dx.chartjs.debug.js 2.2 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708
  1. /*!
  2. * DevExtreme Web
  3. * Version: 15.1.4
  4. * Build date: Jun 22, 2015
  5. *
  6. * Copyright (c) 2012 - 2015 Developer Express Inc. ALL RIGHTS RESERVED
  7. * EULA: https://www.devexpress.com/Support/EULAs/DevExtreme.xml
  8. */
  9. "use strict";
  10. if (!window.DevExpress) {
  11. /*! Module core, file devexpress.js */
  12. (function($, global, undefined) {
  13. global.DevExpress = global.DevExpress || {};
  14. $.extend(global.DevExpress, {
  15. VERSION: "15.1.4",
  16. abstract: function() {
  17. throw global.DevExpress.Error("E0001");
  18. },
  19. stringFormat: function() {
  20. var s = arguments[0],
  21. replaceDollarCount,
  22. reg,
  23. argument;
  24. for (var i = 0; i < arguments.length - 1; i++) {
  25. reg = new RegExp("\\{" + i + "\\}", "gm");
  26. argument = arguments[i + 1];
  27. if ($.type(argument) === "string" && argument.indexOf("$") >= 0) {
  28. replaceDollarCount = "$".replace("$", "$$").length;
  29. argument = argument.replace("$", replaceDollarCount === 1 ? "$$$$" : "$$")
  30. }
  31. s = s.replace(reg, argument)
  32. }
  33. return s
  34. },
  35. parseUrl: function() {
  36. var a = document.createElement("a"),
  37. props = ["protocol", "hostname", "port", "pathname", "search", "hash"];
  38. var normalizePath = function(value) {
  39. if (value.charAt(0) !== "/")
  40. value = "/" + value;
  41. return value
  42. };
  43. return function(url) {
  44. a.href = url;
  45. var result = {};
  46. $.each(props, function() {
  47. result[this] = a[this]
  48. });
  49. result.pathname = normalizePath(result.pathname);
  50. return result
  51. }
  52. }(),
  53. processHardwareBackButton: function() {
  54. this.hardwareBackButton.fire()
  55. },
  56. hardwareBackButton: $.Callbacks(),
  57. viewPort: function() {
  58. var $current;
  59. return function(element) {
  60. if (!arguments.length)
  61. return $current;
  62. var $element = $(element);
  63. var isNewViewportFound = !!$element.length;
  64. var prevViewPort = this.viewPort();
  65. $current = isNewViewportFound ? $element : $("body");
  66. this.viewPortChanged.fire(isNewViewportFound ? this.viewPort() : $(), prevViewPort)
  67. }
  68. }(),
  69. viewPortChanged: $.Callbacks(),
  70. hideTopOverlayCallback: function() {
  71. var callbacks = [];
  72. return {
  73. add: function(callback) {
  74. var indexOfCallback = $.inArray(callback, callbacks);
  75. if (indexOfCallback === -1)
  76. callbacks.push(callback)
  77. },
  78. remove: function(callback) {
  79. var indexOfCallback = $.inArray(callback, callbacks);
  80. if (indexOfCallback !== -1)
  81. callbacks.splice(indexOfCallback, 1)
  82. },
  83. fire: function() {
  84. var callback = callbacks.pop(),
  85. result = !!callback;
  86. if (result)
  87. callback();
  88. return result
  89. },
  90. hasCallback: function() {
  91. return callbacks.length > 0
  92. },
  93. reset: function() {
  94. callbacks = []
  95. }
  96. }
  97. }(),
  98. compareVersions: function(x, y, maxLevel) {
  99. function normalizeArg(value) {
  100. if (typeof value === "string")
  101. return value.split(".");
  102. if (typeof value === "number")
  103. return [value];
  104. return value
  105. }
  106. x = normalizeArg(x);
  107. y = normalizeArg(y);
  108. var length = Math.max(x.length, y.length);
  109. if (isFinite(maxLevel))
  110. length = Math.min(length, maxLevel);
  111. for (var i = 0; i < length; i++) {
  112. var xItem = parseInt(x[i] || 0, 10),
  113. yItem = parseInt(y[i] || 0, 10);
  114. if (xItem < yItem)
  115. return -1;
  116. if (xItem > yItem)
  117. return 1
  118. }
  119. return 0
  120. },
  121. rtlEnabled: false
  122. });
  123. $(function() {
  124. DevExpress.viewPort(".dx-viewport")
  125. })
  126. })(jQuery, this);
  127. /*! Module core, file errors.js */
  128. (function($, DX) {
  129. var ERROR_MESSAGES = {
  130. E0001: "Method is not implemented",
  131. E0002: "Member name collision: {0}",
  132. E0003: "A class must be instantiated using the 'new' keyword",
  133. E0004: "The NAME property of the component is not specified",
  134. E0005: "Unknown device",
  135. E0006: "Unknown endpoint key is requested",
  136. E0007: "'Invalidate' method is called outside the update transaction",
  137. E0008: "Type of the option name is not appropriate to create an action",
  138. E0009: "Component '{0}' has not been initialized for an element",
  139. E0010: "Animation configuration with the '{0}' type requires '{1}' configuration as {2}",
  140. E0011: "Unknown animation type '{0}'",
  141. E0012: "jQuery version is too old. Please upgrade jQuery to 1.10.0 or later",
  142. E0013: "KnockoutJS version is too old. Please upgrade KnockoutJS to 2.3.0 or later",
  143. E0014: "The 'release' method shouldn't be called for an unlocked Lock object",
  144. E0015: "Queued task returned an unexpected result",
  145. E0017: "Event namespace is not defined",
  146. E0018: "DevExpress.ui.dxPopup widget is required",
  147. E0020: "Template engine '{0}' is not supported",
  148. E0021: "Unknown theme is set: {0}",
  149. E0022: "LINK[rel=dx-theme] tags must go before DevExpress included scripts",
  150. E0023: "Template name is not specified",
  151. E0100: "Unknown validation type is detected",
  152. E0101: "Misconfigured range validation rule is detected",
  153. E0102: "Misconfigured comparison validation rule is detected",
  154. E0110: "Unknown validation group is detected",
  155. E0120: "Adapter for a dxValidator component cannot be configured",
  156. W0000: "'{0}' is deprecated in {1}. {2}",
  157. W0001: "{0} - '{1}' option is deprecated in {2}. {3}",
  158. W0002: "{0} - '{1}' method is deprecated in {2}. {3}",
  159. W0003: "{0} - '{1}' property is deprecated in {2}. {3}",
  160. W0004: "Timeout for theme loading is over: {0}",
  161. W0005: "'{0}' event is deprecated in {1}. {2}"
  162. };
  163. var ERROR_URL = "http://js.devexpress.com/error/" + DX.VERSION.split(".").slice(0, 2).join("_") + "/";
  164. var combineMessage = function(args) {
  165. var id = args[0];
  166. args = args.slice(1);
  167. return formatMessage(id, formatDetails(id, args))
  168. };
  169. var formatDetails = function(id, args) {
  170. args = [DX.ERROR_MESSAGES[id]].concat(args);
  171. return DX.stringFormat.apply(this, args).replace(/\.*\s*?$/, '')
  172. };
  173. var formatMessage = function(id, details) {
  174. return DX.stringFormat.apply(this, ["{0} - {1}. See:\n{2}", id, details, ERROR_URL + id])
  175. };
  176. var makeError = function(args) {
  177. var id,
  178. details,
  179. message;
  180. id = args[0];
  181. args = args.slice(1);
  182. details = formatDetails(id, args);
  183. message = formatMessage(id, details);
  184. return $.extend(new Error(message), {
  185. __id: id,
  186. __details: details
  187. })
  188. };
  189. $.extend(DX, {
  190. Error: function() {
  191. return makeError($.makeArray(arguments))
  192. },
  193. log: function(id) {
  194. var method = "log",
  195. logger = DX.utils.logger;
  196. if (/^E\d+$/.test(id))
  197. method = "error";
  198. else if (/^W\d+$/.test(id))
  199. method = "warn";
  200. logger[method](method === "log" ? id : combineMessage($.makeArray(arguments)))
  201. },
  202. ERROR_MESSAGES: ERROR_MESSAGES
  203. })
  204. })(jQuery, DevExpress);
  205. /*! Module core, file class.js */
  206. (function($, global, DX, undefined) {
  207. DX.Class = function() {
  208. var wrapOverridden = function(baseProto, methodName, method) {
  209. return function() {
  210. var prevCallBase = this.callBase;
  211. this.callBase = baseProto[methodName];
  212. try {
  213. return method.apply(this, arguments)
  214. }
  215. finally {
  216. this.callBase = prevCallBase
  217. }
  218. }
  219. };
  220. var clonePrototype = function(obj) {
  221. var func = function(){};
  222. func.prototype = obj.prototype;
  223. return new func
  224. };
  225. var classImpl = function(){};
  226. var redefine = function(members) {
  227. var that = this;
  228. if (!members)
  229. return that;
  230. var memberNames = $.map(members, function(_, k) {
  231. return k
  232. });
  233. $.each(["toString", "toLocaleString", "valueOf"], function() {
  234. if (members[this])
  235. memberNames.push(this)
  236. });
  237. $.each(memberNames, function() {
  238. var overridden = $.isFunction(that.prototype[this]) && $.isFunction(members[this]);
  239. that.prototype[this] = overridden ? wrapOverridden(that.parent.prototype, this, members[this]) : members[this]
  240. });
  241. return that
  242. };
  243. var include = function() {
  244. var classObj = this;
  245. $.each(arguments, function() {
  246. if (this.ctor)
  247. classObj._includedCtors.push(this.ctor);
  248. if (this.postCtor)
  249. classObj._includedPostCtors.push(this.postCtor);
  250. for (var name in this) {
  251. if (name === "ctor" || name === "postCtor")
  252. continue;
  253. if (name in classObj.prototype)
  254. throw DX.Error("E0002", name);
  255. classObj.prototype[name] = this[name]
  256. }
  257. });
  258. return classObj
  259. };
  260. var subclassOf = function(parentClass) {
  261. if (this.parent === parentClass)
  262. return true;
  263. if (!this.parent || !this.parent.subclassOf)
  264. return false;
  265. return this.parent.subclassOf(parentClass)
  266. };
  267. classImpl.inherit = function(members) {
  268. var inheritor = function() {
  269. if (!this || this === global || typeof this.constructor !== "function")
  270. throw DX.Error("E0003");
  271. var instance = this,
  272. ctor = instance.ctor;
  273. $.each(instance.constructor._includedCtors, function() {
  274. this.call(instance)
  275. });
  276. if (ctor)
  277. ctor.apply(instance, arguments);
  278. $.each(instance.constructor._includedPostCtors, function() {
  279. this.call(instance)
  280. })
  281. };
  282. inheritor.prototype = clonePrototype(this);
  283. inheritor.inherit = this.inherit;
  284. inheritor.redefine = redefine;
  285. inheritor.include = include;
  286. inheritor.subclassOf = subclassOf;
  287. inheritor.parent = this;
  288. inheritor._includedCtors = this._includedCtors ? this._includedCtors.slice(0) : [];
  289. inheritor._includedPostCtors = this._includedPostCtors ? this._includedPostCtors.slice(0) : [];
  290. inheritor.prototype.constructor = inheritor;
  291. inheritor.redefine(members);
  292. return inheritor
  293. };
  294. return classImpl
  295. }()
  296. })(jQuery, this, DevExpress);
  297. /*! Module core, file queue.js */
  298. (function($, global, undefined) {
  299. var DX = global.DevExpress;
  300. function createQueue(discardPendingTasks) {
  301. var _tasks = [],
  302. _busy = false;
  303. function exec() {
  304. while (_tasks.length) {
  305. _busy = true;
  306. var task = _tasks.shift(),
  307. result = task();
  308. if (result === undefined)
  309. continue;
  310. if (result.then) {
  311. $.when(result).always(exec);
  312. return
  313. }
  314. throw DX.Error("E0015");
  315. }
  316. _busy = false
  317. }
  318. function add(task, removeTaskCallback) {
  319. if (!discardPendingTasks)
  320. _tasks.push(task);
  321. else {
  322. if (_tasks[0] && removeTaskCallback)
  323. removeTaskCallback(_tasks[0]);
  324. _tasks = [task]
  325. }
  326. if (!_busy)
  327. exec()
  328. }
  329. function busy() {
  330. return _busy
  331. }
  332. return {
  333. add: add,
  334. busy: busy
  335. }
  336. }
  337. $.extend(global.DevExpress, {
  338. createQueue: createQueue,
  339. enqueue: createQueue().add
  340. })
  341. })(jQuery, this);
  342. /*! Module core, file inflector.js */
  343. (function($, DX, undefined) {
  344. var _normalize = function(text) {
  345. if (text === undefined || text === null)
  346. return "";
  347. return String(text)
  348. };
  349. var _ucfirst = function(text) {
  350. return _normalize(text).charAt(0).toUpperCase() + text.substr(1)
  351. };
  352. var _chop = function(text) {
  353. return _normalize(text).replace(/([a-z\d])([A-Z])/g, "$1 $2").split(/[\s_-]+/)
  354. };
  355. var dasherize = function(text) {
  356. return $.map(_chop(text), function(p) {
  357. return p.toLowerCase()
  358. }).join("-")
  359. };
  360. var underscore = function(text) {
  361. return dasherize(text).replace(/-/g, "_")
  362. };
  363. var camelize = function(text, upperFirst) {
  364. return $.map(_chop(text), function(p, i) {
  365. p = p.toLowerCase();
  366. if (upperFirst || i > 0)
  367. p = _ucfirst(p);
  368. return p
  369. }).join("")
  370. };
  371. var humanize = function(text) {
  372. return _ucfirst(dasherize(text).replace(/-/g, " "))
  373. };
  374. var titleize = function(text) {
  375. return $.map(_chop(text), function(p) {
  376. return _ucfirst(p.toLowerCase())
  377. }).join(" ")
  378. };
  379. DX.inflector = {
  380. dasherize: dasherize,
  381. camelize: camelize,
  382. humanize: humanize,
  383. titleize: titleize,
  384. underscore: underscore
  385. }
  386. })(jQuery, DevExpress);
  387. /*! Module core, file eventsMixin.js */
  388. (function($, DX, undefined) {
  389. var EventsMixin = {
  390. ctor: function() {
  391. this._events = {}
  392. },
  393. fireEvent: function(eventName, eventArgs) {
  394. var callbacks = this._events[eventName];
  395. if (callbacks)
  396. callbacks.fireWith(this, eventArgs);
  397. return this
  398. },
  399. on: function(eventName, eventHandler) {
  400. if ($.isPlainObject(eventName))
  401. $.each(eventName, $.proxy(function(e, h) {
  402. this.on(e, h)
  403. }, this));
  404. else {
  405. var callbacks = this._events[eventName],
  406. addFn;
  407. if (!callbacks) {
  408. callbacks = $.Callbacks();
  409. this._events[eventName] = callbacks
  410. }
  411. addFn = callbacks.originalAdd || callbacks.add;
  412. addFn.call(callbacks, eventHandler)
  413. }
  414. return this
  415. },
  416. off: function(eventName, eventHandler) {
  417. var callbacks = this._events[eventName];
  418. if (callbacks)
  419. if ($.isFunction(eventHandler))
  420. callbacks.remove(eventHandler);
  421. else
  422. callbacks.empty();
  423. return this
  424. },
  425. _disposeEvents: function() {
  426. $.each(this._events, function() {
  427. this.empty()
  428. })
  429. },
  430. _callbacksToEvents: function(className, eventNames) {
  431. var that = this;
  432. $.each(eventNames, function(_, eventName) {
  433. var callbacksProperty = that[eventName],
  434. originalAdd;
  435. if (callbacksProperty !== undefined) {
  436. originalAdd = callbacksProperty.add;
  437. callbacksProperty.originalAdd = originalAdd;
  438. callbacksProperty.add = function() {
  439. DX.log("W0003", className, eventName, "14.2", "Use the '" + eventName + "' event instead");
  440. return originalAdd.apply(that, arguments)
  441. };
  442. that._events[eventName] = callbacksProperty
  443. }
  444. })
  445. }
  446. };
  447. $.extend(DX, {EventsMixin: EventsMixin})
  448. })(jQuery, DevExpress);
  449. /*! Module core, file jquery.js */
  450. (function($, DX) {
  451. if (DX.compareVersions($.fn.jquery, [1, 10]) < 0)
  452. throw DX.Error("E0012");
  453. })(jQuery, DevExpress);
  454. /*! Module core, file jquery.selectors.js */
  455. (function($) {
  456. var focusable = function(element, tabIndex) {
  457. var nodeName = element.nodeName.toLowerCase(),
  458. isTabIndexNotNaN = !isNaN(tabIndex),
  459. isVisible = visible(element),
  460. isDisabled = element.disabled,
  461. isDefaultFocus = /^(input|select|textarea|button|object)$/.test(nodeName),
  462. isHyperlink = nodeName === "a",
  463. isFocusable = true;
  464. if (isDefaultFocus)
  465. isFocusable = !isDisabled;
  466. else if (isHyperlink)
  467. isFocusable = element.href || isTabIndexNotNaN;
  468. else
  469. isFocusable = isTabIndexNotNaN;
  470. return isVisible ? isFocusable : false
  471. };
  472. var visible = function(element) {
  473. var $element = $(element);
  474. return $element.is(":visible") && $element.css("visibility") !== "hidden" && $element.parents().css("visibility") !== "hidden"
  475. };
  476. $.extend(jQuery.expr[':'], {
  477. "dx-focusable": function(element) {
  478. return focusable(element, $.attr(element, "tabindex"))
  479. },
  480. "dx-tabbable": function(element) {
  481. var tabIndex = $.attr(element, "tabindex");
  482. return (isNaN(tabIndex) || tabIndex >= 0) && focusable(element, tabIndex)
  483. }
  484. })
  485. })(jQuery);
  486. /*! Module core, file utils.common.js */
  487. (function($, DX, undefined) {
  488. var isDefined = function(object) {
  489. return object !== null && object !== undefined
  490. };
  491. var isString = function(object) {
  492. return $.type(object) === 'string'
  493. };
  494. var isNumber = function(object) {
  495. return typeof object === "number" && isFinite(object) || $.isNumeric(object)
  496. };
  497. var isObject = function(object) {
  498. return $.type(object) === 'object'
  499. };
  500. var isArray = function(object) {
  501. return $.type(object) === 'array'
  502. };
  503. var isDate = function(object) {
  504. return $.type(object) === 'date'
  505. };
  506. var isFunction = function(object) {
  507. return $.type(object) === 'function'
  508. };
  509. var isExponential = function(value) {
  510. return isNumber(value) && value.toString().indexOf('e') !== -1
  511. };
  512. var ensureDefined = function(value, defaultValue) {
  513. return isDefined(value) ? value : defaultValue
  514. };
  515. var getImageSourceType = function(source) {
  516. if (!isDefined(source))
  517. return false;
  518. if (/^fa fa-|^fa-.* fa/.test(source))
  519. return "faIcon";
  520. else if (/^ion-.*|ion.*ion-.*/.test(source))
  521. return "ionIcon";
  522. else if (/^glyphicon glyphicon-|^glyphicon-.* glyphicon/.test(source))
  523. return "glyphIcon";
  524. else if (/data:.*base64|\.|\//.test(source))
  525. return "image";
  526. else if (/^[\w-_]+$/.test(source))
  527. return "dxIcon";
  528. else
  529. return false
  530. };
  531. var getImageContainer = function(source) {
  532. var imageType = getImageSourceType(source),
  533. ICON_CLASS = "dx-icon";
  534. switch (imageType) {
  535. case"image":
  536. return $("<img>", {src: source}).addClass(ICON_CLASS);
  537. case"faIcon":
  538. case"glyphIcon":
  539. return $("<i>", {"class": ICON_CLASS + " " + source});
  540. case"ionIcon":
  541. var result = $("<i>", {"class": ICON_CLASS + " " + source});
  542. if (!result.hasClass("ion") && !result.hasClass("ionicons"))
  543. result.addClass("ion");
  544. return result;
  545. case"dxIcon":
  546. return $("<i>", {"class": ICON_CLASS + " " + ICON_CLASS + "-" + source});
  547. default:
  548. return null
  549. }
  550. };
  551. var extendFromObject = function(target, source, overrideExistingValues) {
  552. target = target || {};
  553. for (var prop in source)
  554. if (source.hasOwnProperty(prop)) {
  555. var value = source[prop];
  556. if (!(prop in target) || overrideExistingValues)
  557. target[prop] = value
  558. }
  559. return target
  560. };
  561. var clone = function() {
  562. function Clone(){}
  563. return function(obj) {
  564. Clone.prototype = obj;
  565. return new Clone
  566. }
  567. }();
  568. var executeAsync = function(action, context) {
  569. var deferred = $.Deferred(),
  570. normalizedContext = context || this,
  571. timerId,
  572. task = {
  573. promise: deferred.promise(),
  574. abort: function() {
  575. clearTimeout(timerId);
  576. deferred.rejectWith(normalizedContext)
  577. }
  578. },
  579. callback = function() {
  580. var result = action.call(normalizedContext);
  581. if (result && result.done && $.isFunction(result.done))
  582. result.done(function() {
  583. deferred.resolveWith(normalizedContext)
  584. });
  585. else
  586. deferred.resolveWith(normalizedContext)
  587. };
  588. timerId = (arguments[2] || setTimeout)(callback, 0);
  589. return task
  590. };
  591. var findBestMatches = function(targetFilter, items, mapFn) {
  592. var bestMatches = [],
  593. maxMatchCount = 0;
  594. $.each(items, function(index, itemSrc) {
  595. var matchCount = 0,
  596. item = mapFn ? mapFn(itemSrc) : itemSrc;
  597. $.each(targetFilter, function(paramName) {
  598. var value = item[paramName];
  599. if (value === undefined)
  600. return;
  601. if (value === targetFilter[paramName]) {
  602. matchCount++;
  603. return
  604. }
  605. matchCount = -1;
  606. return false
  607. });
  608. if (matchCount < maxMatchCount)
  609. return;
  610. if (matchCount > maxMatchCount) {
  611. bestMatches.length = 0;
  612. maxMatchCount = matchCount
  613. }
  614. bestMatches.push(itemSrc)
  615. });
  616. return bestMatches
  617. };
  618. var preg_quote = function(str) {
  619. return (str + "").replace(/([\+\*\?\\\.\[\^\]\$\(\)\{\}\><\|\=\!\:])/g, "\\$1")
  620. };
  621. var replaceAll = function(text, searchToken, replacementToken) {
  622. return text.replace(new RegExp("(" + preg_quote(searchToken) + ")", "gi"), replacementToken)
  623. };
  624. var splitPair = function(raw) {
  625. switch (typeof raw) {
  626. case"string":
  627. return raw.split(/\s+/, 2);
  628. case"object":
  629. return [raw.x || raw.h, raw.y || raw.v];
  630. case"number":
  631. return [raw];
  632. default:
  633. return raw
  634. }
  635. };
  636. var stringPairToObject = function(raw) {
  637. var pair = splitPair(raw),
  638. h = parseInt(pair && pair[0], 10),
  639. v = parseInt(pair && pair[1], 10);
  640. if (!isFinite(h))
  641. h = 0;
  642. if (!isFinite(v))
  643. v = h;
  644. return {
  645. h: h,
  646. v: v
  647. }
  648. };
  649. var orderEach = function(map, func) {
  650. var keys = [],
  651. key,
  652. i;
  653. for (key in map)
  654. keys.push(key);
  655. keys.sort(function(x, y) {
  656. var isNumberX = DX.utils.isNumber(x),
  657. isNumberY = DX.utils.isNumber(y);
  658. if (isNumberX && isNumberY)
  659. return x - y;
  660. if (isNumberX && !isNumberY)
  661. return -1;
  662. if (!isNumberX && isNumberY)
  663. return 1;
  664. if (x < y)
  665. return -1;
  666. if (x > y)
  667. return 1;
  668. return 0
  669. });
  670. for (i = 0; i < keys.length; i++) {
  671. key = keys[i];
  672. func(key, map[key])
  673. }
  674. };
  675. function icontains(elem, text) {
  676. var result = false;
  677. $.each($(elem).contents(), function(index, content) {
  678. if (content.nodeType === 3 && (content.textContent || content.nodeValue || "").toLowerCase().indexOf((text || "").toLowerCase()) > -1) {
  679. result = true;
  680. return false
  681. }
  682. });
  683. return result
  684. }
  685. $.expr[":"].dxicontains = $.expr.createPseudo(function(text) {
  686. return function(elem) {
  687. return icontains(elem, text)
  688. }
  689. });
  690. function deepExtendArraySafe(target, changes) {
  691. var prevValue,
  692. newValue;
  693. for (var name in changes) {
  694. prevValue = target[name];
  695. newValue = changes[name];
  696. if (target === newValue)
  697. continue;
  698. if ($.isPlainObject(newValue) && !(newValue instanceof $.Event))
  699. target[name] = deepExtendArraySafe($.isPlainObject(prevValue) ? prevValue : {}, newValue);
  700. else if (newValue !== undefined)
  701. target[name] = newValue
  702. }
  703. return target
  704. }
  705. function unwrapObservable(value) {
  706. if (DX.support.hasKo)
  707. return ko.utils.unwrapObservable(value);
  708. return value
  709. }
  710. function normalizeIndexes(items, indexParameterName, currentItem, needIndexCallback) {
  711. var indexedItems = {},
  712. parameterIndex = 0;
  713. $.each(items, function(index, item) {
  714. index = item[indexParameterName];
  715. if (isDefined(index)) {
  716. indexedItems[index] = indexedItems[index] || [];
  717. if (item === currentItem)
  718. indexedItems[index].unshift(item);
  719. else
  720. indexedItems[index].push(item);
  721. delete item[indexParameterName]
  722. }
  723. });
  724. orderEach(indexedItems, function(index, items) {
  725. $.each(items, function() {
  726. if (index >= 0)
  727. this[indexParameterName] = parameterIndex++
  728. })
  729. });
  730. $.each(items, function() {
  731. if (!isDefined(this[indexParameterName]) && (!needIndexCallback || needIndexCallback(this)))
  732. this[indexParameterName] = parameterIndex++
  733. });
  734. return parameterIndex
  735. }
  736. DX.utils = {
  737. isDefined: isDefined,
  738. isString: isString,
  739. isNumber: isNumber,
  740. isObject: isObject,
  741. isArray: isArray,
  742. isDate: isDate,
  743. isFunction: isFunction,
  744. isExponential: isExponential,
  745. ensureDefined: ensureDefined,
  746. extendFromObject: extendFromObject,
  747. clone: clone,
  748. executeAsync: executeAsync,
  749. stringFormat: DX.stringFormat,
  750. findBestMatches: findBestMatches,
  751. replaceAll: replaceAll,
  752. deepExtendArraySafe: deepExtendArraySafe,
  753. splitPair: splitPair,
  754. stringPairToObject: stringPairToObject,
  755. normalizeIndexes: normalizeIndexes,
  756. orderEach: orderEach,
  757. unwrapObservable: unwrapObservable,
  758. getImageSourceType: getImageSourceType,
  759. getImageContainer: getImageContainer
  760. }
  761. })(jQuery, DevExpress);
  762. /*! Module core, file utils.console.js */
  763. (function($, DX, undefined) {
  764. var logger = function() {
  765. var console = window.console;
  766. function info(text) {
  767. if (!console || !$.isFunction(console.info))
  768. return;
  769. console.info(text)
  770. }
  771. function warn(text) {
  772. if (!console || !$.isFunction(console.warn))
  773. return;
  774. console.warn(text)
  775. }
  776. function error(text) {
  777. if (!console || !$.isFunction(console.error))
  778. return;
  779. console.error(text)
  780. }
  781. return {
  782. info: info,
  783. warn: warn,
  784. error: error
  785. }
  786. }();
  787. var debug = function() {
  788. function assert(condition, message) {
  789. if (!condition)
  790. throw new Error(message);
  791. }
  792. function assertParam(parameter, message) {
  793. assert(parameter !== null && parameter !== undefined, message)
  794. }
  795. return {
  796. assert: assert,
  797. assertParam: assertParam
  798. }
  799. }();
  800. $.extend(DX.utils, {
  801. logger: logger,
  802. debug: debug
  803. })
  804. })(jQuery, DevExpress);
  805. /*! Module core, file utils.math.js */
  806. (function($, DX, undefined) {
  807. var PI = Math.PI,
  808. LN10 = Math.LN10;
  809. var cos = Math.cos,
  810. sin = Math.sin,
  811. abs = Math.abs,
  812. log = Math.log,
  813. floor = Math.floor,
  814. ceil = Math.ceil,
  815. max = Math.max,
  816. isNaN = window.isNaN,
  817. Number = window.Number,
  818. NaN = window.NaN;
  819. var isNumber = DX.utils.isNumber,
  820. isExponential = DX.utils.isExponential;
  821. var getPrecision = function(value) {
  822. var stringFraction,
  823. stringValue = value.toString(),
  824. pointIndex = stringValue.indexOf('.'),
  825. startIndex,
  826. precision;
  827. if (isExponential(value)) {
  828. precision = getDecimalOrder(value);
  829. if (precision < 0)
  830. return Math.abs(precision);
  831. else
  832. return 0
  833. }
  834. if (pointIndex !== -1) {
  835. startIndex = pointIndex + 1;
  836. stringFraction = stringValue.substring(startIndex, startIndex + 20);
  837. return stringFraction.length
  838. }
  839. return 0
  840. };
  841. var getLog = function(value, base) {
  842. if (!value)
  843. return NaN;
  844. return Math.log(value) / Math.log(base)
  845. };
  846. var raiseTo = function(power, base) {
  847. return Math.pow(base, power)
  848. };
  849. var sign = function(value) {
  850. if (value === 0)
  851. return 0;
  852. return value / abs(value)
  853. };
  854. var normalizeAngle = function(angle) {
  855. return (angle % 360 + 360) % 360
  856. };
  857. var convertAngleToRendererSpace = function(angle) {
  858. return 90 - angle
  859. };
  860. var degreesToRadians = function(value) {
  861. return PI * value / 180
  862. };
  863. var getCosAndSin = function(angle) {
  864. var angleInRadians = degreesToRadians(angle);
  865. return {
  866. cos: cos(angleInRadians),
  867. sin: sin(angleInRadians)
  868. }
  869. };
  870. var DECIMAL_ORDER_THRESHOLD = 1E-14;
  871. var getDistance = function(x1, y1, x2, y2) {
  872. var diffX = x2 - x1,
  873. diffY = y2 - y1;
  874. return Math.sqrt(diffY * diffY + diffX * diffX)
  875. };
  876. var getDecimalOrder = function(number) {
  877. var n = abs(number),
  878. cn;
  879. if (!isNaN(n)) {
  880. if (n > 0) {
  881. n = log(n) / LN10;
  882. cn = ceil(n);
  883. return cn - n < DECIMAL_ORDER_THRESHOLD ? cn : floor(n)
  884. }
  885. return 0
  886. }
  887. return NaN
  888. };
  889. var getAppropriateFormat = function(start, end, count) {
  890. var order = max(getDecimalOrder(start), getDecimalOrder(end)),
  891. precision = -getDecimalOrder(abs(end - start) / count),
  892. format;
  893. if (!isNaN(order) && !isNaN(precision)) {
  894. if (abs(order) <= 4) {
  895. format = 'fixedPoint';
  896. precision < 0 && (precision = 0);
  897. precision > 4 && (precision = 4)
  898. }
  899. else {
  900. format = 'exponential';
  901. precision += order - 1;
  902. precision > 3 && (precision = 3)
  903. }
  904. return {
  905. format: format,
  906. precision: precision
  907. }
  908. }
  909. return null
  910. };
  911. var getFraction = function(value) {
  912. var valueString,
  913. dotIndex;
  914. if (isNumber(value)) {
  915. valueString = value.toString();
  916. dotIndex = valueString.indexOf('.');
  917. if (dotIndex >= 0)
  918. if (isExponential(value))
  919. return valueString.substr(dotIndex + 1, valueString.indexOf('e') - dotIndex - 1);
  920. else {
  921. valueString = value.toFixed(20);
  922. return valueString.substr(dotIndex + 1, valueString.length - dotIndex + 1)
  923. }
  924. }
  925. return ''
  926. };
  927. var getSignificantDigitPosition = function(value) {
  928. var fraction = getFraction(value),
  929. i;
  930. if (fraction)
  931. for (i = 0; i < fraction.length; i++)
  932. if (fraction.charAt(i) !== '0')
  933. return i + 1;
  934. return 0
  935. };
  936. var adjustValue = function(value) {
  937. var fraction = getFraction(value),
  938. nextValue,
  939. i;
  940. if (fraction)
  941. for (i = 1; i <= fraction.length; i++) {
  942. nextValue = roundValue(value, i);
  943. if (nextValue !== 0 && fraction[i - 2] && fraction[i - 1] && fraction[i - 2] === fraction[i - 1])
  944. return nextValue
  945. }
  946. return value
  947. };
  948. var roundValue = function(value, precision) {
  949. if (precision > 20)
  950. precision = 20;
  951. if (isNumber(value))
  952. if (isExponential(value))
  953. return Number(value.toExponential(precision));
  954. else
  955. return Number(value.toFixed(precision))
  956. };
  957. var applyPrecisionByMinDelta = function(min, delta, value) {
  958. var minPrecision = getPrecision(min),
  959. deltaPrecision = getPrecision(delta);
  960. return roundValue(value, minPrecision < deltaPrecision ? deltaPrecision : minPrecision)
  961. };
  962. var fitIntoRange = function(value, minValue, maxValue) {
  963. return Math.min(Math.max(value, minValue), maxValue)
  964. };
  965. var getPower = function(value) {
  966. return value.toExponential().split("e")[1]
  967. };
  968. $.extend(DX.utils, {
  969. getLog: getLog,
  970. raiseTo: raiseTo,
  971. sign: sign,
  972. normalizeAngle: normalizeAngle,
  973. convertAngleToRendererSpace: convertAngleToRendererSpace,
  974. degreesToRadians: degreesToRadians,
  975. getCosAndSin: getCosAndSin,
  976. getDecimalOrder: getDecimalOrder,
  977. getAppropriateFormat: getAppropriateFormat,
  978. getDistance: getDistance,
  979. getFraction: getFraction,
  980. adjustValue: adjustValue,
  981. roundValue: roundValue,
  982. applyPrecisionByMinDelta: applyPrecisionByMinDelta,
  983. getSignificantDigitPosition: getSignificantDigitPosition,
  984. getPower: getPower,
  985. fitIntoRange: fitIntoRange
  986. });
  987. DX.utils.getPrecision = getPrecision
  988. })(jQuery, DevExpress);
  989. /*! Module core, file utils.date.js */
  990. (function($, DX, undefined) {
  991. var isObject = DX.utils.isObject,
  992. isString = DX.utils.isString,
  993. isDate = DX.utils.isDate,
  994. isDefined = DX.utils.isDefined;
  995. var dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'];
  996. var addSubValues = function(value1, value2, isSub) {
  997. return value1 + (isSub ? -1 : 1) * value2
  998. };
  999. var toMilliseconds = function(value) {
  1000. switch (value) {
  1001. case'millisecond':
  1002. return 1;
  1003. case'second':
  1004. return toMilliseconds('millisecond') * 1000;
  1005. case'minute':
  1006. return toMilliseconds('second') * 60;
  1007. case'hour':
  1008. return toMilliseconds('minute') * 60;
  1009. case'day':
  1010. return toMilliseconds('hour') * 24;
  1011. case'week':
  1012. return toMilliseconds('day') * 7;
  1013. case'month':
  1014. return toMilliseconds('day') * 30;
  1015. case'quarter':
  1016. return toMilliseconds('month') * 3;
  1017. case'year':
  1018. return toMilliseconds('day') * 365;
  1019. default:
  1020. return 0
  1021. }
  1022. };
  1023. var convertMillisecondsToDateUnits = function(value) {
  1024. var i,
  1025. dateUnitCount,
  1026. dateUnitInterval,
  1027. dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'month', 'year'],
  1028. result = {};
  1029. for (i = dateUnitIntervals.length - 1; i >= 0; i--) {
  1030. dateUnitInterval = dateUnitIntervals[i];
  1031. dateUnitCount = Math.floor(value / toMilliseconds(dateUnitInterval));
  1032. if (dateUnitCount > 0) {
  1033. result[dateUnitInterval + 's'] = dateUnitCount;
  1034. value -= convertDateUnitToMilliseconds(dateUnitInterval, dateUnitCount)
  1035. }
  1036. }
  1037. return result
  1038. };
  1039. var dateToMilliseconds = function(tickInterval) {
  1040. var milliseconds = 0;
  1041. if (isObject(tickInterval))
  1042. $.each(tickInterval, function(key, value) {
  1043. milliseconds += convertDateUnitToMilliseconds(key.substr(0, key.length - 1), value)
  1044. });
  1045. if (isString(tickInterval))
  1046. milliseconds = convertDateUnitToMilliseconds(tickInterval, 1);
  1047. return milliseconds
  1048. };
  1049. var convertDateUnitToMilliseconds = function(dateUnit, count) {
  1050. return toMilliseconds(dateUnit) * count
  1051. };
  1052. var getDateUnitInterval = function(tickInterval) {
  1053. var maxInterval = -1,
  1054. i;
  1055. if (isString(tickInterval))
  1056. return tickInterval;
  1057. if (isObject(tickInterval)) {
  1058. $.each(tickInterval, function(key, value) {
  1059. for (i = 0; i < dateUnitIntervals.length; i++)
  1060. if (value && (key === dateUnitIntervals[i] + 's' || key === dateUnitIntervals[i]) && maxInterval < i)
  1061. maxInterval = i
  1062. });
  1063. return dateUnitIntervals[maxInterval]
  1064. }
  1065. return ''
  1066. };
  1067. var correctDateWithUnitBeginning = function(date, dateInterval, withCorrection) {
  1068. var oldDate = new Date(date.getTime()),
  1069. dayMonth,
  1070. firstQuarterMonth,
  1071. dateUnitInterval = getDateUnitInterval(dateInterval);
  1072. switch (dateUnitInterval) {
  1073. case'second':
  1074. date.setMilliseconds(0);
  1075. break;
  1076. case'minute':
  1077. date.setSeconds(0, 0);
  1078. break;
  1079. case'hour':
  1080. date.setMinutes(0, 0, 0);
  1081. break;
  1082. case'year':
  1083. date.setMonth(0);
  1084. case'month':
  1085. date.setDate(1);
  1086. case'day':
  1087. date.setHours(0, 0, 0, 0);
  1088. break;
  1089. case'week':
  1090. dayMonth = date.getDate();
  1091. if (date.getDay() !== 0)
  1092. dayMonth += 7 - date.getDay();
  1093. date.setDate(dayMonth);
  1094. date.setHours(0, 0, 0, 0);
  1095. break;
  1096. case'quarter':
  1097. firstQuarterMonth = DX.formatHelper.getFirstQuarterMonth(date.getMonth());
  1098. if (date.getMonth() !== firstQuarterMonth)
  1099. date.setMonth(firstQuarterMonth);
  1100. date.setDate(1);
  1101. date.setHours(0, 0, 0, 0);
  1102. break
  1103. }
  1104. if (withCorrection && dateUnitInterval !== "hour" && dateUnitInterval !== "minute" && dateUnitInterval !== "second")
  1105. fixTimezoneGap(oldDate, date)
  1106. };
  1107. var getDatesDifferences = function(date1, date2) {
  1108. var differences,
  1109. counter = 0;
  1110. differences = {
  1111. year: date1.getFullYear() !== date2.getFullYear(),
  1112. month: date1.getMonth() !== date2.getMonth(),
  1113. day: date1.getDate() !== date2.getDate(),
  1114. hour: date1.getHours() !== date2.getHours(),
  1115. minute: date1.getMinutes() !== date2.getMinutes(),
  1116. second: date1.getSeconds() !== date2.getSeconds()
  1117. };
  1118. $.each(differences, function(key, value) {
  1119. if (value)
  1120. counter++
  1121. });
  1122. differences.count = counter;
  1123. return differences
  1124. };
  1125. var addInterval = function(value, interval, isNegative) {
  1126. var result = null,
  1127. intervalObject;
  1128. if (isDate(value)) {
  1129. intervalObject = isString(interval) ? getDateIntervalByString(interval.toLowerCase()) : interval;
  1130. result = new Date(value.getTime());
  1131. if (intervalObject.years)
  1132. result.setFullYear(addSubValues(result.getFullYear(), intervalObject.years, isNegative));
  1133. if (intervalObject.quarters)
  1134. result.setMonth(addSubValues(result.getMonth(), 3 * intervalObject.quarters, isNegative));
  1135. if (intervalObject.months)
  1136. result.setMonth(addSubValues(result.getMonth(), intervalObject.months, isNegative));
  1137. if (intervalObject.weeks)
  1138. result.setDate(addSubValues(result.getDate(), 7 * intervalObject.weeks, isNegative));
  1139. if (intervalObject.days)
  1140. result.setDate(addSubValues(result.getDate(), intervalObject.days, isNegative));
  1141. if (intervalObject.hours)
  1142. result.setHours(addSubValues(result.getHours(), intervalObject.hours, isNegative));
  1143. if (intervalObject.minutes)
  1144. result.setMinutes(addSubValues(result.getMinutes(), intervalObject.minutes, isNegative));
  1145. if (intervalObject.seconds)
  1146. result.setSeconds(addSubValues(result.getSeconds(), intervalObject.seconds, isNegative));
  1147. if (intervalObject.milliseconds)
  1148. result.setMilliseconds(addSubValues(value.getMilliseconds(), intervalObject.milliseconds, isNegative))
  1149. }
  1150. else
  1151. result = addSubValues(value, interval, isNegative);
  1152. return result
  1153. };
  1154. var getFirstDateView = function(typeView, date) {
  1155. if (!isDefined(date))
  1156. return;
  1157. if (typeView === "month")
  1158. return getFirstMonthDate(date);
  1159. if (typeView === "year")
  1160. return new Date(date.getFullYear(), 0, 1);
  1161. if (typeView === "decade")
  1162. return new Date(getFirstYearInDecade(date), 0, 1);
  1163. if (typeView === "century")
  1164. return new Date(getFirstDecadeInCentury(date), 0, 1)
  1165. };
  1166. var getLastDateView = function(typeView, date) {
  1167. if (typeView === "month")
  1168. return new Date(date.getFullYear(), date.getMonth(), getLastDayOfMonth(date));
  1169. if (typeView === "year")
  1170. return new Date(date.getFullYear(), 11, 1);
  1171. if (typeView === "decade")
  1172. return new Date(getFirstYearInDecade(date) + 9, 0, 1);
  1173. if (typeView === "century")
  1174. return new Date(getFirstDecadeInCentury(date) + 90, 0, 1)
  1175. };
  1176. var sameView = function(view, date1, date2) {
  1177. return DX.utils[DX.inflector.camelize("same " + view)](date1, date2)
  1178. };
  1179. var getViewUp = function(typeView) {
  1180. switch (typeView) {
  1181. case"month":
  1182. return "year";
  1183. case"year":
  1184. return "decade";
  1185. case"decade":
  1186. return "century";
  1187. default:
  1188. break
  1189. }
  1190. };
  1191. var getViewDown = function(typeView) {
  1192. switch (typeView) {
  1193. case"century":
  1194. return "decade";
  1195. case"decade":
  1196. return "year";
  1197. case"year":
  1198. return "month";
  1199. default:
  1200. break
  1201. }
  1202. };
  1203. var getDifferenceInMonth = function(typeView) {
  1204. var difference = 1;
  1205. if (typeView === "year")
  1206. difference = 12;
  1207. if (typeView === "decade")
  1208. difference = 12 * 10;
  1209. if (typeView === "century")
  1210. difference = 12 * 100;
  1211. return difference
  1212. };
  1213. var getDifferenceInMonthForCells = function(typeView) {
  1214. var difference = 1;
  1215. if (typeView === "decade")
  1216. difference = 12;
  1217. if (typeView === "century")
  1218. difference = 12 * 10;
  1219. return difference
  1220. };
  1221. var getDateIntervalByString = function(intervalString) {
  1222. var result = {};
  1223. switch (intervalString) {
  1224. case'year':
  1225. result.years = 1;
  1226. break;
  1227. case'month':
  1228. result.months = 1;
  1229. break;
  1230. case'quarter':
  1231. result.months = 3;
  1232. break;
  1233. case'week':
  1234. result.days = 7;
  1235. break;
  1236. case'day':
  1237. result.days = 1;
  1238. break;
  1239. case'hour':
  1240. result.hours = 1;
  1241. break;
  1242. case'minute':
  1243. result.minutes = 1;
  1244. break;
  1245. case'second':
  1246. result.seconds = 1;
  1247. break;
  1248. case'millisecond':
  1249. result.milliseconds = 1;
  1250. break
  1251. }
  1252. return result
  1253. };
  1254. var sameMonthAndYear = function(date1, date2) {
  1255. return date1 && date2 && date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth()
  1256. };
  1257. var sameYear = function(date1, date2) {
  1258. return date1 && date2 && date1.getFullYear() === date2.getFullYear()
  1259. };
  1260. var sameDecade = function(date1, date2) {
  1261. if (!isDefined(date1) || !isDefined(date2))
  1262. return;
  1263. var startDecadeDate1 = date1.getFullYear() - date1.getFullYear() % 10,
  1264. startDecadeDate2 = date2.getFullYear() - date2.getFullYear() % 10;
  1265. return date1 && date2 && startDecadeDate1 === startDecadeDate2
  1266. };
  1267. var sameCentury = function(date1, date2) {
  1268. if (!isDefined(date1) || !isDefined(date2))
  1269. return;
  1270. var startCenturyDate1 = date1.getFullYear() - date1.getFullYear() % 100,
  1271. startCenturyDate2 = date2.getFullYear() - date2.getFullYear() % 100;
  1272. return date1 && date2 && startCenturyDate1 === startCenturyDate2
  1273. };
  1274. var getFirstDecadeInCentury = function(date) {
  1275. return date && date.getFullYear() - date.getFullYear() % 100
  1276. };
  1277. var getFirstYearInDecade = function(date) {
  1278. return date && date.getFullYear() - date.getFullYear() % 10
  1279. };
  1280. var getShortDate = function(date) {
  1281. return Globalize.format(date, "yyyy/M/d")
  1282. };
  1283. var getLastDayOfMonth = function(date) {
  1284. date = new Date(date.getFullYear(), date.getMonth() + 1, 0);
  1285. return date.getDate()
  1286. };
  1287. var getFirstMonthDate = function(date) {
  1288. if (!isDefined(date))
  1289. return;
  1290. var newDate = new Date(date.getFullYear(), date.getMonth(), 1);
  1291. return newDate
  1292. };
  1293. var getLastMonthDate = function(date) {
  1294. if (!isDefined(date))
  1295. return;
  1296. var newDate = new Date(date.getFullYear(), date.getMonth() + 1, 0);
  1297. return newDate
  1298. };
  1299. var getFirstWeekDate = function(date, firstDayOfWeek) {
  1300. firstDayOfWeek = firstDayOfWeek || Globalize.culture().calendar.firstDay;
  1301. var delta = (date.getDay() - firstDayOfWeek + 7) % 7;
  1302. var result = new Date(date);
  1303. result.setDate(date.getDate() - delta);
  1304. return result
  1305. };
  1306. var dateInRange = function(date, min, max) {
  1307. return normalizeDate(date, min, max) === date
  1308. };
  1309. var normalizeDate = function(date, min, max) {
  1310. var normalizedDate = date;
  1311. if (isDefined(min) && date < min)
  1312. normalizedDate = min;
  1313. if (isDefined(max) && date > max)
  1314. normalizedDate = max;
  1315. return normalizedDate
  1316. };
  1317. var fixTimezoneGap = function(oldDate, newDate) {
  1318. if (!DX.utils.isDefined(oldDate))
  1319. return;
  1320. var diff = newDate.getHours() - oldDate.getHours(),
  1321. sign,
  1322. trial;
  1323. if (diff === 0)
  1324. return;
  1325. sign = diff === 1 || diff === -23 ? -1 : 1,
  1326. trial = new Date(newDate.getTime() + sign * 3600000);
  1327. if (sign > 0 || trial.getDate() === newDate.getDate())
  1328. newDate.setTime(trial.getTime())
  1329. };
  1330. var makeDate = function(date) {
  1331. if (!(date instanceof Date))
  1332. date = new Date(date);
  1333. return date
  1334. };
  1335. $.extend(DX.utils, {
  1336. dateUnitIntervals: dateUnitIntervals,
  1337. convertMillisecondsToDateUnits: convertMillisecondsToDateUnits,
  1338. dateToMilliseconds: dateToMilliseconds,
  1339. convertDateUnitToMilliseconds: convertDateUnitToMilliseconds,
  1340. getDateUnitInterval: getDateUnitInterval,
  1341. getDatesDifferences: getDatesDifferences,
  1342. correctDateWithUnitBeginning: correctDateWithUnitBeginning,
  1343. addInterval: addInterval,
  1344. getDateIntervalByString: getDateIntervalByString,
  1345. sameMonthAndYear: sameMonthAndYear,
  1346. sameMonth: sameMonthAndYear,
  1347. sameYear: sameYear,
  1348. sameDecade: sameDecade,
  1349. sameCentury: sameCentury,
  1350. sameView: sameView,
  1351. getDifferenceInMonth: getDifferenceInMonth,
  1352. getDifferenceInMonthForCells: getDifferenceInMonthForCells,
  1353. getFirstYearInDecade: getFirstYearInDecade,
  1354. getFirstDecadeInCentury: getFirstDecadeInCentury,
  1355. getShortDate: getShortDate,
  1356. getFirstDateView: getFirstDateView,
  1357. getLastDateView: getLastDateView,
  1358. getViewDown: getViewDown,
  1359. getViewUp: getViewUp,
  1360. getLastMonthDate: getLastMonthDate,
  1361. getFirstMonthDate: getFirstMonthDate,
  1362. getFirstWeekDate: getFirstWeekDate,
  1363. getLastDayOfMonth: getLastDayOfMonth,
  1364. dateInRange: dateInRange,
  1365. normalizeDate: normalizeDate,
  1366. fixTimezoneGap: fixTimezoneGap,
  1367. makeDate: makeDate
  1368. })
  1369. })(jQuery, DevExpress);
  1370. /*! Module core, file utils.recurrence.js */
  1371. (function($, DX, undefined) {
  1372. var utils = DX.utils;
  1373. var intervalMap = {
  1374. secondly: "seconds",
  1375. minutely: "minutes",
  1376. hourly: "hours",
  1377. daily: "days",
  1378. weekly: "weeks",
  1379. monthly: "months",
  1380. yearly: "years"
  1381. };
  1382. var dateSetterMap = {
  1383. bysecond: function(date, value) {
  1384. date.setSeconds(value)
  1385. },
  1386. byminute: function(date, value) {
  1387. date.setMinutes(value)
  1388. },
  1389. byhour: function(date, value) {
  1390. date.setHours(value)
  1391. },
  1392. bymonth: function(date, value) {
  1393. date.setMonth(value)
  1394. },
  1395. bymonthday: function(date, value) {
  1396. date.setDate(value)
  1397. },
  1398. byday: function(date, dayOfWeek) {
  1399. date.setDate(date.getDate() - date.getDay() + dayOfWeek)
  1400. }
  1401. };
  1402. var dateGetterMap = {
  1403. bysecond: "getSeconds",
  1404. byminute: "getMinutes",
  1405. byhour: "getHours",
  1406. bymonth: "getMonth",
  1407. bymonthday: "getDate",
  1408. byday: "getDay"
  1409. };
  1410. var dateInRecurrenceRange = function(recurrenceString, currentDate, viewStartDate, viewEndDate) {
  1411. var result = [];
  1412. if (recurrenceString)
  1413. result = getDatesByRecurrence(recurrenceString, currentDate, viewStartDate, viewEndDate);
  1414. return !!result.length
  1415. };
  1416. var normalizeInterval = function(freq, interval) {
  1417. var intervalObject = {},
  1418. intervalField = intervalMap[freq.toLowerCase()];
  1419. intervalObject[intervalField] = interval;
  1420. return intervalObject
  1421. };
  1422. var getDatesByRecurrence = function(recurrenceString, recurrenceStartDate, viewStartDate, viewEndDate) {
  1423. if (!recurrenceString)
  1424. return [];
  1425. var result = [],
  1426. recurrenceRule = getRecurrenceRule(recurrenceString);
  1427. if (!recurrenceRule.freq)
  1428. return result;
  1429. recurrenceRule.interval = normalizeInterval(recurrenceRule.freq, recurrenceRule.interval);
  1430. viewEndDate = utils.normalizeDate(viewEndDate, viewStartDate, recurrenceRule.until);
  1431. var recurrenceCounter = 0,
  1432. dateCounter = 0,
  1433. dateRules = splitDateRules(recurrenceRule),
  1434. ruleDates = getDatesByRules(dateRules, recurrenceStartDate),
  1435. currentDate = ruleDates[0],
  1436. firstDate = new Date(recurrenceStartDate);
  1437. utils.correctDateWithUnitBeginning(firstDate, recurrenceRule.interval);
  1438. var firstDateInterval = getDatePartDiffs(recurrenceStartDate, firstDate);
  1439. while (currentDate <= viewEndDate && recurrenceRule.count !== recurrenceCounter) {
  1440. if (checkDateByRule(currentDate, dateRules)) {
  1441. if (currentDate >= viewStartDate) {
  1442. viewStartDate = new Date(currentDate);
  1443. viewStartDate.setMilliseconds(viewStartDate.getMilliseconds() + 1);
  1444. result.push(new Date(currentDate))
  1445. }
  1446. recurrenceCounter++
  1447. }
  1448. dateCounter++;
  1449. currentDate = ruleDates[dateCounter % ruleDates.length];
  1450. if (dateCounter / ruleDates.length >= 1) {
  1451. dateCounter = 0;
  1452. firstDate = utils.addInterval(firstDate, recurrenceRule.interval);
  1453. ruleDates = getDatesByRules(dateRules, utils.addInterval(firstDate, firstDateInterval));
  1454. currentDate = ruleDates[0]
  1455. }
  1456. }
  1457. return result
  1458. };
  1459. var getDatePartDiffs = function(date1, date2) {
  1460. return {
  1461. years: date1.getFullYear() - date2.getFullYear(),
  1462. months: date1.getMonth() - date2.getMonth(),
  1463. days: date1.getDate() - date2.getDate(),
  1464. hours: date1.getHours() - date2.getHours(),
  1465. minutes: date1.getMinutes() - date2.getMinutes(),
  1466. seconds: date1.getSeconds() - date2.getSeconds()
  1467. }
  1468. };
  1469. var getRecurrenceRule = function(recurrence) {
  1470. if (!recurrence)
  1471. return {};
  1472. var ruleObject = {},
  1473. ruleStrings = recurrence.split(";");
  1474. for (var i = 0, len = ruleStrings.length; i < len; i++) {
  1475. var rule = ruleStrings[i].split("="),
  1476. ruleName = rule[0].toLowerCase(),
  1477. ruleValue = rule[1];
  1478. ruleObject[ruleName] = ruleValue
  1479. }
  1480. return normalizeRRule(ruleObject)
  1481. };
  1482. var normalizeRRule = function(rule) {
  1483. var count = parseInt(rule.count);
  1484. if (!isNaN(count))
  1485. rule.count = count;
  1486. var interval = parseInt(rule.interval);
  1487. rule.interval = isNaN(interval) ? 1 : interval;
  1488. if (rule.freq && rule.until)
  1489. rule.until = getDateByAsciiString(rule.until);
  1490. return rule
  1491. };
  1492. var getDateByAsciiString = function(string) {
  1493. var date = Globalize.parseDate(string, "yyyyMMddThhmmss");
  1494. if (!date)
  1495. date = Globalize.parseDate(string, "yyyyMMdd");
  1496. return date
  1497. };
  1498. var getAsciiStringByDate = function(date) {
  1499. return date.getFullYear() + ('0' + (date.getMonth() + 1)).slice(-2) + ('0' + date.getDate()).slice(-2)
  1500. };
  1501. var splitDateRules = function(rule) {
  1502. var result = [];
  1503. for (var field in dateSetterMap) {
  1504. if (!rule[field])
  1505. continue;
  1506. var ruleFieldValues = rule[field].split(","),
  1507. ruleArray = getDateRuleArray(field, ruleFieldValues);
  1508. result = result.length ? extendObjectArray(ruleArray, result) : ruleArray
  1509. }
  1510. return result
  1511. };
  1512. var getDateRuleArray = function(field, values) {
  1513. var result = [];
  1514. for (var i = 0, length = values.length; i < length; i++) {
  1515. var dateRule = {};
  1516. dateRule[field] = handleRuleFieldValue(field, values[i]);
  1517. result.push(dateRule)
  1518. }
  1519. return result
  1520. };
  1521. var days = {
  1522. SU: 0,
  1523. MO: 1,
  1524. TU: 2,
  1525. WE: 3,
  1526. TH: 4,
  1527. FR: 5,
  1528. SA: 6
  1529. };
  1530. var handleRuleFieldValue = function(field, value) {
  1531. var result = parseInt(value);
  1532. if (field === "bymonth")
  1533. result -= 1;
  1534. if (field === "byday")
  1535. result = days[value];
  1536. return result
  1537. };
  1538. var extendObjectArray = function(firstArray, secondArray) {
  1539. var result = [];
  1540. for (var i = 0, firstArrayLength = firstArray.length; i < firstArrayLength; i++)
  1541. for (var j = 0, secondArrayLength = secondArray.length; j < secondArrayLength; j++)
  1542. result.push($.extend({}, firstArray[i], secondArray[j]));
  1543. return result
  1544. };
  1545. var getDatesByRules = function(dateRules, startDate) {
  1546. var updatedDate = new Date(startDate),
  1547. result = [];
  1548. for (var i = 0, len = dateRules.length; i < len; i++) {
  1549. var current = dateRules[i];
  1550. for (var field in current)
  1551. dateSetterMap[field](updatedDate, current[field]);
  1552. result.push(new Date(updatedDate))
  1553. }
  1554. if (!result.length)
  1555. result.push(updatedDate);
  1556. return result
  1557. };
  1558. var checkDateByRule = function(date, rules) {
  1559. var result = false;
  1560. for (var i = 0; i < rules.length; i++) {
  1561. var current = rules[i],
  1562. currentRuleResult = true;
  1563. for (var field in current)
  1564. if (current[field] !== date[dateGetterMap[field]]())
  1565. currentRuleResult = false;
  1566. result = result || currentRuleResult
  1567. }
  1568. return result || !rules.length
  1569. };
  1570. var getRecurrenceString = function(object) {
  1571. if (!object || !object.freq)
  1572. return;
  1573. var result = "";
  1574. for (var field in object) {
  1575. if (field === "interval" && object[field] < 2)
  1576. continue;
  1577. result += field + "=" + object[field] + ";"
  1578. }
  1579. result = result.substring(0, result.length - 1);
  1580. return result.toUpperCase()
  1581. };
  1582. $.extend(DX.utils, {
  1583. getRecurrenceString: getRecurrenceString,
  1584. getRecurrenceRule: getRecurrenceRule,
  1585. getAsciiStringByDate: getAsciiStringByDate,
  1586. getDatesByRecurrence: getDatesByRecurrence,
  1587. dateInRecurrenceRange: dateInRecurrenceRange
  1588. })
  1589. })(jQuery, DevExpress);
  1590. /*! Module core, file utils.dom.js */
  1591. (function($, DX, undefined) {
  1592. var windowResizeCallbacks = function() {
  1593. var prevSize,
  1594. callbacks = $.Callbacks(),
  1595. jqWindow = $(window),
  1596. resizeEventHandlerAttached = false,
  1597. originalCallbacksAdd = callbacks.add,
  1598. originalCallbacksRemove = callbacks.remove;
  1599. var formatSize = function() {
  1600. return [jqWindow.width(), jqWindow.height()].join()
  1601. };
  1602. var handleResize = function() {
  1603. var now = formatSize();
  1604. if (now === prevSize)
  1605. return;
  1606. prevSize = now;
  1607. setTimeout(callbacks.fire)
  1608. };
  1609. prevSize = formatSize();
  1610. callbacks.add = function() {
  1611. var result = originalCallbacksAdd.apply(callbacks, arguments);
  1612. if (!resizeEventHandlerAttached && callbacks.has()) {
  1613. jqWindow.on("resize", handleResize);
  1614. resizeEventHandlerAttached = true
  1615. }
  1616. return result
  1617. };
  1618. callbacks.remove = function() {
  1619. var result = originalCallbacksRemove.apply(callbacks, arguments);
  1620. if (!callbacks.has() && resizeEventHandlerAttached) {
  1621. jqWindow.off("resize", handleResize);
  1622. resizeEventHandlerAttached = false
  1623. }
  1624. return result
  1625. };
  1626. return callbacks
  1627. }();
  1628. var resetActiveElement = function() {
  1629. var activeElement = document.activeElement;
  1630. if (activeElement && activeElement !== document.body && activeElement.blur)
  1631. activeElement.blur()
  1632. };
  1633. var createMarkupFromString = function(str) {
  1634. var tempElement = $("<div />");
  1635. if (window.WinJS)
  1636. WinJS.Utilities.setInnerHTMLUnsafe(tempElement.get(0), str);
  1637. else
  1638. tempElement.append(str);
  1639. return tempElement.contents()
  1640. };
  1641. var initMobileViewport = function(options) {
  1642. options = $.extend({}, options);
  1643. var device = DX.devices.current();
  1644. var realDevice = DX.devices.real();
  1645. var allowZoom = options.allowZoom,
  1646. allowPan = options.allowPan,
  1647. allowSelection = "allowSelection" in options ? options.allowSelection : device.platform === "generic";
  1648. var metaSelector = "meta[name=viewport]";
  1649. if (!$(metaSelector).length)
  1650. $("<meta />").attr("name", "viewport").appendTo("head");
  1651. var metaVerbs = ["width=device-width"],
  1652. msTouchVerbs = [];
  1653. if (allowZoom)
  1654. msTouchVerbs.push("pinch-zoom");
  1655. else
  1656. metaVerbs.push("initial-scale=1.0", "maximum-scale=1.0, user-scalable=no");
  1657. if (allowPan)
  1658. msTouchVerbs.push("pan-x", "pan-y");
  1659. if (!allowPan && !allowZoom)
  1660. $("html, body").css({
  1661. "-ms-content-zooming": "none",
  1662. "-ms-user-select": "none",
  1663. overflow: "hidden"
  1664. });
  1665. else
  1666. $("html").css("-ms-overflow-style", "-ms-autohiding-scrollbar");
  1667. if (!allowSelection && DX.support.supportProp("user-select"))
  1668. $(".dx-viewport").css(DX.support.styleProp("user-select"), "none");
  1669. $(metaSelector).attr("content", metaVerbs.join());
  1670. $("html").css("-ms-touch-action", msTouchVerbs.join(" ") || "none");
  1671. if (DX.support.touch)
  1672. $(document).off(".dxInitMobileViewport").on("dxpointermove.dxInitMobileViewport", function(e) {
  1673. var count = e.pointers.length,
  1674. isTouchEvent = e.pointerType === "touch",
  1675. zoomDisabled = !allowZoom && count > 1,
  1676. panDisabled = !allowPan && count === 1 && !e.isScrollingEvent;
  1677. if (isTouchEvent && (zoomDisabled || panDisabled))
  1678. e.preventDefault()
  1679. });
  1680. realDevice = DX.devices.real();
  1681. if (realDevice.ios) {
  1682. var isPhoneGap = document.location.protocol === "file:";
  1683. if (!isPhoneGap)
  1684. windowResizeCallbacks.add(function() {
  1685. var windowWidth = $(window).width();
  1686. $("body").width(windowWidth)
  1687. })
  1688. }
  1689. if (realDevice.android)
  1690. windowResizeCallbacks.add(function() {
  1691. document.activeElement.scrollIntoViewIfNeeded()
  1692. })
  1693. };
  1694. var triggerVisibilityChangeEvent = function(eventName) {
  1695. var VISIBILITY_CHANGE_SELECTOR = ".dx-visibility-change-handler";
  1696. return function(element) {
  1697. var $element = $(element || "body");
  1698. var $changeHandlers = $element.find(VISIBILITY_CHANGE_SELECTOR).add($element.filter(VISIBILITY_CHANGE_SELECTOR));
  1699. $changeHandlers.each(function() {
  1700. $(this).triggerHandler(eventName)
  1701. })
  1702. }
  1703. };
  1704. var uniqueId = function() {
  1705. var counter = 0;
  1706. return function(prefix) {
  1707. return (prefix || "") + counter++
  1708. }
  1709. }();
  1710. DX.dataOptionsAttributeName = "data-options";
  1711. var getElementOptions = function(element) {
  1712. var optionsString = $(element).attr(DX.dataOptionsAttributeName),
  1713. result;
  1714. if ($.trim(optionsString).charAt(0) !== "{")
  1715. optionsString = "{" + optionsString + "}";
  1716. try {
  1717. result = new Function("return " + optionsString)()
  1718. }
  1719. catch(ex) {
  1720. throw DX.Error("E3018", ex, optionsString);
  1721. }
  1722. return result
  1723. };
  1724. var createComponents = function(elements, componentTypes) {
  1725. var result = [],
  1726. selector = "[" + DX.dataOptionsAttributeName + "]";
  1727. elements.find(selector).addBack(selector).each(function(index, element) {
  1728. var $element = $(element),
  1729. options = getElementOptions(element);
  1730. for (var componentName in options)
  1731. if (!componentTypes || $.inArray(componentName, componentTypes) > -1)
  1732. if ($element[componentName]) {
  1733. $element[componentName](options[componentName]);
  1734. result.push($element[componentName]("instance"))
  1735. }
  1736. });
  1737. return result
  1738. };
  1739. var normalizeTemplateElement = function(element) {
  1740. var $element = DX.utils.isDefined(element) && (element.nodeType || element.jquery) ? $(element) : $("<div>").html(element).contents();
  1741. if ($element.length === 1 && $element.is("script"))
  1742. $element = normalizeTemplateElement(element.html());
  1743. return $element
  1744. };
  1745. var clearSelection = function() {
  1746. if (window.getSelection) {
  1747. if (window.getSelection().empty)
  1748. window.getSelection().empty();
  1749. else if (window.getSelection().removeAllRanges)
  1750. window.getSelection().removeAllRanges()
  1751. }
  1752. else if (document.selection)
  1753. document.selection.empty()
  1754. };
  1755. var closestCommonParent = function(startTarget, endTarget) {
  1756. var $startParents = $(startTarget).parents().addBack(),
  1757. $endParents = $(endTarget).parents().addBack(),
  1758. startingParent = Math.min($startParents.length, $endParents.length) - 1;
  1759. for (var i = startingParent; i >= 0; i--)
  1760. if ($startParents.eq(i).is($endParents.eq(i)))
  1761. return $startParents.get(i)
  1762. };
  1763. var toggleAttr = function($target, attr, value) {
  1764. value ? $target.attr(attr, value) : $target.removeAttr(attr)
  1765. };
  1766. var clipboardText = function(event, text) {
  1767. var clipboard = event.originalEvent && event.originalEvent.clipboardData || window.clipboardData;
  1768. if (arguments.length === 1)
  1769. return clipboard && clipboard.getData("Text");
  1770. clipboard && clipboard.setData("Text", text)
  1771. };
  1772. $.extend(DX.utils, {
  1773. windowResizeCallbacks: windowResizeCallbacks,
  1774. resetActiveElement: resetActiveElement,
  1775. createMarkupFromString: createMarkupFromString,
  1776. triggerShownEvent: triggerVisibilityChangeEvent("dxshown"),
  1777. triggerHidingEvent: triggerVisibilityChangeEvent("dxhiding"),
  1778. initMobileViewport: initMobileViewport,
  1779. getElementOptions: getElementOptions,
  1780. createComponents: createComponents,
  1781. normalizeTemplateElement: normalizeTemplateElement,
  1782. clearSelection: clearSelection,
  1783. uniqueId: uniqueId,
  1784. closestCommonParent: closestCommonParent,
  1785. clipboardText: clipboardText,
  1786. toggleAttr: toggleAttr
  1787. })
  1788. })(jQuery, DevExpress);
  1789. /*! Module core, file utils.caret.js */
  1790. (function($, DX, undefined) {
  1791. var getCaret = function(input) {
  1792. if (isObsoleteBrowser(input))
  1793. return getCaretForObsoleteBrowser(input);
  1794. return {
  1795. start: input.selectionStart,
  1796. end: input.selectionEnd
  1797. }
  1798. };
  1799. var setCaret = function(input, position) {
  1800. if (isObsoleteBrowser(input)) {
  1801. setCaretForObsoleteBrowser(input, position);
  1802. return
  1803. }
  1804. if (!$.contains(document, input))
  1805. return;
  1806. input.selectionStart = position.start;
  1807. input.selectionEnd = position.end
  1808. };
  1809. var isObsoleteBrowser = function(input) {
  1810. return !input.setSelectionRange
  1811. };
  1812. var getCaretForObsoleteBrowser = function(input) {
  1813. var range = document.selection.createRange();
  1814. var rangeCopy = range.duplicate();
  1815. range.move('character', -input.value.length);
  1816. range.setEndPoint('EndToStart', rangeCopy);
  1817. return {
  1818. start: range.text.length,
  1819. end: range.text.length + rangeCopy.text.length
  1820. }
  1821. };
  1822. var setCaretForObsoleteBrowser = function(input, position) {
  1823. var range = input.createTextRange();
  1824. range.collapse(true);
  1825. range.moveStart("character", position.start);
  1826. range.moveEnd("character", position.end - position.start);
  1827. range.select()
  1828. };
  1829. var caret = function(input, position) {
  1830. input = $(input).get(0);
  1831. if (!DX.utils.isDefined(position))
  1832. return getCaret(input);
  1833. setCaret(input, position)
  1834. };
  1835. $.extend(DX.utils, {caret: caret})
  1836. })(jQuery, DevExpress);
  1837. /*! Module core, file utils.graphics.js */
  1838. (function($, DX, undefined) {
  1839. var _utils = DX.utils,
  1840. isFunction = _utils.isFunction,
  1841. _inArray = $.inArray,
  1842. isDefined = _utils.isDefined;
  1843. var processSeriesTemplate = function(seriesTemplate, items) {
  1844. var customizeSeries = isFunction(seriesTemplate.customizeSeries) ? seriesTemplate.customizeSeries : $.noop,
  1845. nameField = seriesTemplate.nameField || 'series',
  1846. generatedSeries = {},
  1847. seriesOrder = [],
  1848. series;
  1849. for (var i = 0, length = items.length; i < length; i++) {
  1850. var data = items[i];
  1851. if (nameField in data) {
  1852. series = generatedSeries[data[nameField]];
  1853. if (!series) {
  1854. series = generatedSeries[data[nameField]] = {
  1855. name: data[nameField],
  1856. data: []
  1857. };
  1858. seriesOrder.push(series.name)
  1859. }
  1860. series.data.push(data)
  1861. }
  1862. }
  1863. return $.map(seriesOrder, function(orderedName) {
  1864. var group = generatedSeries[orderedName],
  1865. seriesOptions = customizeSeries.call(null, group.name);
  1866. return $.extend(group, seriesOptions)
  1867. })
  1868. };
  1869. var getCategoriesInfo = function(categories, startValue, endValue) {
  1870. if (!(categories && categories.length > 0))
  1871. return {};
  1872. startValue = isDefined(startValue) ? startValue : categories[0];
  1873. endValue = isDefined(endValue) ? endValue : categories[categories.length - 1];
  1874. var categoriesValue = $.map(categories, function(category) {
  1875. return category && category.valueOf()
  1876. }),
  1877. visibleCategories = [],
  1878. indexStartValue = isDefined(startValue) ? _inArray(startValue.valueOf(), categoriesValue) : 0,
  1879. indexEndValue = isDefined(endValue) ? _inArray(endValue.valueOf(), categoriesValue) : categories.length - 1,
  1880. swapBuf,
  1881. hasVisibleCategories,
  1882. inverted = false,
  1883. visibleCategoriesLen;
  1884. indexStartValue < 0 && (indexStartValue = 0);
  1885. indexEndValue < 0 && (indexEndValue = categories.length - 1);
  1886. if (indexEndValue < indexStartValue) {
  1887. swapBuf = indexEndValue;
  1888. indexEndValue = indexStartValue;
  1889. indexStartValue = swapBuf;
  1890. inverted = true
  1891. }
  1892. visibleCategories = categories.slice(indexStartValue, indexEndValue + 1);
  1893. visibleCategoriesLen = visibleCategories.length;
  1894. hasVisibleCategories = visibleCategoriesLen > 0;
  1895. return {
  1896. categories: hasVisibleCategories ? visibleCategories : null,
  1897. start: hasVisibleCategories ? visibleCategories[inverted ? visibleCategoriesLen - 1 : 0] : null,
  1898. end: hasVisibleCategories ? visibleCategories[inverted ? 0 : visibleCategoriesLen - 1] : null,
  1899. inverted: inverted
  1900. }
  1901. };
  1902. $.extend(_utils, {
  1903. processSeriesTemplate: processSeriesTemplate,
  1904. getCategoriesInfo: getCategoriesInfo
  1905. })
  1906. })(jQuery, DevExpress);
  1907. /*! Module core, file utils.arrays.js */
  1908. (function($, DX, undefined) {
  1909. var isEmptyArray = function(entity) {
  1910. return $.isArray(entity) && !entity.length
  1911. };
  1912. var wrapToArray = function(entity) {
  1913. return $.isArray(entity) ? entity : [entity]
  1914. };
  1915. var removeDublicates = function(from, what) {
  1916. if (!$.isArray(from) || from.length === 0)
  1917. return [];
  1918. if (!$.isArray(what) || what.length === 0)
  1919. return from.slice();
  1920. var result = [];
  1921. $.each(from, function(_, value) {
  1922. var bIndex = $.inArray(value, what);
  1923. if (bIndex === -1)
  1924. result.push(value)
  1925. });
  1926. return result
  1927. };
  1928. $.extend(DX.utils, {
  1929. isEmptyArray: isEmptyArray,
  1930. wrapToArray: wrapToArray,
  1931. removeDublicates: removeDublicates
  1932. })
  1933. })(jQuery, DevExpress);
  1934. /*! Module core, file devices.js */
  1935. (function($, DX, undefined) {
  1936. var KNOWN_UA_TABLE = {
  1937. iPhone: "iPhone",
  1938. iPhone5: "iPhone",
  1939. iPhone6: "iPhone",
  1940. iPhone6plus: "iPhone",
  1941. iPad: "iPad",
  1942. iPadMini: "iPad Mini",
  1943. androidPhone: "Android Mobile",
  1944. androidTablet: "Android",
  1945. win8: "MSAppHost",
  1946. win8Phone: "Windows Phone 8",
  1947. msSurface: "MSIE ARM Tablet PC",
  1948. desktop: "desktop"
  1949. };
  1950. var DEFAULT_DEVICE = {
  1951. deviceType: "",
  1952. platform: "",
  1953. version: [],
  1954. phone: false,
  1955. tablet: false,
  1956. android: false,
  1957. ios: false,
  1958. win8: false,
  1959. generic: false,
  1960. grade: "A",
  1961. mac: false
  1962. };
  1963. $.extend(DEFAULT_DEVICE, {
  1964. platform: "generic",
  1965. deviceType: "desktop",
  1966. generic: true
  1967. });
  1968. var uaParsers = {
  1969. win8: function(userAgent) {
  1970. var isPhone = /windows phone/i.test(userAgent) || userAgent.match(/WPDesktop/),
  1971. isTablet = !isPhone && /arm(.*)trident/i.test(userAgent),
  1972. isDesktop = !isPhone && !isTablet && /msapphost/i.test(userAgent);
  1973. if (!(isPhone || isTablet || isDesktop))
  1974. return;
  1975. var matches = userAgent.match(/windows phone (\d+).(\d+)/i) || userAgent.match(/windows nt (\d+).(\d+)/i),
  1976. version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10)] : [];
  1977. return {
  1978. deviceType: isPhone ? "phone" : isTablet ? "tablet" : "desktop",
  1979. platform: "win8",
  1980. version: version,
  1981. grade: "A"
  1982. }
  1983. },
  1984. ios: function(userAgent) {
  1985. if (!/ip(hone|od|ad)/i.test(userAgent))
  1986. return;
  1987. var isPhone = /ip(hone|od)/i.test(userAgent),
  1988. matches = userAgent.match(/os (\d+)_(\d+)_?(\d+)?/i),
  1989. version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],
  1990. isIPhone4 = window.screen.height === 960 / 2,
  1991. grade = isIPhone4 ? "B" : "A";
  1992. return {
  1993. deviceType: isPhone ? "phone" : "tablet",
  1994. platform: "ios",
  1995. version: version,
  1996. grade: grade
  1997. }
  1998. },
  1999. android: function(userAgent) {
  2000. if (!/android|htc_|silk/i.test(userAgent))
  2001. return;
  2002. var isPhone = /mobile/i.test(userAgent),
  2003. matches = userAgent.match(/android (\d+)\.(\d+)\.?(\d+)?/i),
  2004. version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [],
  2005. worseThan4_4 = version.length > 1 && (version[0] < 4 || version[0] === 4 && version[1] < 4),
  2006. grade = worseThan4_4 ? "B" : "A";
  2007. return {
  2008. deviceType: isPhone ? "phone" : "tablet",
  2009. platform: "android",
  2010. version: version,
  2011. grade: grade
  2012. }
  2013. }
  2014. };
  2015. DX.Devices = DX.Class.inherit({
  2016. ctor: function(options) {
  2017. this._window = options && options.window || window;
  2018. this._realDevice = this._getDevice();
  2019. this._currentDevice = undefined;
  2020. this._currentOrientation = undefined;
  2021. this.orientationChanged = $.Callbacks();
  2022. this._callbacksToEvents("Devices", ["orientationChanged"]);
  2023. this._recalculateOrientation();
  2024. DX.utils.windowResizeCallbacks.add($.proxy(this._recalculateOrientation, this))
  2025. },
  2026. current: function(deviceOrName) {
  2027. if (deviceOrName) {
  2028. this._currentDevice = this._getDevice(deviceOrName);
  2029. this._forced = true;
  2030. DX.ui.themes.init({_autoInit: true})
  2031. }
  2032. else {
  2033. if (!this._currentDevice) {
  2034. deviceOrName = undefined;
  2035. try {
  2036. deviceOrName = this._getDeviceOrNameFromWindowScope()
  2037. }
  2038. catch(e) {
  2039. deviceOrName = this._getDeviceNameFromSessionStorage()
  2040. }
  2041. finally {
  2042. if (!deviceOrName)
  2043. deviceOrName = this._getDeviceNameFromSessionStorage();
  2044. if (deviceOrName)
  2045. this._forced = true
  2046. }
  2047. this._currentDevice = this._getDevice(deviceOrName)
  2048. }
  2049. return this._currentDevice
  2050. }
  2051. },
  2052. real: function() {
  2053. var forceDevice = arguments[0];
  2054. if ($.isPlainObject(forceDevice)) {
  2055. $.extend(this._realDevice, forceDevice);
  2056. return
  2057. }
  2058. return $.extend({}, this._realDevice)
  2059. },
  2060. orientation: function() {
  2061. return this._currentOrientation
  2062. },
  2063. isForced: function() {
  2064. return this._forced
  2065. },
  2066. isRippleEmulator: function() {
  2067. return !!this._window.tinyHippos
  2068. },
  2069. _getCssClasses: function(device) {
  2070. var result = [];
  2071. var realDevice = this._realDevice;
  2072. device = device || this.current();
  2073. if (device.deviceType) {
  2074. result.push("dx-device-" + device.deviceType);
  2075. if (device.deviceType !== "desktop")
  2076. result.push("dx-device-mobile")
  2077. }
  2078. result.push("dx-device-" + realDevice.platform);
  2079. if (realDevice.version && realDevice.version.length)
  2080. result.push("dx-device-" + realDevice.platform + "-" + realDevice.version[0]);
  2081. if (DX.devices.isSimulator())
  2082. result.push("dx-simulator");
  2083. if (DX.rtlEnabled)
  2084. result.push("dx-rtl");
  2085. return result
  2086. },
  2087. attachCssClasses: function(element, device) {
  2088. this._deviceClasses = this._getCssClasses(device).join(" ");
  2089. $(element).addClass(this._deviceClasses)
  2090. },
  2091. detachCssClasses: function(element) {
  2092. $(element).removeClass(this._deviceClasses)
  2093. },
  2094. isSimulator: function() {
  2095. try {
  2096. return this._isSimulator || this._window.top !== this._window.self && this._window.top["dx-force-device"] || this.isRippleEmulator()
  2097. }
  2098. catch(e) {
  2099. return false
  2100. }
  2101. },
  2102. forceSimulator: function() {
  2103. this._isSimulator = true
  2104. },
  2105. _getDevice: function(deviceName) {
  2106. if (deviceName === "genericPhone")
  2107. deviceName = {
  2108. deviceType: "phone",
  2109. platform: "generic",
  2110. generic: true
  2111. };
  2112. if ($.isPlainObject(deviceName))
  2113. return this._fromConfig(deviceName);
  2114. else {
  2115. var ua;
  2116. if (deviceName) {
  2117. ua = KNOWN_UA_TABLE[deviceName];
  2118. if (!ua)
  2119. throw DX.Error("E0005");
  2120. }
  2121. else
  2122. ua = navigator.userAgent;
  2123. return this._fromUA(ua)
  2124. }
  2125. },
  2126. _getDeviceOrNameFromWindowScope: function() {
  2127. var result;
  2128. if (this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"])
  2129. result = this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"];
  2130. return result
  2131. },
  2132. _getDeviceNameFromSessionStorage: function() {
  2133. var sessionStorage;
  2134. try {
  2135. sessionStorage = this._window.sessionStorage
  2136. }
  2137. catch(e) {}
  2138. if (!sessionStorage)
  2139. return;
  2140. var deviceOrName = sessionStorage.getItem("dx-force-device");
  2141. try {
  2142. return $.parseJSON(deviceOrName)
  2143. }
  2144. catch(ex) {
  2145. return deviceOrName
  2146. }
  2147. },
  2148. _fromConfig: function(config) {
  2149. var shortcuts = {
  2150. phone: config.deviceType === "phone",
  2151. tablet: config.deviceType === "tablet",
  2152. android: config.platform === "android",
  2153. ios: config.platform === "ios",
  2154. win8: config.platform === "win8",
  2155. generic: config.platform === "generic"
  2156. };
  2157. return $.extend({}, DEFAULT_DEVICE, this._currentDevice, shortcuts, config)
  2158. },
  2159. _fromUA: function(ua) {
  2160. var config;
  2161. $.each(uaParsers, function(platform, parser) {
  2162. config = parser(ua);
  2163. return !config
  2164. });
  2165. if (config)
  2166. return this._fromConfig(config);
  2167. var isMac = /(mac os)/.test(ua.toLowerCase()),
  2168. deviceWithOS = DEFAULT_DEVICE;
  2169. deviceWithOS.mac = isMac;
  2170. return deviceWithOS
  2171. },
  2172. _changeOrientation: function() {
  2173. var $window = $(this._window),
  2174. orientation = $window.height() > $window.width() ? "portrait" : "landscape";
  2175. if (this._currentOrientation === orientation)
  2176. return;
  2177. this._currentOrientation = orientation;
  2178. this.orientationChanged.fire({orientation: orientation})
  2179. },
  2180. _recalculateOrientation: function() {
  2181. var windowWidth = $(this._window).width();
  2182. if (this._currentWidth === windowWidth)
  2183. return;
  2184. this._currentWidth = windowWidth;
  2185. this._changeOrientation()
  2186. }
  2187. }).include(DX.EventsMixin);
  2188. DX.devices = new DX.Devices;
  2189. DX.viewPortChanged.add(function(viewPort, prevViewport) {
  2190. DX.devices.detachCssClasses(prevViewport);
  2191. DX.devices.attachCssClasses(viewPort)
  2192. })
  2193. })(jQuery, DevExpress);
  2194. /*! Module core, file browser.js */
  2195. (function($, DX, global, undefined) {
  2196. var webkitRegExp = /(webkit)[ \/]([\w.]+)/,
  2197. operaRegExp = /(opera)(?:.*version)?[ \/]([\w.]+)/,
  2198. ieRegExp = /(msie) (\d{1,2}\.\d)/,
  2199. ie11RegExp = /(trident).*rv:(\d{1,2}\.\d)/,
  2200. mozillaRegExp = /(mozilla)(?:.*? rv:([\w.]+))?/;
  2201. var ua = navigator.userAgent.toLowerCase();
  2202. var browser = function() {
  2203. var result = {},
  2204. matches = webkitRegExp.exec(ua) || operaRegExp.exec(ua) || ieRegExp.exec(ua) || ie11RegExp.exec(ua) || ua.indexOf("compatible") < 0 && mozillaRegExp.exec(ua) || [],
  2205. browserName = matches[1],
  2206. browserVersion = matches[2];
  2207. if (browserName === "trident")
  2208. browserName = "msie";
  2209. if (browserName) {
  2210. result[browserName] = true;
  2211. result.version = browserVersion
  2212. }
  2213. return result
  2214. }();
  2215. DX.browser = browser
  2216. })(jQuery, DevExpress, this);
  2217. /*! Module core, file support.js */
  2218. (function($, DX, window) {
  2219. var jsPrefixes = ["", "Webkit", "Moz", "O", "Ms"],
  2220. cssPrefixes = {
  2221. "": "",
  2222. Webkit: "-webkit-",
  2223. Moz: "-moz-",
  2224. O: "-o-",
  2225. ms: "-ms-"
  2226. },
  2227. styles = document.createElement("dx").style;
  2228. var transitionEndEventNames = {
  2229. webkitTransition: 'webkitTransitionEnd',
  2230. MozTransition: 'transitionend',
  2231. OTransition: 'oTransitionEnd',
  2232. msTransition: 'MsTransitionEnd',
  2233. transition: 'transitionend'
  2234. };
  2235. var forEachPrefixes = function(prop, callBack) {
  2236. prop = DX.inflector.camelize(prop, true);
  2237. var result;
  2238. for (var i = 0, cssPrefixesCount = jsPrefixes.length; i < cssPrefixesCount; i++) {
  2239. var jsPrefix = jsPrefixes[i];
  2240. var prefixedProp = jsPrefix + prop;
  2241. var lowerPrefixedProp = DX.inflector.camelize(prefixedProp);
  2242. result = callBack(lowerPrefixedProp, jsPrefix);
  2243. if (result === undefined)
  2244. result = callBack(prefixedProp, jsPrefix);
  2245. if (result !== undefined)
  2246. break
  2247. }
  2248. return result
  2249. };
  2250. var styleProp = function(prop) {
  2251. return forEachPrefixes(prop, function(specific) {
  2252. if (specific in styles)
  2253. return specific
  2254. })
  2255. };
  2256. var stylePropPrefix = function(prop) {
  2257. return forEachPrefixes(prop, function(specific, jsPrefix) {
  2258. if (specific in styles)
  2259. return cssPrefixes[jsPrefix]
  2260. })
  2261. };
  2262. var supportProp = function(prop) {
  2263. return !!styleProp(prop)
  2264. };
  2265. var isNativeScrollingSupported = function() {
  2266. var realDevice = DX.devices.real(),
  2267. realPlatform = realDevice.platform,
  2268. realVersion = realDevice.version,
  2269. isObsoleteAndroid = realVersion && realVersion[0] < 4 && realPlatform === "android",
  2270. isNativeScrollDevice = !isObsoleteAndroid && $.inArray(realPlatform, ["ios", "android", "win8"]) > -1 || realDevice.mac;
  2271. return isNativeScrollDevice
  2272. };
  2273. DX.support = {
  2274. touchEvents: "ontouchstart" in window,
  2275. touch: "ontouchstart" in window || !!window.navigator.msMaxTouchPoints,
  2276. pointer: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
  2277. transform: supportProp("transform"),
  2278. transition: supportProp("transition"),
  2279. transitionEndEventName: transitionEndEventNames[styleProp("transition")],
  2280. animation: supportProp("animation"),
  2281. nativeScrolling: isNativeScrollingSupported(),
  2282. winJS: "WinJS" in window,
  2283. styleProp: styleProp,
  2284. stylePropPrefix: stylePropPrefix,
  2285. supportProp: supportProp,
  2286. hasKo: !!window.ko,
  2287. hasNg: !window.ko && !!window.angular,
  2288. inputType: function(type) {
  2289. if (type === "text")
  2290. return true;
  2291. var input = document.createElement("input");
  2292. try {
  2293. input.setAttribute("type", type);
  2294. input.value = "wrongValue";
  2295. return !input.value
  2296. }
  2297. catch(e) {
  2298. return false
  2299. }
  2300. }
  2301. }
  2302. })(jQuery, DevExpress, this);
  2303. /*! Module core, file position.js */
  2304. (function($, DX, undefined) {
  2305. var horzRe = /left|right/,
  2306. vertRe = /top|bottom/,
  2307. collisionRe = /fit|flip|none/;
  2308. var normalizeAlign = function(raw) {
  2309. var result = {
  2310. h: "center",
  2311. v: "center"
  2312. };
  2313. var pair = DX.utils.splitPair(raw);
  2314. if (pair)
  2315. $.each(pair, function() {
  2316. var w = String(this).toLowerCase();
  2317. if (horzRe.test(w))
  2318. result.h = w;
  2319. else if (vertRe.test(w))
  2320. result.v = w
  2321. });
  2322. return result
  2323. };
  2324. var normalizeOffset = function(raw) {
  2325. return DX.utils.stringPairToObject(raw)
  2326. };
  2327. var normalizeCollision = function(raw) {
  2328. var pair = DX.utils.splitPair(raw),
  2329. h = String(pair && pair[0]).toLowerCase(),
  2330. v = String(pair && pair[1]).toLowerCase();
  2331. if (!collisionRe.test(h))
  2332. h = "none";
  2333. if (!collisionRe.test(v))
  2334. v = h;
  2335. return {
  2336. h: h,
  2337. v: v
  2338. }
  2339. };
  2340. var getAlignFactor = function(align) {
  2341. switch (align) {
  2342. case"center":
  2343. return 0.5;
  2344. case"right":
  2345. case"bottom":
  2346. return 1;
  2347. default:
  2348. return 0
  2349. }
  2350. };
  2351. var inverseAlign = function(align) {
  2352. switch (align) {
  2353. case"left":
  2354. return "right";
  2355. case"right":
  2356. return "left";
  2357. case"top":
  2358. return "bottom";
  2359. case"bottom":
  2360. return "top";
  2361. default:
  2362. return align
  2363. }
  2364. };
  2365. var calculateOversize = function(data, bounds) {
  2366. var oversize = 0;
  2367. if (data.myLocation < bounds.min)
  2368. oversize += bounds.min - data.myLocation;
  2369. if (data.myLocation > bounds.max)
  2370. oversize += data.myLocation - bounds.max;
  2371. return oversize
  2372. };
  2373. var initMyLocation = function(data) {
  2374. data.myLocation = data.atLocation + getAlignFactor(data.atAlign) * data.atSize - getAlignFactor(data.myAlign) * data.mySize + data.offset
  2375. };
  2376. var decolliders = {
  2377. fit: function(data, bounds) {
  2378. var result = false;
  2379. if (data.myLocation > bounds.max) {
  2380. data.myLocation = bounds.max;
  2381. result = true
  2382. }
  2383. if (data.myLocation < bounds.min) {
  2384. data.myLocation = bounds.min;
  2385. result = true
  2386. }
  2387. return result
  2388. },
  2389. flip: function(data, bounds) {
  2390. if (data.myAlign === "center" && data.atAlign === "center")
  2391. return false;
  2392. if (data.myLocation < bounds.min || data.myLocation > bounds.max) {
  2393. var inverseData = $.extend({}, data, {
  2394. myAlign: inverseAlign(data.myAlign),
  2395. atAlign: inverseAlign(data.atAlign),
  2396. offset: -data.offset
  2397. });
  2398. initMyLocation(inverseData);
  2399. inverseData.oversize = calculateOversize(inverseData, bounds);
  2400. if (inverseData.myLocation >= bounds.min && inverseData.myLocation <= bounds.max || inverseData.myLocation > data.myLocation || inverseData.oversize < data.oversize) {
  2401. data.myLocation = inverseData.myLocation;
  2402. data.oversize = inverseData.oversize;
  2403. return true
  2404. }
  2405. }
  2406. return false
  2407. }
  2408. };
  2409. var scrollbarWidth;
  2410. var defaultPositionResult = {
  2411. h: {
  2412. location: 0,
  2413. flip: false,
  2414. fit: false,
  2415. oversize: 0
  2416. },
  2417. v: {
  2418. location: 0,
  2419. flip: false,
  2420. fit: false,
  2421. oversize: 0
  2422. }
  2423. };
  2424. var calculatePosition = function(what, options) {
  2425. var $what = $(what),
  2426. currentOffset = $what.offset(),
  2427. result = $.extend(true, {}, defaultPositionResult, {
  2428. h: {location: currentOffset.left},
  2429. v: {location: currentOffset.top}
  2430. });
  2431. if (!options)
  2432. return result;
  2433. var my = normalizeAlign(options.my),
  2434. at = normalizeAlign(options.at),
  2435. of = options.of || window,
  2436. offset = normalizeOffset(options.offset),
  2437. collision = normalizeCollision(options.collision),
  2438. boundary = options.boundary,
  2439. boundaryOffset = normalizeOffset(options.boundaryOffset);
  2440. var h = {
  2441. mySize: $what.outerWidth(),
  2442. myAlign: my.h,
  2443. atAlign: at.h,
  2444. offset: offset.h,
  2445. collision: collision.h,
  2446. boundaryOffset: boundaryOffset.h
  2447. };
  2448. var v = {
  2449. mySize: $what.outerHeight(),
  2450. myAlign: my.v,
  2451. atAlign: at.v,
  2452. offset: offset.v,
  2453. collision: collision.v,
  2454. boundaryOffset: boundaryOffset.v
  2455. };
  2456. if (of.preventDefault) {
  2457. h.atLocation = of.pageX;
  2458. v.atLocation = of.pageY;
  2459. h.atSize = 0;
  2460. v.atSize = 0
  2461. }
  2462. else {
  2463. of = $(of);
  2464. if ($.isWindow(of[0])) {
  2465. h.atLocation = of.scrollLeft();
  2466. v.atLocation = of.scrollTop();
  2467. h.atSize = of.width();
  2468. v.atSize = of.height()
  2469. }
  2470. else if (of[0].nodeType === 9) {
  2471. h.atLocation = 0;
  2472. v.atLocation = 0;
  2473. h.atSize = of.width();
  2474. v.atSize = of.height()
  2475. }
  2476. else {
  2477. var o = of.offset();
  2478. h.atLocation = o.left;
  2479. v.atLocation = o.top;
  2480. h.atSize = of.outerWidth();
  2481. v.atSize = of.outerHeight()
  2482. }
  2483. }
  2484. initMyLocation(h);
  2485. initMyLocation(v);
  2486. var bounds = function() {
  2487. var win = $(window),
  2488. windowWidth = win.width(),
  2489. windowHeight = win.height(),
  2490. left = win.scrollLeft(),
  2491. top = win.scrollTop(),
  2492. hScrollbar = document.width > document.documentElement.clientWidth,
  2493. vScrollbar = document.height > document.documentElement.clientHeight,
  2494. hZoomLevel = DX.support.touch ? document.documentElement.clientWidth / (vScrollbar ? windowWidth - scrollbarWidth : windowWidth) : 1,
  2495. vZoomLevel = DX.support.touch ? document.documentElement.clientHeight / (hScrollbar ? windowHeight - scrollbarWidth : windowHeight) : 1;
  2496. if (scrollbarWidth === undefined)
  2497. scrollbarWidth = calculateScrollbarWidth();
  2498. var boundaryWidth = windowWidth,
  2499. boundaryHeight = windowHeight;
  2500. if (boundary) {
  2501. var $boundary = $(boundary),
  2502. boundaryPosition = $boundary.offset();
  2503. left = boundaryPosition.left;
  2504. top = boundaryPosition.top;
  2505. boundaryWidth = $boundary.width();
  2506. boundaryHeight = $boundary.height()
  2507. }
  2508. return {
  2509. h: {
  2510. min: left + h.boundaryOffset,
  2511. max: left + boundaryWidth / hZoomLevel - h.mySize - h.boundaryOffset
  2512. },
  2513. v: {
  2514. min: top + v.boundaryOffset,
  2515. max: top + boundaryHeight / vZoomLevel - v.mySize - v.boundaryOffset
  2516. }
  2517. }
  2518. }();
  2519. h.oversize = calculateOversize(h, bounds.h);
  2520. v.oversize = calculateOversize(v, bounds.v);
  2521. if (decolliders[h.collision])
  2522. result.h[h.collision] = decolliders[h.collision](h, bounds.h);
  2523. if (decolliders[v.collision])
  2524. result.v[v.collision] = decolliders[v.collision](v, bounds.v);
  2525. var preciser = function(number) {
  2526. return options.precise ? number : Math.round(number)
  2527. };
  2528. $.extend(true, result, {
  2529. h: {
  2530. location: preciser(h.myLocation),
  2531. oversize: preciser(h.oversize)
  2532. },
  2533. v: {
  2534. location: preciser(v.myLocation),
  2535. oversize: preciser(v.oversize)
  2536. },
  2537. precise: options.precise
  2538. });
  2539. return result
  2540. };
  2541. var position = function(what, options) {
  2542. var $what = $(what);
  2543. if (!options)
  2544. return $what.offset();
  2545. DX.translator.resetPosition($what);
  2546. var offset = $what.offset(),
  2547. targetPosition = options.h && options.v ? options : calculatePosition($what, options);
  2548. var preciser = function(number) {
  2549. return options.precise ? number : Math.round(number)
  2550. };
  2551. DX.translator.move($what, {
  2552. left: targetPosition.h.location - preciser(offset.left),
  2553. top: targetPosition.v.location - preciser(offset.top)
  2554. });
  2555. return targetPosition
  2556. };
  2557. $.extend(DX, {
  2558. calculatePosition: calculatePosition,
  2559. position: position
  2560. });
  2561. $.extend(DX.position, {
  2562. inverseAlign: inverseAlign,
  2563. normalizeAlign: normalizeAlign
  2564. });
  2565. var calculateScrollbarWidth = function() {
  2566. var $scrollDiv = $("<div>").css({
  2567. width: 100,
  2568. height: 100,
  2569. overflow: "scroll",
  2570. position: "absolute",
  2571. top: -9999
  2572. }).appendTo($("body")),
  2573. result = $scrollDiv.get(0).offsetWidth - $scrollDiv.get(0).clientWidth;
  2574. $scrollDiv.remove();
  2575. return result
  2576. }
  2577. })(jQuery, DevExpress);
  2578. /*! Module core, file action.js */
  2579. (function($, DX, undefined) {
  2580. var actionExecutors = {};
  2581. var registerExecutor = function(name, executor) {
  2582. if ($.isPlainObject(name)) {
  2583. $.each(name, registerExecutor);
  2584. return
  2585. }
  2586. actionExecutors[name] = executor
  2587. };
  2588. var unregisterExecutor = function() {
  2589. var args = $.makeArray(arguments);
  2590. $.each(args, function() {
  2591. delete actionExecutors[this]
  2592. })
  2593. };
  2594. registerExecutor({
  2595. func: {execute: function(e) {
  2596. if ($.isFunction(e.action)) {
  2597. e.result = e.action.apply(e.context, e.args);
  2598. e.handled = true
  2599. }
  2600. }},
  2601. url: {execute: function(e) {
  2602. if (typeof e.action === "string" && e.action.charAt(0) !== "#")
  2603. document.location = e.action
  2604. }},
  2605. hash: {execute: function(e) {
  2606. if (typeof e.action === "string" && e.action.charAt(0) === "#")
  2607. document.location.hash = e.action
  2608. }}
  2609. });
  2610. var Action = DX.Class.inherit({
  2611. ctor: function(action, config) {
  2612. config = config || {};
  2613. this._action = action || $.noop;
  2614. this._context = config.context || window;
  2615. this._beforeExecute = config.beforeExecute || $.noop;
  2616. this._afterExecute = config.afterExecute || $.noop;
  2617. this._component = config.component;
  2618. this._excludeValidators = config.excludeValidators;
  2619. this._validatingTargetName = config.validatingTargetName
  2620. },
  2621. execute: function() {
  2622. var e = {
  2623. action: this._action,
  2624. args: Array.prototype.slice.call(arguments),
  2625. context: this._context,
  2626. component: this._component,
  2627. validatingTargetName: this._validatingTargetName,
  2628. cancel: false,
  2629. handled: false
  2630. };
  2631. if (!this._validateAction(e))
  2632. return;
  2633. this._beforeExecute.call(this._context, e);
  2634. if (e.cancel)
  2635. return;
  2636. var result = this._executeAction(e);
  2637. this._afterExecute.call(this._context, e);
  2638. return result
  2639. },
  2640. _validateAction: function(e) {
  2641. var excludeValidators = this._excludeValidators;
  2642. $.each(actionExecutors, function(name, executor) {
  2643. if (excludeValidators && $.inArray(name, excludeValidators) > -1)
  2644. return;
  2645. if (executor.validate)
  2646. executor.validate(e);
  2647. if (e.cancel)
  2648. return false
  2649. });
  2650. return !e.cancel
  2651. },
  2652. _executeAction: function(e) {
  2653. var result;
  2654. $.each(actionExecutors, function(index, executor) {
  2655. if (executor.execute)
  2656. executor.execute(e);
  2657. if (e.handled) {
  2658. result = e.result;
  2659. return false
  2660. }
  2661. });
  2662. return result
  2663. }
  2664. });
  2665. $.extend(DX, {
  2666. registerActionExecutor: registerExecutor,
  2667. unregisterActionExecutor: unregisterExecutor,
  2668. Action: Action
  2669. });
  2670. DX.__internals = {actionExecutors: actionExecutors}
  2671. })(jQuery, DevExpress);
  2672. /*! Module core, file translator.js */
  2673. (function($, DX, undefined) {
  2674. var support = DX.support,
  2675. TRANSLATOR_DATA_KEY = "dxTranslator",
  2676. TRANSFORM_MATRIX_REGEX = /matrix(3d)?\((.+?)\)/,
  2677. TRANSLATE_REGEX = /translate(?:3d)?\((.+?)\)/;
  2678. var locate = function($element) {
  2679. var translate = support.transform ? getTranslate($element) : getTranslateFallback($element);
  2680. return {
  2681. left: translate.x,
  2682. top: translate.y
  2683. }
  2684. };
  2685. var move = function($element, position) {
  2686. if (!support.transform) {
  2687. $element.css(position);
  2688. return
  2689. }
  2690. var translate = getTranslate($element),
  2691. left = position.left,
  2692. top = position.top;
  2693. if (left !== undefined)
  2694. translate.x = left || 0;
  2695. if (top !== undefined)
  2696. translate.y = top || 0;
  2697. $element.css({transform: getTranslateCss(translate)});
  2698. if (isPersentValue(left) || isPersentValue(top))
  2699. clearCache($element)
  2700. };
  2701. var isPersentValue = function(value) {
  2702. return $.type(value) === "string" && value[value.length - 1] === "%"
  2703. };
  2704. var getTranslateFallback = function($element) {
  2705. var result;
  2706. try {
  2707. var originalTop = $element.css("top"),
  2708. originalLeft = $element.css("left");
  2709. var position = $element.position();
  2710. $element.css({
  2711. transform: "none",
  2712. top: 0,
  2713. left: 0
  2714. });
  2715. clearCache($element);
  2716. var finalPosition = $element.position();
  2717. result = {
  2718. x: position.left - finalPosition.left || parseInt(originalLeft) || 0,
  2719. y: position.top - finalPosition.top || parseInt(originalTop) || 0
  2720. };
  2721. $element.css({
  2722. top: originalTop,
  2723. left: originalLeft
  2724. })
  2725. }
  2726. catch(e) {
  2727. result = {
  2728. x: 0,
  2729. y: 0
  2730. }
  2731. }
  2732. return result
  2733. };
  2734. var getTranslate = function($element) {
  2735. var result = $element.data(TRANSLATOR_DATA_KEY);
  2736. if (!result) {
  2737. var transformValue = $element.css("transform") || getTranslateCss({
  2738. x: 0,
  2739. y: 0
  2740. }),
  2741. matrix = transformValue.match(TRANSFORM_MATRIX_REGEX),
  2742. is3D = matrix && matrix[1];
  2743. if (matrix) {
  2744. matrix = matrix[2].split(",");
  2745. if (is3D === "3d")
  2746. matrix = matrix.slice(12, 15);
  2747. else {
  2748. matrix.push(0);
  2749. matrix = matrix.slice(4, 7)
  2750. }
  2751. }
  2752. else
  2753. matrix = [0, 0, 0];
  2754. result = {
  2755. x: parseFloat(matrix[0]),
  2756. y: parseFloat(matrix[1]),
  2757. z: parseFloat(matrix[2])
  2758. };
  2759. cacheTranslate($element, result)
  2760. }
  2761. return result
  2762. };
  2763. var cacheTranslate = function($element, translate) {
  2764. $element.data(TRANSLATOR_DATA_KEY, translate)
  2765. };
  2766. var clearCache = function($element) {
  2767. $element.removeData(TRANSLATOR_DATA_KEY)
  2768. };
  2769. var resetPosition = function($element) {
  2770. $element.css({
  2771. left: 0,
  2772. top: 0,
  2773. transform: "none"
  2774. });
  2775. clearCache($element)
  2776. };
  2777. var parseTranslate = function(translateString) {
  2778. var result = translateString.match(TRANSLATE_REGEX);
  2779. if (!result || !result[1])
  2780. return;
  2781. result = result[1].split(",");
  2782. result = {
  2783. x: parseFloat(result[0]),
  2784. y: parseFloat(result[1]),
  2785. z: parseFloat(result[2])
  2786. };
  2787. return result
  2788. };
  2789. var getTranslateCss = function(translate) {
  2790. translate.x = translate.x || 0;
  2791. translate.y = translate.y || 0;
  2792. var xValueString = isPersentValue(translate.x) ? translate.x : translate.x + "px";
  2793. var yValueString = isPersentValue(translate.y) ? translate.y : translate.y + "px";
  2794. return "translate(" + xValueString + ", " + yValueString + ")"
  2795. };
  2796. DX.translator = {
  2797. move: move,
  2798. locate: locate,
  2799. clearCache: clearCache,
  2800. parseTranslate: parseTranslate,
  2801. getTranslate: getTranslate,
  2802. getTranslateCss: getTranslateCss,
  2803. resetPosition: resetPosition
  2804. }
  2805. })(jQuery, DevExpress);
  2806. /*! Module core, file animationFrame.js */
  2807. (function($, DX, undefined) {
  2808. var FRAME_ANIMATION_STEP_TIME = 1000 / 60,
  2809. requestAnimationFrame = function(callback) {
  2810. return this.setTimeout(callback, FRAME_ANIMATION_STEP_TIME)
  2811. },
  2812. cancelAnimationFrame = function(requestID) {
  2813. this.clearTimeout(requestID)
  2814. },
  2815. nativeRequestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame,
  2816. nativeCancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;
  2817. if (nativeRequestAnimationFrame && nativeCancelAnimationFrame) {
  2818. requestAnimationFrame = nativeRequestAnimationFrame;
  2819. cancelAnimationFrame = nativeCancelAnimationFrame
  2820. }
  2821. if (nativeRequestAnimationFrame && !nativeCancelAnimationFrame) {
  2822. var cancelledRequests = {};
  2823. requestAnimationFrame = function(callback) {
  2824. var requestId = nativeRequestAnimationFrame.call(window, function() {
  2825. try {
  2826. if (requestId in cancelledRequests)
  2827. return;
  2828. callback.apply(this, arguments)
  2829. }
  2830. finally {
  2831. delete cancelledRequests[requestId]
  2832. }
  2833. });
  2834. return requestId
  2835. };
  2836. cancelAnimationFrame = function(requestId) {
  2837. cancelledRequests[requestId] = true
  2838. }
  2839. }
  2840. requestAnimationFrame = $.proxy(requestAnimationFrame, window);
  2841. cancelAnimationFrame = $.proxy(cancelAnimationFrame, window);
  2842. $.extend(DX, {
  2843. requestAnimationFrame: requestAnimationFrame,
  2844. cancelAnimationFrame: cancelAnimationFrame
  2845. })
  2846. })(jQuery, DevExpress);
  2847. /*! Module core, file animator.js */
  2848. (function($, DX, undefined) {
  2849. DX.Animator = DX.Class.inherit({
  2850. ctor: function() {
  2851. this._finished = true;
  2852. this._stopped = false;
  2853. this._proxiedStepCore = $.proxy(this._stepCore, this)
  2854. },
  2855. start: function() {
  2856. this._stopped = false;
  2857. this._finished = false;
  2858. this._stepCore()
  2859. },
  2860. stop: function() {
  2861. this._stopped = true;
  2862. DX.cancelAnimationFrame(this._stepAnimationFrame)
  2863. },
  2864. _stepCore: function() {
  2865. if (this._isStopped()) {
  2866. this._stop();
  2867. return
  2868. }
  2869. if (this._isFinished()) {
  2870. this._finished = true;
  2871. this._complete();
  2872. return
  2873. }
  2874. this._step();
  2875. this._stepAnimationFrame = DX.requestAnimationFrame.call(window, this._proxiedStepCore)
  2876. },
  2877. _step: DX.abstract,
  2878. _isFinished: $.noop,
  2879. _stop: $.noop,
  2880. _complete: $.noop,
  2881. _isStopped: function() {
  2882. return this._stopped
  2883. },
  2884. inProgress: function() {
  2885. return !(this._stopped || this._finished)
  2886. }
  2887. })
  2888. })(jQuery, DevExpress);
  2889. /*! Module core, file fx.js */
  2890. (function($, DX, undefined) {
  2891. var translator = DX.translator,
  2892. support = DX.support,
  2893. transitionEndEventName = support.transitionEndEventName + ".dxFX",
  2894. removeEventName = "dxremove.dxFX";
  2895. var CSS_TRANSITION_EASING_REGEX = /cubic-bezier\((\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\)/,
  2896. RELATIVE_VALUE_REGEX = /^([+-])=(.*)/i,
  2897. ANIM_DATA_KEY = "dxAnimData",
  2898. ANIM_QUEUE_KEY = "dxAnimQueue",
  2899. TRANSFORM_PROP = "transform";
  2900. var TransitionAnimationStrategy = {
  2901. initAnimation: function($element, config) {
  2902. $element.css({transitionProperty: "none"});
  2903. if (typeof config.from === "string")
  2904. $element.addClass(config.from);
  2905. else
  2906. setProps($element, config.from)
  2907. },
  2908. animate: function($element, config) {
  2909. var that = this,
  2910. deferred = $.Deferred(),
  2911. cleanupWhen = config.cleanupWhen;
  2912. config.transitionAnimation = {finish: function() {
  2913. that._finishTransition($element, config);
  2914. if (cleanupWhen)
  2915. $.when(deferred, cleanupWhen).always(function() {
  2916. that._cleanup($element, config)
  2917. });
  2918. else
  2919. that._cleanup($element, config);
  2920. deferred.resolveWith($element, [config, $element])
  2921. }};
  2922. this._startAnimation($element, config);
  2923. this._completeAnimationCallback($element, config).done(function() {
  2924. config.transitionAnimation.finish()
  2925. });
  2926. if (!config.duration)
  2927. config.transitionAnimation.finish();
  2928. return deferred.promise()
  2929. },
  2930. _completeAnimationCallback: function($element, config) {
  2931. var startTime = $.now() + config.delay,
  2932. deferred = $.Deferred(),
  2933. transitionEndFired = $.Deferred(),
  2934. simulatedTransitionEndFired = $.Deferred(),
  2935. simulatedEndEventTimer,
  2936. waitForJSCompleteTimer;
  2937. config.transitionAnimation.cleanup = function() {
  2938. clearTimeout(simulatedEndEventTimer);
  2939. clearTimeout(waitForJSCompleteTimer)
  2940. };
  2941. $element.one(transitionEndEventName, function() {
  2942. if ($.now() - startTime >= config.duration)
  2943. transitionEndFired.reject()
  2944. }).off(removeEventName).on(removeEventName, function() {
  2945. config.transitionAnimation.cleanup()
  2946. });
  2947. waitForJSCompleteTimer = setTimeout(function() {
  2948. simulatedEndEventTimer = setTimeout(function() {
  2949. simulatedTransitionEndFired.reject()
  2950. }, config.duration + config.delay + DX.fx._simulatedTransitionEndDelay);
  2951. $.when(transitionEndFired, simulatedTransitionEndFired).fail($.proxy(function() {
  2952. deferred.resolve()
  2953. }, this))
  2954. });
  2955. return deferred.promise()
  2956. },
  2957. _startAnimation: function($element, config) {
  2958. $element.css("transform");
  2959. $element.css({
  2960. transitionProperty: "all",
  2961. transitionDelay: config.delay + "ms",
  2962. transitionDuration: config.duration + "ms",
  2963. transitionTimingFunction: config.easing
  2964. });
  2965. if (typeof config.to === "string")
  2966. $element.addClass(config.to);
  2967. else if (config.to)
  2968. setProps($element, config.to)
  2969. },
  2970. _finishTransition: function($element, config) {
  2971. $element.css("transition", "none")
  2972. },
  2973. _cleanup: function($element, config) {
  2974. $element.off(transitionEndEventName);
  2975. config.transitionAnimation.cleanup();
  2976. if (typeof config.from === "string") {
  2977. $element.removeClass(config.from);
  2978. $element.removeClass(config.to)
  2979. }
  2980. },
  2981. stop: function($element, config, jumpToEnd) {
  2982. if (!config)
  2983. return;
  2984. if (jumpToEnd)
  2985. config.transitionAnimation.finish();
  2986. else {
  2987. if ($.isPlainObject(config.to))
  2988. $.each(config.to, function(key) {
  2989. $element.css(key, $element.css(key))
  2990. });
  2991. this._finishTransition($element, config);
  2992. this._cleanup($element, config)
  2993. }
  2994. }
  2995. };
  2996. var FrameAnimationStrategy = {
  2997. initAnimation: function($element, config) {
  2998. setProps($element, config.from)
  2999. },
  3000. animate: function($element, config) {
  3001. var deferred = $.Deferred(),
  3002. that = this;
  3003. if (!config)
  3004. return deferred.reject().promise();
  3005. $.each(config.to, function(prop) {
  3006. if (config.from[prop] === undefined)
  3007. config.from[prop] = that._normalizeValue($element.css(prop))
  3008. });
  3009. if (config.to[TRANSFORM_PROP]) {
  3010. config.from[TRANSFORM_PROP] = that._parseTransform(config.from[TRANSFORM_PROP]);
  3011. config.to[TRANSFORM_PROP] = that._parseTransform(config.to[TRANSFORM_PROP])
  3012. }
  3013. config.frameAnimation = {
  3014. to: config.to,
  3015. from: config.from,
  3016. currentValue: config.from,
  3017. easing: convertTransitionTimingFuncToJQueryEasing(config.easing),
  3018. duration: config.duration,
  3019. startTime: (new Date).valueOf(),
  3020. finish: function() {
  3021. this.currentValue = this.to;
  3022. this.draw();
  3023. deferred.resolve()
  3024. },
  3025. draw: function() {
  3026. var currentValue = $.extend({}, this.currentValue);
  3027. if (currentValue[TRANSFORM_PROP])
  3028. currentValue[TRANSFORM_PROP] = $.map(currentValue[TRANSFORM_PROP], function(value, prop) {
  3029. if (prop === "translate")
  3030. return translator.getTranslateCss(value);
  3031. else if (prop === "scale")
  3032. return "scale(" + value + ")";
  3033. else if (prop.substr(0, prop.length - 1) === "rotate")
  3034. return prop + "(" + value + "deg)"
  3035. }).join(" ");
  3036. $element.css(currentValue)
  3037. }
  3038. };
  3039. if (config.delay) {
  3040. config.frameAnimation.startTime += config.delay;
  3041. config.frameAnimation.delayTimeout = setTimeout(function() {
  3042. that._animationStep($element, config)
  3043. }, config.delay)
  3044. }
  3045. else
  3046. that._animationStep($element, config);
  3047. return deferred.promise()
  3048. },
  3049. _parseTransform: function(transformString) {
  3050. var result = {};
  3051. $.each(transformString.match(/(\w|\d)+\([^\)]*\)\s*/g), function(i, part) {
  3052. var translateData = translator.parseTranslate(part),
  3053. scaleData = part.match(/scale\((.+?)\)/),
  3054. rotateData = part.match(/(rotate.)\((.+)deg\)/);
  3055. if (translateData)
  3056. result.translate = translateData;
  3057. if (scaleData && scaleData[1])
  3058. result.scale = parseFloat(scaleData[1]);
  3059. if (rotateData && rotateData[1])
  3060. result[rotateData[1]] = parseFloat(rotateData[2])
  3061. });
  3062. return result
  3063. },
  3064. stop: function($element, config, jumpToEnd) {
  3065. var frameAnimation = config && config.frameAnimation;
  3066. if (!frameAnimation)
  3067. return;
  3068. clearTimeout(frameAnimation.delayTimeout);
  3069. if (jumpToEnd)
  3070. frameAnimation.finish();
  3071. delete config.frameAnimation
  3072. },
  3073. _animationStep: function($element, config) {
  3074. var frameAnimation = config && config.frameAnimation;
  3075. if (!frameAnimation)
  3076. return;
  3077. var now = (new Date).valueOf();
  3078. if (now >= frameAnimation.startTime + frameAnimation.duration) {
  3079. frameAnimation.finish();
  3080. return
  3081. }
  3082. frameAnimation.currentValue = this._calcStepValue(frameAnimation, now - frameAnimation.startTime);
  3083. frameAnimation.draw();
  3084. DX.requestAnimationFrame($.proxy(function() {
  3085. this._animationStep($element, config)
  3086. }, this))
  3087. },
  3088. _calcStepValue: function(frameAnimation, currentDuration) {
  3089. var calcValueRecursively = function(from, to) {
  3090. var result = $.isArray(to) ? [] : {};
  3091. var calcEasedValue = function(propName) {
  3092. var x = currentDuration / frameAnimation.duration,
  3093. t = currentDuration,
  3094. b = 1 * from[propName],
  3095. c = to[propName] - from[propName],
  3096. d = frameAnimation.duration;
  3097. return $.easing[frameAnimation.easing](x, t, b, c, d)
  3098. };
  3099. $.each(to, function(propName, endPropValue) {
  3100. if (typeof endPropValue === "string" && parseFloat(endPropValue, 10) === false)
  3101. return true;
  3102. result[propName] = typeof endPropValue === "object" ? calcValueRecursively(from[propName], endPropValue) : calcEasedValue(propName)
  3103. });
  3104. return result
  3105. };
  3106. return calcValueRecursively(frameAnimation.from, frameAnimation.to)
  3107. },
  3108. _normalizeValue: function(value) {
  3109. var numericValue = parseFloat(value, 10);
  3110. if (numericValue === false)
  3111. return value;
  3112. return numericValue
  3113. }
  3114. };
  3115. var FallbackToNoAnimationStrategy = {
  3116. initAnimation: function($element, config){},
  3117. animate: function($element, config) {
  3118. return $.Deferred().resolve().promise()
  3119. }
  3120. };
  3121. var animationStrategies = {
  3122. transition: support.transition ? TransitionAnimationStrategy : FrameAnimationStrategy,
  3123. frame: FrameAnimationStrategy,
  3124. noAnimation: FallbackToNoAnimationStrategy
  3125. };
  3126. var getAnimationStrategy = function(config) {
  3127. config = config || {};
  3128. var strategy = config.strategy || "transition";
  3129. if (config.type === "css" && !support.transition)
  3130. strategy = "noAnimation";
  3131. return animationStrategies[strategy]
  3132. };
  3133. var TransitionTimingFuncMap = {
  3134. linear: "cubic-bezier(0, 0, 1, 1)",
  3135. ease: "cubic-bezier(0.25, 0.1, 0.25, 1)",
  3136. "ease-in": "cubic-bezier(0.42, 0, 1, 1)",
  3137. "ease-out": "cubic-bezier(0, 0, 0.58, 1)",
  3138. "ease-in-out": "cubic-bezier(0.42, 0, 0.58, 1)"
  3139. };
  3140. var convertTransitionTimingFuncToJQueryEasing = function(cssTransitionEasing) {
  3141. cssTransitionEasing = TransitionTimingFuncMap[cssTransitionEasing] || cssTransitionEasing;
  3142. var bezCoeffs = cssTransitionEasing.match(CSS_TRANSITION_EASING_REGEX);
  3143. if (!bezCoeffs)
  3144. return "linear";
  3145. bezCoeffs = bezCoeffs.slice(1, 5);
  3146. $.each(bezCoeffs, function(index, value) {
  3147. bezCoeffs[index] = parseFloat(value)
  3148. });
  3149. var easingName = "cubicbezier_" + bezCoeffs.join("_").replace(/\./g, "p");
  3150. if (!$.isFunction($.easing[easingName])) {
  3151. var polynomBezier = function(x1, y1, x2, y2) {
  3152. var Cx = 3 * x1,
  3153. Bx = 3 * (x2 - x1) - Cx,
  3154. Ax = 1 - Cx - Bx,
  3155. Cy = 3 * y1,
  3156. By = 3 * (y2 - y1) - Cy,
  3157. Ay = 1 - Cy - By;
  3158. var bezierX = function(t) {
  3159. return t * (Cx + t * (Bx + t * Ax))
  3160. };
  3161. var bezierY = function(t) {
  3162. return t * (Cy + t * (By + t * Ay))
  3163. };
  3164. var findXfor = function(t) {
  3165. var x = t,
  3166. i = 0,
  3167. z;
  3168. while (i < 14) {
  3169. z = bezierX(x) - t;
  3170. if (Math.abs(z) < 1e-3)
  3171. break;
  3172. x = x - z / derivativeX(x);
  3173. i++
  3174. }
  3175. return x
  3176. };
  3177. var derivativeX = function(t) {
  3178. return Cx + t * (2 * Bx + t * 3 * Ax)
  3179. };
  3180. return function(t) {
  3181. return bezierY(findXfor(t))
  3182. }
  3183. };
  3184. $.easing[easingName] = function(x, t, b, c, d) {
  3185. return c * polynomBezier(bezCoeffs[0], bezCoeffs[1], bezCoeffs[2], bezCoeffs[3])(t / d) + b
  3186. }
  3187. }
  3188. return easingName
  3189. };
  3190. var baseConfigValidator = function(config, animationType, validate, typeMessage) {
  3191. $.each(["from", "to"], function() {
  3192. if (!validate(config[this]))
  3193. throw DX.Error("E0010", animationType, this, typeMessage);
  3194. })
  3195. };
  3196. var isObjectConfigValidator = function(config, animationType) {
  3197. return baseConfigValidator(config, animationType, function(target) {
  3198. return $.isPlainObject(target)
  3199. }, "a plain object")
  3200. };
  3201. var isStringConfigValidator = function(config, animationType) {
  3202. return baseConfigValidator(config, animationType, function(target) {
  3203. return typeof target === "string"
  3204. }, "a string")
  3205. };
  3206. var CustomAnimationConfigurator = {setup: function($element, config){}};
  3207. var CssAnimationConfigurator = {
  3208. validateConfig: function(config) {
  3209. isStringConfigValidator(config, "css")
  3210. },
  3211. setup: function($element, config){}
  3212. };
  3213. var positionAliases = {
  3214. top: {
  3215. my: "bottom center",
  3216. at: "top center"
  3217. },
  3218. bottom: {
  3219. my: "top center",
  3220. at: "bottom center"
  3221. },
  3222. right: {
  3223. my: "left center",
  3224. at: "right center"
  3225. },
  3226. left: {
  3227. my: "right center",
  3228. at: "left center"
  3229. }
  3230. };
  3231. var SlideAnimationConfigurator = {
  3232. validateConfig: function(config) {
  3233. isObjectConfigValidator(config, "slide")
  3234. },
  3235. setup: function($element, config) {
  3236. var location = translator.locate($element);
  3237. if (config.type !== "slide") {
  3238. var positioningConfig = config.type === "slideIn" ? config.from : config.to;
  3239. positioningConfig.position = $.extend({of: window}, positionAliases[config.direction]);
  3240. setupPosition($element, positioningConfig)
  3241. }
  3242. this._setUpConfig(location, config.from);
  3243. this._setUpConfig(location, config.to);
  3244. translator.clearCache($element);
  3245. if (!support.transform && $element.css("position") === "static")
  3246. $element.css("position", "relative")
  3247. },
  3248. _setUpConfig: function(location, config) {
  3249. config.left = "left" in config ? config.left : "+=0";
  3250. config.top = "top" in config ? config.top : "+=0";
  3251. this._initNewPosition(location, config)
  3252. },
  3253. _initNewPosition: function(location, config) {
  3254. var position = {
  3255. left: config.left,
  3256. top: config.top
  3257. };
  3258. delete config.left;
  3259. delete config.top;
  3260. var relativeValue = this._getRelativeValue(position.left);
  3261. if (relativeValue !== undefined)
  3262. position.left = relativeValue + location.left;
  3263. else
  3264. config.left = 0;
  3265. relativeValue = this._getRelativeValue(position.top);
  3266. if (relativeValue !== undefined)
  3267. position.top = relativeValue + location.top;
  3268. else
  3269. config.top = 0;
  3270. var translate = {
  3271. x: 0,
  3272. y: 0
  3273. };
  3274. if (support.transform)
  3275. translate = {
  3276. x: position.left,
  3277. y: position.top
  3278. };
  3279. else {
  3280. config.left = position.left;
  3281. config.top = position.top
  3282. }
  3283. config[TRANSFORM_PROP] = translator.getTranslateCss(translate)
  3284. },
  3285. _getRelativeValue: function(value) {
  3286. var relativeValue;
  3287. if (typeof value === "string" && (relativeValue = RELATIVE_VALUE_REGEX.exec(value)))
  3288. return parseInt(relativeValue[1] + "1") * relativeValue[2]
  3289. }
  3290. };
  3291. var FadeAnimationConfigurator = {setup: function($element, config) {
  3292. var from = config.from,
  3293. fromOpacity = $.isPlainObject(from) ? config.skipElementInitialStyles ? 0 : $element.css("opacity") : String(from),
  3294. toOpacity;
  3295. switch (config.type) {
  3296. case"fadeIn":
  3297. toOpacity = 1;
  3298. break;
  3299. case"fadeOut":
  3300. toOpacity = 0;
  3301. break;
  3302. default:
  3303. toOpacity = String(config.to)
  3304. }
  3305. config.from = {
  3306. visibility: "visible",
  3307. opacity: fromOpacity
  3308. };
  3309. config.to = {opacity: toOpacity}
  3310. }};
  3311. var PopAnimationConfigurator = {
  3312. validateConfig: function(config) {
  3313. isObjectConfigValidator(config, "pop")
  3314. },
  3315. setup: function($element, config) {
  3316. var from = config.from,
  3317. to = config.to,
  3318. fromOpacity = "opacity" in from ? from.opacity : $element.css("opacity"),
  3319. toOpacity = "opacity" in to ? to.opacity : 1,
  3320. fromScale = "scale" in from ? from.scale : 0,
  3321. toScale = "scale" in to ? to.scale : 1;
  3322. config.from = {opacity: fromOpacity};
  3323. var translate = translator.getTranslate($element);
  3324. config.from[TRANSFORM_PROP] = this._getCssTransform(translate, fromScale);
  3325. config.to = {opacity: toOpacity};
  3326. config.to[TRANSFORM_PROP] = this._getCssTransform(translate, toScale)
  3327. },
  3328. _getCssTransform: function(translate, scale) {
  3329. return translator.getTranslateCss(translate) + "scale(" + scale + ")"
  3330. }
  3331. };
  3332. var animationConfigurators = {
  3333. custom: CustomAnimationConfigurator,
  3334. slide: SlideAnimationConfigurator,
  3335. slideIn: SlideAnimationConfigurator,
  3336. slideOut: SlideAnimationConfigurator,
  3337. fade: FadeAnimationConfigurator,
  3338. fadeIn: FadeAnimationConfigurator,
  3339. fadeOut: FadeAnimationConfigurator,
  3340. pop: PopAnimationConfigurator,
  3341. css: CssAnimationConfigurator
  3342. };
  3343. var getAnimationConfigurator = function(config) {
  3344. var result = animationConfigurators[config.type];
  3345. if (!result)
  3346. throw DX.Error("E0011", config.type);
  3347. return result
  3348. };
  3349. var defaultJSConfig = {
  3350. type: "custom",
  3351. from: {},
  3352. to: {},
  3353. duration: 400,
  3354. start: $.noop,
  3355. complete: $.noop,
  3356. easing: "ease",
  3357. delay: 0
  3358. },
  3359. defaultCssConfig = {
  3360. duration: 400,
  3361. easing: "ease",
  3362. delay: 0
  3363. };
  3364. var setupAnimationOnElement = function() {
  3365. var animation = this,
  3366. $element = animation.$element,
  3367. config = animation.config;
  3368. setupPosition($element, config.from);
  3369. setupPosition($element, config.to);
  3370. animation.configurator.setup($element, config);
  3371. $element.data(ANIM_DATA_KEY, animation);
  3372. if (DX.fx.off)
  3373. config.duration = 0;
  3374. animation.strategy.initAnimation($element, config);
  3375. if (config.start)
  3376. config.start.apply(this, [$element, config])
  3377. };
  3378. var startAnimationOnElement = function() {
  3379. var animation = this,
  3380. $element = animation.$element,
  3381. config = animation.config;
  3382. return animation.strategy.animate($element, config).done(function() {
  3383. $element.removeData(ANIM_DATA_KEY);
  3384. if (config.complete)
  3385. config.complete.apply(this, [$element, config]);
  3386. animation.deferred.resolveWith(this, [$element, config])
  3387. })
  3388. };
  3389. var createAnimation = function($element, initialConfig) {
  3390. var defaultConfig = initialConfig.type === "css" ? defaultCssConfig : defaultJSConfig,
  3391. config = $.extend(true, {}, defaultConfig, initialConfig),
  3392. configurator = getAnimationConfigurator(config),
  3393. strategy = getAnimationStrategy(config),
  3394. animation = {
  3395. $element: $element,
  3396. config: config,
  3397. configurator: configurator,
  3398. strategy: strategy,
  3399. setup: setupAnimationOnElement,
  3400. start: startAnimationOnElement,
  3401. deferred: $.Deferred()
  3402. };
  3403. if ($.isFunction(configurator.validateConfig))
  3404. configurator.validateConfig(config);
  3405. return animation
  3406. };
  3407. var animate = function(element, config) {
  3408. var $element = $(element);
  3409. if (!$element.length)
  3410. return $.Deferred().resolve().promise();
  3411. var animation = createAnimation($element, config);
  3412. pushInAnimationQueue($element, animation);
  3413. return animation.deferred.promise()
  3414. };
  3415. var pushInAnimationQueue = function($element, animation) {
  3416. var queueData = getAnimQueueData($element);
  3417. writeAnimQueueData($element, queueData);
  3418. queueData.push(animation);
  3419. if (!isAnimating($element))
  3420. shiftFromAnimationQueue($element, queueData)
  3421. };
  3422. var getAnimQueueData = function($element) {
  3423. return $element.data(ANIM_QUEUE_KEY) || []
  3424. };
  3425. var writeAnimQueueData = function($element, queueData) {
  3426. $element.data(ANIM_QUEUE_KEY, queueData)
  3427. };
  3428. var destroyAnimQueueData = function($element) {
  3429. $element.removeData(ANIM_QUEUE_KEY)
  3430. };
  3431. var isAnimating = function($element) {
  3432. return !!$element.data(ANIM_DATA_KEY)
  3433. };
  3434. var shiftFromAnimationQueue = function($element, queueData) {
  3435. queueData = getAnimQueueData($element);
  3436. if (!queueData.length)
  3437. return;
  3438. var animation = queueData.shift();
  3439. if (queueData.length === 0)
  3440. destroyAnimQueueData($element);
  3441. executeAnimation(animation).done(function() {
  3442. shiftFromAnimationQueue($element)
  3443. })
  3444. };
  3445. var executeAnimation = function(animation) {
  3446. animation.setup();
  3447. return animation.start()
  3448. };
  3449. var setupPosition = function($element, config) {
  3450. if (!config || !config.position)
  3451. return;
  3452. var position = DX.calculatePosition($element, config.position),
  3453. offset = $element.offset(),
  3454. currentPosition = $element.position();
  3455. $.extend(config, {
  3456. left: position.h.location - offset.left + currentPosition.left,
  3457. top: position.v.location - offset.top + currentPosition.top
  3458. });
  3459. delete config.position
  3460. };
  3461. var setProps = function($element, props) {
  3462. $.each(props, function(key, value) {
  3463. $element.css(key, value)
  3464. })
  3465. };
  3466. var stop = function(element, jumpToEnd) {
  3467. var $element = $(element),
  3468. queueData = getAnimQueueData($element);
  3469. $.each(queueData, function(_, animation) {
  3470. animation.config.duration = 0
  3471. });
  3472. if (!isAnimating($element))
  3473. shiftFromAnimationQueue($element, queueData);
  3474. var animation = $element.data(ANIM_DATA_KEY);
  3475. if (animation)
  3476. animation.strategy.stop($element, animation.config, jumpToEnd);
  3477. $element.removeData(ANIM_DATA_KEY);
  3478. destroyAnimQueueData($element)
  3479. };
  3480. DX.fx = {
  3481. off: false,
  3482. animationTypes: animationConfigurators,
  3483. animate: animate,
  3484. createAnimation: createAnimation,
  3485. isAnimating: isAnimating,
  3486. stop: stop,
  3487. _simulatedTransitionEndDelay: 100
  3488. };
  3489. DX.fx.__internals = {convertTransitionTimingFuncToJQueryEasing: convertTransitionTimingFuncToJQueryEasing}
  3490. })(jQuery, DevExpress);
  3491. /*! Module core, file dxProxyUrlFormatter.js */
  3492. (function($, DX, undefined) {
  3493. var location = window.location,
  3494. DXPROXY_HOST = "dxproxy.devexpress.com:8000",
  3495. IS_DXPROXY_ORIGIN = location.host === DXPROXY_HOST,
  3496. urlMapping = {};
  3497. var extractProxyAppId = function() {
  3498. return location.pathname.split("/")[1]
  3499. };
  3500. var urlFormatter = {
  3501. isProxyUsed: function() {
  3502. return IS_DXPROXY_ORIGIN
  3503. },
  3504. formatProxyUrl: function(localUrl) {
  3505. var urlData = DX.parseUrl(localUrl);
  3506. if (!/^(localhost$|127\.)/i.test(urlData.hostname))
  3507. return localUrl;
  3508. var proxyUrlPart = DXPROXY_HOST + "/" + extractProxyAppId() + "_" + urlData.port;
  3509. urlMapping[proxyUrlPart] = urlData.hostname + ":" + urlData.port;
  3510. var resultUrl = "http://" + proxyUrlPart + urlData.pathname + urlData.search;
  3511. return resultUrl
  3512. },
  3513. formatLocalUrl: function(proxyUrl) {
  3514. if (proxyUrl.indexOf(DXPROXY_HOST) < 0)
  3515. return proxyUrl;
  3516. var resultUrl = proxyUrl;
  3517. for (var proxyUrlPart in urlMapping)
  3518. if (urlMapping.hasOwnProperty(proxyUrlPart))
  3519. if (proxyUrl.indexOf(proxyUrlPart) >= 0) {
  3520. resultUrl = proxyUrl.replace(proxyUrlPart, urlMapping[proxyUrlPart]);
  3521. break
  3522. }
  3523. return resultUrl
  3524. }
  3525. };
  3526. DX._proxyUrlFormatter = urlFormatter
  3527. })(jQuery, DevExpress);
  3528. /*! Module core, file endpointSelector.js */
  3529. (function($, DX, undefined) {
  3530. var location = window.location,
  3531. IS_WINJS_ORIGIN = location.protocol === "ms-appx:",
  3532. IS_LOCAL_ORIGIN = isLocalHostName(location.hostname);
  3533. function isLocalHostName(url) {
  3534. return /^(localhost$|127\.)/i.test(url)
  3535. }
  3536. var EndpointSelector = DX.EndpointSelector = function(config) {
  3537. this.config = config
  3538. };
  3539. EndpointSelector.prototype = {urlFor: function(key) {
  3540. var bag = this.config[key];
  3541. if (!bag)
  3542. throw DX.Error("E0006");
  3543. if (DX._proxyUrlFormatter.isProxyUsed())
  3544. return DX._proxyUrlFormatter.formatProxyUrl(bag.local);
  3545. if (bag.production)
  3546. if (IS_WINJS_ORIGIN && !Debug.debuggerEnabled || !IS_WINJS_ORIGIN && !IS_LOCAL_ORIGIN)
  3547. return bag.production;
  3548. return bag.local
  3549. }}
  3550. })(jQuery, DevExpress);
  3551. /*! Module core, file formatHelper.js */
  3552. (function($, DX, undefined) {
  3553. var utils = DX.utils;
  3554. DX.NumericFormat = {
  3555. currency: 'C',
  3556. fixedpoint: 'N',
  3557. exponential: '',
  3558. percent: 'P',
  3559. decimal: 'D'
  3560. };
  3561. DX.LargeNumberFormatPostfixes = {
  3562. 1: 'K',
  3563. 2: 'M',
  3564. 3: 'B',
  3565. 4: 'T'
  3566. };
  3567. var MAX_LARGE_NUMBER_POWER = 4,
  3568. DECIMAL_BASE = 10;
  3569. DX.LargeNumberFormatPowers = {
  3570. largenumber: 'auto',
  3571. thousands: 1,
  3572. millions: 2,
  3573. billions: 3,
  3574. trillions: 4
  3575. };
  3576. DX.DateTimeFormat = {
  3577. longdate: 'D',
  3578. longtime: 'T',
  3579. monthandday: 'M',
  3580. monthandyear: 'Y',
  3581. quarterandyear: 'qq',
  3582. shortdate: 'd',
  3583. shorttime: 't',
  3584. millisecond: 'fff',
  3585. second: 'T',
  3586. minute: 't',
  3587. hour: 't',
  3588. day: 'dd',
  3589. week: 'dd',
  3590. month: 'MMMM',
  3591. quarter: 'qq',
  3592. year: 'yyyy',
  3593. longdatelongtime: 'D',
  3594. shortdateshorttime: 'd',
  3595. shortyear: 'yy'
  3596. };
  3597. DX.formatHelper = {
  3598. defaultQuarterFormat: 'Q{0}',
  3599. romanDigits: ['I', 'II', 'III', 'IV'],
  3600. _addFormatSeparator: function(format1, format2) {
  3601. var separator = ' ';
  3602. if (format2)
  3603. return format1 + separator + format2;
  3604. return format1
  3605. },
  3606. _getDateTimeFormatPattern: function(dateTimeFormat) {
  3607. return Globalize.findClosestCulture().calendar.patterns[DX.DateTimeFormat[dateTimeFormat.toLowerCase()]]
  3608. },
  3609. _isDateFormatContains: function(format) {
  3610. var result = false;
  3611. $.each(DX.DateTimeFormat, function(key) {
  3612. result = key === format.toLowerCase();
  3613. return !result
  3614. });
  3615. return result
  3616. },
  3617. getQuarter: function(month) {
  3618. return Math.floor(month / 3)
  3619. },
  3620. getFirstQuarterMonth: function(month) {
  3621. return this.getQuarter(month) * 3
  3622. },
  3623. _getQuarterString: function(date, format) {
  3624. var quarter = this.getQuarter(date.getMonth());
  3625. switch (format) {
  3626. case'q':
  3627. return this.romanDigits[quarter];
  3628. case'qq':
  3629. return utils.stringFormat(this.defaultQuarterFormat, this.romanDigits[quarter]);
  3630. case'Q':
  3631. return (quarter + 1).toString();
  3632. case'QQ':
  3633. return utils.stringFormat(this.defaultQuarterFormat, (quarter + 1).toString())
  3634. }
  3635. return ''
  3636. },
  3637. _formatCustomString: function(value, format) {
  3638. var regExp = /qq|q|QQ|Q/g,
  3639. quarterFormat,
  3640. result = '',
  3641. index = 0;
  3642. regExp.lastIndex = 0;
  3643. while (index < format.length) {
  3644. quarterFormat = regExp.exec(format);
  3645. if (!quarterFormat || quarterFormat.index > index)
  3646. result += Globalize.format(value, format.substring(index, quarterFormat ? quarterFormat.index : format.length));
  3647. if (quarterFormat) {
  3648. result += this._getQuarterString(value, quarterFormat[0]);
  3649. index = quarterFormat.index + quarterFormat[0].length
  3650. }
  3651. else
  3652. index = format.length
  3653. }
  3654. return result
  3655. },
  3656. _parseNumberFormatString: function(format) {
  3657. var formatList,
  3658. formatObject = {};
  3659. if (!format || typeof format !== 'string')
  3660. return;
  3661. formatList = format.toLowerCase().split(' ');
  3662. $.each(formatList, function(index, value) {
  3663. if (value in DX.NumericFormat)
  3664. formatObject.formatType = value;
  3665. else if (value in DX.LargeNumberFormatPowers)
  3666. formatObject.power = DX.LargeNumberFormatPowers[value]
  3667. });
  3668. if (formatObject.power && !formatObject.formatType)
  3669. formatObject.formatType = 'fixedpoint';
  3670. if (formatObject.formatType)
  3671. return formatObject
  3672. },
  3673. _calculateNumberPower: function(value, base, minPower, maxPower) {
  3674. var number = Math.abs(value);
  3675. var power = 0;
  3676. if (number > 1)
  3677. while (number && number >= base && (maxPower === undefined || power < maxPower)) {
  3678. power++;
  3679. number = number / base
  3680. }
  3681. else if (number > 0 && number < 1)
  3682. while (number < 1 && (minPower === undefined || power > minPower)) {
  3683. power--;
  3684. number = number * base
  3685. }
  3686. return power
  3687. },
  3688. _getNumberByPower: function(number, power, base) {
  3689. var result = number;
  3690. while (power > 0) {
  3691. result = result / base;
  3692. power--
  3693. }
  3694. while (power < 0) {
  3695. result = result * base;
  3696. power++
  3697. }
  3698. return result
  3699. },
  3700. _formatNumber: function(value, formatObject, precision) {
  3701. var powerPostfix;
  3702. if (formatObject.power === 'auto')
  3703. formatObject.power = this._calculateNumberPower(value, 1000, 0, MAX_LARGE_NUMBER_POWER);
  3704. if (formatObject.power)
  3705. value = this._getNumberByPower(value, formatObject.power, 1000);
  3706. powerPostfix = DX.LargeNumberFormatPostfixes[formatObject.power] || '';
  3707. return this._formatNumberCore(value, formatObject.formatType, precision) + powerPostfix
  3708. },
  3709. _formatNumberExponential: function(value, precision) {
  3710. var power = this._calculateNumberPower(value, DECIMAL_BASE),
  3711. number = this._getNumberByPower(value, power, DECIMAL_BASE),
  3712. powString;
  3713. precision = precision === undefined ? 1 : precision;
  3714. if (number.toFixed(precision || 0) >= DECIMAL_BASE) {
  3715. power++;
  3716. number = number / DECIMAL_BASE
  3717. }
  3718. powString = (power >= 0 ? '+' : '') + power.toString();
  3719. return this._formatNumberCore(number, 'fixedpoint', precision) + 'E' + powString
  3720. },
  3721. _formatNumberCore: function(value, format, precision) {
  3722. if (format === 'exponential')
  3723. return this._formatNumberExponential(value, precision);
  3724. else
  3725. return Globalize.format(value, DX.NumericFormat[format] + (utils.isNumber(precision) ? precision : 0))
  3726. },
  3727. _formatDate: function(date, format) {
  3728. var resultFormat = DX.DateTimeFormat[format.toLowerCase()];
  3729. format = format.toLowerCase();
  3730. if (format === 'quarterandyear')
  3731. resultFormat = this._getQuarterString(date, resultFormat) + ' yyyy';
  3732. if (format === 'quarter')
  3733. return this._getQuarterString(date, resultFormat);
  3734. if (format === 'longdatelongtime')
  3735. return this._formatDate(date, 'longdate') + ' ' + this._formatDate(date, 'longtime');
  3736. if (format === 'shortdateshorttime')
  3737. return this._formatDate(date, 'shortDate') + ' ' + this._formatDate(date, 'shortTime');
  3738. return Globalize.format(date, resultFormat)
  3739. },
  3740. format: function(value, format, precision) {
  3741. if ($.isPlainObject(format) && format.format)
  3742. if (format.dateType)
  3743. return this._formatDateEx(value, format);
  3744. else if (utils.isNumber(value) && isFinite(value))
  3745. return this._formatNumberEx(value, format);
  3746. return this._format(value, format, precision)
  3747. },
  3748. _format: function(value, format, precision) {
  3749. var numberFormatObject;
  3750. if (!utils.isString(format) || format === '' || !utils.isNumber(value) && !utils.isDate(value))
  3751. return utils.isDefined(value) ? value.toString() : '';
  3752. numberFormatObject = this._parseNumberFormatString(format);
  3753. if (utils.isNumber(value) && numberFormatObject)
  3754. return this._formatNumber(value, numberFormatObject, precision);
  3755. if (utils.isDate(value) && this._isDateFormatContains(format))
  3756. return this._formatDate(value, format);
  3757. if (!numberFormatObject && !this._isDateFormatContains(format))
  3758. return this._formatCustomString(value, format)
  3759. },
  3760. _formatNumberEx: function(value, formatInfo) {
  3761. var that = this,
  3762. numericFormatType = DX.NumericFormat[formatInfo.format.toLowerCase()],
  3763. numberFormat = Globalize.culture().numberFormat,
  3764. currencyFormat = formatInfo.currencyCulture && Globalize.cultures[formatInfo.currencyCulture] ? Globalize.cultures[formatInfo.currencyCulture].numberFormat.currency : numberFormat.currency,
  3765. percentFormat = numberFormat.percent,
  3766. formatSettings = that._getUnitFormatSettings(value, formatInfo),
  3767. unit = formatSettings.unit,
  3768. precision = formatSettings.precision,
  3769. showTrailingZeros = formatSettings.showTrailingZeros,
  3770. includeGroupSeparator = formatSettings.includeGroupSeparator,
  3771. groupSymbol = numberFormat[","],
  3772. floatingSymbol = numberFormat["."],
  3773. number,
  3774. isNegative,
  3775. pattern,
  3776. currentFormat,
  3777. regexParts = /n|\$|-|%/g,
  3778. result = "";
  3779. if (!utils.isDefined(value))
  3780. return '';
  3781. value = that._applyUnitToValue(value, unit);
  3782. number = Math.abs(value);
  3783. isNegative = value < 0;
  3784. switch (numericFormatType) {
  3785. case DX.NumericFormat.decimal:
  3786. pattern = "n";
  3787. number = Math[isNegative ? "ceil" : "floor"](number);
  3788. if (precision > 0) {
  3789. var str = "" + number;
  3790. for (var i = str.length; i < precision; i += 1)
  3791. str = "0" + str;
  3792. number = str
  3793. }
  3794. if (isNegative)
  3795. number = "-" + number;
  3796. break;
  3797. case DX.NumericFormat.fixedpoint:
  3798. currentFormat = numberFormat;
  3799. case DX.NumericFormat.currency:
  3800. currentFormat = currentFormat || currencyFormat;
  3801. case DX.NumericFormat.percent:
  3802. currentFormat = currentFormat || percentFormat;
  3803. pattern = isNegative ? currentFormat.pattern[0] : currentFormat.pattern[1] || "n";
  3804. number = Globalize.format(number * (numericFormatType === DX.NumericFormat.percent ? 100 : 1), "N" + precision);
  3805. if (!showTrailingZeros)
  3806. number = that._excludeTrailingZeros(number, floatingSymbol);
  3807. if (!includeGroupSeparator)
  3808. number = number.replace(new RegExp('\\' + groupSymbol, 'g'), '');
  3809. break;
  3810. case DX.NumericFormat.exponential:
  3811. return that._formatNumberExponential(value, precision);
  3812. default:
  3813. throw"Illegal numeric format: '" + numericFormatType + "'";
  3814. }
  3815. for (; ; ) {
  3816. var lastIndex = regexParts.lastIndex,
  3817. matches = regexParts.exec(pattern);
  3818. result += pattern.slice(lastIndex, matches ? matches.index : pattern.length);
  3819. if (matches)
  3820. switch (matches[0]) {
  3821. case"-":
  3822. if (/[1-9]/.test(number))
  3823. result += numberFormat["-"];
  3824. break;
  3825. case"$":
  3826. result += currencyFormat.symbol;
  3827. break;
  3828. case"%":
  3829. result += percentFormat.symbol;
  3830. break;
  3831. case"n":
  3832. result += number + unit;
  3833. break
  3834. }
  3835. else
  3836. break
  3837. }
  3838. return (formatInfo.plus && value > 0 ? "+" : '') + result
  3839. },
  3840. _excludeTrailingZeros: function(strValue, floatingSymbol) {
  3841. var floatingIndex = strValue.indexOf(floatingSymbol),
  3842. stopIndex,
  3843. i;
  3844. if (floatingIndex < 0)
  3845. return strValue;
  3846. stopIndex = strValue.length;
  3847. for (i = stopIndex - 1; i >= floatingIndex && (strValue[i] === '0' || i === floatingIndex); i--)
  3848. stopIndex--;
  3849. return strValue.substring(0, stopIndex)
  3850. },
  3851. _getUnitFormatSettings: function(value, formatInfo) {
  3852. var unit = formatInfo.unit || '',
  3853. precision = formatInfo.precision || 0,
  3854. includeGroupSeparator = formatInfo.includeGroupSeparator || false,
  3855. showTrailingZeros = formatInfo.showTrailingZeros === undefined ? true : formatInfo.showTrailingZeros,
  3856. significantDigits = formatInfo.significantDigits || 1,
  3857. absValue;
  3858. if (unit.toLowerCase() === 'auto') {
  3859. showTrailingZeros = false;
  3860. absValue = Math.abs(value);
  3861. if (significantDigits < 1)
  3862. significantDigits = 1;
  3863. if (absValue >= 1000000000) {
  3864. unit = 'B';
  3865. absValue /= 1000000000
  3866. }
  3867. else if (absValue >= 1000000) {
  3868. unit = 'M';
  3869. absValue /= 1000000
  3870. }
  3871. else if (absValue >= 1000) {
  3872. unit = 'K';
  3873. absValue /= 1000
  3874. }
  3875. else
  3876. unit = '';
  3877. if (absValue === 0)
  3878. precision = 0;
  3879. else if (absValue < 1) {
  3880. precision = significantDigits;
  3881. var smallValue = Math.pow(10, -significantDigits);
  3882. while (absValue < smallValue) {
  3883. smallValue /= 10;
  3884. precision++
  3885. }
  3886. }
  3887. else if (absValue >= 100)
  3888. precision = significantDigits - 3;
  3889. else if (absValue >= 10)
  3890. precision = significantDigits - 2;
  3891. else
  3892. precision = significantDigits - 1
  3893. }
  3894. if (precision < 0)
  3895. precision = 0;
  3896. return {
  3897. unit: unit,
  3898. precision: precision,
  3899. showTrailingZeros: showTrailingZeros,
  3900. includeGroupSeparator: includeGroupSeparator
  3901. }
  3902. },
  3903. _applyUnitToValue: function(value, unit) {
  3904. if (unit === 'B')
  3905. return value.toFixed(1) / 1000000000;
  3906. if (unit === 'M')
  3907. return value / 1000000;
  3908. if (unit === 'K')
  3909. return value / 1000;
  3910. return value
  3911. },
  3912. _formatDateEx: function(value, formatInfo) {
  3913. var that = this,
  3914. format = formatInfo.format,
  3915. dateType = formatInfo.dateType,
  3916. calendar = Globalize.culture().calendars.standard,
  3917. time,
  3918. index,
  3919. dateStr;
  3920. format = format.toLowerCase();
  3921. if (!utils.isDefined(value))
  3922. return '';
  3923. if (dateType !== 'num' || format === 'dayofweek')
  3924. switch (format) {
  3925. case'monthyear':
  3926. return that._formatDate(value, 'monthandyear');
  3927. case'quarteryear':
  3928. return that._getQuarterString(value, 'QQ') + ' ' + value.getFullYear();
  3929. case'daymonthyear':
  3930. return that._formatDate(value, dateType + 'Date');
  3931. case'datehour':
  3932. time = new Date(value.getTime());
  3933. time.setMinutes(0);
  3934. dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
  3935. return dateType === 'timeOnly' ? that._formatDate(time, 'shorttime') : dateStr + ' ' + that._formatDate(time, 'shorttime');
  3936. case'datehourminute':
  3937. dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
  3938. return dateType === 'timeOnly' ? that._formatDate(value, 'shorttime') : dateStr + ' ' + that._formatDate(value, 'shorttime');
  3939. case'datehourminutesecond':
  3940. dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
  3941. return dateType === 'timeOnly' ? that._formatDate(value, 'longtime') : dateStr + ' ' + that._formatDate(value, 'longtime');
  3942. case'year':
  3943. dateStr = value.toString();
  3944. return dateType === 'abbr' ? dateStr.slice(2, 4) : dateStr;
  3945. case'dateyear':
  3946. return dateType === 'abbr' ? that._formatDate(value, 'shortyear') : that._formatDate(value, 'year');
  3947. case'quarter':
  3948. return utils.stringFormat(that.defaultQuarterFormat, value.toString());
  3949. case'month':
  3950. index = value - 1;
  3951. return dateType === 'abbr' ? calendar.months.namesAbbr[index] : calendar.months.names[index];
  3952. case'hour':
  3953. if (dateType === 'long') {
  3954. time = new Date;
  3955. time.setHours(value);
  3956. time.setMinutes(0);
  3957. return that._formatDate(time, 'shorttime')
  3958. }
  3959. return value.toString();
  3960. case'dayofweek':
  3961. index = utils.isString(value) ? $.inArray(value, ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']) : value;
  3962. if (dateType !== 'num')
  3963. return dateType === 'abbr' ? calendar.days.namesAbbr[index] : calendar.days.names[index];
  3964. return ((index - calendar.firstDay + 1 + 7) % 8).toString();
  3965. default:
  3966. return value.toString()
  3967. }
  3968. else
  3969. return value.toString()
  3970. },
  3971. getTimeFormat: function(showSecond) {
  3972. if (showSecond)
  3973. return this._getDateTimeFormatPattern('longtime');
  3974. return this._getDateTimeFormatPattern('shorttime')
  3975. },
  3976. getDateFormatByDifferences: function(dateDifferences) {
  3977. var resultFormat = '';
  3978. if (dateDifferences.millisecond)
  3979. resultFormat = DX.DateTimeFormat.millisecond;
  3980. if (dateDifferences.hour || dateDifferences.minute || dateDifferences.second)
  3981. resultFormat = this._addFormatSeparator(this.getTimeFormat(dateDifferences.second), resultFormat);
  3982. if (dateDifferences.year && dateDifferences.month && dateDifferences.day)
  3983. return this._addFormatSeparator(this._getDateTimeFormatPattern('shortdate'), resultFormat);
  3984. if (dateDifferences.year && dateDifferences.month)
  3985. return DX.DateTimeFormat['monthandyear'];
  3986. if (dateDifferences.year)
  3987. return DX.DateTimeFormat['year'];
  3988. if (dateDifferences.month && dateDifferences.day)
  3989. return this._addFormatSeparator(this._getDateTimeFormatPattern('monthandday'), resultFormat);
  3990. if (dateDifferences.month)
  3991. return DX.DateTimeFormat['month'];
  3992. if (dateDifferences.day)
  3993. return this._addFormatSeparator('dddd, dd', resultFormat);
  3994. return resultFormat
  3995. },
  3996. getDateFormatByTicks: function(ticks) {
  3997. var resultFormat,
  3998. maxDif,
  3999. currentDif,
  4000. i;
  4001. if (ticks.length > 1) {
  4002. maxDif = utils.getDatesDifferences(ticks[0], ticks[1]);
  4003. for (i = 1; i < ticks.length - 1; i++) {
  4004. currentDif = utils.getDatesDifferences(ticks[i], ticks[i + 1]);
  4005. if (maxDif.count < currentDif.count)
  4006. maxDif = currentDif
  4007. }
  4008. }
  4009. else
  4010. maxDif = {
  4011. year: true,
  4012. month: true,
  4013. day: true,
  4014. hour: ticks[0].getHours() > 0,
  4015. minute: ticks[0].getMinutes() > 0,
  4016. second: ticks[0].getSeconds() > 0
  4017. };
  4018. resultFormat = this.getDateFormatByDifferences(maxDif);
  4019. return resultFormat
  4020. },
  4021. getDateFormatByTickInterval: function(startValue, endValue, tickInterval) {
  4022. var resultFormat,
  4023. dateDifferences,
  4024. dateUnitInterval,
  4025. dateDifferencesConverter = {
  4026. quarter: 'month',
  4027. week: 'day'
  4028. },
  4029. correctDateDifferences = function(dateDifferences, tickInterval, value) {
  4030. switch (tickInterval) {
  4031. case'year':
  4032. dateDifferences.month = value;
  4033. case'quarter':
  4034. case'month':
  4035. dateDifferences.day = value;
  4036. case'week':
  4037. case'day':
  4038. dateDifferences.hour = value;
  4039. case'hour':
  4040. dateDifferences.minute = value;
  4041. case'minute':
  4042. dateDifferences.second = value;
  4043. case'second':
  4044. dateDifferences.millisecond = value
  4045. }
  4046. },
  4047. correctDifferencesByMaxDate = function(differences, minDate, maxDate) {
  4048. if (!maxDate.getMilliseconds() && maxDate.getSeconds()) {
  4049. if (maxDate.getSeconds() - minDate.getSeconds() === 1) {
  4050. differences.millisecond = true;
  4051. differences.second = false
  4052. }
  4053. }
  4054. else if (!maxDate.getSeconds() && maxDate.getMinutes()) {
  4055. if (maxDate.getMinutes() - minDate.getMinutes() === 1) {
  4056. differences.second = true;
  4057. differences.minute = false
  4058. }
  4059. }
  4060. else if (!maxDate.getMinutes() && maxDate.getHours()) {
  4061. if (maxDate.getHours() - minDate.getHours() === 1) {
  4062. differences.minute = true;
  4063. differences.hour = false
  4064. }
  4065. }
  4066. else if (!maxDate.getHours() && maxDate.getDate() > 1) {
  4067. if (maxDate.getDate() - minDate.getDate() === 1) {
  4068. differences.hour = true;
  4069. differences.day = false
  4070. }
  4071. }
  4072. else if (maxDate.getDate() === 1 && maxDate.getMonth()) {
  4073. if (maxDate.getMonth() - minDate.getMonth() === 1) {
  4074. differences.day = true;
  4075. differences.month = false
  4076. }
  4077. }
  4078. else if (!maxDate.getMonth() && maxDate.getFullYear())
  4079. if (maxDate.getFullYear() - minDate.getFullYear() === 1) {
  4080. differences.month = true;
  4081. differences.year = false
  4082. }
  4083. };
  4084. tickInterval = utils.isString(tickInterval) ? tickInterval.toLowerCase() : tickInterval;
  4085. dateDifferences = utils.getDatesDifferences(startValue, endValue);
  4086. if (startValue !== endValue)
  4087. correctDifferencesByMaxDate(dateDifferences, startValue > endValue ? endValue : startValue, startValue > endValue ? startValue : endValue);
  4088. dateUnitInterval = utils.getDateUnitInterval(dateDifferences);
  4089. correctDateDifferences(dateDifferences, dateUnitInterval, true);
  4090. dateUnitInterval = utils.getDateUnitInterval(tickInterval || 'second');
  4091. correctDateDifferences(dateDifferences, dateUnitInterval, false);
  4092. dateDifferences[dateDifferencesConverter[dateUnitInterval] || dateUnitInterval] = true;
  4093. resultFormat = this.getDateFormatByDifferences(dateDifferences);
  4094. return resultFormat
  4095. }
  4096. }
  4097. })(jQuery, DevExpress);
  4098. /*! Module core, file color.js */
  4099. (function(DX, undefined) {
  4100. var standardColorNames = {
  4101. aliceblue: 'f0f8ff',
  4102. antiquewhite: 'faebd7',
  4103. aqua: '00ffff',
  4104. aquamarine: '7fffd4',
  4105. azure: 'f0ffff',
  4106. beige: 'f5f5dc',
  4107. bisque: 'ffe4c4',
  4108. black: '000000',
  4109. blanchedalmond: 'ffebcd',
  4110. blue: '0000ff',
  4111. blueviolet: '8a2be2',
  4112. brown: 'a52a2a',
  4113. burlywood: 'deb887',
  4114. cadetblue: '5f9ea0',
  4115. chartreuse: '7fff00',
  4116. chocolate: 'd2691e',
  4117. coral: 'ff7f50',
  4118. cornflowerblue: '6495ed',
  4119. cornsilk: 'fff8dc',
  4120. crimson: 'dc143c',
  4121. cyan: '00ffff',
  4122. darkblue: '00008b',
  4123. darkcyan: '008b8b',
  4124. darkgoldenrod: 'b8860b',
  4125. darkgray: 'a9a9a9',
  4126. darkgreen: '006400',
  4127. darkkhaki: 'bdb76b',
  4128. darkmagenta: '8b008b',
  4129. darkolivegreen: '556b2f',
  4130. darkorange: 'ff8c00',
  4131. darkorchid: '9932cc',
  4132. darkred: '8b0000',
  4133. darksalmon: 'e9967a',
  4134. darkseagreen: '8fbc8f',
  4135. darkslateblue: '483d8b',
  4136. darkslategray: '2f4f4f',
  4137. darkturquoise: '00ced1',
  4138. darkviolet: '9400d3',
  4139. deeppink: 'ff1493',
  4140. deepskyblue: '00bfff',
  4141. dimgray: '696969',
  4142. dodgerblue: '1e90ff',
  4143. feldspar: 'd19275',
  4144. firebrick: 'b22222',
  4145. floralwhite: 'fffaf0',
  4146. forestgreen: '228b22',
  4147. fuchsia: 'ff00ff',
  4148. gainsboro: 'dcdcdc',
  4149. ghostwhite: 'f8f8ff',
  4150. gold: 'ffd700',
  4151. goldenrod: 'daa520',
  4152. gray: '808080',
  4153. green: '008000',
  4154. greenyellow: 'adff2f',
  4155. honeydew: 'f0fff0',
  4156. hotpink: 'ff69b4',
  4157. indianred: 'cd5c5c',
  4158. indigo: '4b0082',
  4159. ivory: 'fffff0',
  4160. khaki: 'f0e68c',
  4161. lavender: 'e6e6fa',
  4162. lavenderblush: 'fff0f5',
  4163. lawngreen: '7cfc00',
  4164. lemonchiffon: 'fffacd',
  4165. lightblue: 'add8e6',
  4166. lightcoral: 'f08080',
  4167. lightcyan: 'e0ffff',
  4168. lightgoldenrodyellow: 'fafad2',
  4169. lightgrey: 'd3d3d3',
  4170. lightgreen: '90ee90',
  4171. lightpink: 'ffb6c1',
  4172. lightsalmon: 'ffa07a',
  4173. lightseagreen: '20b2aa',
  4174. lightskyblue: '87cefa',
  4175. lightslateblue: '8470ff',
  4176. lightslategray: '778899',
  4177. lightsteelblue: 'b0c4de',
  4178. lightyellow: 'ffffe0',
  4179. lime: '00ff00',
  4180. limegreen: '32cd32',
  4181. linen: 'faf0e6',
  4182. magenta: 'ff00ff',
  4183. maroon: '800000',
  4184. mediumaquamarine: '66cdaa',
  4185. mediumblue: '0000cd',
  4186. mediumorchid: 'ba55d3',
  4187. mediumpurple: '9370d8',
  4188. mediumseagreen: '3cb371',
  4189. mediumslateblue: '7b68ee',
  4190. mediumspringgreen: '00fa9a',
  4191. mediumturquoise: '48d1cc',
  4192. mediumvioletred: 'c71585',
  4193. midnightblue: '191970',
  4194. mintcream: 'f5fffa',
  4195. mistyrose: 'ffe4e1',
  4196. moccasin: 'ffe4b5',
  4197. navajowhite: 'ffdead',
  4198. navy: '000080',
  4199. oldlace: 'fdf5e6',
  4200. olive: '808000',
  4201. olivedrab: '6b8e23',
  4202. orange: 'ffa500',
  4203. orangered: 'ff4500',
  4204. orchid: 'da70d6',
  4205. palegoldenrod: 'eee8aa',
  4206. palegreen: '98fb98',
  4207. paleturquoise: 'afeeee',
  4208. palevioletred: 'd87093',
  4209. papayawhip: 'ffefd5',
  4210. peachpuff: 'ffdab9',
  4211. peru: 'cd853f',
  4212. pink: 'ffc0cb',
  4213. plum: 'dda0dd',
  4214. powderblue: 'b0e0e6',
  4215. purple: '800080',
  4216. red: 'ff0000',
  4217. rosybrown: 'bc8f8f',
  4218. royalblue: '4169e1',
  4219. saddlebrown: '8b4513',
  4220. salmon: 'fa8072',
  4221. sandybrown: 'f4a460',
  4222. seagreen: '2e8b57',
  4223. seashell: 'fff5ee',
  4224. sienna: 'a0522d',
  4225. silver: 'c0c0c0',
  4226. skyblue: '87ceeb',
  4227. slateblue: '6a5acd',
  4228. slategray: '708090',
  4229. snow: 'fffafa',
  4230. springgreen: '00ff7f',
  4231. steelblue: '4682b4',
  4232. tan: 'd2b48c',
  4233. teal: '008080',
  4234. thistle: 'd8bfd8',
  4235. tomato: 'ff6347',
  4236. turquoise: '40e0d0',
  4237. violet: 'ee82ee',
  4238. violetred: 'd02090',
  4239. wheat: 'f5deb3',
  4240. white: 'ffffff',
  4241. whitesmoke: 'f5f5f5',
  4242. yellow: 'ffff00',
  4243. yellowgreen: '9acd32'
  4244. };
  4245. var standardColorTypes = [{
  4246. re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
  4247. process: function(colorString) {
  4248. return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10)]
  4249. }
  4250. }, {
  4251. re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*\.*\d+)\)$/,
  4252. process: function(colorString) {
  4253. return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10), parseFloat(colorString[4])]
  4254. }
  4255. }, {
  4256. re: /^#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})$/,
  4257. process: function(colorString) {
  4258. return [parseInt(colorString[1], 16), parseInt(colorString[2], 16), parseInt(colorString[3], 16)]
  4259. }
  4260. }, {
  4261. re: /^#([a-f0-9]{1})([a-f0-9]{1})([a-f0-9]{1})$/,
  4262. process: function(colorString) {
  4263. return [parseInt(colorString[1] + colorString[1], 16), parseInt(colorString[2] + colorString[2], 16), parseInt(colorString[3] + colorString[3], 16)]
  4264. }
  4265. }, {
  4266. re: /^hsv\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
  4267. process: function(colorString) {
  4268. var h = parseInt(colorString[1], 10),
  4269. s = parseInt(colorString[2], 10),
  4270. v = parseInt(colorString[3], 10),
  4271. rgb = hsvToRgb(h, s, v);
  4272. return [rgb[0], rgb[1], rgb[2], 1, [h, s, v]]
  4273. }
  4274. }, {
  4275. re: /^hsl\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
  4276. process: function(colorString) {
  4277. var h = parseInt(colorString[1], 10),
  4278. s = parseInt(colorString[2], 10),
  4279. l = parseInt(colorString[3], 10),
  4280. rgb = hslToRgb(h, s, l);
  4281. return [rgb[0], rgb[1], rgb[2], 1, null, [h, s, l]]
  4282. }
  4283. }];
  4284. function Color(value) {
  4285. this.baseColor = value;
  4286. var color;
  4287. if (value) {
  4288. color = String(value).toLowerCase().replace(/ /g, '');
  4289. color = standardColorNames[color] ? '#' + standardColorNames[color] : color;
  4290. color = parseColor(color)
  4291. }
  4292. if (!color)
  4293. this.colorIsInvalid = true;
  4294. color = color || {};
  4295. this.r = normalize(color[0]);
  4296. this.g = normalize(color[1]);
  4297. this.b = normalize(color[2]);
  4298. this.a = normalize(color[3], 1, 1);
  4299. if (color[4])
  4300. this.hsv = {
  4301. h: color[4][0],
  4302. s: color[4][1],
  4303. v: color[4][2]
  4304. };
  4305. else
  4306. this.hsv = toHsvFromRgb(this.r, this.g, this.b);
  4307. if (color[5])
  4308. this.hsl = {
  4309. h: color[5][0],
  4310. s: color[5][1],
  4311. l: color[5][2]
  4312. };
  4313. else
  4314. this.hsl = toHslFromRgb(this.r, this.g, this.b)
  4315. }
  4316. function parseColor(color) {
  4317. if (color === "transparent")
  4318. return [0, 0, 0, 0];
  4319. var i = 0,
  4320. ii = standardColorTypes.length,
  4321. str;
  4322. for (; i < ii; ++i) {
  4323. str = standardColorTypes[i].re.exec(color);
  4324. if (str)
  4325. return standardColorTypes[i].process(str)
  4326. }
  4327. return null
  4328. }
  4329. function normalize(colorComponent, def, max) {
  4330. def = def || 0;
  4331. max = max || 255;
  4332. return colorComponent < 0 || isNaN(colorComponent) ? def : colorComponent > max ? max : colorComponent
  4333. }
  4334. function toHexFromRgb(r, g, b) {
  4335. return '#' + (0X01000000 | r << 16 | g << 8 | b).toString(16).slice(1)
  4336. }
  4337. function toHsvFromRgb(r, g, b) {
  4338. var max = Math.max(r, g, b),
  4339. min = Math.min(r, g, b),
  4340. delta = max - min,
  4341. H,
  4342. S,
  4343. V;
  4344. V = max;
  4345. S = max === 0 ? 0 : 1 - min / max;
  4346. if (max === min)
  4347. H = 0;
  4348. else
  4349. switch (max) {
  4350. case r:
  4351. H = 60 * ((g - b) / delta);
  4352. if (g < b)
  4353. H = H + 360;
  4354. break;
  4355. case g:
  4356. H = 60 * ((b - r) / delta) + 120;
  4357. break;
  4358. case b:
  4359. H = 60 * ((r - g) / delta) + 240;
  4360. break
  4361. }
  4362. S *= 100;
  4363. V *= 100 / 255;
  4364. return {
  4365. h: Math.round(H),
  4366. s: Math.round(S),
  4367. v: Math.round(V)
  4368. }
  4369. }
  4370. function hsvToRgb(h, s, v) {
  4371. var Vdec,
  4372. Vinc,
  4373. Vmin,
  4374. Hi,
  4375. a,
  4376. r,
  4377. g,
  4378. b;
  4379. Hi = Math.floor(h / 60);
  4380. Vmin = (100 - s) * v / 100;
  4381. a = (v - Vmin) * (h % 60 / 60);
  4382. Vinc = Vmin + a;
  4383. Vdec = v - a;
  4384. switch (Hi) {
  4385. case 0:
  4386. r = v;
  4387. g = Vinc;
  4388. b = Vmin;
  4389. break;
  4390. case 1:
  4391. r = Vdec;
  4392. g = v;
  4393. b = Vmin;
  4394. break;
  4395. case 2:
  4396. r = Vmin;
  4397. g = v;
  4398. b = Vinc;
  4399. break;
  4400. case 3:
  4401. r = Vmin;
  4402. g = Vdec;
  4403. b = v;
  4404. break;
  4405. case 4:
  4406. r = Vinc;
  4407. g = Vmin;
  4408. b = v;
  4409. break;
  4410. case 5:
  4411. r = v;
  4412. g = Vmin;
  4413. b = Vdec;
  4414. break
  4415. }
  4416. return [Math.round(r * 2.55), Math.round(g * 2.55), Math.round(b * 2.55)]
  4417. }
  4418. function calculateHue(r, g, b, delta) {
  4419. var max = Math.max(r, g, b);
  4420. switch (max) {
  4421. case r:
  4422. return (g - b) / delta + (g < b ? 6 : 0);
  4423. case g:
  4424. return (b - r) / delta + 2;
  4425. case b:
  4426. return (r - g) / delta + 4
  4427. }
  4428. }
  4429. function toHslFromRgb(r, g, b) {
  4430. r = convertTo01Bounds(r, 255);
  4431. g = convertTo01Bounds(g, 255);
  4432. b = convertTo01Bounds(b, 255);
  4433. var max = Math.max(r, g, b),
  4434. min = Math.min(r, g, b),
  4435. maxMinSumm = max + min,
  4436. h,
  4437. s,
  4438. l = maxMinSumm / 2;
  4439. if (max === min)
  4440. h = s = 0;
  4441. else {
  4442. var delta = max - min;
  4443. if (l > 0.5)
  4444. s = delta / (2 - maxMinSumm);
  4445. else
  4446. s = delta / maxMinSumm;
  4447. h = calculateHue(r, g, b, delta);
  4448. h /= 6
  4449. }
  4450. return {
  4451. h: _round(h * 360),
  4452. s: _round(s * 100),
  4453. l: _round(l * 100)
  4454. }
  4455. }
  4456. function makeTc(colorPart, h) {
  4457. var Tc = h;
  4458. if (colorPart === "r")
  4459. Tc = h + 1 / 3;
  4460. if (colorPart === "b")
  4461. Tc = h - 1 / 3;
  4462. return Tc
  4463. }
  4464. function modifyTc(Tc) {
  4465. if (Tc < 0)
  4466. Tc += 1;
  4467. if (Tc > 1)
  4468. Tc -= 1;
  4469. return Tc
  4470. }
  4471. function hueToRgb(p, q, Tc) {
  4472. Tc = modifyTc(Tc);
  4473. if (Tc < 1 / 6)
  4474. return p + (q - p) * 6 * Tc;
  4475. if (Tc < 1 / 2)
  4476. return q;
  4477. if (Tc < 2 / 3)
  4478. return p + (q - p) * (2 / 3 - Tc) * 6;
  4479. return p
  4480. }
  4481. function hslToRgb(h, s, l) {
  4482. var r,
  4483. g,
  4484. b;
  4485. h = convertTo01Bounds(h, 360),
  4486. s = convertTo01Bounds(s, 100),
  4487. l = convertTo01Bounds(l, 100);
  4488. if (s === 0)
  4489. r = g = b = l;
  4490. else {
  4491. var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
  4492. p = 2 * l - q;
  4493. r = hueToRgb(p, q, makeTc("r", h));
  4494. g = hueToRgb(p, q, makeTc("g", h));
  4495. b = hueToRgb(p, q, makeTc("b", h))
  4496. }
  4497. return [_round(r * 255), _round(g * 255), _round(b * 255)]
  4498. }
  4499. function convertTo01Bounds(n, max) {
  4500. n = Math.min(max, Math.max(0, parseFloat(n)));
  4501. if (Math.abs(n - max) < 0.000001)
  4502. return 1;
  4503. return n % max / parseFloat(max)
  4504. }
  4505. function isIntegerBtwMinAndMax(number, min, max) {
  4506. min = min || 0;
  4507. max = max || 255;
  4508. if (number % 1 !== 0 || number < min || number > max || typeof number !== 'number' || isNaN(number))
  4509. return false;
  4510. return true
  4511. }
  4512. var _round = Math.round;
  4513. Color.prototype = {
  4514. constructor: Color,
  4515. highlight: function(step) {
  4516. step = step || 10;
  4517. return this.alter(step).toHex()
  4518. },
  4519. darken: function(step) {
  4520. step = step || 10;
  4521. return this.alter(-step).toHex()
  4522. },
  4523. alter: function(step) {
  4524. var result = new Color;
  4525. result.r = normalize(this.r + step);
  4526. result.g = normalize(this.g + step);
  4527. result.b = normalize(this.b + step);
  4528. return result
  4529. },
  4530. blend: function(blendColor, opacity) {
  4531. var other = blendColor instanceof Color ? blendColor : new Color(blendColor),
  4532. result = new Color;
  4533. result.r = normalize(_round(this.r * (1 - opacity) + other.r * opacity));
  4534. result.g = normalize(_round(this.g * (1 - opacity) + other.g * opacity));
  4535. result.b = normalize(_round(this.b * (1 - opacity) + other.b * opacity));
  4536. return result
  4537. },
  4538. toHex: function() {
  4539. return toHexFromRgb(this.r, this.g, this.b)
  4540. },
  4541. getPureColor: function() {
  4542. var rgb = hsvToRgb(this.hsv.h, 100, 100);
  4543. return new Color("rgb(" + rgb.join(",") + ")")
  4544. },
  4545. isValidHex: function(hex) {
  4546. return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex)
  4547. },
  4548. isValidRGB: function(r, g, b) {
  4549. if (!isIntegerBtwMinAndMax(r) || !isIntegerBtwMinAndMax(g) || !isIntegerBtwMinAndMax(b))
  4550. return false;
  4551. return true
  4552. },
  4553. isValidAlpha: function(a) {
  4554. if (isNaN(a) || a < 0 || a > 1 || typeof a !== 'number')
  4555. return false;
  4556. return true
  4557. },
  4558. colorIsInvalid: false
  4559. };
  4560. DX.Color = Color
  4561. })(DevExpress);
  4562. /*! Module core, file localization.js */
  4563. (function($, DX, undefined) {
  4564. Globalize.localize = function(key, cultureSelector) {
  4565. var neutral = (cultureSelector || this.cultureSelector || "").substring(0, 2);
  4566. return this.findClosestCulture(cultureSelector).messages[key] || this.findClosestCulture(neutral).messages[key] || this.cultures["default"].messages[key]
  4567. };
  4568. var localization = function() {
  4569. var newMessages = {};
  4570. return {
  4571. setup: function(localizablePrefix) {
  4572. this.localizeString = function(text) {
  4573. var regex = new RegExp("(^|[^a-zA-Z_0-9" + localizablePrefix + "-]+)(" + localizablePrefix + "{1,2})([a-zA-Z_0-9-]+)", "g"),
  4574. escapeString = localizablePrefix + localizablePrefix;
  4575. return text.replace(regex, function(str, prefix, escape, localizationKey) {
  4576. var result = prefix + localizablePrefix + localizationKey;
  4577. if (escape !== escapeString)
  4578. if (Globalize.cultures["default"].messages[localizationKey])
  4579. result = prefix + Globalize.localize(localizationKey);
  4580. else
  4581. newMessages[localizationKey] = DX.inflector.humanize(localizationKey);
  4582. return result
  4583. })
  4584. }
  4585. },
  4586. localizeNode: function(node) {
  4587. var that = this;
  4588. $(node).each(function(index, nodeItem) {
  4589. if (!nodeItem.nodeType)
  4590. return;
  4591. if (nodeItem.nodeType === 3)
  4592. nodeItem.nodeValue = that.localizeString(nodeItem.nodeValue);
  4593. else if (!$(nodeItem).is("iframe")) {
  4594. $.each(nodeItem.attributes || [], function(index, attr) {
  4595. if (typeof attr.value === "string") {
  4596. var localizedValue = that.localizeString(attr.value);
  4597. if (attr.value !== localizedValue)
  4598. attr.value = localizedValue
  4599. }
  4600. });
  4601. $(nodeItem).contents().each(function(index, node) {
  4602. that.localizeNode(node)
  4603. })
  4604. }
  4605. })
  4606. },
  4607. getDictionary: function(onlyNew) {
  4608. if (onlyNew)
  4609. return newMessages;
  4610. return $.extend({}, newMessages, Globalize.cultures["default"].messages)
  4611. }
  4612. }
  4613. }();
  4614. localization.setup("@");
  4615. DX.localization = localization
  4616. })(jQuery, DevExpress);
  4617. /*! Module core, file core.en.js */
  4618. Globalize.addCultureInfo("default", {messages: {
  4619. Yes: "Yes",
  4620. No: "No",
  4621. Cancel: "Cancel",
  4622. Clear: "Clear",
  4623. Done: "Done",
  4624. Loading: "Loading...",
  4625. Select: "Select...",
  4626. Search: "Search",
  4627. Back: "Back",
  4628. OK: "OK",
  4629. "dxCollectionWidget-noDataText": "No data to display",
  4630. "validation-required": "Required",
  4631. "validation-required-formatted": "{0} is required",
  4632. "validation-numeric": "Value must be a number",
  4633. "validation-numeric-formatted": "{0} must be a number",
  4634. "validation-range": "Value is out of range",
  4635. "validation-range-formatted": "{0} is out of range",
  4636. "validation-stringLength": "The length of the value is not correct",
  4637. "validation-stringLength-formatted": "The length of {0} is not correct",
  4638. "validation-custom": "Value is invalid",
  4639. "validation-custom-formatted": "{0} is invalid",
  4640. "validation-compare": "Values do not match",
  4641. "validation-compare-formatted": "{0} does not match",
  4642. "validation-pattern": "Value does not match pattern",
  4643. "validation-pattern-formatted": "{0} does not match pattern",
  4644. "validation-email": "Email is invalid",
  4645. "validation-email-formatted": "{0} is invalid",
  4646. "validation-mask": "Value is invalid"
  4647. }});
  4648. /*! Module core, file widgets-base.en.js */
  4649. Globalize.addCultureInfo("default", {messages: {
  4650. "dxLookup-searchPlaceholder": "Minimum character number: {0}",
  4651. "dxList-pullingDownText": "Pull down to refresh...",
  4652. "dxList-pulledDownText": "Release to refresh...",
  4653. "dxList-refreshingText": "Refreshing...",
  4654. "dxList-pageLoadingText": "Loading...",
  4655. "dxList-nextButtonText": "More",
  4656. "dxList-selectAll": "Select All",
  4657. "dxListEditDecorator-delete": "Delete",
  4658. "dxListEditDecorator-more": "More",
  4659. "dxScrollView-pullingDownText": "Pull down to refresh...",
  4660. "dxScrollView-pulledDownText": "Release to refresh...",
  4661. "dxScrollView-refreshingText": "Refreshing...",
  4662. "dxScrollView-reachBottomText": "Loading...",
  4663. "dxDateBox-simulatedDataPickerTitleTime": "Select time",
  4664. "dxDateBox-simulatedDataPickerTitleDate": "Select date",
  4665. "dxDateBox-simulatedDataPickerTitleDateTime": "Select date and time",
  4666. "dxDateBox-validation-datetime": "Value must be a date or time",
  4667. "dxFileUploader-selectFile": "Select file",
  4668. "dxFileUploader-dropFile": "or Drop file here",
  4669. "dxFileUploader-bytes": "bytes",
  4670. "dxFileUploader-kb": "kb",
  4671. "dxFileUploader-Mb": "Mb",
  4672. "dxFileUploader-Gb": "Gb",
  4673. "dxFileUploader-upload": "Upload",
  4674. "dxFileUploader-uploaded": "Uploaded",
  4675. "dxFileUploader-readyToUpload": "Ready to upload",
  4676. "dxFileUploader-uploadFailedMessage": "Upload failed",
  4677. "dxRangeSlider-ariaFrom": "From {0}",
  4678. "dxRangeSlider-ariaTill": "Till {0}",
  4679. "dxSwitch-onText": "ON",
  4680. "dxSwitch-offText": "OFF"
  4681. }});
  4682. /*! Module core, file widgets-mobile.en.js */
  4683. /*! Module core, file widgets-web.en.js */
  4684. Globalize.addCultureInfo("default", {messages: {
  4685. "dxDataGrid-columnChooserTitle": "Column Chooser",
  4686. "dxDataGrid-columnChooserEmptyText": "Drag a column here to hide it",
  4687. "dxDataGrid-groupContinuesMessage": "Continues on the next page",
  4688. "dxDataGrid-groupContinuedMessage": "Continued from the previous page",
  4689. "dxDataGrid-editingEditRow": "Edit",
  4690. "dxDataGrid-editingSaveRowChanges": "Save",
  4691. "dxDataGrid-editingCancelRowChanges": "Cancel",
  4692. "dxDataGrid-editingDeleteRow": "Delete",
  4693. "dxDataGrid-editingUndeleteRow": "Undelete",
  4694. "dxDataGrid-editingConfirmDeleteMessage": "Are you sure you want to delete this record?",
  4695. "dxDataGrid-editingConfirmDeleteTitle": "",
  4696. "dxDataGrid-groupPanelEmptyText": "Drag a column header here to group by that column",
  4697. "dxDataGrid-noDataText": "No data",
  4698. "dxDataGrid-searchPanelPlaceholder": "Search...",
  4699. "dxDataGrid-filterRowShowAllText": "(All)",
  4700. "dxDataGrid-filterRowResetOperationText": "Reset",
  4701. "dxDataGrid-filterRowOperationEquals": "Equals",
  4702. "dxDataGrid-filterRowOperationNotEquals": "Does not equal",
  4703. "dxDataGrid-filterRowOperationLess": "Less than",
  4704. "dxDataGrid-filterRowOperationLessOrEquals": "Less than or equal to",
  4705. "dxDataGrid-filterRowOperationGreater": "Greater than",
  4706. "dxDataGrid-filterRowOperationGreaterOrEquals": "Greater than or equal to",
  4707. "dxDataGrid-filterRowOperationStartsWith": "Starts with",
  4708. "dxDataGrid-filterRowOperationContains": "Contains",
  4709. "dxDataGrid-filterRowOperationNotContains": "Does not contain",
  4710. "dxDataGrid-filterRowOperationEndsWith": "Ends with",
  4711. "dxDataGrid-applyFilterText": "Apply filter",
  4712. "dxDataGrid-trueText": "true",
  4713. "dxDataGrid-falseText": "false",
  4714. "dxDataGrid-sortingAscendingText": "Sort Ascending",
  4715. "dxDataGrid-sortingDescendingText": "Sort Descending",
  4716. "dxDataGrid-sortingClearText": "Clear Sorting",
  4717. "dxDataGrid-editingSaveAllChanges": "Save changes",
  4718. "dxDataGrid-editingCancelAllChanges": "Discard changes",
  4719. "dxDataGrid-editingAddRow": "Add a row",
  4720. "dxDataGrid-summaryMin": "Min: {0}",
  4721. "dxDataGrid-summaryMinOtherColumn": "Min of {1} is {0}",
  4722. "dxDataGrid-summaryMax": "Max: {0}",
  4723. "dxDataGrid-summaryMaxOtherColumn": "Max of {1} is {0}",
  4724. "dxDataGrid-summaryAvg": "Avg: {0}",
  4725. "dxDataGrid-summaryAvgOtherColumn": "Avg of {1} is {0}",
  4726. "dxDataGrid-summarySum": "Sum: {0}",
  4727. "dxDataGrid-summarySumOtherColumn": "Sum of {1} is {0}",
  4728. "dxDataGrid-summaryCount": "Count: {0}",
  4729. "dxDataGrid-columnFixingFix": "Fix",
  4730. "dxDataGrid-columnFixingUnfix": "Unfix",
  4731. "dxDataGrid-columnFixingLeftPosition": "To the left",
  4732. "dxDataGrid-columnFixingRightPosition": "To the right",
  4733. "dxDataGrid-exportTo": "Export to",
  4734. "dxDataGrid-exportToExcel": "Export to Excel file",
  4735. "dxDataGrid-excelFormat": "Excel file",
  4736. "dxDataGrid-selectedRows": "Selected rows",
  4737. "dxDataGrid-headerFilterEmptyValue": "(Blanks)",
  4738. "dxDataGrid-headerFilterOK": "OK",
  4739. "dxDataGrid-headerFilterCancel": "Cancel",
  4740. "dxDataGrid-ariaColumn": "Column",
  4741. "dxDataGrid-ariaValue": "Value",
  4742. "dxDataGrid-ariaFilterCell": "Filter cell",
  4743. "dxDataGrid-ariaCollapse": "Collapse",
  4744. "dxDataGrid-ariaExpand": "Expand",
  4745. "dxDataGrid-ariaDataGrid": "Data grid",
  4746. "dxDataGrid-ariaSearchInGrid": "Search in data grid",
  4747. "dxDataGrid-ariaSelectAll": "Select all",
  4748. "dxDataGrid-ariaSelectRow": "Select row",
  4749. "dxPager-infoText": "Page {0} of {1}",
  4750. "dxPivotGrid-grandTotal": "Grand Total",
  4751. "dxPivotGrid-total": "{0} Total",
  4752. "dxPivotGrid-fieldChooserTitle": "Field Chooser",
  4753. "dxPivotGrid-showFieldChooser": "Show Field Chooser",
  4754. "dxPivotGrid-expandAll": "Expand All",
  4755. "dxPivotGrid-collapseAll": "Collapse All",
  4756. "dxPivotGrid-sortColumnBySummary": "Sort \"{0}\" by This Column",
  4757. "dxPivotGrid-sortRowBySummary": "Sort \"{0}\" by This Row",
  4758. "dxPivotGrid-removeAllSorting": "Remove All Sorting",
  4759. "dxPivotGrid-rowFields": "Row Fields",
  4760. "dxPivotGrid-columnFields": "Column Fields",
  4761. "dxPivotGrid-dataFields": "Data Fields",
  4762. "dxPivotGrid-filterFields": "Filter Fields",
  4763. "dxPivotGrid-allFields": "All Fields",
  4764. "dxScheduler-editorLabelTitle": "Subject",
  4765. "dxScheduler-editorLabelStartDate": "Start Date",
  4766. "dxScheduler-editorLabelEndDate": "End Date",
  4767. "dxScheduler-editorLabelDescription": "Description",
  4768. "dxScheduler-editorLabelRecurrence": "Repeat",
  4769. "dxScheduler-openAppointment": "Open appointment",
  4770. "dxScheduler-recurrenceNever": "Never",
  4771. "dxScheduler-recurrenceDaily": "Daily",
  4772. "dxScheduler-recurrenceWeekly": "Weekly",
  4773. "dxScheduler-recurrenceMonthly": "Monthly",
  4774. "dxScheduler-recurrenceYearly": "Yearly",
  4775. "dxScheduler-recurrenceEvery": "Every",
  4776. "dxScheduler-recurrenceEnd": "End repeat",
  4777. "dxScheduler-recurrenceAfter": "After",
  4778. "dxScheduler-recurrenceOn": "On",
  4779. "dxScheduler-recurrenceRepeatDaily": "day(s)",
  4780. "dxScheduler-recurrenceRepeatWeekly": "week(s)",
  4781. "dxScheduler-recurrenceRepeatMonthly": "month(s)",
  4782. "dxScheduler-recurrenceRepeatYearly": "year(s)",
  4783. "dxScheduler-switcherDay": "Day",
  4784. "dxScheduler-switcherWeek": "Week",
  4785. "dxScheduler-switcherWorkWeek": "Work week",
  4786. "dxScheduler-switcherMonth": "Month",
  4787. "dxScheduler-recurrenceRepeatOnDate": "on date",
  4788. "dxScheduler-recurrenceRepeatCount": "occurrence(s)",
  4789. "dxScheduler-allDay": "All day",
  4790. "dxCalendar-todayButtonText": "Today",
  4791. "dxCalendar-ariaWidgetName": "Calendar",
  4792. "dxColorView-ariaRed": "Red",
  4793. "dxColorView-ariaGreen": "Green",
  4794. "dxColorView-ariaBlue": "Blue",
  4795. "dxColorView-ariaAlpha": "Transparency",
  4796. "dxColorView-ariaHex": "Color code"
  4797. }});
  4798. /*! Module core, file validationEngine.js */
  4799. (function($, DX, undefined) {
  4800. var utils = DX.utils;
  4801. var rulesValidators = {
  4802. required: {
  4803. validate: function(value, rule) {
  4804. if (!utils.isDefined(value))
  4805. return false;
  4806. if (value === false)
  4807. return false;
  4808. value = String(value);
  4809. if (rule.trim || !utils.isDefined(rule.trim))
  4810. value = $.trim(value);
  4811. return value !== ""
  4812. },
  4813. defaultMessage: function() {
  4814. return Globalize.localize("validation-required")
  4815. },
  4816. defaultFormattedMessage: function() {
  4817. return Globalize.localize("validation-required-formatted")
  4818. }
  4819. },
  4820. numeric: {
  4821. validate: function(value, rule) {
  4822. if (!rulesValidators.required.validate(value, {}))
  4823. return true;
  4824. if (rule.useCultureSettings && utils.isString(value))
  4825. return !isNaN(Globalize.parseFloat(value));
  4826. else
  4827. return $.isNumeric(value)
  4828. },
  4829. defaultMessage: function() {
  4830. return Globalize.localize("validation-numeric")
  4831. },
  4832. defaultFormattedMessage: function() {
  4833. return Globalize.localize("validation-numeric-formatted")
  4834. }
  4835. },
  4836. range: {
  4837. validate: function(value, rule) {
  4838. if (!rulesValidators.required.validate(value, {}))
  4839. return true;
  4840. var validNumber = rulesValidators["numeric"].validate(value, rule),
  4841. validValue = utils.isDefined(value),
  4842. number = validNumber ? parseFloat(value) : validValue && value.valueOf(),
  4843. min = rule.min,
  4844. max = rule.max;
  4845. if (!(validNumber || utils.isDate(value)) && !validValue)
  4846. return false;
  4847. if (utils.isDefined(min)) {
  4848. if (utils.isDefined(max))
  4849. return number >= min && number <= max;
  4850. return number >= min
  4851. }
  4852. else if (utils.isDefined(max))
  4853. return number <= max;
  4854. else
  4855. throw DX.Error("E0101");
  4856. return false
  4857. },
  4858. defaultMessage: function() {
  4859. return Globalize.localize("validation-range")
  4860. },
  4861. defaultFormattedMessage: function() {
  4862. return Globalize.localize("validation-range-formatted")
  4863. }
  4864. },
  4865. stringLength: {
  4866. validate: function(value, rule) {
  4867. value = String(value);
  4868. if (rule.trim || !utils.isDefined(rule.trim))
  4869. value = $.trim(value);
  4870. return rulesValidators.range.validate(value.length, $.extend({}, rule))
  4871. },
  4872. defaultMessage: function() {
  4873. return Globalize.localize("validation-stringLength")
  4874. },
  4875. defaultFormattedMessage: function() {
  4876. return Globalize.localize("validation-stringLength-formatted")
  4877. }
  4878. },
  4879. custom: {
  4880. validate: function(value, rule) {
  4881. return rule.validationCallback({
  4882. value: value,
  4883. validator: rule.validator,
  4884. rule: rule
  4885. })
  4886. },
  4887. defaultMessage: function() {
  4888. return Globalize.localize("validation-custom")
  4889. },
  4890. defaultFormattedMessage: function() {
  4891. return Globalize.localize("validation-custom-formatted")
  4892. }
  4893. },
  4894. compare: {
  4895. validate: function(value, rule) {
  4896. if (!rule.comparisonTarget)
  4897. throw DX.Error("E0102");
  4898. $.extend(rule, {reevaluate: true});
  4899. var otherValue = rule.comparisonTarget(),
  4900. type = rule.comparisonType || "==";
  4901. switch (type) {
  4902. case"==":
  4903. return value == otherValue;
  4904. case"!=":
  4905. return value != otherValue;
  4906. case"===":
  4907. return value === otherValue;
  4908. case"!==":
  4909. return value !== otherValue;
  4910. case">":
  4911. return value > otherValue;
  4912. case">=":
  4913. return value >= otherValue;
  4914. case"<":
  4915. return value < otherValue;
  4916. case"<=":
  4917. return value <= otherValue
  4918. }
  4919. },
  4920. defaultMessage: function() {
  4921. return Globalize.localize("validation-compare")
  4922. },
  4923. defaultFormattedMessage: function() {
  4924. return Globalize.localize("validation-compare-formatted")
  4925. }
  4926. },
  4927. pattern: {
  4928. validate: function(value, rule) {
  4929. if (!rulesValidators.required.validate(value, {}))
  4930. return true;
  4931. var pattern = rule.pattern;
  4932. if (utils.isString(pattern))
  4933. pattern = new RegExp(pattern);
  4934. return pattern.test(value)
  4935. },
  4936. defaultMessage: function() {
  4937. return Globalize.localize("validation-pattern")
  4938. },
  4939. defaultFormattedMessage: function() {
  4940. return Globalize.localize("validation-pattern-formatted")
  4941. }
  4942. },
  4943. email: {
  4944. validate: function(value, rule) {
  4945. if (!rulesValidators.required.validate(value, {}))
  4946. return true;
  4947. return rulesValidators.pattern.validate(value, $.extend({}, rule, {pattern: /^[\d\w\._\-]+@([\d\w\._\-]+\.)+[\w]+$/i}))
  4948. },
  4949. defaultMessage: function() {
  4950. return Globalize.localize("validation-email")
  4951. },
  4952. defaultFormattedMessage: function() {
  4953. return Globalize.localize("validation-email-formatted")
  4954. }
  4955. }
  4956. };
  4957. var GroupConfig = DX.Class.inherit({
  4958. ctor: function(group) {
  4959. this.group = group;
  4960. this.validators = []
  4961. },
  4962. validate: function() {
  4963. var result = {
  4964. isValid: true,
  4965. brokenRules: [],
  4966. validators: []
  4967. };
  4968. $.each(this.validators, function(_, validator) {
  4969. var validatorResult = validator.validate();
  4970. result.isValid = result.isValid && validatorResult.isValid;
  4971. if (validatorResult.brokenRule)
  4972. result.brokenRules.push(validatorResult.brokenRule);
  4973. result.validators.push(validator)
  4974. });
  4975. this.fireEvent("validated", [{
  4976. validators: result.validators,
  4977. brokenRules: result.brokenRules,
  4978. isValid: result.isValid
  4979. }]);
  4980. return result
  4981. },
  4982. reset: function() {
  4983. $.each(this.validators, function(_, validator) {
  4984. validator.reset()
  4985. })
  4986. }
  4987. }).include(DX.EventsMixin);
  4988. DX.validationEngine = {
  4989. groups: [],
  4990. getGroupConfig: function(group) {
  4991. var result = $.grep(this.groups, function(config) {
  4992. return config.group === group
  4993. });
  4994. if (result.length)
  4995. return result[0]
  4996. },
  4997. initGroups: function() {
  4998. this.groups = [];
  4999. this.addGroup()
  5000. },
  5001. addGroup: function(group) {
  5002. var config = this.getGroupConfig(group);
  5003. if (!config) {
  5004. config = new GroupConfig(group);
  5005. this.groups.push(config)
  5006. }
  5007. return config
  5008. },
  5009. removeGroup: function(group) {
  5010. var config = this.getGroupConfig(group),
  5011. index = $.inArray(config, this.groups);
  5012. if (index > -1)
  5013. this.groups.splice(index, 1);
  5014. return config
  5015. },
  5016. _setDefaultMessage: function(rule, validator, name) {
  5017. if (!utils.isDefined(rule.message))
  5018. if (validator.defaultFormattedMessage && utils.isDefined(name))
  5019. rule.message = validator.defaultFormattedMessage().replace(/\{0\}/, name);
  5020. else
  5021. rule.message = validator.defaultMessage()
  5022. },
  5023. validate: function validate(value, rules, name) {
  5024. var result = {
  5025. name: name,
  5026. value: value,
  5027. brokenRule: null,
  5028. isValid: true,
  5029. validationRules: rules
  5030. },
  5031. that = this;
  5032. $.each(rules || [], function(_, rule) {
  5033. var ruleValidator = rulesValidators[rule.type],
  5034. ruleValidationResult;
  5035. if (ruleValidator) {
  5036. if (utils.isDefined(rule.isValid) && rule.value === value && !rule.reevaluate) {
  5037. if (!rule.isValid) {
  5038. result.isValid = false;
  5039. result.brokenRule = rule;
  5040. return false
  5041. }
  5042. return true
  5043. }
  5044. rule.value = value;
  5045. ruleValidationResult = ruleValidator.validate(value, rule);
  5046. rule.isValid = ruleValidationResult;
  5047. if (!ruleValidationResult) {
  5048. result.isValid = false;
  5049. that._setDefaultMessage(rule, ruleValidator, name);
  5050. result.brokenRule = rule
  5051. }
  5052. if (!rule.isValid)
  5053. return false
  5054. }
  5055. else
  5056. throw DX.Error("E0100");
  5057. });
  5058. return result
  5059. },
  5060. registerValidatorInGroup: function(group, validator) {
  5061. var groupConfig = DX.validationEngine.addGroup(group);
  5062. if ($.inArray(validator, groupConfig.validators) < 0)
  5063. groupConfig.validators.push(validator)
  5064. },
  5065. removeRegistredValidator: function(group, validator) {
  5066. var config = DX.validationEngine.getGroupConfig(group),
  5067. validatorsInGroup = config && config.validators;
  5068. var index = $.inArray(validator, validatorsInGroup);
  5069. if (index > -1)
  5070. validatorsInGroup.splice(index, 1)
  5071. },
  5072. validateGroup: function(group) {
  5073. var groupConfig = DX.validationEngine.getGroupConfig(group);
  5074. if (!groupConfig)
  5075. throw DX.Error("E0110");
  5076. return groupConfig.validate()
  5077. },
  5078. resetGroup: function(group) {
  5079. var groupConfig = DX.validationEngine.getGroupConfig(group);
  5080. if (!groupConfig)
  5081. throw DX.Error("E0110");
  5082. return groupConfig.reset()
  5083. }
  5084. };
  5085. DX.validationEngine.initGroups()
  5086. })(jQuery, DevExpress);
  5087. /*! Module core, file data.errors.js */
  5088. (function($, DX) {
  5089. $.extend(DX.ERROR_MESSAGES, {
  5090. E4000: "[DevExpress.data]: {0}",
  5091. E4001: "Unknown aggregating function is detected: '{0}'",
  5092. E4002: "Unsupported OData protocol version is used",
  5093. E4003: "Unknown filter operation is used: {0}",
  5094. E4004: "The thenby() method is called before the sortby() method",
  5095. E4005: "Store requires a key expression for this operation",
  5096. E4006: "ArrayStore 'data' option must be an array",
  5097. E4007: "Compound keys cannot be auto-generated",
  5098. E4008: "Attempt to insert an item with the a duplicated key",
  5099. E4009: "Data item with specified key value cannot be found",
  5100. E4010: "CustomStore does not support creating queries",
  5101. E4011: "Custom Store method is not implemented or is not a function: {0}",
  5102. E4012: "Custom Store method returns an invalid value: {0}",
  5103. E4013: "Local Store requires the 'name' configuration option is specified",
  5104. E4014: "Unknown key type is detected: {0}",
  5105. E4015: "Unknown entity name or alias is used: {0}",
  5106. E4016: "The compileSetter(expr) method is called with 'self' passed as a parameter",
  5107. E4017: "Keys cannot be modified"
  5108. })
  5109. })(jQuery, DevExpress);
  5110. /*! Module core, file data.js */
  5111. (function($, DX, undefined) {
  5112. var bracketsToDots = function(expr) {
  5113. return expr.replace(/\[/g, ".").replace(/\]/g, "")
  5114. };
  5115. var unwrapObservable = DX.utils.unwrapObservable;
  5116. var isObservable = function(value) {
  5117. return DX.support.hasKo && ko.isObservable(value)
  5118. };
  5119. var readPropValue = function(obj, propName) {
  5120. if (propName === "this")
  5121. return obj;
  5122. return obj[propName]
  5123. };
  5124. var assignPropValue = function(obj, propName, value, options) {
  5125. if (propName === "this")
  5126. throw new DX.Error("E4016");
  5127. var propValue = obj[propName];
  5128. if (options.unwrapObservables && isObservable(propValue))
  5129. propValue(value);
  5130. else
  5131. obj[propName] = value
  5132. };
  5133. var prepareOptions = function(options) {
  5134. options = options || {};
  5135. options.unwrapObservables = options.unwrapObservables !== undefined ? options.unwrapObservables : true;
  5136. return options
  5137. };
  5138. var unwrap = function(value, options) {
  5139. return options.unwrapObservables ? unwrapObservable(value) : value
  5140. };
  5141. var compileGetter = function(expr) {
  5142. if (arguments.length > 1)
  5143. expr = $.makeArray(arguments);
  5144. if (!expr || expr === "this")
  5145. return function(obj) {
  5146. return obj
  5147. };
  5148. if ($.isFunction(expr))
  5149. return expr;
  5150. if ($.isArray(expr))
  5151. return combineGetters(expr);
  5152. expr = bracketsToDots(expr);
  5153. var path = expr.split(".");
  5154. return function(obj, options) {
  5155. options = prepareOptions(options);
  5156. var current = unwrap(obj, options);
  5157. $.each(path, function() {
  5158. if (!current)
  5159. return false;
  5160. var next = unwrap(current[this], options);
  5161. if ($.isFunction(next) && !options.functionsAsIs)
  5162. next = next.call(current);
  5163. current = next
  5164. });
  5165. return current
  5166. }
  5167. };
  5168. var combineGetters = function(getters) {
  5169. var compiledGetters = {};
  5170. $.each(getters, function() {
  5171. compiledGetters[this] = compileGetter(this)
  5172. });
  5173. return function(obj, options) {
  5174. var result = {};
  5175. $.each(compiledGetters, function(name) {
  5176. var value = this(obj, options),
  5177. current,
  5178. path,
  5179. last,
  5180. i;
  5181. if (value === undefined)
  5182. return;
  5183. current = result;
  5184. path = name.split(".");
  5185. last = path.length - 1;
  5186. for (i = 0; i < last; i++)
  5187. current = current[path[i]] = {};
  5188. current[path[i]] = value
  5189. });
  5190. return result
  5191. }
  5192. };
  5193. var compileSetter = function(expr) {
  5194. expr = expr || "this";
  5195. expr = bracketsToDots(expr);
  5196. var pos = expr.lastIndexOf("."),
  5197. targetGetter = compileGetter(expr.substr(0, pos)),
  5198. targetPropName = expr.substr(1 + pos);
  5199. return function(obj, value, options) {
  5200. options = prepareOptions(options);
  5201. var target = targetGetter(obj, {
  5202. functionsAsIs: options.functionsAsIs,
  5203. unwrapObservables: options.unwrapObservables
  5204. }),
  5205. prevTargetValue = readPropValue(target, targetPropName);
  5206. if (!options.functionsAsIs && $.isFunction(prevTargetValue) && !isObservable(prevTargetValue))
  5207. target[targetPropName](value);
  5208. else {
  5209. prevTargetValue = unwrap(prevTargetValue, options);
  5210. if (options.merge && $.isPlainObject(value) && (prevTargetValue === undefined || $.isPlainObject(prevTargetValue)) && !(value instanceof $.Event)) {
  5211. if (!prevTargetValue)
  5212. assignPropValue(target, targetPropName, {}, options);
  5213. DX.utils.deepExtendArraySafe(unwrap(readPropValue(target, targetPropName), options), value)
  5214. }
  5215. else
  5216. assignPropValue(target, targetPropName, value, options)
  5217. }
  5218. }
  5219. };
  5220. var normalizeBinaryCriterion = function(crit) {
  5221. return [crit[0], crit.length < 3 ? "=" : String(crit[1]).toLowerCase(), crit.length < 2 ? true : crit[crit.length - 1]]
  5222. };
  5223. var normalizeSortingInfo = function(info) {
  5224. if (!$.isArray(info))
  5225. info = [info];
  5226. return $.map(info, function(i) {
  5227. return {
  5228. selector: $.isFunction(i) || typeof i === "string" ? i : i.getter || i.field || i.selector,
  5229. desc: !!(i.desc || String(i.dir).charAt(0).toLowerCase() === "d")
  5230. }
  5231. })
  5232. };
  5233. var Guid = DX.Class.inherit({
  5234. ctor: function(value) {
  5235. if (value)
  5236. value = String(value);
  5237. this._value = this._normalize(value || this._generate())
  5238. },
  5239. _normalize: function(value) {
  5240. value = value.replace(/[^a-f0-9]/ig, "").toLowerCase();
  5241. while (value.length < 32)
  5242. value += "0";
  5243. return [value.substr(0, 8), value.substr(8, 4), value.substr(12, 4), value.substr(16, 4), value.substr(20, 12)].join("-")
  5244. },
  5245. _generate: function() {
  5246. var value = "";
  5247. for (var i = 0; i < 32; i++)
  5248. value += Math.round(Math.random() * 15).toString(16);
  5249. return value
  5250. },
  5251. toString: function() {
  5252. return this._value
  5253. },
  5254. valueOf: function() {
  5255. return this._value
  5256. },
  5257. toJSON: function() {
  5258. return this._value
  5259. }
  5260. });
  5261. var toComparable = function(value, caseSensitive) {
  5262. if (value instanceof Date)
  5263. return value.getTime();
  5264. if (value instanceof Guid)
  5265. return value.valueOf();
  5266. if (!caseSensitive && typeof value === "string")
  5267. return value.toLowerCase();
  5268. return value
  5269. };
  5270. var keysEqual = function(keyExpr, key1, key2) {
  5271. if ($.isArray(keyExpr)) {
  5272. var names = $.map(key1, function(v, k) {
  5273. return k
  5274. }),
  5275. name;
  5276. for (var i = 0; i < names.length; i++) {
  5277. name = names[i];
  5278. if (toComparable(key1[name], true) != toComparable(key2[name], true))
  5279. return false
  5280. }
  5281. return true
  5282. }
  5283. return toComparable(key1, true) == toComparable(key2, true)
  5284. };
  5285. var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  5286. var base64_encode = function(input) {
  5287. if (!$.isArray(input))
  5288. input = stringToByteArray(String(input));
  5289. var result = "";
  5290. function getBase64Char(index) {
  5291. return BASE64_CHARS.charAt(index)
  5292. }
  5293. for (var i = 0; i < input.length; i += 3) {
  5294. var octet1 = input[i],
  5295. octet2 = input[i + 1],
  5296. octet3 = input[i + 2];
  5297. result += $.map([octet1 >> 2, (octet1 & 3) << 4 | octet2 >> 4, isNaN(octet2) ? 64 : (octet2 & 15) << 2 | octet3 >> 6, isNaN(octet3) ? 64 : octet3 & 63], getBase64Char).join("")
  5298. }
  5299. return result
  5300. };
  5301. var stringToByteArray = function(str) {
  5302. var bytes = [],
  5303. code,
  5304. i;
  5305. for (i = 0; i < str.length; i++) {
  5306. code = str.charCodeAt(i);
  5307. if (code < 128)
  5308. bytes.push(code);
  5309. else if (code < 2048)
  5310. bytes.push(192 + (code >> 6), 128 + (code & 63));
  5311. else if (code < 65536)
  5312. bytes.push(224 + (code >> 12), 128 + (code >> 6 & 63), 128 + (code & 63));
  5313. else if (code < 2097152)
  5314. bytes.push(240 + (code >> 18), 128 + (code >> 12 & 63), 128 + (code >> 6 & 63), 128 + (code & 63))
  5315. }
  5316. return bytes
  5317. };
  5318. var errorMessageFromXhr = function() {
  5319. var textStatusMessages = {
  5320. timeout: "Network connection timeout",
  5321. error: "Unspecified network error",
  5322. parsererror: "Unexpected server response"
  5323. };
  5324. var textStatusDetails = {
  5325. timeout: "possible causes: the remote host is not accessible, overloaded or is not included into the domain white-list when being run in the native container",
  5326. error: "if the remote host is located on another domain, make sure it properly supports cross-origin resource sharing (CORS), or use the JSONP approach instead",
  5327. parsererror: "the remote host did not respond with valid JSON data"
  5328. };
  5329. var explainTextStatus = function(textStatus) {
  5330. var result = textStatusMessages[textStatus];
  5331. if (!result)
  5332. return textStatus;
  5333. result += " (" + textStatusDetails[textStatus] + ")";
  5334. return result
  5335. };
  5336. return function(xhr, textStatus) {
  5337. if (xhr.status < 400)
  5338. return explainTextStatus(textStatus);
  5339. return xhr.statusText
  5340. }
  5341. }();
  5342. var aggregators = {
  5343. count: {
  5344. seed: 0,
  5345. step: function(count) {
  5346. return 1 + count
  5347. }
  5348. },
  5349. sum: {
  5350. seed: 0,
  5351. step: function(sum, item) {
  5352. return sum + item
  5353. }
  5354. },
  5355. min: {step: function(min, item) {
  5356. return item < min ? item : min
  5357. }},
  5358. max: {step: function(max, item) {
  5359. return item > max ? item : max
  5360. }},
  5361. avg: {
  5362. seed: [0, 0],
  5363. step: function(pair, value) {
  5364. return [pair[0] + value, pair[1] + 1]
  5365. },
  5366. finalize: function(pair) {
  5367. return pair[1] ? pair[0] / pair[1] : NaN
  5368. }
  5369. }
  5370. };
  5371. function handleError(error) {
  5372. var id = "E4000";
  5373. if (error && "__id" in error)
  5374. id = error.__id;
  5375. DX.log(id, error)
  5376. }
  5377. function multiLevelSearch(options) {
  5378. var itemsGetter = options.itemsGetter,
  5379. itemsSetter = options.itemsSetter,
  5380. criteria = options.criteria,
  5381. data = options.data;
  5382. function selector(x) {
  5383. var hash,
  5384. items = itemsGetter(x);
  5385. if (isNotAnEmptyArray(items)) {
  5386. hash = {};
  5387. itemsSetter(hash, multiLevelSearch({
  5388. data: items,
  5389. criteria: criteria,
  5390. itemsGetter: itemsGetter,
  5391. itemsSetter: itemsSetter
  5392. }));
  5393. return $.extend({}, x, hash)
  5394. }
  5395. return x
  5396. }
  5397. function criterion(x) {
  5398. return isNotAnEmptyArray(itemsGetter(x))
  5399. }
  5400. function isNotAnEmptyArray(x) {
  5401. return $.isArray(x) && x.length > 0
  5402. }
  5403. return DX.data.query(data).select(selector).filter([[criterion], "or", criteria]).toArray()
  5404. }
  5405. var data = DX.data = {
  5406. utils: {
  5407. compileGetter: compileGetter,
  5408. compileSetter: compileSetter,
  5409. normalizeBinaryCriterion: normalizeBinaryCriterion,
  5410. normalizeSortingInfo: normalizeSortingInfo,
  5411. toComparable: toComparable,
  5412. keysEqual: keysEqual,
  5413. errorMessageFromXhr: errorMessageFromXhr,
  5414. aggregators: aggregators,
  5415. multiLevelSearch: multiLevelSearch
  5416. },
  5417. Guid: Guid,
  5418. base64_encode: base64_encode,
  5419. queryImpl: {},
  5420. queryAdapters: {},
  5421. query: function() {
  5422. var impl = $.isArray(arguments[0]) ? "array" : "remote";
  5423. return data.queryImpl[impl].apply(this, arguments)
  5424. },
  5425. errorHandler: null,
  5426. _errorHandler: function(error) {
  5427. handleError(error);
  5428. if (data.errorHandler)
  5429. data.errorHandler(error)
  5430. }
  5431. }
  5432. })(jQuery, DevExpress);
  5433. /*! Module core, file data.aggregateCalculator.js */
  5434. (function($, DX, undefined) {
  5435. var data = DX.data,
  5436. utils = data.utils;
  5437. function isCount(aggregator) {
  5438. return aggregator === utils.aggregators.count
  5439. }
  5440. function normalizeAggregate(aggregate) {
  5441. var selector = utils.compileGetter(aggregate.selector),
  5442. aggregator = aggregate.aggregator;
  5443. if (typeof aggregator === "string") {
  5444. aggregator = data.utils.aggregators[aggregator];
  5445. if (!aggregator)
  5446. throw DX.Error("E4001", aggregate.aggregator);
  5447. }
  5448. return {
  5449. selector: selector,
  5450. aggregator: aggregator
  5451. }
  5452. }
  5453. data.AggregateCalculator = DX.Class.inherit({
  5454. ctor: function(options) {
  5455. this._data = options.data;
  5456. this._groupLevel = options.groupLevel || 0;
  5457. this._totalAggregates = $.map(options.totalAggregates || [], normalizeAggregate);
  5458. this._groupAggregates = $.map(options.groupAggregates || [], normalizeAggregate);
  5459. this._totals = []
  5460. },
  5461. calculate: function() {
  5462. if (this._totalAggregates.length)
  5463. this._calculateTotals(0, {items: this._data});
  5464. if (this._groupAggregates.length && this._groupLevel > 0)
  5465. this._calculateGroups(0, {items: this._data})
  5466. },
  5467. totalAggregates: function() {
  5468. return this._totals
  5469. },
  5470. _aggregate: function(data, aggregates, container) {
  5471. var i,
  5472. j;
  5473. for (i = 0; i < aggregates.length; i++) {
  5474. if (isCount(aggregates[i].aggregator)) {
  5475. container[i] = (container[i] || 0) + data.items.length;
  5476. continue
  5477. }
  5478. for (j = 0; j < data.items.length; j++)
  5479. this._accumulate(i, aggregates[i], container, data.items[j])
  5480. }
  5481. },
  5482. _calculateTotals: function(level, data) {
  5483. var i;
  5484. if (level === 0)
  5485. this._totals = this._seed(this._totalAggregates);
  5486. if (level === this._groupLevel)
  5487. this._aggregate(data, this._totalAggregates, this._totals);
  5488. else
  5489. for (i = 0; i < data.items.length; i++)
  5490. this._calculateTotals(level + 1, data.items[i]);
  5491. if (level === 0)
  5492. this._totals = this._finalize(this._totalAggregates, this._totals)
  5493. },
  5494. _calculateGroups: function(level, data, outerAggregates) {
  5495. var i,
  5496. innerAggregates;
  5497. if (level === this._groupLevel)
  5498. this._aggregate(data, this._groupAggregates, outerAggregates);
  5499. else
  5500. for (i = 0; i < data.items.length; i++) {
  5501. innerAggregates = this._seed(this._groupAggregates);
  5502. this._calculateGroups(level + 1, data.items[i], innerAggregates);
  5503. data.items[i].aggregates = this._finalize(this._groupAggregates, innerAggregates);
  5504. if (level > 0) {
  5505. outerAggregates = outerAggregates || this._seed(this._groupAggregates);
  5506. this._calculateGroups(level + 1, data.items[i], outerAggregates)
  5507. }
  5508. }
  5509. },
  5510. _seed: function(aggregates) {
  5511. return $.map(aggregates, function(aggregate) {
  5512. var aggregator = aggregate.aggregator,
  5513. seed = "seed" in aggregator ? aggregator.seed : NaN;
  5514. return $.isArray(seed) ? [seed] : seed
  5515. })
  5516. },
  5517. _accumulate: function(aggregateIndex, aggregate, results, item) {
  5518. var value = aggregate.selector(item),
  5519. aggregator = aggregate.aggregator;
  5520. results[aggregateIndex] = results[aggregateIndex] !== results[aggregateIndex] ? value : aggregator.step(results[aggregateIndex], value)
  5521. },
  5522. _finalize: function(aggregates, results) {
  5523. return $.map(aggregates, function(aggregate, index) {
  5524. var fin = aggregate.aggregator.finalize;
  5525. return fin ? fin(results[index]) : results[index]
  5526. })
  5527. }
  5528. })
  5529. })(jQuery, DevExpress);
  5530. /*! Module core, file data.query.array.js */
  5531. (function($, DX, undefined) {
  5532. var Class = DX.Class,
  5533. data = DX.data,
  5534. queryImpl = data.queryImpl,
  5535. compileGetter = data.utils.compileGetter,
  5536. toComparable = data.utils.toComparable;
  5537. var Iterator = Class.inherit({
  5538. toArray: function() {
  5539. var result = [];
  5540. this.reset();
  5541. while (this.next())
  5542. result.push(this.current());
  5543. return result
  5544. },
  5545. countable: function() {
  5546. return false
  5547. }
  5548. });
  5549. var ArrayIterator = Iterator.inherit({
  5550. ctor: function(array) {
  5551. this.array = array;
  5552. this.index = -1
  5553. },
  5554. next: function() {
  5555. if (this.index + 1 < this.array.length) {
  5556. this.index++;
  5557. return true
  5558. }
  5559. return false
  5560. },
  5561. current: function() {
  5562. return this.array[this.index]
  5563. },
  5564. reset: function() {
  5565. this.index = -1
  5566. },
  5567. toArray: function() {
  5568. return this.array.slice(0)
  5569. },
  5570. countable: function() {
  5571. return true
  5572. },
  5573. count: function() {
  5574. return this.array.length
  5575. }
  5576. });
  5577. var WrappedIterator = Iterator.inherit({
  5578. ctor: function(iter) {
  5579. this.iter = iter
  5580. },
  5581. next: function() {
  5582. return this.iter.next()
  5583. },
  5584. current: function() {
  5585. return this.iter.current()
  5586. },
  5587. reset: function() {
  5588. return this.iter.reset()
  5589. }
  5590. });
  5591. var MapIterator = WrappedIterator.inherit({
  5592. ctor: function(iter, mapper) {
  5593. this.callBase(iter);
  5594. this.index = -1;
  5595. this.mapper = mapper
  5596. },
  5597. current: function() {
  5598. return this.mapper(this.callBase(), this.index)
  5599. },
  5600. next: function() {
  5601. var hasNext = this.callBase();
  5602. if (hasNext)
  5603. this.index++;
  5604. return hasNext
  5605. }
  5606. });
  5607. var SortIterator = Iterator.inherit({
  5608. ctor: function(iter, getter, desc) {
  5609. if (!(iter instanceof MapIterator))
  5610. iter = new MapIterator(iter, this._wrap);
  5611. this.iter = iter;
  5612. this.rules = [{
  5613. getter: getter,
  5614. desc: desc
  5615. }]
  5616. },
  5617. thenBy: function(getter, desc) {
  5618. var result = new SortIterator(this.sortedIter || this.iter, getter, desc);
  5619. if (!this.sortedIter)
  5620. result.rules = this.rules.concat(result.rules);
  5621. return result
  5622. },
  5623. next: function() {
  5624. this._ensureSorted();
  5625. return this.sortedIter.next()
  5626. },
  5627. current: function() {
  5628. this._ensureSorted();
  5629. return this.sortedIter.current()
  5630. },
  5631. reset: function() {
  5632. delete this.sortedIter
  5633. },
  5634. countable: function() {
  5635. return this.sortedIter || this.iter.countable()
  5636. },
  5637. count: function() {
  5638. if (this.sortedIter)
  5639. return this.sortedIter.count();
  5640. return this.iter.count()
  5641. },
  5642. _ensureSorted: function() {
  5643. if (this.sortedIter)
  5644. return;
  5645. $.each(this.rules, function() {
  5646. this.getter = compileGetter(this.getter)
  5647. });
  5648. this.sortedIter = new MapIterator(new ArrayIterator(this.iter.toArray().sort($.proxy(this._compare, this))), this._unwrap)
  5649. },
  5650. _wrap: function(record, index) {
  5651. return {
  5652. index: index,
  5653. value: record
  5654. }
  5655. },
  5656. _unwrap: function(wrappedItem) {
  5657. return wrappedItem.value
  5658. },
  5659. _compare: function(x, y) {
  5660. var xIndex = x.index,
  5661. yIndex = y.index;
  5662. x = x.value;
  5663. y = y.value;
  5664. if (x === y)
  5665. return xIndex - yIndex;
  5666. for (var i = 0, rulesCount = this.rules.length; i < rulesCount; i++) {
  5667. var rule = this.rules[i],
  5668. xValue = toComparable(rule.getter(x)),
  5669. yValue = toComparable(rule.getter(y)),
  5670. factor = rule.desc ? -1 : 1;
  5671. if (xValue < yValue)
  5672. return -factor;
  5673. if (xValue > yValue)
  5674. return factor;
  5675. if (xValue !== yValue)
  5676. return !xValue ? -factor : factor
  5677. }
  5678. return xIndex - yIndex
  5679. }
  5680. });
  5681. var compileCriteria = function() {
  5682. var compileGroup = function(crit) {
  5683. var operands = [],
  5684. bag = ["return function(d) { return "],
  5685. index = 0,
  5686. pushAnd = false;
  5687. $.each(crit, function() {
  5688. if ($.isArray(this) || $.isFunction(this)) {
  5689. if (pushAnd)
  5690. bag.push(" && ");
  5691. operands.push(compileCriteria(this));
  5692. bag.push("op[", index, "](d)");
  5693. index++;
  5694. pushAnd = true
  5695. }
  5696. else {
  5697. bag.push(/and|&/i.test(this) ? " && " : " || ");
  5698. pushAnd = false
  5699. }
  5700. });
  5701. bag.push(" }");
  5702. return new Function("op", bag.join(""))(operands)
  5703. };
  5704. var toString = function(value) {
  5705. return DX.utils.isDefined(value) ? value.toString() : ''
  5706. };
  5707. var compileBinary = function(crit) {
  5708. crit = data.utils.normalizeBinaryCriterion(crit);
  5709. var getter = compileGetter(crit[0]),
  5710. op = crit[1],
  5711. value = crit[2];
  5712. value = toComparable(value);
  5713. switch (op.toLowerCase()) {
  5714. case"=":
  5715. return compileEquals(getter, value);
  5716. case"<>":
  5717. return compileEquals(getter, value, true);
  5718. case">":
  5719. return function(obj) {
  5720. return toComparable(getter(obj)) > value
  5721. };
  5722. case"<":
  5723. return function(obj) {
  5724. return toComparable(getter(obj)) < value
  5725. };
  5726. case">=":
  5727. return function(obj) {
  5728. return toComparable(getter(obj)) >= value
  5729. };
  5730. case"<=":
  5731. return function(obj) {
  5732. return toComparable(getter(obj)) <= value
  5733. };
  5734. case"startswith":
  5735. return function(obj) {
  5736. return toComparable(toString(getter(obj))).indexOf(value) === 0
  5737. };
  5738. case"endswith":
  5739. return function(obj) {
  5740. var getterValue = toComparable(toString(getter(obj))),
  5741. searchValue = toString(value);
  5742. if (getterValue.length < searchValue.length)
  5743. return false;
  5744. return getterValue.lastIndexOf(value) === getterValue.length - value.length
  5745. };
  5746. case"contains":
  5747. return function(obj) {
  5748. return toComparable(toString(getter(obj))).indexOf(value) > -1
  5749. };
  5750. case"notcontains":
  5751. return function(obj) {
  5752. return toComparable(toString(getter(obj))).indexOf(value) === -1
  5753. }
  5754. }
  5755. throw DX.Error("E4003", op);
  5756. };
  5757. function compileEquals(getter, value, negate) {
  5758. return function(obj) {
  5759. obj = toComparable(getter(obj));
  5760. var result = useStrictComparison(value) ? obj === value : obj == value;
  5761. if (negate)
  5762. result = !result;
  5763. return result
  5764. }
  5765. }
  5766. function useStrictComparison(value) {
  5767. return value === "" || value === 0 || value === null || value === false || value === undefined
  5768. }
  5769. return function(crit) {
  5770. if ($.isFunction(crit))
  5771. return crit;
  5772. if ($.isArray(crit[0]))
  5773. return compileGroup(crit);
  5774. return compileBinary(crit)
  5775. }
  5776. }();
  5777. var FilterIterator = WrappedIterator.inherit({
  5778. ctor: function(iter, criteria) {
  5779. this.callBase(iter);
  5780. this.criteria = compileCriteria(criteria)
  5781. },
  5782. next: function() {
  5783. while (this.iter.next())
  5784. if (this.criteria(this.current()))
  5785. return true;
  5786. return false
  5787. }
  5788. });
  5789. var GroupIterator = Iterator.inherit({
  5790. ctor: function(iter, getter) {
  5791. this.iter = iter;
  5792. this.getter = getter
  5793. },
  5794. next: function() {
  5795. this._ensureGrouped();
  5796. return this.groupedIter.next()
  5797. },
  5798. current: function() {
  5799. this._ensureGrouped();
  5800. return this.groupedIter.current()
  5801. },
  5802. reset: function() {
  5803. delete this.groupedIter
  5804. },
  5805. countable: function() {
  5806. return !!this.groupedIter
  5807. },
  5808. count: function() {
  5809. return this.groupedIter.count()
  5810. },
  5811. _ensureGrouped: function() {
  5812. if (this.groupedIter)
  5813. return;
  5814. var hash = {},
  5815. keys = [],
  5816. iter = this.iter,
  5817. getter = compileGetter(this.getter);
  5818. iter.reset();
  5819. while (iter.next()) {
  5820. var current = iter.current(),
  5821. key = getter(current);
  5822. if (key in hash)
  5823. hash[key].push(current);
  5824. else {
  5825. hash[key] = [current];
  5826. keys.push(key)
  5827. }
  5828. }
  5829. this.groupedIter = new ArrayIterator($.map(keys, function(key) {
  5830. return {
  5831. key: key,
  5832. items: hash[key]
  5833. }
  5834. }))
  5835. }
  5836. });
  5837. var SelectIterator = WrappedIterator.inherit({
  5838. ctor: function(iter, getter) {
  5839. this.callBase(iter);
  5840. this.getter = compileGetter(getter)
  5841. },
  5842. current: function() {
  5843. return this.getter(this.callBase())
  5844. },
  5845. countable: function() {
  5846. return this.iter.countable()
  5847. },
  5848. count: function() {
  5849. return this.iter.count()
  5850. }
  5851. });
  5852. var SliceIterator = WrappedIterator.inherit({
  5853. ctor: function(iter, skip, take) {
  5854. this.callBase(iter);
  5855. this.skip = Math.max(0, skip);
  5856. this.take = Math.max(0, take);
  5857. this.pos = 0
  5858. },
  5859. next: function() {
  5860. if (this.pos >= this.skip + this.take)
  5861. return false;
  5862. while (this.pos < this.skip && this.iter.next())
  5863. this.pos++;
  5864. this.pos++;
  5865. return this.iter.next()
  5866. },
  5867. reset: function() {
  5868. this.callBase();
  5869. this.pos = 0
  5870. },
  5871. countable: function() {
  5872. return this.iter.countable()
  5873. },
  5874. count: function() {
  5875. return Math.min(this.iter.count() - this.skip, this.take)
  5876. }
  5877. });
  5878. queryImpl.array = function(iter, queryOptions) {
  5879. queryOptions = queryOptions || {};
  5880. if (!(iter instanceof Iterator))
  5881. iter = new ArrayIterator(iter);
  5882. var handleError = function(error) {
  5883. var handler = queryOptions.errorHandler;
  5884. if (handler)
  5885. handler(error);
  5886. data._errorHandler(error)
  5887. };
  5888. var aggregateCore = function(aggregator) {
  5889. var d = $.Deferred().fail(handleError),
  5890. seed,
  5891. step = aggregator.step,
  5892. finalize = aggregator.finalize;
  5893. try {
  5894. iter.reset();
  5895. if ("seed" in aggregator)
  5896. seed = aggregator.seed;
  5897. else
  5898. seed = iter.next() ? iter.current() : NaN;
  5899. var accumulator = seed;
  5900. while (iter.next())
  5901. accumulator = step(accumulator, iter.current());
  5902. d.resolve(finalize ? finalize(accumulator) : accumulator)
  5903. }
  5904. catch(x) {
  5905. d.reject(x)
  5906. }
  5907. return d.promise()
  5908. };
  5909. var aggregate = function(seed, step, finalize) {
  5910. if (arguments.length < 2)
  5911. return aggregateCore({step: arguments[0]});
  5912. return aggregateCore({
  5913. seed: seed,
  5914. step: step,
  5915. finalize: finalize
  5916. })
  5917. };
  5918. var standardAggregate = function(name) {
  5919. return aggregateCore(data.utils.aggregators[name])
  5920. };
  5921. var select = function(getter) {
  5922. if (!$.isFunction(getter) && !$.isArray(getter))
  5923. getter = $.makeArray(arguments);
  5924. return chainQuery(new SelectIterator(iter, getter))
  5925. };
  5926. var selectProp = function(name) {
  5927. return select(compileGetter(name))
  5928. };
  5929. var chainQuery = function(iter) {
  5930. return queryImpl.array(iter, queryOptions)
  5931. };
  5932. return {
  5933. toArray: function() {
  5934. return iter.toArray()
  5935. },
  5936. enumerate: function() {
  5937. var d = $.Deferred().fail(handleError);
  5938. try {
  5939. d.resolve(iter.toArray())
  5940. }
  5941. catch(x) {
  5942. d.reject(x)
  5943. }
  5944. return d.promise()
  5945. },
  5946. sortBy: function(getter, desc) {
  5947. return chainQuery(new SortIterator(iter, getter, desc))
  5948. },
  5949. thenBy: function(getter, desc) {
  5950. if (iter instanceof SortIterator)
  5951. return chainQuery(iter.thenBy(getter, desc));
  5952. throw DX.Error("E4004");
  5953. },
  5954. filter: function(criteria) {
  5955. if (!$.isArray(criteria))
  5956. criteria = $.makeArray(arguments);
  5957. return chainQuery(new FilterIterator(iter, criteria))
  5958. },
  5959. slice: function(skip, take) {
  5960. if (take === undefined)
  5961. take = Number.MAX_VALUE;
  5962. return chainQuery(new SliceIterator(iter, skip, take))
  5963. },
  5964. select: select,
  5965. groupBy: function(getter) {
  5966. return chainQuery(new GroupIterator(iter, getter))
  5967. },
  5968. aggregate: aggregate,
  5969. count: function() {
  5970. if (iter.countable()) {
  5971. var d = $.Deferred().fail(handleError);
  5972. try {
  5973. d.resolve(iter.count())
  5974. }
  5975. catch(x) {
  5976. d.reject(x)
  5977. }
  5978. return d.promise()
  5979. }
  5980. return standardAggregate("count")
  5981. },
  5982. sum: function(getter) {
  5983. if (getter)
  5984. return selectProp(getter).sum();
  5985. return standardAggregate("sum")
  5986. },
  5987. min: function(getter) {
  5988. if (getter)
  5989. return selectProp(getter).min();
  5990. return standardAggregate("min")
  5991. },
  5992. max: function(getter) {
  5993. if (getter)
  5994. return selectProp(getter).max();
  5995. return standardAggregate("max")
  5996. },
  5997. avg: function(getter) {
  5998. if (getter)
  5999. return selectProp(getter).avg();
  6000. return standardAggregate("avg")
  6001. }
  6002. }
  6003. }
  6004. })(jQuery, DevExpress);
  6005. /*! Module core, file data.query.remote.js */
  6006. (function($, DX, undefined) {
  6007. var data = DX.data,
  6008. queryImpl = data.queryImpl;
  6009. queryImpl.remote = function(url, queryOptions, tasks) {
  6010. tasks = tasks || [];
  6011. queryOptions = queryOptions || {};
  6012. var createTask = function(name, args) {
  6013. return {
  6014. name: name,
  6015. args: args
  6016. }
  6017. };
  6018. var exec = function(executorTask) {
  6019. var d = $.Deferred(),
  6020. _adapterFactory,
  6021. _adapter,
  6022. _taskQueue,
  6023. _currentTask,
  6024. _mergedSortArgs;
  6025. var rejectWithNotify = function(error) {
  6026. var handler = queryOptions.errorHandler;
  6027. if (handler)
  6028. handler(error);
  6029. data._errorHandler(error);
  6030. d.reject(error)
  6031. };
  6032. function mergeSortTask(task) {
  6033. switch (task.name) {
  6034. case"sortBy":
  6035. _mergedSortArgs = [task.args];
  6036. return true;
  6037. case"thenBy":
  6038. if (!_mergedSortArgs)
  6039. throw DX.Error("E4004");
  6040. _mergedSortArgs.push(task.args);
  6041. return true
  6042. }
  6043. return false
  6044. }
  6045. function unmergeSortTasks() {
  6046. var head = _taskQueue[0],
  6047. unmergedTasks = [];
  6048. if (head && head.name === "multiSort") {
  6049. _taskQueue.shift();
  6050. $.each(head.args[0], function() {
  6051. unmergedTasks.push(createTask(unmergedTasks.length ? "thenBy" : "sortBy", this))
  6052. })
  6053. }
  6054. _taskQueue = unmergedTasks.concat(_taskQueue)
  6055. }
  6056. try {
  6057. _adapterFactory = queryOptions.adapter || "odata";
  6058. if (!$.isFunction(_adapterFactory))
  6059. _adapterFactory = data.queryAdapters[_adapterFactory];
  6060. _adapter = _adapterFactory(queryOptions);
  6061. _taskQueue = [].concat(tasks).concat(executorTask);
  6062. while (_taskQueue.length) {
  6063. _currentTask = _taskQueue[0];
  6064. if (!mergeSortTask(_currentTask)) {
  6065. if (_mergedSortArgs) {
  6066. _taskQueue.unshift(createTask("multiSort", [_mergedSortArgs]));
  6067. _mergedSortArgs = null;
  6068. continue
  6069. }
  6070. if (String(_currentTask.name) !== "enumerate")
  6071. if (!_adapter[_currentTask.name] || _adapter[_currentTask.name].apply(_adapter, _currentTask.args) === false)
  6072. break
  6073. }
  6074. _taskQueue.shift()
  6075. }
  6076. unmergeSortTasks();
  6077. _adapter.exec(url).done(function(result, extra) {
  6078. if (!_taskQueue.length)
  6079. d.resolve(result, extra);
  6080. else {
  6081. var clientChain = queryImpl.array(result, {errorHandler: queryOptions.errorHandler});
  6082. $.each(_taskQueue, function() {
  6083. clientChain = clientChain[this.name].apply(clientChain, this.args)
  6084. });
  6085. clientChain.done(d.resolve).fail(d.reject)
  6086. }
  6087. }).fail(rejectWithNotify)
  6088. }
  6089. catch(x) {
  6090. rejectWithNotify(x)
  6091. }
  6092. return d.promise()
  6093. };
  6094. var query = {};
  6095. $.each(["sortBy", "thenBy", "filter", "slice", "select", "groupBy"], function() {
  6096. var name = String(this);
  6097. query[name] = function() {
  6098. return queryImpl.remote(url, queryOptions, tasks.concat(createTask(name, arguments)))
  6099. }
  6100. });
  6101. $.each(["count", "min", "max", "sum", "avg", "aggregate", "enumerate"], function() {
  6102. var name = String(this);
  6103. query[name] = function() {
  6104. return exec.call(this, createTask(name, arguments))
  6105. }
  6106. });
  6107. return query
  6108. }
  6109. })(jQuery, DevExpress);
  6110. /*! Module core, file data.odata.js */
  6111. (function($, DX, undefined) {
  6112. var data = DX.data,
  6113. utils = DX.utils,
  6114. Guid = data.Guid,
  6115. isDefined = utils.isDefined;
  6116. var DEFAULT_PROTOCOL_VERSION = 2;
  6117. var GUID_REGEX = /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/;
  6118. var VERBOSE_DATE_REGEX = /^\/Date\((-?\d+)((\+|-)?(\d+)?)\)\/$/;
  6119. var ISO8601_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[-+]{1}\d{2}(:?)(\d{2})?)?$/;
  6120. var JSON_VERBOSE_MIME_TYPE = "application/json;odata=verbose";
  6121. function formatISO8601(date, skipZeroTime, skipTimezone) {
  6122. var ret = [];
  6123. var pad = function(n) {
  6124. if (n < 10)
  6125. return "0".concat(n);
  6126. return String(n)
  6127. };
  6128. var isZeroTime = function() {
  6129. return date.getHours() + date.getMinutes() + date.getSeconds() + date.getMilliseconds() < 1
  6130. };
  6131. ret.push(date.getFullYear());
  6132. ret.push("-");
  6133. ret.push(pad(date.getMonth() + 1));
  6134. ret.push("-");
  6135. ret.push(pad(date.getDate()));
  6136. if (!(skipZeroTime && isZeroTime())) {
  6137. ret.push("T");
  6138. ret.push(pad(date.getHours()));
  6139. ret.push(":");
  6140. ret.push(pad(date.getMinutes()));
  6141. ret.push(":");
  6142. ret.push(pad(date.getSeconds()));
  6143. if (date.getMilliseconds()) {
  6144. ret.push(".");
  6145. ret.push(date.getMilliseconds())
  6146. }
  6147. if (!skipTimezone)
  6148. ret.push("Z")
  6149. }
  6150. return ret.join("")
  6151. }
  6152. function parseISO8601(isoString) {
  6153. var result = new Date(0);
  6154. var chunks = isoString.replace("Z", "").split("T"),
  6155. date = /(\d{4})-(\d{2})-(\d{2})/.exec(chunks[0]),
  6156. time = /(\d{2}):(\d{2}):(\d{2})\.?(\d{0,7})?/.exec(chunks[1]);
  6157. result.setDate(Number(date[3]));
  6158. result.setMonth(Number(date[2]) - 1);
  6159. result.setFullYear(Number(date[1]));
  6160. if ($.isArray(time) && time.length) {
  6161. result.setHours(Number(time[1]));
  6162. result.setMinutes(Number(time[2]));
  6163. result.setSeconds(Number(time[3]));
  6164. result.setMilliseconds(Number(String(time[4]).substr(0, 3)) || 0)
  6165. }
  6166. return result
  6167. }
  6168. function isAbsoluteUrl(url) {
  6169. return /^(?:[a-z]+:)?\/\//i.test(url)
  6170. }
  6171. function toAbsoluteUrl(basePath, relativePath) {
  6172. var part,
  6173. baseParts = basePath.split("/"),
  6174. relativeParts = relativePath.split("/");
  6175. baseParts.pop();
  6176. while (relativeParts.length) {
  6177. part = relativeParts.shift();
  6178. if (part === "..")
  6179. baseParts.pop();
  6180. else
  6181. baseParts.push(part)
  6182. }
  6183. return baseParts.join("/")
  6184. }
  6185. var ajaxOptionsForRequest = function(protocolVersion, request, requestOptions) {
  6186. request = $.extend({
  6187. method: "get",
  6188. url: "",
  6189. params: {},
  6190. payload: null,
  6191. headers: {},
  6192. timeout: 30000
  6193. }, request);
  6194. requestOptions = requestOptions || {};
  6195. var beforeSend = requestOptions.beforeSend;
  6196. if (beforeSend)
  6197. beforeSend(request);
  6198. var method = (request.method || "get").toLowerCase(),
  6199. isGet = method === "get",
  6200. useJsonp = isGet && requestOptions.jsonp,
  6201. params = $.extend({}, request.params),
  6202. ajaxData = isGet ? params : formatPayload(request.payload),
  6203. qs = !isGet && $.param(params),
  6204. url = request.url,
  6205. contentType = !isGet && JSON_VERBOSE_MIME_TYPE;
  6206. if (qs)
  6207. url += (url.indexOf("?") > -1 ? "&" : "?") + qs;
  6208. if (useJsonp)
  6209. ajaxData["$format"] = "json";
  6210. return {
  6211. url: url,
  6212. data: ajaxData,
  6213. dataType: useJsonp ? "jsonp" : "json",
  6214. jsonp: useJsonp && "$callback",
  6215. type: method,
  6216. timeout: request.timeout,
  6217. headers: request.headers,
  6218. contentType: contentType,
  6219. accepts: {json: [JSON_VERBOSE_MIME_TYPE, "text/plain"].join()},
  6220. xhrFields: {withCredentials: requestOptions.withCredentials}
  6221. };
  6222. function formatPayload(payload) {
  6223. return JSON.stringify(payload, function(key, value) {
  6224. if (!(this[key] instanceof Date))
  6225. return value;
  6226. value = formatISO8601(this[key]);
  6227. switch (protocolVersion) {
  6228. case 2:
  6229. return value.substr(0, value.length - 1);
  6230. case 3:
  6231. case 4:
  6232. return value;
  6233. default:
  6234. throw DX.Error("E4002");
  6235. }
  6236. })
  6237. }
  6238. };
  6239. var sendRequest = function(protocolVersion, request, requestOptions) {
  6240. var d = $.Deferred();
  6241. var options = ajaxOptionsForRequest(protocolVersion, request, requestOptions);
  6242. $.ajax(options).always(function(obj, textStatus) {
  6243. var tuplet = interpretJsonFormat(obj, textStatus),
  6244. error = tuplet.error,
  6245. data = tuplet.data,
  6246. nextUrl = tuplet.nextUrl,
  6247. extra;
  6248. if (error)
  6249. d.reject(error);
  6250. else if (requestOptions.countOnly)
  6251. d.resolve(tuplet.count);
  6252. else if (nextUrl) {
  6253. if (!isAbsoluteUrl(nextUrl))
  6254. nextUrl = toAbsoluteUrl(options.url, nextUrl);
  6255. sendRequest(protocolVersion, {url: nextUrl}, requestOptions).fail(d.reject).done(function(nextData) {
  6256. d.resolve(data.concat(nextData))
  6257. })
  6258. }
  6259. else {
  6260. if (isFinite(tuplet.count))
  6261. extra = {totalCount: tuplet.count};
  6262. d.resolve(data, extra)
  6263. }
  6264. });
  6265. return d.promise()
  6266. };
  6267. var formatDotNetError = function(errorObj) {
  6268. var message,
  6269. currentError = errorObj;
  6270. if ("message" in errorObj)
  6271. if (errorObj.message.value)
  6272. message = errorObj.message.value;
  6273. else
  6274. message = errorObj.message;
  6275. while (currentError = currentError.innererror || currentError.internalexception) {
  6276. message = currentError.message;
  6277. if (currentError.internalexception && message.indexOf("inner exception") === -1)
  6278. break
  6279. }
  6280. return message
  6281. };
  6282. var errorFromResponse = function(obj, textStatus) {
  6283. if (textStatus === "nocontent")
  6284. return null;
  6285. var httpStatus = 200,
  6286. message = "Unknown error",
  6287. response = obj;
  6288. if (textStatus !== "success") {
  6289. httpStatus = obj.status;
  6290. message = data.utils.errorMessageFromXhr(obj, textStatus);
  6291. try {
  6292. response = $.parseJSON(obj.responseText)
  6293. }
  6294. catch(x) {}
  6295. }
  6296. var errorObj = response && (response.error || response["@odata.error"]);
  6297. if (errorObj) {
  6298. message = formatDotNetError(errorObj) || message;
  6299. if (httpStatus === 200)
  6300. httpStatus = 500;
  6301. if (errorObj.code)
  6302. httpStatus = Number(errorObj.code);
  6303. return $.extend(Error(message), {
  6304. httpStatus: httpStatus,
  6305. errorDetails: errorObj
  6306. })
  6307. }
  6308. else if (httpStatus !== 200)
  6309. return $.extend(Error(message), {httpStatus: httpStatus})
  6310. };
  6311. var interpretJsonFormat = function(obj, textStatus) {
  6312. var error = errorFromResponse(obj, textStatus),
  6313. value;
  6314. if (error)
  6315. return {error: error};
  6316. if (!$.isPlainObject(obj))
  6317. return {data: obj};
  6318. if ("d" in obj && (utils.isArray(obj.d) || utils.isObject(obj.d)))
  6319. value = interpretVerboseJsonFormat(obj, textStatus);
  6320. else
  6321. value = interpretLightJsonFormat(obj, textStatus);
  6322. transformTypes(value);
  6323. return value
  6324. };
  6325. var interpretVerboseJsonFormat = function(obj) {
  6326. var data = obj.d;
  6327. if (!isDefined(data))
  6328. return {error: Error("Malformed or unsupported JSON response received")};
  6329. data = data;
  6330. if (isDefined(data.results))
  6331. data = data.results;
  6332. return {
  6333. data: data,
  6334. nextUrl: obj.d.__next,
  6335. count: parseInt(obj.d.__count, 10)
  6336. }
  6337. };
  6338. var interpretLightJsonFormat = function(obj) {
  6339. var data = obj;
  6340. if (isDefined(data.value))
  6341. data = data.value;
  6342. return {
  6343. data: data,
  6344. nextUrl: obj["@odata.nextLink"],
  6345. count: parseInt(obj["@odata.count"], 10)
  6346. }
  6347. };
  6348. var EdmLiteral = DX.Class.inherit({
  6349. ctor: function(value) {
  6350. this._value = value
  6351. },
  6352. valueOf: function() {
  6353. return this._value
  6354. }
  6355. });
  6356. var transformTypes = function(obj) {
  6357. $.each(obj, function(key, value) {
  6358. if (value !== null && typeof value === "object") {
  6359. if ("results" in value)
  6360. obj[key] = value.results;
  6361. transformTypes(obj[key])
  6362. }
  6363. else if (typeof value === "string")
  6364. if (GUID_REGEX.test(value))
  6365. obj[key] = new Guid(value);
  6366. else if (value.match(VERBOSE_DATE_REGEX)) {
  6367. var date = new Date(Number(RegExp.$1) + RegExp.$2 * 60 * 1000);
  6368. obj[key] = new Date(date.valueOf() + date.getTimezoneOffset() * 60 * 1000)
  6369. }
  6370. else if (ISO8601_DATE_REGEX.test(value))
  6371. obj[key] = new Date(parseISO8601(obj[key]).valueOf())
  6372. })
  6373. };
  6374. var serializeDate = function(date) {
  6375. return "datetime'" + formatISO8601(date, true, true) + "'"
  6376. };
  6377. var serializeString = function(value) {
  6378. return "'" + value.replace(/'/g, "''") + "'"
  6379. };
  6380. var serializePropName = function(propName) {
  6381. if (propName instanceof EdmLiteral)
  6382. return propName.valueOf();
  6383. return propName.replace(/\./g, "/")
  6384. };
  6385. var serializeValueV4 = function(value) {
  6386. if (value instanceof Date)
  6387. return formatISO8601(value, false, false);
  6388. if (value instanceof Guid)
  6389. return value.valueOf();
  6390. return serializeValueV2(value)
  6391. };
  6392. var serializeValueV2 = function(value) {
  6393. if (value instanceof Date)
  6394. return serializeDate(value);
  6395. if (value instanceof Guid)
  6396. return "guid'" + value + "'";
  6397. if (value instanceof EdmLiteral)
  6398. return value.valueOf();
  6399. if (typeof value === "string")
  6400. return serializeString(value);
  6401. return String(value)
  6402. };
  6403. var serializeValue = function(value, protocolVersion) {
  6404. switch (protocolVersion) {
  6405. case 2:
  6406. case 3:
  6407. return serializeValueV2(value);
  6408. case 4:
  6409. return serializeValueV4(value);
  6410. default:
  6411. throw DX.Error("E4002");
  6412. }
  6413. };
  6414. var serializeKey = function(key, protocolVersion) {
  6415. if ($.isPlainObject(key)) {
  6416. var parts = [];
  6417. $.each(key, function(k, v) {
  6418. parts.push(serializePropName(k) + "=" + serializeValue(v, protocolVersion))
  6419. });
  6420. return parts.join()
  6421. }
  6422. return serializeValue(key, protocolVersion)
  6423. };
  6424. var keyConverters = {
  6425. String: function(value) {
  6426. return value + ""
  6427. },
  6428. Int32: function(value) {
  6429. return Math.floor(value)
  6430. },
  6431. Int64: function(value) {
  6432. if (value instanceof EdmLiteral)
  6433. return value;
  6434. return new EdmLiteral(value + "L")
  6435. },
  6436. Guid: function(value) {
  6437. if (value instanceof Guid)
  6438. return value;
  6439. return new Guid(value)
  6440. },
  6441. Boolean: function(value) {
  6442. return !!value
  6443. },
  6444. Single: function(value) {
  6445. if (value instanceof EdmLiteral)
  6446. return value;
  6447. return new EdmLiteral(value + "f")
  6448. },
  6449. Decimal: function(value) {
  6450. if (value instanceof EdmLiteral)
  6451. return value;
  6452. return new EdmLiteral(value + "m")
  6453. }
  6454. };
  6455. var compileCriteria = function() {
  6456. var createBinaryOperationFormatter = function(op) {
  6457. return function(prop, val, bag) {
  6458. bag.push(prop, " ", op, " ", val)
  6459. }
  6460. };
  6461. var createStringFuncFormatter = function(op, reverse) {
  6462. return function(prop, val, bag) {
  6463. if (reverse)
  6464. bag.push(op, "(", val, ",", prop, ")");
  6465. else
  6466. bag.push(op, "(", prop, ",", val, ")")
  6467. }
  6468. };
  6469. var formatters = {
  6470. "=": createBinaryOperationFormatter("eq"),
  6471. "<>": createBinaryOperationFormatter("ne"),
  6472. ">": createBinaryOperationFormatter("gt"),
  6473. ">=": createBinaryOperationFormatter("ge"),
  6474. "<": createBinaryOperationFormatter("lt"),
  6475. "<=": createBinaryOperationFormatter("le"),
  6476. startswith: createStringFuncFormatter("startswith"),
  6477. endswith: createStringFuncFormatter("endswith")
  6478. };
  6479. var formattersV2 = $.extend({}, formatters, {
  6480. contains: createStringFuncFormatter("substringof", true),
  6481. notcontains: createStringFuncFormatter("not substringof", true)
  6482. });
  6483. var formattersV4 = $.extend({}, formatters, {
  6484. contains: createStringFuncFormatter("contains"),
  6485. notcontains: createStringFuncFormatter("not contains")
  6486. });
  6487. var compileBinary = function(criteria, bag, protocolVersion) {
  6488. criteria = data.utils.normalizeBinaryCriterion(criteria);
  6489. var op = criteria[1],
  6490. formatters = protocolVersion === 4 ? formattersV4 : formattersV2,
  6491. formatter = formatters[op.toLowerCase()];
  6492. if (!formatter)
  6493. throw DX.Error("E4003", op);
  6494. formatter(serializePropName(criteria[0]), serializeValue(criteria[2], protocolVersion), bag)
  6495. };
  6496. var compileGroup = function(criteria, bag, protocolVersion) {
  6497. var pushAnd = false;
  6498. $.each(criteria, function() {
  6499. if ($.isArray(this)) {
  6500. if (pushAnd)
  6501. bag.push(" and ");
  6502. bag.push("(");
  6503. compileCore(this, bag, protocolVersion);
  6504. bag.push(")");
  6505. pushAnd = true
  6506. }
  6507. else {
  6508. bag.push(/and|&/i.test(this) ? " and " : " or ");
  6509. pushAnd = false
  6510. }
  6511. })
  6512. };
  6513. var compileCore = function(criteria, bag, protocolVersion) {
  6514. if ($.isArray(criteria[0]))
  6515. compileGroup(criteria, bag, protocolVersion);
  6516. else
  6517. compileBinary(criteria, bag, protocolVersion)
  6518. };
  6519. return function(criteria, protocolVersion) {
  6520. var bag = [];
  6521. compileCore(criteria, bag, protocolVersion);
  6522. return bag.join("")
  6523. }
  6524. }();
  6525. var createODataQueryAdapter = function(queryOptions) {
  6526. var _sorting = [],
  6527. _criteria = [],
  6528. _select,
  6529. _skip,
  6530. _take,
  6531. _countQuery;
  6532. var hasSlice = function() {
  6533. return _skip || _take !== undefined
  6534. };
  6535. var hasFunction = function(criterion) {
  6536. for (var i = 0; i < criterion.length; i++) {
  6537. if ($.isFunction(criterion[i]))
  6538. return true;
  6539. if ($.isArray(criterion[i]) && hasFunction(criterion[i]))
  6540. return true
  6541. }
  6542. return false
  6543. };
  6544. var generateExpand = function() {
  6545. var hash = {};
  6546. if (queryOptions.expand)
  6547. $.each($.makeArray(queryOptions.expand), function() {
  6548. hash[serializePropName(this)] = 1
  6549. });
  6550. if (_select)
  6551. $.each(_select, function() {
  6552. var path = this.split(".");
  6553. if (path.length < 2)
  6554. return;
  6555. path.pop();
  6556. hash[serializePropName(path.join("."))] = 1
  6557. });
  6558. return $.map(hash, function(k, v) {
  6559. return v
  6560. }).join() || undefined
  6561. };
  6562. var requestData = function() {
  6563. var result = {};
  6564. if (!_countQuery) {
  6565. if (_sorting.length)
  6566. result["$orderby"] = _sorting.join(",");
  6567. if (_skip)
  6568. result["$skip"] = _skip;
  6569. if (_take !== undefined)
  6570. result["$top"] = _take;
  6571. if (_select)
  6572. result["$select"] = serializePropName(_select.join());
  6573. result["$expand"] = generateExpand()
  6574. }
  6575. if (_criteria.length)
  6576. result["$filter"] = compileCriteria(_criteria.length < 2 ? _criteria[0] : _criteria, queryOptions.version);
  6577. if (_countQuery)
  6578. result["$top"] = 0;
  6579. if (queryOptions.requireTotalCount || _countQuery)
  6580. if (queryOptions.version !== 4)
  6581. result["$inlinecount"] = "allpages";
  6582. else
  6583. result["$count"] = "true";
  6584. return result
  6585. };
  6586. queryOptions.version = queryOptions.version || DEFAULT_PROTOCOL_VERSION;
  6587. return {
  6588. exec: function(url) {
  6589. return sendRequest(queryOptions.version, {
  6590. url: url,
  6591. params: $.extend(requestData(), queryOptions && queryOptions.params)
  6592. }, {
  6593. beforeSend: queryOptions.beforeSend,
  6594. jsonp: queryOptions.jsonp,
  6595. withCredentials: queryOptions.withCredentials,
  6596. countOnly: _countQuery
  6597. })
  6598. },
  6599. multiSort: function(args) {
  6600. var rules;
  6601. if (hasSlice())
  6602. return false;
  6603. for (var i = 0; i < args.length; i++) {
  6604. var getter = args[i][0],
  6605. desc = !!args[i][1],
  6606. rule;
  6607. if (typeof getter !== "string")
  6608. return false;
  6609. rule = serializePropName(getter);
  6610. if (desc)
  6611. rule += " desc";
  6612. rules = rules || [];
  6613. rules.push(rule)
  6614. }
  6615. _sorting = rules
  6616. },
  6617. slice: function(skipCount, takeCount) {
  6618. if (hasSlice())
  6619. return false;
  6620. _skip = skipCount;
  6621. _take = takeCount
  6622. },
  6623. filter: function(criterion) {
  6624. if (hasSlice() || $.isFunction(criterion))
  6625. return false;
  6626. if (!$.isArray(criterion))
  6627. criterion = $.makeArray(arguments);
  6628. if (hasFunction(criterion))
  6629. return false;
  6630. if (_criteria.length)
  6631. _criteria.push("and");
  6632. _criteria.push(criterion)
  6633. },
  6634. select: function(expr) {
  6635. if (_select || $.isFunction(expr))
  6636. return false;
  6637. if (!$.isArray(expr))
  6638. expr = $.makeArray(arguments);
  6639. _select = expr
  6640. },
  6641. count: function() {
  6642. _countQuery = true
  6643. }
  6644. }
  6645. };
  6646. $.extend(true, data, {
  6647. EdmLiteral: EdmLiteral,
  6648. utils: {odata: {
  6649. sendRequest: sendRequest,
  6650. serializePropName: serializePropName,
  6651. serializeValue: serializeValue,
  6652. serializeKey: serializeKey,
  6653. keyConverters: keyConverters
  6654. }},
  6655. queryAdapters: {odata: createODataQueryAdapter}
  6656. });
  6657. data.OData__internals = {interpretJsonFormat: interpretJsonFormat}
  6658. })(jQuery, DevExpress);
  6659. /*! Module core, file data.store.abstract.js */
  6660. (function($, DX, undefined) {
  6661. var Class = DX.Class,
  6662. abstract = DX.abstract,
  6663. data = DX.data,
  6664. normalizeSortingInfo = data.utils.normalizeSortingInfo;
  6665. var STORE_CALLBACK_NAMES = ["loading", "loaded", "modifying", "modified", "inserting", "inserted", "updating", "updated", "removing", "removed"];
  6666. function multiLevelGroup(query, groupInfo) {
  6667. query = query.groupBy(groupInfo[0].selector);
  6668. if (groupInfo.length > 1)
  6669. query = query.select(function(g) {
  6670. return $.extend({}, g, {items: multiLevelGroup(data.query(g.items), groupInfo.slice(1)).toArray()})
  6671. });
  6672. return query
  6673. }
  6674. data.utils.multiLevelGroup = multiLevelGroup;
  6675. function arrangeSortingInfo(groupInfo, sortInfo) {
  6676. var filteredGroup = [];
  6677. $.each(groupInfo, function(_, group) {
  6678. var collision = $.grep(sortInfo, function(sort) {
  6679. return group.selector === sort.selector
  6680. });
  6681. if (collision.length < 1)
  6682. filteredGroup.push(group)
  6683. });
  6684. return filteredGroup.concat(sortInfo)
  6685. }
  6686. data.utils.arrangeSortingInfo = arrangeSortingInfo;
  6687. data.Store = Class.inherit({
  6688. ctor: function(options) {
  6689. var that = this;
  6690. options = options || {};
  6691. $.each(STORE_CALLBACK_NAMES, function() {
  6692. var eventName = this;
  6693. var callbacks = that[eventName] = $.Callbacks();
  6694. var originalAdd = callbacks.add;
  6695. callbacks.add = function() {
  6696. DX.log("W0003", "Store", eventName, "14.2", "Use the '" + eventName + "' event instead");
  6697. return originalAdd.apply(eventName, arguments)
  6698. };
  6699. if (eventName in options)
  6700. callbacks.add(options[eventName]);
  6701. var propertyName = "on" + eventName.charAt(0).toUpperCase() + eventName.slice(1);
  6702. if (propertyName in options)
  6703. that.on(eventName, options[propertyName])
  6704. });
  6705. this._key = options.key;
  6706. this._errorHandler = options.errorHandler;
  6707. this._useDefaultSearch = true
  6708. },
  6709. _customLoadOptions: function() {
  6710. return null
  6711. },
  6712. key: function() {
  6713. return this._key
  6714. },
  6715. keyOf: function(obj) {
  6716. if (!this._keyGetter)
  6717. this._keyGetter = data.utils.compileGetter(this.key());
  6718. return this._keyGetter(obj)
  6719. },
  6720. _requireKey: function() {
  6721. if (!this.key())
  6722. throw DX.Error("E4005");
  6723. },
  6724. load: function(options) {
  6725. var that = this;
  6726. options = options || {};
  6727. this.fireEvent("loading", [options]);
  6728. this.loading.fire(options);
  6729. return this._loadImpl(options).done(function(result, extra) {
  6730. that.fireEvent("loaded", [result, options]);
  6731. that.loaded.fire(result, extra)
  6732. })
  6733. },
  6734. _loadImpl: function(options) {
  6735. var filter = options.filter,
  6736. sort = options.sort,
  6737. select = options.select,
  6738. group = options.group,
  6739. skip = options.skip,
  6740. take = options.take,
  6741. q = this.createQuery(options);
  6742. if (filter)
  6743. q = q.filter(filter);
  6744. if (group)
  6745. group = normalizeSortingInfo(group);
  6746. if (sort || group) {
  6747. sort = normalizeSortingInfo(sort || []);
  6748. if (group)
  6749. sort = arrangeSortingInfo(group, sort);
  6750. $.each(sort, function(index) {
  6751. q = q[index ? "thenBy" : "sortBy"](this.selector, this.desc)
  6752. })
  6753. }
  6754. if (select)
  6755. q = q.select(select);
  6756. if (group)
  6757. q = multiLevelGroup(q, group);
  6758. if (take || skip)
  6759. q = q.slice(skip || 0, take);
  6760. return q.enumerate()
  6761. },
  6762. createQuery: abstract,
  6763. totalCount: function(options) {
  6764. return this._addFailHandlers(this._totalCountImpl(options))
  6765. },
  6766. _totalCountImpl: function(options) {
  6767. options = options || {};
  6768. var q = this.createQuery(),
  6769. group = options.group,
  6770. filter = options.filter;
  6771. if (filter)
  6772. q = q.filter(filter);
  6773. if (group) {
  6774. group = normalizeSortingInfo(group);
  6775. q = multiLevelGroup(q, group)
  6776. }
  6777. return q.count()
  6778. },
  6779. byKey: function(key, extraOptions) {
  6780. return this._addFailHandlers(this._byKeyImpl(key, extraOptions))
  6781. },
  6782. _byKeyImpl: abstract,
  6783. insert: function(values) {
  6784. var that = this;
  6785. that.fireEvent("modifying");
  6786. that.fireEvent("inserting", [values]);
  6787. that.modifying.fire();
  6788. that.inserting.fire(values);
  6789. return that._addFailHandlers(that._insertImpl(values).done(function(callbackValues, callbackKey) {
  6790. that.fireEvent("inserted", [callbackValues, callbackKey]);
  6791. that.fireEvent("modified");
  6792. that.inserted.fire(callbackValues, callbackKey);
  6793. that.modified.fire()
  6794. }))
  6795. },
  6796. _insertImpl: abstract,
  6797. update: function(key, values) {
  6798. var that = this;
  6799. that.fireEvent("modifying");
  6800. that.fireEvent("updating", [key, values]);
  6801. that.modifying.fire();
  6802. that.updating.fire(key, values);
  6803. return that._addFailHandlers(that._updateImpl(key, values).done(function(callbackKey, callbackValues) {
  6804. that.fireEvent("updated", [callbackKey, callbackValues]);
  6805. that.fireEvent("modified");
  6806. that.updated.fire(callbackKey, callbackValues);
  6807. that.modified.fire()
  6808. }))
  6809. },
  6810. _updateImpl: abstract,
  6811. remove: function(key) {
  6812. var that = this;
  6813. that.fireEvent("modifying");
  6814. that.fireEvent("removing", [key]);
  6815. that.modifying.fire();
  6816. that.removing.fire(key);
  6817. return that._addFailHandlers(that._removeImpl(key).done(function(callbackKey) {
  6818. that.fireEvent("removed", [callbackKey]);
  6819. that.fireEvent("modified");
  6820. that.removed.fire(callbackKey);
  6821. that.modified.fire()
  6822. }))
  6823. },
  6824. _removeImpl: abstract,
  6825. _addFailHandlers: function(deferred) {
  6826. return deferred.fail(this._errorHandler, data._errorHandler)
  6827. }
  6828. }).include(DX.EventsMixin)
  6829. })(jQuery, DevExpress);
  6830. /*! Module core, file data.store.array.js */
  6831. (function($, DX, undefined) {
  6832. var data = DX.data,
  6833. Guid = data.Guid;
  6834. var trivialPromise = function() {
  6835. var d = $.Deferred();
  6836. return d.resolve.apply(d, arguments).promise()
  6837. };
  6838. var rejectedPromise = function() {
  6839. var d = $.Deferred();
  6840. return d.reject.apply(d, arguments).promise()
  6841. };
  6842. data.ArrayStore = data.Store.inherit({
  6843. ctor: function(options) {
  6844. if ($.isArray(options))
  6845. options = {data: options};
  6846. else
  6847. options = options || {};
  6848. this.callBase(options);
  6849. var initialArray = options.data;
  6850. if (initialArray && !$.isArray(initialArray))
  6851. throw DX.Error("E4006");
  6852. this._array = initialArray || []
  6853. },
  6854. createQuery: function() {
  6855. return data.query(this._array, {errorHandler: this._errorHandler})
  6856. },
  6857. _byKeyImpl: function(key) {
  6858. var index = this._indexByKey(key);
  6859. if (index === -1)
  6860. return rejectedPromise(DX.Error("E4009"));
  6861. return trivialPromise(this._array[index])
  6862. },
  6863. _insertImpl: function(values) {
  6864. var keyExpr = this.key(),
  6865. keyValue,
  6866. obj;
  6867. if ($.isPlainObject(values))
  6868. obj = $.extend({}, values);
  6869. else
  6870. obj = values;
  6871. if (keyExpr) {
  6872. keyValue = this.keyOf(obj);
  6873. if (keyValue === undefined || typeof keyValue === "object" && $.isEmptyObject(keyValue)) {
  6874. if ($.isArray(keyExpr))
  6875. throw DX.Error("E4007");
  6876. keyValue = obj[keyExpr] = String(new Guid)
  6877. }
  6878. else if (this._array[this._indexByKey(keyValue)] !== undefined)
  6879. return rejectedPromise(DX.Error("E4008"))
  6880. }
  6881. else
  6882. keyValue = obj;
  6883. this._array.push(obj);
  6884. return trivialPromise(values, keyValue)
  6885. },
  6886. _updateImpl: function(key, values) {
  6887. var target,
  6888. index;
  6889. if (this.key()) {
  6890. if (this.keyOf(values))
  6891. if (!data.utils.keysEqual(this.key(), key, this.keyOf(values)))
  6892. return rejectedPromise(DX.Error("E4017"));
  6893. index = this._indexByKey(key);
  6894. if (index < 0)
  6895. return rejectedPromise(DX.Error("E4009"));
  6896. target = this._array[index]
  6897. }
  6898. else
  6899. target = key;
  6900. DX.utils.deepExtendArraySafe(target, values);
  6901. return trivialPromise(key, values)
  6902. },
  6903. _removeImpl: function(key) {
  6904. var index = this._indexByKey(key);
  6905. if (index > -1)
  6906. this._array.splice(index, 1);
  6907. return trivialPromise(key)
  6908. },
  6909. _indexByKey: function(key) {
  6910. for (var i = 0, arrayLength = this._array.length; i < arrayLength; i++)
  6911. if (data.utils.keysEqual(this.key(), this.keyOf(this._array[i]), key))
  6912. return i;
  6913. return -1
  6914. },
  6915. clear: function() {
  6916. this._array = []
  6917. }
  6918. })
  6919. })(jQuery, DevExpress);
  6920. /*! Module core, file data.store.local.js */
  6921. (function($, DX, undefined) {
  6922. var Class = DX.Class,
  6923. abstract = DX.abstract,
  6924. data = DX.data;
  6925. var LocalStoreBackend = Class.inherit({
  6926. ctor: function(store, storeOptions) {
  6927. this._store = store;
  6928. this._dirty = false;
  6929. var immediate = this._immediate = storeOptions.immediate;
  6930. var flushInterval = Math.max(100, storeOptions.flushInterval || 10 * 1000);
  6931. if (!immediate) {
  6932. var saveProxy = $.proxy(this.save, this);
  6933. setInterval(saveProxy, flushInterval);
  6934. $(window).on("beforeunload", saveProxy);
  6935. if (window.cordova)
  6936. document.addEventListener("pause", saveProxy, false)
  6937. }
  6938. },
  6939. notifyChanged: function() {
  6940. this._dirty = true;
  6941. if (this._immediate)
  6942. this.save()
  6943. },
  6944. load: function() {
  6945. this._store._array = this._loadImpl();
  6946. this._dirty = false
  6947. },
  6948. save: function() {
  6949. if (!this._dirty)
  6950. return;
  6951. this._saveImpl(this._store._array);
  6952. this._dirty = false
  6953. },
  6954. _loadImpl: abstract,
  6955. _saveImpl: abstract
  6956. });
  6957. var DomLocalStoreBackend = LocalStoreBackend.inherit({
  6958. ctor: function(store, storeOptions) {
  6959. this.callBase(store, storeOptions);
  6960. var name = storeOptions.name;
  6961. if (!name)
  6962. throw DX.Error("E4013");
  6963. this._key = "dx-data-localStore-" + name
  6964. },
  6965. _loadImpl: function() {
  6966. var raw = localStorage.getItem(this._key);
  6967. if (raw)
  6968. return JSON.parse(raw);
  6969. return []
  6970. },
  6971. _saveImpl: function(array) {
  6972. if (!array.length)
  6973. localStorage.removeItem(this._key);
  6974. else
  6975. localStorage.setItem(this._key, JSON.stringify(array))
  6976. }
  6977. });
  6978. var localStoreBackends = {dom: DomLocalStoreBackend};
  6979. data.LocalStore = data.ArrayStore.inherit({
  6980. ctor: function(options) {
  6981. if (typeof options === "string")
  6982. options = {name: options};
  6983. else
  6984. options = options || {};
  6985. this.callBase(options);
  6986. this._backend = new localStoreBackends[options.backend || "dom"](this, options);
  6987. this._backend.load()
  6988. },
  6989. clear: function() {
  6990. this.callBase();
  6991. this._backend.notifyChanged()
  6992. },
  6993. _insertImpl: function(values) {
  6994. var b = this._backend;
  6995. return this.callBase(values).done($.proxy(b.notifyChanged, b))
  6996. },
  6997. _updateImpl: function(key, values) {
  6998. var b = this._backend;
  6999. return this.callBase(key, values).done($.proxy(b.notifyChanged, b))
  7000. },
  7001. _removeImpl: function(key) {
  7002. var b = this._backend;
  7003. return this.callBase(key).done($.proxy(b.notifyChanged, b))
  7004. }
  7005. })
  7006. })(jQuery, DevExpress);
  7007. /*! Module core, file data.store.odata.js */
  7008. (function($, DX, undefined) {
  7009. var Class = DX.Class,
  7010. data = DX.data,
  7011. utils = DX.utils,
  7012. odataUtils = data.utils.odata;
  7013. var DEFAULT_PROTOCOL_VERSION = 2;
  7014. var formatFunctionInvocationUrl = function(baseUrl, args) {
  7015. return DX.stringFormat("{0}({1})", baseUrl, $.map(args || {}, function(value, key) {
  7016. return DX.stringFormat("{0}={1}", key, value)
  7017. }).join(","))
  7018. };
  7019. var escapeServiceOperationParams = function(params, version) {
  7020. if (!params)
  7021. return params;
  7022. var result = {};
  7023. $.each(params, function(k, v) {
  7024. result[k] = odataUtils.serializeValue(v, version)
  7025. });
  7026. return result
  7027. };
  7028. var convertSimpleKey = function(keyType, keyValue) {
  7029. var converter = odataUtils.keyConverters[keyType];
  7030. if (!converter)
  7031. throw DX.Error("E4014", keyType);
  7032. return converter(keyValue)
  7033. };
  7034. var SharedMethods = {
  7035. _extractServiceOptions: function(options) {
  7036. options = options || {};
  7037. this._url = String(options.url).replace(/\/+$/, "");
  7038. this._beforeSend = options.beforeSend;
  7039. this._jsonp = options.jsonp;
  7040. this._version = options.version || DEFAULT_PROTOCOL_VERSION;
  7041. this._withCredentials = options.withCredentials
  7042. },
  7043. _sendRequest: function(url, method, params, payload) {
  7044. return odataUtils.sendRequest(this.version(), {
  7045. url: url,
  7046. method: method,
  7047. params: params || {},
  7048. payload: payload
  7049. }, {
  7050. beforeSend: this._beforeSend,
  7051. jsonp: this._jsonp,
  7052. withCredentials: this._withCredentials
  7053. })
  7054. },
  7055. version: function() {
  7056. return this._version
  7057. }
  7058. };
  7059. var ODataStore = data.Store.inherit({
  7060. ctor: function(options) {
  7061. this.callBase(options);
  7062. this._extractServiceOptions(options);
  7063. this._keyType = options.keyType;
  7064. if (this.version() === 2)
  7065. this._updateMethod = "MERGE";
  7066. else
  7067. this._updateMethod = "PATCH"
  7068. },
  7069. _customLoadOptions: function() {
  7070. return ["expand", "customQueryParams"]
  7071. },
  7072. _byKeyImpl: function(key, extraOptions) {
  7073. var params = {};
  7074. if (extraOptions)
  7075. if (extraOptions.expand)
  7076. params["$expand"] = $.map($.makeArray(extraOptions.expand), odataUtils.serializePropName).join();
  7077. return this._sendRequest(this._byKeyUrl(key), "GET", params)
  7078. },
  7079. createQuery: function(loadOptions) {
  7080. var url,
  7081. queryOptions;
  7082. loadOptions = loadOptions || {};
  7083. queryOptions = {
  7084. beforeSend: this._beforeSend,
  7085. errorHandler: this._errorHandler,
  7086. jsonp: this._jsonp,
  7087. version: this._version,
  7088. withCredentials: this._withCredentials,
  7089. expand: loadOptions.expand,
  7090. requireTotalCount: loadOptions.requireTotalCount
  7091. };
  7092. if (utils.isDefined(loadOptions.urlOverride))
  7093. url = loadOptions.urlOverride;
  7094. else
  7095. url = this._url;
  7096. if ("customQueryParams" in loadOptions) {
  7097. var params = escapeServiceOperationParams(loadOptions.customQueryParams, this.version());
  7098. if (this.version() === 4)
  7099. url = formatFunctionInvocationUrl(url, params);
  7100. else
  7101. queryOptions.params = params
  7102. }
  7103. return data.query(url, queryOptions)
  7104. },
  7105. _insertImpl: function(values) {
  7106. this._requireKey();
  7107. var that = this,
  7108. d = $.Deferred();
  7109. $.when(this._sendRequest(this._url, "POST", null, values)).done(function(serverResponse) {
  7110. d.resolve(values, that.keyOf(serverResponse))
  7111. }).fail(d.reject);
  7112. return d.promise()
  7113. },
  7114. _updateImpl: function(key, values) {
  7115. var d = $.Deferred();
  7116. $.when(this._sendRequest(this._byKeyUrl(key), this._updateMethod, null, values)).done(function() {
  7117. d.resolve(key, values)
  7118. }).fail(d.reject, d);
  7119. return d.promise()
  7120. },
  7121. _removeImpl: function(key) {
  7122. var d = $.Deferred();
  7123. $.when(this._sendRequest(this._byKeyUrl(key), "DELETE")).done(function() {
  7124. d.resolve(key)
  7125. }).fail(d.reject, d);
  7126. return d.promise()
  7127. },
  7128. _byKeyUrl: function(key, useOriginalHost) {
  7129. var keyObj = key,
  7130. keyType = this._keyType,
  7131. baseUrl = useOriginalHost ? DX._proxyUrlFormatter.formatLocalUrl(this._url) : this._url;
  7132. if ($.isPlainObject(keyType)) {
  7133. keyObj = {};
  7134. $.each(keyType, function(subKeyName, subKeyType) {
  7135. keyObj[subKeyName] = convertSimpleKey(subKeyType, key[subKeyName])
  7136. })
  7137. }
  7138. else if (keyType)
  7139. keyObj = convertSimpleKey(keyType, key);
  7140. return baseUrl + "(" + encodeURIComponent(odataUtils.serializeKey(keyObj, this._version)) + ")"
  7141. }
  7142. }).include(SharedMethods);
  7143. var ODataContext = Class.inherit({
  7144. ctor: function(options) {
  7145. var that = this;
  7146. that._extractServiceOptions(options);
  7147. that._errorHandler = options.errorHandler;
  7148. $.each(options.entities || [], function(entityAlias, entityOptions) {
  7149. that[entityAlias] = new ODataStore($.extend({}, options, {url: that._url + "/" + encodeURIComponent(entityOptions.name || entityAlias)}, entityOptions))
  7150. })
  7151. },
  7152. get: function(operationName, params) {
  7153. return this.invoke(operationName, params, "GET")
  7154. },
  7155. invoke: function(operationName, params, httpMethod) {
  7156. params = params || {};
  7157. httpMethod = (httpMethod || "POST").toLowerCase();
  7158. var d = $.Deferred(),
  7159. url = this._url + "/" + encodeURIComponent(operationName),
  7160. payload;
  7161. if (this.version() === 4)
  7162. if (httpMethod === "get") {
  7163. url = formatFunctionInvocationUrl(url, escapeServiceOperationParams(params, this.version()));
  7164. params = null
  7165. }
  7166. else if (httpMethod === "post") {
  7167. payload = params;
  7168. params = null
  7169. }
  7170. $.when(this._sendRequest(url, httpMethod, escapeServiceOperationParams(params, this.version()), payload)).done(function(r) {
  7171. if ($.isPlainObject(r) && operationName in r)
  7172. r = r[operationName];
  7173. d.resolve(r)
  7174. }).fail([this._errorHandler, data._errorHandler, d.reject]);
  7175. return d.promise()
  7176. },
  7177. objectLink: function(entityAlias, key) {
  7178. var store = this[entityAlias];
  7179. if (!store)
  7180. throw DX.Error("E4015", entityAlias);
  7181. if (!utils.isDefined(key))
  7182. return null;
  7183. return {__metadata: {uri: store._byKeyUrl(key, true)}}
  7184. }
  7185. }).include(SharedMethods);
  7186. $.extend(data, {
  7187. ODataStore: ODataStore,
  7188. ODataContext: ODataContext
  7189. })
  7190. })(jQuery, DevExpress);
  7191. /*! Module core, file data.store.custom.js */
  7192. (function($, DX, undefined) {
  7193. var data = DX.data;
  7194. var TOTAL_COUNT = "totalCount",
  7195. LOAD = "load",
  7196. BY_KEY = "byKey",
  7197. INSERT = "insert",
  7198. UPDATE = "update",
  7199. REMOVE = "remove";
  7200. function isPromise(obj) {
  7201. return obj && $.isFunction(obj.then)
  7202. }
  7203. function trivialPromise(value) {
  7204. return $.Deferred().resolve(value).promise()
  7205. }
  7206. function ensureRequiredFuncOption(name, obj) {
  7207. if (!$.isFunction(obj))
  7208. throw DX.Error("E4011", name);
  7209. }
  7210. function throwInvalidUserFuncResult(name) {
  7211. throw DX.Error("E4012", name);
  7212. }
  7213. function createUserFuncFailureHandler(pendingDeferred) {
  7214. function errorMessageFromXhr(promiseArguments) {
  7215. var xhr = promiseArguments[0],
  7216. textStatus = promiseArguments[1];
  7217. if (!xhr || !xhr.getResponseHeader)
  7218. return null;
  7219. return data.utils.errorMessageFromXhr(xhr, textStatus)
  7220. }
  7221. return function(arg) {
  7222. var error;
  7223. if (arg instanceof Error)
  7224. error = arg;
  7225. else
  7226. error = new Error(errorMessageFromXhr(arguments) || arg && String(arg) || "Unknown error");
  7227. pendingDeferred.reject(error)
  7228. }
  7229. }
  7230. data.CustomStore = data.Store.inherit({
  7231. ctor: function(options) {
  7232. options = options || {};
  7233. this.callBase(options);
  7234. this._useDefaultSearch = false;
  7235. this._loadFunc = options[LOAD];
  7236. this._totalCountFunc = options[TOTAL_COUNT];
  7237. this._byKeyFunc = options[BY_KEY];
  7238. this._insertFunc = options[INSERT];
  7239. this._updateFunc = options[UPDATE];
  7240. this._removeFunc = options[REMOVE]
  7241. },
  7242. createQuery: function() {
  7243. throw DX.Error("E4010");
  7244. },
  7245. _totalCountImpl: function(options) {
  7246. var userFunc = this._totalCountFunc,
  7247. userResult,
  7248. d = $.Deferred();
  7249. ensureRequiredFuncOption(TOTAL_COUNT, userFunc);
  7250. userResult = userFunc(options);
  7251. if (!isPromise(userResult)) {
  7252. userResult = Number(userResult);
  7253. if (!isFinite(userResult))
  7254. throwInvalidUserFuncResult(TOTAL_COUNT);
  7255. userResult = trivialPromise(userResult)
  7256. }
  7257. userResult.then(function(count) {
  7258. d.resolve(Number(count))
  7259. }, createUserFuncFailureHandler(d));
  7260. return d.promise()
  7261. },
  7262. _loadImpl: function(options) {
  7263. var userFunc = this._loadFunc,
  7264. userResult,
  7265. d = $.Deferred();
  7266. ensureRequiredFuncOption(LOAD, userFunc);
  7267. userResult = userFunc(options);
  7268. if ($.isArray(userResult))
  7269. userResult = trivialPromise(userResult);
  7270. else if (userResult === null || userResult === undefined)
  7271. userResult = trivialPromise([]);
  7272. else if (!isPromise(userResult))
  7273. throwInvalidUserFuncResult(LOAD);
  7274. userResult.then(function(data, extra) {
  7275. d.resolve(data, extra)
  7276. }, createUserFuncFailureHandler(d));
  7277. return this._addFailHandlers(d.promise())
  7278. },
  7279. _byKeyImpl: function(key, extraOptions) {
  7280. var userFunc = this._byKeyFunc,
  7281. userResult,
  7282. d = $.Deferred();
  7283. ensureRequiredFuncOption(BY_KEY, userFunc);
  7284. userResult = userFunc(key, extraOptions);
  7285. if (!isPromise(userResult))
  7286. userResult = trivialPromise(userResult);
  7287. userResult.then(function(obj) {
  7288. d.resolve(obj)
  7289. }, createUserFuncFailureHandler(d));
  7290. return d.promise()
  7291. },
  7292. _insertImpl: function(values) {
  7293. var userFunc = this._insertFunc,
  7294. userResult,
  7295. d = $.Deferred();
  7296. ensureRequiredFuncOption(INSERT, userFunc);
  7297. userResult = userFunc(values);
  7298. if (!isPromise(userResult))
  7299. userResult = trivialPromise(userResult);
  7300. userResult.then(function(newKey) {
  7301. d.resolve(values, newKey)
  7302. }, createUserFuncFailureHandler(d));
  7303. return d.promise()
  7304. },
  7305. _updateImpl: function(key, values) {
  7306. var userFunc = this._updateFunc,
  7307. userResult,
  7308. d = $.Deferred();
  7309. ensureRequiredFuncOption(UPDATE, userFunc);
  7310. userResult = userFunc(key, values);
  7311. if (!isPromise(userResult))
  7312. userResult = trivialPromise();
  7313. userResult.then(function() {
  7314. d.resolve(key, values)
  7315. }, createUserFuncFailureHandler(d));
  7316. return d.promise()
  7317. },
  7318. _removeImpl: function(key) {
  7319. var userFunc = this._removeFunc,
  7320. userResult,
  7321. d = $.Deferred();
  7322. ensureRequiredFuncOption(REMOVE, userFunc);
  7323. userResult = userFunc(key);
  7324. if (!isPromise(userResult))
  7325. userResult = trivialPromise();
  7326. userResult.then(function() {
  7327. d.resolve(key)
  7328. }, createUserFuncFailureHandler(d));
  7329. return d.promise()
  7330. }
  7331. })
  7332. })(jQuery, DevExpress);
  7333. /*! Module core, file data.dataSource.js */
  7334. (function($, DX, undefined) {
  7335. var data = DX.data,
  7336. CustomStore = data.CustomStore,
  7337. Class = DX.Class;
  7338. var storeTypeRegistry = {
  7339. jaydata: "JayDataStore",
  7340. breeze: "BreezeStore",
  7341. odata: "ODataStore",
  7342. local: "LocalStore",
  7343. array: "ArrayStore"
  7344. };
  7345. var nextLoadOperationId = function() {
  7346. var id = -1;
  7347. return function() {
  7348. return ++id
  7349. }
  7350. }();
  7351. var canceledOperationsRegistry = function() {
  7352. var registry = {};
  7353. return {
  7354. add: function(operationId) {
  7355. registry[operationId] = true
  7356. },
  7357. has: function(operationId) {
  7358. return operationId in registry
  7359. },
  7360. remove: function(operationId) {
  7361. delete registry[operationId]
  7362. }
  7363. }
  7364. }();
  7365. var ensureIsNotRejected = function(loadOperationId, pendingDeferred) {
  7366. if (canceledOperationsRegistry.has(loadOperationId)) {
  7367. canceledOperationsRegistry.remove(loadOperationId);
  7368. pendingDeferred.reject("canceled");
  7369. return false
  7370. }
  7371. return true
  7372. };
  7373. function normalizeDataSourceOptions(options) {
  7374. var store;
  7375. function createCustomStoreFromLoadFunc() {
  7376. var storeConfig = {};
  7377. $.each(["key", "load", "byKey", "lookup", "totalCount", "insert", "update", "remove"], function() {
  7378. storeConfig[this] = options[this];
  7379. delete options[this]
  7380. });
  7381. return new CustomStore(storeConfig)
  7382. }
  7383. function createStoreFromConfig(storeConfig) {
  7384. var storeCtor = data[storeTypeRegistry[storeConfig.type]];
  7385. delete storeConfig.type;
  7386. return new storeCtor(storeConfig)
  7387. }
  7388. function createCustomStoreFromUrl(url) {
  7389. return new CustomStore({load: function() {
  7390. return $.getJSON(url)
  7391. }})
  7392. }
  7393. if (typeof options === "string")
  7394. options = createCustomStoreFromUrl(options);
  7395. if (options === undefined)
  7396. options = [];
  7397. if ($.isArray(options) || options instanceof data.Store)
  7398. options = {store: options};
  7399. else
  7400. options = $.extend({}, options);
  7401. if (options.store === undefined)
  7402. options.store = [];
  7403. store = options.store;
  7404. if ("load" in options)
  7405. store = createCustomStoreFromLoadFunc();
  7406. else if ($.isArray(store))
  7407. store = new data.ArrayStore(store);
  7408. else if ($.isPlainObject(store))
  7409. store = createStoreFromConfig($.extend({}, store));
  7410. options.store = store;
  7411. return options
  7412. }
  7413. function normalizeStoreLoadOptionAccessorArguments(originalArguments) {
  7414. switch (originalArguments.length) {
  7415. case 0:
  7416. return undefined;
  7417. case 1:
  7418. return originalArguments[0]
  7419. }
  7420. return $.makeArray(originalArguments)
  7421. }
  7422. function generateStoreLoadOptionAccessor(optionName) {
  7423. return function() {
  7424. var args = normalizeStoreLoadOptionAccessorArguments(arguments);
  7425. if (args !== undefined)
  7426. this._storeLoadOptions[optionName] = args;
  7427. return this._storeLoadOptions[optionName]
  7428. }
  7429. }
  7430. function mapDataRespectingGrouping(items, mapper, groupInfo) {
  7431. function mapRecursive(items, level) {
  7432. if (!DX.utils.isArray(items))
  7433. return items;
  7434. return level ? mapGroup(items, level) : $.map(items, mapper)
  7435. }
  7436. function mapGroup(group, level) {
  7437. return $.map(group, function(item) {
  7438. var result = {
  7439. key: item.key,
  7440. items: mapRecursive(item.items, level - 1)
  7441. };
  7442. if ("aggregates" in item)
  7443. result.aggregates = item.aggregates;
  7444. return result
  7445. })
  7446. }
  7447. return mapRecursive(items, groupInfo ? data.utils.normalizeSortingInfo(groupInfo).length : 0)
  7448. }
  7449. var DataSource = Class.inherit({
  7450. ctor: function(options) {
  7451. options = normalizeDataSourceOptions(options);
  7452. this._store = options.store;
  7453. this._storeLoadOptions = this._extractLoadOptions(options);
  7454. this._mapFunc = options.map;
  7455. this._postProcessFunc = options.postProcess;
  7456. this._pageIndex = options.pageIndex !== undefined ? options.pageIndex : 0;
  7457. this._pageSize = options.pageSize !== undefined ? options.pageSize : 20;
  7458. this._items = [];
  7459. this._totalCount = -1;
  7460. this._isLoaded = false;
  7461. this._loadingCount = 0;
  7462. this._loadQueue = this._createLoadQueue();
  7463. this._searchValue = "searchValue" in options ? options.searchValue : null;
  7464. this._searchOperation = options.searchOperation || "contains";
  7465. this._searchExpr = options.searchExpr;
  7466. this._paginate = options.paginate;
  7467. if (this._paginate === undefined)
  7468. this._paginate = !this.group();
  7469. this._isLastPage = !this._paginate;
  7470. this._userData = {};
  7471. $.each(["changed", "loadError", "loadingChanged"], $.proxy(function(_, eventName) {
  7472. var callbacks = this[eventName] = $.Callbacks();
  7473. var originalAdd = callbacks.add;
  7474. callbacks.add = function() {
  7475. DX.log("W0003", "DataSource", eventName, "14.2", "Use the '" + eventName + "' event instead");
  7476. return originalAdd.apply(eventName, arguments)
  7477. }
  7478. }, this));
  7479. $.each(["changed", "loadError", "loadingChanged", "customizeLoadResult", "customizeStoreLoadOptions"], $.proxy(function(_, eventName) {
  7480. var optionName = "on" + eventName[0].toUpperCase() + eventName.slice(1);
  7481. if (options.hasOwnProperty(optionName))
  7482. this.on(eventName, options[optionName])
  7483. }, this))
  7484. },
  7485. dispose: function() {
  7486. this.changed.empty();
  7487. this.loadError.empty();
  7488. this.loadingChanged.empty();
  7489. this._disposeEvents();
  7490. delete this._store;
  7491. if (this._delayedLoadTask)
  7492. this._delayedLoadTask.abort();
  7493. this._disposed = true
  7494. },
  7495. _extractLoadOptions: function(options) {
  7496. var result = {},
  7497. names = ["sort", "filter", "select", "group", "requireTotalCount"],
  7498. customNames = this._store._customLoadOptions();
  7499. if (customNames)
  7500. names = names.concat(customNames);
  7501. $.each(names, function() {
  7502. result[this] = options[this]
  7503. });
  7504. return result
  7505. },
  7506. loadOptions: function() {
  7507. return this._storeLoadOptions
  7508. },
  7509. items: function() {
  7510. return this._items
  7511. },
  7512. pageIndex: function(newIndex) {
  7513. if (newIndex !== undefined) {
  7514. this._pageIndex = newIndex;
  7515. this._isLastPage = !this._paginate
  7516. }
  7517. return this._pageIndex
  7518. },
  7519. paginate: function(value) {
  7520. if (arguments.length < 1)
  7521. return this._paginate;
  7522. value = !!value;
  7523. if (this._paginate !== value) {
  7524. this._paginate = value;
  7525. this.pageIndex(0)
  7526. }
  7527. },
  7528. pageSize: function(value) {
  7529. if (arguments.length < 1)
  7530. return this._pageSize;
  7531. this._pageSize = value
  7532. },
  7533. isLastPage: function() {
  7534. return this._isLastPage
  7535. },
  7536. sort: generateStoreLoadOptionAccessor("sort"),
  7537. filter: function() {
  7538. var newFilter = normalizeStoreLoadOptionAccessorArguments(arguments);
  7539. if (newFilter !== undefined) {
  7540. this._storeLoadOptions.filter = newFilter;
  7541. this.pageIndex(0)
  7542. }
  7543. return this._storeLoadOptions.filter
  7544. },
  7545. group: generateStoreLoadOptionAccessor("group"),
  7546. select: generateStoreLoadOptionAccessor("select"),
  7547. requireTotalCount: generateStoreLoadOptionAccessor("requireTotalCount"),
  7548. searchValue: function(value) {
  7549. if (value !== undefined) {
  7550. this.pageIndex(0);
  7551. this._searchValue = value
  7552. }
  7553. return this._searchValue
  7554. },
  7555. searchOperation: function(op) {
  7556. if (op !== undefined) {
  7557. this.pageIndex(0);
  7558. this._searchOperation = op
  7559. }
  7560. return this._searchOperation
  7561. },
  7562. searchExpr: function(expr) {
  7563. var argc = arguments.length;
  7564. if (argc) {
  7565. if (argc > 1)
  7566. expr = $.makeArray(arguments);
  7567. this.pageIndex(0);
  7568. this._searchExpr = expr
  7569. }
  7570. return this._searchExpr
  7571. },
  7572. store: function() {
  7573. return this._store
  7574. },
  7575. key: function() {
  7576. return this._store && this._store.key()
  7577. },
  7578. totalCount: function() {
  7579. return this._totalCount
  7580. },
  7581. isLoaded: function() {
  7582. return this._isLoaded
  7583. },
  7584. isLoading: function() {
  7585. return this._loadingCount > 0
  7586. },
  7587. _createLoadQueue: function() {
  7588. return DX.createQueue()
  7589. },
  7590. _changeLoadingCount: function(increment) {
  7591. var oldLoading = this.isLoading(),
  7592. newLoading;
  7593. this._loadingCount += increment;
  7594. newLoading = this.isLoading();
  7595. if (oldLoading ^ newLoading) {
  7596. this.fireEvent("loadingChanged", [newLoading]);
  7597. this.loadingChanged.fire(newLoading)
  7598. }
  7599. },
  7600. _scheduleLoadCallbacks: function(deferred) {
  7601. var that = this;
  7602. that._changeLoadingCount(1);
  7603. deferred.always(function() {
  7604. that._changeLoadingCount(-1)
  7605. })
  7606. },
  7607. _scheduleChangedCallbacks: function(deferred) {
  7608. var that = this;
  7609. deferred.done(function() {
  7610. that.fireEvent("changed");
  7611. that.changed.fire()
  7612. })
  7613. },
  7614. loadSingle: function(propName, propValue) {
  7615. var that = this;
  7616. var d = $.Deferred().fail(function() {
  7617. that.fireEvent("loadError", arguments);
  7618. that.loadError.fire.apply(that, arguments)
  7619. }),
  7620. key = this.key(),
  7621. store = this._store,
  7622. loadOptions = this._createStoreLoadOptions();
  7623. function handleSuccess(data) {
  7624. if (data === null || typeof data === "undefined" || $.isArray(data) && data.length < 1)
  7625. d.reject();
  7626. else
  7627. d.resolve(that._transformLoadedData(data)[0])
  7628. }
  7629. if (arguments.length < 2) {
  7630. propValue = propName;
  7631. propName = key
  7632. }
  7633. delete loadOptions.skip;
  7634. delete loadOptions.group;
  7635. delete loadOptions.refresh;
  7636. delete loadOptions.pageIndex;
  7637. delete loadOptions.searchString;
  7638. if (propName === key || store instanceof data.CustomStore)
  7639. store.byKey(propValue, loadOptions).done(handleSuccess).fail(d.reject);
  7640. else {
  7641. loadOptions.take = 1;
  7642. loadOptions.filter = loadOptions.filter ? [loadOptions.filter, [propName, propValue]] : [propName, propValue];
  7643. store.load(loadOptions).done(handleSuccess).fail(d.reject)
  7644. }
  7645. return d.promise()
  7646. },
  7647. load: function() {
  7648. var that = this,
  7649. d = $.Deferred(),
  7650. loadOptions;
  7651. this._scheduleLoadCallbacks(d);
  7652. this._scheduleChangedCallbacks(d);
  7653. loadOptions = this._createLoadOptions();
  7654. this.fireEvent("customizeStoreLoadOptions", [loadOptions]);
  7655. if (!ensureIsNotRejected(loadOptions.operationId, d))
  7656. return d.promise();
  7657. function errorCallback() {
  7658. if (arguments[0] !== "canceled") {
  7659. that.fireEvent("loadError", arguments);
  7660. that.loadError.fire.apply(that.loadError, arguments)
  7661. }
  7662. }
  7663. function loadTask() {
  7664. if (that._disposed)
  7665. return undefined;
  7666. return that._loadFromStore(loadOptions, d)
  7667. }
  7668. this._loadQueue.add(function() {
  7669. if (typeof loadOptions.delay === "number")
  7670. that._delayedLoadTask = DX.utils.executeAsync(loadTask, loadOptions.delay);
  7671. else
  7672. loadTask();
  7673. return d.promise()
  7674. });
  7675. return d.promise({loadOperationId: loadOptions.operationId}).fail(errorCallback)
  7676. },
  7677. reload: function() {
  7678. var prop,
  7679. userData = this._userData;
  7680. for (prop in userData)
  7681. if (userData.hasOwnProperty(prop))
  7682. delete userData[prop];
  7683. this._totalCount = -1;
  7684. this._isLoaded = false;
  7685. return this.load()
  7686. },
  7687. cancel: function(loadOperationId) {
  7688. canceledOperationsRegistry.add(loadOperationId)
  7689. },
  7690. _addSearchOptions: function(storeLoadOptions) {
  7691. if (this._disposed)
  7692. return;
  7693. if (this.store()._useDefaultSearch)
  7694. this._addSearchFilter(storeLoadOptions);
  7695. else {
  7696. storeLoadOptions.searchOperation = this._searchOperation;
  7697. storeLoadOptions.searchValue = this._searchValue;
  7698. storeLoadOptions.searchExpr = this._searchExpr
  7699. }
  7700. },
  7701. _createStoreLoadOptions: function() {
  7702. var result = $.extend({}, this._storeLoadOptions);
  7703. this._addSearchOptions(result);
  7704. if (this._paginate)
  7705. if (this._pageSize) {
  7706. result.skip = this._pageIndex * this._pageSize;
  7707. result.take = this._pageSize
  7708. }
  7709. result.userData = this._userData;
  7710. return result
  7711. },
  7712. _createLoadOptions: function() {
  7713. return {
  7714. operationId: nextLoadOperationId(),
  7715. storeLoadOptions: this._createStoreLoadOptions()
  7716. }
  7717. },
  7718. _addSearchFilter: function(storeLoadOptions) {
  7719. var value = this._searchValue,
  7720. op = this._searchOperation,
  7721. selector = this._searchExpr,
  7722. searchFilter = [];
  7723. if (!value)
  7724. return;
  7725. if (!selector)
  7726. selector = "this";
  7727. if (!$.isArray(selector))
  7728. selector = [selector];
  7729. $.each(selector, function(i, item) {
  7730. if (searchFilter.length)
  7731. searchFilter.push("or");
  7732. searchFilter.push([item, op, value])
  7733. });
  7734. if (storeLoadOptions.filter)
  7735. storeLoadOptions.filter = [searchFilter, storeLoadOptions.filter];
  7736. else
  7737. storeLoadOptions.filter = searchFilter
  7738. },
  7739. _loadFromStore: function(loadOptions, pendingDeferred) {
  7740. var that = this;
  7741. function handleSuccess(data, extra) {
  7742. function processResult() {
  7743. var loadResult;
  7744. loadResult = $.extend({
  7745. data: data,
  7746. extra: extra
  7747. }, loadOptions);
  7748. that.fireEvent("customizeLoadResult", [loadResult]);
  7749. if (ensureIsNotRejected(loadOptions.operationId, pendingDeferred))
  7750. that._processStoreLoadResult(loadResult, pendingDeferred)
  7751. }
  7752. if (that._disposed)
  7753. return;
  7754. processResult()
  7755. }
  7756. if (!ensureIsNotRejected(loadOptions.operationId, pendingDeferred))
  7757. return pendingDeferred.promise();
  7758. return this.store().load(loadOptions.storeLoadOptions).done(handleSuccess).fail(pendingDeferred.reject)
  7759. },
  7760. _processStoreLoadResult: function(loadResult, pendingDeferred) {
  7761. var that = this;
  7762. var data = loadResult.data,
  7763. extra = loadResult.extra,
  7764. storeLoadOptions = loadResult.storeLoadOptions;
  7765. function resolvePendingDeferred() {
  7766. if (!ensureIsNotRejected(loadResult.operationId, pendingDeferred))
  7767. return pendingDeferred;
  7768. that._isLoaded = true;
  7769. that._totalCount = isFinite(extra.totalCount) ? extra.totalCount : -1;
  7770. return pendingDeferred.resolve(data, extra)
  7771. }
  7772. function proceedLoadingTotalCount() {
  7773. that.store().totalCount(storeLoadOptions).done(function(count) {
  7774. extra.totalCount = count;
  7775. resolvePendingDeferred()
  7776. }).fail(function(){})
  7777. }
  7778. if (that._disposed)
  7779. return;
  7780. data = that._transformLoadedData(data);
  7781. if (!$.isPlainObject(extra))
  7782. extra = {};
  7783. that._items = data;
  7784. if (!data.length || !that._paginate || that._pageSize && data.length < that._pageSize)
  7785. that._isLastPage = true;
  7786. if (storeLoadOptions.requireTotalCount && !isFinite(extra.totalCount))
  7787. proceedLoadingTotalCount();
  7788. else
  7789. resolvePendingDeferred()
  7790. },
  7791. _transformLoadedData: function(data) {
  7792. var result = $.makeArray(data);
  7793. if (this._mapFunc)
  7794. result = mapDataRespectingGrouping(result, this._mapFunc, this.group());
  7795. if (this._postProcessFunc)
  7796. result = this._postProcessFunc(result);
  7797. return result
  7798. }
  7799. }).include(DX.EventsMixin);
  7800. $.extend(true, data, {
  7801. DataSource: DataSource,
  7802. utils: {
  7803. storeTypeRegistry: storeTypeRegistry,
  7804. normalizeDataSourceOptions: normalizeDataSourceOptions
  7805. }
  7806. })
  7807. })(jQuery, DevExpress);
  7808. /*! Module core, file ko.js */
  7809. (function($, DX) {
  7810. if (DX.support.hasKo && DX.compareVersions(ko.version, [2, 3]) < 0)
  7811. throw DX.Error("E0013");
  7812. })(jQuery, DevExpress);
  7813. /*! Module core, file ng.js */
  7814. (function($, DX, undefined) {
  7815. if (!DX.support.hasNg)
  7816. return;
  7817. DX.ng = {module: window.angular.module("dx", ["ngSanitize"])}
  7818. })(jQuery, DevExpress);
  7819. /*! Module core, file component.js */
  7820. (function($, DX, undefined) {
  7821. var utils = DX.utils,
  7822. dataUtils = DX.data.utils,
  7823. inflector = DX.inflector;
  7824. var Component = DX.Class.inherit({
  7825. NAME: "Component",
  7826. _setDeprecatedOptions: function() {
  7827. this._deprecatedOptions = {}
  7828. },
  7829. _getDeprecatedOptions: function() {
  7830. return this._deprecatedOptions
  7831. },
  7832. _setOptionAliases: function() {
  7833. var aliases = this._optionAliases = {};
  7834. $.each(this._getDeprecatedOptions(), function(optionName, info) {
  7835. var optionAlias = info.alias;
  7836. if (optionAlias)
  7837. aliases[optionName] = optionAlias
  7838. })
  7839. },
  7840. _getOptionAliases: function() {
  7841. return this._optionAliases
  7842. },
  7843. _getOptionAliasesByName: function(optionName) {
  7844. return $.map(this._getOptionAliases(), function(aliasedOption, aliasName) {
  7845. return optionName === aliasedOption ? aliasName : undefined
  7846. })
  7847. },
  7848. _setDefaultOptions: function() {
  7849. this.option({
  7850. onInitialized: null,
  7851. onOptionChanged: null,
  7852. onDisposing: null,
  7853. defaultOptionsRules: null
  7854. })
  7855. },
  7856. _defaultOptionsRules: function() {
  7857. return []
  7858. },
  7859. _setOptionsByDevice: function(userRules) {
  7860. var rules = this._defaultOptionsRules();
  7861. if (this._customRules)
  7862. rules = rules.concat(this._customRules);
  7863. if ($.isArray(userRules))
  7864. rules = rules.concat(userRules);
  7865. this.option(this._convertRulesToOptions(rules))
  7866. },
  7867. _convertRulesToOptions: function(rules) {
  7868. var options = {};
  7869. var currentDevice = DX.devices.current();
  7870. var deviceMatch = function(device, filter) {
  7871. filter = $.makeArray(filter);
  7872. return filter.length === 1 && $.isEmptyObject(filter[0]) || utils.findBestMatches(device, filter).length > 0
  7873. };
  7874. $.each(rules, function(index, rule) {
  7875. var deviceFilter = rule.device || {},
  7876. match;
  7877. if ($.isFunction(deviceFilter))
  7878. match = deviceFilter(currentDevice);
  7879. else
  7880. match = deviceMatch(currentDevice, deviceFilter);
  7881. if (match)
  7882. $.extend(options, rule.options)
  7883. });
  7884. return options
  7885. },
  7886. _isInitialOptionValue: function(name) {
  7887. var isCustomOption = this._customRules && this._convertRulesToOptions(this._customRules).hasOwnProperty(name);
  7888. var isInitialOption = this.option(name) === this._initialOptions[name];
  7889. return !isCustomOption && isInitialOption
  7890. },
  7891. _setOptionsByReference: function() {
  7892. this._optionsByReference = {}
  7893. },
  7894. _getOptionsByReference: function() {
  7895. return this._optionsByReference
  7896. },
  7897. ctor: function(options) {
  7898. if (!this.NAME)
  7899. throw DX.Error("E0004");
  7900. options = options || {};
  7901. this._options = {};
  7902. this._cachedGetters = {};
  7903. this._updateLockCount = 0;
  7904. this._optionChangedCallbacks = options._optionChangedCallbacks || $.Callbacks();
  7905. this._disposingCallbacks = options._disposingCallbacks || $.Callbacks();
  7906. this.optionChanged = $.Callbacks();
  7907. this.disposing = $.Callbacks();
  7908. $.each(["optionChanged", "disposing"], $.proxy(function(_, propertyName) {
  7909. var that = this,
  7910. originalAdd = this[propertyName].add;
  7911. this[propertyName].add = function() {
  7912. DX.log("W0003", that.NAME, propertyName, "14.2", "Use the '" + propertyName + "' event instead");
  7913. return originalAdd.apply(this, arguments)
  7914. }
  7915. }, this));
  7916. this.beginUpdate();
  7917. try {
  7918. this._suppressDeprecatedWarnings();
  7919. this._setOptionsByReference();
  7920. this._setDeprecatedOptions();
  7921. this._setOptionAliases();
  7922. this._setDefaultOptions();
  7923. this._setOptionsByDevice(options.defaultOptionsRules);
  7924. this._resumeDeprecatedWarnings();
  7925. this._initialOptions = $.extend({}, this.option());
  7926. this._initOptions(options)
  7927. }
  7928. finally {
  7929. this.endUpdate()
  7930. }
  7931. },
  7932. _initOptions: function(options) {
  7933. this.option(options)
  7934. },
  7935. _optionValuesEqual: function(name, oldValue, newValue) {
  7936. oldValue = dataUtils.toComparable(oldValue, true);
  7937. newValue = dataUtils.toComparable(newValue, true);
  7938. if (oldValue && newValue && oldValue.jquery && newValue.jquery)
  7939. return newValue.is(oldValue);
  7940. var oldValueIsNaN = oldValue !== oldValue,
  7941. newValueIsNaN = newValue !== newValue;
  7942. if (oldValueIsNaN && newValueIsNaN)
  7943. return true;
  7944. if (oldValue === null || typeof oldValue !== "object")
  7945. return oldValue === newValue;
  7946. return false
  7947. },
  7948. _init: function() {
  7949. this._createOptionChangedAction();
  7950. this._createDisposingAction();
  7951. this.on("optionChanged", function(args) {
  7952. this._optionChangedCallbacks.fireWith(this, [args])
  7953. });
  7954. this.on("disposing", function(args) {
  7955. this._disposingCallbacks.fireWith(this, [args])
  7956. })
  7957. },
  7958. _createOptionChangedAction: function() {
  7959. this._optionChangedAction = this._createActionByOption("onOptionChanged", {excludeValidators: ["disabled", "readOnly"]})
  7960. },
  7961. _createDisposingAction: function() {
  7962. this._disposingAction = this._createActionByOption("onDisposing", {excludeValidators: ["disabled", "readOnly"]})
  7963. },
  7964. _optionChanged: function(args) {
  7965. switch (args.name) {
  7966. case"onInitialized":
  7967. break;
  7968. case"onOptionChanged":
  7969. this._createOptionChangedAction();
  7970. break;
  7971. case"onDisposing":
  7972. this._createDisposingAction();
  7973. break;
  7974. case"defaultOptionsRules":
  7975. break
  7976. }
  7977. },
  7978. _dispose: function() {
  7979. this.optionChanged.empty();
  7980. this.disposing.fireWith(this).empty();
  7981. this._disposingAction();
  7982. this._disposeEvents();
  7983. this._disposed = true
  7984. },
  7985. instance: function() {
  7986. return this
  7987. },
  7988. beginUpdate: function() {
  7989. this._updateLockCount++
  7990. },
  7991. endUpdate: function() {
  7992. this._updateLockCount--;
  7993. if (!this._updateLockCount)
  7994. if (!this._initializing && !this._initialized) {
  7995. this._initializing = true;
  7996. try {
  7997. this._init()
  7998. }
  7999. finally {
  8000. this._initializing = false;
  8001. this._initialized = true;
  8002. this._createActionByOption("onInitialized")()
  8003. }
  8004. }
  8005. },
  8006. _logWarningIfDeprecated: function(option) {
  8007. var info = this._getDeprecatedOptions()[option];
  8008. if (info && !this._deprecatedOptionsSuppressed)
  8009. this._logDeprecatedWarning(option, info)
  8010. },
  8011. _logDeprecatedWarningCount: 0,
  8012. _logDeprecatedWarning: function(option, info) {
  8013. var message = info.message || "Use the '" + info.alias + "' option instead";
  8014. DX.log("W0001", this.NAME, option, info.since, message);
  8015. ++this._logDeprecatedWarningCount
  8016. },
  8017. _suppressDeprecatedWarnings: function() {
  8018. this._deprecatedOptionsSuppressed = true
  8019. },
  8020. _resumeDeprecatedWarnings: function() {
  8021. this._deprecatedOptionsSuppressed = false
  8022. },
  8023. _notifyOptionChanged: function(option, value, previousValue) {
  8024. var that = this;
  8025. if (this._initialized)
  8026. $.each(that._getOptionAliasesByName(option).concat([option]), function(index, name) {
  8027. var args = {
  8028. name: name.split(/[.\[]/)[0],
  8029. fullName: name,
  8030. value: value,
  8031. previousValue: previousValue
  8032. };
  8033. that.optionChanged.fireWith(that, [args.name, value, previousValue]);
  8034. that._optionChangedAction($.extend({}, args));
  8035. if (!that._disposed)
  8036. that._optionChanged(args)
  8037. })
  8038. },
  8039. initialOption: function(optionName) {
  8040. var options = this._initialOptions;
  8041. return options[optionName]
  8042. },
  8043. _defaultActionConfig: function() {
  8044. return {
  8045. context: this,
  8046. component: this
  8047. }
  8048. },
  8049. _defaultActionArgs: function() {
  8050. return {component: this}
  8051. },
  8052. _createAction: function(actionSource, config) {
  8053. var that = this,
  8054. action = new DX.Action(actionSource, $.extend(config, that._defaultActionConfig()));
  8055. return function(e) {
  8056. if (!arguments.length)
  8057. e = {};
  8058. if (e instanceof $.Event)
  8059. throw Error("Action must be executed with jQuery.Event like action({ jQueryEvent: event })");
  8060. if (!$.isPlainObject(e))
  8061. e = {actionValue: e};
  8062. return action.execute.call(action, $.extend(e, that._defaultActionArgs()))
  8063. }
  8064. },
  8065. _createActionByOption: function(optionName, config) {
  8066. config = config || {};
  8067. if (typeof optionName !== "string")
  8068. throw DX.Error("E0008");
  8069. var matches = /^on(\w+)/.exec(optionName);
  8070. if (matches) {
  8071. var eventName = inflector.camelize(matches[1]),
  8072. afterExecute = config.afterExecute || $.noop,
  8073. that = this;
  8074. config.afterExecute = function(args) {
  8075. that.fireEvent(eventName, args.args);
  8076. return afterExecute.apply(this, arguments)
  8077. }
  8078. }
  8079. else {
  8080. var optionAlias = this._getOptionAliasesByName(optionName),
  8081. isOptionDeprecated = Boolean(this._getDeprecatedOptions()[optionName]);
  8082. if (isOptionDeprecated) {
  8083. if (optionAlias.length)
  8084. throw Error("The '" + optionName + "' is deprecated and has alias '" + optionAlias + "'");
  8085. }
  8086. else
  8087. throw Error("The '" + optionName + "' option name should start with 'on' prefix");
  8088. }
  8089. this._suppressDeprecatedWarnings();
  8090. var action = this._createAction(this.option(optionName), config);
  8091. this._resumeDeprecatedWarnings();
  8092. return action
  8093. },
  8094. option: function(options) {
  8095. var that = this,
  8096. name = options,
  8097. value = arguments[1],
  8098. optionAliases = this._getOptionAliases();
  8099. var normalizeOptionName = function(name) {
  8100. if (name) {
  8101. that._logWarningIfDeprecated(name);
  8102. if (optionAliases[name])
  8103. name = optionAliases[name]
  8104. }
  8105. return name
  8106. };
  8107. var getOptionValue = function(name, unwrapObservables) {
  8108. if (!that._cachedGetters[name])
  8109. that._cachedGetters[name] = dataUtils.compileGetter(name);
  8110. return that._cachedGetters[name](that._options, {
  8111. functionsAsIs: true,
  8112. unwrapObservables: unwrapObservables
  8113. })
  8114. };
  8115. if (arguments.length < 2 && $.type(name) !== "object") {
  8116. name = normalizeOptionName(name);
  8117. return getOptionValue(name)
  8118. }
  8119. if (typeof name === "string") {
  8120. options = {};
  8121. options[name] = value
  8122. }
  8123. that.beginUpdate();
  8124. try {
  8125. $.each(options, function(name, value) {
  8126. name = normalizeOptionName(name);
  8127. var prevValue = getOptionValue(name, false);
  8128. if (that._optionValuesEqual(name, prevValue, value))
  8129. return;
  8130. dataUtils.compileSetter(name)(that._options, value, {
  8131. functionsAsIs: true,
  8132. merge: !that._getOptionsByReference()[name],
  8133. unwrapObservables: false
  8134. });
  8135. that._notifyOptionChanged(name, value, prevValue)
  8136. })
  8137. }
  8138. finally {
  8139. that.endUpdate()
  8140. }
  8141. }
  8142. }).include(DX.EventsMixin);
  8143. $.extend(DX, {Component: Component})
  8144. })(jQuery, DevExpress);
  8145. /*! Module core, file transitionExecutor.js */
  8146. (function($, DX) {
  8147. var directionPostfixes = {
  8148. forward: " dx-forward",
  8149. backward: " dx-backward",
  8150. none: " dx-no-direction",
  8151. undefined: " dx-no-direction"
  8152. };
  8153. var addToAnimate = function(targetArray, $elements, animationConfig, type) {
  8154. $elements.each(function() {
  8155. var resultAnimationConfig = prepareElementAnimationConfig(animationConfig, type);
  8156. if (resultAnimationConfig)
  8157. targetArray.push({
  8158. $element: $(this),
  8159. animationConfig: resultAnimationConfig
  8160. })
  8161. })
  8162. };
  8163. var prepareElementAnimationConfig = function(config, type) {
  8164. var result;
  8165. if (typeof config === "string") {
  8166. var presetName = config;
  8167. config = DX.animationPresets.getPreset(presetName)
  8168. }
  8169. if (!config)
  8170. result = undefined;
  8171. else if ($.isFunction(config[type]))
  8172. result = config[type];
  8173. else {
  8174. var cssClass = "dx-" + type;
  8175. result = $.extend({skipElementInitialStyles: true}, config);
  8176. if (!result.type || result.type === "css") {
  8177. var extraCssClasses = result.extraCssClasses ? " " + result.extraCssClasses : "";
  8178. result.type = "css";
  8179. result.from = result.from || cssClass + extraCssClasses;
  8180. result.to = result.to || cssClass + "-active"
  8181. }
  8182. }
  8183. return result
  8184. };
  8185. var setupAnimations = function(items, config) {
  8186. var result = [];
  8187. $.each(items, function(index, item) {
  8188. var animationConfig = item.animationConfig,
  8189. $element = item.$element,
  8190. animationInstance;
  8191. if ($.isPlainObject(animationConfig)) {
  8192. var fxConfig = getFXConfig(animationConfig, config);
  8193. fxConfig.staggerDelay = fxConfig.staggerDelay || 0;
  8194. fxConfig.delay = index * fxConfig.staggerDelay + fxConfig.delay;
  8195. animationInstance = DX.fx.createAnimation($element, fxConfig)
  8196. }
  8197. else if ($.isFunction(animationConfig))
  8198. animationInstance = animationConfig($element, config);
  8199. animationInstance.setup();
  8200. result.push({
  8201. $element: $element,
  8202. animationInstance: animationInstance
  8203. })
  8204. });
  8205. return result
  8206. };
  8207. var startAnimations = function(items) {
  8208. for (var i = 0; i < items.length; i++)
  8209. items[i].animationInstance.start()
  8210. };
  8211. var getFXConfig = function(animation, config) {
  8212. var result = animation;
  8213. result.cleanupWhen = config.cleanupWhen;
  8214. result.delay = result.delay || 0;
  8215. if (result.type === "css") {
  8216. var direction = animation.direction || config.direction,
  8217. directionPostfix = directionPostfixes[direction];
  8218. result.from += directionPostfix
  8219. }
  8220. return result
  8221. };
  8222. var TransitionExecutor = DevExpress.Class.inherit({
  8223. ctor: function() {
  8224. this.toEnterItems = [];
  8225. this.toLeaveItems = [];
  8226. this.reset()
  8227. },
  8228. reset: function() {
  8229. this.toEnterItems.length = 0;
  8230. this.toLeaveItems.length = 0
  8231. },
  8232. enter: function($elements, animation) {
  8233. animation = animation || {};
  8234. addToAnimate(this.toEnterItems, $elements, animation, "enter")
  8235. },
  8236. leave: function($elements, animation) {
  8237. animation = animation || {};
  8238. addToAnimate(this.toLeaveItems, $elements, animation, "leave")
  8239. },
  8240. start: function(config) {
  8241. config = $.extend({}, config);
  8242. var that = this,
  8243. result;
  8244. if (!this.toEnterItems.length && !this.toLeaveItems.length) {
  8245. that.reset();
  8246. result = $.Deferred().resolve().promise()
  8247. }
  8248. else {
  8249. var animationItems = [],
  8250. animationDeferreds,
  8251. completeDeferred = $.Deferred();
  8252. config.cleanupWhen = completeDeferred.promise();
  8253. animationItems.push.apply(animationItems, setupAnimations(this.toEnterItems, config));
  8254. animationItems.push.apply(animationItems, setupAnimations(this.toLeaveItems, config));
  8255. animationDeferreds = $.map(animationItems, function(item) {
  8256. return item.animationInstance.deferred
  8257. });
  8258. result = $.when.apply($, animationDeferreds).always(function() {
  8259. completeDeferred.resolve();
  8260. that.reset()
  8261. });
  8262. DX.utils.executeAsync(function() {
  8263. startAnimations(animationItems)
  8264. })
  8265. }
  8266. return result
  8267. }
  8268. });
  8269. var optionPrefix = "preset_";
  8270. var AnimationPresetCollection = DevExpress.Component.inherit({
  8271. ctor: function() {
  8272. this.callBase.apply(this, arguments);
  8273. this._customRules = [];
  8274. this._registeredPresets = [];
  8275. this.resetToDefaults()
  8276. },
  8277. _setDefaultOptions: function() {
  8278. this.callBase();
  8279. this.option({
  8280. defaultAnimationDuration: 400,
  8281. defaultAnimationDelay: 0,
  8282. defaultStaggerAnimationDuration: 300,
  8283. defaultStaggerAnimationDelay: 40,
  8284. defaultStaggerAnimationStartDelay: 500
  8285. })
  8286. },
  8287. _defaultOptionsRules: function() {
  8288. return this.callBase().concat([{
  8289. device: function(device) {
  8290. return device.phone
  8291. },
  8292. options: {
  8293. defaultStaggerAnimationDuration: 350,
  8294. defaultStaggerAnimationDelay: 50,
  8295. defaultStaggerAnimationStartDelay: 0
  8296. }
  8297. }, {
  8298. device: function(device) {
  8299. return device.android
  8300. },
  8301. options: {defaultAnimationDelay: 100}
  8302. }])
  8303. },
  8304. _getPresetOptionName: function(animationName) {
  8305. return optionPrefix + animationName
  8306. },
  8307. resetToDefaults: function() {
  8308. this.clear();
  8309. this.registerDefaultPresets();
  8310. this.applyChanges()
  8311. },
  8312. clear: function(name) {
  8313. var that = this,
  8314. newRegisteredPresets = [];
  8315. $.each(this._registeredPresets, function(index, preset) {
  8316. if (!name || name === preset.name)
  8317. that.option(that._getPresetOptionName(preset.name), undefined);
  8318. else
  8319. newRegisteredPresets.push(preset)
  8320. });
  8321. this._registeredPresets = newRegisteredPresets;
  8322. this.applyChanges()
  8323. },
  8324. registerPreset: function(name, config) {
  8325. this._registeredPresets.push({
  8326. name: name,
  8327. config: config
  8328. })
  8329. },
  8330. applyChanges: function() {
  8331. var that = this;
  8332. this._customRules.length = 0;
  8333. $.each(this._registeredPresets, function(index, preset) {
  8334. var rule = {
  8335. device: preset.config.device,
  8336. options: {}
  8337. };
  8338. rule.options[that._getPresetOptionName(preset.name)] = preset.config.animation;
  8339. that._customRules.push(rule)
  8340. });
  8341. this._setOptionsByDevice()
  8342. },
  8343. getPreset: function(name) {
  8344. var result = name;
  8345. while (typeof result === "string")
  8346. result = this.option(this._getPresetOptionName(result));
  8347. return result
  8348. },
  8349. registerDefaultPresets: function() {
  8350. this.registerPreset("fade", {animation: {
  8351. extraCssClasses: "dx-fade-animation",
  8352. delay: this.option("defaultAnimationDelay"),
  8353. duration: this.option("defaultAnimationDuration")
  8354. }});
  8355. this.registerPreset("slide", {animation: {
  8356. extraCssClasses: "dx-slide-animation",
  8357. delay: this.option("defaultAnimationDelay"),
  8358. duration: this.option("defaultAnimationDuration")
  8359. }});
  8360. this.registerPreset("ios7-slide", {animation: {
  8361. extraCssClasses: "dx-ios7-slide-animation",
  8362. delay: this.option("defaultAnimationDelay"),
  8363. duration: this.option("defaultAnimationDuration")
  8364. }});
  8365. this.registerPreset("overflow", {animation: {
  8366. extraCssClasses: "dx-overflow-animation",
  8367. delay: this.option("defaultAnimationDelay"),
  8368. duration: this.option("defaultAnimationDuration")
  8369. }});
  8370. this.registerPreset("ios7-toolbar", {animation: {
  8371. extraCssClasses: "dx-ios7-toolbar-animation",
  8372. delay: this.option("defaultAnimationDelay"),
  8373. duration: this.option("defaultAnimationDuration")
  8374. }});
  8375. this.registerPreset("stagger-fade", {animation: {
  8376. extraCssClasses: "dx-fade-animation",
  8377. staggerDelay: this.option("defaultStaggerAnimationDelay"),
  8378. duration: this.option("defaultStaggerAnimationDuration"),
  8379. delay: this.option("defaultStaggerAnimationStartDelay")
  8380. }});
  8381. this.registerPreset("stagger-slide", {animation: {
  8382. extraCssClasses: "dx-slide-animation",
  8383. staggerDelay: this.option("defaultStaggerAnimationDelay"),
  8384. duration: this.option("defaultStaggerAnimationDuration"),
  8385. delay: this.option("defaultStaggerAnimationStartDelay")
  8386. }});
  8387. this.registerPreset("stagger-fade-slide", {animation: {
  8388. extraCssClasses: "dx-fade-slide-animation",
  8389. staggerDelay: this.option("defaultStaggerAnimationDelay"),
  8390. duration: this.option("defaultStaggerAnimationDuration"),
  8391. delay: this.option("defaultStaggerAnimationStartDelay")
  8392. }});
  8393. this.registerPreset("stagger-drop", {animation: {
  8394. extraCssClasses: "dx-drop-animation",
  8395. staggerDelay: this.option("defaultStaggerAnimationDelay"),
  8396. duration: this.option("defaultStaggerAnimationDuration"),
  8397. delay: this.option("defaultStaggerAnimationStartDelay")
  8398. }});
  8399. this.registerPreset("stagger-fade-drop", {animation: {
  8400. extraCssClasses: "dx-fade-drop-animation",
  8401. staggerDelay: this.option("defaultStaggerAnimationDelay"),
  8402. duration: this.option("defaultStaggerAnimationDuration"),
  8403. delay: this.option("defaultStaggerAnimationStartDelay")
  8404. }});
  8405. this.registerPreset("stagger-3d-drop", {animation: {
  8406. extraCssClasses: "dx-3d-drop-animation",
  8407. staggerDelay: this.option("defaultStaggerAnimationDelay"),
  8408. duration: this.option("defaultStaggerAnimationDuration"),
  8409. delay: this.option("defaultStaggerAnimationStartDelay")
  8410. }});
  8411. this.registerPreset("stagger-fade-zoom", {animation: {
  8412. extraCssClasses: "dx-fade-zoom-animation",
  8413. staggerDelay: this.option("defaultStaggerAnimationDelay"),
  8414. duration: this.option("defaultStaggerAnimationDuration"),
  8415. delay: this.option("defaultStaggerAnimationStartDelay")
  8416. }})
  8417. }
  8418. });
  8419. DX.TransitionExecutor = TransitionExecutor;
  8420. DX.AnimationPresetCollection = AnimationPresetCollection;
  8421. DX.animationPresets = new AnimationPresetCollection
  8422. })(jQuery, DevExpress);
  8423. /*! Module core, file DOMComponent.js */
  8424. (function($, DX, undefined) {
  8425. var windowResizeCallbacks = DX.utils.windowResizeCallbacks;
  8426. var RTL_DIRECTION_CLASS = "dx-rtl",
  8427. COMPONENT_NAMES_DATA_KEY = "dxComponents",
  8428. VISIBILITY_CHANGE_CLASS = "dx-visibility-change-handler",
  8429. VISIBILITY_CHANGE_EVENTNAMESPACE = "dxVisibilityChange";
  8430. var DOMComponent = DX.Component.inherit({
  8431. NAME: "DOMComponent",
  8432. _setDefaultOptions: function() {
  8433. this.callBase();
  8434. this.option({
  8435. width: undefined,
  8436. height: undefined,
  8437. rtlEnabled: DX.rtlEnabled
  8438. })
  8439. },
  8440. ctor: function(element, options) {
  8441. this._$element = $(element);
  8442. this.element().data(this.NAME, this);
  8443. this._attachInstanceToElement(this._$element);
  8444. this.callBase(options)
  8445. },
  8446. _attachInstanceToElement: $.noop,
  8447. _visibilityChanged: DX.abstract,
  8448. _dimensionChanged: DX.abstract,
  8449. _init: function() {
  8450. this.callBase();
  8451. this._attachWindowResizeCallback()
  8452. },
  8453. _attachWindowResizeCallback: function() {
  8454. if (this._isDimensionChangeSupported()) {
  8455. var windowResizeCallBack = this._windowResizeCallBack = $.proxy(this._dimensionChanged, this);
  8456. windowResizeCallbacks.add(windowResizeCallBack)
  8457. }
  8458. },
  8459. _isDimensionChangeSupported: function() {
  8460. return this._dimensionChanged !== DX.abstract
  8461. },
  8462. _render: function() {
  8463. this._toggleRTLDirection(this.option("rtlEnabled"));
  8464. this._renderVisibilityChange();
  8465. this._renderDimensions()
  8466. },
  8467. _renderVisibilityChange: function() {
  8468. if (!this._isVisibilityChangeSupported())
  8469. return;
  8470. this.element().addClass(VISIBILITY_CHANGE_CLASS);
  8471. this._attachVisiblityChangeHandlers()
  8472. },
  8473. _renderDimensions: function() {
  8474. var width = this.option("width"),
  8475. height = this.option("height"),
  8476. $element = this.element();
  8477. $element.outerWidth(width);
  8478. $element.outerHeight(height)
  8479. },
  8480. _attachVisiblityChangeHandlers: function() {
  8481. var that = this;
  8482. that.element().off("." + VISIBILITY_CHANGE_EVENTNAMESPACE).on("dxhiding." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
  8483. that._visibilityChanged(false)
  8484. }).on("dxshown." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
  8485. that._visibilityChanged(true)
  8486. })
  8487. },
  8488. _isVisibilityChangeSupported: function() {
  8489. return this._visibilityChanged !== DX.abstract
  8490. },
  8491. _clean: $.noop,
  8492. _modelByElement: $.noop,
  8493. _invalidate: function() {
  8494. if (!this._updateLockCount)
  8495. throw DX.Error("E0007");
  8496. this._requireRefresh = true
  8497. },
  8498. _refresh: function() {
  8499. this._clean();
  8500. this._render()
  8501. },
  8502. _dispose: function() {
  8503. this.callBase();
  8504. this._clean();
  8505. this._detachWindowResizeCallback()
  8506. },
  8507. _detachWindowResizeCallback: function() {
  8508. if (this._isDimensionChangeSupported())
  8509. windowResizeCallbacks.remove(this._windowResizeCallBack)
  8510. },
  8511. _toggleRTLDirection: function(rtl) {
  8512. this.element().toggleClass(RTL_DIRECTION_CLASS, rtl)
  8513. },
  8514. _createComponent: function(element, name, config) {
  8515. config = config || {};
  8516. this._extendConfig(config, {rtlEnabled: this.option("rtlEnabled")});
  8517. var $element = $(element)[name](config);
  8518. return $element[name]("instance")
  8519. },
  8520. _extendConfig: function(config, extendConfig) {
  8521. $.each(extendConfig, function(key, value) {
  8522. config[key] = config.hasOwnProperty(key) ? config[key] : value
  8523. })
  8524. },
  8525. _defaultActionConfig: function() {
  8526. return $.extend(this.callBase(), {context: this._modelByElement(this.element())})
  8527. },
  8528. _defaultActionArgs: function() {
  8529. var element = this.element(),
  8530. model = this._modelByElement(this.element());
  8531. return $.extend(this.callBase(), {
  8532. element: element,
  8533. model: model
  8534. })
  8535. },
  8536. _optionChanged: function(args) {
  8537. switch (args.name) {
  8538. case"width":
  8539. case"height":
  8540. this._renderDimensions();
  8541. break;
  8542. case"rtlEnabled":
  8543. this._invalidate();
  8544. break;
  8545. default:
  8546. this.callBase(args);
  8547. break
  8548. }
  8549. },
  8550. endUpdate: function() {
  8551. var requireRender = !this._initializing && !this._initialized;
  8552. this.callBase.apply(this, arguments);
  8553. if (!this._updateLockCount)
  8554. if (requireRender)
  8555. this._render();
  8556. else if (this._requireRefresh) {
  8557. this._requireRefresh = false;
  8558. this._refresh()
  8559. }
  8560. },
  8561. element: function() {
  8562. return this._$element
  8563. }
  8564. });
  8565. var registerComponent = function(name, namespace, componentClass) {
  8566. if (!componentClass) {
  8567. componentClass = namespace;
  8568. namespace = DX
  8569. }
  8570. componentClass.redefine({_attachInstanceToElement: function($element) {
  8571. $element.data(name, this);
  8572. if (!$element.data(COMPONENT_NAMES_DATA_KEY))
  8573. $element.data(COMPONENT_NAMES_DATA_KEY, []);
  8574. $element.data(COMPONENT_NAMES_DATA_KEY).push(name)
  8575. }});
  8576. namespace[name] = componentClass;
  8577. componentClass.prototype.NAME = name;
  8578. componentClass.defaultOptions = function(rule) {
  8579. componentClass.prototype._customRules = componentClass.prototype._customRules || [];
  8580. componentClass.prototype._customRules.push(rule)
  8581. };
  8582. $.fn[name] = function(options) {
  8583. var isMemberInvoke = typeof options === "string",
  8584. result;
  8585. if (isMemberInvoke) {
  8586. var memberName = options,
  8587. memberArgs = $.makeArray(arguments).slice(1);
  8588. this.each(function() {
  8589. var instance = $(this).data(name);
  8590. if (!instance)
  8591. throw DX.Error("E0009", name);
  8592. var member = instance[memberName],
  8593. memberValue = member.apply(instance, memberArgs);
  8594. if (result === undefined)
  8595. result = memberValue
  8596. })
  8597. }
  8598. else {
  8599. this.each(function() {
  8600. var instance = $(this).data(name);
  8601. if (instance)
  8602. instance.option(options);
  8603. else
  8604. new componentClass(this, options)
  8605. });
  8606. result = this
  8607. }
  8608. return result
  8609. }
  8610. };
  8611. var getComponents = function(element) {
  8612. element = $(element);
  8613. var names = element.data(COMPONENT_NAMES_DATA_KEY);
  8614. if (!names)
  8615. return [];
  8616. return $.map(names, function(name) {
  8617. return element.data(name)
  8618. })
  8619. };
  8620. var disposeComponents = function() {
  8621. $.each(getComponents(this), function() {
  8622. this._dispose()
  8623. })
  8624. };
  8625. var originalCleanData = $.cleanData;
  8626. $.cleanData = function(element) {
  8627. $.each(element, disposeComponents);
  8628. return originalCleanData.apply(this, arguments)
  8629. };
  8630. registerComponent("DOMComponent", DOMComponent);
  8631. DX.registerComponent = registerComponent
  8632. })(jQuery, DevExpress);
  8633. /*! Module core, file ui.js */
  8634. (function($, DX, undefined) {
  8635. DX.ui = {};
  8636. var createValidatorByTargetElement = function(condition) {
  8637. return function(e) {
  8638. if (!e.args.length)
  8639. return;
  8640. var args = e.args[0],
  8641. element = args[e.validatingTargetName] || args.element;
  8642. if (element && condition(element))
  8643. e.cancel = true
  8644. }
  8645. };
  8646. DX.registerActionExecutor({
  8647. designMode: {validate: function(e) {
  8648. if (DX.designMode)
  8649. e.cancel = true
  8650. }},
  8651. disabled: {validate: createValidatorByTargetElement(function($target) {
  8652. return $target.is(".dx-state-disabled, .dx-state-disabled *")
  8653. })},
  8654. readOnly: {validate: createValidatorByTargetElement(function($target) {
  8655. return $target.is(".dx-state-readonly, .dx-state-readonly *")
  8656. })}
  8657. })
  8658. })(jQuery, DevExpress);
  8659. /*! Module core, file ui.templates.js */
  8660. (function($, DX, undefined) {
  8661. var ui = DX.ui,
  8662. triggerShownEvent = DX.utils.triggerShownEvent;
  8663. var getWidgetName = function(widgetConstructor) {
  8664. return widgetConstructor.prototype.NAME
  8665. };
  8666. var TemplateProviderBase = DX.Class.inherit({
  8667. ctor: function() {
  8668. this.widgetTemplatesCache = {}
  8669. },
  8670. createTemplate: DX.abstract,
  8671. getTemplates: function(widget) {
  8672. return this._getWidgetTemplates(widget.constructor)
  8673. },
  8674. _getWidgetTemplates: function(widgetConstructor) {
  8675. if (!getWidgetName(widgetConstructor))
  8676. return {};
  8677. return this._getCachedWidgetTemplates(widgetConstructor)
  8678. },
  8679. _getCachedWidgetTemplates: function(widgetConstructor) {
  8680. var widgetName = getWidgetName(widgetConstructor),
  8681. templatesCache = this.widgetTemplatesCache;
  8682. if (!templatesCache[widgetName])
  8683. templatesCache[widgetName] = $.extend({}, this._getWidgetTemplates(widgetConstructor.parent), this._templatesForWidget(widgetName));
  8684. return templatesCache[widgetName]
  8685. },
  8686. _templatesForWidget: DX.abstract
  8687. });
  8688. var TemplateBase = DX.Class.inherit({
  8689. ctor: function(element, owner) {
  8690. this._element = $(element);
  8691. this._owner = owner
  8692. },
  8693. owner: function() {
  8694. return this._owner
  8695. },
  8696. render: function(data, $container, index) {
  8697. if (data instanceof jQuery) {
  8698. $container = data;
  8699. data = undefined
  8700. }
  8701. if ($container)
  8702. data = this._prepareDataForContainer(data, $container);
  8703. var $result = this._renderCore(data, index, $container);
  8704. if (this._shouldAppend && $container) {
  8705. $container.append($result);
  8706. if ($.contains(document.body, $container.get(0)))
  8707. triggerShownEvent($result)
  8708. }
  8709. return $result
  8710. },
  8711. source: function() {
  8712. return this._element.clone()
  8713. },
  8714. _prepareDataForContainer: function(data) {
  8715. return data
  8716. },
  8717. _renderCore: DX.abstract,
  8718. _shouldAppend: true,
  8719. dispose: function() {
  8720. this._owner = null
  8721. }
  8722. });
  8723. $.extend(ui, {
  8724. TemplateProviderBase: TemplateProviderBase,
  8725. TemplateBase: TemplateBase
  8726. })
  8727. })(jQuery, DevExpress);
  8728. /*! Module core, file jquery.templates.js */
  8729. (function($, DX, undefined) {
  8730. var ui = DX.ui,
  8731. utils = DX.utils,
  8732. isString = DX.utils.isString,
  8733. currentTemplateEngine,
  8734. templateEngines = {};
  8735. var Template = ui.TemplateBase.inherit({
  8736. ctor: function(element, owner) {
  8737. this.callBase(element, owner);
  8738. this._compiledTemplate = currentTemplateEngine.compile(element)
  8739. },
  8740. _renderCore: function(data) {
  8741. return $("<div>").append(currentTemplateEngine.render(this._compiledTemplate, data)).contents()
  8742. }
  8743. });
  8744. var setTemplateEngine = function(templateEngine) {
  8745. if (isString(templateEngine)) {
  8746. currentTemplateEngine = templateEngines[templateEngine];
  8747. if (!currentTemplateEngine)
  8748. throw DX.Error("E0020", templateEngine);
  8749. }
  8750. else
  8751. currentTemplateEngine = templateEngine
  8752. };
  8753. var registerTemplateEngine = function(name, templateEngine) {
  8754. templateEngines[name] = templateEngine
  8755. };
  8756. var outerHtml = function(element) {
  8757. element = $(element);
  8758. if (!element.length || element[0].nodeName.toLowerCase() !== "script")
  8759. element = $("<div>").append(element);
  8760. return element.html()
  8761. };
  8762. registerTemplateEngine("default", {
  8763. compile: function(element) {
  8764. return DX.utils.normalizeTemplateElement(element)
  8765. },
  8766. render: function(template, data) {
  8767. return template.clone()
  8768. }
  8769. });
  8770. registerTemplateEngine("jquery-tmpl", {
  8771. compile: function(element) {
  8772. return $("<div>").append(DX.utils.normalizeTemplateElement(element))
  8773. },
  8774. render: function(template, data) {
  8775. return template.tmpl(data)
  8776. }
  8777. });
  8778. registerTemplateEngine("jsrender", {
  8779. compile: function(element) {
  8780. return $.templates(outerHtml(element))
  8781. },
  8782. render: function(template, data) {
  8783. return template.render(data)
  8784. }
  8785. });
  8786. registerTemplateEngine("mustache", {
  8787. compile: function(element) {
  8788. return Mustache.compile(outerHtml(element))
  8789. },
  8790. render: function(template, data) {
  8791. return template(data)
  8792. }
  8793. });
  8794. registerTemplateEngine("hogan", {
  8795. compile: function(element) {
  8796. return Hogan.compile(outerHtml(element))
  8797. },
  8798. render: function(template, data) {
  8799. return template.render(data)
  8800. }
  8801. });
  8802. registerTemplateEngine("underscore", {
  8803. compile: function(element) {
  8804. return _.template(outerHtml(element))
  8805. },
  8806. render: function(template, data) {
  8807. return template(data)
  8808. }
  8809. });
  8810. registerTemplateEngine("handlebars", {
  8811. compile: function(element) {
  8812. return Handlebars.compile(outerHtml(element))
  8813. },
  8814. render: function(template, data) {
  8815. return template(data)
  8816. }
  8817. });
  8818. registerTemplateEngine("doT", {
  8819. compile: function(element) {
  8820. return doT.template(outerHtml(element))
  8821. },
  8822. render: function(template, data) {
  8823. return template(data)
  8824. }
  8825. });
  8826. setTemplateEngine("default");
  8827. var DefaultTemplate = ui.TemplateBase.inherit({
  8828. ctor: function(render, owner) {
  8829. this.callBase($("<div>"), owner);
  8830. this._render = render
  8831. },
  8832. _renderCore: function(data, index, container) {
  8833. return DX.utils.normalizeTemplateElement(this._render(data, index, container))
  8834. }
  8835. });
  8836. var TemplateProvider = new(ui.TemplateProviderBase.inherit({
  8837. createTemplate: function(element, owner) {
  8838. return new ui.Template(element, owner)
  8839. },
  8840. _templatesForWidget: function(widgetName) {
  8841. var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},
  8842. templates = {};
  8843. $.each(templateGenerators, function(name, generator) {
  8844. templates[name] = new ui.DefaultTemplate(function() {
  8845. var $markup = generator.apply(this, arguments);
  8846. if (name !== "itemFrame")
  8847. $markup = $markup.contents();
  8848. return $markup
  8849. }, TemplateProvider)
  8850. });
  8851. return templates
  8852. }
  8853. }));
  8854. var TEMPLATE_GENERATORS = {};
  8855. var emptyTemplate = function() {
  8856. return $()
  8857. };
  8858. var ITEM_CONTENT_PLACEHOLDER_CLASS = "dx-item-content-placeholder";
  8859. TEMPLATE_GENERATORS.CollectionWidget = {
  8860. item: function(itemData) {
  8861. var $itemContent = $("<div>");
  8862. if ($.isPlainObject(itemData)) {
  8863. if (itemData.text)
  8864. $itemContent.text(itemData.text);
  8865. if (itemData.html)
  8866. $itemContent.html(itemData.html)
  8867. }
  8868. else
  8869. $itemContent.html(String(itemData));
  8870. return $itemContent
  8871. },
  8872. itemFrame: function(itemData) {
  8873. var $itemFrame = $("<div>");
  8874. $itemFrame.toggleClass("dx-state-invisible", itemData.visible !== undefined && !itemData.visible);
  8875. $itemFrame.toggleClass("dx-state-disabled", !!itemData.disabled);
  8876. var $placeholder = $("<div>").addClass(ITEM_CONTENT_PLACEHOLDER_CLASS);
  8877. $itemFrame.append($placeholder);
  8878. return $itemFrame
  8879. }
  8880. };
  8881. var BUTTON_TEXT_CLASS = "dx-button-text";
  8882. TEMPLATE_GENERATORS.dxButton = {content: function(itemData) {
  8883. var $itemContent = $("<div>"),
  8884. $iconElement = utils.getImageContainer(itemData.icon),
  8885. $textContainer = itemData.text ? $("<span>").text(itemData.text).addClass(BUTTON_TEXT_CLASS) : undefined;
  8886. $itemContent.append($iconElement).append($textContainer);
  8887. return $itemContent
  8888. }};
  8889. var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",
  8890. LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",
  8891. BADGE_CLASS = "dx-badge",
  8892. LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",
  8893. LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";
  8894. TEMPLATE_GENERATORS.dxList = {
  8895. item: function(itemData) {
  8896. var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
  8897. if (itemData.key) {
  8898. var $key = $("<div>").text(itemData.key);
  8899. $key.appendTo($itemContent)
  8900. }
  8901. return $itemContent
  8902. },
  8903. itemFrame: function(itemData) {
  8904. var $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
  8905. if (itemData.badge) {
  8906. var $badgeContainer = $("<div>").addClass(LIST_ITEM_BADGE_CONTAINER_CLASS),
  8907. $badge = $("<div>").addClass(LIST_ITEM_BADGE_CLASS).addClass(BADGE_CLASS);
  8908. $badge.text(itemData.badge);
  8909. $badgeContainer.append($badge).appendTo($itemFrame)
  8910. }
  8911. if (itemData.showChevron) {
  8912. var $chevronContainer = $("<div>").addClass(LIST_ITEM_CHEVRON_CONTAINER_CLASS),
  8913. $chevron = $("<div>").addClass(LIST_ITEM_CHEVRON_CLASS);
  8914. $chevronContainer.append($chevron).appendTo($itemFrame)
  8915. }
  8916. return $itemFrame
  8917. },
  8918. group: function(groupData) {
  8919. var $groupContent = $("<div>");
  8920. if ($.isPlainObject(groupData)) {
  8921. if (groupData.key)
  8922. $groupContent.text(groupData.key)
  8923. }
  8924. else
  8925. $groupContent.html(String(groupData));
  8926. return $groupContent
  8927. }
  8928. };
  8929. TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};
  8930. TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};
  8931. TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};
  8932. TEMPLATE_GENERATORS.dxScheduler = {item: function(itemData) {
  8933. var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
  8934. var $details = $("<div>").addClass("dx-scheduler-appointment-content-details");
  8935. if (itemData.startDate)
  8936. $("<strong>").text(Globalize.format(DX.utils.makeDate(itemData.startDate), "t")).appendTo($details);
  8937. if (itemData.endDate)
  8938. $("<strong>").text(" - " + Globalize.format(DX.utils.makeDate(itemData.endDate), "t")).appendTo($details);
  8939. $details.appendTo($itemContent);
  8940. if (itemData.recurrenceRule)
  8941. $("<span>").addClass("dx-scheduler-appointment-recurrence-icon").appendTo($itemContent);
  8942. return $itemContent
  8943. }};
  8944. TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};
  8945. TEMPLATE_GENERATORS.dxSlideOutView = {
  8946. menu: emptyTemplate,
  8947. content: emptyTemplate
  8948. };
  8949. TEMPLATE_GENERATORS.dxSlideOut = {
  8950. menuItem: TEMPLATE_GENERATORS.dxList.item,
  8951. menuGroup: TEMPLATE_GENERATORS.dxList.group,
  8952. content: emptyTemplate
  8953. };
  8954. TEMPLATE_GENERATORS.dxAccordion = {
  8955. title: function(titleData) {
  8956. var $titleContent = $("<div>"),
  8957. icon = titleData.icon,
  8958. iconSrc = titleData.iconSrc,
  8959. $iconElement = utils.getImageContainer(icon || iconSrc);
  8960. if ($.isPlainObject(titleData)) {
  8961. if (titleData.title)
  8962. $titleContent.text(titleData.title)
  8963. }
  8964. else
  8965. $titleContent.html(String(titleData));
  8966. $iconElement && $iconElement.prependTo($titleContent);
  8967. return $titleContent
  8968. },
  8969. item: TEMPLATE_GENERATORS.CollectionWidget.item
  8970. };
  8971. TEMPLATE_GENERATORS.dxActionSheet = {item: function(itemData) {
  8972. return $("<div>").append($("<div>").dxButton($.extend({onClick: itemData.click}, itemData)))
  8973. }};
  8974. TEMPLATE_GENERATORS.dxGallery = {item: function(itemData) {
  8975. var $itemContent = $("<div>");
  8976. if (itemData.imageSrc)
  8977. $('<img>').attr('src', itemData.imageSrc).appendTo($itemContent);
  8978. else
  8979. $('<img>').attr('src', String(itemData)).appendTo($itemContent);
  8980. return $itemContent
  8981. }};
  8982. var DX_MENU_ITEM_CAPTION_CLASS = 'dx-menu-item-text',
  8983. DX_MENU_ITEM_POPOUT_CLASS = 'dx-menu-item-popout',
  8984. DX_MENU_ITEM_POPOUT_CONTAINER_CLASS = 'dx-menu-item-popout-container';
  8985. TEMPLATE_GENERATORS.dxMenuBase = {item: function(itemData) {
  8986. var $itemContent = $("<div>"),
  8987. icon = itemData.icon,
  8988. iconSrc = itemData.iconSrc,
  8989. $iconElement = utils.getImageContainer(icon || iconSrc);
  8990. $iconElement && $iconElement.appendTo($itemContent);
  8991. var $itemCaption;
  8992. if ($.isPlainObject(itemData) && itemData.text)
  8993. $itemCaption = $('<span>').addClass(DX_MENU_ITEM_CAPTION_CLASS).text(itemData.text);
  8994. else if (!$.isPlainObject(itemData))
  8995. $itemCaption = $('<span>').addClass(DX_MENU_ITEM_CAPTION_CLASS).html(String(itemData));
  8996. $itemContent.append($itemCaption);
  8997. var $popOutImage,
  8998. $popOutContainer;
  8999. if (itemData.items && itemData.items.length > 0) {
  9000. $popOutContainer = $('<span>').addClass(DX_MENU_ITEM_POPOUT_CONTAINER_CLASS).appendTo($itemContent);
  9001. $popOutImage = $('<div>').addClass(DX_MENU_ITEM_POPOUT_CLASS).appendTo($popOutContainer)
  9002. }
  9003. return $itemContent
  9004. }};
  9005. var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";
  9006. TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function(itemData) {
  9007. var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
  9008. if (itemData.title) {
  9009. var $itemHeader = $("<div>").addClass(PANORAMA_ITEM_TITLE_CLASS).text(itemData.title);
  9010. $itemContent.prepend($itemHeader)
  9011. }
  9012. return $itemContent
  9013. }};
  9014. TEMPLATE_GENERATORS.dxPivotTabs = {item: function(itemData) {
  9015. var $itemContent = $("<div>");
  9016. var $itemText;
  9017. if ($.isPlainObject(itemData))
  9018. $itemText = $("<span>").text(itemData.title);
  9019. else
  9020. $itemText = $("<span>").text(String(itemData));
  9021. $itemContent.html($itemText);
  9022. return $itemContent
  9023. }};
  9024. TEMPLATE_GENERATORS.dxPivot = {
  9025. title: TEMPLATE_GENERATORS.dxPivotTabs.item,
  9026. content: emptyTemplate
  9027. };
  9028. var TABS_ITEM_TEXT_CLASS = "dx-tab-text";
  9029. TEMPLATE_GENERATORS.dxTabs = {
  9030. item: function(itemData) {
  9031. var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
  9032. if (itemData.html)
  9033. return $itemContent;
  9034. var icon = itemData.icon,
  9035. iconSrc = itemData.iconSrc,
  9036. $iconElement = utils.getImageContainer(icon || iconSrc);
  9037. if (!itemData.html)
  9038. $itemContent.wrapInner($("<span>").addClass(TABS_ITEM_TEXT_CLASS));
  9039. $iconElement && $iconElement.prependTo($itemContent);
  9040. return $itemContent
  9041. },
  9042. itemFrame: function(itemData) {
  9043. var $badge = $(),
  9044. $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
  9045. if (itemData.badge)
  9046. $badge = $("<div>", {"class": "dx-tabs-item-badge dx-badge"}).text(itemData.badge);
  9047. $itemFrame.append($badge);
  9048. return $itemFrame
  9049. }
  9050. };
  9051. TEMPLATE_GENERATORS.dxTabPanel = {
  9052. item: TEMPLATE_GENERATORS.CollectionWidget.item,
  9053. title: function(itemData) {
  9054. var itemTitleData = itemData;
  9055. if ($.isPlainObject(itemData))
  9056. itemTitleData = $.extend({}, itemData, {text: itemData.title});
  9057. var $title = TEMPLATE_GENERATORS.dxTabs.item(itemTitleData);
  9058. return $title
  9059. }
  9060. };
  9061. var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";
  9062. TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function(itemData) {
  9063. var $itemFrame = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(itemData);
  9064. if (itemData.badge) {
  9065. var $badge = $("<div>").addClass(NAVBAR_ITEM_BADGE_CLASS).addClass(BADGE_CLASS);
  9066. $badge.text(itemData.badge);
  9067. $badge.appendTo($itemFrame)
  9068. }
  9069. return $itemFrame
  9070. }};
  9071. TEMPLATE_GENERATORS.dxToolbar = {
  9072. item: function(itemData) {
  9073. var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item(itemData);
  9074. var widget = itemData.widget;
  9075. if (widget) {
  9076. var widgetElement = $("<div>").appendTo($itemContent),
  9077. widgetName = DX.inflector.camelize("dx-" + widget),
  9078. options = itemData.options || {};
  9079. widgetElement[widgetName](options)
  9080. }
  9081. else if (itemData.text)
  9082. $itemContent.wrapInner("<div>");
  9083. return $itemContent
  9084. },
  9085. menuItem: TEMPLATE_GENERATORS.dxList.item,
  9086. actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item
  9087. };
  9088. TEMPLATE_GENERATORS.dxTreeView = {item: function(itemData) {
  9089. var $itemContent = $("<div>"),
  9090. icon = itemData.icon,
  9091. iconSrc = itemData.iconSrc,
  9092. $iconElement = utils.getImageContainer(icon || iconSrc);
  9093. if (itemData.html)
  9094. $itemContent.html(itemData.html);
  9095. else {
  9096. $iconElement && $iconElement.appendTo($itemContent);
  9097. $("<span>").text(itemData.text).appendTo($itemContent)
  9098. }
  9099. return $itemContent
  9100. }};
  9101. var popupTitleAndBottom = function(itemData) {
  9102. return $("<div>").append($("<div>").dxToolbar({items: itemData}))
  9103. };
  9104. TEMPLATE_GENERATORS.dxPopup = {
  9105. title: popupTitleAndBottom,
  9106. bottom: popupTitleAndBottom
  9107. };
  9108. TEMPLATE_GENERATORS.dxLookup = {
  9109. title: TEMPLATE_GENERATORS.dxPopup.title,
  9110. group: TEMPLATE_GENERATORS.dxList.group
  9111. };
  9112. TEMPLATE_GENERATORS.dxTagBox = {tag: function(itemData) {
  9113. return $("<div>").append($("<span>").text(itemData))
  9114. }};
  9115. TEMPLATE_GENERATORS.dxCalendar = {cell: function(itemData) {
  9116. return $("<div>").text(itemData.text || String(itemData))
  9117. }};
  9118. $.extend(ui, {
  9119. TemplateProvider: TemplateProvider,
  9120. Template: Template,
  9121. DefaultTemplate: DefaultTemplate,
  9122. setTemplateEngine: setTemplateEngine
  9123. })
  9124. })(jQuery, DevExpress);
  9125. /*! Module core, file ko.components.js */
  9126. (function($, DX, undefined) {
  9127. if (!DX.support.hasKo)
  9128. return;
  9129. var ko = window.ko,
  9130. ui = DX.ui,
  9131. LOCKS_DATA_KEY = "dxKoLocks",
  9132. CREATED_WITH_KO_DATA_KEY = "dxKoCreation";
  9133. var Locks = function() {
  9134. var info = {};
  9135. var currentCount = function(lockName) {
  9136. return info[lockName] || 0
  9137. };
  9138. return {
  9139. obtain: function(lockName) {
  9140. info[lockName] = currentCount(lockName) + 1
  9141. },
  9142. release: function(lockName) {
  9143. var count = currentCount(lockName);
  9144. if (count < 1)
  9145. throw DX.Error("E0014");
  9146. if (count === 1)
  9147. delete info[lockName];
  9148. else
  9149. info[lockName] = count - 1
  9150. },
  9151. locked: function(lockName) {
  9152. return currentCount(lockName) > 0
  9153. }
  9154. }
  9155. };
  9156. var editorsBingindHandlers = [];
  9157. var registerComponentKoBinding = function(componentName, componentClass) {
  9158. if (componentClass.subclassOf(ui.Editor))
  9159. editorsBingindHandlers.push(componentName);
  9160. ko.bindingHandlers[componentName] = {init: function(domNode, valueAccessor) {
  9161. var $element = $(domNode),
  9162. optionChangedCallbacks = $.Callbacks(),
  9163. ctorOptions = {
  9164. templateProvider: ui.KoTemplateProvider,
  9165. _optionChangedCallbacks: optionChangedCallbacks
  9166. },
  9167. optionNameToModelMap = {};
  9168. var applyModelValueToOption = function(optionName, modelValue) {
  9169. var component = $element.data(componentName),
  9170. locks = $element.data(LOCKS_DATA_KEY),
  9171. optionValue = ko.unwrap(modelValue);
  9172. if (ko.isWriteableObservable(modelValue))
  9173. optionNameToModelMap[optionName] = modelValue;
  9174. if (component) {
  9175. if (locks.locked(optionName))
  9176. return;
  9177. locks.obtain(optionName);
  9178. try {
  9179. component.option(optionName, optionValue)
  9180. }
  9181. finally {
  9182. locks.release(optionName)
  9183. }
  9184. }
  9185. else
  9186. ctorOptions[optionName] = optionValue
  9187. };
  9188. var handleOptionChanged = function(args) {
  9189. var optionName = args.fullName,
  9190. optionValue = args.value;
  9191. if (!(optionName in optionNameToModelMap))
  9192. return;
  9193. var $element = this._$element,
  9194. locks = $element.data(LOCKS_DATA_KEY);
  9195. if (locks.locked(optionName))
  9196. return;
  9197. locks.obtain(optionName);
  9198. try {
  9199. optionNameToModelMap[optionName](optionValue)
  9200. }
  9201. finally {
  9202. locks.release(optionName)
  9203. }
  9204. };
  9205. var createComponent = function() {
  9206. optionChangedCallbacks.add(handleOptionChanged);
  9207. $element.data(CREATED_WITH_KO_DATA_KEY, true).data(LOCKS_DATA_KEY, new Locks)[componentName](ctorOptions);
  9208. ctorOptions = null
  9209. };
  9210. var unwrapModelValue = function(option, model) {
  9211. var modelUnwrapped;
  9212. ko.computed(function() {
  9213. applyModelValueToOption(option, model);
  9214. modelUnwrapped = ko.unwrap(model)
  9215. }, null, {disposeWhenNodeIsRemoved: domNode});
  9216. if ($.isPlainObject(modelUnwrapped))
  9217. $.each(modelUnwrapped, function(optionName, modelValue) {
  9218. unwrapModelValue(option + "." + optionName, modelValue)
  9219. })
  9220. };
  9221. ko.computed(function() {
  9222. var component = $element.data(componentName);
  9223. if (component)
  9224. component.beginUpdate();
  9225. $.each(ko.unwrap(valueAccessor()), function(optionName, modelValue) {
  9226. unwrapModelValue(optionName, modelValue)
  9227. });
  9228. if (component)
  9229. component.endUpdate();
  9230. else
  9231. createComponent()
  9232. }, null, {disposeWhenNodeIsRemoved: domNode});
  9233. return {controlsDescendantBindings: componentClass.subclassOf(ui.Widget)}
  9234. }};
  9235. if (componentName === "dxValidator")
  9236. ko.bindingHandlers["dxValidator"].after = editorsBingindHandlers
  9237. };
  9238. DX.DOMComponent.redefine({_modelByElement: function(element) {
  9239. if (element.length)
  9240. return ko.dataFor(element.get(0))
  9241. }});
  9242. var originalRegisterComponent = DX.registerComponent;
  9243. var registerKoComponent = function(componentName, _, componentClass) {
  9244. componentClass = componentClass || _;
  9245. originalRegisterComponent.apply(this, arguments);
  9246. registerComponentKoBinding(componentName, componentClass)
  9247. };
  9248. DX.registerComponent = registerKoComponent;
  9249. var cleanKoData = function(element, andSelf) {
  9250. var cleanNode = function() {
  9251. ko.cleanNode(this)
  9252. };
  9253. if (andSelf)
  9254. element.each(cleanNode);
  9255. else
  9256. element.find("*").each(cleanNode)
  9257. };
  9258. var originalEmpty = $.fn.empty;
  9259. $.fn.empty = function() {
  9260. cleanKoData(this, false);
  9261. return originalEmpty.apply(this, arguments)
  9262. };
  9263. var originalRemove = $.fn.remove;
  9264. $.fn.remove = function(selector, keepData) {
  9265. if (!keepData) {
  9266. var subject = this;
  9267. if (selector)
  9268. subject = subject.filter(selector);
  9269. cleanKoData(subject, true)
  9270. }
  9271. return originalRemove.call(this, selector, keepData)
  9272. };
  9273. var originalHtml = $.fn.html;
  9274. $.fn.html = function(value) {
  9275. if (typeof value === "string")
  9276. cleanKoData(this, false);
  9277. return originalHtml.apply(this, arguments)
  9278. };
  9279. ko.bindingHandlers.dxAction = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
  9280. var $element = $(element);
  9281. var unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
  9282. actionSource = unwrappedValue,
  9283. actionOptions = {context: element};
  9284. if (unwrappedValue.execute) {
  9285. actionSource = unwrappedValue.execute;
  9286. $.extend(actionOptions, unwrappedValue)
  9287. }
  9288. var action = new DX.Action(actionSource, actionOptions);
  9289. $element.off(".dxActionBinding").on("dxclick.dxActionBinding", function(e) {
  9290. action.execute({
  9291. element: $element,
  9292. model: viewModel,
  9293. evaluate: function(expression) {
  9294. var context = viewModel;
  9295. if (expression.length > 0 && expression[0] === "$")
  9296. context = ko.contextFor(element);
  9297. var getter = DX.data.utils.compileGetter(expression);
  9298. return getter(context)
  9299. },
  9300. jQueryEvent: e
  9301. });
  9302. if (!actionOptions.bubbling)
  9303. e.stopPropagation()
  9304. })
  9305. }};
  9306. ko.bindingHandlers.dxControlsDescendantBindings = {init: function(_, valueAccessor) {
  9307. return {controlsDescendantBindings: ko.unwrap(valueAccessor())}
  9308. }};
  9309. var render = function($element, options, viewModel, bindingContext) {
  9310. var result = $.Deferred();
  9311. $element.removeClass("dx-pending-rendering-manual");
  9312. $element.addClass("dx-pending-rendering-active");
  9313. if (options.showLoadIndicator && options.showLoadIndicatorImmediately !== true)
  9314. showLoadIndicator($element);
  9315. DX.utils.executeAsync(function() {
  9316. renderImpl($element, options, viewModel, bindingContext).done(function() {
  9317. var shownArgs = {element: $element};
  9318. if (options.onShown)
  9319. options.onShown.apply(viewModel, [shownArgs]);
  9320. result.resolve(shownArgs)
  9321. }).fail(function() {
  9322. result.rejectWith(result, arguments)
  9323. })
  9324. });
  9325. return result.promise()
  9326. };
  9327. var showLoadIndicator = function($container) {
  9328. var $indicator = $('<div/>').dxLoadIndicator({visible: true}).addClass("dx-defered-rendering-load-indicator");
  9329. $container.append($indicator)
  9330. };
  9331. var isElementInViewport = function(element) {
  9332. var rect = element.getBoundingClientRect();
  9333. return rect.bottom >= 0 && rect.right >= 0 && rect.top <= (window.innerHeight || document.documentElement.clientHeight) && rect.left <= (window.innerWidth || document.documentElement.clientWidth)
  9334. };
  9335. var renderImpl = function($element, options, viewModel, bindingContext) {
  9336. var animatePromise,
  9337. childBindingContext = bindingContext.createChildContext(viewModel),
  9338. renderedArgs = {element: $element};
  9339. $element.find(".dx-defered-rendering-load-indicator").remove();
  9340. ko.applyBindingsToDescendants(childBindingContext, $element[0]);
  9341. options._renderedDeferred.resolve(renderedArgs);
  9342. if (options.onRendered)
  9343. options.onRendered.apply(viewModel, [renderedArgs]);
  9344. $element.children().removeClass("dx-invisible-while-pending-rendering");
  9345. DX.utils.triggerShownEvent($element.children());
  9346. $element.removeClass("dx-pending-rendering");
  9347. $element.removeClass("dx-pending-rendering-active");
  9348. if (options.animation) {
  9349. var transitionExecutor = new DX.TransitionExecutor;
  9350. if (options.staggerItemSelector) {
  9351. $element.find(options.staggerItemSelector).each(function() {
  9352. if (isElementInViewport(this))
  9353. transitionExecutor.enter($(this), options.animation)
  9354. });
  9355. animatePromise = $.when(animatePromise, transitionExecutor.start())
  9356. }
  9357. else {
  9358. transitionExecutor.enter($element, options.animation || "content-rendered");
  9359. animatePromise = transitionExecutor.start()
  9360. }
  9361. }
  9362. else
  9363. animatePromise = $.Deferred().resolve().promise();
  9364. return animatePromise
  9365. };
  9366. var initElement = function($element, options) {
  9367. $element.addClass("dx-defer-rendering dx-pending-rendering dx-loadindicator-container");
  9368. $element.data("dx-rendered-promise", options._renderedDeferred.promise());
  9369. if (options.hiddenUntilRendered)
  9370. $element.children().addClass("dx-invisible-while-pending-rendering");
  9371. if (options.showLoadIndicator && options.showLoadIndicatorImmediately)
  9372. showLoadIndicator($element)
  9373. };
  9374. var initRender = function($element, options, viewModel, bindingContext) {
  9375. var doRender = function() {
  9376. return render($element, options, viewModel, bindingContext)
  9377. };
  9378. if (options.renderWhen)
  9379. options.renderWhen.done(doRender);
  9380. else {
  9381. $element.data("dx-render-delegate", doRender);
  9382. $element.addClass("dx-pending-rendering-manual")
  9383. }
  9384. };
  9385. ko.bindingHandlers.dxDeferRendering = {init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
  9386. var $element = $(element),
  9387. passedOptions = ko.unwrap(valueAccessor()),
  9388. showLoadIndicatorImmediately = ko.unwrap(passedOptions.showLoadIndicatorImmediately),
  9389. hiddenUntilRendered = ko.unwrap(passedOptions.hiddenUntilRendered),
  9390. options = {
  9391. showLoadIndicator: ko.unwrap(passedOptions.showLoadIndicator) || false,
  9392. showLoadIndicatorImmediately: showLoadIndicatorImmediately !== undefined ? showLoadIndicatorImmediately : true,
  9393. hiddenUntilRendered: hiddenUntilRendered !== undefined ? hiddenUntilRendered : true,
  9394. renderWhen: ko.unwrap(passedOptions.renderWhen),
  9395. animation: ko.unwrap(passedOptions.animation),
  9396. staggerItemSelector: ko.unwrap(passedOptions.staggerItemSelector),
  9397. onRendered: ko.unwrap(passedOptions.onRendered),
  9398. onShown: ko.unwrap(passedOptions.onShown),
  9399. _renderedDeferred: $.Deferred()
  9400. };
  9401. initElement($element, options);
  9402. initRender($element, options, viewModel, bindingContext);
  9403. return {controlsDescendantBindings: true}
  9404. }};
  9405. ko.bindingHandlers.dxIcon = {
  9406. init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
  9407. var options = ko.utils.unwrapObservable(valueAccessor()) || {},
  9408. iconElement = DevExpress.utils.getImageContainer(options);
  9409. ko.virtualElements.emptyNode(element);
  9410. if (iconElement)
  9411. ko.virtualElements.prepend(element, iconElement.get(0))
  9412. },
  9413. update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
  9414. var options = ko.utils.unwrapObservable(valueAccessor()) || {},
  9415. iconElement = DevExpress.utils.getImageContainer(options);
  9416. ko.virtualElements.emptyNode(element);
  9417. if (iconElement)
  9418. ko.virtualElements.prepend(element, iconElement.get(0))
  9419. }
  9420. };
  9421. ko.virtualElements.allowedBindings.dxIcon = true
  9422. })(jQuery, DevExpress);
  9423. /*! Module core, file ng.components.js */
  9424. (function($, DX, undefined) {
  9425. if (!DX.support.hasNg)
  9426. return;
  9427. var ui = DX.ui,
  9428. compileSetter = DX.data.utils.compileSetter,
  9429. compileGetter = DX.data.utils.compileGetter;
  9430. var ITEM_ALIAS_ATTRIBUTE_NAME = "dxItemAlias",
  9431. DEFAULT_MODEL_ALIAS = "scopeValue";
  9432. var SKIP_APPLY_ACTION_CATEGORIES = ["rendering"];
  9433. var phoneJsModule = DX.ng.module;
  9434. var safeApply = function(func, scope) {
  9435. if (scope.$root.$$phase)
  9436. func(scope);
  9437. else
  9438. scope.$apply(function() {
  9439. func(scope)
  9440. })
  9441. };
  9442. var ComponentBuilder = DX.Class.inherit({
  9443. ctor: function(options) {
  9444. this._$element = options.$element;
  9445. this._$templates = options.$templates;
  9446. this._componentClass = options.componentClass;
  9447. this._scope = options.scope;
  9448. this._parse = options.parse;
  9449. this._compile = options.compile;
  9450. this._ngOptions = this._normalizeOptions(options.ngOptions);
  9451. this._itemAlias = options.itemAlias;
  9452. this._componentDisposing = $.Callbacks();
  9453. if (options.ngOptions.data)
  9454. this._initDataScope(options.ngOptions.data)
  9455. },
  9456. _normalizeOptions: function(options) {
  9457. var result = $.extend({}, options);
  9458. if (options.bindingOptions)
  9459. $.each(options.bindingOptions, function(key, value) {
  9460. if ($.type(value) === 'string')
  9461. result.bindingOptions[key] = {dataPath: value}
  9462. });
  9463. return result
  9464. },
  9465. initComponentWithBindings: function() {
  9466. this._initComponentBindings();
  9467. this._initComponent(this._scope);
  9468. this._shownEventTimer = setTimeout($.proxy(function() {
  9469. DX.utils.triggerShownEvent(this._$element)
  9470. }, this))
  9471. },
  9472. _initDataScope: function(data) {
  9473. if (typeof data === "string") {
  9474. var dataStr = data,
  9475. rootScope = this._scope;
  9476. data = rootScope.$eval(data);
  9477. this._scope = rootScope.$new();
  9478. this._synchronizeDataScopes(rootScope, this._scope, data, dataStr)
  9479. }
  9480. $.extend(this._scope, data)
  9481. },
  9482. _synchronizeDataScopes: function(parentScope, childScope, data, parentPrefix) {
  9483. var that = this;
  9484. $.each(data, function(fieldPath) {
  9485. that._synchronizeScopeField({
  9486. parentScope: parentScope,
  9487. childScope: childScope,
  9488. fieldPath: fieldPath,
  9489. parentPrefix: parentPrefix
  9490. })
  9491. })
  9492. },
  9493. _initComponent: function(scope) {
  9494. this._component = new this._componentClass(this._$element, this._evalOptions(scope))
  9495. },
  9496. _initComponentBindings: function() {
  9497. var that = this,
  9498. optionDependencies = {};
  9499. that._disposingCallbacks = $.Callbacks();
  9500. if (that._ngOptions.bindingOptions)
  9501. $.each(that._ngOptions.bindingOptions, function(optionPath, value) {
  9502. var separatorIndex = optionPath.search(/\[|\./),
  9503. optionForSubscribe = separatorIndex > -1 ? optionPath.substring(0, separatorIndex) : optionPath,
  9504. prevWatchMethod,
  9505. clearWatcher,
  9506. valuePath = value.dataPath,
  9507. deepWatch = true,
  9508. forcePlainWatchMethod = false;
  9509. if (value.deep !== undefined)
  9510. forcePlainWatchMethod = deepWatch = !!value.deep;
  9511. if (!optionDependencies[optionForSubscribe])
  9512. optionDependencies[optionForSubscribe] = {};
  9513. optionDependencies[optionForSubscribe][optionPath] = valuePath;
  9514. var watchCallback = function(newValue, oldValue) {
  9515. if (newValue !== oldValue) {
  9516. that._component.option(optionPath, newValue);
  9517. updateWatcher()
  9518. }
  9519. };
  9520. var updateWatcher = function() {
  9521. var watchMethod = $.isArray(that._scope.$eval(valuePath)) && !forcePlainWatchMethod ? "$watchCollection" : "$watch";
  9522. if (prevWatchMethod !== watchMethod) {
  9523. if (clearWatcher)
  9524. clearWatcher();
  9525. clearWatcher = that._scope[watchMethod](valuePath, watchCallback, deepWatch);
  9526. prevWatchMethod = watchMethod
  9527. }
  9528. };
  9529. updateWatcher();
  9530. that._disposingCallbacks.add(function() {
  9531. clearWatcher();
  9532. that._componentDisposing.fire()
  9533. })
  9534. });
  9535. that._optionChangedCallbacks = $.Callbacks().add(function(args) {
  9536. var optionName = args.name,
  9537. optionValue = args.value;
  9538. if (that._scope.$root.$$phase === "$digest" || !optionDependencies || !optionDependencies[optionName])
  9539. return;
  9540. safeApply(function(scope) {
  9541. $.each(optionDependencies[optionName], function(optionPath, valuePath) {
  9542. var getter = compileGetter(optionPath);
  9543. var tmpData = {};
  9544. tmpData[optionName] = optionValue;
  9545. that._parse(valuePath).assign(that._scope, getter(tmpData))
  9546. })
  9547. }, that._scope)
  9548. });
  9549. that._disposingCallbacks.add(function() {
  9550. clearTimeout(that._shownEventTimer)
  9551. })
  9552. },
  9553. _compilerByTemplate: function(template) {
  9554. var that = this,
  9555. scopeItemsPath = this._getScopeItemsPath();
  9556. return function(data, index) {
  9557. var $resultMarkup = $(template).clone(),
  9558. templateScope;
  9559. if (data !== undefined) {
  9560. var dataIsScope = data.$id;
  9561. templateScope = dataIsScope ? data : that._createScopeWithData(data);
  9562. $resultMarkup.on("$destroy", function() {
  9563. var destroyAlreadyCalled = !templateScope.$parent;
  9564. if (destroyAlreadyCalled)
  9565. return;
  9566. templateScope.$destroy()
  9567. })
  9568. }
  9569. else
  9570. templateScope = that._scope;
  9571. if (scopeItemsPath)
  9572. that._synchronizeScopes(templateScope, scopeItemsPath, index);
  9573. safeApply(that._compile($resultMarkup), templateScope);
  9574. return $resultMarkup
  9575. }
  9576. },
  9577. _getScopeItemsPath: function() {
  9578. if (this._componentClass.subclassOf(ui.CollectionWidget) && this._ngOptions.bindingOptions && this._ngOptions.bindingOptions.items)
  9579. return this._ngOptions.bindingOptions.items.dataPath
  9580. },
  9581. _createScopeWithData: function(data) {
  9582. var newScope = this._scope.$new(true);
  9583. data = this._enshureDataIsPlainObject(data);
  9584. $.extend(newScope, data);
  9585. return newScope
  9586. },
  9587. _synchronizeScopes: function(itemScope, parentPrefix, itemIndex) {
  9588. var that = this,
  9589. item = compileGetter(parentPrefix + "[" + itemIndex + "]")(this._scope);
  9590. item = that._enshureDataIsPlainObject(item);
  9591. $.each(item, function(itemPath) {
  9592. that._synchronizeScopeField({
  9593. parentScope: that._scope,
  9594. childScope: itemScope,
  9595. fieldPath: itemPath,
  9596. parentPrefix: parentPrefix,
  9597. itemIndex: itemIndex
  9598. })
  9599. })
  9600. },
  9601. _synchronizeScopeField: function(args) {
  9602. var parentScope = args.parentScope,
  9603. childScope = args.childScope,
  9604. fieldPath = args.fieldPath,
  9605. parentPrefix = args.parentPrefix,
  9606. itemIndex = args.itemIndex;
  9607. var innerPathSuffix = fieldPath === (this._itemAlias || DEFAULT_MODEL_ALIAS) ? "" : "." + fieldPath,
  9608. collectionField = itemIndex !== undefined,
  9609. optionOuterBag = [parentPrefix],
  9610. optionOuterPath;
  9611. if (collectionField)
  9612. optionOuterBag.push("[", itemIndex, "]");
  9613. optionOuterBag.push(innerPathSuffix);
  9614. optionOuterPath = optionOuterBag.join("");
  9615. var clearParentWatcher = parentScope.$watch(optionOuterPath, function(newValue, oldValue) {
  9616. if (newValue !== oldValue)
  9617. compileSetter(fieldPath)(childScope, newValue)
  9618. });
  9619. var clearItemWatcher = childScope.$watch(fieldPath, function(newValue, oldValue) {
  9620. if (newValue !== oldValue) {
  9621. if (collectionField && !compileGetter(parentPrefix)(parentScope)[itemIndex]) {
  9622. clearItemWatcher();
  9623. return
  9624. }
  9625. compileSetter(optionOuterPath)(parentScope, newValue)
  9626. }
  9627. });
  9628. this._componentDisposing.add([clearParentWatcher, clearItemWatcher])
  9629. },
  9630. _evalOptions: function(scope) {
  9631. var result = $.extend({}, this._ngOptions);
  9632. delete result.data;
  9633. delete result.bindingOptions;
  9634. if (this._ngOptions.bindingOptions)
  9635. $.each(this._ngOptions.bindingOptions, function(key, value) {
  9636. result[key] = scope.$eval(value.dataPath)
  9637. });
  9638. result._optionChangedCallbacks = this._optionChangedCallbacks;
  9639. result._disposingCallbacks = this._disposingCallbacks;
  9640. result.templateProvider = ui.NgTemplateProvider;
  9641. result.templateCompiler = $.proxy(function($template) {
  9642. return this._compilerByTemplate($template)
  9643. }, this);
  9644. return result
  9645. },
  9646. _enshureDataIsPlainObject: function(object) {
  9647. var result;
  9648. if ($.isPlainObject(object))
  9649. result = object;
  9650. else {
  9651. result = {};
  9652. result[DEFAULT_MODEL_ALIAS] = object
  9653. }
  9654. if (this._itemAlias)
  9655. result[this._itemAlias] = object;
  9656. return result
  9657. }
  9658. });
  9659. ComponentBuilder = ComponentBuilder.inherit({
  9660. ctor: function(options) {
  9661. this.callBase.apply(this, arguments);
  9662. this._componentName = options.componentName;
  9663. this._ngModel = options.ngModel;
  9664. this._ngModelController = options.ngModelController
  9665. },
  9666. _isNgModelRequired: function() {
  9667. return this._componentClass.subclassOf(ui.Editor) && this._ngModel
  9668. },
  9669. _initComponentBindings: function() {
  9670. this.callBase.apply(this, arguments);
  9671. this._initNgModelBinding()
  9672. },
  9673. _initNgModelBinding: function() {
  9674. if (!this._isNgModelRequired())
  9675. return;
  9676. var that = this;
  9677. var ngModelWatcher = this._scope.$watch(this._ngModel, function(newValue, oldValue) {
  9678. if (newValue === oldValue)
  9679. return;
  9680. that._component.option(that._ngModelOption(), newValue)
  9681. });
  9682. that._optionChangedCallbacks.add(function(args) {
  9683. if (args.name !== that._ngModelOption())
  9684. return;
  9685. that._ngModelController.$setViewValue(args.value)
  9686. });
  9687. this._disposingCallbacks.add(function() {
  9688. ngModelWatcher()
  9689. })
  9690. },
  9691. _ngModelOption: function() {
  9692. if ($.inArray(this._componentName, ["dxFileUploader", "dxTagBox"]) > -1)
  9693. return "values";
  9694. return "value"
  9695. },
  9696. _evalOptions: function() {
  9697. if (!this._isNgModelRequired())
  9698. return this.callBase.apply(this, arguments);
  9699. var result = this.callBase.apply(this, arguments);
  9700. result[this._ngModelOption()] = this._parse(this._ngModel)(this._scope);
  9701. return result
  9702. }
  9703. });
  9704. var NgComponent = DX.DOMComponent.inherit({
  9705. _modelByElement: function(element) {
  9706. if (element.length)
  9707. return element.scope()
  9708. },
  9709. _createActionByOption: function(optionName, config) {
  9710. var action = this.callBase.apply(this, arguments);
  9711. if (config && $.inArray(config.category, SKIP_APPLY_ACTION_CATEGORIES) > -1)
  9712. return action;
  9713. var component = this,
  9714. wrappedAction = function() {
  9715. var that = this,
  9716. scope = component._modelByElement(component.element()),
  9717. args = arguments;
  9718. if (!scope || !scope.$root || scope.$root.$$phase)
  9719. return action.apply(that, args);
  9720. return scope.$apply(function() {
  9721. return action.apply(that, args)
  9722. })
  9723. };
  9724. return wrappedAction
  9725. },
  9726. _createComponent: function(element, name, config) {
  9727. return this.callBase(element, name, $.extend({templateCompiler: this.option("templateCompiler")}, config))
  9728. }
  9729. });
  9730. var registeredComponents = {};
  9731. var originalRegisterComponent = DX.registerComponent;
  9732. var registerNgComponent = function(componentName, _, componentClass) {
  9733. componentClass = componentClass || _;
  9734. originalRegisterComponent.apply(this, arguments);
  9735. if (!registeredComponents[componentName])
  9736. registerComponentDirective(componentName);
  9737. registeredComponents[componentName] = componentClass
  9738. };
  9739. var registerComponentDirective = function(componentName) {
  9740. var priority = componentName !== "dxValidator" ? 1 : 10;
  9741. phoneJsModule.directive(componentName, ["$compile", "$parse", function($compile, $parse) {
  9742. return {
  9743. restrict: "A",
  9744. require: "^?ngModel",
  9745. priority: priority,
  9746. compile: function($element) {
  9747. var componentClass = registeredComponents[componentName],
  9748. $content = componentClass.subclassOf(ui.Widget) ? $element.contents().detach() : null;
  9749. return function(scope, $element, attrs, ngModelController) {
  9750. $element.append($content);
  9751. var componentBuilder = new ComponentBuilder({
  9752. componentClass: componentClass,
  9753. componentName: componentName,
  9754. compile: $compile,
  9755. parse: $parse,
  9756. $element: $element,
  9757. scope: scope,
  9758. ngOptions: attrs[componentName] ? scope.$eval(attrs[componentName]) : {},
  9759. ngModel: attrs.ngModel,
  9760. ngModelController: ngModelController,
  9761. itemAlias: attrs[ITEM_ALIAS_ATTRIBUTE_NAME]
  9762. });
  9763. componentBuilder.initComponentWithBindings()
  9764. }
  9765. }
  9766. }
  9767. }])
  9768. };
  9769. phoneJsModule.filter('dxGlobalize', function() {
  9770. return function(input, param) {
  9771. return Globalize.format(input, param)
  9772. }
  9773. });
  9774. phoneJsModule.directive("dxIcon", ["$compile", function($compile) {
  9775. return {
  9776. restrict: 'E',
  9777. link: function($scope, $element, $attrs) {
  9778. var html = DX.utils.getImageContainer($scope.icon || $scope.iconSrc);
  9779. if (html) {
  9780. var e = $compile(html.get(0))($scope);
  9781. $element.replaceWith(e)
  9782. }
  9783. }
  9784. }
  9785. }]);
  9786. DX.registerComponent = registerNgComponent;
  9787. registerNgComponent("DOMComponent", NgComponent)
  9788. })(jQuery, DevExpress);
  9789. /*! Module core, file ko.templates.js */
  9790. (function($, DX, undefined) {
  9791. if (!DX.support.hasKo)
  9792. return;
  9793. var ko = window.ko,
  9794. ui = DX.ui;
  9795. var KoTemplate = ui.TemplateBase.inherit({
  9796. ctor: function(element) {
  9797. this.callBase.apply(this, arguments);
  9798. this._template = $("<div>").append(DX.utils.normalizeTemplateElement(element));
  9799. this._registerKoTemplate()
  9800. },
  9801. _registerKoTemplate: function() {
  9802. var template = this._template.get(0);
  9803. new ko.templateSources.anonymousTemplate(template)['nodes'](template)
  9804. },
  9805. _prepareDataForContainer: function(data, container) {
  9806. var result = data,
  9807. containerElement,
  9808. containerContext;
  9809. if (container.length) {
  9810. containerElement = container.get(0);
  9811. data = data !== undefined ? data : ko.dataFor(containerElement) || {};
  9812. containerContext = ko.contextFor(containerElement);
  9813. if (containerContext)
  9814. result = data === containerContext.$data ? containerContext : containerContext.createChildContext(data);
  9815. else
  9816. result = data
  9817. }
  9818. return result
  9819. },
  9820. _renderCore: function(data) {
  9821. var $renderBag = $("<div>");
  9822. ko.renderTemplate(this._template.get(0), data, null, $renderBag.get(0));
  9823. var $result = $renderBag.contents().detach();
  9824. $renderBag.remove();
  9825. return $result
  9826. },
  9827. dispose: function() {
  9828. this.callBase();
  9829. this._template.remove()
  9830. }
  9831. });
  9832. var KoTemplateProvider = new(ui.TemplateProviderBase.inherit({
  9833. createTemplate: function(element, owner) {
  9834. return new KoTemplate(element, owner)
  9835. },
  9836. applyTemplate: function(element, model) {
  9837. ko.applyBindings(model, element)
  9838. },
  9839. _templatesForWidget: function(widgetName) {
  9840. var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},
  9841. templates = {};
  9842. $.each(templateGenerators, function(name, generator) {
  9843. var $markup = DX.utils.createMarkupFromString(generator());
  9844. if (name !== "itemFrame")
  9845. $markup = $markup.contents();
  9846. templates[name] = new KoTemplate($markup, KoTemplateProvider)
  9847. });
  9848. return templates
  9849. }
  9850. }));
  9851. var createElementWithBindAttr = function(tagName, bindings, closeTag, additionalProperties) {
  9852. closeTag = closeTag === undefined ? true : closeTag;
  9853. var bindAttr = $.map(bindings, function(value, key) {
  9854. return key + ":" + value
  9855. }).join(",");
  9856. additionalProperties = additionalProperties || "";
  9857. return "<" + tagName + " data-bind=\"" + bindAttr + "\" " + additionalProperties + ">" + (closeTag ? "</" + tagName + ">" : "")
  9858. };
  9859. var defaultKoTemplateBasicBindings = {css: "{ 'dx-state-disabled': $data.disabled, 'dx-state-invisible': !($data.visible === undefined || ko.unwrap($data.visible)) }"};
  9860. var TEMPLATE_GENERATORS = {};
  9861. var emptyTemplate = function() {
  9862. return ""
  9863. };
  9864. TEMPLATE_GENERATORS.CollectionWidget = {
  9865. itemFrame: function() {
  9866. var markup = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false), "<div class='dx-item-content-placeholder'></div>", "</div>"];
  9867. return markup.join("")
  9868. },
  9869. item: function() {
  9870. var htmlBinding = createElementWithBindAttr("div", {html: "html"}),
  9871. textBinding = createElementWithBindAttr("div", {text: "text"}),
  9872. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
  9873. var markup = ["<div>", "<!-- ko if: $data.html && !$data.text -->", htmlBinding, "<!-- /ko -->", "<!-- ko if: !$data.html && $data.text -->", textBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];
  9874. return markup.join("")
  9875. }
  9876. };
  9877. var BUTTON_TEXT_CLASS = "dx-button-text";
  9878. TEMPLATE_GENERATORS.dxButton = {content: function() {
  9879. var textBinding = createElementWithBindAttr("span", {
  9880. text: "$data.text",
  9881. css: "{ '" + BUTTON_TEXT_CLASS + "' : !!$data.text }"
  9882. });
  9883. var markup = ["<div>", "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", textBinding, "</div>"];
  9884. return markup.join("")
  9885. }};
  9886. var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",
  9887. LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",
  9888. BADGE_CLASS = "dx-badge",
  9889. LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",
  9890. LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";
  9891. TEMPLATE_GENERATORS.dxList = {
  9892. item: function() {
  9893. var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
  9894. keyBinding = createElementWithBindAttr("div", {text: "key"});
  9895. template = [template.substring(0, template.length - 6), "<!-- ko if: $data.key -->" + keyBinding + "<!-- /ko -->", "</div>"];
  9896. return template.join("")
  9897. },
  9898. itemFrame: function() {
  9899. var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
  9900. badgeBinding = createElementWithBindAttr("div", {text: "badge"}, true, 'class="' + LIST_ITEM_BADGE_CLASS + " " + BADGE_CLASS + '"');
  9901. var markup = [template.substring(0, template.length - 6), "<!-- ko if: $data.badge -->", "<div class=\"" + LIST_ITEM_BADGE_CONTAINER_CLASS + "\">", badgeBinding, "</div>", "<!-- /ko -->", "<!-- ko if: $data.showChevron -->", "<div class=\"" + LIST_ITEM_CHEVRON_CONTAINER_CLASS + "\">", "<div class=\"" + LIST_ITEM_CHEVRON_CLASS + "\"></div>", "</div>", "<!-- /ko -->", "</div>"];
  9902. return markup.join("")
  9903. },
  9904. group: function() {
  9905. var keyBinding = createElementWithBindAttr("div", {text: "key"}),
  9906. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
  9907. var markup = ["<div>", "<!-- ko if: $data.key -->", keyBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];
  9908. return markup.join("")
  9909. }
  9910. };
  9911. TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};
  9912. TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};
  9913. TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};
  9914. TEMPLATE_GENERATORS.dxScheduler = {item: function() {
  9915. var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
  9916. startDateBinding = createElementWithBindAttr("strong", {text: "Globalize.format(DevExpress.utils.makeDate($data.startDate), 't')"}),
  9917. endDateBinding = createElementWithBindAttr("strong", {text: "' - ' + Globalize.format(DevExpress.utils.makeDate($data.endDate), 't')"});
  9918. template = [template.substring(0, template.length - 6), "<div class='dx-scheduler-appointment-content-details'>", "<!-- ko if: $data.startDate -->" + startDateBinding + "<!-- /ko -->", "<!-- ko if: $data.endDate -->" + endDateBinding + "<!-- /ko -->", "</div>", "<!-- ko if: $data.recurrenceRule --><span class='dx-scheduler-appointment-recurrence-icon'></span><!-- /ko -->", "</div>"];
  9919. return template.join("")
  9920. }};
  9921. TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};
  9922. TEMPLATE_GENERATORS.dxSlideOutView = {
  9923. menu: emptyTemplate,
  9924. content: emptyTemplate
  9925. };
  9926. TEMPLATE_GENERATORS.dxSlideOut = {
  9927. menuItem: TEMPLATE_GENERATORS.dxList.item,
  9928. menuGroup: TEMPLATE_GENERATORS.dxList.group,
  9929. content: emptyTemplate
  9930. };
  9931. TEMPLATE_GENERATORS.dxAccordion = {
  9932. title: function() {
  9933. var titleBinding = createElementWithBindAttr("span", {text: "$.isPlainObject($data) ? $data.title : String($data)"});
  9934. var markup = ["<div>", "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", titleBinding, "</div>"];
  9935. return markup.join("")
  9936. },
  9937. item: TEMPLATE_GENERATORS.CollectionWidget.item
  9938. };
  9939. TEMPLATE_GENERATORS.dxResponsiveBox = {item: TEMPLATE_GENERATORS.CollectionWidget.item},
  9940. TEMPLATE_GENERATORS.dxPivotTabs = {item: function() {
  9941. var titleBinding = createElementWithBindAttr("span", {text: "title"}),
  9942. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
  9943. var markup = ["<div>", "<!-- ko if: $data.title -->", titleBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];
  9944. return markup.join("")
  9945. }};
  9946. TEMPLATE_GENERATORS.dxPivot = {
  9947. title: TEMPLATE_GENERATORS.dxPivotTabs.item,
  9948. content: emptyTemplate
  9949. };
  9950. var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";
  9951. TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function() {
  9952. var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
  9953. headerBinding = createElementWithBindAttr("div", {text: "title"}, true, 'class="' + PANORAMA_ITEM_TITLE_CLASS + '"');
  9954. var divInnerStart = template.indexOf(">") + 1;
  9955. template = [template.substring(0, divInnerStart), "<!-- ko if: $data.title -->", headerBinding, "<!-- /ko -->", template.substring(divInnerStart, template.length)];
  9956. return template.join("")
  9957. }};
  9958. TEMPLATE_GENERATORS.dxActionSheet = {item: function() {
  9959. return ["<div>", createElementWithBindAttr("div", {dxButton: "{ text: $data.text, onClick: $data.clickAction || $data.onClick, type: $data.type, disabled: !!ko.unwrap($data.disabled) }"}), "</div>"].join("")
  9960. }};
  9961. TEMPLATE_GENERATORS.dxToolbar = {
  9962. item: function() {
  9963. var template = TEMPLATE_GENERATORS.CollectionWidget.item();
  9964. template = [template.substring(0, template.length - 6), "<!-- ko if: $data.widget -->"];
  9965. $.each(["button", "tabs", "dropDownMenu"], function() {
  9966. var bindingName = DX.inflector.camelize(["dx", "-", this].join("")),
  9967. bindingObj = {};
  9968. bindingObj[bindingName] = "$data.options";
  9969. template.push("<!-- ko if: $data.widget === '", this, "' -->", createElementWithBindAttr("div", bindingObj), "<!-- /ko -->")
  9970. });
  9971. template.push("<!-- /ko -->");
  9972. return template.join("")
  9973. },
  9974. menuItem: TEMPLATE_GENERATORS.dxList.item,
  9975. actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item
  9976. };
  9977. TEMPLATE_GENERATORS.dxGallery = {item: function() {
  9978. var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
  9979. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),
  9980. imgBinding = createElementWithBindAttr("img", {attr: "{ src: String($data) }"}, false);
  9981. template = [template.substring(0, template.length - 6).replace(primitiveBinding, imgBinding), "<!-- ko if: $data.imageSrc -->", createElementWithBindAttr("img", {attr: "{ src: $data.imageSrc }"}, false), "<!-- /ko -->"].join("");
  9982. return template
  9983. }};
  9984. TEMPLATE_GENERATORS.dxTabs = {
  9985. item: function() {
  9986. var template = TEMPLATE_GENERATORS.CollectionWidget.item(),
  9987. basePrimitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),
  9988. primitiveBinding = "<span class=\"dx-tab-text\" data-bind=\"text: String($data)\"></span>",
  9989. baseTextBinding = createElementWithBindAttr("div", {text: "text"}),
  9990. textBinding = "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->" + "<span class=\"dx-tab-text\" data-bind=\"text: $data.text\"></span>";
  9991. template = template.replace("<!-- ko if: !$data.html && $data.text -->", "<!-- ko if: !$data.html && ($data.text || $data.icon || $data.iconSrc) -->").replace(basePrimitiveBinding, primitiveBinding).replace(baseTextBinding, textBinding);
  9992. return template
  9993. },
  9994. itemFrame: function() {
  9995. var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
  9996. badgeBinding = createElementWithBindAttr("div", {
  9997. attr: "{ 'class': 'dx-tabs-item-badge dx-badge' }",
  9998. text: "badge"
  9999. });
  10000. var markup = [template.substring(0, template.length - 6), "<!-- ko if: $data.badge -->", badgeBinding, "<!-- /ko -->", "</div>"];
  10001. return markup.join("")
  10002. }
  10003. };
  10004. TEMPLATE_GENERATORS.dxTabPanel = {
  10005. item: TEMPLATE_GENERATORS.CollectionWidget.item,
  10006. title: function() {
  10007. var template = TEMPLATE_GENERATORS.dxTabs.item();
  10008. return template.replace(/\$data\.text/g, '$data.title')
  10009. }
  10010. };
  10011. var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";
  10012. TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function() {
  10013. var template = TEMPLATE_GENERATORS.CollectionWidget.itemFrame(),
  10014. badgeBinding = createElementWithBindAttr("div", {text: "badge"}, true, 'class="' + NAVBAR_ITEM_BADGE_CLASS + " " + BADGE_CLASS + '"');
  10015. var markup = [template.substring(0, template.length - 6), "<!-- ko if: $data.badge -->", badgeBinding, "<!-- /ko -->", "</div>"];
  10016. return markup.join("")
  10017. }};
  10018. TEMPLATE_GENERATORS.dxMenuBase = {item: function() {
  10019. var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)],
  10020. textBinding = createElementWithBindAttr("span", {
  10021. text: "text",
  10022. css: "{ 'dx-menu-item-text': true }"
  10023. }),
  10024. primitiveBinding = createElementWithBindAttr("span", {
  10025. text: "String($data)",
  10026. css: "{ 'dx-menu-item-text': true }"
  10027. }),
  10028. popout = "<span class='dx-menu-item-popout-container'><div class='dx-menu-item-popout'></div></span>";
  10029. template.push("<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", "<!-- ko if: $.isPlainObject($data) && $data.text -->", textBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "<!-- ko if: $data.items -->", popout, "<!-- /ko -->", "</div>");
  10030. return template.join("")
  10031. }};
  10032. TEMPLATE_GENERATORS.dxTreeView = {item: function() {
  10033. var node = [],
  10034. link = createElementWithBindAttr("span", {text: "text"}, true),
  10035. htmlBinding = createElementWithBindAttr("div", {html: "html"});
  10036. node.push("<div>", "<!-- ko if: $data.html && !$data.text -->", htmlBinding, "<!-- /ko -->", "<!-- ko dxIcon: $data.icon || $data.iconSrc --><!-- /ko -->", "<!-- ko if: !$data.html && $data.text -->" + link + "<!-- /ko -->", "</div>");
  10037. return node.join("")
  10038. }};
  10039. TEMPLATE_GENERATORS.dxCalendar = {cell: function() {
  10040. var textBinding = createElementWithBindAttr("span", {text: "text"}),
  10041. primitiveBinding = createElementWithBindAttr("span", {text: "String($data)"});
  10042. var markup = ["<div>", "<!-- ko if: !$data.html && $data.text -->", textBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>"];
  10043. return markup.join("")
  10044. }};
  10045. var popupTitleAndBottom = function() {
  10046. return ["<div>", createElementWithBindAttr("div", {dxToolbar: "{ items: $data }"}), "</div>"].join("")
  10047. };
  10048. TEMPLATE_GENERATORS.dxPopup = {
  10049. title: popupTitleAndBottom,
  10050. bottom: popupTitleAndBottom
  10051. };
  10052. TEMPLATE_GENERATORS.dxLookup = {
  10053. title: TEMPLATE_GENERATORS.dxPopup.title,
  10054. group: TEMPLATE_GENERATORS.dxList.group
  10055. };
  10056. TEMPLATE_GENERATORS.dxTagBox = {tag: function() {
  10057. return ["<div>", createElementWithBindAttr("span", {text: "$data"})].join("")
  10058. }};
  10059. $.extend(ui, {
  10060. KoTemplateProvider: KoTemplateProvider,
  10061. KoTemplate: KoTemplate
  10062. })
  10063. })(jQuery, DevExpress);
  10064. /*! Module core, file ng.templates.js */
  10065. (function($, DX, undefined) {
  10066. if (!DX.support.hasNg)
  10067. return;
  10068. var ui = DX.ui;
  10069. var TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";
  10070. var NgTemplate = ui.TemplateBase.inherit({
  10071. ctor: function() {
  10072. this.callBase.apply(this, arguments);
  10073. this.setCompiler(this._getParentTemplateCompiler())
  10074. },
  10075. _getParentTemplateCompiler: function() {
  10076. var templateCompiler = null,
  10077. owner = this.owner();
  10078. while (!templateCompiler && owner) {
  10079. templateCompiler = $.isFunction(owner.option) ? owner.option("templateCompiler") : null;
  10080. owner = $.isFunction(owner.owner) ? owner.owner() : null
  10081. }
  10082. return templateCompiler
  10083. },
  10084. _renderCore: function(data, index, $container) {
  10085. var compiledTemplate = this._compiledTemplate,
  10086. result = $.isFunction(compiledTemplate) ? compiledTemplate(data, index, $container) : compiledTemplate;
  10087. return result
  10088. },
  10089. setCompiler: function(templateCompiler) {
  10090. if (!templateCompiler)
  10091. return;
  10092. this._compiledTemplate = templateCompiler(DX.utils.normalizeTemplateElement(this._element))
  10093. }
  10094. });
  10095. var NgTemplateProvider = new(ui.TemplateProviderBase.inherit({
  10096. createTemplate: function(element, owner) {
  10097. return new NgTemplate(element, owner)
  10098. },
  10099. getTemplates: function(widget) {
  10100. var templateCompiler = widget.option("templateCompiler"),
  10101. templates = this.callBase.apply(this, arguments);
  10102. $.each(templates, function(_, template) {
  10103. template.setCompiler(templateCompiler)
  10104. });
  10105. return templates
  10106. },
  10107. _templatesForWidget: function(widgetName) {
  10108. var templateGenerators = TEMPLATE_GENERATORS[widgetName] || {},
  10109. templates = {};
  10110. $.each(templateGenerators, function(name, generator) {
  10111. var $markup = DX.utils.createMarkupFromString(generator());
  10112. templates[name] = new NgTemplate($markup.wrap(), NgTemplateProvider)
  10113. });
  10114. return templates
  10115. }
  10116. }));
  10117. var baseElements = {
  10118. container: function() {
  10119. return $("<div>").addClass(TEMPLATE_WRAPPER_CLASS)
  10120. },
  10121. html: function() {
  10122. return $("<div>").attr("ng-if", "html").attr("ng-bind-html", "html")
  10123. },
  10124. text: function() {
  10125. return $("<div>").attr("ng-if", "text").attr("ng-bind", "text")
  10126. },
  10127. primitive: function() {
  10128. return $("<div>").attr("ng-if", "scopeValue").attr("ng-bind-html", "'' + scopeValue")
  10129. }
  10130. };
  10131. var TEMPLATE_GENERATORS = {};
  10132. var emptyTemplate = function() {
  10133. return $()
  10134. };
  10135. TEMPLATE_GENERATORS.CollectionWidget = {
  10136. item: function() {
  10137. return baseElements.container().append(baseElements.html()).append(baseElements.text()).append(baseElements.primitive())
  10138. },
  10139. itemFrame: function() {
  10140. var $container = $("<div>").attr("ng-class", "{ 'dx-state-invisible': !visible && visible != undefined, 'dx-state-disabled': !!disabled }"),
  10141. $placeholder = $("<div>").addClass("dx-item-content-placeholder");
  10142. $container.append($placeholder);
  10143. return $container
  10144. }
  10145. };
  10146. var BUTTON_TEXT_CLASS = "dx-button-text";
  10147. TEMPLATE_GENERATORS.dxButton = {content: function() {
  10148. var $titleBinding = $("<span>").attr("ng-bind", "text").attr("ng-class", "{ '" + BUTTON_TEXT_CLASS + "' : !!text }"),
  10149. icon = $("<dx-icon>");
  10150. return baseElements.container().append(icon).append($titleBinding).append(baseElements.primitive())
  10151. }};
  10152. var LIST_ITEM_BADGE_CONTAINER_CLASS = "dx-list-item-badge-container",
  10153. LIST_ITEM_BADGE_CLASS = "dx-list-item-badge",
  10154. BADGE_CLASS = "dx-badge",
  10155. LIST_ITEM_CHEVRON_CONTAINER_CLASS = "dx-list-item-chevron-container",
  10156. LIST_ITEM_CHEVRON_CLASS = "dx-list-item-chevron";
  10157. TEMPLATE_GENERATORS.dxList = {
  10158. item: function() {
  10159. return TEMPLATE_GENERATORS.CollectionWidget.item().append($("<div>").attr("ng-if", "key").attr("ng-bind", "key"))
  10160. },
  10161. itemFrame: function() {
  10162. var $badgeContainer = $("<div>").addClass(LIST_ITEM_BADGE_CONTAINER_CLASS).attr("ng-if", "badge"),
  10163. $badge = $("<div>").addClass(LIST_ITEM_BADGE_CLASS).addClass(BADGE_CLASS).attr("ng-bind", "badge");
  10164. var $chevronContainer = $("<div>").addClass(LIST_ITEM_CHEVRON_CONTAINER_CLASS).attr("ng-if", "showChevron"),
  10165. $chevron = $("<div>").addClass(LIST_ITEM_CHEVRON_CLASS);
  10166. return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badgeContainer.append($badge)).append($chevronContainer.append($chevron))
  10167. },
  10168. group: function() {
  10169. var $keyBinding = $("<div>").attr("ng-if", "key").attr("ng-bind", "key");
  10170. return baseElements.container().append($keyBinding).append(baseElements.primitive())
  10171. }
  10172. };
  10173. TEMPLATE_GENERATORS.dxDropDownMenu = {item: TEMPLATE_GENERATORS.dxList.item};
  10174. TEMPLATE_GENERATORS.dxDropDownList = {item: TEMPLATE_GENERATORS.dxList.item};
  10175. TEMPLATE_GENERATORS.dxRadioGroup = {item: TEMPLATE_GENERATORS.CollectionWidget.item};
  10176. TEMPLATE_GENERATORS.dxScheduler = {item: function() {
  10177. var $itemContent = TEMPLATE_GENERATORS.CollectionWidget.item();
  10178. var $details = $("<div>").addClass("dx-scheduler-appointment-content-details");
  10179. $("<strong>").attr("ng-if", "startDate").text("{{startDate | date : 'shortTime' }}").appendTo($details);
  10180. $("<strong>").attr("ng-if", "endDate").text(" - {{endDate | date : 'shortTime' }}").appendTo($details);
  10181. $details.appendTo($itemContent);
  10182. $("<span>").attr("ng-if", "recurrenceRule").addClass("dx-scheduler-appointment-recurrence-icon").appendTo($itemContent);
  10183. return $itemContent
  10184. }};
  10185. TEMPLATE_GENERATORS.dxOverlay = {content: emptyTemplate};
  10186. TEMPLATE_GENERATORS.dxSlideOutView = {
  10187. menu: emptyTemplate,
  10188. content: emptyTemplate
  10189. };
  10190. TEMPLATE_GENERATORS.dxSlideOut = {
  10191. menuItem: TEMPLATE_GENERATORS.dxList.item,
  10192. menuGroup: TEMPLATE_GENERATORS.dxList.group,
  10193. content: emptyTemplate
  10194. };
  10195. TEMPLATE_GENERATORS.dxAccordion = {
  10196. title: function() {
  10197. var $titleBinding = $("<span>").attr("ng-if", "title").attr("ng-bind", "title"),
  10198. icon = $("<dx-icon>");
  10199. return baseElements.container().append(icon).append($titleBinding).append(baseElements.primitive())
  10200. },
  10201. content: TEMPLATE_GENERATORS.CollectionWidget.item
  10202. };
  10203. TEMPLATE_GENERATORS.dxPivotTabs = {item: function() {
  10204. return baseElements.container().append($("<span>").attr("ng-if", "title").attr("ng-bind", "title")).append(baseElements.primitive())
  10205. }};
  10206. TEMPLATE_GENERATORS.dxPivot = {
  10207. title: TEMPLATE_GENERATORS.dxPivotTabs.item,
  10208. content: emptyTemplate
  10209. };
  10210. var PANORAMA_ITEM_TITLE_CLASS = "dx-panorama-item-title";
  10211. TEMPLATE_GENERATORS.dxPanorama = {itemFrame: function() {
  10212. return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().prepend($("<div>").addClass(PANORAMA_ITEM_TITLE_CLASS).attr("ng-if", "title").attr("ng-bind", "title"))
  10213. }};
  10214. TEMPLATE_GENERATORS.dxActionSheet = {item: function() {
  10215. return baseElements.container().append($("<div>").attr("dx-button", "{ bindingOptions: { text: 'text', onClick: 'onClick', type: 'type', disabled: 'disabled' } }"))
  10216. }};
  10217. TEMPLATE_GENERATORS.dxToolbar = {
  10218. item: function() {
  10219. var template = TEMPLATE_GENERATORS.CollectionWidget.item();
  10220. $.each(["button", "tabs", "dropDownMenu"], function(i, widgetName) {
  10221. var bindingName = "dx-" + DX.inflector.dasherize(this);
  10222. $("<div>").attr("ng-if", "widget === '" + widgetName + "'").attr(bindingName, "options").appendTo(template)
  10223. });
  10224. return template
  10225. },
  10226. menuItem: TEMPLATE_GENERATORS.dxList.item,
  10227. actionSheetItem: TEMPLATE_GENERATORS.dxActionSheet.item
  10228. };
  10229. TEMPLATE_GENERATORS.dxGallery = {item: function() {
  10230. return baseElements.container().append(baseElements.html()).append(baseElements.text()).append($("<img>").attr("ng-if", "scopeValue").attr("ng-src", "{{'' + scopeValue}}")).append($("<img>").attr("ng-if", "imageSrc").attr("ng-src", "{{imageSrc}}"))
  10231. }};
  10232. var TABS_ITEM_TEXT_CLASS = "dx-tab-text";
  10233. TEMPLATE_GENERATORS.dxTabs = {
  10234. item: function() {
  10235. var container = baseElements.container();
  10236. var text = $("<span>").addClass(TABS_ITEM_TEXT_CLASS).attr("ng-bind", "text").attr("ng-if", "text"),
  10237. icon = $("<dx-icon>");
  10238. return container.append(baseElements.html()).append(icon).append(text).append(baseElements.primitive().addClass(TABS_ITEM_TEXT_CLASS))
  10239. },
  10240. itemFrame: function() {
  10241. var $badge = $("<div>").addClass("dx-tabs-item-badge dx-badge").attr("ng-bind", "badge").attr("ng-if", "badge");
  10242. return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badge)
  10243. }
  10244. };
  10245. var NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";
  10246. TEMPLATE_GENERATORS.dxNavBar = {itemFrame: function() {
  10247. var $badge = $("<div>").addClass(NAVBAR_ITEM_BADGE_CLASS).addClass(BADGE_CLASS).attr("ng-if", "badge").attr("ng-bind", "badge");
  10248. return TEMPLATE_GENERATORS.CollectionWidget.itemFrame().append($badge)
  10249. }};
  10250. TEMPLATE_GENERATORS.dxMenuBase = {item: function() {
  10251. var container = baseElements.container();
  10252. var text = $("<span>").attr("ng-if", "text").addClass("dx-menu-item-text").attr("ng-bind", "text"),
  10253. icon = $("<dx-icon>"),
  10254. popout = $("<span>").addClass("dx-menu-item-popout-container").attr("ng-if", "items").append($("<div>").addClass("dx-menu-item-popout"));
  10255. container.append(baseElements.html()).append(icon).append(text).append(popout).append(baseElements.primitive()).appendTo(container);
  10256. return container
  10257. }};
  10258. TEMPLATE_GENERATORS.dxTreeView = {item: function() {
  10259. var content = baseElements.container(),
  10260. link = $("<span/>").attr("ng-bind", "text"),
  10261. icon = $("<dx-icon>");
  10262. content.append(baseElements.html()).append(icon).append(link).append(baseElements.primitive());
  10263. return content
  10264. }};
  10265. TEMPLATE_GENERATORS.dxTabPanel = {
  10266. item: TEMPLATE_GENERATORS.CollectionWidget.item,
  10267. title: function() {
  10268. var content = TEMPLATE_GENERATORS.dxTabs.item();
  10269. content.find(".dx-tab-text").eq(0).attr("ng-bind", "title").attr("ng-if", "title");
  10270. return content
  10271. }
  10272. };
  10273. var popupTitleAndBottom = function() {
  10274. return $("<div>").attr("dx-toolbar", "{ bindingOptions: { items: 'scopeValue' } }")
  10275. };
  10276. TEMPLATE_GENERATORS.dxPopup = {
  10277. title: popupTitleAndBottom,
  10278. bottom: popupTitleAndBottom
  10279. };
  10280. TEMPLATE_GENERATORS.dxLookup = {
  10281. title: TEMPLATE_GENERATORS.dxPopup.title,
  10282. group: TEMPLATE_GENERATORS.dxList.group
  10283. };
  10284. TEMPLATE_GENERATORS.dxTagBox = {tag: function() {
  10285. return $("<div>").append($("<span>").attr("ng-bind", "scopeValue"))
  10286. }};
  10287. TEMPLATE_GENERATORS.dxCalendar = {cell: function() {
  10288. var $cell = $("<span>").attr("ng-if", "text").attr("ng-bind", "text");
  10289. return baseElements.container().append($cell).append(baseElements.primitive())
  10290. }};
  10291. $.extend(ui, {
  10292. NgTemplate: NgTemplate,
  10293. NgTemplateProvider: NgTemplateProvider
  10294. })
  10295. })(jQuery, DevExpress);
  10296. /*! Module core, file ko.validation.js */
  10297. (function($, DX, undefined) {
  10298. if (!DX.support.hasKo)
  10299. return;
  10300. var ko = window.ko;
  10301. var koDxValidator = DX.Class.inherit({
  10302. ctor: function(target, option) {
  10303. var that = this;
  10304. that.target = target;
  10305. that.validationRules = option.validationRules;
  10306. that.name = option.name;
  10307. that.isValid = ko.observable(true);
  10308. that.validationError = ko.observable();
  10309. $.each(this.validationRules, function(_, rule) {
  10310. rule.validator = that
  10311. })
  10312. },
  10313. validate: function() {
  10314. var result = DevExpress.validationEngine.validate(this.target(), this.validationRules, this.name);
  10315. this._applyValidationResult(result);
  10316. return result
  10317. },
  10318. reset: function() {
  10319. this.target(null);
  10320. var result = {
  10321. isValid: true,
  10322. brokenRule: null
  10323. };
  10324. this._applyValidationResult(result);
  10325. return result
  10326. },
  10327. _applyValidationResult: function(result) {
  10328. result.validator = this;
  10329. this.target.dxValidator.isValid(result.isValid);
  10330. this.target.dxValidator.validationError(result.brokenRule);
  10331. this.fireEvent("validated", [result])
  10332. }
  10333. }).include(DX.EventsMixin);
  10334. ko.extenders.dxValidator = function(target, option) {
  10335. target.dxValidator = new koDxValidator(target, option);
  10336. target.subscribe($.proxy(target.dxValidator.validate, target.dxValidator));
  10337. return target
  10338. };
  10339. DevExpress.validationEngine.registerModelForValidation = function(model) {
  10340. $.each(model, function(name, member) {
  10341. if (ko.isObservable(member) && member.dxValidator)
  10342. DevExpress.validationEngine.registerValidatorInGroup(model, member.dxValidator)
  10343. })
  10344. };
  10345. DevExpress.validationEngine.validateModel = DevExpress.validationEngine.validateGroup
  10346. })(jQuery, DevExpress);
  10347. /*! Module core, file ui.themes.js */
  10348. (function($, DX, undefined) {
  10349. var DX_LINK_SELECTOR = "link[rel=dx-theme]",
  10350. THEME_ATTR = "data-theme",
  10351. ACTIVE_ATTR = "data-active";
  10352. var context,
  10353. $activeThemeLink,
  10354. knownThemes,
  10355. currentThemeName,
  10356. pendingThemeName;
  10357. var THEME_MARKER_PREFIX = "dx.";
  10358. function readThemeMarker() {
  10359. var element = $("<div></div>", context).addClass("dx-theme-marker").appendTo(context.documentElement),
  10360. result;
  10361. try {
  10362. result = element.css("font-family");
  10363. if (!result)
  10364. return null;
  10365. result = result.replace(/["']/g, "");
  10366. if (result.substr(0, THEME_MARKER_PREFIX.length) !== THEME_MARKER_PREFIX)
  10367. return null;
  10368. return result.substr(THEME_MARKER_PREFIX.length)
  10369. }
  10370. finally {
  10371. element.remove()
  10372. }
  10373. }
  10374. function waitForThemeLoad(themeName, callback) {
  10375. var timerId,
  10376. waitStartTime;
  10377. pendingThemeName = themeName;
  10378. function handleLoaded() {
  10379. pendingThemeName = null;
  10380. callback()
  10381. }
  10382. if (isPendingThemeLoaded())
  10383. handleLoaded();
  10384. else {
  10385. waitStartTime = $.now();
  10386. timerId = setInterval(function() {
  10387. var isLoaded = isPendingThemeLoaded(),
  10388. isTimeout = !isLoaded && $.now() - waitStartTime > 15 * 1000;
  10389. if (isTimeout)
  10390. DX.log("W0004", pendingThemeName);
  10391. if (isLoaded || isTimeout) {
  10392. clearInterval(timerId);
  10393. handleLoaded()
  10394. }
  10395. }, 10)
  10396. }
  10397. }
  10398. function isPendingThemeLoaded() {
  10399. return !pendingThemeName || readThemeMarker() === pendingThemeName
  10400. }
  10401. function processMarkup() {
  10402. var $allThemeLinks = $(DX_LINK_SELECTOR, context);
  10403. if (!$allThemeLinks.length)
  10404. return;
  10405. knownThemes = {};
  10406. $activeThemeLink = $(DX.utils.createMarkupFromString("<link rel=stylesheet>"), context);
  10407. $allThemeLinks.each(function() {
  10408. var link = $(this, context),
  10409. fullThemeName = link.attr(THEME_ATTR),
  10410. url = link.attr("href"),
  10411. isActive = link.attr(ACTIVE_ATTR) === "true";
  10412. knownThemes[fullThemeName] = {
  10413. url: url,
  10414. isActive: isActive
  10415. }
  10416. });
  10417. $allThemeLinks.last().after($activeThemeLink);
  10418. $allThemeLinks.remove()
  10419. }
  10420. function resolveFullThemeName(desiredThemeName) {
  10421. var desiredThemeParts = desiredThemeName.split("."),
  10422. result = null;
  10423. if (knownThemes)
  10424. $.each(knownThemes, function(knownThemeName, themeData) {
  10425. var knownThemeParts = knownThemeName.split(".");
  10426. if (knownThemeParts[0] !== desiredThemeParts[0])
  10427. return;
  10428. if (desiredThemeParts[1] && desiredThemeParts[1] !== knownThemeParts[1])
  10429. return;
  10430. if (desiredThemeParts[2] && desiredThemeParts[2] !== knownThemeParts[2])
  10431. return;
  10432. if (!result || themeData.isActive)
  10433. result = knownThemeName;
  10434. if (themeData.isActive)
  10435. return false
  10436. });
  10437. return result
  10438. }
  10439. function initContext(newContext) {
  10440. try {
  10441. if (newContext !== context)
  10442. knownThemes = null
  10443. }
  10444. catch(x) {
  10445. knownThemes = null
  10446. }
  10447. context = newContext
  10448. }
  10449. function init(options) {
  10450. options = options || {};
  10451. initContext(options.context || document);
  10452. processMarkup();
  10453. currentThemeName = undefined;
  10454. current(options)
  10455. }
  10456. function current(options) {
  10457. if (!arguments.length)
  10458. return currentThemeName || readThemeMarker();
  10459. detachCssClasses(DX.viewPort(), currentThemeName);
  10460. options = options || {};
  10461. if (typeof options === "string")
  10462. options = {theme: options};
  10463. var isAutoInit = options._autoInit,
  10464. loadCallback = options.loadCallback,
  10465. currentThemeData;
  10466. currentThemeName = options.theme || currentThemeName;
  10467. if (isAutoInit && !currentThemeName)
  10468. currentThemeName = themeNameFromDevice(DX.devices.current());
  10469. currentThemeName = resolveFullThemeName(currentThemeName);
  10470. if (currentThemeName)
  10471. currentThemeData = knownThemes[currentThemeName];
  10472. if (currentThemeData) {
  10473. $activeThemeLink.attr("href", knownThemes[currentThemeName].url);
  10474. if (loadCallback)
  10475. waitForThemeLoad(currentThemeName, loadCallback);
  10476. else if (pendingThemeName)
  10477. pendingThemeName = currentThemeName
  10478. }
  10479. else if (isAutoInit) {
  10480. if (loadCallback)
  10481. loadCallback()
  10482. }
  10483. else
  10484. throw DX.Error("E0021", currentThemeName);
  10485. attachCssClasses(DX.viewPort(), currentThemeName)
  10486. }
  10487. function themeNameFromDevice(device) {
  10488. var themeName = device.platform;
  10489. if (themeName === "ios")
  10490. themeName += "7";
  10491. if (themeName === "android")
  10492. themeName += "5";
  10493. return themeName
  10494. }
  10495. function getCssClasses(themeName) {
  10496. themeName = themeName || current();
  10497. var result = [],
  10498. themeNameParts = themeName && themeName.split(".");
  10499. if (themeNameParts) {
  10500. result.push("dx-theme-" + themeNameParts[0], "dx-theme-" + themeNameParts[0] + "-typography");
  10501. if (themeNameParts.length > 1)
  10502. result.push("dx-color-scheme-" + themeNameParts[1])
  10503. }
  10504. return result
  10505. }
  10506. var themeClasses;
  10507. function attachCssClasses(element, themeName) {
  10508. themeClasses = getCssClasses(themeName).join(" ");
  10509. $(element).addClass(themeClasses)
  10510. }
  10511. function detachCssClasses(element, themeName) {
  10512. $(element).removeClass(themeClasses)
  10513. }
  10514. $.holdReady(true);
  10515. init({
  10516. _autoInit: true,
  10517. loadCallback: function() {
  10518. $.holdReady(false)
  10519. }
  10520. });
  10521. $(function() {
  10522. if ($(DX_LINK_SELECTOR, context).length)
  10523. throw DX.Error("E0022");
  10524. });
  10525. DX.viewPortChanged.add(function(viewPort, prevViewPort) {
  10526. detachCssClasses(prevViewPort);
  10527. attachCssClasses(viewPort)
  10528. });
  10529. DX.ui.themes = {
  10530. init: init,
  10531. current: current,
  10532. attachCssClasses: attachCssClasses,
  10533. detachCssClasses: detachCssClasses
  10534. };
  10535. DX.ui.themes.__internals = {
  10536. themeNameFromDevice: themeNameFromDevice,
  10537. waitForThemeLoad: waitForThemeLoad,
  10538. resetTheme: function() {
  10539. $activeThemeLink.attr("href", "about:blank");
  10540. currentThemeName = null;
  10541. pendingThemeName = null
  10542. }
  10543. }
  10544. })(jQuery, DevExpress);
  10545. /*! Module core, file ui.events.js */
  10546. (function($, DX, undefined) {
  10547. var ui = DX.ui,
  10548. eventNS = $.event,
  10549. hooksNS = eventNS.fixHooks,
  10550. specialNS = eventNS.special,
  10551. EVENT_SOURCES_REGEX = {
  10552. dx: /^dx/i,
  10553. mouse: /(mouse|wheel)/i,
  10554. touch: /^touch/i,
  10555. keyboard: /^key/i,
  10556. pointer: /^(ms)?pointer/i
  10557. };
  10558. var eventSource = function(e) {
  10559. var result = "other";
  10560. $.each(EVENT_SOURCES_REGEX, function(key) {
  10561. if (this.test(e.type)) {
  10562. result = key;
  10563. return false
  10564. }
  10565. });
  10566. return result
  10567. };
  10568. var isDxEvent = function(e) {
  10569. return eventSource(e) === "dx"
  10570. };
  10571. var isNativeMouseEvent = function(e) {
  10572. return eventSource(e) === "mouse"
  10573. };
  10574. var isNativeTouchEvent = function(e) {
  10575. return eventSource(e) === "touch"
  10576. };
  10577. var isPointerEvent = function(e) {
  10578. return eventSource(e) === "pointer"
  10579. };
  10580. var isMouseEvent = function(e) {
  10581. return isNativeMouseEvent(e) || (isPointerEvent(e) || isDxEvent(e)) && e.pointerType === "mouse"
  10582. };
  10583. var isTouchEvent = function(e) {
  10584. return isNativeTouchEvent(e) || (isPointerEvent(e) || isDxEvent(e)) && e.pointerType === "touch"
  10585. };
  10586. var isKeyboardEvent = function(e) {
  10587. return eventSource(e) === "keyboard"
  10588. };
  10589. var eventData = function(e) {
  10590. return {
  10591. x: e.pageX,
  10592. y: e.pageY,
  10593. time: e.timeStamp
  10594. }
  10595. };
  10596. var eventDelta = function(from, to) {
  10597. return {
  10598. x: to.x - from.x,
  10599. y: to.y - from.y,
  10600. time: to.time - from.time || 1
  10601. }
  10602. };
  10603. var hasTouches = function(e) {
  10604. if (isNativeTouchEvent(e))
  10605. return (e.originalEvent.touches || []).length;
  10606. if (isDxEvent(e))
  10607. return (e.pointers || []).length;
  10608. return 0
  10609. };
  10610. var needSkipEvent = function(e) {
  10611. var $target = $(e.target),
  10612. touchInInput = $target.is("input, textarea, select");
  10613. if (e.type === 'dxmousewheel')
  10614. return $target.is("input[type='number'], textarea, select") && $target.is(':focus');
  10615. if (isMouseEvent(e))
  10616. return touchInInput || e.which > 1;
  10617. if (isTouchEvent(e))
  10618. return touchInInput && $target.is(":focus")
  10619. };
  10620. var createEvent = function(originalEvent, args) {
  10621. var event = $.Event(originalEvent),
  10622. fixHook = hooksNS[originalEvent.type] || eventNS.mouseHooks;
  10623. var props = fixHook.props ? eventNS.props.concat(fixHook.props) : eventNS.props,
  10624. propIndex = props.length;
  10625. while (propIndex--) {
  10626. var prop = props[propIndex];
  10627. event[prop] = originalEvent[prop]
  10628. }
  10629. if (args)
  10630. $.extend(event, args);
  10631. return fixHook.filter ? fixHook.filter(event, originalEvent) : event
  10632. };
  10633. var fireEvent = function(props) {
  10634. var event = createEvent(props.originalEvent, props);
  10635. eventNS.trigger(event, null, props.delegateTarget || event.target);
  10636. return event
  10637. };
  10638. var addNamespace = function(eventNames, namespace) {
  10639. if (!namespace)
  10640. throw DX.Error("E0017");
  10641. if (typeof eventNames === "string")
  10642. return addNamespace(eventNames.split(/\s+/g), namespace);
  10643. $.each(eventNames, function(index, eventName) {
  10644. eventNames[index] = eventName + "." + namespace
  10645. });
  10646. return eventNames.join(" ")
  10647. };
  10648. var dxEventHook = {props: eventNS.mouseHooks.props.concat(["pointerType", "pointerId", "pointers"])};
  10649. var registerEvent = function(eventName, eventObject) {
  10650. var strategy = {};
  10651. if ("noBubble" in eventObject)
  10652. strategy.noBubble = eventObject.noBubble;
  10653. if ("bindType" in eventObject)
  10654. strategy.bindType = eventObject.bindType;
  10655. if ("delegateType" in eventObject)
  10656. strategy.delegateType = eventObject.delegateType;
  10657. $.each(["setup", "teardown", "add", "remove", "trigger", "handle", "_default", "dispose"], function(_, methodName) {
  10658. if (!eventObject[methodName])
  10659. return;
  10660. strategy[methodName] = function() {
  10661. var args = $.makeArray(arguments);
  10662. args.unshift(this);
  10663. return eventObject[methodName].apply(eventObject, args)
  10664. }
  10665. });
  10666. hooksNS[eventName] = dxEventHook;
  10667. specialNS[eventName] = strategy
  10668. };
  10669. ui.events = {
  10670. eventSource: eventSource,
  10671. isPointerEvent: isPointerEvent,
  10672. isMouseEvent: isMouseEvent,
  10673. isTouchEvent: isTouchEvent,
  10674. isKeyboardEvent: isKeyboardEvent,
  10675. hasTouches: hasTouches,
  10676. eventData: eventData,
  10677. eventDelta: eventDelta,
  10678. needSkipEvent: needSkipEvent,
  10679. createEvent: createEvent,
  10680. fireEvent: fireEvent,
  10681. addNamespace: addNamespace,
  10682. registerEvent: registerEvent
  10683. }
  10684. })(jQuery, DevExpress);
  10685. /*! Module core, file ko.events.js */
  10686. (function($, DX, undefined) {
  10687. if (!DX.support.hasKo)
  10688. return;
  10689. var ko = window.ko,
  10690. events = DX.ui.events;
  10691. var originalRegisterEvent = events.registerEvent;
  10692. var registerKoEvent = function(eventName, eventObject) {
  10693. originalRegisterEvent(eventName, eventObject);
  10694. var koBindingEventName = events.addNamespace(eventName, eventName + "Binding");
  10695. ko.bindingHandlers[eventName] = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
  10696. var $element = $(element),
  10697. unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
  10698. eventSource = unwrappedValue.execute ? unwrappedValue.execute : unwrappedValue;
  10699. $element.off(koBindingEventName).on(koBindingEventName, $.isPlainObject(unwrappedValue) ? unwrappedValue : {}, function(e) {
  10700. eventSource.call(viewModel, viewModel, e)
  10701. })
  10702. }}
  10703. };
  10704. $.extend(events, {registerEvent: registerKoEvent})
  10705. })(jQuery, DevExpress);
  10706. /*! Module core, file ng.events.js */
  10707. (function($, DX, undefined) {
  10708. if (!DX.support.hasNg)
  10709. return;
  10710. var events = DX.ui.events;
  10711. var originalRegisterEvent = events.registerEvent;
  10712. var registerNgEvent = function(eventName, eventObject) {
  10713. originalRegisterEvent(eventName, eventObject);
  10714. var ngEventName = eventName.slice(0, 2) + eventName.charAt(2).toUpperCase() + eventName.slice(3);
  10715. DX.ng.module.directive(ngEventName, ['$parse', function($parse) {
  10716. return function(scope, element, attr) {
  10717. var attrValue = $.trim(attr[ngEventName]),
  10718. handler,
  10719. eventOptions = {};
  10720. if (attrValue.charAt(0) === "{") {
  10721. eventOptions = scope.$eval(attrValue);
  10722. handler = $parse(eventOptions.execute)
  10723. }
  10724. else
  10725. handler = $parse(attr[ngEventName]);
  10726. element.on(eventName, eventOptions, function(e) {
  10727. scope.$apply(function() {
  10728. handler(scope, {$event: e})
  10729. })
  10730. })
  10731. }
  10732. }])
  10733. };
  10734. $.extend(events, {registerEvent: registerNgEvent})
  10735. })(jQuery, DevExpress);
  10736. /*! Module core, file ui.keyboardProcessor.js */
  10737. (function($, DX, undefined) {
  10738. var ui = DX.ui,
  10739. events = ui.events;
  10740. ui.KeyboardProcessor = DX.Class.inherit({
  10741. _keydown: events.addNamespace("keydown", "KeyboardProcessor"),
  10742. codes: {
  10743. "8": "backspace",
  10744. "9": "tab",
  10745. "13": "enter",
  10746. "27": "escape",
  10747. "33": "pageUp",
  10748. "34": "pageDown",
  10749. "35": "end",
  10750. "36": "home",
  10751. "37": "leftArrow",
  10752. "38": "upArrow",
  10753. "39": "rightArrow",
  10754. "40": "downArrow",
  10755. "46": "del",
  10756. "32": "space",
  10757. "70": "F",
  10758. "65": "A",
  10759. "106": "asterisk",
  10760. "109": "minus"
  10761. },
  10762. ctor: function(options) {
  10763. var _this = this;
  10764. options = options || {};
  10765. if (options.element)
  10766. this._element = $(options.element);
  10767. if (options.focusTarget)
  10768. this._focusTarget = options.focusTarget;
  10769. this._handler = options.handler;
  10770. this._context = options.context;
  10771. this._childProcessors = [];
  10772. if (this._element)
  10773. this._element.on(this._keydown, function(e) {
  10774. _this.process(e)
  10775. })
  10776. },
  10777. dispose: function() {
  10778. if (this._element)
  10779. this._element.off(this._keydown);
  10780. this._element = undefined;
  10781. this._handler = undefined;
  10782. this._context = undefined;
  10783. this._childProcessors = undefined
  10784. },
  10785. clearChildren: function() {
  10786. this._childProcessors = []
  10787. },
  10788. push: function(child) {
  10789. if (!this._childProcessors)
  10790. this.clearChildren();
  10791. this._childProcessors.push(child);
  10792. return child
  10793. },
  10794. attachChildProcessor: function() {
  10795. var childProcessor = new ui.KeyboardProcessor;
  10796. this._childProcessors.push(childProcessor);
  10797. return childProcessor
  10798. },
  10799. reinitialize: function(childHandler, childContext) {
  10800. this._context = childContext;
  10801. this._handler = childHandler;
  10802. return this
  10803. },
  10804. process: function(e) {
  10805. if (this._focusTarget && this._focusTarget !== e.target && $.inArray(e.target, this._focusTarget) < 0)
  10806. return false;
  10807. var args = {
  10808. key: this.codes[e.which] || e.which,
  10809. ctrl: e.ctrlKey,
  10810. shift: e.shiftKey,
  10811. alt: e.altKey,
  10812. originalEvent: e
  10813. };
  10814. var handlerResult = this._handler && this._handler.call(this._context, args);
  10815. if (handlerResult && this._childProcessors)
  10816. $.each(this._childProcessors, function(index, childProcessor) {
  10817. childProcessor.process(e)
  10818. })
  10819. }
  10820. })
  10821. })(jQuery, DevExpress);
  10822. /*! Module core, file ui.dialog.js */
  10823. (function($, DX, undefined) {
  10824. var ui = DX.ui,
  10825. utils = DX.utils;
  10826. var DEFAULT_BUTTON = {
  10827. text: "OK",
  10828. onClick: function() {
  10829. return true
  10830. }
  10831. };
  10832. var DX_DIALOG_CLASSNAME = "dx-dialog",
  10833. DX_DIALOG_WRAPPER_CLASSNAME = DX_DIALOG_CLASSNAME + "-wrapper",
  10834. DX_DIALOG_ROOT_CLASSNAME = DX_DIALOG_CLASSNAME + "-root",
  10835. DX_DIALOG_CONTENT_CLASSNAME = DX_DIALOG_CLASSNAME + "-content",
  10836. DX_DIALOG_MESSAGE_CLASSNAME = DX_DIALOG_CLASSNAME + "-message",
  10837. DX_DIALOG_BUTTONS_CLASSNAME = DX_DIALOG_CLASSNAME + "-buttons",
  10838. DX_DIALOG_BUTTON_CLASSNAME = DX_DIALOG_CLASSNAME + "-button";
  10839. var FakeDialogComponent = DX.Component.inherit({
  10840. NAME: "dxDialog",
  10841. ctor: function(element, options) {
  10842. this.callBase(options)
  10843. },
  10844. _defaultOptionsRules: function() {
  10845. return this.callBase().concat([{
  10846. device: {platform: "ios"},
  10847. options: {width: 276}
  10848. }, {
  10849. device: {platform: "android"},
  10850. options: {
  10851. lWidth: "60%",
  10852. pWidth: "80%"
  10853. }
  10854. }, {
  10855. device: {
  10856. platform: "win8",
  10857. phone: false
  10858. },
  10859. options: {width: function() {
  10860. return $(window).width()
  10861. }}
  10862. }, {
  10863. device: {
  10864. platform: "win8",
  10865. phone: true
  10866. },
  10867. options: {position: {
  10868. my: "top center",
  10869. at: "top center",
  10870. of: window,
  10871. offset: "0 0"
  10872. }}
  10873. }])
  10874. }
  10875. });
  10876. var dialog = function(options) {
  10877. if (!ui.dxPopup)
  10878. throw DX.Error("E0018");
  10879. var deferred = $.Deferred();
  10880. var defaultOptions = (new FakeDialogComponent).option();
  10881. options = $.extend(defaultOptions, options);
  10882. var $element = $("<div>").addClass(DX_DIALOG_CLASSNAME).appendTo(DX.viewPort());
  10883. var $message = $("<div>").addClass(DX_DIALOG_MESSAGE_CLASSNAME).html(String(options.message));
  10884. var popupButtons = [];
  10885. $.each(options.buttons || [DEFAULT_BUTTON], function() {
  10886. if (this.clickAction) {
  10887. DX.log("W0001", "Dialog", "clickAction", "14.2", "Use 'onClick' option instead");
  10888. this.onClick = this.clickAction
  10889. }
  10890. var action = new DX.Action(this.onClick || this.clickAction, {context: popupInstance});
  10891. popupButtons.push({
  10892. toolbar: 'bottom',
  10893. location: 'center',
  10894. widget: 'button',
  10895. options: {
  10896. text: this.text,
  10897. onClick: function() {
  10898. var result = action.execute(arguments);
  10899. hide(result)
  10900. }
  10901. }
  10902. })
  10903. });
  10904. var popupInstance = $element.dxPopup({
  10905. title: options.title || this.title,
  10906. showTitle: function() {
  10907. var isTitle = options.showTitle === undefined ? true : options.showTitle;
  10908. return isTitle
  10909. }(),
  10910. height: "auto",
  10911. width: function() {
  10912. var isPortrait = $(window).height() > $(window).width(),
  10913. key = (isPortrait ? "p" : "l") + "Width",
  10914. widthOption = options.hasOwnProperty(key) ? options[key] : options["width"];
  10915. return $.isFunction(widthOption) ? widthOption() : widthOption
  10916. },
  10917. showCloseButton: false,
  10918. focusStateEnabled: false,
  10919. onContentReady: function(args) {
  10920. args.component.content().addClass(DX_DIALOG_CONTENT_CLASSNAME).append($message)
  10921. },
  10922. onShowing: function(e) {
  10923. e.component.bottomToolbar().addClass(DX_DIALOG_BUTTONS_CLASSNAME).find(".dx-button").addClass(DX_DIALOG_BUTTON_CLASSNAME).first().focus()
  10924. },
  10925. buttons: popupButtons,
  10926. animation: {
  10927. show: {
  10928. type: "pop",
  10929. duration: 400
  10930. },
  10931. hide: {
  10932. type: "pop",
  10933. duration: 400,
  10934. to: {
  10935. opacity: 0,
  10936. scale: 0
  10937. },
  10938. from: {
  10939. opacity: 1,
  10940. scale: 1
  10941. }
  10942. }
  10943. },
  10944. rtlEnabled: DX.rtlEnabled,
  10945. boundaryOffset: {
  10946. h: 10,
  10947. v: 0
  10948. }
  10949. }).dxPopup("instance");
  10950. popupInstance._wrapper().addClass(DX_DIALOG_WRAPPER_CLASSNAME);
  10951. if (options.position)
  10952. popupInstance.option("position", options.position);
  10953. popupInstance._wrapper().addClass(DX_DIALOG_ROOT_CLASSNAME);
  10954. function show() {
  10955. popupInstance.show();
  10956. utils.resetActiveElement();
  10957. return deferred.promise()
  10958. }
  10959. function hide(value) {
  10960. popupInstance.hide().done(function() {
  10961. popupInstance.element().remove()
  10962. });
  10963. deferred.resolve(value)
  10964. }
  10965. return {
  10966. show: show,
  10967. hide: hide
  10968. }
  10969. };
  10970. var alert = function(message, title, showTitle) {
  10971. var dialogInstance,
  10972. options = $.isPlainObject(message) ? message : {
  10973. title: title,
  10974. message: message,
  10975. showTitle: showTitle
  10976. };
  10977. dialogInstance = ui.dialog.custom(options);
  10978. return dialogInstance.show()
  10979. };
  10980. var confirm = function(message, title, showTitle) {
  10981. var dialogInstance,
  10982. options = $.isPlainObject(message) ? message : {
  10983. title: title,
  10984. message: message,
  10985. showTitle: showTitle,
  10986. buttons: [{
  10987. text: Globalize.localize("Yes"),
  10988. onClick: function() {
  10989. return true
  10990. }
  10991. }, {
  10992. text: Globalize.localize("No"),
  10993. onClick: function() {
  10994. return false
  10995. }
  10996. }]
  10997. };
  10998. dialogInstance = ui.dialog.custom(options);
  10999. return dialogInstance.show()
  11000. };
  11001. var $notify = null;
  11002. var notify = function(message, type, displayTime) {
  11003. var options = $.isPlainObject(message) ? message : {message: message};
  11004. if (!ui.dxToast) {
  11005. alert(options.message);
  11006. return
  11007. }
  11008. if (options.hiddenAction) {
  11009. DX.log("W0001", "Dialog", "hiddenAction", "14.2", "Use 'onHidden' option instead");
  11010. options.onHidden = options.hiddenAction
  11011. }
  11012. var userHiddenAction = options.onHidden;
  11013. $.extend(options, {
  11014. type: type,
  11015. displayTime: displayTime,
  11016. onHidden: function(args) {
  11017. args.element.remove();
  11018. new DX.Action(userHiddenAction, {context: args.model}).execute(arguments)
  11019. }
  11020. });
  11021. $notify = $("<div>").appendTo(DX.viewPort()).dxToast(options);
  11022. $notify.dxToast("instance").show()
  11023. };
  11024. $.extend(ui, {
  11025. notify: notify,
  11026. dialog: {
  11027. custom: dialog,
  11028. alert: alert,
  11029. confirm: confirm
  11030. }
  11031. });
  11032. ui.dialog.FakeDialogComponent = FakeDialogComponent
  11033. })(jQuery, DevExpress);
  11034. /*! Module core, file ui.dataHelper.js */
  11035. (function($, DX, undefined) {
  11036. var data = DX.data;
  11037. var DATA_SOURCE_OPTIONS_METHOD = "_dataSourceOptions",
  11038. DATA_SOURCE_CHANGED_METHOD = "_dataSourceChangedHandler",
  11039. DATA_SOURCE_LOAD_ERROR_METHOD = "_dataSourceLoadErrorHandler",
  11040. DATA_SOURCE_LOADING_CHANGED_METHOD = "_dataSourceLoadingChangedHandler";
  11041. DX.ui.DataHelperMixin = {
  11042. postCtor: function() {
  11043. this.on("disposing", function() {
  11044. this._disposeDataSource()
  11045. })
  11046. },
  11047. _isDataSourceReady: function() {
  11048. return !this._dataSource || this._dataSource.isLoaded()
  11049. },
  11050. _refreshDataSource: function() {
  11051. this._initDataSource();
  11052. this._loadDataSource()
  11053. },
  11054. _initDataSource: function() {
  11055. var dataSourceOptions = this.option("dataSource"),
  11056. widgetDataSourceOptions,
  11057. dataSourceType;
  11058. this._disposeDataSource();
  11059. if (dataSourceOptions) {
  11060. if (dataSourceOptions instanceof data.DataSource) {
  11061. this._isSharedDataSource = true;
  11062. this._dataSource = dataSourceOptions
  11063. }
  11064. else {
  11065. widgetDataSourceOptions = DATA_SOURCE_OPTIONS_METHOD in this ? this[DATA_SOURCE_OPTIONS_METHOD]() : {};
  11066. dataSourceType = this._dataSourceType ? this._dataSourceType() : data.DataSource;
  11067. this._dataSource = new dataSourceType($.extend(true, {}, widgetDataSourceOptions, data.utils.normalizeDataSourceOptions(dataSourceOptions)))
  11068. }
  11069. this._addDataSourceHandlers()
  11070. }
  11071. },
  11072. _addDataSourceHandlers: function() {
  11073. if (DATA_SOURCE_CHANGED_METHOD in this)
  11074. this._addDataSourceChangeHandler();
  11075. if (DATA_SOURCE_LOAD_ERROR_METHOD in this)
  11076. this._addDataSourceLoadErrorHandler();
  11077. if (DATA_SOURCE_LOADING_CHANGED_METHOD in this)
  11078. this._addDataSourceLoadingChangedHandler();
  11079. this._addReadyWatcher()
  11080. },
  11081. _addReadyWatcher: function() {
  11082. this._dataSource.on("loadingChanged", $.proxy(function(isLoading) {
  11083. this._ready && this._ready(!isLoading)
  11084. }, this))
  11085. },
  11086. _addDataSourceChangeHandler: function() {
  11087. var dataSource = this._dataSource;
  11088. this._proxiedDataSourceChangedHandler = $.proxy(function() {
  11089. this[DATA_SOURCE_CHANGED_METHOD](dataSource.items())
  11090. }, this);
  11091. dataSource.on("changed", this._proxiedDataSourceChangedHandler)
  11092. },
  11093. _addDataSourceLoadErrorHandler: function() {
  11094. this._proxiedDataSourceLoadErrorHandler = $.proxy(this[DATA_SOURCE_LOAD_ERROR_METHOD], this);
  11095. this._dataSource.on("loadError", this._proxiedDataSourceLoadErrorHandler)
  11096. },
  11097. _addDataSourceLoadingChangedHandler: function() {
  11098. this._proxiedDataSourceLoadingChangedHandler = $.proxy(this[DATA_SOURCE_LOADING_CHANGED_METHOD], this);
  11099. this._dataSource.on("loadingChanged", this._proxiedDataSourceLoadingChangedHandler)
  11100. },
  11101. _loadDataSource: function() {
  11102. if (this._dataSource) {
  11103. var dataSource = this._dataSource;
  11104. if (dataSource.isLoaded())
  11105. this._proxiedDataSourceChangedHandler && this._proxiedDataSourceChangedHandler();
  11106. else
  11107. dataSource.load()
  11108. }
  11109. },
  11110. _loadSingle: function(key, value) {
  11111. key = key === "this" ? this._dataSource.key() || "this" : key;
  11112. return this._dataSource.loadSingle(key, value)
  11113. },
  11114. _isLastPage: function() {
  11115. return !this._dataSource || this._dataSource.isLastPage() || !this._dataSource._pageSize
  11116. },
  11117. _isDataSourceLoading: function() {
  11118. return this._dataSource && this._dataSource.isLoading()
  11119. },
  11120. _disposeDataSource: function() {
  11121. if (this._dataSource) {
  11122. if (this._isSharedDataSource) {
  11123. delete this._isSharedDataSource;
  11124. this._proxiedDataSourceChangedHandler && this._dataSource.off("changed", this._proxiedDataSourceChangedHandler);
  11125. this._proxiedDataSourceLoadErrorHandler && this._dataSource.off("loadError", this._proxiedDataSourceLoadErrorHandler);
  11126. this._proxiedDataSourceLoadingChangedHandler && this._dataSource.off("loadingChanged", this._proxiedDataSourceLoadingChangedHandler)
  11127. }
  11128. else
  11129. this._dataSource.dispose();
  11130. delete this._dataSource;
  11131. delete this._proxiedDataSourceChangedHandler;
  11132. delete this._proxiedDataSourceLoadErrorHandler;
  11133. delete this._proxiedDataSourceLoadingChangedHandler
  11134. }
  11135. }
  11136. }
  11137. })(jQuery, DevExpress);
  11138. /*! Module core, file ui.dataExpression.js */
  11139. (function($, DX, undefined) {
  11140. var ui = DX.ui,
  11141. utils = DX.utils,
  11142. dataUtils = DX.data.utils;
  11143. ui.DataExpressionMixin = $.extend(ui.DataHelperMixin, {
  11144. _dataExpressionDeprecatedOptions: function() {
  11145. return {itemRender: {
  11146. since: "14.2",
  11147. alias: "itemTemplate"
  11148. }}
  11149. },
  11150. _dataExpressionDefaultOptions: function() {
  11151. return {
  11152. items: [],
  11153. dataSource: null,
  11154. itemTemplate: "item",
  11155. value: null,
  11156. valueExpr: "this",
  11157. displayExpr: undefined
  11158. }
  11159. },
  11160. _initDataExpressions: function() {
  11161. this._compileValueGetter();
  11162. this._compileDisplayGetter();
  11163. this._initDynamicTemplates();
  11164. this._initDataSource();
  11165. this._itemsToDataSource()
  11166. },
  11167. _itemsToDataSource: function() {
  11168. if (!this.option("dataSource"))
  11169. this._dataSource = new DevExpress.data.DataSource({
  11170. store: new DevExpress.data.ArrayStore(this.option("items")),
  11171. pageSize: 0
  11172. })
  11173. },
  11174. _compileDisplayGetter: function() {
  11175. this._displayGetter = dataUtils.compileGetter(this._displayGetterExpr())
  11176. },
  11177. _displayGetterExpr: function() {
  11178. return this.option("displayExpr")
  11179. },
  11180. _compileValueGetter: function() {
  11181. this._valueGetter = dataUtils.compileGetter(this._valueGetterExpr())
  11182. },
  11183. _valueGetterExpr: function() {
  11184. return this.option("valueExpr") || "this"
  11185. },
  11186. _loadValue: function(value) {
  11187. var deferred = $.Deferred();
  11188. value = this._unwrappedValue(value);
  11189. if (!utils.isDefined(value))
  11190. return deferred.reject().promise();
  11191. this._loadSingle(this._valueGetterExpr(), value).done($.proxy(function(item) {
  11192. this._isValueEquals(this._valueGetter(item), value) ? deferred.resolve(item) : deferred.reject()
  11193. }, this)).fail(function() {
  11194. deferred.reject()
  11195. });
  11196. return deferred.promise()
  11197. },
  11198. _unwrappedValue: function(value) {
  11199. value = DX.utils.isDefined(value) ? value : this.option("value");
  11200. if (value && this._dataSource && this._valueGetterExpr() === "this") {
  11201. var key = this._dataSource.key();
  11202. if (key && typeof value === "object")
  11203. value = value[key]
  11204. }
  11205. return utils.unwrapObservable(value)
  11206. },
  11207. _isValueEquals: function(value1, value2) {
  11208. var isDefined = utils.isDefined;
  11209. var ensureDefined = utils.ensureDefined;
  11210. var unwrapObservable = utils.unwrapObservable;
  11211. var dataSourceKey = this._dataSource && this._dataSource.key();
  11212. var result = this._compareValues(value1, value2);
  11213. if (!result && isDefined(value1) && isDefined(value2) && dataSourceKey) {
  11214. var valueKey1 = ensureDefined(unwrapObservable(value1[dataSourceKey]), value1);
  11215. var valueKey2 = ensureDefined(unwrapObservable(value2[dataSourceKey]), value2);
  11216. result = this._compareValues(valueKey1, valueKey2)
  11217. }
  11218. return result
  11219. },
  11220. _compareValues: function(value1, value2) {
  11221. return dataUtils.toComparable(value1) === dataUtils.toComparable(value2)
  11222. },
  11223. _initDynamicTemplates: function() {
  11224. if (this._displayGetterExpr())
  11225. this._dynamicTemplates["item"] = new ui.DefaultTemplate($.proxy(function(data) {
  11226. return this._displayGetter(data)
  11227. }, this));
  11228. else
  11229. delete this._dynamicTemplates["item"]
  11230. },
  11231. _setCollectionWidgetItemTemplate: function() {
  11232. this._initDynamicTemplates();
  11233. this._setCollectionWidgetOption("itemTemplate", this._getTemplateByOption("itemTemplate"))
  11234. },
  11235. _dataExpressionOptionChanged: function(args) {
  11236. switch (args.name) {
  11237. case"items":
  11238. this._itemsToDataSource();
  11239. this._setCollectionWidgetOption("items");
  11240. break;
  11241. case"dataSource":
  11242. this._initDataSource();
  11243. break;
  11244. case"itemTemplate":
  11245. this._setCollectionWidgetItemTemplate();
  11246. break;
  11247. case"valueExpr":
  11248. this._compileValueGetter();
  11249. break;
  11250. case"displayExpr":
  11251. this._compileDisplayGetter();
  11252. this._setCollectionWidgetItemTemplate();
  11253. break
  11254. }
  11255. }
  11256. })
  11257. })(jQuery, DevExpress);
  11258. /*! Module core, file ui.events.pointer.touchHooks.js */
  11259. (function($, DX, undefined) {
  11260. var touchEventHook = {
  11261. filter: function(event, originalEvent) {
  11262. var touches = originalEvent.touches.length ? originalEvent.touches : originalEvent.changedTouches;
  11263. $.each(["pageX", "pageY", "screenX", "screenY", "clientX", "clientY"], function() {
  11264. event[this] = touches[0][this]
  11265. });
  11266. return event
  11267. },
  11268. props: $.event.mouseHooks.props.concat(["touches", "changedTouches", "targetTouches", "detail", "result", "originalTarget", "charCode", "prevValue"])
  11269. };
  11270. $.each(["touchstart", "touchmove", "touchend", "touchcancel"], function() {
  11271. $.event.fixHooks[this] = touchEventHook
  11272. })
  11273. })(jQuery, DevExpress);
  11274. /*! Module core, file ui.events.pointer.mspointerHooks.js */
  11275. (function($, DX, undefined) {
  11276. var POINTER_TYPE_MAP = {
  11277. 2: "touch",
  11278. 3: "pen",
  11279. 4: "mouse"
  11280. };
  11281. var pointerEventHook = {
  11282. filter: function(event, originalEvent) {
  11283. var pointerType = originalEvent.pointerType;
  11284. if ($.isNumeric(pointerType))
  11285. event.pointerType = POINTER_TYPE_MAP[pointerType];
  11286. return event
  11287. },
  11288. props: $.event.mouseHooks.props.concat(["pointerId", "pointerType", "originalTarget", "width", "height", "pressure", "result", "tiltX", "charCode", "tiltY", "detail", "isPrimary", "prevValue"])
  11289. };
  11290. $.each(["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel", "MSPointerOver", "MSPointerOut", "mouseenter", "mouseleave", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave"], function() {
  11291. $.event.fixHooks[this] = pointerEventHook
  11292. })
  11293. })(jQuery, DevExpress);
  11294. /*! Module core, file ui.events.pointer.base.js */
  11295. (function($, DX, undefined) {
  11296. var ui = DX.ui,
  11297. events = ui.events;
  11298. var POINTER_EVENTS_NAMESPACE = "dxPointerEvents";
  11299. var BaseStrategy = DX.Class.inherit({
  11300. ctor: function(eventName, originalEvents) {
  11301. this._eventName = eventName;
  11302. this._eventNamespace = [POINTER_EVENTS_NAMESPACE, ".", this._eventName].join("");
  11303. this._originalEvents = originalEvents;
  11304. this._handlerCount = 0;
  11305. this.noBubble = this._isNoBubble()
  11306. },
  11307. _isNoBubble: function() {
  11308. var eventName = this._eventName;
  11309. return eventName === "dxpointerenter" || eventName === "dxpointerleave"
  11310. },
  11311. _handler: function(e) {
  11312. var delegateTarget = this._getDelegateTarget(e);
  11313. return this._fireEvent({
  11314. type: this._eventName,
  11315. pointerType: e.pointerType || events.eventSource(e),
  11316. originalEvent: e,
  11317. delegateTarget: delegateTarget
  11318. })
  11319. },
  11320. _getDelegateTarget: function(e) {
  11321. var delegateTarget;
  11322. if (this.noBubble)
  11323. delegateTarget = e.delegateTarget;
  11324. return delegateTarget
  11325. },
  11326. _fireEvent: function(args) {
  11327. return events.fireEvent(args)
  11328. },
  11329. setup: function() {
  11330. return true
  11331. },
  11332. add: function(element, handleObj) {
  11333. if (this._handlerCount <= 0 || this.noBubble) {
  11334. this._selector = handleObj.selector;
  11335. element = this.noBubble ? element : document;
  11336. $(element).on(events.addNamespace(this._originalEvents, this._eventNamespace), this._selector, $.proxy(this._handler, this))
  11337. }
  11338. if (!this.noBubble)
  11339. this._handlerCount++
  11340. },
  11341. remove: function(element) {
  11342. if (!this.noBubble)
  11343. this._handlerCount--
  11344. },
  11345. teardown: function(element) {
  11346. if (this._handlerCount && !this.noBubble)
  11347. return;
  11348. element = this.noBubble ? element : document;
  11349. $(element).off("." + this._eventNamespace, this._selector)
  11350. },
  11351. dispose: function(element) {
  11352. element = this.noBubble ? element : document;
  11353. $(element).off("." + this._eventNamespace)
  11354. }
  11355. });
  11356. events.pointer = {};
  11357. events.pointer.BaseStrategy = BaseStrategy
  11358. })(jQuery, DevExpress);
  11359. /*! Module core, file ui.events.pointer.mouse.js */
  11360. (function($, DX, undefined) {
  11361. var ui = DX.ui,
  11362. events = ui.events,
  11363. pointer = events.pointer;
  11364. var MouseStrategyEventMap = {
  11365. dxpointerdown: "mousedown",
  11366. dxpointermove: "mousemove",
  11367. dxpointerup: "mouseup",
  11368. dxpointercancel: "",
  11369. dxpointerover: "mouseover",
  11370. dxpointerout: "mouseout",
  11371. dxpointerenter: "mouseenter",
  11372. dxpointerleave: "mouseleave"
  11373. };
  11374. var normalizeMouseEvent = function(e) {
  11375. var pointers = [];
  11376. e.pointerId = 1;
  11377. if (e.type !== "mouseup")
  11378. pointers.push(e);
  11379. return {
  11380. pointers: pointers,
  11381. pointerId: 1
  11382. }
  11383. };
  11384. var MouseStrategy = pointer.BaseStrategy.inherit({_fireEvent: function(args) {
  11385. return this.callBase($.extend(normalizeMouseEvent(args.originalEvent), args))
  11386. }});
  11387. pointer.mouse = {
  11388. strategy: MouseStrategy,
  11389. map: MouseStrategyEventMap,
  11390. normalize: normalizeMouseEvent
  11391. }
  11392. })(jQuery, DevExpress);
  11393. /*! Module core, file ui.events.pointer.touch.js */
  11394. (function($, DX, undefined) {
  11395. var ui = DX.ui,
  11396. device = $.proxy(DX.devices.real, DX.devices),
  11397. events = ui.events,
  11398. pointer = events.pointer;
  11399. var TouchStrategyEventMap = {
  11400. dxpointerdown: "touchstart",
  11401. dxpointermove: "touchmove",
  11402. dxpointerup: "touchend",
  11403. dxpointercancel: "touchcancel"
  11404. };
  11405. var normalizeTouchEvent = function(e) {
  11406. var pointers = [];
  11407. $.each(e.touches, function(_, touch) {
  11408. pointers.push($.extend({pointerId: touch.identifier}, touch))
  11409. });
  11410. return {
  11411. pointers: pointers,
  11412. pointerId: e.changedTouches[0].identifier
  11413. }
  11414. };
  11415. var skipTouchWithSameIdentifier = function(pointerEvent) {
  11416. return device().platform === "ios" && (pointerEvent === "dxpointerdown" || pointerEvent === "dxpointerup")
  11417. };
  11418. var TouchStrategy = pointer.BaseStrategy.inherit({
  11419. ctor: function() {
  11420. this.callBase.apply(this, arguments);
  11421. this._pointerId = 0
  11422. },
  11423. _handler: function(e) {
  11424. if (skipTouchWithSameIdentifier(this._eventName)) {
  11425. var touch = e.changedTouches[0];
  11426. if (this._pointerId === touch.identifier && this._pointerId !== 0)
  11427. return;
  11428. this._pointerId = touch.identifier
  11429. }
  11430. return this.callBase.apply(this, arguments)
  11431. },
  11432. _fireEvent: function(args) {
  11433. return this.callBase($.extend(normalizeTouchEvent(args.originalEvent), args))
  11434. }
  11435. });
  11436. pointer.touch = {
  11437. strategy: TouchStrategy,
  11438. map: TouchStrategyEventMap,
  11439. normalize: normalizeTouchEvent
  11440. }
  11441. })(jQuery, DevExpress);
  11442. /*! Module core, file ui.events.pointer.mouseAndTouch.js */
  11443. (function($, DX, undefined) {
  11444. var ui = DX.ui,
  11445. events = ui.events,
  11446. pointer = events.pointer;
  11447. var MouseAndTouchStrategyEventMap = {
  11448. dxpointerdown: "touchstart mousedown",
  11449. dxpointermove: "touchmove mousemove",
  11450. dxpointerup: "touchend mouseup",
  11451. dxpointercancel: "touchcancel",
  11452. dxpointerover: "mouseover",
  11453. dxpointerout: "mouseout",
  11454. dxpointerenter: "mouseenter",
  11455. dxpointerleave: "mouseleave"
  11456. };
  11457. var MouseAndTouchStrategy = pointer.BaseStrategy.inherit({
  11458. EVENT_LOCK_TIMEOUT: 100,
  11459. _handler: function(e) {
  11460. var isMouseEvent = events.isMouseEvent(e);
  11461. if (!isMouseEvent)
  11462. this._skipNextEvents = true;
  11463. if (isMouseEvent && this._mouseLocked)
  11464. return;
  11465. if (isMouseEvent && this._skipNextEvents) {
  11466. this._skipNextEvents = false;
  11467. this._mouseLocked = true;
  11468. clearTimeout(this._unlockMouseTimer);
  11469. this._unlockMouseTimer = setTimeout($.proxy(function() {
  11470. this._mouseLocked = false
  11471. }, this), this.EVENT_LOCK_TIMEOUT);
  11472. return
  11473. }
  11474. return this.callBase(e)
  11475. },
  11476. _fireEvent: function(args) {
  11477. var isMouseEvent = events.isMouseEvent(args.originalEvent),
  11478. normalizer = isMouseEvent ? pointer.mouse.normalize : pointer.touch.normalize;
  11479. return this.callBase($.extend(normalizer(args.originalEvent), args))
  11480. },
  11481. dispose: function() {
  11482. this.callBase();
  11483. this._skipNextEvents = false;
  11484. this._mouseLocked = false;
  11485. clearTimeout(this._unlockMouseTimer)
  11486. }
  11487. });
  11488. pointer.mouseAndTouch = {
  11489. strategy: MouseAndTouchStrategy,
  11490. map: MouseAndTouchStrategyEventMap
  11491. }
  11492. })(jQuery, DevExpress);
  11493. /*! Module core, file ui.events.pointer.mspointer.js */
  11494. (function($, DX, undefined) {
  11495. var ui = DX.ui,
  11496. events = ui.events,
  11497. pointer = events.pointer;
  11498. var MsPointerStrategyEventMap = {
  11499. dxpointerdown: "MSPointerDown pointerdown",
  11500. dxpointermove: "MSPointerMove pointermove",
  11501. dxpointerup: "MSPointerUp pointerup",
  11502. dxpointercancel: "MSPointerCancel pointercancel",
  11503. dxpointerover: "MSPointerOver pointerover",
  11504. dxpointerout: "MSPointerOut pointerout",
  11505. dxpointerenter: "mouseenter",
  11506. dxpointerleave: "mouseleave"
  11507. };
  11508. var pointers = [];
  11509. var getPointerIndex = function(e) {
  11510. var index = -1;
  11511. $.each(pointers, function(i, pointer) {
  11512. if (e.pointerId === pointer.pointerId) {
  11513. index = i;
  11514. return true
  11515. }
  11516. });
  11517. return index
  11518. };
  11519. var addPointer = function(e) {
  11520. if (getPointerIndex(e) === -1)
  11521. pointers.push(e)
  11522. };
  11523. var removePointer = function(e) {
  11524. pointers.splice(getPointerIndex(e), 1)
  11525. };
  11526. var updatePointer = function(e) {
  11527. pointers[getPointerIndex(e)] = e
  11528. };
  11529. var addEventsListner = function(events, handler) {
  11530. events = events.split(" ");
  11531. $.each(events, function(_, event) {
  11532. document.addEventListener(event, handler, true)
  11533. })
  11534. };
  11535. var activateMspointerStrategy = function() {
  11536. var eventMap = MsPointerStrategyEventMap;
  11537. addEventsListner(eventMap.dxpointerdown, addPointer);
  11538. addEventsListner(eventMap.dxpointermove, updatePointer);
  11539. addEventsListner(eventMap.dxpointerup, removePointer);
  11540. addEventsListner(eventMap.dxpointercancel, removePointer);
  11541. activateMspointerStrategy = $.noop
  11542. };
  11543. var MsPointerStrategy = pointer.BaseStrategy.inherit({
  11544. ctor: function() {
  11545. this.callBase.apply(this, arguments);
  11546. activateMspointerStrategy()
  11547. },
  11548. _fireEvent: function(args) {
  11549. return this.callBase($.extend({
  11550. pointers: pointers,
  11551. pointerId: args.originalEvent.pointerId
  11552. }, args))
  11553. }
  11554. });
  11555. pointer.msPointer = {
  11556. strategy: MsPointerStrategy,
  11557. map: MsPointerStrategyEventMap
  11558. };
  11559. DX.ui.events.__internals = DX.ui.events.__internals || {};
  11560. $.extend(DX.ui.events.__internals, {cleanMsPointers: function() {
  11561. pointers = []
  11562. }})
  11563. })(jQuery, DevExpress);
  11564. /*! Module core, file ui.events.pointer.js */
  11565. (function($, DX, undefined) {
  11566. var ui = DX.ui,
  11567. support = DX.support,
  11568. device = $.proxy(DX.devices.real, DX.devices),
  11569. events = ui.events,
  11570. pointer = events.pointer;
  11571. var eventType = function() {
  11572. if (support.pointer)
  11573. return pointer.msPointer;
  11574. if (support.touch && !(device().tablet || device().phone))
  11575. return pointer.mouseAndTouch;
  11576. if (support.touch)
  11577. return pointer.touch;
  11578. return pointer.mouse
  11579. }();
  11580. $.each(eventType.map, function(pointerEvent, originalEvents) {
  11581. events.registerEvent(pointerEvent, new eventType.strategy(pointerEvent, originalEvents))
  11582. })
  11583. })(jQuery, DevExpress);
  11584. /*! Module core, file ui.events.wheel.js */
  11585. (function($, DX, undefined) {
  11586. var ui = DX.ui,
  11587. events = ui.events;
  11588. var EVENT_NAME = "dxmousewheel",
  11589. EVENT_NAMESPACE = "dxWheel";
  11590. $.event.fixHooks["wheel"] = $.event.mouseHooks;
  11591. var wheelEvent = document.onmousewheel !== undefined ? "mousewheel" : "wheel";
  11592. var wheel = {
  11593. setup: function(element, data) {
  11594. var $element = $(element);
  11595. $element.on(events.addNamespace(wheelEvent, EVENT_NAMESPACE), $.proxy(wheel._wheelHandler, wheel))
  11596. },
  11597. teardown: function(element) {
  11598. var $element = $(element);
  11599. $element.off("." + EVENT_NAMESPACE)
  11600. },
  11601. _wheelHandler: function(e) {
  11602. var delta = this._getWheelDelta(e.originalEvent);
  11603. events.fireEvent({
  11604. type: EVENT_NAME,
  11605. originalEvent: e,
  11606. delta: delta,
  11607. pointerType: "mouse"
  11608. });
  11609. e.stopPropagation()
  11610. },
  11611. _getWheelDelta: function(event) {
  11612. return event.wheelDelta ? event.wheelDelta : -event.deltaY * 30
  11613. }
  11614. };
  11615. events.registerEvent(EVENT_NAME, wheel)
  11616. })(jQuery, DevExpress);
  11617. /*! Module core, file ui.events.hover.js */
  11618. (function($, DX, undefined) {
  11619. var ui = DX.ui,
  11620. events = ui.events;
  11621. var HOVERSTART_NAMESPACE = "dxHoverStart",
  11622. HOVERSTART = "dxhoverstart",
  11623. POINTERENTER_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerenter", HOVERSTART_NAMESPACE),
  11624. POINTERDOWN_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerdown", HOVERSTART_NAMESPACE),
  11625. POINTERUP_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerup", HOVERSTART_NAMESPACE),
  11626. HOVEREND_NAMESPACE = "dxHoverEnd",
  11627. HOVEREND = "dxhoverend",
  11628. POINTERLEAVE_NAMESPACED_EVENT_NAME = events.addNamespace("dxpointerleave", HOVEREND_NAMESPACE);
  11629. var Hover = DX.Class.inherit({
  11630. noBubble: true,
  11631. add: function(element, handleObj) {
  11632. var $element = $(element);
  11633. $element.off("." + this._namespace).on(this._originalEventName, handleObj.selector, $.proxy(this._handler, this))
  11634. },
  11635. _handler: function(e) {
  11636. if (events.isTouchEvent(e))
  11637. return;
  11638. events.fireEvent({
  11639. type: this._eventName,
  11640. originalEvent: e,
  11641. delegateTarget: e.delegateTarget
  11642. })
  11643. },
  11644. teardown: function(element) {
  11645. $(element).off("." + this._namespace)
  11646. }
  11647. });
  11648. var HoverStart = Hover.inherit({
  11649. ctor: function() {
  11650. this._eventName = HOVERSTART;
  11651. this._originalEventName = POINTERENTER_NAMESPACED_EVENT_NAME;
  11652. this._namespace = HOVERSTART_NAMESPACE;
  11653. this._isMouseDown = false;
  11654. this._eventsAttached = 0
  11655. },
  11656. _handler: function(e) {
  11657. if (!this._isMouseDown)
  11658. this.callBase.apply(this, arguments)
  11659. },
  11660. setup: function() {
  11661. $(document).off("." + HOVERSTART_NAMESPACE).on(POINTERDOWN_NAMESPACED_EVENT_NAME, $.proxy(function() {
  11662. this._isMouseDown = true
  11663. }, this)).on(POINTERUP_NAMESPACED_EVENT_NAME, $.proxy(function() {
  11664. this._isMouseDown = false
  11665. }, this));
  11666. this._eventsAttached++
  11667. },
  11668. teardown: function() {
  11669. this._eventsAttached--;
  11670. if (this._eventsAttached === 0)
  11671. $(document).off("." + HOVERSTART_NAMESPACE)
  11672. }
  11673. });
  11674. var HoverEnd = Hover.inherit({ctor: function() {
  11675. this._eventName = HOVEREND;
  11676. this._originalEventName = POINTERLEAVE_NAMESPACED_EVENT_NAME;
  11677. this._namespace = HOVEREND_NAMESPACE
  11678. }});
  11679. events.registerEvent(HOVERSTART, new HoverStart);
  11680. events.registerEvent(HOVEREND, new HoverEnd)
  11681. })(jQuery, DevExpress);
  11682. /*! Module core, file ui.events.manager.js */
  11683. (function($, DX, undefined) {
  11684. var ui = DX.ui,
  11685. events = ui.events;
  11686. var MANAGER_EVENT = "dxEventManager",
  11687. EMITTER_DATA = "dxEmitter";
  11688. var EventManager = DX.Class.inherit({
  11689. ctor: function() {
  11690. this._attachHandlers();
  11691. this.reset();
  11692. this._proxiedCancelHandler = $.proxy(this._cancelHandler, this);
  11693. this._proxiedAcceptHandler = $.proxy(this._acceptHandler, this)
  11694. },
  11695. _attachHandlers: function() {
  11696. $(document).on(events.addNamespace("dxpointerdown", MANAGER_EVENT), $.proxy(this._pointerDownHandler, this)).on(events.addNamespace("dxpointermove", MANAGER_EVENT), $.proxy(this._pointerMoveHandler, this)).on(events.addNamespace("dxpointerup dxpointercancel", MANAGER_EVENT), $.proxy(this._pointerUpHandler, this)).on(events.addNamespace("dxmousewheel", MANAGER_EVENT), $.proxy(this._mouseWheelHandler, this))
  11697. },
  11698. _eachEmitter: function(callback) {
  11699. var activeEmitters = this._activeEmitters || [];
  11700. var i = 0;
  11701. while (activeEmitters.length > i) {
  11702. var emitter = activeEmitters[i];
  11703. if (callback(emitter) === false)
  11704. break;
  11705. if (activeEmitters[i] === emitter)
  11706. i++
  11707. }
  11708. },
  11709. _applyToEmitters: function(method, arg) {
  11710. this._eachEmitter(function(emitter) {
  11711. emitter[method].call(emitter, arg)
  11712. })
  11713. },
  11714. reset: function() {
  11715. this._eachEmitter(this._proxiedCancelHandler);
  11716. this._activeEmitters = []
  11717. },
  11718. resetEmitter: function(emitter) {
  11719. this._proxiedCancelHandler(emitter)
  11720. },
  11721. _pointerDownHandler: function(e) {
  11722. if (events.isMouseEvent(e) && e.which > 1)
  11723. return;
  11724. this._updateEmitters(e)
  11725. },
  11726. _updateEmitters: function(e) {
  11727. if (!this._isSetChanged(e))
  11728. return;
  11729. this._cleanEmitters(e);
  11730. this._fetchEmitters(e)
  11731. },
  11732. _isSetChanged: function(e) {
  11733. var currentSet = this._closestEmitter(e);
  11734. var previousSet = this._emittersSet || [];
  11735. var setChanged = currentSet.length !== previousSet.length;
  11736. $.each(currentSet, function(index, emitter) {
  11737. setChanged = setChanged || previousSet[index] !== emitter;
  11738. return !setChanged
  11739. });
  11740. this._emittersSet = currentSet;
  11741. return setChanged
  11742. },
  11743. _closestEmitter: function(e) {
  11744. var that = this,
  11745. result = [],
  11746. $element = $(e.target);
  11747. function handleEmitter(_, emitter) {
  11748. if (!!emitter && emitter.validatePointers(e) && emitter.validate(e)) {
  11749. emitter.addCancelCallback(that._proxiedCancelHandler);
  11750. emitter.addAcceptCallback(that._proxiedAcceptHandler);
  11751. result.push(emitter)
  11752. }
  11753. }
  11754. while ($element.length) {
  11755. var emitters = $.data($element.get(0), EMITTER_DATA) || [];
  11756. $.each(emitters, handleEmitter);
  11757. $element = $element.parent()
  11758. }
  11759. return result
  11760. },
  11761. _acceptHandler: function(acceptedEmitter, e) {
  11762. var that = this;
  11763. this._eachEmitter(function(emitter) {
  11764. if (emitter !== acceptedEmitter)
  11765. that._cancelEmitter(emitter, e)
  11766. })
  11767. },
  11768. _cancelHandler: function(canceledEmitter, e) {
  11769. this._cancelEmitter(canceledEmitter, e)
  11770. },
  11771. _cancelEmitter: function(emitter, e) {
  11772. var activeEmitters = this._activeEmitters;
  11773. if (e)
  11774. emitter.cancel(e);
  11775. else
  11776. emitter.reset();
  11777. emitter.removeCancelCallback();
  11778. emitter.removeAcceptCallback();
  11779. var emitterIndex = $.inArray(emitter, activeEmitters);
  11780. if (emitterIndex > -1)
  11781. activeEmitters.splice(emitterIndex, 1)
  11782. },
  11783. _cleanEmitters: function(e) {
  11784. this._applyToEmitters("end", e);
  11785. this.reset(e)
  11786. },
  11787. _fetchEmitters: function(e) {
  11788. this._activeEmitters = this._emittersSet.slice();
  11789. this._applyToEmitters("start", e)
  11790. },
  11791. _pointerMoveHandler: function(e) {
  11792. this._applyToEmitters("move", e)
  11793. },
  11794. _pointerUpHandler: function(e) {
  11795. this._updateEmitters(e)
  11796. },
  11797. _mouseWheelHandler: function(e) {
  11798. var allowInterruption = true;
  11799. this._eachEmitter(function(emitter) {
  11800. allowInterruption = emitter.allowInterruptionByMousewheel() && allowInterruption;
  11801. return allowInterruption
  11802. });
  11803. if (!allowInterruption)
  11804. return;
  11805. e.pointers = [null];
  11806. this._pointerDownHandler(e);
  11807. this._eachEmitter(function(emitter) {
  11808. var direction = emitter.getDirection ? emitter.getDirection(e) : "",
  11809. prop = direction !== "horizontal" ? "pageY" : "pageX";
  11810. if (direction)
  11811. e[prop] += e.delta;
  11812. return !direction
  11813. });
  11814. this._pointerMoveHandler(e);
  11815. e.pointers = [];
  11816. this._pointerUpHandler(e)
  11817. },
  11818. isActive: function(element) {
  11819. var result = false;
  11820. this._eachEmitter(function(emitter) {
  11821. result = result || emitter.getElement().is(element)
  11822. });
  11823. return result
  11824. }
  11825. });
  11826. var eventManager = new EventManager;
  11827. var EMITTER_SUBSCRIPTION_DATA = "dxEmitterSubscription";
  11828. var registerEmitter = function(emitterConfig) {
  11829. var emitterClass = emitterConfig.emitter,
  11830. emitterName = emitterConfig.events[0],
  11831. emitterEvents = emitterConfig.events;
  11832. $.each(emitterEvents, function(_, eventName) {
  11833. events.registerEvent(eventName, {
  11834. noBubble: !emitterConfig.bubble,
  11835. setup: function(element, data) {
  11836. var subscriptions = $.data(element, EMITTER_SUBSCRIPTION_DATA) || {},
  11837. emitters = $.data(element, EMITTER_DATA) || {},
  11838. emitter = emitters[emitterName] || new emitterClass(element);
  11839. subscriptions[eventName] = true;
  11840. emitters[emitterName] = emitter;
  11841. $.data(element, EMITTER_DATA, emitters);
  11842. $.data(element, EMITTER_SUBSCRIPTION_DATA, subscriptions)
  11843. },
  11844. add: function(element, handleObj) {
  11845. var emitters = $.data(element, EMITTER_DATA),
  11846. emitter = emitters[emitterName];
  11847. emitter.configurate($.extend({delegateSelector: handleObj.selector}, handleObj.data), handleObj.type)
  11848. },
  11849. teardown: function(element) {
  11850. var subscriptions = $.data(element, EMITTER_SUBSCRIPTION_DATA),
  11851. emitters = $.data(element, EMITTER_DATA),
  11852. emitter = emitters[emitterName];
  11853. delete subscriptions[eventName];
  11854. var disposeEmitter = true;
  11855. $.each(emitterEvents, function(_, eventName) {
  11856. disposeEmitter = disposeEmitter && !subscriptions[eventName];
  11857. return disposeEmitter
  11858. });
  11859. if (disposeEmitter) {
  11860. if (eventManager.isActive(element))
  11861. eventManager.resetEmitter(emitter);
  11862. emitter && emitter.dispose();
  11863. delete emitters[emitterName]
  11864. }
  11865. }
  11866. })
  11867. })
  11868. };
  11869. $.extend(events, {registerEmitter: registerEmitter})
  11870. })(jQuery, DevExpress);
  11871. /*! Module core, file ui.events.emitter.js */
  11872. (function($, DX, undefined) {
  11873. var ui = DX.ui,
  11874. events = ui.events;
  11875. var Emitter = DX.Class.inherit({
  11876. ctor: function(element) {
  11877. this._$element = $(element);
  11878. this._cancelCallback = $.Callbacks();
  11879. this._acceptCallback = $.Callbacks()
  11880. },
  11881. getElement: function() {
  11882. return this._$element
  11883. },
  11884. validate: function(e) {
  11885. return e.type !== "dxmousewheel"
  11886. },
  11887. validatePointers: function(e) {
  11888. return events.hasTouches(e) === 1
  11889. },
  11890. allowInterruptionByMousewheel: function() {
  11891. return true
  11892. },
  11893. configurate: function(data) {
  11894. $.extend(this, data)
  11895. },
  11896. addCancelCallback: function(callback) {
  11897. this._cancelCallback.add(callback)
  11898. },
  11899. removeCancelCallback: function() {
  11900. this._cancelCallback.empty()
  11901. },
  11902. _cancel: function(e) {
  11903. this._cancelCallback.fire(this, e)
  11904. },
  11905. addAcceptCallback: function(callback) {
  11906. this._acceptCallback.add(callback)
  11907. },
  11908. removeAcceptCallback: function() {
  11909. this._acceptCallback.empty()
  11910. },
  11911. _accept: function(e) {
  11912. this._acceptCallback.fire(this, e)
  11913. },
  11914. _requestAccept: function(e) {
  11915. this._acceptRequestEvent = e
  11916. },
  11917. _forgetAccept: function() {
  11918. this._accept(this._acceptRequestEvent);
  11919. this._acceptRequestEvent = null
  11920. },
  11921. start: $.noop,
  11922. move: $.noop,
  11923. end: $.noop,
  11924. cancel: $.noop,
  11925. reset: function() {
  11926. if (this._acceptRequestEvent)
  11927. this._accept(this._acceptRequestEvent)
  11928. },
  11929. _fireEvent: function(eventName, e, params) {
  11930. var eventData = $.extend({
  11931. type: eventName,
  11932. originalEvent: e,
  11933. target: this._getEmitterTarget(e),
  11934. delegateTarget: this.getElement().get(0)
  11935. }, params);
  11936. e = events.fireEvent(eventData);
  11937. if (e.cancel)
  11938. this._cancel(e);
  11939. return e
  11940. },
  11941. _getEmitterTarget: function(e) {
  11942. return (this.delegateSelector ? $(e.target).closest(this.delegateSelector) : this.getElement()).get(0)
  11943. },
  11944. dispose: $.noop
  11945. });
  11946. $.extend(events, {Emitter: Emitter})
  11947. })(jQuery, DevExpress);
  11948. /*! Module core, file ui.events.emitter.feedback.js */
  11949. (function($, DX, undefined) {
  11950. var ui = DX.ui,
  11951. events = ui.events,
  11952. ACTIVE_EVENT_NAME = "dxactive",
  11953. INACTIVE_EVENT_NAME = "dxinactive",
  11954. ACTIVE_TIMEOUT = 30,
  11955. INACTIVE_TIMEOUT = 400;
  11956. var activeEmitter;
  11957. var FeedbackEmitter = events.Emitter.inherit({
  11958. configurate: function(data, eventName) {
  11959. switch (eventName) {
  11960. case ACTIVE_EVENT_NAME:
  11961. data.activeTimeout = data.timeout;
  11962. break;
  11963. case INACTIVE_EVENT_NAME:
  11964. data.inactiveTimeout = data.timeout;
  11965. break
  11966. }
  11967. this.callBase(data)
  11968. },
  11969. start: function(e) {
  11970. var element = this.getElement().get(0);
  11971. var activeElement = activeEmitter && activeEmitter.getElement().get(0);
  11972. var activeChildExists = $.contains(element, activeElement);
  11973. var childJustActivated = activeEmitter && activeEmitter._activeTimer !== null;
  11974. if (activeChildExists && childJustActivated)
  11975. this._cancel();
  11976. else {
  11977. if (activeEmitter)
  11978. activeEmitter._forceInactiveTimer();
  11979. activeEmitter = this;
  11980. var eventTarget = this._getEmitterTarget(e);
  11981. this._forceActiveTimer = $.proxy(this._fireActive, this, e, eventTarget);
  11982. this._forceInactiveTimer = $.proxy(this._fireInctive, this, e, eventTarget);
  11983. this._startActiveTimer(e)
  11984. }
  11985. },
  11986. cancel: function(e) {
  11987. this.end(e)
  11988. },
  11989. end: function(e) {
  11990. var skipTimers = e.type !== "dxpointerup";
  11991. if (skipTimers)
  11992. this._stopActiveTimer();
  11993. else
  11994. this._forceActiveTimer();
  11995. this._startInactiveTimer(e);
  11996. if (skipTimers)
  11997. this._forceInactiveTimer()
  11998. },
  11999. dispose: function() {
  12000. this._stopActiveTimer();
  12001. this._stopInactiveTimer();
  12002. this.callBase()
  12003. },
  12004. _startActiveTimer: function(e) {
  12005. var activeTimeout = "activeTimeout" in this ? this.activeTimeout : ACTIVE_TIMEOUT;
  12006. this._activeTimer = window.setTimeout(this._forceActiveTimer, activeTimeout)
  12007. },
  12008. _fireActive: function(e, eventTarget) {
  12009. this._stopActiveTimer();
  12010. this._fireEvent(ACTIVE_EVENT_NAME, e, {target: eventTarget})
  12011. },
  12012. _stopActiveTimer: function() {
  12013. clearTimeout(this._activeTimer);
  12014. this._activeTimer = null
  12015. },
  12016. _forceActiveTimer: $.noop,
  12017. _startInactiveTimer: function(e) {
  12018. var inactiveTimeout = "inactiveTimeout" in this ? this.inactiveTimeout : INACTIVE_TIMEOUT;
  12019. this._inactiveTimer = window.setTimeout(this._forceInactiveTimer, inactiveTimeout)
  12020. },
  12021. _fireInctive: function(e, eventTarget) {
  12022. this._stopInactiveTimer();
  12023. activeEmitter = null;
  12024. this._fireEvent(INACTIVE_EVENT_NAME, e, {target: eventTarget})
  12025. },
  12026. _stopInactiveTimer: function() {
  12027. clearTimeout(this._inactiveTimer);
  12028. this._inactiveTimer = null
  12029. },
  12030. _forceInactiveTimer: $.noop,
  12031. lockInactive: function() {
  12032. this._forceActiveTimer();
  12033. this._stopInactiveTimer();
  12034. activeEmitter = null;
  12035. this._cancel();
  12036. return this._forceInactiveTimer
  12037. }
  12038. });
  12039. ui.events = $.extend(ui.events, {lockFeedback: function(deferred) {
  12040. var lockInactive = activeEmitter ? activeEmitter.lockInactive() : $.noop;
  12041. $.when(deferred).always(lockInactive)
  12042. }});
  12043. events.registerEmitter({
  12044. emitter: FeedbackEmitter,
  12045. events: [ACTIVE_EVENT_NAME, INACTIVE_EVENT_NAME]
  12046. })
  12047. })(jQuery, DevExpress);
  12048. /*! Module core, file ui.events.emitter.click.js */
  12049. (function($, DX, wnd, undefined) {
  12050. var ui = DX.ui,
  12051. utils = DX.utils,
  12052. events = ui.events,
  12053. abs = Math.abs,
  12054. CLICK_EVENT_NAME = "dxclick",
  12055. TOUCH_BOUNDARY = 10;
  12056. var isInput = function(element) {
  12057. return $(element).is("input, textarea, select, button ,:focus, :focus *")
  12058. };
  12059. var misc = {requestAnimationFrame: DX.requestAnimationFrame};
  12060. var ClickEmitter = events.Emitter.inherit({
  12061. ctor: function(element) {
  12062. this.callBase(element);
  12063. this._makeElementClickable($(element))
  12064. },
  12065. _makeElementClickable: function($element) {
  12066. if (!$element.attr("onclick"))
  12067. $element.attr("onclick", "void(0)")
  12068. },
  12069. start: function(e) {
  12070. this._blurPrevented = e.dxPreventBlur;
  12071. this._startTarget = e.target;
  12072. this._startEventData = events.eventData(e)
  12073. },
  12074. end: function(e) {
  12075. if (this._eventOutOfElement(e, this.getElement().get(0)) || e.type === "dxpointercancel") {
  12076. this._cancel(e);
  12077. return
  12078. }
  12079. if (!isInput(e.target) && !this._blurPrevented)
  12080. utils.resetActiveElement();
  12081. this._accept(e);
  12082. misc.requestAnimationFrame($.proxy(function() {
  12083. this._fireClickEvent(e)
  12084. }, this))
  12085. },
  12086. _eventOutOfElement: function(e, element) {
  12087. var target = e.target,
  12088. targetChanged = !$.contains(element, target) && element !== target,
  12089. gestureDelta = events.eventDelta(events.eventData(e), this._startEventData),
  12090. boundsExceeded = abs(gestureDelta.x) > TOUCH_BOUNDARY || abs(gestureDelta.y) > TOUCH_BOUNDARY;
  12091. return targetChanged || boundsExceeded
  12092. },
  12093. _fireClickEvent: function(e) {
  12094. this._fireEvent(CLICK_EVENT_NAME, e, {target: utils.closestCommonParent(this._startTarget, e.target)})
  12095. }
  12096. });
  12097. (function() {
  12098. var useNativeClick = DX.devices.real().generic;
  12099. if (useNativeClick) {
  12100. var prevented = null;
  12101. ClickEmitter = ClickEmitter.inherit({
  12102. start: function() {
  12103. prevented = null
  12104. },
  12105. end: $.noop,
  12106. cancel: function() {
  12107. prevented = true
  12108. }
  12109. });
  12110. var clickHandler = function(e) {
  12111. if ((!e.which || e.which === 1) && !prevented)
  12112. events.fireEvent({
  12113. type: CLICK_EVENT_NAME,
  12114. originalEvent: e
  12115. })
  12116. };
  12117. $(document).on(events.addNamespace("click", "NATIVE_DXCLICK_STRATEGY"), clickHandler)
  12118. }
  12119. $.extend(events.__internals, {useNativeClick: useNativeClick})
  12120. })();
  12121. (function() {
  12122. var fixBuggyInertia = DX.devices.real().ios;
  12123. if (fixBuggyInertia) {
  12124. var GESTURE_LOCK_KEY = "dxGestureLock";
  12125. ClickEmitter = ClickEmitter.inherit({_fireClickEvent: function(e) {
  12126. var $element = $(e.target);
  12127. while ($element.length) {
  12128. if ($.data($element.get(0), GESTURE_LOCK_KEY))
  12129. return;
  12130. $element = $element.parent()
  12131. }
  12132. this.callBase.apply(this, arguments)
  12133. }})
  12134. }
  12135. $.extend(events.__internals, {fixBuggyInertia: fixBuggyInertia})
  12136. })();
  12137. (function() {
  12138. var desktopDevice = DX.devices.real().generic;
  12139. if (!desktopDevice) {
  12140. var startTarget = null,
  12141. blurPrevented = false;
  12142. var pointerDownHandler = function(e) {
  12143. startTarget = e.target;
  12144. blurPrevented = e.dxPreventBlur
  12145. };
  12146. var clickHandler = function(e) {
  12147. var $target = $(e.target);
  12148. if (!blurPrevented && startTarget && !$target.is(startTarget) && !$(startTarget).is("label") && isInput($target))
  12149. utils.resetActiveElement();
  12150. startTarget = null;
  12151. blurPrevented = false
  12152. };
  12153. var NATIVE_CLICK_FIXER_NAMESPACE = "NATIVE_CLICK_FIXER";
  12154. $(document).on(events.addNamespace("dxpointerdown", NATIVE_CLICK_FIXER_NAMESPACE), pointerDownHandler).on(events.addNamespace("click", NATIVE_CLICK_FIXER_NAMESPACE), clickHandler)
  12155. }
  12156. })();
  12157. events.registerEmitter({
  12158. emitter: ClickEmitter,
  12159. bubble: true,
  12160. events: [CLICK_EVENT_NAME]
  12161. });
  12162. $.extend(events.__internals, {
  12163. useFastClick: !events.__internals.useNativeClick && !events.__internals.fixBuggyInertia,
  12164. misc: misc
  12165. })
  12166. })(jQuery, DevExpress, window);
  12167. /*! Module core, file ui.events.emitter.hold.js */
  12168. (function($, DX, undefined) {
  12169. var ui = DX.ui,
  12170. events = ui.events,
  12171. abs = Math.abs,
  12172. HOLD_EVENT_NAME = "dxhold",
  12173. HOLD_TIMEOUT = 750,
  12174. TOUCH_BOUNDARY = 5;
  12175. var HoldEmitter = events.Emitter.inherit({
  12176. start: function(e) {
  12177. this._startEventData = events.eventData(e);
  12178. this._startTimer(e)
  12179. },
  12180. _startTimer: function(e) {
  12181. var holdTimeout = "timeout" in this ? this.timeout : HOLD_TIMEOUT;
  12182. this._holdTimer = setTimeout($.proxy(function() {
  12183. this._requestAccept(e);
  12184. this._fireEvent(HOLD_EVENT_NAME, e, {target: e.target});
  12185. this._forgetAccept()
  12186. }, this), holdTimeout)
  12187. },
  12188. move: function(e) {
  12189. if (this._touchWasMoved(e))
  12190. this._cancel(e)
  12191. },
  12192. _touchWasMoved: function(e) {
  12193. var delta = events.eventDelta(this._startEventData, events.eventData(e));
  12194. return abs(delta.x) > TOUCH_BOUNDARY || abs(delta.y) > TOUCH_BOUNDARY
  12195. },
  12196. end: function() {
  12197. this._stopTimer()
  12198. },
  12199. _stopTimer: function() {
  12200. clearTimeout(this._holdTimer)
  12201. },
  12202. cancel: function() {
  12203. this._stopTimer()
  12204. }
  12205. });
  12206. events.registerEmitter({
  12207. emitter: HoldEmitter,
  12208. bubble: true,
  12209. events: [HOLD_EVENT_NAME]
  12210. })
  12211. })(jQuery, DevExpress);
  12212. /*! Module core, file ui.events.emitter.gesture.js */
  12213. (function($, DX, undefined) {
  12214. var ui = DX.ui,
  12215. utils = DX.utils,
  12216. events = ui.events,
  12217. devices = DX.devices,
  12218. support = DX.support,
  12219. abs = Math.abs;
  12220. var SLEEP = 0,
  12221. INITED = 1,
  12222. STARTED = 2,
  12223. TOUCH_BOUNDARY = 10,
  12224. IMMEDIATE_TOUCH_BOUNDARY = 0,
  12225. IMMEDIATE_TIMEOUT = 180;
  12226. var isMousewheelEvent = function(e) {
  12227. return e && e.type === "dxmousewheel"
  12228. };
  12229. var GestureEmitter = events.Emitter.inherit({
  12230. configurate: function(data) {
  12231. this.getElement().css("msTouchAction", data.immediate ? "pinch-zoom" : "");
  12232. this.callBase(data)
  12233. },
  12234. allowInterruptionByMousewheel: function() {
  12235. return this._stage !== STARTED
  12236. },
  12237. getDirection: function() {
  12238. return this.direction
  12239. },
  12240. _cancel: function(e) {
  12241. this.callBase.apply(this, arguments);
  12242. this._togglePointerAddons(true);
  12243. this._stage = SLEEP
  12244. },
  12245. start: function(e) {
  12246. if (events.needSkipEvent(e)) {
  12247. this._cancel(e);
  12248. return
  12249. }
  12250. this._startEvent = events.createEvent(e);
  12251. this._startEventData = events.eventData(e);
  12252. this._prevEventData = this._startEventData;
  12253. this._stage = INITED;
  12254. this._init(e);
  12255. this._setupImmediateTimer()
  12256. },
  12257. _setupImmediateTimer: function() {
  12258. clearTimeout(this._immediateTimer);
  12259. this._immedeateAccepted = false;
  12260. if (!this.immediate)
  12261. return;
  12262. this._immediateTimer = setTimeout($.proxy(function() {
  12263. this._immedeateAccepted = true
  12264. }, this), IMMEDIATE_TIMEOUT)
  12265. },
  12266. move: function(e) {
  12267. if (this._stage === INITED && this._directionConfirmed(e)) {
  12268. this._stage = STARTED;
  12269. this._resetActiveElement();
  12270. this._togglePointerAddons(false, e);
  12271. this._clearSelection(e);
  12272. this._adjustStartEvent(e);
  12273. this._start(this._startEvent);
  12274. this._prevEventData = events.eventData(this._startEvent);
  12275. if (this._stage === SLEEP)
  12276. return;
  12277. this._requestAccept(e);
  12278. this._move(e);
  12279. this._forgetAccept()
  12280. }
  12281. else if (this._stage === STARTED)
  12282. this._move(e);
  12283. this._prevEventData = events.eventData(e)
  12284. },
  12285. _directionConfirmed: function(e) {
  12286. var touchBoundary = this._getTouchBoundary(e),
  12287. delta = events.eventDelta(this._startEventData, events.eventData(e)),
  12288. deltaX = abs(delta.x),
  12289. deltaY = abs(delta.y);
  12290. var horizontalMove = this._validateMove(touchBoundary, deltaX, deltaY),
  12291. verticalMove = this._validateMove(touchBoundary, deltaY, deltaX);
  12292. var direction = this.getDirection(e),
  12293. bothAccepted = direction === "both" && (horizontalMove || verticalMove),
  12294. horizontalAccepted = direction === "horizontal" && horizontalMove,
  12295. verticalAccepted = direction === "vertical" && verticalMove;
  12296. return bothAccepted || horizontalAccepted || verticalAccepted || this._immedeateAccepted
  12297. },
  12298. _validateMove: function(touchBoundary, mainAxis, crossAxis) {
  12299. return mainAxis && mainAxis >= touchBoundary && (this.immediate ? mainAxis >= crossAxis : true)
  12300. },
  12301. _getTouchBoundary: function(e) {
  12302. return this.immediate || isMousewheelEvent(e) ? IMMEDIATE_TOUCH_BOUNDARY : TOUCH_BOUNDARY
  12303. },
  12304. _adjustStartEvent: function(e) {
  12305. var touchBoundary = this._getTouchBoundary(e),
  12306. delta = events.eventDelta(this._startEventData, events.eventData(e));
  12307. this._startEvent.pageX += utils.sign(delta.x) * touchBoundary;
  12308. this._startEvent.pageY += utils.sign(delta.y) * touchBoundary
  12309. },
  12310. _resetActiveElement: function() {
  12311. if (devices.real().platform === "ios" && $(":focus", this.getElement()).length)
  12312. utils.resetActiveElement()
  12313. },
  12314. _togglePointerAddons: function(toggle, e) {
  12315. var isStarted = this._stage === STARTED;
  12316. if (isStarted) {
  12317. this._togglePointerInteration(toggle);
  12318. if (!isMousewheelEvent(e))
  12319. this._togglePointerCursor(toggle)
  12320. }
  12321. },
  12322. _togglePointerInteration: function(toggle) {
  12323. var isDesktop = devices.real().platform === "generic";
  12324. if (isDesktop) {
  12325. $("body").css("pointer-events", toggle ? "" : "none");
  12326. if (support.supportProp("user-select"))
  12327. $("body").css(support.styleProp("user-select"), toggle ? "" : "none")
  12328. }
  12329. },
  12330. _togglePointerCursor: function(toggle) {
  12331. if (toggle)
  12332. $("html").css("cursor", this._originalCursor);
  12333. else {
  12334. this._originalCursor = $("html").css("cursor");
  12335. $("html").css("cursor", this.getElement().css("cursor"))
  12336. }
  12337. },
  12338. _clearSelection: function(e) {
  12339. if (isMousewheelEvent(e) || events.isTouchEvent(e))
  12340. return;
  12341. utils.clearSelection()
  12342. },
  12343. end: function(e) {
  12344. this._togglePointerAddons(true, e);
  12345. if (this._stage === STARTED)
  12346. this._end(e);
  12347. else if (this._stage === INITED)
  12348. this._stop(e);
  12349. this._stage = SLEEP
  12350. },
  12351. dispose: function() {
  12352. clearTimeout(this._immediateTimer);
  12353. this.callBase.apply(this, arguments);
  12354. this._togglePointerAddons(true)
  12355. },
  12356. _init: $.noop,
  12357. _start: $.noop,
  12358. _move: $.noop,
  12359. _stop: $.noop,
  12360. _end: $.noop
  12361. });
  12362. $.extend(events, {GestureEmitter: GestureEmitter});
  12363. var ORIG_TOUCH_BOUNDARY = TOUCH_BOUNDARY;
  12364. $.extend(DX.ui.events.__internals, {
  12365. GESTURE_TOUCH_BOUNDARY: ORIG_TOUCH_BOUNDARY,
  12366. resetTouchBoundary: function() {
  12367. TOUCH_BOUNDARY = ORIG_TOUCH_BOUNDARY;
  12368. events.__internals.GESTURE_TOUCH_BOUNDARY = ORIG_TOUCH_BOUNDARY
  12369. },
  12370. cleanTouchBoundary: function() {
  12371. TOUCH_BOUNDARY = 0
  12372. }
  12373. })
  12374. })(jQuery, DevExpress);
  12375. /*! Module core, file ui.events.emitter.gesture.scroll.js */
  12376. (function($, DX, undefined) {
  12377. var ui = DX.ui,
  12378. events = ui.events;
  12379. var SCROLL_INIT_EVENT = "dxscrollinit",
  12380. SCROLL_START_EVENT = "dxscrollstart",
  12381. SCROLL_MOVE_EVENT = "dxscroll",
  12382. SCROLL_END_EVENT = "dxscrollend",
  12383. SCROLL_STOP_EVENT = "dxscrollstop",
  12384. SCROLL_CANCEL_EVENT = "dxscrollcancel",
  12385. INERTIA_TIMEOUT = 100,
  12386. VELOCITY_CALC_TIMEOUT = 200,
  12387. FRAME_DURATION = Math.round(1000 / 60),
  12388. GESTURE_LOCK_KEY = "dxGestureLock",
  12389. GESTURE_LOCK_TIMEOUT = 200,
  12390. NAMESPACED_SCROLL_EVENT = events.addNamespace("scroll", "dxScrollEmitter");
  12391. var ScrollEmitter = events.GestureEmitter.inherit({
  12392. ctor: function(element) {
  12393. this.callBase.apply(this, arguments);
  12394. this.direction = "both";
  12395. $.data(element, "scroll", $.proxy(this._treatScroll, this));
  12396. $(element).on(NAMESPACED_SCROLL_EVENT, $.proxy(this._treatScroll, this))
  12397. },
  12398. validate: function() {
  12399. return true
  12400. },
  12401. _domElement: function() {
  12402. return this.getElement().get(0)
  12403. },
  12404. _treatScroll: function() {
  12405. this._prepareGesture();
  12406. this._forgetGesture()
  12407. },
  12408. _prepareGesture: function() {
  12409. if (this._gestureEndTimer)
  12410. this._clearGestureTimer();
  12411. else
  12412. $.data(this._domElement(), GESTURE_LOCK_KEY, true)
  12413. },
  12414. _forgetGesture: function() {
  12415. var that = this;
  12416. this._gestureEndTimer = setTimeout(function() {
  12417. $.data(that._domElement(), GESTURE_LOCK_KEY, false);
  12418. that._gestureEndTimer = null
  12419. }, GESTURE_LOCK_TIMEOUT)
  12420. },
  12421. _init: function(e) {
  12422. if ($.data(this._domElement(), GESTURE_LOCK_KEY))
  12423. this._accept(e);
  12424. this._fireEvent(SCROLL_INIT_EVENT, e)
  12425. },
  12426. move: function(e) {
  12427. this.callBase.apply(this, arguments);
  12428. e.isScrollingEvent = this.isNative || e.isScrollingEvent
  12429. },
  12430. _start: function(e) {
  12431. this._savedEventData = events.eventData(e);
  12432. this._fireEvent(SCROLL_START_EVENT, e, {delta: events.eventDelta(this._savedEventData, events.eventData(e))})
  12433. },
  12434. _move: function(e) {
  12435. var currentEventData = events.eventData(e);
  12436. this._fireEvent(SCROLL_MOVE_EVENT, e, {delta: events.eventDelta(this._prevEventData, currentEventData)});
  12437. var eventDelta = events.eventDelta(this._savedEventData, currentEventData);
  12438. if (eventDelta.time > VELOCITY_CALC_TIMEOUT)
  12439. this._savedEventData = this._prevEventData
  12440. },
  12441. _end: function(e) {
  12442. var endEventDelta = events.eventDelta(this._prevEventData, events.eventData(e));
  12443. var velocity = {
  12444. x: 0,
  12445. y: 0
  12446. };
  12447. var isWheelEvent = e.type === "dxmousewheel";
  12448. if (endEventDelta.time < INERTIA_TIMEOUT) {
  12449. var deltaEventData = events.eventDelta(this._savedEventData, this._prevEventData);
  12450. velocity = {
  12451. x: isWheelEvent ? 0 : deltaEventData.x * FRAME_DURATION / deltaEventData.time,
  12452. y: isWheelEvent ? 0 : deltaEventData.y * FRAME_DURATION / deltaEventData.time
  12453. }
  12454. }
  12455. this._fireEvent(SCROLL_END_EVENT, e, {velocity: velocity})
  12456. },
  12457. _stop: function(e) {
  12458. this._fireEvent(SCROLL_STOP_EVENT, e)
  12459. },
  12460. cancel: function(e) {
  12461. this.callBase.apply(this, arguments);
  12462. this._fireEvent(SCROLL_CANCEL_EVENT, e)
  12463. },
  12464. dispose: function() {
  12465. this.callBase.apply(this, arguments);
  12466. $.data(this._domElement(), GESTURE_LOCK_KEY, false);
  12467. this._clearGestureTimer();
  12468. this.getElement().off(NAMESPACED_SCROLL_EVENT)
  12469. },
  12470. _clearGestureTimer: function() {
  12471. clearTimeout(this._gestureEndTimer);
  12472. this._gestureEndTimer = null
  12473. }
  12474. });
  12475. events.registerEmitter({
  12476. emitter: ScrollEmitter,
  12477. events: [SCROLL_INIT_EVENT, SCROLL_START_EVENT, SCROLL_MOVE_EVENT, SCROLL_END_EVENT, SCROLL_STOP_EVENT, SCROLL_CANCEL_EVENT]
  12478. })
  12479. })(jQuery, DevExpress);
  12480. /*! Module core, file ui.events.emitter.gesture.swipe.js */
  12481. (function($, DX, undefined) {
  12482. var ui = DX.ui,
  12483. events = ui.events,
  12484. SWIPE_START_EVENT = "dxswipestart",
  12485. SWIPE_EVENT = "dxswipe",
  12486. SWIPE_END_EVENT = "dxswipeend";
  12487. var HorizontalStrategy = {
  12488. defaultItemSizeFunc: function() {
  12489. return this.getElement().width()
  12490. },
  12491. getBounds: function() {
  12492. return [this._maxLeftOffset, this._maxRightOffset]
  12493. },
  12494. calcOffsetRatio: function(e) {
  12495. var endEventData = events.eventData(e);
  12496. return (endEventData.x - (this._savedEventData && this._savedEventData.x || 0)) / this._itemSizeFunc().call(this, e)
  12497. },
  12498. isFastSwipe: function(e) {
  12499. var endEventData = events.eventData(e);
  12500. return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.x - this._tickData.x) >= endEventData.time - this._tickData.time
  12501. }
  12502. };
  12503. var VerticalStrategy = {
  12504. defaultItemSizeFunc: function() {
  12505. return this.getElement().height()
  12506. },
  12507. getBounds: function() {
  12508. return [this._maxTopOffset, this._maxBottomOffset]
  12509. },
  12510. calcOffsetRatio: function(e) {
  12511. var endEventData = events.eventData(e);
  12512. return (endEventData.y - (this._savedEventData && this._savedEventData.y || 0)) / this._itemSizeFunc().call(this, e)
  12513. },
  12514. isFastSwipe: function(e) {
  12515. var endEventData = events.eventData(e);
  12516. return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.y - this._tickData.y) >= endEventData.time - this._tickData.time
  12517. }
  12518. };
  12519. var STRATEGIES = {
  12520. horizontal: HorizontalStrategy,
  12521. vertical: VerticalStrategy
  12522. };
  12523. var SwipeEmitter = events.GestureEmitter.inherit({
  12524. TICK_INTERVAL: 300,
  12525. FAST_SWIPE_SPEED_LIMIT: 5,
  12526. ctor: function(element) {
  12527. this.callBase(element);
  12528. this.direction = "horizontal";
  12529. this.elastic = true
  12530. },
  12531. _getStrategy: function() {
  12532. return STRATEGIES[this.direction]
  12533. },
  12534. _defaultItemSizeFunc: function() {
  12535. return this._getStrategy().defaultItemSizeFunc.call(this)
  12536. },
  12537. _itemSizeFunc: function() {
  12538. return this.itemSizeFunc || this._defaultItemSizeFunc
  12539. },
  12540. _start: function(e) {
  12541. this._savedEventData = events.eventData(e);
  12542. this._tickData = {time: 0};
  12543. e = this._fireEvent(SWIPE_START_EVENT, e);
  12544. if (!e.cancel) {
  12545. this._maxLeftOffset = e.maxLeftOffset;
  12546. this._maxRightOffset = e.maxRightOffset;
  12547. this._maxTopOffset = e.maxTopOffset;
  12548. this._maxBottomOffset = e.maxBottomOffset
  12549. }
  12550. },
  12551. _move: function(e) {
  12552. var strategy = this._getStrategy(),
  12553. moveEventData = events.eventData(e),
  12554. offset = strategy.calcOffsetRatio.call(this, e);
  12555. offset = this._fitOffset(offset, this.elastic);
  12556. if (moveEventData.time - this._tickData.time > this.TICK_INTERVAL)
  12557. this._tickData = moveEventData;
  12558. this._fireEvent(SWIPE_EVENT, e, {offset: offset});
  12559. e.preventDefault()
  12560. },
  12561. _end: function(e) {
  12562. var strategy = this._getStrategy(),
  12563. offsetRatio = strategy.calcOffsetRatio.call(this, e),
  12564. isFast = strategy.isFastSwipe.call(this, e),
  12565. startOffset = offsetRatio,
  12566. targetOffset = this._calcTargetOffset(offsetRatio, isFast);
  12567. startOffset = this._fitOffset(startOffset, this.elastic);
  12568. targetOffset = this._fitOffset(targetOffset, false);
  12569. this._fireEvent(SWIPE_END_EVENT, e, {
  12570. offset: startOffset,
  12571. targetOffset: targetOffset
  12572. })
  12573. },
  12574. _fitOffset: function(offset, elastic) {
  12575. var strategy = this._getStrategy(),
  12576. bounds = strategy.getBounds.call(this);
  12577. if (offset < -bounds[0])
  12578. return elastic ? (-2 * bounds[0] + offset) / 3 : -bounds[0];
  12579. if (offset > bounds[1])
  12580. return elastic ? (2 * bounds[1] + offset) / 3 : bounds[1];
  12581. return offset
  12582. },
  12583. _calcTargetOffset: function(offsetRatio, isFast) {
  12584. var result;
  12585. if (isFast) {
  12586. result = Math.ceil(Math.abs(offsetRatio));
  12587. if (offsetRatio < 0)
  12588. result = -result
  12589. }
  12590. else
  12591. result = Math.round(offsetRatio);
  12592. return result
  12593. }
  12594. });
  12595. events.registerEmitter({
  12596. emitter: SwipeEmitter,
  12597. events: [SWIPE_START_EVENT, SWIPE_EVENT, SWIPE_END_EVENT]
  12598. })
  12599. })(jQuery, DevExpress);
  12600. /*! Module core, file ui.events.emitter.gesture.drag.js */
  12601. (function($, DX, undefined) {
  12602. var ui = DX.ui,
  12603. utils = DX.utils,
  12604. events = ui.events,
  12605. wrapToArray = utils.wrapToArray;
  12606. var DRAG_START_EVENT = "dxdragstart",
  12607. DRAG_EVENT = "dxdrag",
  12608. DRAG_END_EVENT = "dxdragend",
  12609. DRAG_ENTER_EVENT = "dxdragenter",
  12610. DRAG_LEAVE_EVENT = "dxdragleave",
  12611. DROP_EVENT = "dxdrop";
  12612. var knownDropTargets = [],
  12613. knownDropTargetSelectors = [],
  12614. knownDropTargetConfigs = [];
  12615. var dropTargetRegistration = {
  12616. setup: function(element, data) {
  12617. var knownDropTarget = $.inArray(element, knownDropTargets) !== -1;
  12618. if (!knownDropTarget) {
  12619. knownDropTargets.push(element);
  12620. knownDropTargetSelectors.push([]);
  12621. knownDropTargetConfigs.push(data || {})
  12622. }
  12623. },
  12624. add: function(element, handleObj) {
  12625. var index = $.inArray(element, knownDropTargets);
  12626. var selector = handleObj.selector;
  12627. if ($.inArray(selector, knownDropTargetSelectors[index]) === -1)
  12628. knownDropTargetSelectors[index].push(selector)
  12629. },
  12630. teardown: function(element, data) {
  12631. var elementEvents = $._data(element, "events"),
  12632. handlersCount = 0;
  12633. $.each([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT], function(_, eventName) {
  12634. var eventHandlers = elementEvents[eventName];
  12635. if (eventHandlers)
  12636. handlersCount += eventHandlers.length
  12637. });
  12638. if (!handlersCount) {
  12639. var index = $.inArray(element, knownDropTargets);
  12640. knownDropTargets.splice(index, 1);
  12641. knownDropTargetSelectors.splice(index, 1);
  12642. knownDropTargetConfigs.splice(index, 1)
  12643. }
  12644. }
  12645. };
  12646. events.registerEvent(DRAG_ENTER_EVENT, dropTargetRegistration);
  12647. events.registerEvent(DRAG_LEAVE_EVENT, dropTargetRegistration);
  12648. events.registerEvent(DROP_EVENT, dropTargetRegistration);
  12649. var getItemDelegatedTargets = function($element) {
  12650. var dropTargetIndex = $.inArray($element.get(0), knownDropTargets),
  12651. dropTargetSelectors = knownDropTargetSelectors[dropTargetIndex];
  12652. var $delegatedTargets = $element.find(dropTargetSelectors.join(", "));
  12653. if ($.inArray(undefined, dropTargetSelectors) !== -1)
  12654. $delegatedTargets = $delegatedTargets.addBack();
  12655. return $delegatedTargets
  12656. };
  12657. var getItemConfig = function($element) {
  12658. var dropTargetIndex = $.inArray($element.get(0), knownDropTargets);
  12659. return knownDropTargetConfigs[dropTargetIndex]
  12660. };
  12661. var getItemPosition = function(dropTargetConfig, $element) {
  12662. if (dropTargetConfig.itemPositionFunc)
  12663. return dropTargetConfig.itemPositionFunc($element);
  12664. else
  12665. return $element.offset()
  12666. };
  12667. var getItemSize = function(dropTargetConfig, $element) {
  12668. if (dropTargetConfig.itemSizeFunc)
  12669. return dropTargetConfig.itemSizeFunc($element);
  12670. return {
  12671. width: $element.width(),
  12672. height: $element.height()
  12673. }
  12674. };
  12675. var DragEmitter = events.GestureEmitter.inherit({
  12676. ctor: function(element) {
  12677. this.callBase(element);
  12678. this.direction = "both"
  12679. },
  12680. _init: function(e) {
  12681. this._initEvent = e
  12682. },
  12683. _start: function(e) {
  12684. e = this._fireEvent(DRAG_START_EVENT, this._initEvent);
  12685. this._maxLeftOffset = e.maxLeftOffset;
  12686. this._maxRightOffset = e.maxRightOffset;
  12687. this._maxTopOffset = e.maxTopOffset;
  12688. this._maxBottomOffset = e.maxBottomOffset;
  12689. var dropTargets = wrapToArray(e.targetElements || (e.targetElements === null ? [] : knownDropTargets));
  12690. this._dropTargets = $.map(dropTargets, function(element) {
  12691. return $(element).get(0)
  12692. })
  12693. },
  12694. _move: function(e) {
  12695. var eventData = events.eventData(e),
  12696. dragOffset = this._calculateOffset(eventData);
  12697. this._fireEvent(DRAG_EVENT, e, {offset: dragOffset});
  12698. this._processDropTargets(e, dragOffset);
  12699. e.preventDefault()
  12700. },
  12701. _calculateOffset: function(eventData) {
  12702. return {
  12703. x: this._calculateXOffset(eventData),
  12704. y: this._calculateYOffset(eventData)
  12705. }
  12706. },
  12707. _calculateXOffset: function(eventData) {
  12708. if (this.direction !== "vertical") {
  12709. var offset = eventData.x - this._startEventData.x;
  12710. return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset)
  12711. }
  12712. return 0
  12713. },
  12714. _calculateYOffset: function(eventData) {
  12715. if (this.direction !== "horizontal") {
  12716. var offset = eventData.y - this._startEventData.y;
  12717. return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset)
  12718. }
  12719. return 0
  12720. },
  12721. _fitOffset: function(offset, minOffset, maxOffset) {
  12722. if (minOffset != null)
  12723. offset = Math.max(offset, -minOffset);
  12724. if (maxOffset != null)
  12725. offset = Math.min(offset, maxOffset);
  12726. return offset
  12727. },
  12728. _processDropTargets: function(e, dragOffset) {
  12729. var target = this._findDropTarget(e),
  12730. sameTarget = target === this._currentDropTarget;
  12731. if (!sameTarget) {
  12732. this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT);
  12733. this._currentDropTarget = target;
  12734. this._fireDropTargetEvent(e, DRAG_ENTER_EVENT)
  12735. }
  12736. },
  12737. _fireDropTargetEvent: function(event, eventName) {
  12738. if (!this._currentDropTarget)
  12739. return;
  12740. var eventData = {
  12741. type: eventName,
  12742. originalEvent: event,
  12743. draggingElement: this._$element.get(0),
  12744. target: this._currentDropTarget
  12745. };
  12746. events.fireEvent(eventData)
  12747. },
  12748. _findDropTarget: function(e) {
  12749. var that = this,
  12750. result;
  12751. $.each(knownDropTargets, function(_, target) {
  12752. if (!that._checkDropTargetActive(target))
  12753. return;
  12754. var $target = $(target);
  12755. $.each(getItemDelegatedTargets($target), function(_, delegatedTarget) {
  12756. var $delegatedTarget = $(delegatedTarget);
  12757. if (that._checkDropTarget(getItemConfig($target), $delegatedTarget, e))
  12758. result = delegatedTarget
  12759. })
  12760. });
  12761. return result
  12762. },
  12763. _checkDropTargetActive: function(target) {
  12764. var active = false;
  12765. $.each(this._dropTargets, function(_, activeTarget) {
  12766. active = active || activeTarget === target || $.contains(activeTarget, target);
  12767. return !active
  12768. });
  12769. return active
  12770. },
  12771. _checkDropTarget: function(config, $target, e) {
  12772. var isDraggingElement = $target.get(0) === this._$element.get(0);
  12773. if (isDraggingElement)
  12774. return false;
  12775. var targetPosition = getItemPosition(config, $target);
  12776. if (e.pageX < targetPosition.left)
  12777. return false;
  12778. if (e.pageY < targetPosition.top)
  12779. return false;
  12780. var targetSize = getItemSize(config, $target);
  12781. if (e.pageX > targetPosition.left + targetSize.width)
  12782. return false;
  12783. if (e.pageY > targetPosition.top + targetSize.height)
  12784. return false;
  12785. return $target
  12786. },
  12787. _end: function(e) {
  12788. var eventData = events.eventData(e);
  12789. this._fireEvent(DRAG_END_EVENT, e, {offset: this._calculateOffset(eventData)});
  12790. this._fireDropTargetEvent(e, DROP_EVENT);
  12791. delete this._currentDropTarget
  12792. }
  12793. });
  12794. events.registerEmitter({
  12795. emitter: DragEmitter,
  12796. events: [DRAG_START_EVENT, DRAG_EVENT, DRAG_END_EVENT]
  12797. });
  12798. DX.ui.events.__internals = DX.ui.events.__internals || {};
  12799. $.extend(DX.ui.events.__internals, {dropTargets: knownDropTargets})
  12800. })(jQuery, DevExpress);
  12801. /*! Module core, file ui.events.emitter.transform.js */
  12802. (function($, DX, undefined) {
  12803. var ui = DX.ui,
  12804. utils = DX.utils,
  12805. events = ui.events,
  12806. fitIntoRange = utils.fitIntoRange;
  12807. var DX_PREFIX = "dx",
  12808. TRANSFORM = "transform",
  12809. TRANSLATE = "translate",
  12810. ZOOM = "zoom",
  12811. PINCH = "pinch",
  12812. ROTATE = "rotate",
  12813. START_POSTFIX = "start",
  12814. UPDATE_POSTFIX = "",
  12815. END_POSTFIX = "end";
  12816. var eventAliases = [];
  12817. var addAlias = function(eventName, eventArgs) {
  12818. eventAliases.push({
  12819. name: eventName,
  12820. args: eventArgs
  12821. })
  12822. };
  12823. addAlias(TRANSFORM, {
  12824. scale: true,
  12825. deltaScale: true,
  12826. rotation: true,
  12827. deltaRotation: true,
  12828. translation: true,
  12829. deltaTranslation: true
  12830. });
  12831. addAlias(TRANSLATE, {
  12832. translation: true,
  12833. deltaTranslation: true
  12834. });
  12835. addAlias(ZOOM, {
  12836. scale: true,
  12837. deltaScale: true
  12838. });
  12839. addAlias(PINCH, {
  12840. scale: true,
  12841. deltaScale: true
  12842. });
  12843. addAlias(ROTATE, {
  12844. rotation: true,
  12845. deltaRotation: true
  12846. });
  12847. var getVector = function(first, second) {
  12848. return {
  12849. x: second.pageX - first.pageX,
  12850. y: -second.pageY + first.pageY,
  12851. centerX: (second.pageX + first.pageX) * 0.5,
  12852. centerY: (second.pageY + first.pageY) * 0.5
  12853. }
  12854. };
  12855. var getEventVector = function(e) {
  12856. var pointers = e.pointers;
  12857. return getVector(pointers[0], pointers[1])
  12858. };
  12859. var getDistance = function(vector) {
  12860. return Math.sqrt(vector.x * vector.x + vector.y * vector.y)
  12861. };
  12862. var getScale = function(firstVector, secondVector) {
  12863. return getDistance(firstVector) / getDistance(secondVector)
  12864. };
  12865. var getRotation = function(firstVector, secondVector) {
  12866. var scalarProduct = firstVector.x * secondVector.x + firstVector.y * secondVector.y;
  12867. var distanceProduct = getDistance(firstVector) * getDistance(secondVector);
  12868. if (distanceProduct === 0)
  12869. return 0;
  12870. var sign = utils.sign(firstVector.x * secondVector.y - secondVector.x * firstVector.y);
  12871. var angle = Math.acos(fitIntoRange(scalarProduct / distanceProduct, -1, 1));
  12872. return sign * angle
  12873. };
  12874. var getTranslation = function(firstVector, secondVector) {
  12875. return {
  12876. x: firstVector.centerX - secondVector.centerX,
  12877. y: firstVector.centerY - secondVector.centerY
  12878. }
  12879. };
  12880. var TransformEmitter = events.Emitter.inherit({
  12881. configurate: function(data, eventName) {
  12882. if (eventName.indexOf(ZOOM) > -1)
  12883. DX.log("W0005", eventName, "15.1", "Use '" + eventName.replace(ZOOM, PINCH) + "' event instead");
  12884. this.callBase(data)
  12885. },
  12886. validatePointers: function(e) {
  12887. return events.hasTouches(e) > 1
  12888. },
  12889. start: function(e) {
  12890. this._accept(e);
  12891. var startVector = getEventVector(e);
  12892. this._startVector = startVector;
  12893. this._prevVector = startVector;
  12894. this._fireEventAliases(START_POSTFIX, e)
  12895. },
  12896. move: function(e) {
  12897. var currentVector = getEventVector(e),
  12898. eventArgs = this._getEventArgs(currentVector);
  12899. this._fireEventAliases(UPDATE_POSTFIX, e, eventArgs);
  12900. this._prevVector = currentVector
  12901. },
  12902. end: function(e) {
  12903. var eventArgs = this._getEventArgs(this._prevVector);
  12904. this._fireEventAliases(END_POSTFIX, e, eventArgs)
  12905. },
  12906. _getEventArgs: function(vector) {
  12907. return {
  12908. scale: getScale(vector, this._startVector),
  12909. deltaScale: getScale(vector, this._prevVector),
  12910. rotation: getRotation(vector, this._startVector),
  12911. deltaRotation: getRotation(vector, this._prevVector),
  12912. translation: getTranslation(vector, this._startVector),
  12913. deltaTranslation: getTranslation(vector, this._prevVector)
  12914. }
  12915. },
  12916. _fireEventAliases: function(eventPostfix, originalEvent, eventArgs) {
  12917. eventArgs = eventArgs || {};
  12918. $.each(eventAliases, $.proxy(function(_, eventAlias) {
  12919. var args = {};
  12920. $.each(eventAlias.args, function(name) {
  12921. if (name in eventArgs)
  12922. args[name] = eventArgs[name]
  12923. });
  12924. this._fireEvent(DX_PREFIX + eventAlias.name + eventPostfix, originalEvent, args)
  12925. }, this))
  12926. }
  12927. });
  12928. events.registerEmitter({
  12929. emitter: TransformEmitter,
  12930. events: $.map(eventAliases, function(eventAlias) {
  12931. var eventNames = [];
  12932. $.each([START_POSTFIX, UPDATE_POSTFIX, END_POSTFIX], function(_, eventPostfix) {
  12933. eventNames.push(DX_PREFIX + eventAlias.name + eventPostfix)
  12934. });
  12935. return eventNames
  12936. })
  12937. })
  12938. })(jQuery, DevExpress);
  12939. /*! Module core, file ui.events.dblclick.js */
  12940. (function($, DX, undefined) {
  12941. var ui = DX.ui,
  12942. events = ui.events,
  12943. utils = DX.utils,
  12944. DBLCLICK_EVENT_NAME = "dxdblclick",
  12945. DBLCLICK_NAMESPACE = "dxDblClick",
  12946. NAMESPACED_CLICK_EVENT = events.addNamespace("dxclick", DBLCLICK_NAMESPACE),
  12947. DBLCLICK_TIMEOUT = 300;
  12948. var DblClick = DX.Class.inherit({
  12949. ctor: function() {
  12950. this._handlerCount = 0;
  12951. this._forgetLastClick()
  12952. },
  12953. _forgetLastClick: function() {
  12954. this._firstClickTarget = null;
  12955. this._lastClickTimeStamp = -DBLCLICK_TIMEOUT
  12956. },
  12957. add: function() {
  12958. if (this._handlerCount <= 0)
  12959. $(document).on(NAMESPACED_CLICK_EVENT, $.proxy(this._clickHandler, this));
  12960. this._handlerCount++
  12961. },
  12962. _clickHandler: function(e) {
  12963. var timeStamp = e.timeStamp || $.now();
  12964. if (timeStamp - this._lastClickTimeStamp < DBLCLICK_TIMEOUT) {
  12965. events.fireEvent({
  12966. type: DBLCLICK_EVENT_NAME,
  12967. target: utils.closestCommonParent(this._firstClickTarget, e.target),
  12968. originalEvent: e
  12969. });
  12970. this._forgetLastClick()
  12971. }
  12972. else {
  12973. this._firstClickTarget = e.target;
  12974. this._lastClickTimeStamp = timeStamp
  12975. }
  12976. },
  12977. remove: function() {
  12978. this._handlerCount--;
  12979. if (this._handlerCount <= 0) {
  12980. this._forgetLastClick();
  12981. $(document).off(NAMESPACED_CLICK_EVENT)
  12982. }
  12983. }
  12984. });
  12985. events.registerEvent(DBLCLICK_EVENT_NAME, new DblClick)
  12986. })(jQuery, DevExpress);
  12987. /*! Module core, file ui.events.remove.js */
  12988. (function($) {
  12989. (function(cleanData) {
  12990. $.cleanData = function(elements) {
  12991. $.each(elements, function() {
  12992. $(this).triggerHandler("dxremove")
  12993. });
  12994. return cleanData.apply(this, arguments)
  12995. }
  12996. })($.cleanData)
  12997. })(jQuery);
  12998. /*! Module core, file ui.events.contextmenu.js */
  12999. (function($, DX, undefined) {
  13000. var ui = DX.ui,
  13001. events = ui.events,
  13002. support = DX.support,
  13003. CONTEXTMENU_NAMESPACE = "dxContexMenu",
  13004. CONTEXTMENU_NAMESPACED_EVENT_NAME = events.addNamespace("contextmenu", CONTEXTMENU_NAMESPACE),
  13005. HOLD_NAMESPACED_EVENT_NAME = events.addNamespace("dxhold", CONTEXTMENU_NAMESPACE),
  13006. CONTEXTMENU_EVENT_NAME = "dxcontextmenu";
  13007. var ContextMenu = DX.Class.inherit({
  13008. setup: function(element, data) {
  13009. var $element = $(element);
  13010. $element.on(CONTEXTMENU_NAMESPACED_EVENT_NAME, $.proxy(this._contextMenuHandler, this));
  13011. if (support.touch || DX.devices.isSimulator())
  13012. $element.on(HOLD_NAMESPACED_EVENT_NAME, $.proxy(this._holdHandler, this))
  13013. },
  13014. _holdHandler: function(e) {
  13015. if (events.isMouseEvent(e) && !DX.devices.isSimulator())
  13016. return;
  13017. this._fireContextMenu(e)
  13018. },
  13019. _contextMenuHandler: function(e) {
  13020. e = this._fireContextMenu(e);
  13021. if (!e.cancel)
  13022. e.preventDefault()
  13023. },
  13024. _fireContextMenu: function(e) {
  13025. return events.fireEvent({
  13026. type: CONTEXTMENU_EVENT_NAME,
  13027. originalEvent: e
  13028. })
  13029. },
  13030. teardown: function(element) {
  13031. $(element).off("." + CONTEXTMENU_NAMESPACE)
  13032. }
  13033. });
  13034. events.registerEvent(CONTEXTMENU_EVENT_NAME, new ContextMenu)
  13035. })(jQuery, DevExpress);
  13036. /*! Module core, file ui.widget.js */
  13037. (function($, DX, undefined) {
  13038. var ui = DX.ui,
  13039. utils = DX.utils,
  13040. events = ui.events,
  13041. UI_FEEDBACK = "UIFeedback",
  13042. WIDGET_CLASS = "dx-widget",
  13043. ACTIVE_STATE_CLASS = "dx-state-active",
  13044. DISABLED_STATE_CLASS = "dx-state-disabled",
  13045. INVISIBLE_STATE_CLASS = "dx-state-invisible",
  13046. HOVER_STATE_CLASS = "dx-state-hover",
  13047. FOCUSED_STATE_CLASS = "dx-state-focused",
  13048. FEEDBACK_SHOW_TIMEOUT = 30,
  13049. FEEDBACK_HIDE_TIMEOUT = 400,
  13050. HOVER_START = "dxhoverstart",
  13051. HOVER_END = "dxhoverend",
  13052. FOCUS_NAMESPACE = "Focus",
  13053. ANONYMOUS_TEMPLATE_NAME = "template",
  13054. TEXT_NODE = 3,
  13055. TEMPLATE_SELECTOR = "[data-options*='dxTemplate']",
  13056. TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";
  13057. var DynamicTemplate = ui.TemplateBase.inherit({
  13058. ctor: function(compileFunction, owner) {
  13059. this.callBase($(), owner);
  13060. this._compileFunction = compileFunction
  13061. },
  13062. _renderCore: function(data, index, container) {
  13063. if (data === undefined && index === undefined) {
  13064. data = container;
  13065. container = undefined
  13066. }
  13067. var compiledTemplate = index === undefined ? this._compileFunction(data, container) : this._compileFunction(data, index, container);
  13068. var renderResult = compiledTemplate.render(data, container, index);
  13069. if (compiledTemplate.owner() === this)
  13070. compiledTemplate.dispose();
  13071. return renderResult
  13072. }
  13073. });
  13074. var EmptyTemplate = ui.TemplateBase.inherit({
  13075. ctor: function(owner) {
  13076. this.callBase($(), owner)
  13077. },
  13078. _renderCore: function(data, index, container) {
  13079. return $()
  13080. }
  13081. });
  13082. var RendererTemplate = ui.TemplateBase.inherit({_renderCore: function() {
  13083. return this._element
  13084. }});
  13085. ui.Widget = DX.DOMComponent.inherit({
  13086. NAME: "Widget",
  13087. _supportedKeys: function() {
  13088. return {}
  13089. },
  13090. _setDeprecatedOptions: function() {
  13091. this.callBase();
  13092. $.extend(this._deprecatedOptions, {contentReadyAction: {
  13093. since: "14.2",
  13094. alias: "onContentReady"
  13095. }})
  13096. },
  13097. _setDefaultOptions: function() {
  13098. this.callBase();
  13099. this.option({
  13100. disabled: false,
  13101. visible: true,
  13102. hint: undefined,
  13103. activeStateEnabled: false,
  13104. onContentReady: null,
  13105. hoverStateEnabled: false,
  13106. focusStateEnabled: false,
  13107. tabIndex: 0,
  13108. accessKey: null,
  13109. onFocusIn: null,
  13110. onFocusOut: null,
  13111. templateProvider: ui.TemplateProvider,
  13112. _keyboardProcessor: undefined,
  13113. _templates: {}
  13114. })
  13115. },
  13116. _init: function() {
  13117. this.callBase();
  13118. this._feedbackShowTimeout = FEEDBACK_SHOW_TIMEOUT;
  13119. this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT;
  13120. this._tempTemplates = [];
  13121. this._dynamicTemplates = {};
  13122. this._initTemplates();
  13123. this._initContentReadyAction();
  13124. this._initFocusActions()
  13125. },
  13126. _initTemplates: function() {
  13127. this._extractTemplates();
  13128. this._extractAnonimousTemplate()
  13129. },
  13130. _extractTemplates: function() {
  13131. var templates = this.option("_templates"),
  13132. templateElements = this.element().contents().filter(TEMPLATE_SELECTOR);
  13133. var templatesMap = {};
  13134. templateElements.each(function(_, template) {
  13135. var templateOptions = utils.getElementOptions(template).dxTemplate;
  13136. if (!templateOptions)
  13137. return;
  13138. if (!templateOptions.name)
  13139. throw DX.Error("E0023");
  13140. $(template).addClass(TEMPLATE_WRAPPER_CLASS).detach();
  13141. templatesMap[templateOptions.name] = templatesMap[templateOptions.name] || [];
  13142. templatesMap[templateOptions.name].push(template)
  13143. });
  13144. $.each(templatesMap, $.proxy(function(templateName, value) {
  13145. var deviceTemplate = this._findTemplateByDevice(value);
  13146. if (deviceTemplate)
  13147. templates[templateName] = this._createTemplate(deviceTemplate, this)
  13148. }, this))
  13149. },
  13150. _findTemplateByDevice: function(templates) {
  13151. var suitableTemplate = DX.utils.findBestMatches(DX.devices.current(), templates, function(template) {
  13152. return utils.getElementOptions(template).dxTemplate
  13153. })[0];
  13154. $.each(templates, function(index, template) {
  13155. if (template !== suitableTemplate)
  13156. $(template).remove()
  13157. });
  13158. return suitableTemplate
  13159. },
  13160. _extractAnonimousTemplate: function() {
  13161. var templates = this.option("_templates"),
  13162. anonimiousTemplateName = this._getAnonimousTemplateName(),
  13163. $anonimiousTemplate = this.element().contents().detach();
  13164. var $notJunkTemplateContent = $anonimiousTemplate.filter(function(_, element) {
  13165. var isTextNode = element.nodeType === TEXT_NODE,
  13166. isEmptyText = $.trim($(element).text()).length < 1;
  13167. return !(isTextNode && isEmptyText)
  13168. }),
  13169. onlyJunkTemplateContent = $notJunkTemplateContent.length < 1;
  13170. if (!templates[anonimiousTemplateName] && !onlyJunkTemplateContent)
  13171. templates[anonimiousTemplateName] = this._createTemplate($anonimiousTemplate, this)
  13172. },
  13173. _getAriaTarget: function() {
  13174. return this.element()
  13175. },
  13176. _getAnonimousTemplateName: function() {
  13177. return ANONYMOUS_TEMPLATE_NAME
  13178. },
  13179. _getTemplateByOption: function(optionName) {
  13180. return this._getTemplate(this.option(optionName))
  13181. },
  13182. _getTemplate: function(templateSource) {
  13183. if ($.isFunction(templateSource)) {
  13184. var that = this;
  13185. return new DynamicTemplate(function() {
  13186. var templateSourceResult = templateSource.apply(that, arguments);
  13187. if (utils.isDefined(templateSourceResult))
  13188. return that._acquireTemplate(templateSourceResult, this, true);
  13189. else
  13190. return new EmptyTemplate
  13191. }, this)
  13192. }
  13193. return this._acquireTemplate(templateSource, this)
  13194. },
  13195. _acquireTemplate: function(templateSource, owner, preferRenderer) {
  13196. if (templateSource == null)
  13197. return this._createTemplate(utils.normalizeTemplateElement(templateSource), owner);
  13198. if (templateSource instanceof ui.TemplateBase)
  13199. return templateSource;
  13200. if (templateSource.nodeType || templateSource.jquery) {
  13201. templateSource = $(templateSource);
  13202. if (preferRenderer && !templateSource.is("script"))
  13203. return new RendererTemplate(templateSource, owner);
  13204. return this._createTemplate(templateSource, owner)
  13205. }
  13206. if (typeof templateSource === "string") {
  13207. var userTemplate = this.option("_templates")[templateSource];
  13208. if (userTemplate)
  13209. return userTemplate;
  13210. var dynamicTemplate = this._dynamicTemplates[templateSource];
  13211. if (dynamicTemplate)
  13212. return dynamicTemplate;
  13213. var defaultTemplate = this.option("templateProvider").getTemplates(this)[templateSource];
  13214. if (defaultTemplate)
  13215. return defaultTemplate;
  13216. return this._createTemplate(utils.normalizeTemplateElement(templateSource), owner)
  13217. }
  13218. return this._acquireTemplate(templateSource.toString(), owner)
  13219. },
  13220. _createTemplate: function(element, owner) {
  13221. var template = this.option("templateProvider").createTemplate(element, owner);
  13222. this._tempTemplates.push(template);
  13223. return template
  13224. },
  13225. _cleanTemplates: function() {
  13226. var that = this;
  13227. $.each(this.option("_templates"), function(_, template) {
  13228. if (that === template.owner())
  13229. template.dispose()
  13230. });
  13231. $.each(this._tempTemplates, function(_, template) {
  13232. template.dispose()
  13233. })
  13234. },
  13235. _initContentReadyAction: function() {
  13236. this._contentReadyAction = this._createActionByOption("onContentReady", {excludeValidators: ["designMode", "disabled", "readOnly"]})
  13237. },
  13238. _initFocusActions: function() {
  13239. var focusInAction = this._createActionByOption("onFocusIn", {excludeValidators: ["readOnly"]});
  13240. var focusOutAction = this._createActionByOption("onFocusOut", {excludeValidators: ["readOnly"]});
  13241. this._focusInAction = this._createAction(function(e) {
  13242. e.component._focusInHandler(e.jQueryEvent);
  13243. focusInAction(e)
  13244. }, {excludeValidators: ["readOnly"]});
  13245. this._focusOutAction = this._createAction(function(e) {
  13246. e.component._focusOutHandler(e.jQueryEvent);
  13247. focusOutAction(e)
  13248. }, {excludeValidators: ["readOnly"]})
  13249. },
  13250. _render: function() {
  13251. this.element().addClass(WIDGET_CLASS);
  13252. this.callBase();
  13253. this._toggleDisabledState(this.option("disabled"));
  13254. this._toggleVisibility(this.option("visible"));
  13255. this._renderHint();
  13256. this._renderContent();
  13257. this._renderFocusState();
  13258. this._attachFeedbackEvents();
  13259. this._attachHoverEvents()
  13260. },
  13261. _renderHint: function() {
  13262. utils.toggleAttr(this.element(), "title", this.option("hint"))
  13263. },
  13264. _renderContent: function() {
  13265. this._renderContentImpl();
  13266. this._fireContentReadyAction()
  13267. },
  13268. _renderContentImpl: $.noop,
  13269. _fireContentReadyAction: function() {
  13270. this._contentReadyAction()
  13271. },
  13272. _dispose: function() {
  13273. this._cleanTemplates();
  13274. this._contentReadyAction = null;
  13275. this.callBase()
  13276. },
  13277. _clean: function() {
  13278. this._cleanFocusState();
  13279. this.callBase();
  13280. this.element().empty()
  13281. },
  13282. _toggleVisibility: function(visible) {
  13283. this.element().toggleClass(INVISIBLE_STATE_CLASS, !visible);
  13284. this.setAria("hidden", !visible || undefined)
  13285. },
  13286. _renderFocusState: function() {
  13287. if (!this.option("focusStateEnabled") || this.option("disabled"))
  13288. return;
  13289. this._renderFocusTarget();
  13290. this._attachFocusEvents();
  13291. this._attachKeyboardEvents();
  13292. this._renderAccessKey()
  13293. },
  13294. _renderAccessKey: function() {
  13295. var focusTarget = this._focusTarget();
  13296. focusTarget.attr("accesskey", this.option("accessKey"));
  13297. var clickNamespace = events.addNamespace("dxclick", UI_FEEDBACK);
  13298. focusTarget.off(clickNamespace);
  13299. this.option("accessKey") && focusTarget.on(clickNamespace, $.proxy(function(e) {
  13300. if (e.screenX === 0 && !e.offsetX && e.pageX === 0) {
  13301. e.stopImmediatePropagation();
  13302. this.focus()
  13303. }
  13304. }, this))
  13305. },
  13306. _eventBindingTarget: function() {
  13307. return this.element()
  13308. },
  13309. _focusTarget: function() {
  13310. return this._getActiveElement()
  13311. },
  13312. _getActiveElement: function() {
  13313. var activeElement = this._eventBindingTarget();
  13314. if (this._activeStateUnit)
  13315. activeElement = activeElement.find(this._activeStateUnit).not("." + DISABLED_STATE_CLASS);
  13316. return activeElement
  13317. },
  13318. _renderFocusTarget: function() {
  13319. this._focusTarget().attr("tabindex", this.option("tabIndex"))
  13320. },
  13321. _keyboardEventBindingTarget: function() {
  13322. return this._eventBindingTarget()
  13323. },
  13324. _attachFocusEvents: function() {
  13325. var focusInEvent = events.addNamespace("focusin", this.NAME + FOCUS_NAMESPACE);
  13326. var focusOutEvent = events.addNamespace("focusout", this.NAME + FOCUS_NAMESPACE);
  13327. var beforeactivateEventNamespace = events.addNamespace("beforeactivate", this.NAME + FOCUS_NAMESPACE);
  13328. this._focusTarget().off("." + this.NAME + FOCUS_NAMESPACE).on(focusInEvent, $.proxy(function(e) {
  13329. this._focusInAction({jQueryEvent: e})
  13330. }, this)).on(focusOutEvent, $.proxy(function(e) {
  13331. this._focusOutAction({jQueryEvent: e})
  13332. }, this)).on(beforeactivateEventNamespace, function(e) {
  13333. if (!$(e.target).is(":dx-focusable"))
  13334. e.preventDefault()
  13335. })
  13336. },
  13337. _focusInHandler: function(e) {
  13338. this._updateFocusState(e, true)
  13339. },
  13340. _focusOutHandler: function(e) {
  13341. this._updateFocusState(e, false)
  13342. },
  13343. _updateFocusState: function(e, isFocused) {
  13344. var currentTarget = e.currentTarget,
  13345. focusTargets = this._focusTarget();
  13346. if ($.inArray(currentTarget, focusTargets) !== -1)
  13347. $(e.currentTarget).toggleClass(FOCUSED_STATE_CLASS, isFocused)
  13348. },
  13349. _attachKeyboardEvents: function() {
  13350. var processor = this.option("_keyboardProcessor") || new ui.KeyboardProcessor({
  13351. element: this._keyboardEventBindingTarget(),
  13352. focusTarget: this._focusTarget()
  13353. });
  13354. this._keyboardProcessor = processor.reinitialize(this._keyboardHandler, this)
  13355. },
  13356. _keyboardHandler: function(options) {
  13357. var e = options.originalEvent,
  13358. key = options.key;
  13359. var keys = this._supportedKeys(),
  13360. func = keys[key];
  13361. if (func !== undefined) {
  13362. var handler = $.proxy(func, this);
  13363. return handler(e) || false
  13364. }
  13365. else
  13366. return true
  13367. },
  13368. _refreshFocusState: function() {
  13369. this._cleanFocusState();
  13370. this._renderFocusState()
  13371. },
  13372. _cleanFocusState: function() {
  13373. var $element = this._focusTarget();
  13374. $element.off("." + this.NAME + FOCUS_NAMESPACE);
  13375. $element.removeClass(FOCUSED_STATE_CLASS);
  13376. $element.removeAttr("tabindex");
  13377. if (this._keyboardProcessor)
  13378. this._keyboardProcessor.dispose()
  13379. },
  13380. _attachHoverEvents: function() {
  13381. var that = this,
  13382. hoverableSelector = that._activeStateUnit,
  13383. nameStart = events.addNamespace(HOVER_START, UI_FEEDBACK),
  13384. nameEnd = events.addNamespace(HOVER_END, UI_FEEDBACK);
  13385. that._eventBindingTarget().off(nameStart, hoverableSelector).off(nameEnd, hoverableSelector);
  13386. if (that.option("hoverStateEnabled")) {
  13387. var startAction = new DX.Action(function(args) {
  13388. that._hoverStartHandler(args.event);
  13389. var $target = args.element;
  13390. that._refreshHoveredElement($target)
  13391. });
  13392. that._eventBindingTarget().on(nameStart, hoverableSelector, function(e) {
  13393. startAction.execute({
  13394. element: $(e.target),
  13395. event: e
  13396. })
  13397. }).on(nameEnd, hoverableSelector, function(e) {
  13398. that._hoverEndHandler(e);
  13399. that._forgetHoveredElement()
  13400. })
  13401. }
  13402. else
  13403. that._toggleHoverClass(false)
  13404. },
  13405. _hoverStartHandler: $.noop,
  13406. _hoverEndHandler: $.noop,
  13407. _attachFeedbackEvents: function() {
  13408. var that = this,
  13409. feedbackSelector = that._activeStateUnit,
  13410. activeEventName = events.addNamespace("dxactive", UI_FEEDBACK),
  13411. inactiveEventName = events.addNamespace("dxinactive", UI_FEEDBACK);
  13412. that._eventBindingTarget().off(activeEventName, feedbackSelector).off(inactiveEventName, feedbackSelector);
  13413. if (that.option("activeStateEnabled")) {
  13414. var feedbackActionHandler = function(args) {
  13415. var $element = args.element,
  13416. value = args.value;
  13417. that._toggleActiveState($element, value)
  13418. };
  13419. var feedbackAction = new DX.Action(function(args) {
  13420. feedbackActionHandler(args)
  13421. }),
  13422. feedbackActionDisabled = new DX.Action(function(args) {
  13423. feedbackActionHandler(args)
  13424. }, {excludeValidators: ["disabled", "readOnly"]});
  13425. that._eventBindingTarget().on(activeEventName, feedbackSelector, {timeout: that._feedbackShowTimeout}, function(e) {
  13426. feedbackAction.execute({
  13427. element: $(e.currentTarget),
  13428. value: true
  13429. })
  13430. }).on(inactiveEventName, feedbackSelector, {timeout: that._feedbackHideTimeout}, function(e) {
  13431. feedbackActionDisabled.execute({
  13432. element: $(e.currentTarget),
  13433. value: false
  13434. })
  13435. })
  13436. }
  13437. },
  13438. _toggleActiveState: function($element, value) {
  13439. this._toggleHoverClass(!value);
  13440. $element.toggleClass(ACTIVE_STATE_CLASS, value)
  13441. },
  13442. _refreshHoveredElement: function(hoveredElement) {
  13443. var selector = this._activeStateUnit || this.element();
  13444. this._forgetHoveredElement();
  13445. this._hoveredElement = hoveredElement.closest(selector);
  13446. this._toggleHoverClass(true)
  13447. },
  13448. _forgetHoveredElement: function() {
  13449. this._toggleHoverClass(false);
  13450. delete this._hoveredElement
  13451. },
  13452. _toggleHoverClass: function(value) {
  13453. if (this._hoveredElement)
  13454. this._hoveredElement.toggleClass(HOVER_STATE_CLASS, value && this.option("hoverStateEnabled"))
  13455. },
  13456. _toggleDisabledState: function(value) {
  13457. this.element().toggleClass(DISABLED_STATE_CLASS, Boolean(value));
  13458. this._toggleHoverClass(!value);
  13459. this.setAria("disabled", value || undefined)
  13460. },
  13461. _setWidgetOption: function(widgetName, args) {
  13462. if (!this[widgetName])
  13463. return;
  13464. if ($.isPlainObject(args[0])) {
  13465. $.each(args[0], $.proxy(function(option, value) {
  13466. this._setWidgetOption(widgetName, [option, value])
  13467. }, this));
  13468. return
  13469. }
  13470. var optionName = args[0];
  13471. var value = args[1];
  13472. if (args.length === 1)
  13473. value = this.option(optionName);
  13474. var widgetOptionMap = this[widgetName + "OptionMap"];
  13475. this[widgetName].option(widgetOptionMap ? widgetOptionMap(optionName) : optionName, value)
  13476. },
  13477. _createComponent: function(element, name, config) {
  13478. config = config || {};
  13479. this._extendConfig(config, {
  13480. templateProvider: this.option("templateProvider"),
  13481. _templates: this.option("_templates")
  13482. });
  13483. return this.callBase(element, name, config)
  13484. },
  13485. _optionChanged: function(args) {
  13486. switch (args.name) {
  13487. case"disabled":
  13488. this._toggleDisabledState(args.value);
  13489. this._refreshFocusState();
  13490. break;
  13491. case"hint":
  13492. this._renderHint();
  13493. break;
  13494. case"activeStateEnabled":
  13495. this._attachFeedbackEvents();
  13496. break;
  13497. case"hoverStateEnabled":
  13498. this._attachHoverEvents();
  13499. break;
  13500. case"tabIndex":
  13501. case"_keyboardProcessor":
  13502. case"focusStateEnabled":
  13503. this._refreshFocusState();
  13504. break;
  13505. case"onFocusIn":
  13506. case"onFocusOut":
  13507. this._initFocusActions();
  13508. break;
  13509. case"accessKey":
  13510. this._renderAccessKey();
  13511. break;
  13512. case"visible":
  13513. var visible = args.value;
  13514. this._toggleVisibility(visible);
  13515. if (this._isVisibilityChangeSupported())
  13516. this._visibilityChanged(visible);
  13517. break;
  13518. case"onContentReady":
  13519. this._initContentReadyAction();
  13520. break;
  13521. case"_templates":
  13522. case"templateProvider":
  13523. this._refresh();
  13524. break;
  13525. default:
  13526. this.callBase(args)
  13527. }
  13528. },
  13529. beginUpdate: function() {
  13530. this._ready(false);
  13531. this.callBase()
  13532. },
  13533. endUpdate: function() {
  13534. this.callBase();
  13535. if (this._initialized)
  13536. this._ready(true)
  13537. },
  13538. _ready: function(value) {
  13539. if (arguments.length === 0)
  13540. return this._isReady;
  13541. this._isReady = value
  13542. },
  13543. setAria: function() {
  13544. var setAttribute = function(option) {
  13545. var attrName = $.inArray(option.name, ["role", "id"]) + 1 ? option.name : "aria-" + option.name,
  13546. attrValue = option.value;
  13547. if (attrValue === null || attrValue === undefined)
  13548. attrValue = undefined;
  13549. else
  13550. attrValue = attrValue.toString();
  13551. utils.toggleAttr(option.target, attrName, attrValue)
  13552. };
  13553. if (!$.isPlainObject(arguments[0]))
  13554. setAttribute({
  13555. name: arguments[0],
  13556. value: arguments[1],
  13557. target: arguments[2] || this._getAriaTarget()
  13558. });
  13559. else {
  13560. var $target = arguments[1] || this._getAriaTarget();
  13561. $.each(arguments[0], function(key, value) {
  13562. setAttribute({
  13563. name: key,
  13564. value: value,
  13565. target: $target
  13566. })
  13567. })
  13568. }
  13569. },
  13570. isReady: function() {
  13571. return this._ready()
  13572. },
  13573. repaint: function() {
  13574. this._refresh()
  13575. },
  13576. focus: function() {
  13577. this._focusTarget().focus()
  13578. },
  13579. registerKeyHandler: function(key, handler) {
  13580. var currentKeys = this._supportedKeys(),
  13581. addingKeys = {};
  13582. addingKeys[key] = handler;
  13583. this._supportedKeys = function() {
  13584. return $.extend(currentKeys, addingKeys)
  13585. }
  13586. }
  13587. })
  13588. })(jQuery, DevExpress);
  13589. /*! Module core, file ui.editor.js */
  13590. (function($, DX, undefined) {
  13591. var ui = DX.ui,
  13592. READONLY_STATE_CLASS = "dx-state-readonly",
  13593. INVALID_CLASS = "dx-invalid",
  13594. INVALID_MESSAGE = "dx-invalid-message",
  13595. INVALID_MESSAGE_AUTO = "dx-invalid-message-auto",
  13596. INVALID_MESSAGE_ALWAYS = "dx-invalid-message-always";
  13597. ui.validation = ui.validation || {};
  13598. ui.validation.findGroup = function() {
  13599. var group = this.option("validationGroup"),
  13600. $dxGroup;
  13601. if (!group) {
  13602. $dxGroup = this.element().parents(".dx-validationgroup:first");
  13603. if ($dxGroup.length)
  13604. group = $dxGroup.dxValidationGroup("instance");
  13605. else
  13606. group = this._modelByElement(this.element())
  13607. }
  13608. return group
  13609. };
  13610. ui.Editor = ui.Widget.inherit({
  13611. _init: function() {
  13612. this.callBase();
  13613. this.validationRequest = $.Callbacks();
  13614. var $element = this.element();
  13615. if ($element) {
  13616. $element.data("dx-validation-target", this);
  13617. this.on("disposing", function() {
  13618. $element.data("dx-validation-target", null)
  13619. })
  13620. }
  13621. this._createValueChangeAction()
  13622. },
  13623. _setDeprecatedOptions: function() {
  13624. this.callBase();
  13625. $.extend(this._deprecatedOptions, {valueChangeAction: {
  13626. since: "14.2",
  13627. alias: "onValueChanged",
  13628. message: "'onValueChanged' option instead"
  13629. }})
  13630. },
  13631. _setDefaultOptions: function() {
  13632. this.callBase();
  13633. this.option({
  13634. value: null,
  13635. onValueChanged: null,
  13636. activeStateEnabled: true,
  13637. readOnly: false,
  13638. isValid: true,
  13639. validationError: null,
  13640. validationMessageMode: "auto",
  13641. validationTooltipOffset: {
  13642. h: 0,
  13643. v: -10
  13644. }
  13645. })
  13646. },
  13647. _defaultOptionsRules: function() {
  13648. return this.callBase().concat([{
  13649. device: function(device) {
  13650. return device.platform === "android"
  13651. },
  13652. options: {invalidTooltipOffset: {
  13653. h: 9,
  13654. v: -7
  13655. }}
  13656. }, {
  13657. device: {platform: "win8"},
  13658. options: {invalidTooltipOffset: {
  13659. h: 9,
  13660. v: -4
  13661. }}
  13662. }])
  13663. },
  13664. _attachKeyboardEvents: function() {
  13665. if (this.option("readOnly"))
  13666. return;
  13667. this.callBase.apply(this, arguments);
  13668. this._attachChildKeyboardEvents()
  13669. },
  13670. _attachChildKeyboardEvents: $.noop,
  13671. _setOptionsByReference: function() {
  13672. this.callBase();
  13673. $.extend(this._optionsByReference, {validationError: true})
  13674. },
  13675. _createValueChangeAction: function() {
  13676. this._valueChangeAction = this._createActionByOption("onValueChanged", {excludeValidators: ["disabled", "readOnly"]})
  13677. },
  13678. _suppressValueChangeAction: function() {
  13679. this._valueChangeActionSuppressed = true
  13680. },
  13681. _resumeValueChangeAction: function() {
  13682. this._valueChangeActionSuppressed = false
  13683. },
  13684. _render: function() {
  13685. this._renderValidationState();
  13686. this._toggleReadOnlyState();
  13687. this.callBase()
  13688. },
  13689. _raiseValueChangeAction: function(value, previousValue, extraArguments) {
  13690. this._valueChangeAction(this._valueChangeArgs(value, previousValue))
  13691. },
  13692. _valueChangeArgs: function(value, previousValue) {
  13693. return {
  13694. value: value,
  13695. previousValue: previousValue,
  13696. jQueryEvent: this._valueChangeEventInstance
  13697. }
  13698. },
  13699. _saveValueChangeEvent: function(e) {
  13700. this._valueChangeEventInstance = e
  13701. },
  13702. _renderValidationState: function() {
  13703. var isValid = this.option("isValid"),
  13704. validationError = this.option("validationError"),
  13705. validationMessageMode = this.option("validationMessageMode"),
  13706. $element = this.element();
  13707. $element.toggleClass(INVALID_CLASS, !isValid);
  13708. this.setAria("invalid", !isValid || undefined);
  13709. if (this._$validationMessage) {
  13710. this._$validationMessage.remove();
  13711. this._$validationMessage = null
  13712. }
  13713. if (!isValid && validationError && validationError.message) {
  13714. this._$validationMessage = $("<div/>", {"class": INVALID_MESSAGE}).text(validationError.message).appendTo($element);
  13715. this._createComponent(this._$validationMessage, "dxTooltip", {
  13716. target: $element,
  13717. container: $element,
  13718. position: this._getValidationTooltipPosition("below"),
  13719. closeOnOutsideClick: false,
  13720. closeOnTargetScroll: false,
  13721. animation: null,
  13722. visible: true
  13723. });
  13724. this._$validationMessage.toggleClass(INVALID_MESSAGE_AUTO, validationMessageMode === "auto").toggleClass(INVALID_MESSAGE_ALWAYS, validationMessageMode === "always")
  13725. }
  13726. },
  13727. _getValidationTooltipPosition: function(positionRequest) {
  13728. var rtlEnabled = this.option("rtlEnabled"),
  13729. tooltipPositionSide = rtlEnabled ? "right" : "left",
  13730. tooltipOriginalOffset = this.option("validationTooltipOffset"),
  13731. tooltipOffset = {
  13732. h: tooltipOriginalOffset.h,
  13733. v: tooltipOriginalOffset.v
  13734. },
  13735. verticalPositions = positionRequest === "below" ? [" top", " bottom"] : [" bottom", " top"];
  13736. if (rtlEnabled)
  13737. tooltipOffset.h = -tooltipOffset.h;
  13738. if (positionRequest !== "below")
  13739. tooltipOffset.v = -tooltipOffset.v;
  13740. return {
  13741. offset: tooltipOffset,
  13742. my: tooltipPositionSide + verticalPositions[0],
  13743. at: tooltipPositionSide + verticalPositions[1],
  13744. collision: "none"
  13745. }
  13746. },
  13747. _toggleReadOnlyState: function() {
  13748. this.element().toggleClass(READONLY_STATE_CLASS, this.option("readOnly"));
  13749. this.setAria("readonly", this.option("readOnly") || undefined)
  13750. },
  13751. _optionChanged: function(args) {
  13752. switch (args.name) {
  13753. case"onValueChanged":
  13754. this._createValueChangeAction();
  13755. break;
  13756. case"isValid":
  13757. case"validationError":
  13758. case"validationMessageMode":
  13759. this._renderValidationState();
  13760. break;
  13761. case"readOnly":
  13762. this._toggleReadOnlyState();
  13763. this._refreshFocusState();
  13764. break;
  13765. case"value":
  13766. if (!this._valueChangeActionSuppressed) {
  13767. this._raiseValueChangeAction(args.value, args.previousValue);
  13768. this._saveValueChangeEvent(undefined)
  13769. }
  13770. if (args.value != args.previousValue)
  13771. this.validationRequest.fire({
  13772. value: args.value,
  13773. editor: this
  13774. });
  13775. break;
  13776. default:
  13777. this.callBase(args)
  13778. }
  13779. },
  13780. reset: function() {
  13781. this.option("value", null)
  13782. }
  13783. })
  13784. })(jQuery, DevExpress);
  13785. /*! Module core, file ui.CollectionWidget.js */
  13786. (function($, DX, undefined) {
  13787. var ui = DX.ui,
  13788. utils = DX.utils,
  13789. events = ui.events;
  13790. var COLLECTION_CLASS = "dx-collection",
  13791. ITEM_CLASS = "dx-item",
  13792. CONTENT_CLASS_POSTFIX = "-content",
  13793. ITEM_CONTENT_PLACEHOLDER_CLASS = "dx-item-content-placeholder",
  13794. ITEM_DATA_KEY = "dxItemData",
  13795. ITEM_TEMPLATE_ID_PREFIX = "tmpl-",
  13796. ITEMS_SELECTOR = "[data-options*='dxItem']",
  13797. SELECTED_ITEM_CLASS = "dx-item-selected",
  13798. FOCUSED_STATE_CLASS = "dx-state-focused",
  13799. ITEM_RESPONSE_WAIT_CLASS = "dx-item-response-wait",
  13800. EMPTY_COLLECTION = "dx-empty-collection",
  13801. TEMPLATE_WRAPPER_CLASS = "dx-template-wrapper";
  13802. var FOCUS_UP = "up",
  13803. FOCUS_DOWN = "down",
  13804. FOCUS_LEFT = "left",
  13805. FOCUS_RIGHT = "right",
  13806. FOCUS_PAGE_UP = "pageup",
  13807. FOCUS_PAGE_DOWN = "pagedown",
  13808. FOCUS_LAST = "last",
  13809. FOCUS_FIRST = "first";
  13810. var CollectionWidget = ui.Widget.inherit({
  13811. NAME: "CollectionWidget",
  13812. _activeStateUnit: "." + ITEM_CLASS,
  13813. _supportedKeys: function() {
  13814. var click = function(e) {
  13815. var $itemElement = this.option("focusedElement");
  13816. if (!$itemElement)
  13817. return;
  13818. e.target = $itemElement;
  13819. e.currentTarget = $itemElement;
  13820. this._itemClickHandler(e)
  13821. },
  13822. move = function(location, e) {
  13823. e.preventDefault();
  13824. e.stopPropagation();
  13825. this._moveFocus(location, e)
  13826. };
  13827. return $.extend(this.callBase(), {
  13828. space: click,
  13829. enter: click,
  13830. leftArrow: $.proxy(move, this, FOCUS_LEFT),
  13831. rightArrow: $.proxy(move, this, FOCUS_RIGHT),
  13832. upArrow: $.proxy(move, this, FOCUS_UP),
  13833. downArrow: $.proxy(move, this, FOCUS_DOWN),
  13834. pageUp: $.proxy(move, this, FOCUS_UP),
  13835. pageDown: $.proxy(move, this, FOCUS_DOWN),
  13836. home: $.proxy(move, this, FOCUS_FIRST),
  13837. end: $.proxy(move, this, FOCUS_LAST)
  13838. })
  13839. },
  13840. _setDeprecatedOptions: function() {
  13841. this.callBase();
  13842. $.extend(this._deprecatedOptions, {
  13843. itemClickAction: {
  13844. since: "14.2",
  13845. alias: "onItemClick"
  13846. },
  13847. itemHoldAction: {
  13848. since: "14.2",
  13849. alias: "onItemHold"
  13850. },
  13851. itemRenderedAction: {
  13852. since: "14.2",
  13853. alias: "onItemRendered"
  13854. },
  13855. itemRender: {
  13856. since: "14.2",
  13857. alias: "itemTemplate"
  13858. }
  13859. })
  13860. },
  13861. _setDefaultOptions: function() {
  13862. this.callBase();
  13863. this.option({
  13864. selectOnFocus: false,
  13865. loopItemFocus: true,
  13866. items: [],
  13867. itemTemplate: "item",
  13868. onItemRendered: null,
  13869. onItemClick: null,
  13870. onItemHold: null,
  13871. itemHoldTimeout: 750,
  13872. onItemContextMenu: null,
  13873. onFocusedItemChanged: null,
  13874. noDataText: Globalize.localize("dxCollectionWidget-noDataText"),
  13875. dataSource: null,
  13876. _itemAttributes: {},
  13877. itemTemplateProperty: "template",
  13878. focusOnSelectedItem: true,
  13879. focusedElement: null
  13880. })
  13881. },
  13882. _getAnonimousTemplateName: function() {
  13883. return "item"
  13884. },
  13885. _init: function() {
  13886. this.callBase();
  13887. this._cleanRenderedItems();
  13888. this._refreshDataSource()
  13889. },
  13890. _initTemplates: function() {
  13891. this._initItemsFromMarkup();
  13892. this.callBase()
  13893. },
  13894. _initItemsFromMarkup: function() {
  13895. var $items = this.element().contents().filter(ITEMS_SELECTOR);
  13896. if (!$items.length || this.option("items").length)
  13897. return;
  13898. var items = $.map($items, $.proxy(function(item) {
  13899. var $item = $(item);
  13900. var result = utils.getElementOptions(item).dxItem;
  13901. var isTemplateRequired = $.trim($item.html()) && !result.template;
  13902. if (isTemplateRequired)
  13903. result.template = this._prepareItemTemplate($item);
  13904. else
  13905. $item.remove();
  13906. return result
  13907. }, this));
  13908. this.option("items", items)
  13909. },
  13910. _prepareItemTemplate: function($item) {
  13911. var templateId = ITEM_TEMPLATE_ID_PREFIX + new DX.data.Guid;
  13912. var templateOptions = "dxTemplate: { name: \"" + templateId + "\" }";
  13913. $item.attr("data-options", templateOptions).data("options", templateOptions);
  13914. return templateId
  13915. },
  13916. _dataSourceOptions: function() {
  13917. return {paginate: false}
  13918. },
  13919. _cleanRenderedItems: function() {
  13920. this._renderedItemsCount = 0
  13921. },
  13922. _focusTarget: function() {
  13923. return this.element()
  13924. },
  13925. _focusInHandler: function(e) {
  13926. this.callBase.apply(this, arguments);
  13927. var $focusedElement = this.option("focusedElement");
  13928. if ($focusedElement && $focusedElement.length)
  13929. this._setFocusedItem($focusedElement);
  13930. else {
  13931. var $activeItem = this._getActiveItem();
  13932. this.option("focusedElement", $activeItem)
  13933. }
  13934. },
  13935. _focusOutHandler: function(e) {
  13936. this.callBase.apply(this, arguments);
  13937. var $target = this.option("focusedElement");
  13938. if ($target)
  13939. $target.removeClass(FOCUSED_STATE_CLASS)
  13940. },
  13941. _getActiveItem: function(last) {
  13942. var $focusedElement = this.option("focusedElement");
  13943. if ($focusedElement && $focusedElement.length)
  13944. return $focusedElement;
  13945. var index = this.option("focusOnSelectedItem") ? this.option("selectedIndex") : 0,
  13946. activeElements = this._getActiveElement(),
  13947. lastIndex = activeElements.length - 1;
  13948. if (index < 0)
  13949. index = last ? lastIndex : 0;
  13950. return activeElements.eq(index)
  13951. },
  13952. _renderFocusTarget: function() {
  13953. this.callBase.apply(this, arguments);
  13954. this._refreshActiveDescendant()
  13955. },
  13956. _moveFocus: function(location) {
  13957. var $items = this._itemElements().filter(":visible").not(".dx-state-disabled"),
  13958. $newTarget;
  13959. switch (location) {
  13960. case FOCUS_PAGE_UP:
  13961. case FOCUS_UP:
  13962. $newTarget = this._prevItem($items);
  13963. break;
  13964. case FOCUS_PAGE_DOWN:
  13965. case FOCUS_DOWN:
  13966. $newTarget = this._nextItem($items);
  13967. break;
  13968. case FOCUS_RIGHT:
  13969. $newTarget = this.option("rtlEnabled") ? this._prevItem($items) : this._nextItem($items);
  13970. break;
  13971. case FOCUS_LEFT:
  13972. $newTarget = this.option("rtlEnabled") ? this._nextItem($items) : this._prevItem($items);
  13973. break;
  13974. case FOCUS_FIRST:
  13975. $newTarget = $items.first();
  13976. break;
  13977. case FOCUS_LAST:
  13978. $newTarget = $items.last();
  13979. break;
  13980. default:
  13981. return false
  13982. }
  13983. if ($newTarget.length !== 0)
  13984. this.option("focusedElement", $newTarget)
  13985. },
  13986. _prevItem: function($items) {
  13987. var $target = this._getActiveItem(),
  13988. targetIndex = $items.index($target),
  13989. $last = $items.last(),
  13990. $item = $($items[targetIndex - 1]),
  13991. loop = this.option("loopItemFocus");
  13992. if ($item.length === 0 && loop)
  13993. $item = $last;
  13994. return $item
  13995. },
  13996. _nextItem: function($items) {
  13997. var $target = this._getActiveItem(true),
  13998. targetIndex = $items.index($target),
  13999. $first = $items.first(),
  14000. $item = $($items[targetIndex + 1]),
  14001. loop = this.option("loopItemFocus");
  14002. if ($item.length === 0 && loop)
  14003. $item = $first;
  14004. return $item
  14005. },
  14006. _selectFocusedItem: function($target) {
  14007. this.selectItem($target)
  14008. },
  14009. _removeFocusedItem: function($target) {
  14010. if ($target && $target.length) {
  14011. $target.removeClass(FOCUSED_STATE_CLASS);
  14012. $target.removeAttr("id")
  14013. }
  14014. },
  14015. _refreshActiveDescendant: function() {
  14016. this.setAria("activedescendant", "");
  14017. this.setAria("activedescendant", this.getFocusedItemId())
  14018. },
  14019. _setFocusedItem: function($target) {
  14020. if (!$target || !$target.length)
  14021. return;
  14022. $target.attr("id", this.getFocusedItemId());
  14023. $target.addClass(FOCUSED_STATE_CLASS);
  14024. this.onFocusedItemChanged(this.getFocusedItemId());
  14025. this._refreshActiveDescendant();
  14026. if (this.option("selectOnFocus"))
  14027. this._selectFocusedItem($target)
  14028. },
  14029. _optionChanged: function(args) {
  14030. switch (args.name) {
  14031. case"items":
  14032. case"_itemAttributes":
  14033. case"itemTemplateProperty":
  14034. this._cleanRenderedItems();
  14035. this._invalidate();
  14036. break;
  14037. case"dataSource":
  14038. this._refreshDataSource();
  14039. if (!this._dataSource)
  14040. this.option("items", []);
  14041. this._renderEmptyMessage();
  14042. break;
  14043. case"noDataText":
  14044. this._renderEmptyMessage();
  14045. break;
  14046. case"itemTemplate":
  14047. this._invalidate();
  14048. break;
  14049. case"onItemRendered":
  14050. this._createItemRenderAction();
  14051. break;
  14052. case"onItemClick":
  14053. break;
  14054. case"onItemHold":
  14055. case"itemHoldTimeout":
  14056. this._attachHoldEvent();
  14057. break;
  14058. case"onItemContextMenu":
  14059. this._attachContextMenuEvent();
  14060. break;
  14061. case"onFocusedItemChanged":
  14062. this.onFocusedItemChanged = this._createActionByOption("onFocusedItemChanged");
  14063. break;
  14064. case"selectOnFocus":
  14065. case"loopItemFocus":
  14066. case"focusOnSelectedItem":
  14067. break;
  14068. case"focusedElement":
  14069. this._removeFocusedItem(args.previousValue);
  14070. this._setFocusedItem(args.value);
  14071. break;
  14072. default:
  14073. this.callBase(args)
  14074. }
  14075. },
  14076. _loadNextPage: function() {
  14077. var dataSource = this._dataSource;
  14078. this._expectNextPageLoading();
  14079. dataSource.pageIndex(1 + dataSource.pageIndex());
  14080. return dataSource.load()
  14081. },
  14082. _expectNextPageLoading: function() {
  14083. this._startIndexForAppendedItems = 0
  14084. },
  14085. _expectLastItemLoading: function() {
  14086. this._startIndexForAppendedItems = -1
  14087. },
  14088. _forgetNextPageLoading: function() {
  14089. this._startIndexForAppendedItems = null
  14090. },
  14091. _dataSourceChangedHandler: function(newItems) {
  14092. var items = this.option("items");
  14093. if (this._initialized && items && this._shouldAppendItems()) {
  14094. this._renderedItemsCount = items.length;
  14095. if (!this._isLastPage() || this._startIndexForAppendedItems !== -1)
  14096. this.option().items = items.concat(newItems.slice(this._startIndexForAppendedItems));
  14097. this._forgetNextPageLoading();
  14098. this._renderContent();
  14099. this._renderFocusTarget()
  14100. }
  14101. else
  14102. this.option("items", newItems)
  14103. },
  14104. _dataSourceLoadErrorHandler: function() {
  14105. this._forgetNextPageLoading();
  14106. this.option("items", this.option("items"))
  14107. },
  14108. _shouldAppendItems: function() {
  14109. return this._startIndexForAppendedItems != null && this._allowDinamicItemsAppend()
  14110. },
  14111. _allowDinamicItemsAppend: function() {
  14112. return false
  14113. },
  14114. _clean: function() {
  14115. this._cleanFocusState();
  14116. this._cleanItemContainer()
  14117. },
  14118. _cleanItemContainer: function() {
  14119. this._itemContainer().empty()
  14120. },
  14121. _refresh: function() {
  14122. this._cleanRenderedItems();
  14123. this.callBase.apply(this, arguments)
  14124. },
  14125. _itemContainer: function() {
  14126. return this.element()
  14127. },
  14128. _itemClass: function() {
  14129. return ITEM_CLASS
  14130. },
  14131. _itemContentClass: function() {
  14132. return this._itemClass() + CONTENT_CLASS_POSTFIX
  14133. },
  14134. _selectedItemClass: function() {
  14135. return SELECTED_ITEM_CLASS
  14136. },
  14137. _itemResponseWaitClass: function() {
  14138. return ITEM_RESPONSE_WAIT_CLASS
  14139. },
  14140. _itemSelector: function() {
  14141. return "." + this._itemClass()
  14142. },
  14143. _itemDataKey: function() {
  14144. return ITEM_DATA_KEY
  14145. },
  14146. _itemElements: function() {
  14147. return this._itemContainer().find(this._itemSelector())
  14148. },
  14149. _render: function() {
  14150. this.callBase();
  14151. this.element().addClass(COLLECTION_CLASS);
  14152. this._attachClickEvent();
  14153. this._attachHoldEvent();
  14154. this._attachContextMenuEvent();
  14155. this.onFocusedItemChanged = this._createActionByOption("onFocusedItemChanged")
  14156. },
  14157. _attachClickEvent: function() {
  14158. var itemSelector = this._itemSelector(),
  14159. clickEventNamespace = events.addNamespace("dxclick", this.NAME),
  14160. pointerDownEventNamespace = events.addNamespace("dxpointerdown", this.NAME),
  14161. that = this;
  14162. var pointerDownAction = new DX.Action(function(args) {
  14163. var event = args.event;
  14164. that._itemPointerDownHandler(event)
  14165. });
  14166. this._itemContainer().off(clickEventNamespace, itemSelector).off(pointerDownEventNamespace, itemSelector).on(clickEventNamespace, itemSelector, $.proxy(this._itemClickHandler, this)).on(pointerDownEventNamespace, itemSelector, function(e) {
  14167. pointerDownAction.execute({
  14168. element: $(e.target),
  14169. event: e
  14170. })
  14171. })
  14172. },
  14173. _itemClickHandler: function(e) {
  14174. this._itemJQueryEventHandler(e, "onItemClick")
  14175. },
  14176. _itemPointerDownHandler: function(e) {
  14177. if (!this.option("focusStateEnabled"))
  14178. return;
  14179. var elementClass = this._itemClass(),
  14180. $target = $(e.target).closest("." + elementClass);
  14181. if ($target.hasClass(elementClass))
  14182. this.option("focusedElement", $target)
  14183. },
  14184. _attachHoldEvent: function() {
  14185. var $itemContainer = this._itemContainer(),
  14186. itemSelector = this._itemSelector(),
  14187. eventName = events.addNamespace("dxhold", this.NAME);
  14188. $itemContainer.off(eventName, itemSelector);
  14189. if (this._shouldAttachHoldEvent())
  14190. $itemContainer.on(eventName, itemSelector, {timeout: this._getHoldTimeout()}, $.proxy(this._itemHoldHandler, this))
  14191. },
  14192. _getHoldTimeout: function() {
  14193. return this.option("itemHoldTimeout")
  14194. },
  14195. _shouldAttachHoldEvent: function() {
  14196. return this.option("onItemHold")
  14197. },
  14198. _itemHoldHandler: function(e) {
  14199. this._itemJQueryEventHandler(e, "onItemHold")
  14200. },
  14201. _attachContextMenuEvent: function() {
  14202. var $itemContainer = this._itemContainer(),
  14203. itemSelector = this._itemSelector(),
  14204. eventName = events.addNamespace("dxcontextmenu", this.NAME);
  14205. $itemContainer.off(eventName, itemSelector);
  14206. if (this._shouldAttachContextMenuEvent())
  14207. $itemContainer.on(eventName, itemSelector, $.proxy(this._itemContextMenuHandler, this))
  14208. },
  14209. _shouldAttachContextMenuEvent: function() {
  14210. return this.option("onItemContextMenu")
  14211. },
  14212. _itemContextMenuHandler: function(e) {
  14213. this._itemJQueryEventHandler(e, "onItemContextMenu")
  14214. },
  14215. _renderContentImpl: function() {
  14216. var items = this.option("items") || [];
  14217. if (this._renderedItemsCount)
  14218. this._renderItems(items.slice(this._renderedItemsCount));
  14219. else
  14220. this._renderItems(items)
  14221. },
  14222. _renderItems: function(items) {
  14223. if (items.length)
  14224. $.each(items, $.proxy(this._renderItem, this));
  14225. this._renderEmptyMessage()
  14226. },
  14227. _renderItem: function(index, itemData, $container) {
  14228. $container = $container || this._itemContainer();
  14229. var $itemFrame = this._renderItemFrame(index, itemData, $container);
  14230. this._setElementData($itemFrame, itemData);
  14231. var $itemContent = $itemFrame.find("." + ITEM_CONTENT_PLACEHOLDER_CLASS);
  14232. $itemContent.removeClass(ITEM_CONTENT_PLACEHOLDER_CLASS);
  14233. $itemContent = this._renderItemContent(index, itemData, $itemContent);
  14234. this._postprocessRenderItem({
  14235. itemElement: $itemFrame,
  14236. itemContent: $itemContent,
  14237. itemData: itemData,
  14238. itemIndex: index
  14239. });
  14240. this._executeItemRenderAction(index, itemData, $itemFrame);
  14241. this._attachItemClickEvent(itemData, $itemFrame);
  14242. return $itemFrame.attr(this.option("_itemAttributes"))
  14243. },
  14244. _attachItemClickEvent: function(itemData, $itemElement) {
  14245. if (!itemData || !itemData.onClick)
  14246. return;
  14247. $itemElement.on("dxclick", $.proxy(function(e) {
  14248. this._itemEventHandlerByHandler($itemElement, itemData.onClick, {jQueryEvent: e})
  14249. }, this))
  14250. },
  14251. _renderItemContent: function(index, itemData, $container) {
  14252. var $itemNode = itemData && itemData.node;
  14253. var itemTemplateName = this._getItemTemplateName(itemData);
  14254. var itemTemplate = this._getTemplate(itemTemplateName, itemData, index, $container);
  14255. var renderArgs = {
  14256. index: index,
  14257. item: itemData,
  14258. container: $container
  14259. };
  14260. if ($itemNode) {
  14261. $container.replaceWith($itemNode);
  14262. $container = $itemNode;
  14263. this._addItemContentClasses($container, itemData)
  14264. }
  14265. else {
  14266. this._addItemContentClasses($container, itemData);
  14267. var $result = this._createItemByTemplate(itemTemplate, renderArgs);
  14268. if ($result.hasClass(TEMPLATE_WRAPPER_CLASS)) {
  14269. $container.replaceWith($result);
  14270. $container = $result;
  14271. this._addItemContentClasses($container, itemData)
  14272. }
  14273. }
  14274. return $container
  14275. },
  14276. _addItemContentClasses: function($container) {
  14277. $container.addClass([ITEM_CLASS + CONTENT_CLASS_POSTFIX, this._itemContentClass()].join(" "))
  14278. },
  14279. _renderItemFrame: function(index, itemData, $container) {
  14280. var itemFrameTemplate = this.option("templateProvider").getTemplates(this)["itemFrame"],
  14281. $itemFrame = itemFrameTemplate.render(utils.isDefined(itemData) ? itemData : {}, $container, index);
  14282. $itemFrame.appendTo($container);
  14283. return $itemFrame
  14284. },
  14285. _postprocessRenderItem: $.noop,
  14286. _executeItemRenderAction: function(index, itemData, itemElement) {
  14287. this._getItemRenderAction()({
  14288. itemElement: itemElement,
  14289. itemIndex: index,
  14290. itemData: itemData
  14291. })
  14292. },
  14293. _setElementData: function(element, data) {
  14294. element.addClass([ITEM_CLASS, this._itemClass()].join(" ")).data(this._itemDataKey(), data)
  14295. },
  14296. _createItemRenderAction: function() {
  14297. return this._itemRenderAction = this._createActionByOption("onItemRendered", {
  14298. element: this.element(),
  14299. excludeValidators: ["designMode", "disabled", "readOnly"],
  14300. category: "rendering"
  14301. })
  14302. },
  14303. _getItemRenderAction: function() {
  14304. return this._itemRenderAction || this._createItemRenderAction()
  14305. },
  14306. _getItemTemplateName: function(itemData) {
  14307. var templateProperty = this.option("itemTemplateProperty");
  14308. return itemData && itemData[templateProperty] || this.option("itemTemplate")
  14309. },
  14310. _createItemByTemplate: function(itemTemplate, renderArgs) {
  14311. return itemTemplate.render(renderArgs.item, renderArgs.container, renderArgs.index, "ignoreTarget")
  14312. },
  14313. _renderEmptyMessage: function() {
  14314. var noDataText = this.option("noDataText"),
  14315. items = this.option("items"),
  14316. hideNoData = !noDataText || items && items.length || this._isDataSourceLoading();
  14317. if (hideNoData && this._$nodata) {
  14318. this._$nodata.remove();
  14319. this._$nodata = null;
  14320. this.setAria("label", undefined)
  14321. }
  14322. if (!hideNoData) {
  14323. this._$nodata = this._$nodata || $("<div>").addClass("dx-empty-message");
  14324. this._$nodata.appendTo(this._itemContainer()).html(noDataText);
  14325. this.setAria("label", noDataText)
  14326. }
  14327. this.element().toggleClass(EMPTY_COLLECTION, !hideNoData)
  14328. },
  14329. _itemJQueryEventHandler: function(jQueryEvent, handlerOptionName, actionArgs, actionConfig) {
  14330. this._itemEventHandler(jQueryEvent.target, handlerOptionName, $.extend(actionArgs, {jQueryEvent: jQueryEvent}), actionConfig)
  14331. },
  14332. _itemEventHandler: function(initiator, handlerOptionName, actionArgs, actionConfig) {
  14333. var action = this._createActionByOption(handlerOptionName, $.extend({validatingTargetName: "itemElement"}, actionConfig));
  14334. return this._itemEventHandlerImpl(initiator, action, actionArgs)
  14335. },
  14336. _itemEventHandlerByHandler: function(initiator, handler, actionArgs, actionConfig) {
  14337. var action = this._createAction(handler, $.extend({validatingTargetName: "itemElement"}, actionConfig));
  14338. return this._itemEventHandlerImpl(initiator, action, actionArgs)
  14339. },
  14340. _itemEventHandlerImpl: function(initiator, action, actionArgs) {
  14341. var $itemElement = this._closestItemElement($(initiator));
  14342. return action($.extend(this._extendActionArgs($itemElement), actionArgs))
  14343. },
  14344. _extendActionArgs: function($itemElement) {
  14345. return {
  14346. itemElement: $itemElement,
  14347. itemIndex: $itemElement.index(this._itemSelector()),
  14348. itemData: this._getItemData($itemElement)
  14349. }
  14350. },
  14351. _closestItemElement: function($element) {
  14352. return $($element).closest(this._itemSelector())
  14353. },
  14354. _getItemData: function(itemElement) {
  14355. return $(itemElement).data(this._itemDataKey())
  14356. },
  14357. getFocusedItemId: function() {
  14358. if (!this._focusedItemId)
  14359. this._focusedItemId = new DevExpress.data.Guid;
  14360. return this._focusedItemId
  14361. },
  14362. itemElements: function() {
  14363. return this._itemElements()
  14364. },
  14365. itemsContainer: function() {
  14366. return this._itemContainer()
  14367. }
  14368. }).include(ui.DataHelperMixin);
  14369. ui.CollectionWidget = CollectionWidget
  14370. })(jQuery, DevExpress);
  14371. /*! Module core, file ui.CollectionWidget.edit.js */
  14372. (function($, DX, undefined) {
  14373. var ui = DX.ui,
  14374. utils = DX.utils;
  14375. var ITEM_DELETING_DATA_KEY = "dxItemDeleting";
  14376. var CollectionWidget = ui.CollectionWidget.inherit({
  14377. _setOptionsByReference: function() {
  14378. this.callBase();
  14379. $.extend(this._optionsByReference, {selectedItem: true})
  14380. },
  14381. _setDeprecatedOptions: function() {
  14382. this.callBase();
  14383. $.extend(this._deprecatedOptions, {itemSelectAction: {
  14384. since: "14.2",
  14385. message: "Use the 'onSelectionChanged' option instead"
  14386. }})
  14387. },
  14388. _setDefaultOptions: function() {
  14389. this.callBase();
  14390. this.option({
  14391. selectionMode: 'none',
  14392. selectionRequired: false,
  14393. selectionByClick: true,
  14394. selectedItems: [],
  14395. selectedIndex: -1,
  14396. selectedItem: null,
  14397. onSelectionChanged: null,
  14398. onItemReordered: null,
  14399. onItemDeleting: null,
  14400. onItemDeleted: null
  14401. })
  14402. },
  14403. _init: function() {
  14404. this.callBase();
  14405. this._initEditStrategy();
  14406. this._selectedItemIndices = []
  14407. },
  14408. _initEditStrategy: function() {
  14409. var strategy = ui.CollectionWidget.PlainEditStrategy;
  14410. this._editStrategy = new strategy(this)
  14411. },
  14412. _render: function() {
  14413. this._syncSelectionOptions();
  14414. this._normalizeSelectedItems();
  14415. this._initSelectedItems();
  14416. this.callBase();
  14417. this._renderSelection(this._selectedItemIndices, [])
  14418. },
  14419. _syncSelectionOptions: function(byOption) {
  14420. byOption = byOption || this._chooseSelectOption();
  14421. var selectedItem,
  14422. selectedItems;
  14423. switch (byOption) {
  14424. case"selectedIndex":
  14425. selectedItem = this._editStrategy.getItemDataByIndex(this.option("selectedIndex"));
  14426. if (utils.isDefined(selectedItem)) {
  14427. this._setOptionSilent("selectedItems", [selectedItem]);
  14428. this._setOptionSilent("selectedItem", selectedItem)
  14429. }
  14430. else {
  14431. this._setOptionSilent("selectedItems", []);
  14432. this._setOptionSilent("selectedItem", null)
  14433. }
  14434. break;
  14435. case"selectedItems":
  14436. selectedItems = this.option("selectedItems") || [];
  14437. this._setOptionSilent("selectedItem", selectedItems[0]);
  14438. this._setOptionSilent("selectedIndex", this._editStrategy.getIndexByItemData(selectedItems[0]));
  14439. break;
  14440. case"selectedItem":
  14441. selectedItem = this.option("selectedItem");
  14442. if (utils.isDefined(selectedItem)) {
  14443. this._setOptionSilent("selectedItems", [selectedItem]);
  14444. this._setOptionSilent("selectedIndex", this._editStrategy.getIndexByItemData(selectedItem))
  14445. }
  14446. else {
  14447. this._setOptionSilent("selectedItems", []);
  14448. this._setOptionSilent("selectedIndex", -1)
  14449. }
  14450. break
  14451. }
  14452. },
  14453. _chooseSelectOption: function() {
  14454. var optionName = "selectedIndex";
  14455. if (this.option("selectedItems").length)
  14456. optionName = "selectedItems";
  14457. else if (utils.isDefined(this.option("selectedItem")))
  14458. optionName = "selectedItem";
  14459. return optionName
  14460. },
  14461. _normalizeSelectedItems: function() {
  14462. if (this.option("selectionMode") === "none") {
  14463. this._setOptionSilent("selectedItems", []);
  14464. this._syncSelectionOptions("selectedItems")
  14465. }
  14466. else if (this.option("selectionMode") === "single") {
  14467. var newSelection = this._editStrategy.selectedItemIndices(this.option("selectedItems"));
  14468. if (newSelection.length > 1 || !newSelection.length && this.option("selectionRequired") && this.option("items") && this.option("items").length) {
  14469. var normalizedSelection = [newSelection[0] || this._selectedItemIndices[0] || 0];
  14470. this._setOptionSilent("selectedItems", this._editStrategy.fetchSelectedItems(normalizedSelection));
  14471. this._syncSelectionOptions("selectedItems")
  14472. }
  14473. }
  14474. },
  14475. _initSelectedItems: function() {
  14476. this._selectedItemIndices = this._editStrategy.selectedItemIndices(this.option("selectedItems"))
  14477. },
  14478. _renderSelection: $.noop,
  14479. _itemClickHandler: function(e) {
  14480. this._createAction($.proxy(function(e) {
  14481. this._itemSelectHandler(e.jQueryEvent)
  14482. }, this), {validatingTargetName: "itemElement"})({
  14483. itemElement: $(e.currentTarget),
  14484. jQueryEvent: e
  14485. });
  14486. this.callBase.apply(this, arguments)
  14487. },
  14488. _itemSelectHandler: function(e) {
  14489. if (!this.option("selectionByClick"))
  14490. return;
  14491. var $itemElement = e.currentTarget;
  14492. if (this.isItemSelected($itemElement))
  14493. this.unselectItem(e.currentTarget);
  14494. else
  14495. this.selectItem(e.currentTarget)
  14496. },
  14497. _selectedItemElement: function(index) {
  14498. return this._itemElements().eq(index)
  14499. },
  14500. _postprocessRenderItem: function(args) {
  14501. var $itemElement = $(args.itemElement);
  14502. if (this._isItemSelected(this._editStrategy.getNormalizedIndex($itemElement))) {
  14503. $itemElement.addClass(this._selectedItemClass());
  14504. this._setAriaSelected($itemElement, "true")
  14505. }
  14506. else
  14507. this._setAriaSelected($itemElement, "false")
  14508. },
  14509. _updateSelectedItems: function() {
  14510. var oldSelection = this._selectedItemIndices.slice(),
  14511. newSelection = this._editStrategy.selectedItemIndices(),
  14512. addedSelection = utils.removeDublicates(newSelection, oldSelection),
  14513. removedSelection = utils.removeDublicates(oldSelection, newSelection);
  14514. $.each(removedSelection, $.proxy(function(_, normalizedIndex) {
  14515. this._removeSelection(normalizedIndex)
  14516. }, this));
  14517. $.each(addedSelection, $.proxy(function(_, normalizedIndex) {
  14518. this._addSelection(normalizedIndex)
  14519. }, this));
  14520. if (removedSelection.length || addedSelection.length) {
  14521. var selectionChangePromise = this._selectionChangePromise;
  14522. this._updateSelection(addedSelection, removedSelection);
  14523. $.when(selectionChangePromise).done($.proxy(function() {
  14524. this._fireSelectItemEvent(addedSelection, removedSelection);
  14525. this._fireSelectionChangeEvent(addedSelection, removedSelection)
  14526. }, this))
  14527. }
  14528. },
  14529. _fireSelectionChangeEvent: function(addedSelection, removedSelection) {
  14530. this._createActionByOption("onSelectionChanged", {excludeValidators: ["disabled", "readOnly"]})({
  14531. addedItems: this._editStrategy.fetchSelectedItems(addedSelection),
  14532. removedItems: this._editStrategy.fetchSelectedItems(removedSelection)
  14533. })
  14534. },
  14535. _fireSelectItemEvent: function(addedSelection, removedSelection) {
  14536. if (this.NAME === "dxList" && this.option("selectionMode") !== "single")
  14537. return;
  14538. this._itemEventHandler(this._selectedItemElement(addedSelection[0]), "itemSelectAction", {
  14539. selectedIndex: addedSelection[0],
  14540. previousIndex: removedSelection[0]
  14541. }, {excludeValidators: ["disabled", "readOnly"]})
  14542. },
  14543. _updateSelection: function() {
  14544. this._renderSelection.apply(this, arguments)
  14545. },
  14546. _setAriaSelected: function($target, value) {
  14547. this.setAria("selected", value, $target)
  14548. },
  14549. _removeSelection: function(normalizedIndex) {
  14550. var $itemElement = this._editStrategy.getItemElement(normalizedIndex),
  14551. itemSelectionIndex = $.inArray(normalizedIndex, this._selectedItemIndices);
  14552. if (itemSelectionIndex > -1) {
  14553. $itemElement.removeClass(this._selectedItemClass());
  14554. this._setAriaSelected($itemElement, "false");
  14555. this._selectedItemIndices.splice(itemSelectionIndex, 1);
  14556. $itemElement.triggerHandler("stateChanged");
  14557. if (this.NAME === "dxList")
  14558. this._itemEventHandler($itemElement, "itemUnselectAction", {}, {excludeValidators: ["disabled", "readOnly"]})
  14559. }
  14560. },
  14561. _addSelection: function(normalizedIndex) {
  14562. var $itemElement = this._editStrategy.getItemElement(normalizedIndex);
  14563. if (normalizedIndex > -1 && !this._isItemSelected(normalizedIndex)) {
  14564. $itemElement.addClass(this._selectedItemClass());
  14565. this._setAriaSelected($itemElement, "true");
  14566. this._selectedItemIndices.push(normalizedIndex);
  14567. $itemElement.triggerHandler("stateChanged");
  14568. if (this.NAME === "dxList")
  14569. this._itemEventHandler($itemElement, "itemSelectAction", {}, {excludeValidators: ["disabled", "readOnly"]})
  14570. }
  14571. },
  14572. _isItemSelected: function(index) {
  14573. return $.inArray(index, this._selectedItemIndices) > -1
  14574. },
  14575. _optionChanged: function(args) {
  14576. if (this._cancelOptionChange)
  14577. return;
  14578. switch (args.name) {
  14579. case"items":
  14580. if (args.previousValue && args.previousValue.length > 0)
  14581. this._clearSelectedItems();
  14582. this.callBase(args);
  14583. break;
  14584. case"selectionMode":
  14585. this._invalidate();
  14586. break;
  14587. case"selectedIndex":
  14588. case"selectedItem":
  14589. case"selectedItems":
  14590. this._syncSelectionOptions(args.name);
  14591. this._normalizeSelectedItems();
  14592. this._updateSelectedItems();
  14593. break;
  14594. case"selectionRequired":
  14595. this._normalizeSelectedItems();
  14596. this._updateSelectedItems();
  14597. break;
  14598. case"selectionByClick":
  14599. case"onSelectionChanged":
  14600. case"onItemDeleting":
  14601. case"onItemDeleted":
  14602. case"onItemReordered":
  14603. case"itemSelectAction":
  14604. case"itemUnselectAction":
  14605. break;
  14606. default:
  14607. this.callBase(args)
  14608. }
  14609. },
  14610. _clearSelectedItems: function() {
  14611. this._selectedItemIndices = [];
  14612. this.option("selectedItems", [])
  14613. },
  14614. _setOptionSilent: function(name, value) {
  14615. this._cancelOptionChange = true;
  14616. this.option(name, value);
  14617. this._cancelOptionChange = false
  14618. },
  14619. _waitDeletingPrepare: function($itemElement) {
  14620. if ($itemElement.data(ITEM_DELETING_DATA_KEY))
  14621. return $.Deferred().resolve().promise();
  14622. $itemElement.data(ITEM_DELETING_DATA_KEY, true);
  14623. var deferred = $.Deferred(),
  14624. deletePromise = this._itemEventHandler($itemElement, "onItemDeleting", {}, {excludeValidators: ["disabled", "readOnly"]});
  14625. $.when(deletePromise).always($.proxy(function(value) {
  14626. var deletePromiseExists = !deletePromise,
  14627. deletePromiseResolved = !deletePromiseExists && deletePromise.state() === "resolved",
  14628. argumentsSpecified = !!arguments.length,
  14629. shouldDelete = deletePromiseExists || deletePromiseResolved && !argumentsSpecified || deletePromiseResolved && value;
  14630. $itemElement.data(ITEM_DELETING_DATA_KEY, false);
  14631. shouldDelete ? deferred.resolve() : deferred.reject()
  14632. }, this));
  14633. return deferred.promise()
  14634. },
  14635. _deleteItemFromDS: function($item) {
  14636. if (!this._dataSource)
  14637. return $.Deferred().resolve().promise();
  14638. var deferred = $.Deferred(),
  14639. disabledState = this.option("disabled"),
  14640. dataStore = this._dataSource.store();
  14641. this.option("disabled", true);
  14642. if (!dataStore.remove)
  14643. throw DX.Error("E1011");
  14644. dataStore.remove(dataStore.keyOf(this._getItemData($item))).done(function(key) {
  14645. if (key !== undefined)
  14646. deferred.resolve();
  14647. else
  14648. deferred.reject()
  14649. }).fail(function() {
  14650. deferred.reject()
  14651. });
  14652. deferred.always($.proxy(function() {
  14653. this.option("disabled", disabledState)
  14654. }, this));
  14655. return deferred
  14656. },
  14657. _tryRefreshLastPage: function() {
  14658. var deferred = $.Deferred();
  14659. if (this._isLastPage() || this.option("grouped"))
  14660. deferred.resolve();
  14661. else
  14662. this._refreshLastPage().done(function() {
  14663. deferred.resolve()
  14664. });
  14665. return deferred.promise()
  14666. },
  14667. _refreshLastPage: function() {
  14668. this._expectLastItemLoading();
  14669. return this._dataSource.load()
  14670. },
  14671. _updateSelectionAfterDelete: function(fromIndex) {
  14672. var itemIndex = $.inArray(fromIndex, this._selectedItemIndices);
  14673. if (itemIndex > -1)
  14674. this._selectedItemIndices.splice(itemIndex, 1);
  14675. this._editStrategy.updateSelectionAfterDelete(fromIndex);
  14676. this.option("selectedItems", this._editStrategy.fetchSelectedItems())
  14677. },
  14678. _simulateOptionChange: function(optionName) {
  14679. var optionValue = this.option(optionName);
  14680. if (optionValue instanceof DX.data.DataSource)
  14681. return;
  14682. this.fireEvent("optionChanged", [{
  14683. name: optionName,
  14684. fullName: optionName,
  14685. value: optionValue
  14686. }])
  14687. },
  14688. isItemSelected: function(itemElement) {
  14689. return this._isItemSelected(this._editStrategy.getNormalizedIndex(itemElement))
  14690. },
  14691. selectItem: function(itemElement) {
  14692. var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);
  14693. if (itemIndex === -1)
  14694. return;
  14695. var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);
  14696. if (itemSelectionIndex !== -1)
  14697. return;
  14698. if (this.option("selectionMode") === "single")
  14699. this.option("selectedItems", this._editStrategy.fetchSelectedItems([itemIndex]));
  14700. else {
  14701. var newSelectedIndices = this._selectedItemIndices.slice();
  14702. newSelectedIndices.push(itemIndex);
  14703. this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))
  14704. }
  14705. },
  14706. unselectItem: function(itemElement) {
  14707. var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);
  14708. if (itemIndex === -1)
  14709. return;
  14710. var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);
  14711. if (itemSelectionIndex === -1)
  14712. return;
  14713. var newSelectedIndices = this._selectedItemIndices.slice();
  14714. newSelectedIndices.splice(itemSelectionIndex, 1);
  14715. if (this.option("selectionRequired") && newSelectedIndices.length === 0)
  14716. return;
  14717. this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))
  14718. },
  14719. deleteItem: function(itemElement) {
  14720. var that = this,
  14721. deferred = $.Deferred(),
  14722. $item = this._editStrategy.getItemElement(itemElement),
  14723. index = this._editStrategy.getNormalizedIndex(itemElement),
  14724. changingOption = this._dataSource ? "dataSource" : "items",
  14725. itemResponseWaitClass = this._itemResponseWaitClass();
  14726. if (index > -1)
  14727. this._waitDeletingPrepare($item).done(function() {
  14728. $item.addClass(itemResponseWaitClass);
  14729. that._deleteItemFromDS($item).done(function() {
  14730. that._editStrategy.deleteItemAtIndex(index);
  14731. that._simulateOptionChange(changingOption);
  14732. that._updateSelectionAfterDelete(index);
  14733. that._itemEventHandler($item, "onItemDeleted", {}, {
  14734. beforeExecute: function() {
  14735. $item.detach()
  14736. },
  14737. excludeValidators: ["disabled", "readOnly"]
  14738. });
  14739. that._renderEmptyMessage();
  14740. that._tryRefreshLastPage().done(function() {
  14741. deferred.resolveWith(that)
  14742. })
  14743. }).fail(function() {
  14744. $item.removeClass(itemResponseWaitClass);
  14745. deferred.rejectWith(that)
  14746. })
  14747. }).fail(function() {
  14748. deferred.rejectWith(that)
  14749. });
  14750. else
  14751. deferred.rejectWith(that);
  14752. return deferred.promise()
  14753. },
  14754. reorderItem: function(itemElement, toItemElement) {
  14755. var deferred = $.Deferred(),
  14756. that = this,
  14757. strategy = this._editStrategy,
  14758. $movingItem = strategy.getItemElement(itemElement),
  14759. $destinationItem = strategy.getItemElement(toItemElement),
  14760. movingIndex = strategy.getNormalizedIndex(itemElement),
  14761. destinationIndex = strategy.getNormalizedIndex(toItemElement),
  14762. changingOption;
  14763. var canMoveItems = movingIndex > -1 && destinationIndex > -1 && movingIndex !== destinationIndex;
  14764. if (canMoveItems)
  14765. if (this._dataSource) {
  14766. changingOption = "dataSource";
  14767. deferred.resolveWith(this)
  14768. }
  14769. else {
  14770. changingOption = "items";
  14771. deferred.resolveWith(this)
  14772. }
  14773. else
  14774. deferred.rejectWith(this);
  14775. return deferred.promise().done(function() {
  14776. $destinationItem[strategy.itemPlacementFunc(movingIndex, destinationIndex)]($movingItem);
  14777. var newSelectedItems = strategy.getSelectedItemsAfterReorderItem(movingIndex, destinationIndex);
  14778. strategy.moveItemAtIndexToIndex(movingIndex, destinationIndex);
  14779. that._selectedItemIndices = strategy.selectedItemIndices(newSelectedItems);
  14780. that.option("selectedItems", strategy.fetchSelectedItems());
  14781. that._simulateOptionChange(changingOption);
  14782. that._itemEventHandler($movingItem, "onItemReordered", {
  14783. fromIndex: strategy.getIndex(movingIndex),
  14784. toIndex: strategy.getIndex(destinationIndex)
  14785. }, {excludeValidators: ["disabled", "readOnly"]})
  14786. })
  14787. }
  14788. });
  14789. ui.CollectionWidget = CollectionWidget
  14790. })(jQuery, DevExpress);
  14791. /*! Module core, file ui.collectionWidget.edit.strategy.js */
  14792. (function($, DX, undefined) {
  14793. var ui = DX.ui;
  14794. ui.CollectionWidget.EditStrategy = DX.Class.inherit({
  14795. ctor: function(collectionWidget) {
  14796. this._collectionWidget = collectionWidget
  14797. },
  14798. getIndexByItemData: DX.abstract,
  14799. getItemDataByIndex: DX.abstract,
  14800. getNormalizedIndex: function(value) {
  14801. if (this._isNormalisedItemIndex(value))
  14802. return value;
  14803. if (this._isItemIndex(value))
  14804. return this._normalizeItemIndex(value);
  14805. return this._getNormalizedItemIndex(value)
  14806. },
  14807. getIndex: function(value) {
  14808. if (this._isNormalisedItemIndex(value))
  14809. return this._denormalizeItemIndex(value);
  14810. if (this._isItemIndex(value))
  14811. return value;
  14812. return this._denormalizeItemIndex(this._getNormalizedItemIndex(value))
  14813. },
  14814. getItemElement: function(value) {
  14815. if (this._isNormalisedItemIndex(value))
  14816. return this._getItemByNormalizedIndex(value);
  14817. if (this._isItemIndex(value))
  14818. return this._getItemByNormalizedIndex(this._normalizeItemIndex(value));
  14819. return $(value)
  14820. },
  14821. deleteItemAtIndex: DX.abstract,
  14822. updateSelectionAfterDelete: DX.abstract,
  14823. fetchSelectedItems: DX.abstract,
  14824. selectedItemIndices: DX.abstract,
  14825. itemPlacementFunc: function(movingIndex, destinationIndex) {
  14826. return this._itemsFromSameParent(movingIndex, destinationIndex) && movingIndex < destinationIndex ? "after" : "before"
  14827. },
  14828. moveItemAtIndexToIndex: DX.abstract,
  14829. getSelectedItemsAfterReorderItem: function() {
  14830. return this._collectionWidget.option("selectedItems")
  14831. },
  14832. _isNormalisedItemIndex: function(index) {
  14833. return $.isNumeric(index)
  14834. },
  14835. _isItemIndex: DX.abstract,
  14836. _getNormalizedItemIndex: DX.abstract,
  14837. _normalizeItemIndex: DX.abstract,
  14838. _denormalizeItemIndex: DX.abstract,
  14839. _getItemByNormalizedIndex: DX.abstract,
  14840. _itemsFromSameParent: DX.abstract
  14841. })
  14842. })(jQuery, DevExpress);
  14843. /*! Module core, file ui.collectionWidget.edit.strategy.plain.js */
  14844. (function($, DX, undefined) {
  14845. var ui = DX.ui;
  14846. ui.CollectionWidget.PlainEditStrategy = ui.CollectionWidget.EditStrategy.inherit({
  14847. _getPlainItems: function() {
  14848. return this._collectionWidget.option("items") || []
  14849. },
  14850. getIndexByItemData: function(itemData) {
  14851. return $.inArray(itemData, this._getPlainItems())
  14852. },
  14853. getItemDataByIndex: function(index) {
  14854. return this._getPlainItems()[index]
  14855. },
  14856. deleteItemAtIndex: function(index) {
  14857. this._getPlainItems().splice(index, 1)
  14858. },
  14859. updateSelectionAfterDelete: function(fromIndex) {
  14860. var selectedItemIndices = this._collectionWidget._selectedItemIndices;
  14861. $.each(selectedItemIndices, function(i, index) {
  14862. if (index > fromIndex)
  14863. selectedItemIndices[i] -= 1
  14864. })
  14865. },
  14866. fetchSelectedItems: function(indices) {
  14867. indices = indices || this._collectionWidget._selectedItemIndices;
  14868. var items = this._getPlainItems(),
  14869. selectedItems = [];
  14870. $.each(indices, function(_, index) {
  14871. selectedItems.push(items[index])
  14872. });
  14873. return selectedItems
  14874. },
  14875. selectedItemIndices: function() {
  14876. var selectedIndices = [],
  14877. items = this._getPlainItems(),
  14878. selected = this._collectionWidget.option("selectedItems");
  14879. $.each(selected, function(_, selectedItem) {
  14880. var index = $.inArray(selectedItem, items);
  14881. if (index !== -1)
  14882. selectedIndices.push(index);
  14883. else
  14884. DX.log("W1002", selectedItem)
  14885. });
  14886. return selectedIndices
  14887. },
  14888. moveItemAtIndexToIndex: function(movingIndex, destinationIndex) {
  14889. var items = this._getPlainItems(),
  14890. movedItemData = items[movingIndex];
  14891. items.splice(movingIndex, 1);
  14892. items.splice(destinationIndex, 0, movedItemData)
  14893. },
  14894. _isItemIndex: function(index) {
  14895. return $.isNumeric(index)
  14896. },
  14897. _getNormalizedItemIndex: function(itemElement) {
  14898. return this._collectionWidget._itemElements().index(itemElement)
  14899. },
  14900. _normalizeItemIndex: function(index) {
  14901. return index
  14902. },
  14903. _denormalizeItemIndex: function(index) {
  14904. return index
  14905. },
  14906. _getItemByNormalizedIndex: function(index) {
  14907. return this._collectionWidget._itemElements().eq(index)
  14908. },
  14909. _itemsFromSameParent: function() {
  14910. return true
  14911. }
  14912. })
  14913. })(jQuery, DevExpress);
  14914. /*! Module core, file ui.tooltip.js */
  14915. (function($, DX, undefined) {
  14916. var $tooltip = null;
  14917. var createTooltip = function(options) {
  14918. options = $.extend({position: "top"}, options);
  14919. var content = options.content;
  14920. delete options.content;
  14921. return $("<div />").html(content).appendTo(DX.viewPort()).dxTooltip(options)
  14922. };
  14923. var removeTooltip = function() {
  14924. if (!$tooltip)
  14925. return;
  14926. $tooltip.remove();
  14927. $tooltip = null
  14928. };
  14929. var tooltip = {
  14930. show: function(options) {
  14931. removeTooltip();
  14932. $tooltip = createTooltip(options);
  14933. return $tooltip.dxTooltip("show")
  14934. },
  14935. hide: function() {
  14936. if (!$tooltip)
  14937. return $.when();
  14938. return $tooltip.dxTooltip("hide").done(removeTooltip).promise()
  14939. }
  14940. };
  14941. DX.ui.tooltip = tooltip
  14942. })(jQuery, DevExpress)
  14943. }
  14944. if (!DevExpress.MOD_VIZ_CORE) {
  14945. if (!window.DevExpress)
  14946. throw Error('Required module is not referenced: core');
  14947. /*! Module viz-core, file namespaces.js */
  14948. (function(DevExpress) {
  14949. DevExpress.viz = {}
  14950. })(DevExpress);
  14951. /*! Module viz-core, file namespaces.js */
  14952. (function(DevExpress) {
  14953. DevExpress.viz.core = {}
  14954. })(DevExpress);
  14955. /*! Module viz-core, file errorsWarnings.js */
  14956. (function($, DX) {
  14957. $.extend(DX.ERROR_MESSAGES, {
  14958. E2001: "Invalid data source",
  14959. E2002: "Axis type and data type are incompatible",
  14960. E2003: "\"{0}\" data source field contains data of unsupported type",
  14961. E2004: "\"{0}\" data source field is inconsistent",
  14962. E2101: "Unknown series type was specified: {0}",
  14963. E2102: "Ambiguity occurred between two value axes with the same name",
  14964. E2103: "\"{0}\" option must be a function",
  14965. E2104: "Invalid logarithm base",
  14966. E2105: "Invalid value of a \"{0}\"",
  14967. E2106: "Invalid visible range",
  14968. E2202: "Invalid scale {0} value",
  14969. E2203: "The \"{0}\" field of the \"selectedRange\" configuration object is not valid",
  14970. W2001: "{0} cannot be drawn because its container is invisible",
  14971. W2002: "The {0} data field is absent",
  14972. W2003: "Tick interval is too small",
  14973. W2101: "\"{0}\" pane does not exist; \"{1}\" pane is used instead",
  14974. W2102: "Value axis with the \"{0}\" name was created automatically",
  14975. W2103: "Chart title was hidden due to container size",
  14976. W2104: "Legend was hidden due to container size",
  14977. W2105: "Title of \"{0}\" axis was hidden due to container size",
  14978. W2106: "Labels of \"{0}\" axis were hidden due to container size",
  14979. W2301: "Invalid value range"
  14980. })
  14981. })(jQuery, DevExpress);
  14982. /*! Module viz-core, file numericTickManager.js */
  14983. (function($, DX, undefined) {
  14984. var core = DX.viz.core,
  14985. utils = DX.utils,
  14986. _isDefined = utils.isDefined,
  14987. _adjustValue = utils.adjustValue,
  14988. _math = Math,
  14989. _abs = _math.abs,
  14990. _ceil = _math.ceil,
  14991. _floor = _math.floor,
  14992. _noop = $.noop,
  14993. MINOR_TICKS_COUNT_LIMIT = 200,
  14994. DEFAULT_MINOR_NUMBER_MULTIPLIERS = [2, 4, 5, 8, 10];
  14995. core.outOfScreen = {
  14996. x: -1000,
  14997. y: -1000
  14998. };
  14999. core.tickManager = {};
  15000. core.tickManager.continuous = {
  15001. _hasUnitBeginningTickCorrection: _noop,
  15002. _removeBoundedOverlappingDates: _noop,
  15003. _correctInterval: function(step) {
  15004. this._tickInterval *= step
  15005. },
  15006. _correctMax: function(tickInterval) {
  15007. this._max = this._adjustNumericTickValue(_ceil(this._max / tickInterval) * tickInterval, tickInterval, this._min)
  15008. },
  15009. _correctMin: function(tickInterval) {
  15010. this._min = this._adjustNumericTickValue(_floor(this._min / tickInterval) * tickInterval, tickInterval, this._min)
  15011. },
  15012. _findBusinessDelta: function(min, max) {
  15013. return _adjustValue(_abs(min - max))
  15014. },
  15015. _findTickIntervalForCustomTicks: function() {
  15016. return _abs(this._customTicks[1] - this._customTicks[0])
  15017. },
  15018. _getBoundInterval: function() {
  15019. var that = this,
  15020. boundCoef = that._options.boundCoef;
  15021. return _isDefined(boundCoef) && isFinite(boundCoef) ? that._tickInterval * _abs(boundCoef) : that._tickInterval / 2
  15022. },
  15023. _getInterval: function(deltaCoef, numberMultipliers) {
  15024. var interval = deltaCoef || this._getDeltaCoef(this._screenDelta, this._businessDelta, this._options.gridSpacingFactor),
  15025. multipliers = numberMultipliers || this._options.numberMultipliers,
  15026. factor,
  15027. result = 0,
  15028. newResult,
  15029. hasResult = false,
  15030. i;
  15031. if (interval > 1.0)
  15032. for (factor = 1; !hasResult; factor *= 10)
  15033. for (i = 0; i < multipliers.length; i++) {
  15034. result = multipliers[i] * factor;
  15035. if (interval <= result) {
  15036. hasResult = true;
  15037. break
  15038. }
  15039. }
  15040. else if (interval > 0) {
  15041. result = 1;
  15042. for (factor = 0.1; !hasResult; factor /= 10)
  15043. for (i = multipliers.length - 1; i >= 0; i--) {
  15044. newResult = multipliers[i] * factor;
  15045. if (interval > newResult) {
  15046. hasResult = true;
  15047. break
  15048. }
  15049. result = newResult
  15050. }
  15051. }
  15052. return _adjustValue(result)
  15053. },
  15054. _getMarginValue: function(min, max, margin) {
  15055. return utils.applyPrecisionByMinDelta(min, margin, _abs(max - min) * margin)
  15056. },
  15057. _getDefaultMinorInterval: function(screenDelta, businessDelta) {
  15058. var deltaCoef = this._getDeltaCoef(screenDelta, businessDelta, this._options.minorGridSpacingFactor),
  15059. multipliers = DEFAULT_MINOR_NUMBER_MULTIPLIERS,
  15060. i = multipliers.length - 1,
  15061. result;
  15062. for (i; i >= 0; i--) {
  15063. result = businessDelta / multipliers[i];
  15064. if (deltaCoef <= result)
  15065. return _adjustValue(result)
  15066. }
  15067. return 0
  15068. },
  15069. _getMinorInterval: function(screenDelta, businessDelta) {
  15070. var that = this,
  15071. options = that._options,
  15072. minorTickInterval = options.minorTickInterval,
  15073. minorTickCount = options.minorTickCount,
  15074. interval,
  15075. intervalsCount,
  15076. count;
  15077. if (isFinite(minorTickInterval) && that._isTickIntervalCorrect(minorTickInterval, MINOR_TICKS_COUNT_LIMIT, businessDelta)) {
  15078. interval = minorTickInterval;
  15079. count = interval < businessDelta ? _ceil(businessDelta / interval) - 1 : 0
  15080. }
  15081. else if (_isDefined(minorTickCount)) {
  15082. intervalsCount = _isDefined(minorTickCount) ? minorTickCount + 1 : _floor(screenDelta / options.minorGridSpacingFactor);
  15083. count = intervalsCount - 1;
  15084. interval = count > 0 ? businessDelta / intervalsCount : 0
  15085. }
  15086. else {
  15087. interval = that._getDefaultMinorInterval(screenDelta, businessDelta);
  15088. count = interval < businessDelta ? _floor(businessDelta / interval) - 1 : 0
  15089. }
  15090. that._minorTickInterval = interval;
  15091. that._minorTickCount = count
  15092. },
  15093. _getNextTickValue: function(value, tickInterval, isTickIntervalNegative) {
  15094. tickInterval = _isDefined(isTickIntervalNegative) && isTickIntervalNegative ? -tickInterval : tickInterval;
  15095. value += tickInterval;
  15096. return this._adjustNumericTickValue(value, tickInterval, this._min)
  15097. },
  15098. _isTickIntervalValid: function(tickInterval) {
  15099. return _isDefined(tickInterval) && isFinite(tickInterval) && tickInterval !== 0
  15100. }
  15101. }
  15102. })(jQuery, DevExpress);
  15103. /*! Module viz-core, file datetimeTickManager.js */
  15104. (function($, DX, undefined) {
  15105. var core = DX.viz.core,
  15106. utils = DX.utils,
  15107. _isDefined = utils.isDefined,
  15108. _convertDateUnitToMilliseconds = utils.convertDateUnitToMilliseconds,
  15109. _correctDateWithUnitBeginning = utils.correctDateWithUnitBeginning,
  15110. _dateToMilliseconds = utils.dateToMilliseconds,
  15111. _convertMillisecondsToDateUnits = utils.convertMillisecondsToDateUnits,
  15112. _math = Math,
  15113. _abs = _math.abs,
  15114. _ceil = _math.ceil,
  15115. _floor = _math.floor,
  15116. _round = _math.round,
  15117. MINOR_TICKS_COUNT_LIMIT = 50,
  15118. DEFAULT_DATETIME_MULTIPLIERS = {
  15119. millisecond: [1, 2, 5, 10, 25, 100, 250, 300, 500],
  15120. second: [1, 2, 3, 5, 10, 15, 20, 30],
  15121. minute: [1, 2, 3, 5, 10, 15, 20, 30],
  15122. hour: [1, 2, 3, 4, 6, 8, 12],
  15123. day: [1, 2, 3, 5, 7, 10, 14],
  15124. month: [1, 2, 3, 6]
  15125. };
  15126. core.tickManager.datetime = $.extend({}, core.tickManager.continuous, {
  15127. _correctInterval: function(step) {
  15128. var tickIntervalInMs = _dateToMilliseconds(this._tickInterval);
  15129. this._tickInterval = _convertMillisecondsToDateUnits(tickIntervalInMs * step)
  15130. },
  15131. _correctMax: function(tickInterval) {
  15132. var interval = _dateToMilliseconds(tickInterval);
  15133. this._max = new Date(_ceil(this._max / interval) * interval)
  15134. },
  15135. _correctMin: function(tickInterval) {
  15136. var interval = _dateToMilliseconds(tickInterval);
  15137. this._min = new Date(_floor(this._min / interval) * interval);
  15138. if (this._options.setTicksAtUnitBeginning)
  15139. _correctDateWithUnitBeginning(this._min, tickInterval)
  15140. },
  15141. _findTickIntervalForCustomTicks: function() {
  15142. return _convertMillisecondsToDateUnits(_abs(this._customTicks[1] - this._customTicks[0]))
  15143. },
  15144. _getBoundInterval: function() {
  15145. var that = this,
  15146. interval = that._tickInterval,
  15147. intervalInMs = _dateToMilliseconds(interval),
  15148. boundCoef = that._options.boundCoef,
  15149. boundIntervalInMs = _isDefined(boundCoef) && isFinite(boundCoef) ? intervalInMs * _abs(boundCoef) : intervalInMs / 2;
  15150. return _convertMillisecondsToDateUnits(boundIntervalInMs)
  15151. },
  15152. _getInterval: function(deltaCoef) {
  15153. var interval = deltaCoef || this._getDeltaCoef(this._screenDelta, this._businessDelta, this._options.gridSpacingFactor),
  15154. multipliers = this._options.numberMultipliers,
  15155. result = {},
  15156. factor,
  15157. i,
  15158. key,
  15159. specificMultipliers,
  15160. yearsCount;
  15161. if (interval > 0 && interval < 1.0)
  15162. return {milliseconds: 1};
  15163. if (interval === 0)
  15164. return 0;
  15165. for (key in DEFAULT_DATETIME_MULTIPLIERS)
  15166. if (DEFAULT_DATETIME_MULTIPLIERS.hasOwnProperty(key)) {
  15167. specificMultipliers = DEFAULT_DATETIME_MULTIPLIERS[key];
  15168. for (i = 0; i < specificMultipliers.length; i++)
  15169. if (interval <= _convertDateUnitToMilliseconds(key, specificMultipliers[i])) {
  15170. result[key + 's'] = specificMultipliers[i];
  15171. return result
  15172. }
  15173. }
  15174. for (factor = 1; ; factor *= 10)
  15175. for (i = 0; i < multipliers.length; i++) {
  15176. yearsCount = factor * multipliers[i];
  15177. if (interval <= _convertDateUnitToMilliseconds('year', yearsCount))
  15178. return {years: yearsCount}
  15179. }
  15180. return 0
  15181. },
  15182. _getMarginValue: function(min, max, margin) {
  15183. return _convertMillisecondsToDateUnits(_round(_abs(max - min) * margin))
  15184. },
  15185. _getMinorInterval: function(screenDelta, businessDelta) {
  15186. var that = this,
  15187. options = that._options,
  15188. interval,
  15189. intervalInMs,
  15190. intervalsCount,
  15191. count;
  15192. if (_isDefined(options.minorTickInterval) && that._isTickIntervalCorrect(options.minorTickInterval, MINOR_TICKS_COUNT_LIMIT, businessDelta)) {
  15193. interval = options.minorTickInterval;
  15194. intervalInMs = _dateToMilliseconds(interval);
  15195. count = intervalInMs < businessDelta ? _ceil(businessDelta / intervalInMs) - 1 : 0
  15196. }
  15197. else {
  15198. intervalsCount = _isDefined(options.minorTickCount) ? options.minorTickCount + 1 : _floor(screenDelta / options.minorGridSpacingFactor);
  15199. count = intervalsCount - 1;
  15200. interval = count > 0 ? _convertMillisecondsToDateUnits(businessDelta / intervalsCount) : 0
  15201. }
  15202. that._minorTickInterval = interval;
  15203. that._minorTickCount = count
  15204. },
  15205. _getNextTickValue: function(value, tickInterval, isTickIntervalNegative, isTickIntervalWithPow, withCorrection) {
  15206. var newValue = utils.addInterval(value, tickInterval, isTickIntervalNegative);
  15207. if (this._options.setTicksAtUnitBeginning && withCorrection !== false) {
  15208. _correctDateWithUnitBeginning(newValue, tickInterval, true);
  15209. this._correctDateWithUnitBeginningCalled = true
  15210. }
  15211. return newValue
  15212. },
  15213. _getUnitBeginningMinorTicks: function(minorTicks) {
  15214. var that = this,
  15215. ticks = that._ticks,
  15216. tickInterval = that._findMinorTickInterval(ticks[1], ticks[2]),
  15217. isTickIntervalNegative = true,
  15218. isTickIntervalWithPow = false,
  15219. needCorrectTick = false,
  15220. startTick = that._getNextTickValue(ticks[1], tickInterval, isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);
  15221. if (that._isTickIntervalValid(tickInterval))
  15222. minorTicks = that._createTicks(minorTicks, tickInterval, startTick, ticks[0], isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);
  15223. return minorTicks
  15224. },
  15225. _hasUnitBeginningTickCorrection: function() {
  15226. var ticks = this._ticks;
  15227. if (ticks.length < 3)
  15228. return false;
  15229. return ticks[1] - ticks[0] !== ticks[2] - ticks[1] && this._options.setTicksAtUnitBeginning && this._options.minorTickCount
  15230. },
  15231. _isTickIntervalValid: function(tickInterval) {
  15232. return _isDefined(tickInterval) && _dateToMilliseconds(tickInterval) !== 0
  15233. },
  15234. _removeBoundedOverlappingDates: function() {
  15235. var dates = this._ticks;
  15236. if (dates.length > 2 && this.getOverlappingBehavior().mode !== "stagger" && !this._areDisplayValuesValid(dates[0], dates[1]))
  15237. dates.splice(1, 1)
  15238. }
  15239. })
  15240. })(jQuery, DevExpress);
  15241. /*! Module viz-core, file logarithmicTickManager.js */
  15242. (function($, DX, undefined) {
  15243. var core = DX.viz.core,
  15244. utils = DX.utils,
  15245. _isDefined = utils.isDefined,
  15246. _addInterval = utils.addInterval,
  15247. _adjustValue = utils.adjustValue,
  15248. _getLog = utils.getLog,
  15249. _raiseTo = utils.raiseTo,
  15250. _math = Math,
  15251. _abs = _math.abs,
  15252. _ceil = _math.ceil,
  15253. _floor = _math.floor,
  15254. _round = _math.round;
  15255. core.tickManager.logarithmic = $.extend({}, core.tickManager.continuous, {
  15256. _correctMax: function() {
  15257. var base = this._options.base;
  15258. this._max = _adjustValue(_raiseTo(_ceil(_adjustValue(_getLog(this._max, base))), base))
  15259. },
  15260. _correctMin: function() {
  15261. var base = this._options.base;
  15262. this._min = _adjustValue(_raiseTo(_floor(_adjustValue(_getLog(this._min, base))), base))
  15263. },
  15264. _findBusinessDelta: function(min, max, isTickIntervalWithPow) {
  15265. var delta;
  15266. if (min <= 0 || max <= 0)
  15267. return 0;
  15268. if (isTickIntervalWithPow === false)
  15269. delta = core.tickManager.continuous._findBusinessDelta(min, max);
  15270. else
  15271. delta = _round(_abs(_getLog(min, this._options.base) - _getLog(max, this._options.base)));
  15272. return delta
  15273. },
  15274. _findTickIntervalForCustomTicks: function() {
  15275. return _adjustValue(_getLog(this._customTicks[1] / this._customTicks[0], this._options.base))
  15276. },
  15277. _getInterval: function(deltaCoef) {
  15278. var interval = deltaCoef || this._getDeltaCoef(this._screenDelta, this._businessDelta, this._options.gridSpacingFactor),
  15279. multipliers = this._options.numberMultipliers,
  15280. factor,
  15281. result = 0,
  15282. hasResult = false,
  15283. i;
  15284. if (interval !== 0)
  15285. for (factor = 1; !hasResult; factor *= 10)
  15286. for (i = 0; i < multipliers.length; i++) {
  15287. result = multipliers[i] * factor;
  15288. if (interval <= result) {
  15289. hasResult = true;
  15290. break
  15291. }
  15292. }
  15293. return _adjustValue(result)
  15294. },
  15295. _getMinorInterval: function(screenDelta, businessDelta) {
  15296. var that = this,
  15297. options = that._options,
  15298. minorTickCount = options.minorTickCount,
  15299. intervalsCount = _isDefined(minorTickCount) ? minorTickCount + 1 : _floor(screenDelta / options.minorGridSpacingFactor),
  15300. count = intervalsCount - 1,
  15301. interval = count > 0 ? businessDelta / intervalsCount : 0;
  15302. that._minorTickInterval = interval;
  15303. that._minorTickCount = count
  15304. },
  15305. _getMarginValue: function() {
  15306. return null
  15307. },
  15308. _getNextTickValue: function(value, tickInterval, isTickIntervalNegative, isTickIntervalWithPow) {
  15309. var that = this,
  15310. pow,
  15311. nextTickValue;
  15312. tickInterval = _isDefined(isTickIntervalNegative) && isTickIntervalNegative ? -tickInterval : tickInterval;
  15313. if (isTickIntervalWithPow === false)
  15314. nextTickValue = value + tickInterval;
  15315. else {
  15316. pow = _addInterval(_getLog(value, that._options.base), tickInterval, that._min > that._max);
  15317. nextTickValue = _adjustValue(_raiseTo(pow, that._options.base))
  15318. }
  15319. return nextTickValue
  15320. }
  15321. })
  15322. })(jQuery, DevExpress);
  15323. /*! Module viz-core, file tickOverlappingManager.js */
  15324. (function($, DX, undefined) {
  15325. var core = DX.viz.core,
  15326. coreTickManager = core.tickManager,
  15327. utils = DX.utils,
  15328. _isDefined = utils.isDefined,
  15329. _isNumber = utils.isNumber,
  15330. _math = Math,
  15331. _abs = _math.abs,
  15332. _ceil = _math.ceil,
  15333. _floor = _math.floor,
  15334. _atan = _math.atan,
  15335. _max = _math.max,
  15336. _each = $.each,
  15337. _map = $.map,
  15338. _noop = $.noop,
  15339. _isFunction = $.isFunction,
  15340. SCREEN_DELTA_KOEF = 4,
  15341. AXIS_STAGGER_OVERLAPPING_KOEF = 2,
  15342. STAGGER = "stagger",
  15343. ROTATE = "rotate",
  15344. MIN_ARRANGEMENT_TICKS_COUNT = 2;
  15345. function nextState(state) {
  15346. switch (state) {
  15347. case"overlap":
  15348. return STAGGER;
  15349. case STAGGER:
  15350. return ROTATE;
  15351. default:
  15352. return "end"
  15353. }
  15354. }
  15355. function defaultGetTextFunc(value) {
  15356. return value.toString()
  15357. }
  15358. coreTickManager.overlappingMethods = {};
  15359. coreTickManager.overlappingMethods.base = {
  15360. _applyOverlappingBehavior: function() {
  15361. var that = this,
  15362. options = that._options,
  15363. overlappingBehavior = options && options.overlappingBehavior;
  15364. if (overlappingBehavior && overlappingBehavior.mode !== "ignore") {
  15365. that._useAutoArrangement = true;
  15366. that._correctTicks();
  15367. if (overlappingBehavior.mode === "auto") {
  15368. that._applyAutoOverlappingBehavior();
  15369. that._useAutoArrangement = options.overlappingBehavior.isOverlapped
  15370. }
  15371. if (that._useAutoArrangement) {
  15372. if (overlappingBehavior.mode === STAGGER)
  15373. that._screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
  15374. that._applyAutoArrangement()
  15375. }
  15376. }
  15377. },
  15378. _checkBoundedTicksOverlapping: function() {
  15379. this._removeBoundedOverlappingDates();
  15380. this._applyStartEndTicksCorrection()
  15381. },
  15382. getMaxLabelParams: function(ticks) {
  15383. var that = this,
  15384. getText = that._options.getText || defaultGetTextFunc,
  15385. tickWithMaxLength,
  15386. tickTextWithMaxLength,
  15387. maxLength = 0,
  15388. bbox;
  15389. ticks = ticks || that._getMajorTicks();
  15390. if (!ticks.length)
  15391. return {
  15392. width: 0,
  15393. height: 0,
  15394. length: 0,
  15395. y: 0
  15396. };
  15397. _each(ticks, function(_, item) {
  15398. var text = getText(item, that._options.labelOptions),
  15399. length = text.length;
  15400. if (maxLength < length) {
  15401. maxLength = length;
  15402. tickWithMaxLength = item;
  15403. tickTextWithMaxLength = text
  15404. }
  15405. });
  15406. bbox = that._getTextElementBbox(tickWithMaxLength, tickTextWithMaxLength);
  15407. return {
  15408. width: bbox.width,
  15409. height: bbox.height,
  15410. y: bbox.y,
  15411. length: maxLength
  15412. }
  15413. },
  15414. _applyAutoArrangement: function() {
  15415. var that = this,
  15416. options = that._options,
  15417. arrangementStep,
  15418. maxDisplayValueSize;
  15419. if (that._useAutoArrangement) {
  15420. maxDisplayValueSize = that._getTicksSize();
  15421. arrangementStep = that._getAutoArrangementStep(maxDisplayValueSize);
  15422. if (arrangementStep > 1)
  15423. if (_isDefined(that._tickInterval) || _isDefined(that._customTicks))
  15424. that._ticks = that._getAutoArrangementTicks(arrangementStep);
  15425. else {
  15426. options.gridSpacingFactor = maxDisplayValueSize;
  15427. that._ticks = that._createTicks([], that._findTickInterval(), that._min, that._max)
  15428. }
  15429. }
  15430. },
  15431. _getAutoArrangementTicks: function(step) {
  15432. var that = this,
  15433. ticks = that._ticks,
  15434. ticksLength = ticks.length,
  15435. resultTicks = ticks,
  15436. decimatedTicks = that._decimatedTicks || [],
  15437. i;
  15438. if (step > 1) {
  15439. resultTicks = [];
  15440. for (i = 0; i < ticksLength; i++)
  15441. if (i % step === 0)
  15442. resultTicks.push(ticks[i]);
  15443. else
  15444. decimatedTicks.push(ticks[i]);
  15445. that._correctInterval(step)
  15446. }
  15447. return resultTicks
  15448. },
  15449. _isOverlappedTicks: function(screenDelta) {
  15450. return this._getAutoArrangementStep(this._getTicksSize(), screenDelta, -1) > 1
  15451. },
  15452. _areDisplayValuesValid: function(value1, value2) {
  15453. var that = this,
  15454. options = that._options,
  15455. getText = options.getText || defaultGetTextFunc,
  15456. rotationAngle = options.overlappingBehavior && _isNumber(options.overlappingBehavior.rotationAngle) ? options.overlappingBehavior.rotationAngle : 0,
  15457. bBox1 = that._getTextElementBbox(value1, getText(value1, options.labelOptions)),
  15458. bBox2 = that._getTextElementBbox(value2, getText(value2, options.labelOptions)),
  15459. horizontalInverted = bBox1.x > bBox2.x,
  15460. verticalInverted = bBox1.y > bBox2.y,
  15461. hasHorizontalOverlapping,
  15462. hasVerticalOverlapping,
  15463. result;
  15464. if (rotationAngle !== 0)
  15465. result = that._getDistanceByAngle(bBox1.height, rotationAngle) <= _abs(bBox2.x - bBox1.x);
  15466. else {
  15467. hasHorizontalOverlapping = !horizontalInverted ? bBox1.x + bBox1.width > bBox2.x : bBox2.x + bBox2.width > bBox1.x;
  15468. hasVerticalOverlapping = !verticalInverted ? bBox1.y + bBox1.height > bBox2.y : bBox2.y + bBox2.height > bBox1.y;
  15469. result = !(hasHorizontalOverlapping && hasVerticalOverlapping)
  15470. }
  15471. return result
  15472. }
  15473. };
  15474. coreTickManager.overlappingMethods.circular = $.extend({}, coreTickManager.overlappingMethods.base, {
  15475. _correctTicks: _noop,
  15476. _applyAutoOverlappingBehavior: function() {
  15477. this._options.overlappingBehavior.isOverlapped = true
  15478. },
  15479. _getTextElementBbox: function(value, text) {
  15480. var textOptions = $.extend({}, this._options.textOptions, {rotate: 0}),
  15481. delta = _isFunction(this._options.translate) ? this._options.translate(value) : {
  15482. x: 0,
  15483. y: 0
  15484. },
  15485. bbox;
  15486. text = this._options.renderText(text, delta.x, delta.y).css(this._options.textFontStyles).attr(textOptions);
  15487. bbox = text.getBBox();
  15488. text.remove();
  15489. return bbox
  15490. },
  15491. _getTicksSize: function() {
  15492. return this.getMaxLabelParams(this._ticks)
  15493. },
  15494. _applyStartEndTicksCorrection: function() {
  15495. var ticks = this._ticks,
  15496. lastTick = ticks[ticks.length - 1];
  15497. if (ticks.length > 1 && !this._areDisplayValuesValid(ticks[0], lastTick))
  15498. ticks.pop()
  15499. },
  15500. _getAutoArrangementStep: function(maxDisplayValueSize) {
  15501. var that = this,
  15502. options = that._options,
  15503. radius = options.circularRadius,
  15504. startAngle = options.circularStartAngle,
  15505. endAngle = options.circularEndAngle,
  15506. circleDelta = startAngle === endAngle ? 360 : _abs(startAngle - endAngle),
  15507. businessDelta = that._businessDelta || that._ticks.length,
  15508. degreesPerTick = that._tickInterval * circleDelta / businessDelta,
  15509. width = maxDisplayValueSize.width,
  15510. height = maxDisplayValueSize.height,
  15511. angle1 = _abs(2 * _atan(height / (2 * radius - width)) * 180 / _math.PI),
  15512. angle2 = _abs(2 * _atan(width / (2 * radius - height)) * 180 / _math.PI),
  15513. minAngleForTick = _max(angle1, angle2),
  15514. step = 1;
  15515. if (degreesPerTick < minAngleForTick)
  15516. step = _ceil(minAngleForTick / degreesPerTick);
  15517. return _max(1, step)
  15518. }
  15519. });
  15520. coreTickManager.overlappingMethods.linear = $.extend({}, coreTickManager.overlappingMethods.base, {
  15521. _correctTicks: function() {
  15522. var getIntervalFunc = coreTickManager.continuous._getInterval,
  15523. arrangementStep;
  15524. if (this._testingGetIntervalFunc)
  15525. getIntervalFunc = this._testingGetIntervalFunc;
  15526. arrangementStep = _ceil(getIntervalFunc.call(this, this._getDeltaCoef(this._screenDelta * SCREEN_DELTA_KOEF, this._ticks.length))) || this._ticks.length;
  15527. this._appliedArrangementStep = arrangementStep;
  15528. this._ticks = this._getAutoArrangementTicks(arrangementStep)
  15529. },
  15530. _getTextElementBbox: function(value, text) {
  15531. var textOptions = $.extend({}, this._options.textOptions, {rotate: 0}),
  15532. x = 0,
  15533. y = 0,
  15534. delta = _isFunction(this._options.translate) ? this._options.translate(value) : 0,
  15535. bbox;
  15536. if (this._options.isHorizontal)
  15537. x += delta;
  15538. else
  15539. y += delta;
  15540. text = this._options.renderText(text, x, y).css(this._options.textFontStyles).attr(textOptions);
  15541. bbox = text.getBBox();
  15542. text.remove();
  15543. return bbox
  15544. },
  15545. _applyStartEndTicksCorrection: _noop,
  15546. _getAutoArrangementStep: function(maxDisplayValueSize, screenDelta, minArrangementTicksStep) {
  15547. var that = this,
  15548. options = that._options,
  15549. requiredValuesCount,
  15550. textSpacing = options.textSpacing || 0,
  15551. addedSpacing = options.isHorizontal ? textSpacing : 0;
  15552. screenDelta = screenDelta || that._screenDelta;
  15553. minArrangementTicksStep = _isDefined(minArrangementTicksStep) ? minArrangementTicksStep : 1;
  15554. if (options.getCustomAutoArrangementStep)
  15555. return options.getCustomAutoArrangementStep(that._ticks, options);
  15556. if (maxDisplayValueSize > 0) {
  15557. requiredValuesCount = _floor((screenDelta + textSpacing) / (maxDisplayValueSize + addedSpacing));
  15558. requiredValuesCount = requiredValuesCount <= minArrangementTicksStep ? MIN_ARRANGEMENT_TICKS_COUNT : requiredValuesCount;
  15559. return _ceil((options.ticksCount || that._ticks.length) / requiredValuesCount)
  15560. }
  15561. return 1
  15562. },
  15563. _getOptimalRotationAngle: function() {
  15564. var that = this,
  15565. options = that._options,
  15566. tick1 = that._ticks[0],
  15567. tick2 = that._ticks[1],
  15568. outOfScreen = core.outOfScreen,
  15569. textOptions = that._textOptions,
  15570. getText = options.getText || defaultGetTextFunc,
  15571. textFontStyles = options.textFontStyles,
  15572. svgElement1 = options.renderText(getText(tick1, options.labelOptions), outOfScreen.x + options.translate(tick1, !options.isHorizontal), outOfScreen.y).css(textFontStyles).attr(textOptions),
  15573. svgElement2 = options.renderText(getText(tick2, options.labelOptions), outOfScreen.x + options.translate(tick2, !options.isHorizontal), outOfScreen.y).css(textFontStyles).attr(textOptions),
  15574. bBox1 = svgElement1.getBBox(),
  15575. bBox2 = svgElement2.getBBox(),
  15576. angle = _math.asin((bBox1.height + options.textSpacing) / (bBox2.x - bBox1.x)) * 180 / Math.PI;
  15577. svgElement1.remove();
  15578. svgElement2.remove();
  15579. return isNaN(angle) ? 90 : _ceil(angle)
  15580. },
  15581. _applyAutoOverlappingBehavior: function() {
  15582. var that = this,
  15583. overlappingBehavior = that._options.overlappingBehavior,
  15584. screenDelta = that._screenDelta,
  15585. isOverlapped = false,
  15586. rotationAngle = null,
  15587. mode = null,
  15588. state = "overlap";
  15589. while (state !== "end") {
  15590. isOverlapped = rotationAngle && rotationAngle !== 90 ? false : that._isOverlappedTicks(screenDelta);
  15591. state = nextState(isOverlapped ? state : null);
  15592. switch (state) {
  15593. case STAGGER:
  15594. screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
  15595. mode = state;
  15596. break;
  15597. case ROTATE:
  15598. rotationAngle = that._getOptimalRotationAngle();
  15599. screenDelta = that._screenDelta;
  15600. mode = state;
  15601. break
  15602. }
  15603. }
  15604. overlappingBehavior.isOverlapped = isOverlapped;
  15605. overlappingBehavior.mode = mode;
  15606. overlappingBehavior.rotationAngle = rotationAngle
  15607. },
  15608. _getDistanceByAngle: function(elementHeight, rotationAngle) {
  15609. return elementHeight / _abs(_math.sin(rotationAngle * (_math.PI / 180)))
  15610. },
  15611. _getTicksSize: function() {
  15612. var that = this,
  15613. options = that._options,
  15614. ticks = that._ticks,
  15615. ticksString,
  15616. rotationAngle = options.overlappingBehavior ? options.overlappingBehavior.rotationAngle : 0,
  15617. bBox,
  15618. result,
  15619. getText = options.getText || defaultGetTextFunc,
  15620. isRotate = _isNumber(rotationAngle) && rotationAngle !== 0,
  15621. joinNeeded = !isRotate && options.isHorizontal;
  15622. if (ticks.length === 0)
  15623. return 0;
  15624. ticksString = joinNeeded ? _map(ticks, function(tick) {
  15625. return getText(tick, options.labelOptions)
  15626. }).join("\n") : getText(ticks[0], options.labelOptions);
  15627. bBox = that._getTextElementBbox(ticksString, ticksString);
  15628. result = isRotate ? that._getDistanceByAngle(bBox.height, rotationAngle) : options.isHorizontal ? bBox.width : bBox.height;
  15629. return _ceil(result)
  15630. }
  15631. })
  15632. })(jQuery, DevExpress);
  15633. /*! Module viz-core, file baseTickManager.js */
  15634. (function($, DX, undefined) {
  15635. var core = DX.viz.core,
  15636. coreTickManager = core.tickManager,
  15637. utils = DX.utils,
  15638. _isDefined = utils.isDefined,
  15639. _isNumber = utils.isNumber,
  15640. _addInterval = utils.addInterval,
  15641. _adjustValue = utils.adjustValue,
  15642. _each = $.each,
  15643. _map = $.map,
  15644. _inArray = $.inArray,
  15645. _noop = $.noop,
  15646. DEFAULT_GRID_SPACING_FACTOR = 30,
  15647. DEFAULT_MINOR_GRID_SPACING_FACTOR = 15,
  15648. DEFAULT_NUMBER_MULTIPLIERS = [1, 2, 3, 5],
  15649. TICKS_COUNT_LIMIT = 2000,
  15650. MIN_ARRANGEMENT_TICKS_COUNT = 2;
  15651. function concatAndSort(array1, array2) {
  15652. var array = array1.concat(array2).sort(function(x, y) {
  15653. return _isDefined(x) && _isDefined(y) && x.valueOf() - y.valueOf()
  15654. }),
  15655. length = array.length,
  15656. i;
  15657. for (i = length - 1; i > 0; i--)
  15658. if (_isDefined(array[i]) && _isDefined(array[i - 1]) && array[i].valueOf() === array[i - 1].valueOf())
  15659. array.splice(i, 1);
  15660. return array
  15661. }
  15662. coreTickManager.discrete = $.extend({}, coreTickManager.continuous, {
  15663. _getMinorTicks: _noop,
  15664. _findTickInterval: _noop,
  15665. _createTicks: function() {
  15666. return []
  15667. },
  15668. _getMarginValue: _noop,
  15669. _generateBounds: _noop,
  15670. _correctMin: _noop,
  15671. _correctMax: _noop,
  15672. _findBusinessDelta: _noop,
  15673. _addBoundedTicks: _noop,
  15674. getFullTicks: function() {
  15675. return this._customTicks
  15676. },
  15677. getMinorTicks: function() {
  15678. return this._decimatedTicks || []
  15679. },
  15680. _findTickIntervalForCustomTicks: function() {
  15681. return 1
  15682. }
  15683. });
  15684. coreTickManager.TickManager = DX.Class.inherit({
  15685. ctor: function(types, data, options) {
  15686. options = options || {};
  15687. this.update(types || {}, data || {}, options);
  15688. this._initOverlappingMethods(options.overlappingBehaviorType)
  15689. },
  15690. dispose: function() {
  15691. this._ticks = null;
  15692. this._minorTicks = null;
  15693. this._decimatedTicks = null;
  15694. this._boundaryTicks = null;
  15695. this._options = null
  15696. },
  15697. update: function(types, data, options) {
  15698. this._updateOptions(options || {});
  15699. this._min = data.min;
  15700. this._updateTypes(types || {});
  15701. this._updateData(data || {})
  15702. },
  15703. _updateMinMax: function(data) {
  15704. var min = data.min || 0,
  15705. max = data.max || 0,
  15706. newMinMax = this._applyMinMaxMargins(min, max);
  15707. this._min = this._originalMin = newMinMax.min;
  15708. this._max = this._originalMax = newMinMax.max;
  15709. this._updateBusinessDelta()
  15710. },
  15711. _updateBusinessDelta: function() {
  15712. this._businessDelta = this._findBusinessDelta && this._findBusinessDelta(this._min, this._max)
  15713. },
  15714. _updateTypes: function(types) {
  15715. var that = this,
  15716. axisType = that._validateAxisType(types.axisType),
  15717. dataType = that._validateDataType(types.dataType);
  15718. that._resetMethods();
  15719. this._axisType = axisType;
  15720. this._dataType = dataType;
  15721. this._initMethods()
  15722. },
  15723. _updateData: function(data) {
  15724. data = $.extend({}, data);
  15725. data.min = _isDefined(data.min) ? data.min : this._originalMin;
  15726. data.max = _isDefined(data.max) ? data.max : this._originalMax;
  15727. this._updateMinMax(data);
  15728. this._customTicks = data.customTicks && data.customTicks.slice();
  15729. this._customMinorTicks = data.customMinorTicks;
  15730. this._screenDelta = data.screenDelta || 0
  15731. },
  15732. _updateOptions: function(options) {
  15733. var opt;
  15734. this._options = opt = options;
  15735. this._useAutoArrangement = !!this._options.useTicksAutoArrangement;
  15736. opt.gridSpacingFactor = opt.gridSpacingFactor || DEFAULT_GRID_SPACING_FACTOR;
  15737. opt.minorGridSpacingFactor = opt.minorGridSpacingFactor || DEFAULT_MINOR_GRID_SPACING_FACTOR;
  15738. opt.numberMultipliers = opt.numberMultipliers || DEFAULT_NUMBER_MULTIPLIERS
  15739. },
  15740. getTickBounds: function() {
  15741. return {
  15742. minVisible: this._minBound,
  15743. maxVisible: this._maxBound
  15744. }
  15745. },
  15746. getTicks: function(withoutOverlappingBehavior) {
  15747. var that = this,
  15748. options = that._options;
  15749. that._ticks = that._getMajorTicks();
  15750. that._checkLabelFormat();
  15751. that._decimatedTicks = [];
  15752. that._applyAutoArrangement();
  15753. !withoutOverlappingBehavior && that._applyOverlappingBehavior();
  15754. that._generateBounds();
  15755. if (options.showMinorTicks)
  15756. that._minorTicks = that._customMinorTicks || that._getMinorTicks();
  15757. that._addBoundedTicks();
  15758. !withoutOverlappingBehavior && that._checkBoundedTicksOverlapping();
  15759. return that._ticks
  15760. },
  15761. getMinorTicks: function() {
  15762. var that = this,
  15763. decimatedTicks = that._decimatedTicks || [],
  15764. options = that._options || {},
  15765. hasDecimatedTicks = decimatedTicks.length,
  15766. hasMinorTickOptions = _isDefined(options.minorTickInterval) || _isDefined(options.minorTickCount),
  15767. hasCustomMinorTicks = that._customMinorTicks && that._customMinorTicks.length,
  15768. hasMinorTicks = options.showMinorTicks && (hasMinorTickOptions || hasCustomMinorTicks),
  15769. ticks = hasDecimatedTicks && !hasMinorTicks ? decimatedTicks : that._minorTicks || [];
  15770. return concatAndSort(ticks, [])
  15771. },
  15772. getDecimatedTicks: function() {
  15773. return concatAndSort(this._decimatedTicks || [], [])
  15774. },
  15775. getFullTicks: function() {
  15776. return concatAndSort(this._ticks || [], this.getMinorTicks(), this._axisType)
  15777. },
  15778. getBoundaryTicks: function() {
  15779. return concatAndSort(this._boundaryTicks || [], [])
  15780. },
  15781. getTickInterval: function() {
  15782. return this._tickInterval
  15783. },
  15784. getMinorTickInterval: function() {
  15785. return this._minorTickInterval
  15786. },
  15787. getOverlappingBehavior: function() {
  15788. return this._options.overlappingBehavior
  15789. },
  15790. getOptions: function() {
  15791. return this._options
  15792. },
  15793. _getMajorTicks: function() {
  15794. var ticks;
  15795. if (this._customTicks) {
  15796. ticks = this._customTicks.slice();
  15797. this._tickInterval = ticks.length > 1 ? this._findTickIntervalForCustomTicks() : 0
  15798. }
  15799. else
  15800. ticks = this._createTicks([], this._findTickInterval(), this._min, this._max);
  15801. return ticks
  15802. },
  15803. _applyMargin: function(margin, min, max, isNegative) {
  15804. var coef,
  15805. value = min;
  15806. if (isFinite(margin)) {
  15807. coef = this._getMarginValue(min, max, margin);
  15808. if (coef)
  15809. value = this._getNextTickValue(min, coef, isNegative, false)
  15810. }
  15811. return value
  15812. },
  15813. _applyMinMaxMargins: function(min, max) {
  15814. var options = this._options,
  15815. newMin = min > max ? max : min,
  15816. newMax = max > min ? max : min;
  15817. this._minCorrectionEnabled = this._getCorrectionEnabled(min, "min");
  15818. this._maxCorrectionEnabled = this._getCorrectionEnabled(max, "max");
  15819. if (options && !options.stick) {
  15820. newMin = this._applyMargin(options.minValueMargin, min, max, true);
  15821. newMax = this._applyMargin(options.maxValueMargin, max, min, false)
  15822. }
  15823. return {
  15824. min: newMin,
  15825. max: newMax
  15826. }
  15827. },
  15828. _checkBoundedTickInArray: function(value, array) {
  15829. var arrayValues = _map(array || [], function(item) {
  15830. return item.valueOf()
  15831. }),
  15832. minorTicksIndex = _inArray(value.valueOf(), arrayValues);
  15833. if (minorTicksIndex !== -1)
  15834. array.splice(minorTicksIndex, 1)
  15835. },
  15836. _checkLabelFormat: function() {
  15837. var options = this._options;
  15838. if (this._dataType === "datetime" && !options.hasLabelFormat && this._ticks.length)
  15839. options.labelOptions.format = DX.formatHelper.getDateFormatByTicks(this._ticks)
  15840. },
  15841. _generateBounds: function() {
  15842. var that = this,
  15843. interval = that._getBoundInterval(),
  15844. stick = that._options.stick,
  15845. minStickValue = that._options.minStickValue,
  15846. maxStickValue = that._options.maxStickValue,
  15847. minBound = that._minCorrectionEnabled && !stick ? that._getNextTickValue(that._min, interval, true) : that._originalMin,
  15848. maxBound = that._maxCorrectionEnabled && !stick ? that._getNextTickValue(that._max, interval) : that._originalMax;
  15849. that._minBound = minBound < minStickValue ? minStickValue : minBound;
  15850. that._maxBound = maxBound > maxStickValue ? maxStickValue : maxBound
  15851. },
  15852. _initOverlappingMethods: function(type) {
  15853. this._initMethods(coreTickManager.overlappingMethods[type || "linear"])
  15854. },
  15855. _addBoundedTicks: function() {
  15856. var that = this,
  15857. tickValues = _map(that._ticks, function(tick) {
  15858. return tick.valueOf()
  15859. }),
  15860. min = that._originalMin,
  15861. max = that._originalMax,
  15862. addMinMax = that._options.addMinMax || {};
  15863. that._boundaryTicks = [];
  15864. if (addMinMax.min && _inArray(min.valueOf(), tickValues) === -1) {
  15865. that._ticks.splice(0, 0, min);
  15866. that._boundaryTicks.push(min);
  15867. that._checkBoundedTickInArray(min, that._minorTicks);
  15868. that._checkBoundedTickInArray(min, that._decimatedTicks)
  15869. }
  15870. if (addMinMax.max && _inArray(max.valueOf(), tickValues) === -1) {
  15871. that._ticks.push(max);
  15872. that._boundaryTicks.push(max);
  15873. that._checkBoundedTickInArray(max, that._minorTicks);
  15874. that._checkBoundedTickInArray(max, that._decimatedTicks)
  15875. }
  15876. },
  15877. _getCorrectionEnabled: function(value, marginSelector) {
  15878. var options = this._options || {},
  15879. hasPercentStick = options.percentStick && value === 1,
  15880. hasValueMargin = options[marginSelector + "ValueMargin"];
  15881. return !hasPercentStick && !hasValueMargin
  15882. },
  15883. _validateAxisType: function(type) {
  15884. var defaultType = "continuous",
  15885. allowedTypes = {
  15886. continuous: true,
  15887. discrete: true,
  15888. logarithmic: true
  15889. };
  15890. return allowedTypes[type] ? type : defaultType
  15891. },
  15892. _validateDataType: function(type) {
  15893. var allowedTypes = {
  15894. numeric: true,
  15895. datetime: true,
  15896. string: true
  15897. };
  15898. if (!allowedTypes[type])
  15899. type = _isDefined(this._min) ? this._getDataType(this._min) : "numeric";
  15900. return type
  15901. },
  15902. _getDataType: function(value) {
  15903. return utils.isDate(value) ? 'datetime' : 'numeric'
  15904. },
  15905. _getMethods: function() {
  15906. var methods;
  15907. if (this._axisType === "continuous")
  15908. methods = this._dataType === "datetime" ? coreTickManager.datetime : coreTickManager.continuous;
  15909. else
  15910. methods = coreTickManager[this._axisType] || coreTickManager.continuous;
  15911. return methods
  15912. },
  15913. _resetMethods: function() {
  15914. var that = this,
  15915. methods = that._getMethods();
  15916. _each(methods, function(name) {
  15917. if (that[name])
  15918. delete that[name]
  15919. })
  15920. },
  15921. _initMethods: function(methods) {
  15922. var that = this;
  15923. methods = methods || that._getMethods();
  15924. _each(methods, function(name, func) {
  15925. that[name] = func
  15926. })
  15927. },
  15928. _getDeltaCoef: function(screenDelta, businessDelta, gridSpacingFactor) {
  15929. var count;
  15930. gridSpacingFactor = gridSpacingFactor || this._options.gridSpacingFactor;
  15931. screenDelta = screenDelta || this._screenDelta;
  15932. businessDelta = businessDelta || this._businessDelta;
  15933. count = screenDelta / gridSpacingFactor;
  15934. count = count <= 1 ? MIN_ARRANGEMENT_TICKS_COUNT : count;
  15935. return businessDelta / count
  15936. },
  15937. _adjustNumericTickValue: function(value, interval, min) {
  15938. return utils.isExponential(value) ? _adjustValue(value) : utils.applyPrecisionByMinDelta(min, interval, value)
  15939. },
  15940. _isTickIntervalCorrect: function(tickInterval, tickCountLimit, businessDelta) {
  15941. var date;
  15942. businessDelta = businessDelta || this._businessDelta;
  15943. if (!_isNumber(tickInterval)) {
  15944. date = new Date;
  15945. tickInterval = _addInterval(date, tickInterval) - date;
  15946. if (!tickInterval)
  15947. return false
  15948. }
  15949. if (_isNumber(tickInterval))
  15950. if (tickInterval > 0 && businessDelta / tickInterval > tickCountLimit) {
  15951. if (this._options.incidentOccured)
  15952. this._options.incidentOccured('W2003')
  15953. }
  15954. else
  15955. return true;
  15956. return false
  15957. },
  15958. _correctValue: function(valueTypeSelector, tickInterval, correctionMethod) {
  15959. var that = this,
  15960. correctionEnabledSelector = "_" + valueTypeSelector + "CorrectionEnabled",
  15961. spaceCorrectionSelector = valueTypeSelector + "SpaceCorrection",
  15962. valueSelector = "_" + valueTypeSelector,
  15963. minStickValue = that._options.minStickValue,
  15964. maxStickValue = that._options.maxStickValue;
  15965. if (that[correctionEnabledSelector]) {
  15966. if (that._options[spaceCorrectionSelector])
  15967. that[valueSelector] = that._getNextTickValue(that[valueSelector], tickInterval, valueTypeSelector === "min");
  15968. correctionMethod.call(this, tickInterval)
  15969. }
  15970. if (valueTypeSelector === "min")
  15971. that[valueSelector] = that[valueSelector] < minStickValue ? minStickValue : that[valueSelector];
  15972. if (valueTypeSelector === "max")
  15973. that[valueSelector] = that[valueSelector] > maxStickValue ? maxStickValue : that[valueSelector]
  15974. },
  15975. _findTickInterval: function() {
  15976. var that = this,
  15977. options = that._options,
  15978. tickInterval;
  15979. tickInterval = that._isTickIntervalValid(options.tickInterval) && that._isTickIntervalCorrect(options.tickInterval, TICKS_COUNT_LIMIT) ? options.tickInterval : that._getInterval();
  15980. if (that._isTickIntervalValid(tickInterval)) {
  15981. that._correctValue("min", tickInterval, that._correctMin);
  15982. that._correctValue("max", tickInterval, that._correctMax);
  15983. that._updateBusinessDelta()
  15984. }
  15985. that._tickInterval = tickInterval;
  15986. return tickInterval
  15987. },
  15988. _findMinorTickInterval: function(firstTick, secondTick) {
  15989. var that = this,
  15990. ticks = that._ticks,
  15991. intervals = that._options.stick ? ticks.length - 1 : ticks.length;
  15992. if (intervals < 1)
  15993. intervals = 1;
  15994. that._getMinorInterval(that._screenDelta / intervals, that._findBusinessDelta(firstTick, secondTick, false));
  15995. return that._minorTickInterval
  15996. },
  15997. _createMinorTicks: function(ticks, firstTick, secondTick) {
  15998. var that = this,
  15999. tickInterval = that._findMinorTickInterval(firstTick, secondTick),
  16000. isTickIntervalNegative = false,
  16001. isTickIntervalWithPow = false,
  16002. needCorrectTick = false,
  16003. startTick = that._getNextTickValue(firstTick, tickInterval, isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);
  16004. if (that._isTickIntervalValid(tickInterval))
  16005. ticks = that._createCountedTicks(ticks, tickInterval, startTick, secondTick, that._minorTickCount, isTickIntervalNegative, isTickIntervalWithPow, needCorrectTick);
  16006. return ticks
  16007. },
  16008. _getMinorTicks: function() {
  16009. var that = this,
  16010. minorTicks = [],
  16011. ticks = that._ticks,
  16012. ticksLength = ticks.length,
  16013. hasUnitBeginningTick = that._hasUnitBeginningTickCorrection(),
  16014. i = hasUnitBeginningTick ? 1 : 0;
  16015. if (ticks.length) {
  16016. minorTicks = that._getBoundedMinorTicks(minorTicks, that._minBound, ticks[0], true);
  16017. if (hasUnitBeginningTick)
  16018. minorTicks = that._getUnitBeginningMinorTicks(minorTicks);
  16019. for (i; i < ticksLength - 1; i++)
  16020. minorTicks = that._createMinorTicks(minorTicks, ticks[i], ticks[i + 1]);
  16021. minorTicks = that._getBoundedMinorTicks(minorTicks, that._maxBound, ticks[ticksLength - 1])
  16022. }
  16023. else
  16024. minorTicks = that._createMinorTicks(minorTicks, that._minBound, that._maxBound);
  16025. return minorTicks
  16026. },
  16027. _createCountedTicks: function(ticks, tickInterval, min, max, count, isTickIntervalWithPow, needMax) {
  16028. var value = min,
  16029. i;
  16030. for (i = 0; i < count; i++) {
  16031. if (!(needMax === false && value.valueOf() === max.valueOf()))
  16032. ticks.push(value);
  16033. value = this._getNextTickValue(value, tickInterval, false, isTickIntervalWithPow, false)
  16034. }
  16035. return ticks
  16036. },
  16037. _createTicks: function(ticks, tickInterval, min, max, isTickIntervalNegative, isTickIntervalWithPow, withCorrection) {
  16038. var that = this,
  16039. value = min,
  16040. newValue = min,
  16041. leftBound,
  16042. rightBound,
  16043. boundedRule;
  16044. if (that._isTickIntervalValid(tickInterval)) {
  16045. boundedRule = min - max < 0;
  16046. do {
  16047. value = newValue;
  16048. if (that._options.stick) {
  16049. if (value >= that._originalMin && value <= that._originalMax)
  16050. ticks.push(value)
  16051. }
  16052. else
  16053. ticks.push(value);
  16054. newValue = that._getNextTickValue(value, tickInterval, isTickIntervalNegative, isTickIntervalWithPow, withCorrection);
  16055. if (value.valueOf() === newValue.valueOf())
  16056. break;
  16057. leftBound = newValue - min >= 0;
  16058. rightBound = max - newValue >= 0
  16059. } while (boundedRule === leftBound && boundedRule === rightBound)
  16060. }
  16061. else
  16062. ticks.push(value);
  16063. return ticks
  16064. },
  16065. _getBoundedMinorTicks: function(minorTicks, boundedTick, tick, isNegative) {
  16066. var that = this,
  16067. needCorrectTick = false,
  16068. nextTick = that._tickInterval ? this._getNextTickValue(tick, that._tickInterval, isNegative, true, needCorrectTick) : boundedTick,
  16069. tickInterval = that._findMinorTickInterval(tick, nextTick),
  16070. isTickIntervalCorrect = that._isTickIntervalCorrect(tickInterval, TICKS_COUNT_LIMIT, that._findBusinessDelta(tick, boundedTick, false)),
  16071. startTick,
  16072. endTick,
  16073. boundedTickValue = boundedTick.valueOf();
  16074. if (isTickIntervalCorrect && that._isTickIntervalValid(tickInterval) && that._minorTickCount > 0) {
  16075. if (isNegative) {
  16076. if (tick.valueOf() <= boundedTickValue)
  16077. return minorTicks;
  16078. while (nextTick.valueOf() < boundedTickValue)
  16079. nextTick = this._getNextTickValue(nextTick, tickInterval, false, false, needCorrectTick);
  16080. startTick = nextTick;
  16081. endTick = that._getNextTickValue(tick, tickInterval, true, false, false)
  16082. }
  16083. else {
  16084. startTick = that._getNextTickValue(tick, tickInterval, false, false, false);
  16085. endTick = boundedTick
  16086. }
  16087. minorTicks = that._createTicks(minorTicks, tickInterval, startTick, endTick, false, false, needCorrectTick)
  16088. }
  16089. return minorTicks
  16090. },
  16091. getTypes: function() {
  16092. return {
  16093. axisType: this._axisType,
  16094. dataType: this._dataType
  16095. }
  16096. },
  16097. getData: function() {
  16098. return {
  16099. min: this._min,
  16100. max: this._max,
  16101. customTicks: this._customTicks,
  16102. customMinorTicks: this._customMinorTicks,
  16103. screenDelta: this._screenDelta
  16104. }
  16105. }
  16106. })
  16107. })(jQuery, DevExpress);
  16108. /*! Module viz-core, file numericTranslator.js */
  16109. (function($, DX, undefined) {
  16110. var utils = DX.utils,
  16111. isDefined = utils.isDefined,
  16112. round = Math.round;
  16113. DX.viz.core.numericTranslatorFunctions = {
  16114. translate: function(bp) {
  16115. var that = this,
  16116. canvasOptions = that._canvasOptions,
  16117. doubleError = canvasOptions.rangeDoubleError,
  16118. specialValue = that.translateSpecialCase(bp);
  16119. if (isDefined(specialValue))
  16120. return specialValue;
  16121. if (isNaN(bp) || bp.valueOf() + doubleError < canvasOptions.rangeMin || bp.valueOf() - doubleError > canvasOptions.rangeMax)
  16122. return null;
  16123. return that._conversionValue(that._calculateProjection((bp - canvasOptions.rangeMinVisible) * canvasOptions.ratioOfCanvasRange))
  16124. },
  16125. untranslate: function(pos, _directionOffset, enableOutOfCanvas) {
  16126. var canvasOptions = this._canvasOptions,
  16127. startPoint = canvasOptions.startPoint;
  16128. if (!enableOutOfCanvas && (pos < startPoint || pos > canvasOptions.endPoint) || !isDefined(canvasOptions.rangeMin) || !isDefined(canvasOptions.rangeMax))
  16129. return null;
  16130. return this._calculateUnProjection((pos - startPoint) / canvasOptions.ratioOfCanvasRange)
  16131. },
  16132. getInterval: function() {
  16133. return round(this._canvasOptions.ratioOfCanvasRange * (this._businessRange.interval || Math.abs(this._canvasOptions.rangeMax - this._canvasOptions.rangeMin)))
  16134. },
  16135. _getValue: function(val) {
  16136. return val
  16137. },
  16138. zoom: function(translate, scale) {
  16139. var that = this,
  16140. canvasOptions = that._canvasOptions,
  16141. startPoint = canvasOptions.startPoint,
  16142. endPoint = canvasOptions.endPoint,
  16143. newStart = (startPoint + translate) / scale,
  16144. newEnd = (endPoint + translate) / scale,
  16145. minPoint = Math.min(that.translate(that._getValue(canvasOptions.rangeMin)), that.translate(that._getValue(canvasOptions.rangeMax))),
  16146. maxPoint = Math.max(that.translate(that._getValue(canvasOptions.rangeMin)), that.translate(that._getValue(canvasOptions.rangeMax)));
  16147. if (minPoint > newStart) {
  16148. newEnd -= newStart - minPoint;
  16149. newStart = minPoint
  16150. }
  16151. if (maxPoint < newEnd) {
  16152. newStart -= newEnd - maxPoint;
  16153. newEnd = maxPoint
  16154. }
  16155. if (maxPoint - minPoint < newEnd - newStart) {
  16156. newStart = minPoint;
  16157. newEnd = maxPoint
  16158. }
  16159. translate = (endPoint - startPoint) * newStart / (newEnd - newStart) - startPoint;
  16160. scale = (startPoint + translate) / newStart || 1;
  16161. return {
  16162. min: that.untranslate(newStart, undefined, true),
  16163. max: that.untranslate(newEnd, undefined, true),
  16164. translate: translate,
  16165. scale: scale
  16166. }
  16167. },
  16168. getMinScale: function(zoom) {
  16169. return zoom ? 1.1 : 0.9
  16170. },
  16171. getScale: function(val1, val2) {
  16172. var canvasOptions = this._canvasOptions;
  16173. val1 = isDefined(val1) ? val1 : canvasOptions.rangeMin;
  16174. val2 = isDefined(val2) ? val2 : canvasOptions.rangeMax;
  16175. return (canvasOptions.rangeMax - canvasOptions.rangeMin) / Math.abs(val1 - val2)
  16176. }
  16177. }
  16178. })(jQuery, DevExpress);
  16179. /*! Module viz-core, file datetimeTranslator.js */
  16180. (function($, DX, undefined) {
  16181. var core = DX.viz.core,
  16182. numericTranslator = core.numericTranslatorFunctions;
  16183. core.datetimeTranslatorFunctions = {
  16184. translate: numericTranslator.translate,
  16185. untranslate: function() {
  16186. var result = numericTranslator.untranslate.apply(this, arguments);
  16187. return result === null ? result : new Date(result)
  16188. },
  16189. _getValue: numericTranslator._getValue,
  16190. getInterval: numericTranslator.getInterval,
  16191. zoom: numericTranslator.zoom,
  16192. getMinScale: numericTranslator.getMinScale,
  16193. getScale: numericTranslator.getScale
  16194. }
  16195. })(jQuery, DevExpress);
  16196. /*! Module viz-core, file categoryTranslator.js */
  16197. (function($, DX, undefined) {
  16198. var isDefined = DX.utils.isDefined,
  16199. round = Math.round;
  16200. DX.viz.core.categoryTranslatorFunctions = {
  16201. translate: function(category, directionOffset) {
  16202. var that = this,
  16203. canvasOptions = that._canvasOptions,
  16204. categoryRecord = that._categoriesToPoints[category],
  16205. stickDelta,
  16206. specialValue = that.translateSpecialCase(category),
  16207. startPointIndex = canvasOptions.startPointIndex || 0,
  16208. stickInterval = that._businessRange.stick ? 0 : 0.5;
  16209. if (isDefined(specialValue))
  16210. return specialValue;
  16211. if (!categoryRecord)
  16212. return null;
  16213. directionOffset = directionOffset || 0;
  16214. directionOffset = canvasOptions.invert ? -directionOffset : directionOffset;
  16215. stickDelta = categoryRecord.index + stickInterval - startPointIndex + directionOffset * 0.5;
  16216. return round(canvasOptions.startPoint + canvasOptions.interval * stickDelta)
  16217. },
  16218. untranslate: function(pos, directionOffset, enableOutOfCanvas) {
  16219. var that = this,
  16220. canvasOptions = that._canvasOptions,
  16221. startPoint = canvasOptions.startPoint,
  16222. categories = that.visibleCategories || that._categories,
  16223. categoriesLength = categories.length,
  16224. result = 0,
  16225. stickInterval = that._businessRange.stick ? 0.5 : 0;
  16226. if (!enableOutOfCanvas && (pos < startPoint || pos > canvasOptions.endPoint))
  16227. return null;
  16228. directionOffset = directionOffset || 0;
  16229. result = round((pos - startPoint) / canvasOptions.interval + stickInterval - 0.5 - directionOffset * 0.5);
  16230. if (categoriesLength === result)
  16231. result--;
  16232. if (result === -1)
  16233. result = 0;
  16234. if (canvasOptions.invert)
  16235. result = categoriesLength - result - 1;
  16236. return categories[result]
  16237. },
  16238. getInterval: function() {
  16239. return this._canvasOptions.interval
  16240. },
  16241. zoom: function(translate, scale) {
  16242. var that = this,
  16243. canvasOptions = that._canvasOptions,
  16244. interval = canvasOptions.interval * scale,
  16245. translateCaltegories = translate / interval,
  16246. stick = that._businessRange.stick,
  16247. startCategoryIndex = parseInt((canvasOptions.startPointIndex || 0) + translateCaltegories + 0.5),
  16248. categoriesLength = parseInt(canvasOptions.canvasLength / interval + (stick ? 1 : 0)) || 1,
  16249. endCategoryIndex,
  16250. newVisibleCategories,
  16251. categories = that._categories,
  16252. newInterval;
  16253. canvasOptions.invert && (categories = categories.slice().reverse());
  16254. if (startCategoryIndex < 0)
  16255. startCategoryIndex = 0;
  16256. endCategoryIndex = startCategoryIndex + categoriesLength;
  16257. if (endCategoryIndex > categories.length) {
  16258. endCategoryIndex = categories.length;
  16259. startCategoryIndex = endCategoryIndex - categoriesLength;
  16260. if (startCategoryIndex < 0)
  16261. startCategoryIndex = 0
  16262. }
  16263. newVisibleCategories = categories.slice(parseInt(startCategoryIndex), parseInt(endCategoryIndex));
  16264. newInterval = that._getDiscreteInterval(newVisibleCategories.length, canvasOptions);
  16265. scale = newInterval / canvasOptions.interval;
  16266. translate = that.translate(newVisibleCategories[0]) * scale - (canvasOptions.startPoint + (stick ? 0 : newInterval / 2));
  16267. return {
  16268. min: !canvasOptions.invert ? newVisibleCategories[0] : newVisibleCategories[newVisibleCategories.length - 1],
  16269. max: !canvasOptions.invert ? newVisibleCategories[newVisibleCategories.length - 1] : newVisibleCategories[0],
  16270. translate: translate,
  16271. scale: scale
  16272. }
  16273. },
  16274. getMinScale: function(zoom) {
  16275. var that = this,
  16276. canvasOptions = that._canvasOptions,
  16277. categoriesLength = (that.visibleCategories || that._categories).length;
  16278. categoriesLength += (parseInt(categoriesLength * 0.1) || 1) * (zoom ? -2 : 2);
  16279. return canvasOptions.canvasLength / (Math.max(categoriesLength, 1) * canvasOptions.interval)
  16280. },
  16281. getScale: function(min, max) {
  16282. var that = this,
  16283. canvasOptions = that._canvasOptions,
  16284. visibleArea = that.getCanvasVisibleArea(),
  16285. stickOffset = !that._businessRange.stick && 1,
  16286. minPoint = that.translate(min, -stickOffset),
  16287. maxPoint = that.translate(max, +stickOffset);
  16288. if (!isDefined(minPoint))
  16289. minPoint = canvasOptions.invert ? visibleArea.max : visibleArea.min;
  16290. if (!isDefined(maxPoint))
  16291. maxPoint = canvasOptions.invert ? visibleArea.min : visibleArea.max;
  16292. return that.canvasLength / Math.abs(maxPoint - minPoint)
  16293. }
  16294. }
  16295. })(jQuery, DevExpress);
  16296. /*! Module viz-core, file logarithmicTranslator.js */
  16297. (function($, DX, undefined) {
  16298. var core = DX.viz.core,
  16299. numericTranslator = core.numericTranslatorFunctions,
  16300. utils = DX.utils,
  16301. raiseTo = utils.raiseTo,
  16302. getLog = utils.getLog;
  16303. core.logarithmicTranslatorFunctions = {
  16304. translate: function(bp) {
  16305. var that = this,
  16306. specialValue = that.translateSpecialCase(bp);
  16307. if (utils.isDefined(specialValue))
  16308. return specialValue;
  16309. return numericTranslator.translate.call(that, getLog(bp, that._businessRange.base))
  16310. },
  16311. untranslate: function() {
  16312. var result = numericTranslator.untranslate.apply(this, arguments);
  16313. return result === null ? result : raiseTo(result, this._businessRange.base)
  16314. },
  16315. getInterval: numericTranslator.getInterval,
  16316. _getValue: function(value) {
  16317. return Math.pow(this._canvasOptions.base, value)
  16318. },
  16319. zoom: numericTranslator.zoom,
  16320. getMinScale: numericTranslator.getMinScale,
  16321. getScale: function(val1, val2) {
  16322. var base = this._businessRange.base;
  16323. val1 = utils.isDefined(val1) ? getLog(val1, base) : undefined;
  16324. val2 = utils.isDefined(val2) ? getLog(val2, base) : undefined;
  16325. return numericTranslator.getScale.call(this, val1, val2)
  16326. }
  16327. }
  16328. })(jQuery, DevExpress);
  16329. /*! Module viz-core, file translator1D.js */
  16330. (function(DX, undefined) {
  16331. var _Number = Number;
  16332. function Translator1D() {
  16333. this.setDomain(arguments[0], arguments[1]).setCodomain(arguments[2], arguments[3])
  16334. }
  16335. Translator1D.prototype = {
  16336. constructor: Translator1D,
  16337. setDomain: function(domain1, domain2) {
  16338. var that = this;
  16339. that._domain1 = _Number(domain1);
  16340. that._domain2 = _Number(domain2);
  16341. that._domainDelta = that._domain2 - that._domain1;
  16342. return that
  16343. },
  16344. setCodomain: function(codomain1, codomain2) {
  16345. var that = this;
  16346. that._codomain1 = _Number(codomain1);
  16347. that._codomain2 = _Number(codomain2);
  16348. that._codomainDelta = that._codomain2 - that._codomain1;
  16349. return that
  16350. },
  16351. getDomain: function() {
  16352. return [this._domain1, this._domain2]
  16353. },
  16354. getCodomain: function() {
  16355. return [this._codomain1, this._codomain2]
  16356. },
  16357. getDomainStart: function() {
  16358. return this._domain1
  16359. },
  16360. getDomainEnd: function() {
  16361. return this._domain2
  16362. },
  16363. getCodomainStart: function() {
  16364. return this._codomain1
  16365. },
  16366. getCodomainEnd: function() {
  16367. return this._codomain2
  16368. },
  16369. getDomainRange: function() {
  16370. return this._domainDelta
  16371. },
  16372. getCodomainRange: function() {
  16373. return this._codomainDelta
  16374. },
  16375. translate: function(value) {
  16376. var ratio = (_Number(value) - this._domain1) / this._domainDelta;
  16377. return 0 <= ratio && ratio <= 1 ? this._codomain1 + ratio * this._codomainDelta : NaN
  16378. },
  16379. adjust: function(value) {
  16380. var ratio = (_Number(value) - this._domain1) / this._domainDelta,
  16381. result = NaN;
  16382. if (ratio < 0)
  16383. result = this._domain1;
  16384. else if (ratio > 1)
  16385. result = this._domain2;
  16386. else if (0 <= ratio && ratio <= 1)
  16387. result = _Number(value);
  16388. return result
  16389. }
  16390. };
  16391. DX.viz.core.Translator1D = Translator1D
  16392. })(DevExpress);
  16393. /*! Module viz-core, file translator2D.js */
  16394. (function($, DX, undefined) {
  16395. var core = DX.viz.core,
  16396. utils = DX.utils,
  16397. getLog = utils.getLog,
  16398. getPower = utils.getPower,
  16399. isDefined = utils.isDefined,
  16400. _abs = Math.abs,
  16401. CANVAS_PROP = ["width", "height", "left", "top", "bottom", "right"],
  16402. NUMBER_EQUALITY_CORRECTION = 1,
  16403. DATETIME_EQUALITY_CORRECTION = 60000,
  16404. _noop = $.noop,
  16405. _Translator2d;
  16406. var validateCanvas = function(canvas) {
  16407. $.each(CANVAS_PROP, function(_, prop) {
  16408. canvas[prop] = parseInt(canvas[prop]) || 0
  16409. });
  16410. return canvas
  16411. };
  16412. var makeCategoriesToPoints = function(categories, invert) {
  16413. var categoriesToPoints = {},
  16414. category,
  16415. length = categories.length,
  16416. i;
  16417. for (i = 0; i < length; i++) {
  16418. category = categories[i];
  16419. categoriesToPoints[category] = {
  16420. name: category,
  16421. index: invert ? length - 1 - i : i
  16422. }
  16423. }
  16424. return categoriesToPoints
  16425. };
  16426. var validateBusinessRange = function(businessRange) {
  16427. function validate(valueSelector, baseValueSeletor) {
  16428. if (!isDefined(businessRange[valueSelector]) && isDefined(businessRange[baseValueSeletor]))
  16429. businessRange[valueSelector] = businessRange[baseValueSeletor]
  16430. }
  16431. validate("minVisible", "min");
  16432. validate("maxVisible", "max");
  16433. return businessRange
  16434. };
  16435. _Translator2d = core.Translator2D = function(businessRange, canvas, options) {
  16436. this.update(businessRange, canvas, options)
  16437. };
  16438. _Translator2d.prototype = {
  16439. constructor: _Translator2d,
  16440. reinit: function() {
  16441. var that = this,
  16442. range = that._businessRange,
  16443. categories = range.categories || [],
  16444. script = {},
  16445. canvasOptions = that._prepareCanvasOptions(),
  16446. visibleCategories = utils.getCategoriesInfo(categories, range.minVisible, range.maxVisible).categories,
  16447. categoriesLength = (visibleCategories || categories).length;
  16448. switch (range.axisType) {
  16449. case"logarithmic":
  16450. script = core.logarithmicTranslatorFunctions;
  16451. break;
  16452. case"discrete":
  16453. script = core.categoryTranslatorFunctions;
  16454. that._categories = categories;
  16455. canvasOptions.interval = that._getDiscreteInterval(range.addSpiderCategory ? categoriesLength + 1 : categoriesLength, canvasOptions);
  16456. that._categoriesToPoints = makeCategoriesToPoints(categories, canvasOptions.invert);
  16457. if (visibleCategories && visibleCategories.length) {
  16458. canvasOptions.startPointIndex = that._categoriesToPoints[visibleCategories[canvasOptions.invert ? visibleCategories.length - 1 : 0]].index;
  16459. that.visibleCategories = visibleCategories
  16460. }
  16461. break;
  16462. default:
  16463. if (range.dataType === "datetime")
  16464. script = core.datetimeTranslatorFunctions;
  16465. else
  16466. script = core.numericTranslatorFunctions
  16467. }
  16468. that.translate = script.translate;
  16469. that.untranslate = script.untranslate;
  16470. that.getInterval = script.getInterval;
  16471. that.zoom = script.zoom;
  16472. that.getMinScale = script.getMinScale;
  16473. that._getValue = script._getValue;
  16474. that.getScale = script.getScale;
  16475. that._conversionValue = that._options.conversionValue ? function(value) {
  16476. return value
  16477. } : function(value) {
  16478. return Math.round(value)
  16479. }
  16480. },
  16481. _getDiscreteInterval: function(categoriesLength, canvasOptions) {
  16482. var correctedCategoriesCount = categoriesLength - (this._businessRange.stick ? 1 : 0);
  16483. return correctedCategoriesCount > 0 ? canvasOptions.canvasLength / correctedCategoriesCount : canvasOptions.canvasLength
  16484. },
  16485. _getCanvasBounds: function(range) {
  16486. var min = range.min,
  16487. max = range.max,
  16488. minVisible = range.minVisible,
  16489. maxVisible = range.maxVisible,
  16490. newMin,
  16491. newMax,
  16492. base = range.base,
  16493. isDateTime = utils.isDate(max) || utils.isDate(min),
  16494. correction = isDateTime ? DATETIME_EQUALITY_CORRECTION : NUMBER_EQUALITY_CORRECTION;
  16495. if (range.axisType === 'logarithmic') {
  16496. maxVisible = getLog(maxVisible, base);
  16497. minVisible = getLog(minVisible, base);
  16498. min = getLog(min, base);
  16499. max = getLog(max, base)
  16500. }
  16501. if (isDefined(min) && isDefined(max) && min.valueOf() === max.valueOf()) {
  16502. newMin = min.valueOf() - correction;
  16503. newMax = max.valueOf() + correction;
  16504. if (isDateTime) {
  16505. min = new Date(newMin);
  16506. max = new Date(newMax)
  16507. }
  16508. else {
  16509. min = min !== 0 ? newMin : 0;
  16510. max = newMax
  16511. }
  16512. }
  16513. if (isDefined(minVisible) && isDefined(maxVisible) && minVisible.valueOf() === maxVisible.valueOf()) {
  16514. newMin = minVisible.valueOf() - correction;
  16515. newMax = maxVisible.valueOf() + correction;
  16516. if (isDateTime) {
  16517. minVisible = newMin < min.valueOf() ? min : new Date(newMin);
  16518. maxVisible = newMax > max.valueOf() ? max : new Date(newMax)
  16519. }
  16520. else {
  16521. if (minVisible !== 0)
  16522. minVisible = newMin < min ? min : newMin;
  16523. maxVisible = newMax > max ? max : newMax
  16524. }
  16525. }
  16526. return {
  16527. base: base,
  16528. rangeMin: min,
  16529. rangeMax: max,
  16530. rangeMinVisible: minVisible,
  16531. rangeMaxVisible: maxVisible
  16532. }
  16533. },
  16534. _prepareCanvasOptions: function() {
  16535. var that = this,
  16536. businessRange = that._businessRange,
  16537. canvasOptions = that._canvasOptions = that._getCanvasBounds(businessRange),
  16538. length,
  16539. canvas = that._canvas;
  16540. if (that._options.direction === "horizontal") {
  16541. canvasOptions.startPoint = canvas.left;
  16542. length = canvas.width;
  16543. canvasOptions.endPoint = canvas.width - canvas.right;
  16544. canvasOptions.invert = businessRange.invert
  16545. }
  16546. else {
  16547. canvasOptions.startPoint = canvas.top;
  16548. length = canvas.height;
  16549. canvasOptions.endPoint = canvas.height - canvas.bottom;
  16550. canvasOptions.invert = !businessRange.invert
  16551. }
  16552. that.canvasLength = canvasOptions.canvasLength = canvasOptions.endPoint - canvasOptions.startPoint;
  16553. canvasOptions.rangeDoubleError = Math.pow(10, getPower(canvasOptions.rangeMax - canvasOptions.rangeMin) - getPower(length) - 2);
  16554. canvasOptions.ratioOfCanvasRange = canvasOptions.canvasLength / (canvasOptions.rangeMaxVisible - canvasOptions.rangeMinVisible);
  16555. return canvasOptions
  16556. },
  16557. updateBusinessRange: function(businessRange) {
  16558. this._businessRange = validateBusinessRange(businessRange);
  16559. this.reinit()
  16560. },
  16561. update: function(businessRange, canvas, options) {
  16562. var that = this;
  16563. that._options = $.extend(that._options || {}, options);
  16564. that._canvas = validateCanvas(canvas);
  16565. that.updateBusinessRange(businessRange)
  16566. },
  16567. getBusinessRange: function() {
  16568. return this._businessRange
  16569. },
  16570. getCanvasVisibleArea: function() {
  16571. return {
  16572. min: this._canvasOptions.startPoint,
  16573. max: this._canvasOptions.endPoint
  16574. }
  16575. },
  16576. translateSpecialCase: function(value) {
  16577. var that = this,
  16578. canvasOptions = that._canvasOptions,
  16579. startPoint = canvasOptions.startPoint,
  16580. endPoint = canvasOptions.endPoint,
  16581. range = that._businessRange,
  16582. minVisible = range.minVisible,
  16583. maxVisible = range.maxVisible,
  16584. invert,
  16585. result = null;
  16586. switch (value) {
  16587. case"canvas_position_default":
  16588. if (minVisible <= 0 && maxVisible >= 0)
  16589. result = that.translate(0);
  16590. else {
  16591. invert = range.invert ^ (minVisible <= 0 && maxVisible <= 0);
  16592. if (that._options.direction === "horizontal")
  16593. result = invert ? endPoint : startPoint;
  16594. else
  16595. result = invert ? startPoint : endPoint
  16596. }
  16597. break;
  16598. case"canvas_position_left":
  16599. case"canvas_position_top":
  16600. result = startPoint;
  16601. break;
  16602. case"canvas_position_center":
  16603. case"canvas_position_middle":
  16604. result = startPoint + canvasOptions.canvasLength / 2;
  16605. break;
  16606. case"canvas_position_right":
  16607. case"canvas_position_bottom":
  16608. result = endPoint;
  16609. break;
  16610. case"canvas_position_start":
  16611. result = canvasOptions.invert ? endPoint : startPoint;
  16612. break;
  16613. case"canvas_position_end":
  16614. result = canvasOptions.invert ? startPoint : endPoint;
  16615. break
  16616. }
  16617. return result
  16618. },
  16619. _calculateProjection: function(distance) {
  16620. var canvasOptions = this._canvasOptions;
  16621. return canvasOptions.invert ? canvasOptions.endPoint - distance : canvasOptions.startPoint + distance
  16622. },
  16623. _calculateUnProjection: function(distance) {
  16624. var canvasOptions = this._canvasOptions;
  16625. return canvasOptions.invert ? canvasOptions.rangeMaxVisible.valueOf() - distance : canvasOptions.rangeMinVisible.valueOf() + distance
  16626. },
  16627. getVisibleCategories: function() {
  16628. return this.visibleCategories
  16629. },
  16630. getMinBarSize: function(minBarSize) {
  16631. var visibleArea = this.getCanvasVisibleArea(),
  16632. minValue = this.untranslate(visibleArea.min + minBarSize);
  16633. return _abs(this.untranslate(visibleArea.min) - (!isDefined(minValue) ? this.untranslate(visibleArea.max) : minValue))
  16634. },
  16635. translate: _noop,
  16636. untranslate: _noop,
  16637. getInterval: _noop,
  16638. zoom: _noop,
  16639. getMinScale: _noop
  16640. }
  16641. })(jQuery, DevExpress);
  16642. /*! Module viz-core, file polarTranslator.js */
  16643. (function($, DX, undefined) {
  16644. var utils = DX.utils,
  16645. SHIFT_ANGLE = 90,
  16646. _round = Math.round;
  16647. function PolarTranslator(businessRange, canvas, options) {
  16648. var that = this;
  16649. that._argCanvas = {
  16650. left: 0,
  16651. right: 0,
  16652. width: this._getAngle()
  16653. };
  16654. that._valCanvas = {
  16655. left: 0,
  16656. right: 0
  16657. };
  16658. that.canvas = canvas;
  16659. that._init();
  16660. that._arg = new DX.viz.core.Translator2D(businessRange.arg, that._argCanvas, {
  16661. direction: "horizontal",
  16662. conversionValue: true
  16663. });
  16664. that._val = new DX.viz.core.Translator2D(businessRange.val, that._valCanvas, {direction: "horizontal"});
  16665. that._businessRange = businessRange;
  16666. that.startAngle = utils.isNumber(options.startAngle) ? options.startAngle : 0
  16667. }
  16668. PolarTranslator.prototype = {
  16669. constructor: PolarTranslator,
  16670. _init: function() {
  16671. var canvas = this.canvas;
  16672. this._setCoords({
  16673. x: canvas.left + (canvas.width - canvas.right - canvas.left) / 2,
  16674. y: canvas.top + (canvas.height - canvas.top - canvas.bottom) / 2,
  16675. r: Math.min(canvas.width - canvas.left - canvas.right, canvas.height - canvas.top - canvas.bottom) / 2
  16676. });
  16677. this._valCanvas.width = this._rad
  16678. },
  16679. reinit: function() {
  16680. this._init();
  16681. this._arg.reinit();
  16682. this._val.reinit()
  16683. },
  16684. _setCoords: function(coord) {
  16685. this._x0 = coord.x;
  16686. this._y0 = coord.y;
  16687. this._rad = coord.r < 0 ? 0 : coord.r
  16688. },
  16689. getBusinessRange: function() {
  16690. return this._businessRange
  16691. },
  16692. translate: function(arg, val, offsets) {
  16693. var that = this,
  16694. argTranslate = that._arg.translate(arg, offsets && offsets[0]),
  16695. radius = that._val.translate(val, offsets && offsets[1]),
  16696. angle = utils.isDefined(argTranslate) ? argTranslate + that.startAngle - SHIFT_ANGLE : null,
  16697. cossin = utils.getCosAndSin(angle),
  16698. x,
  16699. y;
  16700. y = _round(that._y0 + radius * cossin.sin);
  16701. x = _round(that._x0 + radius * cossin.cos);
  16702. return {
  16703. x: x,
  16704. y: y,
  16705. angle: angle,
  16706. radius: radius
  16707. }
  16708. },
  16709. getValLength: function() {
  16710. return this._rad
  16711. },
  16712. getCenter: function() {
  16713. return {
  16714. x: this._x0,
  16715. y: this._y0
  16716. }
  16717. },
  16718. getBaseAngle: function() {
  16719. return this.startAngle - SHIFT_ANGLE
  16720. },
  16721. getInterval: function() {
  16722. return this._arg.getInterval()
  16723. },
  16724. getValInterval: function() {
  16725. return this._val.getInterval()
  16726. },
  16727. _getAngle: function() {
  16728. return 360
  16729. },
  16730. getStartAngle: function() {
  16731. return this.startAngle
  16732. },
  16733. getComponent: function(type) {
  16734. var that = this,
  16735. translator = this["_" + type];
  16736. translator.getRadius = function() {
  16737. return that.getValLength()
  16738. };
  16739. translator.getCenter = function() {
  16740. return that.getCenter()
  16741. };
  16742. translator.getStartAngle = function() {
  16743. return that.getStartAngle()
  16744. };
  16745. return translator
  16746. },
  16747. _untranslate: function(x, y) {
  16748. var radius = utils.getDistance(this._x0, this._y0, x, y),
  16749. angle = Math.atan2(y - this._y0, x - this._x0);
  16750. return {
  16751. r: radius,
  16752. phi: angle
  16753. }
  16754. },
  16755. untranslate: function(x, y) {
  16756. var pos = this._untranslate(x, y);
  16757. pos.phi = _round(utils.normalizeAngle(pos.phi * 180 / Math.PI));
  16758. pos.r = _round(pos.r);
  16759. return pos
  16760. },
  16761. getVisibleCategories: $.noop,
  16762. getCanvasVisibleArea: function() {
  16763. return {}
  16764. },
  16765. getMinBarSize: function(minBarSize) {
  16766. return this._val.getMinBarSize(minBarSize)
  16767. }
  16768. };
  16769. DX.viz.core.PolarTranslator = PolarTranslator
  16770. })(jQuery, DevExpress);
  16771. /*! Module viz-core, file rectangle.js */
  16772. (function(DX, undefined) {
  16773. var isFinite = window.isFinite;
  16774. DX.viz.core.Rectangle = DX.Class.inherit({
  16775. ctor: function(options) {
  16776. var that = this;
  16777. options = options || {};
  16778. that.left = Number(options.left) || 0;
  16779. that.right = Number(options.right) || 0;
  16780. that.top = Number(options.top) || 0;
  16781. that.bottom = Number(options.bottom) || 0
  16782. },
  16783. width: function() {
  16784. return this.right - this.left
  16785. },
  16786. height: function() {
  16787. return this.bottom - this.top
  16788. },
  16789. horizontalMiddle: function() {
  16790. return (this.left + this.right) / 2
  16791. },
  16792. verticalMiddle: function() {
  16793. return (this.top + this.bottom) / 2
  16794. },
  16795. raw: function() {
  16796. var that = this;
  16797. return {
  16798. left: that.left,
  16799. top: that.top,
  16800. right: that.right,
  16801. bottom: that.bottom
  16802. }
  16803. },
  16804. clone: function() {
  16805. return new this.constructor(this.raw())
  16806. },
  16807. move: function(dx, dy) {
  16808. var result = this.clone();
  16809. if (isFinite(dx) && isFinite(dy)) {
  16810. result.left += Number(dx);
  16811. result.right += Number(dx);
  16812. result.top += Number(dy);
  16813. result.bottom += Number(dy)
  16814. }
  16815. return result
  16816. },
  16817. inflate: function(dx, dy) {
  16818. var result = this.clone();
  16819. if (isFinite(dx) && isFinite(dy)) {
  16820. result.left -= Number(dx);
  16821. result.right += Number(dx);
  16822. result.top -= Number(dy);
  16823. result.bottom += Number(dy)
  16824. }
  16825. return result
  16826. },
  16827. scale: function(factor) {
  16828. var that = this;
  16829. if (factor > 0)
  16830. return that.inflate(that.width() * (factor - 1) / 2, that.height() * (factor - 1) / 2);
  16831. return that.clone()
  16832. }
  16833. })
  16834. })(DevExpress);
  16835. /*! Module viz-core, file layoutElement.js */
  16836. (function($, DX, undefined) {
  16837. var core = DX.viz.core,
  16838. _round = Math.round;
  16839. var _splitPair = DX.utils.splitPair;
  16840. var defaultPosition = ["center", "center"],
  16841. defaultOffset = [0, 0];
  16842. var getAlignFactor = function(align) {
  16843. switch (align) {
  16844. case"center":
  16845. return 0.5;
  16846. case"right":
  16847. case"bottom":
  16848. return 1;
  16849. default:
  16850. return 0
  16851. }
  16852. };
  16853. function WrapperLayoutElement(renderElement, bbox) {
  16854. this._renderElement = renderElement;
  16855. this._cacheBBox = bbox
  16856. }
  16857. WrapperLayoutElement.prototype = {
  16858. position: function(options) {
  16859. var that = this,
  16860. ofBBox = options.of.getBBox ? options.of.getBBox() : options.of,
  16861. myBBox = this.getBBox(),
  16862. at = _splitPair(options.at) || defaultPosition,
  16863. my = _splitPair(options.my) || defaultPosition,
  16864. offset = _splitPair(options.offset) || defaultOffset,
  16865. shiftX = -getAlignFactor(my[0]) * myBBox.width + ofBBox.x - myBBox.x + getAlignFactor(at[0]) * ofBBox.width + parseInt(offset[0]),
  16866. shiftY = -getAlignFactor(my[1]) * myBBox.height + ofBBox.y - myBBox.y + getAlignFactor(at[1]) * ofBBox.height + parseInt(offset[1]);
  16867. that._renderElement.move(_round(shiftX), _round(shiftY))
  16868. },
  16869. getBBox: function() {
  16870. return this._cacheBBox || this._renderElement.getBBox()
  16871. },
  16872. draw: function(){}
  16873. };
  16874. core.WrapperLayoutElement = WrapperLayoutElement
  16875. })(jQuery, DevExpress);
  16876. /*! Module viz-core, file themes.js */
  16877. (function(DX, $, undefined) {
  16878. var themes = {},
  16879. themesMapping = {},
  16880. themesSchemeMapping = {},
  16881. _extend = $.extend,
  16882. _each = $.each,
  16883. currentThemeName = null,
  16884. nextCacheUid = 0,
  16885. widgetsCache = {};
  16886. function normalizeName(name) {
  16887. return name ? String(name).toLowerCase() : null
  16888. }
  16889. function findTheme(themeName) {
  16890. var name = normalizeName(themeName);
  16891. return themes[name] || themes[themesMapping[name] || currentThemeName]
  16892. }
  16893. function findThemeNameByName(name, scheme) {
  16894. return themesMapping[name + '.' + scheme] || themesSchemeMapping[name + '.' + scheme] || themesMapping[name]
  16895. }
  16896. function findThemeNameByPlatform(platform, version, scheme) {
  16897. return findThemeNameByName(platform + version, scheme) || findThemeNameByName(platform, scheme)
  16898. }
  16899. function currentTheme(themeName, colorScheme) {
  16900. if (!arguments.length)
  16901. return currentThemeName;
  16902. var scheme = normalizeName(colorScheme);
  16903. currentThemeName = (themeName && themeName.platform ? findThemeNameByPlatform(normalizeName(themeName.platform), themeName.version, scheme) : findThemeNameByName(normalizeName(themeName), scheme)) || currentThemeName;
  16904. return this
  16905. }
  16906. function getThemeInfo(themeName, splitter) {
  16907. var k = themeName.indexOf(splitter);
  16908. return k > 0 ? {
  16909. name: themeName.substring(0, k),
  16910. scheme: themeName.substring(k + 1)
  16911. } : null
  16912. }
  16913. function registerThemeName(themeName, targetThemeName) {
  16914. var themeInfo = getThemeInfo(themeName, '.') || getThemeInfo(themeName, '-') || {name: themeName},
  16915. name = themeInfo.name,
  16916. scheme = themeInfo.scheme;
  16917. if (scheme) {
  16918. themesMapping[name] = themesMapping[name] || targetThemeName;
  16919. themesMapping[name + '.' + scheme] = themesMapping[name + '-' + scheme] = targetThemeName
  16920. }
  16921. else
  16922. themesMapping[name] = targetThemeName
  16923. }
  16924. function registerTheme(theme, baseThemeName) {
  16925. var themeName = normalizeName(theme && theme.name);
  16926. if (themeName) {
  16927. registerThemeName(themeName, themeName);
  16928. themes[themeName] = _extend(true, {}, findTheme(baseThemeName), patchTheme(theme))
  16929. }
  16930. }
  16931. function registerThemeAlias(alias, theme) {
  16932. registerThemeName(normalizeName(alias), normalizeName(theme))
  16933. }
  16934. function registerThemeSchemeAlias(from, to) {
  16935. themesSchemeMapping[from] = to
  16936. }
  16937. function mergeScalar(target, field, source, sourceValue) {
  16938. var _value = source ? source[field] : sourceValue;
  16939. if (_value !== undefined && target[field] === undefined)
  16940. target[field] = _value
  16941. }
  16942. function mergeObject(target, field, source, sourceValue) {
  16943. var _value = source ? source[field] : sourceValue;
  16944. if (_value !== undefined)
  16945. target[field] = _extend(true, {}, _value, target[field])
  16946. }
  16947. function patchTheme(theme) {
  16948. theme = _extend(true, {
  16949. loadingIndicator: {font: {}},
  16950. legend: {
  16951. font: {},
  16952. border: {}
  16953. },
  16954. title: {font: {}},
  16955. tooltip: {font: {}},
  16956. "chart:common": {},
  16957. "chart:common:axis": {
  16958. grid: {},
  16959. minorGrid: {},
  16960. tick: {},
  16961. minorTick: {},
  16962. title: {font: {}},
  16963. label: {font: {}}
  16964. },
  16965. chart: {commonSeriesSettings: {candlestick: {}}},
  16966. pie: {},
  16967. polar: {},
  16968. gauge: {scale: {
  16969. majorTick: {},
  16970. minorTick: {},
  16971. label: {font: {}}
  16972. }},
  16973. barGauge: {},
  16974. map: {background: {}},
  16975. rangeSelector: {
  16976. scale: {label: {font: {}}},
  16977. chart: {}
  16978. },
  16979. sparkline: {},
  16980. bullet: {}
  16981. }, theme);
  16982. mergeScalar(theme.loadingIndicator, "backgroundColor", theme);
  16983. mergeScalar(theme.chart.commonSeriesSettings.candlestick, "innerColor", null, theme.backgroundColor);
  16984. mergeScalar(theme.map.background, "color", null, theme.backgroundColor);
  16985. mergeScalar(theme.title.font, "color", null, theme.primaryTitleColor);
  16986. mergeScalar(theme.legend.font, "color", null, theme.secondaryTitleColor);
  16987. mergeScalar(theme.legend.border, "color", null, theme.axisColor);
  16988. patchAxes(theme);
  16989. _each(["chart", "pie", "polar", "gauge", "barGauge", "map", "rangeSelector", "sparkline", "bullet"], function(_, section) {
  16990. mergeScalar(theme[section], "redrawOnResize", theme);
  16991. mergeScalar(theme[section], "containerBackgroundColor", null, theme.backgroundColor);
  16992. mergeObject(theme[section], "tooltip", theme)
  16993. });
  16994. _each(["chart", "pie", "polar", "gauge", "barGauge", "map", "rangeSelector"], function(_, section) {
  16995. mergeObject(theme[section], "loadingIndicator", theme);
  16996. mergeObject(theme[section], "legend", theme)
  16997. });
  16998. _each(["chart", "pie", "polar", "gauge", "barGauge"], function(_, section) {
  16999. mergeObject(theme[section], "title", theme)
  17000. });
  17001. _each(["gauge", "barGauge"], function(_, section) {
  17002. mergeObject(theme[section], "subtitle", null, theme.title)
  17003. });
  17004. _each(["chart", "pie", "polar"], function(_, section) {
  17005. mergeObject(theme, section, null, theme["chart:common"])
  17006. });
  17007. _each(["chart", "polar"], function(_, section) {
  17008. theme[section] = theme[section] || {};
  17009. mergeObject(theme[section], "commonAxisSettings", null, theme["chart:common:axis"])
  17010. });
  17011. mergeObject(theme.rangeSelector.chart, "commonSeriesSettings", theme.chart);
  17012. mergeObject(theme.rangeSelector.chart, "dataPrepareSettings", theme.chart);
  17013. mergeScalar(theme.map.legend, "backgroundColor", theme);
  17014. return theme
  17015. }
  17016. function patchAxes(theme) {
  17017. var commonAxisSettings = theme["chart:common:axis"],
  17018. colorFieldName = "color";
  17019. _each([commonAxisSettings, commonAxisSettings.grid, commonAxisSettings.minorGrid, commonAxisSettings.tick, commonAxisSettings.minorTick], function(_, obj) {
  17020. mergeScalar(obj, colorFieldName, null, theme.axisColor)
  17021. });
  17022. mergeScalar(commonAxisSettings.title.font, colorFieldName, null, theme.secondaryTitleColor);
  17023. mergeScalar(commonAxisSettings.label.font, colorFieldName, null, theme.axisLabelColor);
  17024. mergeScalar(theme.gauge.scale.label.font, colorFieldName, null, theme.axisLabelColor);
  17025. mergeScalar(theme.gauge.scale.majorTick, colorFieldName, null, theme.backgroundColor);
  17026. mergeScalar(theme.gauge.scale.minorTick, colorFieldName, null, theme.backgroundColor);
  17027. mergeScalar(theme.rangeSelector.scale.label.font, colorFieldName, null, theme.axisLabelColor)
  17028. }
  17029. function addCacheItem(target) {
  17030. var cacheUid = ++nextCacheUid;
  17031. target._cache = cacheUid;
  17032. widgetsCache[cacheUid] = target
  17033. }
  17034. function removeCacheItem(target) {
  17035. delete widgetsCache[target._cache]
  17036. }
  17037. function refreshAll() {
  17038. _each(widgetsCache, function() {
  17039. this.refresh()
  17040. });
  17041. return this
  17042. }
  17043. _extend(DX.viz.core, {
  17044. findTheme: findTheme,
  17045. currentTheme: currentTheme,
  17046. registerTheme: registerTheme,
  17047. registerThemeAlias: registerThemeAlias,
  17048. registerThemeSchemeAlias: registerThemeSchemeAlias,
  17049. refreshAll: refreshAll,
  17050. addCacheItem: addCacheItem,
  17051. removeCacheItem: removeCacheItem
  17052. });
  17053. _extend(DX.viz.core, {
  17054. themes: themes,
  17055. themesMapping: themesMapping,
  17056. themesSchemeMapping: themesSchemeMapping,
  17057. widgetsCache: widgetsCache
  17058. })
  17059. })(DevExpress, jQuery);
  17060. /*! Module viz-core, file palette.js */
  17061. (function(DX, $, undefined) {
  17062. var _String = window.String,
  17063. _floor = Math.floor,
  17064. _ceil = Math.ceil,
  17065. _Color = DX.Color,
  17066. _isArray = DX.utils.isArray,
  17067. _isString = DX.utils.isString,
  17068. _extend = $.extend;
  17069. var palettes = {
  17070. 'default': {
  17071. simpleSet: ['#5f8b95', '#ba4d51', '#af8a53', '#955f71', '#859666', '#7e688c'],
  17072. indicatingSet: ['#a3b97c', '#e1b676', '#ec7f83'],
  17073. gradientSet: ['#5f8b95', '#ba4d51']
  17074. },
  17075. 'harmony light': {
  17076. simpleSet: ['#fcb65e', '#679ec5', '#ad79ce', '#7abd5c', '#e18e92', '#b6d623', '#b7abea', '#85dbd5'],
  17077. indicatingSet: ['#b6d623', '#fcb65e', '#e18e92'],
  17078. gradientSet: ['#7abd5c', '#fcb65e']
  17079. },
  17080. 'soft pastel': {
  17081. simpleSet: ['#60a69f', '#78b6d9', '#6682bb', '#a37182', '#eeba69', '#90ba58', '#456c68', '#7565a4'],
  17082. indicatingSet: ['#90ba58', '#eeba69', '#a37182'],
  17083. gradientSet: ['#78b6d9', '#eeba69']
  17084. },
  17085. pastel: {
  17086. simpleSet: ['#bb7862', '#70b3a1', '#bb626a', '#057d85', '#ab394b', '#dac599', '#153459', '#b1d2c6'],
  17087. indicatingSet: ['#70b3a1', '#dac599', '#bb626a'],
  17088. gradientSet: ['#bb7862', '#70b3a1']
  17089. },
  17090. bright: {
  17091. simpleSet: ['#70c92f', '#f8ca00', '#bd1550', '#e97f02', '#9d419c', '#7e4452', '#9ab57e', '#36a3a6'],
  17092. indicatingSet: ['#70c92f', '#f8ca00', '#bd1550'],
  17093. gradientSet: ['#e97f02', '#f8ca00']
  17094. },
  17095. soft: {
  17096. simpleSet: ['#cbc87b', '#9ab57e', '#e55253', '#7e4452', '#e8c267', '#565077', '#6babac', '#ad6082'],
  17097. indicatingSet: ['#9ab57e', '#e8c267', '#e55253'],
  17098. gradientSet: ['#9ab57e', '#e8c267']
  17099. },
  17100. ocean: {
  17101. simpleSet: ['#75c099', '#acc371', '#378a8a', '#5fa26a', '#064970', '#38c5d2', '#00a7c6', '#6f84bb'],
  17102. indicatingSet: ['#c8e394', '#7bc59d', '#397c8b'],
  17103. gradientSet: ['#acc371', '#38c5d2']
  17104. },
  17105. vintage: {
  17106. simpleSet: ['#dea484', '#efc59c', '#cb715e', '#eb9692', '#a85c4c', '#f2c0b5', '#c96374', '#dd956c'],
  17107. indicatingSet: ['#ffe5c6', '#f4bb9d', '#e57660'],
  17108. gradientSet: ['#efc59c', '#cb715e']
  17109. },
  17110. violet: {
  17111. simpleSet: ['#d1a1d1', '#eeacc5', '#7b5685', '#7e7cad', '#a13d73', '#5b41ab', '#e287e2', '#689cc1'],
  17112. indicatingSet: ['#d8e2f6', '#d0b2da', '#d56a8a'],
  17113. gradientSet: ['#eeacc5', '#7b5685']
  17114. }
  17115. };
  17116. var currentPaletteName = 'default';
  17117. function currentPalette(name) {
  17118. if (name === undefined)
  17119. return currentPaletteName;
  17120. else {
  17121. name = String(name).toLowerCase();
  17122. currentPaletteName = name in palettes ? name : 'default'
  17123. }
  17124. }
  17125. function getPalette(palette, parameters) {
  17126. var result;
  17127. if (_isArray(palette))
  17128. result = palette;
  17129. else {
  17130. parameters = parameters || {};
  17131. var type = parameters.type || 'simpleSet';
  17132. if (_isString(palette)) {
  17133. var name = palette.toLowerCase(),
  17134. baseContainer = palettes[name],
  17135. themedContainer = parameters.theme && palettes[name + '_' + _String(parameters.theme).toLowerCase()];
  17136. result = themedContainer && themedContainer[type] || baseContainer && baseContainer[type]
  17137. }
  17138. if (!result)
  17139. result = palettes[currentPaletteName][type]
  17140. }
  17141. return result ? result.slice(0) : null
  17142. }
  17143. function registerPalette(name, palette, theme) {
  17144. var item = {};
  17145. if (_isArray(palette))
  17146. item.simpleSet = palette.slice(0);
  17147. else if (palette) {
  17148. item.simpleSet = _isArray(palette.simpleSet) ? palette.simpleSet.slice(0) : undefined;
  17149. item.indicatingSet = _isArray(palette.indicatingSet) ? palette.indicatingSet.slice(0) : undefined;
  17150. item.gradientSet = _isArray(palette.gradientSet) ? palette.gradientSet.slice(0) : undefined
  17151. }
  17152. if (item.simpleSet || item.indicatingSet || item.gradientSet) {
  17153. var paletteName = _String(name).toLowerCase();
  17154. if (theme)
  17155. paletteName = paletteName + '_' + _String(theme).toLowerCase();
  17156. _extend(palettes[paletteName] = palettes[paletteName] || {}, item)
  17157. }
  17158. }
  17159. function RingBuf(buf) {
  17160. var ind = 0;
  17161. this.next = function() {
  17162. var res = buf[ind++];
  17163. if (ind === buf.length)
  17164. this.reset();
  17165. return res
  17166. };
  17167. this.reset = function() {
  17168. ind = 0
  17169. }
  17170. }
  17171. function Palette(palette, parameters) {
  17172. parameters = parameters || {};
  17173. this._originalPalette = getPalette(palette, parameters);
  17174. var stepHighlight = parameters ? parameters.stepHighlight || 0 : 0;
  17175. this._paletteSteps = new RingBuf([0, stepHighlight, -stepHighlight]);
  17176. this._resetPalette()
  17177. }
  17178. _extend(Palette.prototype, {
  17179. dispose: function() {
  17180. this._originalPalette = this._palette = this._paletteSteps = null;
  17181. return this
  17182. },
  17183. getNextColor: function() {
  17184. var that = this;
  17185. if (that._currentColor >= that._palette.length)
  17186. that._resetPalette();
  17187. return that._palette[that._currentColor++]
  17188. },
  17189. _resetPalette: function() {
  17190. var that = this;
  17191. that._currentColor = 0;
  17192. var step = that._paletteSteps.next(),
  17193. originalPalette = that._originalPalette;
  17194. if (step) {
  17195. var palette = that._palette = [],
  17196. i = 0,
  17197. ii = originalPalette.length;
  17198. for (; i < ii; ++i)
  17199. palette[i] = getNewColor(originalPalette[i], step)
  17200. }
  17201. else
  17202. that._palette = originalPalette.slice(0)
  17203. },
  17204. reset: function() {
  17205. this._paletteSteps.reset();
  17206. this._resetPalette();
  17207. return this
  17208. }
  17209. });
  17210. function getNewColor(currentColor, step) {
  17211. var newColor = new _Color(currentColor).alter(step),
  17212. lightness = getLightness(newColor);
  17213. if (lightness > 200 || lightness < 55)
  17214. newColor = new _Color(currentColor).alter(-step / 2);
  17215. return newColor.toHex()
  17216. }
  17217. function getLightness(color) {
  17218. return color.r * 0.3 + color.g * 0.59 + color.b * 0.11
  17219. }
  17220. function GradientPalette(source, size) {
  17221. var palette = getPalette(source, {type: 'gradientSet'});
  17222. palette = size > 0 ? createGradientColors(palette, size) : [];
  17223. this.getColor = function(index) {
  17224. return palette[index] || null
  17225. };
  17226. this._DEBUG_source = source;
  17227. this._DEBUG_size = size
  17228. }
  17229. function createGradientColors(source, count) {
  17230. var ncolors = count - 1,
  17231. nsource = source.length - 1,
  17232. colors = [],
  17233. gradient = [],
  17234. i;
  17235. for (i = 0; i <= nsource; ++i)
  17236. colors.push(new _Color(source[i]));
  17237. if (ncolors > 0)
  17238. for (i = 0; i <= ncolors; ++i)
  17239. addColor(i / ncolors);
  17240. else
  17241. addColor(0.5);
  17242. return gradient;
  17243. function addColor(pos) {
  17244. var k = nsource * pos,
  17245. kl = _floor(k),
  17246. kr = _ceil(k);
  17247. gradient.push(colors[kl].blend(colors[kr], k - kl).toHex())
  17248. }
  17249. }
  17250. _extend(DX.viz.core, {
  17251. registerPalette: registerPalette,
  17252. getPalette: getPalette,
  17253. Palette: Palette,
  17254. GradientPalette: GradientPalette,
  17255. currentPalette: currentPalette
  17256. });
  17257. DX.viz.core._DEBUG_palettes = palettes
  17258. })(DevExpress, jQuery);
  17259. /*! Module viz-core, file utils.js */
  17260. (function(DX, $, undefined) {
  17261. var _ceil = Math.ceil,
  17262. _min = Math.min,
  17263. _round = Math.round;
  17264. function selectByKeys(object, keys) {
  17265. return $.map(keys, function(key) {
  17266. return object[key] ? object[key] : null
  17267. })
  17268. }
  17269. function decreaseFields(object, keys, eachDecrease, decrease) {
  17270. var dec = decrease;
  17271. $.each(keys, function(_, key) {
  17272. if (object[key]) {
  17273. object[key] -= eachDecrease;
  17274. dec -= eachDecrease
  17275. }
  17276. });
  17277. return dec
  17278. }
  17279. DX.viz.core.utils = {
  17280. decreaseGaps: function(object, keys, decrease) {
  17281. var arrayGaps;
  17282. do {
  17283. arrayGaps = selectByKeys(object, keys);
  17284. arrayGaps.push(_ceil(decrease / arrayGaps.length));
  17285. decrease = decreaseFields(object, keys, _min.apply(null, arrayGaps), decrease)
  17286. } while (decrease > 0 && arrayGaps.length > 1);
  17287. return decrease
  17288. },
  17289. parseScalar: function(value, defaultValue) {
  17290. return value !== undefined ? value : defaultValue
  17291. },
  17292. enumParser: function(values) {
  17293. var stored = {},
  17294. i,
  17295. ii;
  17296. for (i = 0, ii = values.length; i < ii; ++i)
  17297. stored[String(values[i]).toLowerCase()] = 1;
  17298. return function(value, defaultValue) {
  17299. var _value = String(value).toLowerCase();
  17300. return stored[_value] ? _value : defaultValue
  17301. }
  17302. },
  17303. patchFontOptions: function(options) {
  17304. var fontOptions = {};
  17305. $.each(options || {}, function(key, value) {
  17306. if (/^(cursor|opacity)$/i.test(key));
  17307. else if (key === "color")
  17308. key = "fill";
  17309. else
  17310. key = "font-" + key;
  17311. fontOptions[key] = value
  17312. });
  17313. return fontOptions
  17314. },
  17315. convertPolarToXY: function(centerCoords, startAngle, angle, radius) {
  17316. var shiftAngle = 90,
  17317. cossin;
  17318. angle = DX.utils.isDefined(angle) ? angle + startAngle - shiftAngle : 0;
  17319. cossin = DX.utils.getCosAndSin(angle);
  17320. return {
  17321. x: _round(centerCoords.x + radius * cossin.cos),
  17322. y: _round(centerCoords.y + radius * cossin.sin)
  17323. }
  17324. },
  17325. convertXYToPolar: function(centerCoords, x, y) {
  17326. var radius = DX.utils.getDistance(centerCoords.x, centerCoords.y, x, y),
  17327. angle = Math.atan2(y - centerCoords.y, x - centerCoords.x);
  17328. return {
  17329. phi: _round(DX.utils.normalizeAngle(angle * 180 / Math.PI)),
  17330. r: _round(radius)
  17331. }
  17332. }
  17333. }
  17334. })(DevExpress, jQuery);
  17335. /*! Module viz-core, file baseThemeManager.js */
  17336. (function(DX, $, undefined) {
  17337. var _isString = DX.utils.isString,
  17338. _parseScalar = DX.viz.core.utils.parseScalar,
  17339. _findTheme = DX.viz.core.findTheme,
  17340. _addCacheItem = DX.viz.core.addCacheItem,
  17341. _removeCacheItem = DX.viz.core.removeCacheItem,
  17342. _extend = $.extend,
  17343. _each = $.each;
  17344. function getThemePart(theme, path) {
  17345. var _theme = theme;
  17346. path && _each(path.split('.'), function(_, pathItem) {
  17347. return _theme = _theme[pathItem]
  17348. });
  17349. return _theme
  17350. }
  17351. DX.viz.core.BaseThemeManager = DX.Class.inherit({
  17352. ctor: function() {
  17353. _addCacheItem(this)
  17354. },
  17355. dispose: function() {
  17356. var that = this;
  17357. _removeCacheItem(that);
  17358. that._callback = that._theme = that._font = null;
  17359. return that
  17360. },
  17361. setCallback: function(callback) {
  17362. this._callback = callback;
  17363. return this
  17364. },
  17365. setTheme: function(theme, rtl) {
  17366. this._current = theme;
  17367. this._rtl = rtl;
  17368. return this.refresh()
  17369. },
  17370. refresh: function() {
  17371. var that = this,
  17372. current = that._current || {},
  17373. theme = _findTheme(current.name || current);
  17374. that._themeName = theme.name;
  17375. that._font = _extend({}, theme.font, current.font);
  17376. that._themeSection && _each(that._themeSection.split('.'), function(_, path) {
  17377. theme = _extend(true, {}, theme[path], that._IE8 ? theme[path + 'IE8'] : {})
  17378. });
  17379. that._theme = _extend(true, {}, theme, _isString(current) ? {} : current);
  17380. that._initializeTheme();
  17381. if (_parseScalar(that._rtl, that._theme.rtlEnabled))
  17382. _extend(true, that._theme, that._theme._rtl);
  17383. that._callback();
  17384. return that
  17385. },
  17386. theme: function(path) {
  17387. return getThemePart(this._theme, path)
  17388. },
  17389. themeName: function() {
  17390. return this._themeName
  17391. },
  17392. _initializeTheme: function() {
  17393. var that = this;
  17394. _each(that._fontFields || [], function(_, path) {
  17395. that._initializeFont(getThemePart(that._theme, path))
  17396. })
  17397. },
  17398. _initializeFont: function(font) {
  17399. _extend(font, this._font, _extend({}, font))
  17400. }
  17401. })
  17402. })(DevExpress, jQuery);
  17403. /*! Module viz-core, file parseUtils.js */
  17404. (function($, DX) {
  17405. var viz = DX.viz,
  17406. core = viz.core,
  17407. Class = DX.Class,
  17408. isDefined = DX.utils.isDefined;
  17409. var parseUtils = Class.inherit({
  17410. correctValueType: function(type) {
  17411. return type === 'numeric' || type === 'datetime' || type === 'string' ? type : ''
  17412. },
  17413. _parsers: {
  17414. string: function(val) {
  17415. return isDefined(val) ? '' + val : val
  17416. },
  17417. numeric: function(val) {
  17418. if (!isDefined(val))
  17419. return val;
  17420. var parsedVal = Number(val);
  17421. if (isNaN(parsedVal))
  17422. parsedVal = undefined;
  17423. return parsedVal
  17424. },
  17425. datetime: function(val) {
  17426. if (!isDefined(val))
  17427. return val;
  17428. var parsedVal,
  17429. numVal = Number(val);
  17430. if (!isNaN(numVal))
  17431. parsedVal = new Date(numVal);
  17432. else
  17433. parsedVal = new Date(val);
  17434. if (isNaN(Number(parsedVal)))
  17435. parsedVal = undefined;
  17436. return parsedVal
  17437. }
  17438. },
  17439. getParser: function(valueType) {
  17440. return this._parsers[this.correctValueType(valueType)] || $.noop
  17441. }
  17442. });
  17443. core.ParseUtils = parseUtils
  17444. })(jQuery, DevExpress);
  17445. /*! Module viz-core, file loadIndicator.js */
  17446. (function(DX, $, undefined) {
  17447. var _patchFontOptions = DX.viz.core.utils.patchFontOptions;
  17448. var STATE_HIDE = 0,
  17449. STATE_SHOW = 1,
  17450. STATE_ENDLOADING = 2;
  17451. function LoadIndicator(parameters) {
  17452. var that = this;
  17453. that._$widgetContainer = parameters.container;
  17454. that._$container = $("<div>", {css: {
  17455. position: "relative",
  17456. height: 0,
  17457. padding: 0,
  17458. margin: 0,
  17459. border: 0
  17460. }}).appendTo(that._$widgetContainer).hide();
  17461. that._renderer = new DX.viz.renderers.Renderer({animation: {
  17462. easing: "linear",
  17463. duration: 150
  17464. }});
  17465. that._renderer.draw(that._$container[0]);
  17466. that._rect = that._renderer.rect().attr({opacity: 0}).append(that._renderer.root);
  17467. that._text = that._renderer.text().attr({
  17468. align: "center",
  17469. visibility: "hidden"
  17470. }).append(that._renderer.root);
  17471. that._createStates(parameters.eventTrigger)
  17472. }
  17473. LoadIndicator.prototype = {
  17474. constructor: LoadIndicator,
  17475. _createStates: function(eventTrigger) {
  17476. var that = this;
  17477. that._states = {};
  17478. that._states[STATE_HIDE] = {
  17479. o: 0,
  17480. c: function() {
  17481. that._$container.hide();
  17482. eventTrigger("loadingIndicatorReady")
  17483. }
  17484. };
  17485. that._states[STATE_SHOW] = {
  17486. o: 0.85,
  17487. c: function() {
  17488. eventTrigger("loadingIndicatorReady")
  17489. }
  17490. };
  17491. that._states[STATE_ENDLOADING] = {
  17492. o: 1,
  17493. c: function() {
  17494. var onEndLoading = that._onEndLoading;
  17495. that._onEndLoading = null;
  17496. that._noHiding = true;
  17497. onEndLoading && onEndLoading();
  17498. that._noHiding = false;
  17499. that._onCompleteAction && that[that._onCompleteAction]()
  17500. }
  17501. }
  17502. },
  17503. applyCanvas: function(canvas) {
  17504. var width = canvas.width,
  17505. height = canvas.height;
  17506. this._renderer.resize(width, height);
  17507. this._rect.attr({
  17508. width: width,
  17509. height: height
  17510. });
  17511. this._text.attr({
  17512. x: width / 2,
  17513. y: height / 2
  17514. })
  17515. },
  17516. applyOptions: function(options) {
  17517. this._rect.attr({fill: options.backgroundColor});
  17518. this._text.css(_patchFontOptions(options.font)).attr({text: options.text})
  17519. },
  17520. dispose: function() {
  17521. var that = this;
  17522. that._$container.remove();
  17523. that._renderer.dispose();
  17524. that._$widgetContainer = that._$container = that._renderer = that._rect = that._text = that._states = null
  17525. },
  17526. toForeground: function() {
  17527. this._$container.appendTo(this._$widgetContainer)
  17528. },
  17529. forceShow: function() {
  17530. this._rect.stopAnimation(false).attr({opacity: 1})
  17531. },
  17532. _transit: function(stateId) {
  17533. var state = this._states[stateId];
  17534. this._rect.stopAnimation(true).animate({opacity: state.o}, {complete: state.c})
  17535. },
  17536. show: function() {
  17537. var that = this;
  17538. that._isHiding = false;
  17539. if (that._onEndLoading)
  17540. that._onCompleteAction = "show";
  17541. else {
  17542. that._onCompleteAction = null;
  17543. if (!that._visible) {
  17544. that._visible = true;
  17545. that._$container.show();
  17546. that._renderer.root.css({
  17547. position: "absolute",
  17548. left: 0,
  17549. top: that._$widgetContainer.offset().top - that._$container.offset().top
  17550. });
  17551. that._text.attr({visibility: "visible"})
  17552. }
  17553. that._transit(STATE_SHOW)
  17554. }
  17555. },
  17556. endLoading: function(complete) {
  17557. var that = this;
  17558. if (!that._onEndLoading)
  17559. if (that._visible) {
  17560. that._onEndLoading = complete;
  17561. that._transit(STATE_ENDLOADING)
  17562. }
  17563. else
  17564. complete && complete()
  17565. },
  17566. hide: function() {
  17567. var that = this;
  17568. that._isHiding = false;
  17569. if (that._onEndLoading)
  17570. that._onCompleteAction = "hide";
  17571. else {
  17572. that._onCompleteAction = null;
  17573. if (that._visible) {
  17574. that._visible = false;
  17575. that._text.attr({visibility: "hidden"});
  17576. that._transit(STATE_HIDE)
  17577. }
  17578. }
  17579. },
  17580. scheduleHiding: function() {
  17581. if (!this._noHiding) {
  17582. this._isHiding = true;
  17583. this._onCompleteAction = null
  17584. }
  17585. },
  17586. fulfillHiding: function() {
  17587. var isHiding = this._isHiding;
  17588. isHiding && this.hide();
  17589. return isHiding
  17590. }
  17591. };
  17592. DX.viz.core.LoadIndicator = LoadIndicator
  17593. })(DevExpress, jQuery);
  17594. /*! Module viz-core, file tooltip.js */
  17595. (function(DX, $, doc, undefined) {
  17596. var HALF_ARROW_WIDTH = 10,
  17597. FORMAT_PRECISION = {
  17598. argument: ["argumentFormat", "argumentPrecision"],
  17599. percent: ["percent", "percentPrecision"],
  17600. value: ["format", "precision"]
  17601. },
  17602. formatHelper = DX.formatHelper,
  17603. mathCeil = Math.ceil;
  17604. function hideElement($element) {
  17605. $element.css({left: "-9999px"}).detach()
  17606. }
  17607. function Tooltip(params) {
  17608. var that = this,
  17609. renderer,
  17610. root;
  17611. that._eventTrigger = params.eventTrigger;
  17612. that._wrapper = $("<div></div>").css({
  17613. position: "absolute",
  17614. overflow: "visible",
  17615. width: 0,
  17616. height: 0
  17617. }).addClass(params.cssClass);
  17618. that._renderer = renderer = new DX.viz.renderers.Renderer({});
  17619. root = renderer.root;
  17620. root.attr({"pointer-events": "none"});
  17621. renderer.draw(that._wrapper.get(0));
  17622. that._cloud = renderer.path([], "area").sharp().append(root);
  17623. that._shadow = renderer.shadowFilter();
  17624. that._textGroup = renderer.g().attr({align: "center"}).append(root);
  17625. that._text = renderer.text(undefined, 0, 0).append(that._textGroup);
  17626. that._textGroupHtml = $("<div></div>").css({
  17627. position: "absolute",
  17628. width: 0,
  17629. padding: 0,
  17630. margin: 0,
  17631. border: "0px solid transparent"
  17632. }).appendTo(that._wrapper);
  17633. that._textHtml = $("<div></div>").css({
  17634. position: "relative",
  17635. display: "inline-block",
  17636. padding: 0,
  17637. margin: 0,
  17638. border: "0px solid transparent"
  17639. }).appendTo(that._textGroupHtml)
  17640. }
  17641. Tooltip.prototype = {
  17642. constructor: Tooltip,
  17643. dispose: function() {
  17644. this._wrapper.remove();
  17645. this._renderer.dispose();
  17646. this._options = null
  17647. },
  17648. setOptions: function(options) {
  17649. options = options || {};
  17650. var that = this,
  17651. cloudSettings = that._cloudSettigns = {
  17652. opacity: options.opacity,
  17653. filter: that._shadow.ref,
  17654. "stroke-width": null,
  17655. stroke: null
  17656. },
  17657. borderOptions = options.border || {};
  17658. that._shadowSettigns = $.extend({
  17659. x: "-50%",
  17660. y: "-50%",
  17661. width: "200%",
  17662. height: "200%"
  17663. }, options.shadow);
  17664. that._options = options;
  17665. if (borderOptions.visible)
  17666. $.extend(cloudSettings, {
  17667. "stroke-width": borderOptions.width,
  17668. stroke: borderOptions.color,
  17669. "stroke-opacity": borderOptions.opacity,
  17670. dashStyle: borderOptions.dashStyle
  17671. });
  17672. that._textFontStyles = DX.viz.core.utils.patchFontOptions(options.font);
  17673. that._textFontStyles.color = options.font.color;
  17674. that._wrapper.css({"z-index": options.zIndex});
  17675. that._customizeTooltip = $.isFunction(options.customizeTooltip) ? options.customizeTooltip : null;
  17676. return that
  17677. },
  17678. setRendererOptions: function(options) {
  17679. this._renderer.setOptions(options);
  17680. this._textGroupHtml.css({direction: options.rtl ? "rtl" : "ltr"});
  17681. return this
  17682. },
  17683. render: function() {
  17684. var that = this;
  17685. hideElement(that._wrapper);
  17686. that._cloud.attr(that._cloudSettigns);
  17687. that._shadow.attr(that._shadowSettigns);
  17688. that._textGroupHtml.css(that._textFontStyles);
  17689. that._textGroup.css(that._textFontStyles);
  17690. that._text.css(that._textFontStyles);
  17691. that._eventData = null;
  17692. return that
  17693. },
  17694. update: function(options) {
  17695. return this.setOptions(options).render()
  17696. },
  17697. _prepare: function(formatObject, state) {
  17698. var options = this._options,
  17699. customize = {};
  17700. if (this._customizeTooltip) {
  17701. customize = this._customizeTooltip.call(formatObject, formatObject);
  17702. customize = $.isPlainObject(customize) ? customize : {};
  17703. if ("text" in customize)
  17704. state.text = DX.utils.isDefined(customize.text) ? String(customize.text) : "";
  17705. if ("html" in customize)
  17706. state.html = DX.utils.isDefined(customize.html) ? String(customize.html) : ""
  17707. }
  17708. if (!("text" in state) && !("html" in state))
  17709. state.text = formatObject.valueText || "";
  17710. state.color = customize.color || options.color;
  17711. state.borderColor = customize.borderColor || (options.border || {}).color;
  17712. state.textColor = customize.fontColor || (options.font || {}).color;
  17713. return !!state.text || !!state.html
  17714. },
  17715. show: function(formatObject, params, eventData) {
  17716. var that = this,
  17717. state = {},
  17718. options = that._options,
  17719. plr = options.paddingLeftRight,
  17720. ptb = options.paddingTopBottom,
  17721. textGroupHtml = that._textGroupHtml,
  17722. textHtml = that._textHtml,
  17723. bBox,
  17724. contentSize,
  17725. ss = that._shadowSettigns,
  17726. xOff = ss.offsetX,
  17727. yOff = ss.offsetY,
  17728. blur = ss.blur * 2 + 1;
  17729. if (!that._prepare(formatObject, state))
  17730. return false;
  17731. that._state = state;
  17732. state.tc = {};
  17733. that._wrapper.appendTo($("body"));
  17734. that._cloud.attr({
  17735. fill: state.color,
  17736. stroke: state.borderColor
  17737. });
  17738. if (state.html) {
  17739. that._text.attr({text: ""});
  17740. textGroupHtml.css({
  17741. color: state.textColor,
  17742. width: that._getCanvas().width
  17743. });
  17744. textHtml.html(state.html);
  17745. bBox = textHtml.get(0).getBoundingClientRect();
  17746. bBox = {
  17747. x: 0,
  17748. y: 0,
  17749. width: mathCeil(bBox.right - bBox.left),
  17750. height: mathCeil(bBox.bottom - bBox.top)
  17751. };
  17752. textGroupHtml.width(bBox.width);
  17753. textGroupHtml.height(bBox.height)
  17754. }
  17755. else {
  17756. textHtml.html("");
  17757. that._text.css({fill: state.textColor}).attr({text: state.text});
  17758. bBox = that._textGroup.css({fill: state.textColor}).getBBox()
  17759. }
  17760. contentSize = state.contentSize = {
  17761. x: bBox.x - plr,
  17762. y: bBox.y - ptb,
  17763. width: bBox.width + 2 * plr,
  17764. height: bBox.height + 2 * ptb,
  17765. lm: blur - xOff > 0 ? blur - xOff : 0,
  17766. rm: blur + xOff > 0 ? blur + xOff : 0,
  17767. tm: blur - yOff > 0 ? blur - yOff : 0,
  17768. bm: blur + yOff > 0 ? blur + yOff : 0
  17769. };
  17770. contentSize.fullWidth = contentSize.width + contentSize.lm + contentSize.rm;
  17771. contentSize.fullHeight = contentSize.height + contentSize.tm + contentSize.bm + options.arrowLength;
  17772. that.move(params.x, params.y, params.offset);
  17773. that._eventData && that._eventTrigger("tooltipHidden", that._eventData);
  17774. that._eventData = eventData;
  17775. that._eventTrigger("tooltipShown", that._eventData);
  17776. return true
  17777. },
  17778. hide: function() {
  17779. var that = this;
  17780. hideElement(that._wrapper);
  17781. that._eventData && that._eventTrigger("tooltipHidden", that._eventData);
  17782. that._eventData = null
  17783. },
  17784. move: function(x, y, offset) {
  17785. offset = offset || 0;
  17786. var that = this,
  17787. canvas = that._getCanvas(),
  17788. state = that._state,
  17789. coords = state.tc,
  17790. contentSize = state.contentSize;
  17791. if (that._calculatePosition(x, y, offset)) {
  17792. that._cloud.attr({points: coords.cloudPoints}).move(contentSize.lm, contentSize.tm);
  17793. if (state.html)
  17794. that._textGroupHtml.css({
  17795. left: -contentSize.x + contentSize.lm,
  17796. top: -contentSize.y + contentSize.tm + coords.correction
  17797. });
  17798. else
  17799. that._textGroup.move(-contentSize.x + contentSize.lm, -contentSize.y + contentSize.tm + coords.correction);
  17800. that._renderer.resize(coords.hp === "out" ? canvas.fullWidth - canvas.left : contentSize.fullWidth, coords.vp === "out" ? canvas.fullHeight - canvas.top : contentSize.fullHeight)
  17801. }
  17802. that._wrapper.css({
  17803. left: coords.x,
  17804. top: coords.y
  17805. })
  17806. },
  17807. formatValue: function(value, specialFormat) {
  17808. var formatObj = FORMAT_PRECISION[specialFormat || "value"],
  17809. format = formatObj[0] in this._options ? this._options[formatObj[0]] : specialFormat;
  17810. return formatHelper.format(value, format, this._options[formatObj[1]] || 0)
  17811. },
  17812. getLocation: function() {
  17813. return (this._options.location + "").toLowerCase()
  17814. },
  17815. isEnabled: function() {
  17816. return !!this._options.enabled
  17817. },
  17818. isShared: function() {
  17819. return !!this._options.shared
  17820. },
  17821. _calculatePosition: function(x, y, offset) {
  17822. var that = this,
  17823. canvas = that._getCanvas(),
  17824. options = that._options,
  17825. arrowLength = options.arrowLength,
  17826. state = that._state,
  17827. coords = state.tc,
  17828. contentSize = state.contentSize,
  17829. contentWidth = contentSize.width,
  17830. halfContentWidth = contentWidth / 2,
  17831. contentHeight = contentSize.height,
  17832. cTop = y - canvas.top,
  17833. cBottom = canvas.top + canvas.height - y,
  17834. cLeft = x - canvas.left,
  17835. cRight = canvas.width + canvas.left - x,
  17836. tTop = contentHeight + arrowLength + offset + contentSize.tm,
  17837. tBottom = contentHeight + arrowLength + offset + contentSize.bm,
  17838. tLeft = contentWidth + contentSize.lm,
  17839. tRight = contentWidth + contentSize.rm,
  17840. tHalfLeft = halfContentWidth + contentSize.lm,
  17841. tHalfRight = halfContentWidth + contentSize.rm,
  17842. correction = 0,
  17843. cloudPoints,
  17844. arrowPoints = [6, 0],
  17845. x1 = halfContentWidth + HALF_ARROW_WIDTH,
  17846. x2 = halfContentWidth,
  17847. x3 = halfContentWidth - HALF_ARROW_WIDTH,
  17848. y1,
  17849. y3,
  17850. y2 = contentHeight + arrowLength,
  17851. hp = "center",
  17852. vp = "bottom",
  17853. hasDeprecatedPosition;
  17854. y1 = y3 = contentHeight;
  17855. switch (options.verticalAlignment) {
  17856. case"top":
  17857. vp = "bottom";
  17858. hasDeprecatedPosition = true;
  17859. break;
  17860. case"bottom":
  17861. vp = "top";
  17862. hasDeprecatedPosition = true;
  17863. break
  17864. }
  17865. if (!hasDeprecatedPosition)
  17866. if (tTop > cTop && tBottom > cBottom)
  17867. vp = "out";
  17868. else if (tTop > cTop)
  17869. vp = "top";
  17870. hasDeprecatedPosition = false;
  17871. switch (options.horizontalAlignment) {
  17872. case"left":
  17873. hp = "right";
  17874. hasDeprecatedPosition = true;
  17875. break;
  17876. case"center":
  17877. hp = "center";
  17878. hasDeprecatedPosition = true;
  17879. break;
  17880. case"right":
  17881. hp = "left";
  17882. hasDeprecatedPosition = true;
  17883. break
  17884. }
  17885. if (!hasDeprecatedPosition)
  17886. if (tLeft > cLeft && tRight > cRight)
  17887. hp = "out";
  17888. else if (tHalfLeft > cLeft && tRight < cRight)
  17889. hp = "left";
  17890. else if (tHalfRight > cRight && tLeft < cLeft)
  17891. hp = "right";
  17892. if (hp === "out")
  17893. x = canvas.left;
  17894. else if (hp === "left") {
  17895. x1 = HALF_ARROW_WIDTH;
  17896. x2 = x3 = 0
  17897. }
  17898. else if (hp === "right") {
  17899. x1 = x2 = contentWidth;
  17900. x3 = contentWidth - HALF_ARROW_WIDTH;
  17901. x = x - contentWidth
  17902. }
  17903. else if (hp === "center")
  17904. x = x - halfContentWidth;
  17905. if (vp === "out")
  17906. y = canvas.top;
  17907. else if (vp === "top") {
  17908. hp !== "out" && (correction = arrowLength);
  17909. arrowPoints[0] = 2;
  17910. y1 = y3 = arrowLength;
  17911. y2 = x1;
  17912. x1 = x3;
  17913. x3 = y2;
  17914. y2 = 0;
  17915. y = y + offset
  17916. }
  17917. else
  17918. y = y - (contentHeight + arrowLength + offset);
  17919. coords.x = x - contentSize.lm;
  17920. coords.y = y - contentSize.tm;
  17921. coords.correction = correction;
  17922. if (hp === coords.hp && vp === coords.vp)
  17923. return false;
  17924. coords.hp = hp;
  17925. coords.vp = vp;
  17926. cloudPoints = [0, 0 + correction, contentWidth, 0 + correction, contentWidth, contentHeight + correction, 0, contentHeight + correction];
  17927. if (hp !== "out" && vp !== "out") {
  17928. arrowPoints.splice(2, 0, x1, y1, x2, y2, x3, y3);
  17929. cloudPoints.splice.apply(cloudPoints, arrowPoints)
  17930. }
  17931. coords.cloudPoints = cloudPoints;
  17932. return true
  17933. },
  17934. _getCanvas: function() {
  17935. var html = doc.documentElement,
  17936. body = doc.body,
  17937. win = window;
  17938. return {
  17939. left: win.pageXOffset || html.scrollLeft || 0,
  17940. top: win.pageYOffset || html.scrollTop || 0,
  17941. width: html.clientWidth || 0,
  17942. height: html.clientHeight || 0,
  17943. fullWidth: Math.max(body.scrollWidth, html.scrollWidth, body.offsetWidth, html.offsetWidth, body.clientWidth, html.clientWidth),
  17944. fullHeight: Math.max(body.scrollHeight, html.scrollHeight, body.offsetHeight, html.offsetHeight, body.clientHeight, html.clientHeight)
  17945. }
  17946. }
  17947. };
  17948. DX.viz.core.Tooltip = Tooltip
  17949. })(DevExpress, jQuery, document);
  17950. /*! Module viz-core, file legend.js */
  17951. (function(DX, $, undefined) {
  17952. var core = DX.viz.core,
  17953. coreUtils = core.utils,
  17954. WrapperLayoutElement = core.WrapperLayoutElement,
  17955. _Number = Number,
  17956. _String = String,
  17957. _math = Math,
  17958. _round = _math.round,
  17959. _max = _math.max,
  17960. _min = _math.min,
  17961. _ceil = _math.ceil,
  17962. utils = DX.utils,
  17963. _isDefined = utils.isDefined,
  17964. _isFunction = utils.isFunction,
  17965. _enumParser = coreUtils.enumParser,
  17966. _extend = $.extend,
  17967. _each = $.each,
  17968. _map = $.map,
  17969. DEFAULT_MARGIN = 10,
  17970. DEFAULT_MARKER_HATCHING_WIDTH = 2,
  17971. DEFAULT_MARKER_HATCHING_STEP = 5,
  17972. CENTER = "center",
  17973. RIGHT = "right",
  17974. LEFT = "left",
  17975. TOP = "top",
  17976. BOTTOM = "bottom",
  17977. HORIZONTAL = "horizontal",
  17978. VERTICAL = "vertical",
  17979. INSIDE = "inside",
  17980. OUTSIDE = "outside",
  17981. NONE = "none",
  17982. HEIGHT = "height",
  17983. WIDTH = "width",
  17984. parseHorizontalAlignment = _enumParser([LEFT, CENTER, RIGHT]),
  17985. parseVerticalAlignment = _enumParser([TOP, BOTTOM]),
  17986. parseOrientation = _enumParser([VERTICAL, HORIZONTAL]),
  17987. parseItemTextPosition = _enumParser([LEFT, RIGHT, TOP, BOTTOM]),
  17988. parsePosition = _enumParser([OUTSIDE, INSIDE]),
  17989. parseItemsAlignment = _enumParser([LEFT, CENTER, RIGHT]);
  17990. function getPattern(renderer, states, action, color) {
  17991. if (!states || !states[action])
  17992. return;
  17993. var direction = states[action].hatching.direction,
  17994. hatching,
  17995. colorFromAction = states[action].fill;
  17996. color = colorFromAction === NONE ? color : colorFromAction;
  17997. direction = !direction || direction === NONE ? RIGHT : direction;
  17998. hatching = _extend({}, states[action].hatching, {
  17999. direction: direction,
  18000. step: DEFAULT_MARKER_HATCHING_STEP,
  18001. width: DEFAULT_MARKER_HATCHING_WIDTH
  18002. });
  18003. return renderer.pattern(color, hatching)
  18004. }
  18005. function parseMargins(options) {
  18006. var margin = options.margin;
  18007. if (margin >= 0) {
  18008. margin = _Number(options.margin);
  18009. margin = {
  18010. top: margin,
  18011. bottom: margin,
  18012. left: margin,
  18013. right: margin
  18014. }
  18015. }
  18016. else
  18017. margin = {
  18018. top: margin.top >= 0 ? _Number(margin.top) : DEFAULT_MARGIN,
  18019. bottom: margin.bottom >= 0 ? _Number(margin.bottom) : DEFAULT_MARGIN,
  18020. left: margin.left >= 0 ? _Number(margin.left) : DEFAULT_MARGIN,
  18021. right: margin.right >= 0 ? _Number(margin.right) : DEFAULT_MARGIN
  18022. };
  18023. options.margin = margin
  18024. }
  18025. function getSizeItem(options, markerSize, labelBBox) {
  18026. var defaultXMargin = 7,
  18027. defaultTopMargin = 4,
  18028. width,
  18029. height;
  18030. switch (options.itemTextPosition) {
  18031. case LEFT:
  18032. case RIGHT:
  18033. width = markerSize + defaultXMargin + labelBBox.width;
  18034. height = _max(markerSize, labelBBox.height);
  18035. break;
  18036. case TOP:
  18037. case BOTTOM:
  18038. width = _max(markerSize, labelBBox.width);
  18039. height = markerSize + defaultTopMargin + labelBBox.height;
  18040. break
  18041. }
  18042. return {
  18043. width: width,
  18044. height: height
  18045. }
  18046. }
  18047. function calculateBboxLabelAndMarker(markerBBox, labelBBox) {
  18048. var bbox = {};
  18049. bbox.left = _min(markerBBox.x, labelBBox.x);
  18050. bbox.top = _min(markerBBox.y, labelBBox.y);
  18051. bbox.right = _max(markerBBox.x + markerBBox.width, labelBBox.x + labelBBox.width);
  18052. bbox.bottom = _max(markerBBox.y + markerBBox.height, labelBBox.y + labelBBox.height);
  18053. return bbox
  18054. }
  18055. function applyMarkerState(id, idToIndexMap, items, stateName) {
  18056. var item = idToIndexMap && items[idToIndexMap[id]];
  18057. if (item)
  18058. item.marker.attr(item.states[stateName])
  18059. }
  18060. function parseOptions(options, textField) {
  18061. if (!options)
  18062. return null;
  18063. DX.utils.debug.assertParam(options.visible, "Visibility was not passed");
  18064. DX.utils.debug.assertParam(options.markerSize, "markerSize was not passed");
  18065. DX.utils.debug.assertParam(options.font.color, "fontColor was not passed");
  18066. DX.utils.debug.assertParam(options.font.family, "fontFamily was not passed");
  18067. DX.utils.debug.assertParam(options.font.size, "fontSize was not passed");
  18068. DX.utils.debug.assertParam(options.paddingLeftRight, "paddingLeftRight was not passed");
  18069. DX.utils.debug.assertParam(options.paddingTopBottom, "paddingTopBottom was not passed");
  18070. DX.utils.debug.assertParam(options.columnItemSpacing, "columnItemSpacing was not passed");
  18071. DX.utils.debug.assertParam(options.rowItemSpacing, "rowItemSpacing was not passed");
  18072. parseMargins(options);
  18073. options.horizontalAlignment = parseHorizontalAlignment(options.horizontalAlignment, RIGHT);
  18074. options.verticalAlignment = parseVerticalAlignment(options.verticalAlignment, options.horizontalAlignment === CENTER ? BOTTOM : TOP);
  18075. options.orientation = parseOrientation(options.orientation, options.horizontalAlignment === CENTER ? HORIZONTAL : VERTICAL);
  18076. options.itemTextPosition = parseItemTextPosition(options.itemTextPosition, options.orientation === HORIZONTAL ? BOTTOM : RIGHT);
  18077. options.position = parsePosition(options.position, OUTSIDE);
  18078. options.itemsAlignment = parseItemsAlignment(options.itemsAlignment, null);
  18079. options.hoverMode = _String(options.hoverMode || "").toLowerCase();
  18080. options.customizeText = _isFunction(options.customizeText) ? options.customizeText : function() {
  18081. return this[textField]
  18082. };
  18083. options.customizeHint = _isFunction(options.customizeHint) ? options.customizeHint : $.noop;
  18084. return options
  18085. }
  18086. function createSquareMarker(renderer, size) {
  18087. return renderer.rect(0, 0, size, size)
  18088. }
  18089. function createCircleMarker(renderer, size) {
  18090. return renderer.circle(size / 2, size / 2, size / 2)
  18091. }
  18092. function isCircle(type) {
  18093. return _String(type).toLowerCase() === "circle"
  18094. }
  18095. function getMarkerCreator(type) {
  18096. return isCircle(type) ? createCircleMarker : createSquareMarker
  18097. }
  18098. function inRect(rect, x, y) {
  18099. return x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
  18100. }
  18101. function checkLinesSize(lines, layoutOptions, countItems) {
  18102. var position = {
  18103. x: 0,
  18104. y: 0
  18105. },
  18106. maxMeasureLength = 0,
  18107. maxOrtMeasureLength = 0;
  18108. $.each(lines, function(i, line) {
  18109. var firstItem = line[0];
  18110. $.each(line, function(_, item) {
  18111. var offset = item.offset || layoutOptions.spacing;
  18112. position[layoutOptions.direction] += item[layoutOptions.measure] + offset;
  18113. maxMeasureLength = _max(maxMeasureLength, position[layoutOptions.direction])
  18114. });
  18115. position[layoutOptions.direction] = 0;
  18116. position[layoutOptions.ortDirection] += firstItem[layoutOptions.ortMeasure] + firstItem.ortOffset || layoutOptions.ortSpacing;
  18117. maxOrtMeasureLength = _max(maxOrtMeasureLength, position[layoutOptions.ortDirection])
  18118. });
  18119. if (maxMeasureLength > layoutOptions.length) {
  18120. layoutOptions.countItem = decreaseItemCount(layoutOptions, countItems);
  18121. return true
  18122. }
  18123. }
  18124. function decreaseItemCount(layoutOptions, countItems) {
  18125. layoutOptions.ortCountItem++;
  18126. return _ceil(countItems / layoutOptions.ortCountItem)
  18127. }
  18128. function getLineLength(line, layoutOptions) {
  18129. var lineLength = 0;
  18130. $.each(line, function(_, item) {
  18131. var offset = item.offset || layoutOptions.spacing;
  18132. lineLength += item[layoutOptions.measure] + offset
  18133. });
  18134. return lineLength
  18135. }
  18136. function getMaxLineLength(lines, layoutOptions) {
  18137. var maxLineLength = 0;
  18138. $.each(lines, function(_, line) {
  18139. maxLineLength = _max(maxLineLength, getLineLength(line, layoutOptions))
  18140. });
  18141. return maxLineLength
  18142. }
  18143. function getInitPositionForDirection(line, layoutOptions, maxLineLength) {
  18144. var lineLength = getLineLength(line, layoutOptions),
  18145. initPosition;
  18146. switch (layoutOptions.itemsAlignment) {
  18147. case RIGHT:
  18148. initPosition = maxLineLength - lineLength;
  18149. break;
  18150. case CENTER:
  18151. initPosition = (maxLineLength - lineLength) / 2;
  18152. break;
  18153. default:
  18154. initPosition = 0
  18155. }
  18156. return initPosition
  18157. }
  18158. function getPos(layoutOptions) {
  18159. switch (layoutOptions.itemTextPosition) {
  18160. case BOTTOM:
  18161. return CENTER + " " + TOP;
  18162. case TOP:
  18163. return CENTER + " " + BOTTOM;
  18164. case LEFT:
  18165. return RIGHT + " " + CENTER;
  18166. case RIGHT:
  18167. return LEFT + " " + CENTER
  18168. }
  18169. }
  18170. function getLines(lines, layoutOptions, itemIndex) {
  18171. var tableLine = {};
  18172. if (itemIndex % layoutOptions.countItem === 0)
  18173. if (layoutOptions.markerOffset)
  18174. lines.push([], []);
  18175. else
  18176. lines.push([]);
  18177. if (layoutOptions.markerOffset) {
  18178. tableLine.firstLine = lines[lines.length - 1];
  18179. tableLine.secondLine = lines[lines.length - 2]
  18180. }
  18181. else
  18182. tableLine.firstLine = tableLine.secondLine = lines[lines.length - 1];
  18183. return tableLine
  18184. }
  18185. function setMaxInLine(line, mesuare) {
  18186. var maxLineSize = 0;
  18187. $.each(line, function(_, item) {
  18188. if (!item)
  18189. return;
  18190. maxLineSize = _max(maxLineSize, item[mesuare])
  18191. });
  18192. $.each(line, function(_, item) {
  18193. if (!item)
  18194. return;
  18195. item[mesuare] = maxLineSize
  18196. })
  18197. }
  18198. function transpose(array) {
  18199. var width = array.length,
  18200. height = array[0].length,
  18201. i,
  18202. j,
  18203. transposeArray = [];
  18204. for (i = 0; i < height; i++) {
  18205. transposeArray[i] = [];
  18206. for (j = 0; j < width; j++)
  18207. transposeArray[i][j] = array[j][i]
  18208. }
  18209. return transposeArray
  18210. }
  18211. function getAlign(position) {
  18212. switch (position) {
  18213. case TOP:
  18214. case BOTTOM:
  18215. return CENTER;
  18216. case LEFT:
  18217. return RIGHT;
  18218. case RIGHT:
  18219. return LEFT
  18220. }
  18221. }
  18222. var _Legend = DX.viz.core.Legend = function(settings) {
  18223. var that = this;
  18224. that._renderer = settings.renderer;
  18225. that._legendGroup = settings.group;
  18226. that._backgroundClass = settings.backgroundClass;
  18227. that._itemGroupClass = settings.itemGroupClass;
  18228. that._textField = settings.textField;
  18229. that._getCustomizeObject = settings.getFormatObject;
  18230. that._patterns = []
  18231. };
  18232. _Legend.prototype = {
  18233. constructor: _Legend,
  18234. update: function(data, options) {
  18235. var that = this;
  18236. that._data = data;
  18237. that._boundingRect = {
  18238. width: 0,
  18239. height: 0,
  18240. x: 0,
  18241. y: 0
  18242. };
  18243. that._options = parseOptions(options, that._textField);
  18244. return that
  18245. },
  18246. setSize: function(size) {
  18247. this._size = {
  18248. width: size.width,
  18249. height: size.height
  18250. };
  18251. return this
  18252. },
  18253. draw: function(size) {
  18254. var that = this,
  18255. options = that._options,
  18256. renderer = that._renderer,
  18257. items = that._data;
  18258. size && that.setSize(size);
  18259. that.erase();
  18260. if (!(options && options.visible && items && items.length))
  18261. return that;
  18262. that._insideLegendGroup = renderer.g().append(that._legendGroup);
  18263. that._createBackground();
  18264. that._createItems(that._getItemData());
  18265. that._locateElements(options);
  18266. that._finalUpdate(options);
  18267. return that
  18268. },
  18269. _createItems: function(items) {
  18270. var that = this,
  18271. options = that._options,
  18272. initMarkerSize = options.markerSize,
  18273. renderer = that._renderer,
  18274. markersOptions = [],
  18275. maxMarkerSize = 0,
  18276. i = 0,
  18277. bbox,
  18278. maxBboxWidth = 0,
  18279. maxBboxHeight = 0,
  18280. createMarker = getMarkerCreator(options.markerType);
  18281. _each(items, function(_i, item) {
  18282. maxMarkerSize = _max(maxMarkerSize, _Number(item.size > 0 ? item.size : initMarkerSize))
  18283. });
  18284. that._markersId = {};
  18285. for (; i < that._patterns.length; i++)
  18286. that._patterns[i].dispose();
  18287. that._patterns = [];
  18288. that._items = _map(items, function(dataItem, i) {
  18289. var group = that._insideLegendGroup,
  18290. markerSize = _Number(dataItem.size > 0 ? dataItem.size : initMarkerSize),
  18291. stateOfDataItem = dataItem.states,
  18292. normalState = stateOfDataItem.normal,
  18293. normalStateFill = normalState.fill,
  18294. marker = createMarker(renderer, markerSize).attr({
  18295. fill: normalStateFill || options.markerColor,
  18296. opacity: normalState.opacity
  18297. }).append(group),
  18298. label = that._createLabel(dataItem, group),
  18299. hoverPattern = getPattern(renderer, stateOfDataItem, "hover", normalStateFill),
  18300. selectionPattern = getPattern(renderer, stateOfDataItem, "selection", normalStateFill),
  18301. states = {normal: {fill: normalStateFill}},
  18302. labelBBox = label.getBBox();
  18303. if (hoverPattern) {
  18304. states.hovered = {fill: hoverPattern.id};
  18305. that._patterns.push(hoverPattern)
  18306. }
  18307. if (selectionPattern) {
  18308. states.selected = {fill: selectionPattern.id};
  18309. that._patterns.push(selectionPattern)
  18310. }
  18311. if (dataItem.id !== undefined)
  18312. that._markersId[dataItem.id] = i;
  18313. bbox = getSizeItem(options, markerSize, labelBBox);
  18314. maxBboxWidth = _max(maxBboxWidth, bbox.width);
  18315. maxBboxHeight = _max(maxBboxHeight, bbox.height);
  18316. markersOptions.push({
  18317. size: markerSize,
  18318. marker: marker
  18319. });
  18320. that._createHint(dataItem, label);
  18321. return {
  18322. label: label,
  18323. labelBBox: labelBBox,
  18324. group: group,
  18325. bbox: bbox,
  18326. marker: marker,
  18327. markerSize: markerSize,
  18328. tracker: {id: dataItem.id},
  18329. states: states,
  18330. itemTextPosition: options.itemTextPosition,
  18331. markerOffset: 0,
  18332. bboxs: []
  18333. }
  18334. });
  18335. if (options.equalRowHeight)
  18336. $.each(that._items, function(_, item) {
  18337. item.bbox.height = maxBboxHeight
  18338. })
  18339. },
  18340. _getItemData: function() {
  18341. var items = this._data;
  18342. if (this._options.inverted)
  18343. items = items.slice().reverse();
  18344. return items
  18345. },
  18346. _finalUpdate: function(options) {
  18347. this._adjustBackgroundSettings(options);
  18348. this._setBoundingRect(options.margin)
  18349. },
  18350. erase: function() {
  18351. var that = this,
  18352. insideLegendGroup = that._insideLegendGroup;
  18353. insideLegendGroup && insideLegendGroup.dispose();
  18354. that._insideLegendGroup = that._x1 = that._x2 = that._y2 = that._y2 = null;
  18355. return that
  18356. },
  18357. _locateElements: function(locationOptions) {
  18358. this._moveInInitialValues();
  18359. this._locateRowsColumns(locationOptions)
  18360. },
  18361. _moveInInitialValues: function() {
  18362. var that = this;
  18363. that._legendGroup && that._legendGroup.move(0, 0);
  18364. that._background && that._background.attr({
  18365. x: 0,
  18366. y: 0,
  18367. width: 0,
  18368. height: 0
  18369. })
  18370. },
  18371. applySelected: function(id) {
  18372. applyMarkerState(id, this._markersId, this._items, "selected");
  18373. return this
  18374. },
  18375. applyHover: function(id) {
  18376. applyMarkerState(id, this._markersId, this._items, "hovered");
  18377. return this
  18378. },
  18379. resetItem: function(id) {
  18380. applyMarkerState(id, this._markersId, this._items, "normal");
  18381. return this
  18382. },
  18383. _createLabel: function(data, group) {
  18384. var labelFormatObject = this._getCustomizeObject(data),
  18385. align = getAlign(this._options.itemTextPosition),
  18386. text = this._options.customizeText.call(labelFormatObject, labelFormatObject),
  18387. fontStyle = _isDefined(data.textOpacity) ? _extend({}, this._options.font, {opacity: data.textOpacity}) : this._options.font;
  18388. return this._renderer.text(text, 0, 0).css(coreUtils.patchFontOptions(fontStyle)).attr({align: align}).append(group)
  18389. },
  18390. _createHint: function(data, label) {
  18391. var labelFormatObject = this._getCustomizeObject(data),
  18392. text = this._options.customizeHint.call(labelFormatObject, labelFormatObject);
  18393. if (_isDefined(text) && text !== "")
  18394. label.setTitle(text)
  18395. },
  18396. _createBackground: function() {
  18397. var that = this,
  18398. isInside = that._options.position === INSIDE,
  18399. color = that._options.backgroundColor,
  18400. fill = color || (isInside ? that._options.containerBackgroundColor : NONE);
  18401. if (that._options.border.visible || (isInside || color) && color !== NONE)
  18402. that._background = that._renderer.rect(0, 0, 0, 0).attr({
  18403. fill: fill,
  18404. 'class': that._backgroundClass
  18405. }).append(that._insideLegendGroup)
  18406. },
  18407. _locateRowsColumns: function() {
  18408. var that = this,
  18409. iteration = 0,
  18410. layoutOptions = that._getItemsLayoutOptions(),
  18411. countItems = that._items.length,
  18412. lines;
  18413. do {
  18414. lines = [];
  18415. that._createLines(lines, layoutOptions);
  18416. that._alignLines(lines, layoutOptions);
  18417. iteration++
  18418. } while (checkLinesSize(lines, layoutOptions, countItems) && iteration < countItems);
  18419. that._applyItemPosition(lines, layoutOptions)
  18420. },
  18421. _createLines: function(lines, layoutOptions) {
  18422. $.each(this._items, function(i, item) {
  18423. var tableLine = getLines(lines, layoutOptions, i),
  18424. labelBox = {
  18425. width: item.labelBBox.width,
  18426. height: item.labelBBox.height,
  18427. element: item.label,
  18428. bbox: item.labelBBox,
  18429. pos: getPos(layoutOptions),
  18430. itemIndex: i
  18431. },
  18432. markerBox = {
  18433. width: item.markerSize,
  18434. height: item.markerSize,
  18435. element: item.marker,
  18436. bbox: {
  18437. width: item.markerSize,
  18438. height: item.markerSize,
  18439. x: 0,
  18440. y: 0
  18441. },
  18442. itemIndex: i
  18443. },
  18444. firstItem,
  18445. secondItem,
  18446. offsetDirection = layoutOptions.markerOffset ? "ortOffset" : "offset";
  18447. if (layoutOptions.inverseLabelPosition) {
  18448. firstItem = labelBox;
  18449. secondItem = markerBox
  18450. }
  18451. else {
  18452. firstItem = markerBox;
  18453. secondItem = labelBox
  18454. }
  18455. firstItem[offsetDirection] = layoutOptions.labelOffset;
  18456. tableLine.secondLine.push(firstItem);
  18457. tableLine.firstLine.push(secondItem)
  18458. })
  18459. },
  18460. _alignLines: function(lines, layoutOptions) {
  18461. var i,
  18462. measure = layoutOptions.ortMeasure;
  18463. _each(lines, processLine);
  18464. measure = layoutOptions.measure;
  18465. if (layoutOptions.itemsAlignment) {
  18466. if (layoutOptions.markerOffset)
  18467. for (i = 0; i < lines.length; )
  18468. _each(transpose([lines[i++], lines[i++]]), processLine)
  18469. }
  18470. else
  18471. _each(transpose(lines), processLine);
  18472. function processLine(_, line) {
  18473. setMaxInLine(line, measure)
  18474. }
  18475. },
  18476. _applyItemPosition: function(lines, layoutOptions) {
  18477. var that = this,
  18478. position = {
  18479. x: 0,
  18480. y: 0
  18481. },
  18482. maxLineLength = getMaxLineLength(lines, layoutOptions),
  18483. itemIndex = 0;
  18484. $.each(lines, function(i, line) {
  18485. var firstItem = line[0],
  18486. ortOffset = firstItem.ortOffset || layoutOptions.ortSpacing;
  18487. position[layoutOptions.direction] = getInitPositionForDirection(line, layoutOptions, maxLineLength);
  18488. $.each(line, function(_, item) {
  18489. var offset = item.offset || layoutOptions.spacing,
  18490. wrap = new WrapperLayoutElement(item.element, item.bbox),
  18491. itemBBox = {
  18492. x: position.x,
  18493. y: position.y,
  18494. width: item.width,
  18495. height: item.height
  18496. },
  18497. itemLegend = that._items[item.itemIndex];
  18498. wrap.position({
  18499. of: itemBBox,
  18500. my: item.pos,
  18501. at: item.pos
  18502. });
  18503. itemLegend.bboxs.push(itemBBox);
  18504. position[layoutOptions.direction] += item[layoutOptions.measure] + offset;
  18505. itemIndex++
  18506. });
  18507. position[layoutOptions.ortDirection] += firstItem[layoutOptions.ortMeasure] + ortOffset
  18508. });
  18509. $.each(this._items, function(_, item) {
  18510. var itemBBox = calculateBboxLabelAndMarker(item.bboxs[0], item.bboxs[1]),
  18511. horizontal = that._options.columnItemSpacing / 2,
  18512. vertical = that._options.rowItemSpacing / 2;
  18513. item.tracker.left = itemBBox.left - horizontal;
  18514. item.tracker.right = itemBBox.right + horizontal;
  18515. item.tracker.top = itemBBox.top - vertical;
  18516. item.tracker.bottom = itemBBox.bottom + vertical
  18517. })
  18518. },
  18519. _getItemsLayoutOptions: function() {
  18520. var that = this,
  18521. options = that._options,
  18522. border = options.border.visible,
  18523. orientation = options.orientation,
  18524. layoutOptions = {
  18525. itemsAlignment: options.itemsAlignment,
  18526. orientation: options.orientation
  18527. },
  18528. width = that._size.width - (border ? 2 * options.paddingLeftRight : 0),
  18529. height = that._size.height - (border ? 2 * options.paddingTopBottom : 0);
  18530. if (orientation === HORIZONTAL) {
  18531. layoutOptions.length = width;
  18532. layoutOptions.ortLength = height;
  18533. layoutOptions.spacing = options.columnItemSpacing;
  18534. layoutOptions.direction = "x";
  18535. layoutOptions.measure = WIDTH;
  18536. layoutOptions.ortMeasure = HEIGHT;
  18537. layoutOptions.ortDirection = "y";
  18538. layoutOptions.ortSpacing = options.rowItemSpacing;
  18539. layoutOptions.countItem = options.columnCount;
  18540. layoutOptions.ortCountItem = options.rowCount;
  18541. layoutOptions.marginTextLabel = 4;
  18542. layoutOptions.labelOffset = 7;
  18543. if (options.itemTextPosition === BOTTOM || options.itemTextPosition === TOP) {
  18544. layoutOptions.labelOffset = 4;
  18545. layoutOptions.markerOffset = true
  18546. }
  18547. }
  18548. else {
  18549. layoutOptions.length = height;
  18550. layoutOptions.ortLength = width;
  18551. layoutOptions.spacing = options.rowItemSpacing;
  18552. layoutOptions.direction = "y";
  18553. layoutOptions.measure = HEIGHT;
  18554. layoutOptions.ortMeasure = WIDTH;
  18555. layoutOptions.ortDirection = "x";
  18556. layoutOptions.ortSpacing = options.columnItemSpacing;
  18557. layoutOptions.countItem = options.rowCount;
  18558. layoutOptions.ortCountItem = options.columnCount;
  18559. layoutOptions.marginTextLabel = 7;
  18560. layoutOptions.labelOffset = 4;
  18561. if (options.itemTextPosition === RIGHT || options.itemTextPosition === LEFT) {
  18562. layoutOptions.labelOffset = 7;
  18563. layoutOptions.markerOffset = true
  18564. }
  18565. }
  18566. if (!layoutOptions.countItem)
  18567. if (layoutOptions.ortCountItem)
  18568. layoutOptions.countItem = _ceil(that._items.length / layoutOptions.ortCountItem);
  18569. else
  18570. layoutOptions.countItem = that._items.length;
  18571. if (options.itemTextPosition === TOP || options.itemTextPosition === LEFT)
  18572. layoutOptions.inverseLabelPosition = true;
  18573. layoutOptions.itemTextPosition = options.itemTextPosition;
  18574. layoutOptions.ortCountItem = layoutOptions.ortCountItem || _ceil(that._items.length / layoutOptions.countItem);
  18575. return layoutOptions
  18576. },
  18577. _adjustBackgroundSettings: function(locationOptions) {
  18578. if (!this._background)
  18579. return;
  18580. var border = locationOptions.border,
  18581. legendBox = this._insideLegendGroup.getBBox(),
  18582. backgroundSettings = {
  18583. x: _round(legendBox.x - locationOptions.paddingLeftRight),
  18584. y: _round(legendBox.y - locationOptions.paddingTopBottom),
  18585. width: _round(legendBox.width) + 2 * locationOptions.paddingLeftRight,
  18586. height: _round(legendBox.height) + 2 * locationOptions.paddingTopBottom,
  18587. opacity: locationOptions.backgroundOpacity
  18588. };
  18589. if (border.visible && border.width && border.color && border.color !== NONE) {
  18590. backgroundSettings["stroke-width"] = border.width;
  18591. backgroundSettings.stroke = border.color;
  18592. backgroundSettings["stroke-opacity"] = border.opacity;
  18593. backgroundSettings.dashStyle = border.dashStyle;
  18594. backgroundSettings.rx = border.cornerRadius || 0;
  18595. backgroundSettings.ry = border.cornerRadius || 0
  18596. }
  18597. this._background.attr(backgroundSettings)
  18598. },
  18599. _setBoundingRect: function(margin) {
  18600. if (!this._insideLegendGroup)
  18601. return;
  18602. var box = this._insideLegendGroup.getBBox();
  18603. box.height += margin.top + margin.bottom;
  18604. box.width += margin.left + margin.right;
  18605. box.x -= margin.left;
  18606. box.y -= margin.top;
  18607. this._boundingRect = box
  18608. },
  18609. changeSize: function() {
  18610. this.fit.apply(this, arguments)
  18611. },
  18612. fit: function(sizeForDecrease) {
  18613. var that = this,
  18614. beforeFit = that.getLayoutOptions(),
  18615. afterFit;
  18616. function fitLegendToDirection(direction) {
  18617. var size = $.extend({}, that._size);
  18618. size[direction] = beforeFit[direction] - sizeForDecrease[direction];
  18619. that.draw(size);
  18620. afterFit = that.getLayoutOptions();
  18621. if (that._insideLegendGroup)
  18622. if (beforeFit[direction] - sizeForDecrease[direction] < afterFit[direction]) {
  18623. that._options._incidentOccured("W2104");
  18624. that.erase()
  18625. }
  18626. }
  18627. if (sizeForDecrease.width > 0)
  18628. fitLegendToDirection(WIDTH);
  18629. if (sizeForDecrease.height > 0)
  18630. fitLegendToDirection(HEIGHT);
  18631. return this
  18632. },
  18633. getActionCallback: function(point) {
  18634. var that = this;
  18635. if (that._options.visible)
  18636. return function(act) {
  18637. var pointType = point.type,
  18638. seriesType = pointType || point.series.type;
  18639. if (pointType || seriesType === "pie" || seriesType === "doughnut" || seriesType === "donut")
  18640. that[act] && that[act](point.index)
  18641. };
  18642. else
  18643. return $.noop
  18644. },
  18645. getLayoutOptions: function() {
  18646. var options = this._options,
  18647. boundingRect = this._insideLegendGroup ? this._boundingRect : {
  18648. width: 0,
  18649. height: 0,
  18650. x: 0,
  18651. y: 0
  18652. };
  18653. if (options) {
  18654. boundingRect.verticalAlignment = options.verticalAlignment;
  18655. boundingRect.horizontalAlignment = options.horizontalAlignment;
  18656. if (options.orientation === HORIZONTAL)
  18657. boundingRect.cutLayoutSide = options.verticalAlignment;
  18658. else
  18659. boundingRect.cutLayoutSide = options.horizontalAlignment === CENTER ? options.verticalAlignment : options.horizontalAlignment;
  18660. return boundingRect
  18661. }
  18662. return null
  18663. },
  18664. shift: function(x, y) {
  18665. var that = this,
  18666. box = {};
  18667. if (that._insideLegendGroup) {
  18668. that._insideLegendGroup.attr({
  18669. translateX: x - that._boundingRect.x,
  18670. translateY: y - that._boundingRect.y
  18671. });
  18672. box = that._legendGroup.getBBox()
  18673. }
  18674. that._x1 = box.x;
  18675. that._y1 = box.y;
  18676. that._x2 = box.x + box.width;
  18677. that._y2 = box.y + box.height;
  18678. return that
  18679. },
  18680. getPosition: function() {
  18681. return this._options.position
  18682. },
  18683. coordsIn: function(x, y) {
  18684. return x >= this._x1 && x <= this._x2 && y >= this._y1 && y <= this._y2
  18685. },
  18686. getItemByCoord: function(x, y) {
  18687. var items = this._items,
  18688. legendGroup = this._insideLegendGroup;
  18689. x = x - legendGroup.attr("translateX");
  18690. y = y - legendGroup.attr("translateY");
  18691. for (var i = 0; i < items.length; i++)
  18692. if (inRect(items[i].tracker, x, y))
  18693. return items[i].tracker;
  18694. return null
  18695. },
  18696. dispose: function() {
  18697. var that = this;
  18698. that._legendGroup = that._insideLegendGroup = that._renderer = that._options = that._data = that._items = null;
  18699. return that
  18700. }
  18701. };
  18702. var __getMarkerCreator = getMarkerCreator;
  18703. DX.viz.core._DEBUG_stubMarkerCreator = function(callback) {
  18704. getMarkerCreator = function() {
  18705. return callback
  18706. }
  18707. };
  18708. DX.viz.core._DEBUG_restoreMarkerCreator = function() {
  18709. getMarkerCreator = __getMarkerCreator
  18710. }
  18711. })(DevExpress, jQuery);
  18712. /*! Module viz-core, file range.js */
  18713. (function($, DX, undefined) {
  18714. var core = DX.viz.core,
  18715. utils = DX.utils,
  18716. _isDefined = utils.isDefined,
  18717. _isDate = utils.isDate,
  18718. NUMBER_EQUALITY_CORRECTION = 1,
  18719. DATETIME_EQUALITY_CORRECTION = 60000,
  18720. minSelector = "min",
  18721. maxSelector = "max",
  18722. minVisibleSelector = "minVisible",
  18723. maxVisibleSelector = "maxVisible",
  18724. categoriesSelector = "categories",
  18725. baseSelector = "base",
  18726. axisTypeSelector = "axisType",
  18727. _Range;
  18728. function otherLessThan(thisValue, otherValue) {
  18729. return otherValue < thisValue
  18730. }
  18731. function otherGreaterThan(thisValue, otherValue) {
  18732. return otherValue > thisValue
  18733. }
  18734. function compareAndReplace(thisValue, otherValue, setValue, compare) {
  18735. var otherValueDefined = _isDefined(otherValue);
  18736. if (_isDefined(thisValue)) {
  18737. if (otherValueDefined && compare(thisValue, otherValue))
  18738. setValue(otherValue)
  18739. }
  18740. else if (otherValueDefined)
  18741. setValue(otherValue)
  18742. }
  18743. function returnValue(value) {
  18744. return value
  18745. }
  18746. function returnValueOf(value) {
  18747. return value.valueOf()
  18748. }
  18749. function getUniqueCategories(categories, otherCategories, dataType) {
  18750. var length = categories.length,
  18751. found,
  18752. i,
  18753. j,
  18754. valueOf = dataType === "datetime" ? returnValueOf : returnValue;
  18755. if (otherCategories && otherCategories.length)
  18756. for (i = 0; i < otherCategories.length; i++) {
  18757. for (j = 0, found = false; j < length; j++)
  18758. if (valueOf(categories[j]) === valueOf(otherCategories[i])) {
  18759. found = true;
  18760. break
  18761. }
  18762. !found && categories.push(otherCategories[i])
  18763. }
  18764. return categories
  18765. }
  18766. DX.viz.core.__NUMBER_EQUALITY_CORRECTION = NUMBER_EQUALITY_CORRECTION;
  18767. DX.viz.core.__DATETIME_EQUALITY_CORRECTION = DATETIME_EQUALITY_CORRECTION;
  18768. _Range = core.Range = function(range) {
  18769. range && $.extend(this, range)
  18770. };
  18771. _Range.prototype = {
  18772. constructor: _Range,
  18773. dispose: function() {
  18774. this[categoriesSelector] = null
  18775. },
  18776. addRange: function(otherRange) {
  18777. var that = this,
  18778. categories = that[categoriesSelector],
  18779. otherCategories = otherRange[categoriesSelector];
  18780. var compareAndReplaceByField = function(field, compare) {
  18781. compareAndReplace(that[field], otherRange[field], function(value) {
  18782. that[field] = value
  18783. }, compare)
  18784. };
  18785. var controlValuesByVisibleBounds = function(valueField, visibleValueField, compare) {
  18786. compareAndReplace(that[valueField], that[visibleValueField], function(value) {
  18787. _isDefined(that[valueField]) && (that[valueField] = value)
  18788. }, compare)
  18789. };
  18790. var checkField = function(field) {
  18791. that[field] = that[field] || otherRange[field]
  18792. };
  18793. if (utils.isDefined(otherRange.stick))
  18794. that.stick = otherRange.stick;
  18795. checkField("addSpiderCategory");
  18796. checkField("percentStick");
  18797. checkField("minSpaceCorrection");
  18798. checkField("maxSpaceCorrection");
  18799. checkField("invert");
  18800. checkField(axisTypeSelector);
  18801. checkField("dataType");
  18802. if (that[axisTypeSelector] === "logarithmic")
  18803. checkField(baseSelector);
  18804. else
  18805. that[baseSelector] = undefined;
  18806. compareAndReplaceByField(minSelector, otherLessThan);
  18807. compareAndReplaceByField(maxSelector, otherGreaterThan);
  18808. if (that[axisTypeSelector] === "discrete") {
  18809. checkField(minVisibleSelector);
  18810. checkField(maxVisibleSelector)
  18811. }
  18812. else {
  18813. compareAndReplaceByField(minVisibleSelector, otherLessThan);
  18814. compareAndReplaceByField(maxVisibleSelector, otherGreaterThan)
  18815. }
  18816. compareAndReplaceByField("interval", otherLessThan);
  18817. controlValuesByVisibleBounds(minSelector, minVisibleSelector, otherLessThan);
  18818. controlValuesByVisibleBounds(minSelector, maxVisibleSelector, otherLessThan);
  18819. controlValuesByVisibleBounds(maxSelector, maxVisibleSelector, otherGreaterThan);
  18820. controlValuesByVisibleBounds(maxSelector, minVisibleSelector, otherGreaterThan);
  18821. if (categories === undefined)
  18822. that[categoriesSelector] = otherCategories;
  18823. else
  18824. that[categoriesSelector] = getUniqueCategories(categories, otherCategories, that.dataType);
  18825. return this
  18826. },
  18827. isDefined: function() {
  18828. return _isDefined(this[minSelector]) && _isDefined(this[maxSelector]) || _isDefined(this[categoriesSelector])
  18829. },
  18830. setStubData: function(dataType) {
  18831. var that = this,
  18832. year = (new Date).getYear() - 1,
  18833. isDate = dataType === "datetime",
  18834. isCategories = that.axisType === "discrete";
  18835. if (isCategories)
  18836. that.categories = ["0", "1", "2"];
  18837. else {
  18838. that[minSelector] = isDate ? new Date(year, 0, 1) : 0;
  18839. that[maxSelector] = isDate ? new Date(year, 11, 31) : 10
  18840. }
  18841. that.stubData = true;
  18842. return that
  18843. },
  18844. correctValueZeroLevel: function() {
  18845. var that = this;
  18846. if (_isDate(that[maxSelector]) || _isDate(that[minSelector]))
  18847. return that;
  18848. function setZeroLevel(min, max) {
  18849. that[min] < 0 && that[max] < 0 && (that[max] = 0);
  18850. that[min] > 0 && that[max] > 0 && (that[min] = 0)
  18851. }
  18852. setZeroLevel(minSelector, maxSelector);
  18853. setZeroLevel(minVisibleSelector, maxVisibleSelector);
  18854. return that
  18855. },
  18856. checkZeroStick: function() {
  18857. var that = this;
  18858. if (that.min >= 0 && that.max >= 0)
  18859. that.minStickValue = 0;
  18860. else if (that.min <= 0 && that.max <= 0)
  18861. that.maxStickValue = 0;
  18862. return that
  18863. }
  18864. }
  18865. })(jQuery, DevExpress);
  18866. /*! Module viz-core, file svgRenderer.js */
  18867. (function($, DX, doc, undefined) {
  18868. var rendererNS = DX.viz.renderers = {},
  18869. math = Math,
  18870. mathMin = math.min,
  18871. mathMax = math.max,
  18872. mathCeil = math.ceil,
  18873. mathFloor = math.floor,
  18874. mathRound = math.round,
  18875. mathSin = math.sin,
  18876. mathCos = math.cos,
  18877. mathAbs = math.abs,
  18878. mathPI = math.PI,
  18879. PI_DIV_180 = mathPI / 180,
  18880. _parseInt = parseInt,
  18881. MAX_PIXEL_COUNT = 1E10,
  18882. SHARPING_CORRECTION = 0.5,
  18883. ARC_COORD_PREC = 5;
  18884. var pxAddingExceptions = {
  18885. "column-count": true,
  18886. "fill-opacity": true,
  18887. "flex-grow": true,
  18888. "flex-shrink": true,
  18889. "font-weight": true,
  18890. "line-height": true,
  18891. opacity: true,
  18892. order: true,
  18893. orphans: true,
  18894. widows: true,
  18895. "z-index": true,
  18896. zoom: true
  18897. };
  18898. var KEY_TEXT = "text",
  18899. KEY_STROKE = "stroke",
  18900. KEY_STROKE_WIDTH = "stroke-width",
  18901. KEY_STROKE_OPACITY = "stroke-opacity",
  18902. KEY_FONT_SIZE = "font-size",
  18903. KEY_FONT_STYLE = "font-style",
  18904. KEY_FONT_WEIGHT = "font-weight",
  18905. KEY_TEXT_DECORATION = "text-decoration",
  18906. NONE = "none";
  18907. var DEFAULTS = {
  18908. scaleX: 1,
  18909. scaleY: 1
  18910. };
  18911. var getNextDefsSvgId = function() {
  18912. var numDefsSvgElements = 1;
  18913. return function() {
  18914. return "DevExpress_" + numDefsSvgElements++
  18915. }
  18916. }();
  18917. function isObjectArgument(value) {
  18918. return typeof value !== "string"
  18919. }
  18920. function isDefined(value) {
  18921. return value !== null && value !== undefined
  18922. }
  18923. function isArray(value) {
  18924. return Object.prototype.toString.call(value) === "[object Array]"
  18925. }
  18926. function isObject(value) {
  18927. return Object.prototype.toString.call(value) === "[object Object]"
  18928. }
  18929. function createElement(tagName) {
  18930. return doc.createElementNS("http://www.w3.org/2000/svg", tagName)
  18931. }
  18932. function getPatternUrl(id, pathModified) {
  18933. return id !== null ? "url(" + (pathModified ? window.location.href : "") + "#" + id + ")" : ""
  18934. }
  18935. function extend(a, b, skipNonDefined) {
  18936. var value;
  18937. for (var key in b) {
  18938. value = b[key];
  18939. if (!skipNonDefined || skipNonDefined && value !== undefined && value !== null)
  18940. a[key] = value
  18941. }
  18942. return a
  18943. }
  18944. function rotateBBox(bbox, center, angle) {
  18945. var cos = Number(mathCos(angle * PI_DIV_180).toFixed(3)),
  18946. sin = Number(mathSin(angle * PI_DIV_180).toFixed(3)),
  18947. w2 = bbox.width / 2,
  18948. h2 = bbox.height / 2,
  18949. xc = bbox.x + w2,
  18950. yc = bbox.y + h2,
  18951. w2_ = mathAbs(w2 * cos) + mathAbs(h2 * sin),
  18952. h2_ = mathAbs(w2 * sin) + mathAbs(h2 * cos),
  18953. xc_ = center[0] + (xc - center[0]) * cos + (yc - center[1]) * sin,
  18954. yc_ = center[1] - (xc - center[0]) * sin + (yc - center[1]) * cos;
  18955. return normalizeBBox({
  18956. x: xc_ - w2_,
  18957. y: yc_ - h2_,
  18958. width: 2 * w2_,
  18959. height: 2 * h2_
  18960. })
  18961. }
  18962. function normalizeBBoxField(value) {
  18963. return -MAX_PIXEL_COUNT < value && value < +MAX_PIXEL_COUNT ? value : 0
  18964. }
  18965. function normalizeBBox(bbox) {
  18966. var rxl = normalizeBBoxField(mathFloor(bbox.x)),
  18967. ryt = normalizeBBoxField(mathFloor(bbox.y)),
  18968. rxr = normalizeBBoxField(mathCeil(bbox.width + bbox.x)),
  18969. ryb = normalizeBBoxField(mathCeil(bbox.height + bbox.y)),
  18970. result = {
  18971. x: rxl,
  18972. y: ryt,
  18973. width: rxr - rxl,
  18974. height: ryb - ryt
  18975. };
  18976. result.isEmpty = !result.x && !result.y && !result.width && !result.height;
  18977. return result
  18978. }
  18979. function getPreserveAspectRatio(location) {
  18980. return {
  18981. full: NONE,
  18982. lefttop: "xMinYMin",
  18983. leftcenter: "xMinYMid",
  18984. leftbottom: "xMinYMax",
  18985. centertop: "xMidYMin",
  18986. center: "xMidYMid",
  18987. centerbottom: "xMidYMax",
  18988. righttop: "xMaxYMin",
  18989. rightcenter: "xMaxYMid",
  18990. rightbottom: "xMaxYMax"
  18991. }[(location || "").toLowerCase()] || NONE
  18992. }
  18993. rendererNS._normalizeArcParams = function(x, y, innerR, outerR, startAngle, endAngle) {
  18994. var isCircle,
  18995. noArc = true;
  18996. if (mathRound(startAngle) !== mathRound(endAngle)) {
  18997. if (mathAbs(endAngle - startAngle) % 360 === 0) {
  18998. startAngle = 0;
  18999. endAngle = 360;
  19000. isCircle = true;
  19001. endAngle -= 0.01
  19002. }
  19003. if (startAngle > 360)
  19004. startAngle = startAngle % 360;
  19005. if (endAngle > 360)
  19006. endAngle = endAngle % 360;
  19007. if (startAngle > endAngle)
  19008. startAngle -= 360;
  19009. noArc = false
  19010. }
  19011. startAngle = startAngle * PI_DIV_180;
  19012. endAngle = endAngle * PI_DIV_180;
  19013. return [x, y, mathMin(outerR, innerR), mathMax(outerR, innerR), mathCos(startAngle), mathSin(startAngle), mathCos(endAngle), mathSin(endAngle), isCircle, mathFloor(mathAbs(endAngle - startAngle) / mathPI) % 2 ? "1" : "0", noArc]
  19014. };
  19015. var buildArcPath = function(x, y, innerR, outerR, startAngleCos, startAngleSin, endAngleCos, endAngleSin, isCircle, longFlag) {
  19016. return ["M", (x + outerR * startAngleCos).toFixed(ARC_COORD_PREC), (y - outerR * startAngleSin).toFixed(ARC_COORD_PREC), "A", outerR.toFixed(ARC_COORD_PREC), outerR.toFixed(ARC_COORD_PREC), 0, longFlag, 0, (x + outerR * endAngleCos).toFixed(ARC_COORD_PREC), (y - outerR * endAngleSin).toFixed(ARC_COORD_PREC), isCircle ? "M" : "L", (x + innerR * endAngleCos).toFixed(5), (y - innerR * endAngleSin).toFixed(ARC_COORD_PREC), "A", innerR.toFixed(ARC_COORD_PREC), innerR.toFixed(ARC_COORD_PREC), 0, longFlag, 1, (x + innerR * startAngleCos).toFixed(ARC_COORD_PREC), (y - innerR * startAngleSin).toFixed(ARC_COORD_PREC), "Z"].join(" ")
  19017. };
  19018. function buildPathSegments(points, type) {
  19019. var list = [["M", 0, 0]];
  19020. switch (type) {
  19021. case"line":
  19022. list = buildLineSegments(points);
  19023. break;
  19024. case"area":
  19025. list = buildLineSegments(points, true);
  19026. break;
  19027. case"bezier":
  19028. list = buildCurveSegments(points);
  19029. break;
  19030. case"bezierarea":
  19031. list = buildCurveSegments(points, true);
  19032. break
  19033. }
  19034. return list
  19035. }
  19036. function buildLineSegments(points, close) {
  19037. return buildSegments(points, buildSimpleLineSegment, close)
  19038. }
  19039. function buildCurveSegments(points, close) {
  19040. return buildSegments(points, buildSimpleCurveSegment, close)
  19041. }
  19042. function buildSegments(points, buildSimpleSegment, close) {
  19043. var i = 0,
  19044. ii = (points || []).length,
  19045. list = [];
  19046. if (isArray(points[0]))
  19047. for (; i < ii; )
  19048. buildSimpleSegment(points[i++], close, list);
  19049. else
  19050. buildSimpleSegment(points, close, list);
  19051. return list
  19052. }
  19053. function buildSimpleLineSegment(points, close, list) {
  19054. var i = 0,
  19055. ii = (points || []).length;
  19056. if (ii)
  19057. if (isObject(points[0]))
  19058. for (; i < ii; )
  19059. list.push([!i ? "M" : "L", points[i].x, points[i++].y]);
  19060. else
  19061. for (; i < ii; )
  19062. list.push([!i ? "M" : "L", points[i++], points[i++]]);
  19063. else
  19064. list.push(["M", 0, 0]);
  19065. close && list.push(["Z"]);
  19066. return list
  19067. }
  19068. function buildSimpleCurveSegment(points, close, list) {
  19069. var i = 2,
  19070. ii = (points || []).length;
  19071. if (ii)
  19072. if (isObject(points[0])) {
  19073. i = 1;
  19074. list.push(["M", points[0].x, points[0].y]);
  19075. for (; i < ii; )
  19076. list.push(["C", points[i].x, points[i++].y, points[i].x, points[i++].y, points[i].x, points[i++].y])
  19077. }
  19078. else {
  19079. list.push(["M", points[0], points[1]]);
  19080. for (; i < ii; )
  19081. list.push(["C", points[i++], points[i++], points[i++], points[i++], points[i++], points[i++]])
  19082. }
  19083. else
  19084. list.push(["M", 0, 0]);
  19085. close && list.push(["Z"]);
  19086. return list
  19087. }
  19088. function combinePathParam(segments) {
  19089. var d = [],
  19090. i = 0,
  19091. length = segments.length;
  19092. for (; i < length; i++)
  19093. d.push(segments[i].join(" "));
  19094. return d.join(" ")
  19095. }
  19096. function compensateSegments(oldSegments, newSegments, type) {
  19097. var oldLength = oldSegments.length,
  19098. newLength = newSegments.length,
  19099. i,
  19100. originalNewSegments,
  19101. makeEqualSegments = type.indexOf("area") !== -1 ? makeEqualAreaSegments : makeEqualLineSegments;
  19102. if (oldLength === 0)
  19103. for (i = 0; i < newLength; i++)
  19104. oldSegments.push(newSegments[i].slice(0));
  19105. else if (oldLength < newLength)
  19106. makeEqualSegments(oldSegments, newSegments, type);
  19107. else if (oldLength > newLength) {
  19108. originalNewSegments = newSegments.slice(0);
  19109. makeEqualSegments(newSegments, oldSegments, type)
  19110. }
  19111. return originalNewSegments
  19112. }
  19113. function prepareConstSegment(constSeg, type) {
  19114. var x = constSeg[constSeg.length - 2],
  19115. y = constSeg[constSeg.length - 1];
  19116. switch (type) {
  19117. case"line":
  19118. case"area":
  19119. constSeg[0] = "L";
  19120. break;
  19121. case"bezier":
  19122. case"bezierarea":
  19123. constSeg[0] = "C";
  19124. constSeg[1] = constSeg[3] = constSeg[5] = x;
  19125. constSeg[2] = constSeg[4] = constSeg[6] = y;
  19126. break
  19127. }
  19128. }
  19129. function makeEqualLineSegments(short, long, type) {
  19130. var constSeg = short[short.length - 1].slice(),
  19131. i = short.length;
  19132. prepareConstSegment(constSeg, type);
  19133. for (; i < long.length; i++)
  19134. short[i] = constSeg.slice(0)
  19135. }
  19136. function makeEqualAreaSegments(short, long, type) {
  19137. var i,
  19138. head,
  19139. shortLength = short.length,
  19140. longLength = long.length,
  19141. constsSeg1,
  19142. constsSeg2;
  19143. if ((shortLength - 1) % 2 === 0 && (longLength - 1) % 2 === 0) {
  19144. i = (shortLength - 1) / 2 - 1;
  19145. head = short.slice(0, i + 1);
  19146. constsSeg1 = head[head.length - 1].slice(0);
  19147. constsSeg2 = short.slice(i + 1)[0].slice(0);
  19148. prepareConstSegment(constsSeg1, type);
  19149. prepareConstSegment(constsSeg2, type);
  19150. for (var j = i; j < (longLength - 1) / 2 - 1; j++) {
  19151. short.splice(j + 1, 0, constsSeg1);
  19152. short.splice(j + 3, 0, constsSeg2)
  19153. }
  19154. }
  19155. }
  19156. function baseCss(styles) {
  19157. var elemStyles = this._styles,
  19158. str = "",
  19159. key,
  19160. value;
  19161. extend(elemStyles, styles || {}, true);
  19162. for (key in elemStyles) {
  19163. value = elemStyles[key];
  19164. if (value === "")
  19165. continue;
  19166. if (typeof value === "number" && !pxAddingExceptions[key])
  19167. value += "px";
  19168. str += key + ":" + value + ";"
  19169. }
  19170. str && this.element.setAttribute("style", str);
  19171. return this
  19172. }
  19173. function baseAttr(attrs) {
  19174. attrs = attrs || {};
  19175. var that = this,
  19176. settings = that._settings,
  19177. attributes = {},
  19178. key,
  19179. value,
  19180. elem = that.element,
  19181. renderer = that.renderer,
  19182. rtl = renderer.rtl,
  19183. hasTransformations,
  19184. recalculateDashStyle,
  19185. sw,
  19186. i;
  19187. if (!isObjectArgument(attrs)) {
  19188. if (attrs in settings)
  19189. return settings[attrs];
  19190. if (attrs in DEFAULTS)
  19191. return DEFAULTS[attrs];
  19192. return 0
  19193. }
  19194. extend(attributes, attrs);
  19195. for (key in attributes) {
  19196. value = attributes[key];
  19197. if (value === undefined)
  19198. continue;
  19199. settings[key] = value;
  19200. if (key === "align") {
  19201. key = "text-anchor";
  19202. value = {
  19203. left: rtl ? "end" : "start",
  19204. center: "middle",
  19205. right: rtl ? "start" : "end"
  19206. }[value] || ""
  19207. }
  19208. else if (key === "dashStyle") {
  19209. recalculateDashStyle = true;
  19210. continue
  19211. }
  19212. else if (key === KEY_STROKE_WIDTH)
  19213. recalculateDashStyle = true;
  19214. else if (key === "clipId") {
  19215. key = "clip-path";
  19216. value = getPatternUrl(value, renderer.pathModified)
  19217. }
  19218. else if (/^(translate(X|Y)|rotate[XY]?|scale(X|Y)|sharp)$/i.test(key)) {
  19219. hasTransformations = true;
  19220. continue
  19221. }
  19222. else if (/^(x|y|d)$/i.test(key))
  19223. hasTransformations = true;
  19224. if (value === null)
  19225. elem.removeAttribute(key);
  19226. else
  19227. elem.setAttribute(key, value)
  19228. }
  19229. if (recalculateDashStyle && "dashStyle" in settings) {
  19230. value = settings.dashStyle;
  19231. sw = ("_originalSW" in that ? that._originalSW : settings[KEY_STROKE_WIDTH]) || 1;
  19232. key = "stroke-dasharray";
  19233. value = value === null ? "" : value.toLowerCase();
  19234. if (value === "" || value === "solid" || value === NONE)
  19235. that.element.removeAttribute(key);
  19236. else {
  19237. value = value.replace(/longdash/g, "8,3,").replace(/dash/g, "4,3,").replace(/dot/g, "1,3,").replace(/,$/, "").split(",");
  19238. i = value.length;
  19239. while (i--)
  19240. value[i] = _parseInt(value[i]) * sw;
  19241. that.element.setAttribute(key, value.join(","))
  19242. }
  19243. }
  19244. if (hasTransformations)
  19245. that._applyTransformation();
  19246. return that
  19247. }
  19248. function createPathAttr(baseAttr) {
  19249. return function(attrs, inh) {
  19250. var that = this,
  19251. segments;
  19252. if (isObjectArgument(attrs)) {
  19253. attrs = extend({}, attrs);
  19254. segments = attrs.segments;
  19255. if ("points" in attrs) {
  19256. segments = buildPathSegments(attrs.points, that.type);
  19257. delete attrs.points
  19258. }
  19259. if (segments) {
  19260. attrs.d = combinePathParam(segments);
  19261. that.segments = segments;
  19262. delete attrs.segments
  19263. }
  19264. }
  19265. return baseAttr.call(that, attrs, inh)
  19266. }
  19267. }
  19268. function createArcAttr(baseAttr, buildArcPath) {
  19269. return function(attrs, inh) {
  19270. var settings = this._settings,
  19271. x,
  19272. y,
  19273. innerRadius,
  19274. outerRadius,
  19275. startAngle,
  19276. endAngle;
  19277. if (isObjectArgument(attrs)) {
  19278. attrs = extend({}, attrs);
  19279. if ("x" in attrs || "y" in attrs || "innerRadius" in attrs || "outerRadius" in attrs || "startAngle" in attrs || "endAngle" in attrs) {
  19280. settings.x = x = "x" in attrs ? attrs.x : settings.x;
  19281. delete attrs.x;
  19282. settings.y = y = "y" in attrs ? attrs.y : settings.y;
  19283. delete attrs.y;
  19284. settings.innerRadius = innerRadius = "innerRadius" in attrs ? attrs.innerRadius : settings.innerRadius;
  19285. delete attrs.innerRadius;
  19286. settings.outerRadius = outerRadius = "outerRadius" in attrs ? attrs.outerRadius : settings.outerRadius;
  19287. delete attrs.outerRadius;
  19288. settings.startAngle = startAngle = "startAngle" in attrs ? attrs.startAngle : settings.startAngle;
  19289. delete attrs.startAngle;
  19290. settings.endAngle = endAngle = "endAngle" in attrs ? attrs.endAngle : settings.endAngle;
  19291. delete attrs.endAngle;
  19292. attrs.d = buildArcPath.apply(this, rendererNS._normalizeArcParams(x, y, innerRadius, outerRadius, startAngle, endAngle))
  19293. }
  19294. }
  19295. return baseAttr.call(this, attrs, inh)
  19296. }
  19297. }
  19298. function createRectAttr(baseAttr) {
  19299. return function(attrs, inh) {
  19300. var that = this,
  19301. x,
  19302. y,
  19303. width,
  19304. height,
  19305. sw,
  19306. maxSW,
  19307. newSW;
  19308. if (isObjectArgument(attrs)) {
  19309. attrs = extend({}, attrs);
  19310. if (!inh && (attrs.x !== undefined || attrs.y !== undefined || attrs.width !== undefined || attrs.height !== undefined || attrs[KEY_STROKE_WIDTH] !== undefined)) {
  19311. attrs.x !== undefined ? x = that._originalX = attrs.x : x = that._originalX || 0;
  19312. attrs.y !== undefined ? y = that._originalY = attrs.y : y = that._originalY || 0;
  19313. attrs.width !== undefined ? width = that._originalWidth = attrs.width : width = that._originalWidth || 0;
  19314. attrs.height !== undefined ? height = that._originalHeight = attrs.height : height = that._originalHeight || 0;
  19315. attrs[KEY_STROKE_WIDTH] !== undefined ? sw = that._originalSW = attrs[KEY_STROKE_WIDTH] : sw = that._originalSW;
  19316. maxSW = ~~((width < height ? width : height) / 2);
  19317. newSW = (sw || 0) < maxSW ? sw || 0 : maxSW;
  19318. attrs.x = x + newSW / 2;
  19319. attrs.y = y + newSW / 2;
  19320. attrs.width = width - newSW;
  19321. attrs.height = height - newSW;
  19322. ((sw || 0) !== newSW || !(newSW === 0 && sw === undefined)) && (attrs[KEY_STROKE_WIDTH] = newSW)
  19323. }
  19324. if ("sharp" in attrs)
  19325. delete attrs.sharp
  19326. }
  19327. return baseAttr.call(that, attrs, inh)
  19328. }
  19329. }
  19330. var pathAttr = createPathAttr(baseAttr),
  19331. arcAttr = createArcAttr(baseAttr, buildArcPath),
  19332. rectAttr = createRectAttr(baseAttr);
  19333. function textAttr(attrs) {
  19334. var that = this,
  19335. settings,
  19336. isResetRequired,
  19337. wasStroked,
  19338. isStroked;
  19339. if (!isObjectArgument(attrs))
  19340. return baseAttr.call(that, attrs);
  19341. attrs = extend({}, attrs);
  19342. settings = that._settings;
  19343. wasStroked = isDefined(settings[KEY_STROKE]) && isDefined(settings[KEY_STROKE_WIDTH]);
  19344. if (attrs[KEY_TEXT] !== undefined) {
  19345. settings[KEY_TEXT] = attrs[KEY_TEXT];
  19346. delete attrs[KEY_TEXT];
  19347. isResetRequired = true
  19348. }
  19349. if (attrs[KEY_STROKE] !== undefined) {
  19350. settings[KEY_STROKE] = attrs[KEY_STROKE];
  19351. delete attrs[KEY_STROKE]
  19352. }
  19353. if (attrs[KEY_STROKE_WIDTH] !== undefined) {
  19354. settings[KEY_STROKE_WIDTH] = attrs[KEY_STROKE_WIDTH];
  19355. delete attrs[KEY_STROKE_WIDTH]
  19356. }
  19357. if (attrs[KEY_STROKE_OPACITY] !== undefined) {
  19358. settings[KEY_STROKE_OPACITY] = attrs[KEY_STROKE_OPACITY];
  19359. delete attrs[KEY_STROKE_OPACITY]
  19360. }
  19361. isStroked = isDefined(settings[KEY_STROKE]) && isDefined(settings[KEY_STROKE_WIDTH]);
  19362. baseAttr.call(that, attrs);
  19363. isResetRequired = isResetRequired || isStroked !== wasStroked && settings[KEY_TEXT];
  19364. if (isResetRequired)
  19365. createTextNodes(that, settings.text, isStroked);
  19366. if (isResetRequired || attrs["x"] !== undefined || attrs["y"] !== undefined)
  19367. locateTextNodes(that);
  19368. if (isStroked)
  19369. strokeTextNodes(that);
  19370. return that
  19371. }
  19372. function textCss(styles) {
  19373. styles = styles || {};
  19374. baseCss.call(this, styles);
  19375. if (KEY_FONT_SIZE in styles)
  19376. locateTextNodes(this);
  19377. return this
  19378. }
  19379. function orderHtmlTree(strCount, node, textArray) {
  19380. var nodeParams = node.params = node.params || {style: {}},
  19381. nodeStyle = nodeParams.style,
  19382. parentStyle = node.parentNode && node.parentNode.params && node.parentNode.params.style || {},
  19383. nativeElementStyle = node.style,
  19384. childCount = node.childNodes.length,
  19385. count = 0;
  19386. if (node.nodeName !== '#text')
  19387. extend(nodeStyle, parentStyle);
  19388. switch (node.tagName) {
  19389. case'B':
  19390. case'STRONG':
  19391. nodeStyle[KEY_FONT_WEIGHT] = 'bold';
  19392. break;
  19393. case'I':
  19394. case'EM':
  19395. nodeStyle[KEY_FONT_STYLE] = 'italic';
  19396. break;
  19397. case'U':
  19398. nodeStyle[KEY_TEXT_DECORATION] = 'underline';
  19399. break;
  19400. case'BR':
  19401. strCount++;
  19402. break
  19403. }
  19404. if (nativeElementStyle) {
  19405. if (nativeElementStyle.fontSize)
  19406. nodeStyle[KEY_FONT_SIZE] = (_parseInt(nativeElementStyle.fontSize, 10) || nodeStyle[KEY_FONT_SIZE]) + 'px';
  19407. nodeStyle.fill = nativeElementStyle.color || nodeStyle.fill;
  19408. nodeStyle[KEY_FONT_STYLE] = nativeElementStyle.fontStyle || nodeStyle[KEY_FONT_STYLE];
  19409. nodeStyle[KEY_FONT_WEIGHT] = nativeElementStyle.fontWeight || nodeStyle[KEY_FONT_WEIGHT];
  19410. nodeStyle[KEY_TEXT_DECORATION] = nativeElementStyle.textDecoration || nodeStyle[KEY_TEXT_DECORATION]
  19411. }
  19412. while (count !== childCount)
  19413. strCount = orderHtmlTree(strCount, node.childNodes[count++], textArray);
  19414. if (node.wholeText !== undefined) {
  19415. extend(nodeStyle, parentStyle);
  19416. textArray.push({
  19417. value: node.wholeText,
  19418. style: nodeStyle,
  19419. line: strCount,
  19420. height: _parseInt(nodeStyle[KEY_FONT_SIZE], 10) || 0
  19421. })
  19422. }
  19423. return strCount
  19424. }
  19425. function adjustLineHeights(items) {
  19426. var i,
  19427. ii,
  19428. currentItem = items[0],
  19429. item;
  19430. for (i = 1, ii = items.length; i < ii; ++i) {
  19431. item = items[i];
  19432. if (item.line === currentItem.line) {
  19433. currentItem.height = mathMax(currentItem.height, item.height);
  19434. currentItem.inherits = currentItem.inherits || item.height === 0;
  19435. item.height = NaN
  19436. }
  19437. else
  19438. currentItem = item
  19439. }
  19440. }
  19441. function parseHTML(text) {
  19442. var items = [],
  19443. div = doc.createElement("div");
  19444. div.innerHTML = text.replace(/\r/g, "").replace(/\n/g, "<br/>");
  19445. orderHtmlTree(0, div, items);
  19446. adjustLineHeights(items);
  19447. return items
  19448. }
  19449. function parseMultiline(text) {
  19450. var texts = text.replace(/\r/g, "").split("\n"),
  19451. i = 0,
  19452. items = [];
  19453. for (; i < texts.length; i++)
  19454. items.push({
  19455. value: texts[i],
  19456. height: 0
  19457. });
  19458. return items
  19459. }
  19460. function createTspans(items, element, fieldName) {
  19461. var i,
  19462. ii,
  19463. item;
  19464. for (i = 0, ii = items.length; i < ii; ++i) {
  19465. item = items[i];
  19466. item[fieldName] = createElement("tspan");
  19467. item[fieldName].appendChild(doc.createTextNode(item.value));
  19468. item.style && baseCss.call({
  19469. element: item[fieldName],
  19470. _styles: {}
  19471. }, item.style);
  19472. element.appendChild(item[fieldName])
  19473. }
  19474. }
  19475. function createTextNodes(wrapper, text, isStroked) {
  19476. var items;
  19477. wrapper._texts = null;
  19478. wrapper.clear();
  19479. if (text === null)
  19480. return;
  19481. text = "" + text;
  19482. if (!wrapper.renderer.encodeHtml && (text.indexOf("<") !== -1 || text.indexOf("&") !== -1))
  19483. items = parseHTML(text);
  19484. else if (text.indexOf("\n") !== -1)
  19485. items = parseMultiline(text);
  19486. else if (isStroked)
  19487. items = [{
  19488. value: text,
  19489. height: 0
  19490. }];
  19491. if (items) {
  19492. if (items.length) {
  19493. wrapper._texts = items;
  19494. if (isStroked)
  19495. createTspans(items, wrapper.element, KEY_STROKE);
  19496. createTspans(items, wrapper.element, "tspan")
  19497. }
  19498. }
  19499. else
  19500. wrapper.element.appendChild(doc.createTextNode(text))
  19501. }
  19502. function setTextNodeAttribute(item, name, value) {
  19503. item.tspan.setAttribute(name, value);
  19504. item.stroke && item.stroke.setAttribute(name, value)
  19505. }
  19506. function locateTextNodes(wrapper) {
  19507. if (!wrapper._texts)
  19508. return;
  19509. var items = wrapper._texts,
  19510. x = wrapper._settings.x,
  19511. lineHeight = wrapper._styles[KEY_FONT_SIZE] || 12,
  19512. i,
  19513. ii,
  19514. item = items[0];
  19515. setTextNodeAttribute(item, "x", x);
  19516. setTextNodeAttribute(item, "y", wrapper._settings.y);
  19517. for (i = 1, ii = items.length; i < ii; ++i) {
  19518. item = items[i];
  19519. if (item.height >= 0) {
  19520. setTextNodeAttribute(item, "x", x);
  19521. setTextNodeAttribute(item, "dy", item.inherits ? mathMax(item.height, lineHeight) : item.height || lineHeight)
  19522. }
  19523. }
  19524. }
  19525. function strokeTextNodes(wrapper) {
  19526. if (!wrapper._texts)
  19527. return;
  19528. var items = wrapper._texts,
  19529. stroke = wrapper._settings[KEY_STROKE],
  19530. strokeWidth = wrapper._settings[KEY_STROKE_WIDTH],
  19531. strokeOpacity = wrapper._settings[KEY_STROKE_OPACITY] || 1,
  19532. tspan,
  19533. i,
  19534. ii;
  19535. for (i = 0, ii = items.length; i < ii; ++i) {
  19536. tspan = items[i].stroke;
  19537. tspan.setAttribute(KEY_STROKE, stroke);
  19538. tspan.setAttribute(KEY_STROKE_WIDTH, strokeWidth);
  19539. tspan.setAttribute(KEY_STROKE_OPACITY, strokeOpacity);
  19540. tspan.setAttribute("stroke-linejoin", "round")
  19541. }
  19542. }
  19543. function baseAnimate(params, options, complete) {
  19544. options = options || {};
  19545. var that = this,
  19546. key,
  19547. value,
  19548. renderer = that.renderer,
  19549. settings = that._settings,
  19550. animationParams = {};
  19551. var defaults = {
  19552. translateX: 0,
  19553. translateY: 0,
  19554. scaleX: 1,
  19555. scaleY: 1,
  19556. rotate: 0,
  19557. rotateX: 0,
  19558. rotateY: 0
  19559. };
  19560. if (complete)
  19561. options.complete = complete;
  19562. if (renderer.animationEnabled()) {
  19563. for (key in params) {
  19564. value = params[key];
  19565. if (/^(translate(X|Y)|rotate[XY]?|scale(X|Y))$/i.test(key)) {
  19566. animationParams.transform = animationParams.transform || {
  19567. from: {},
  19568. to: {}
  19569. };
  19570. animationParams.transform.from[key] = key in settings ? settings[key] : defaults[key];
  19571. animationParams.transform.to[key] = value
  19572. }
  19573. else if (key === "arc" || key === "segments")
  19574. animationParams[key] = value;
  19575. else
  19576. animationParams[key] = {
  19577. from: key in settings ? settings[key] : parseFloat(that.element.getAttribute(key) || 0),
  19578. to: value
  19579. }
  19580. }
  19581. renderer.animateElement(that, animationParams, extend(extend({}, renderer._animation), options))
  19582. }
  19583. else {
  19584. options.step && options.step.call(that, 1, 1);
  19585. options.complete && options.complete.call(that);
  19586. that.attr(params)
  19587. }
  19588. return that
  19589. }
  19590. function pathAnimate(params, options, complete) {
  19591. var that = this,
  19592. curSegments = that.segments || [],
  19593. newSegments,
  19594. endSegments;
  19595. if (that.renderer.animationEnabled() && "points" in params) {
  19596. newSegments = buildPathSegments(params.points, that.type);
  19597. endSegments = compensateSegments(curSegments, newSegments, that.type);
  19598. params.segments = {
  19599. from: curSegments,
  19600. to: newSegments,
  19601. end: endSegments
  19602. };
  19603. delete params.points
  19604. }
  19605. return baseAnimate.call(that, params, options, complete)
  19606. }
  19607. function arcAnimate(params, options, complete) {
  19608. var that = this,
  19609. settings = that._settings,
  19610. arcParams = {
  19611. from: {},
  19612. to: {}
  19613. };
  19614. if (that.renderer.animationEnabled() && ("x" in params || "y" in params || "innerRadius" in params || "outerRadius" in params || "startAngle" in params || "endAngle" in params)) {
  19615. arcParams.from.x = settings.x || 0;
  19616. arcParams.from.y = settings.y || 0;
  19617. arcParams.from.innerRadius = settings.innerRadius || 0;
  19618. arcParams.from.outerRadius = settings.outerRadius || 0;
  19619. arcParams.from.startAngle = settings.startAngle || 0;
  19620. arcParams.from.endAngle = settings.endAngle || 0;
  19621. arcParams.to.x = "x" in params ? params.x : settings.x;
  19622. delete params.x;
  19623. arcParams.to.y = "y" in params ? params.y : settings.y;
  19624. delete params.y;
  19625. arcParams.to.innerRadius = "innerRadius" in params ? params.innerRadius : settings.innerRadius;
  19626. delete params.innerRadius;
  19627. arcParams.to.outerRadius = "outerRadius" in params ? params.outerRadius : settings.outerRadius;
  19628. delete params.outerRadius;
  19629. arcParams.to.startAngle = "startAngle" in params ? params.startAngle : settings.startAngle;
  19630. delete params.startAngle;
  19631. arcParams.to.endAngle = "endAngle" in params ? params.endAngle : settings.endAngle;
  19632. delete params.endAngle;
  19633. params.arc = arcParams
  19634. }
  19635. return baseAnimate.call(that, params, options, complete)
  19636. }
  19637. rendererNS.__mockPrivateFunctions = function(fs) {
  19638. fs = fs || {};
  19639. function mockFunction(mock, orig) {
  19640. if (!mock)
  19641. return orig;
  19642. var originalFunction = orig;
  19643. orig = mock;
  19644. orig._originalFunction = originalFunction;
  19645. return orig
  19646. }
  19647. createElement = mockFunction(fs.createElement, createElement);
  19648. baseAttr = mockFunction(fs.baseAttr, baseAttr);
  19649. baseAnimate = mockFunction(fs.baseAnimate, baseAnimate);
  19650. getNextDefsSvgId = mockFunction(fs.getNextDefsSvgId, getNextDefsSvgId);
  19651. compensateSegments = mockFunction(fs.compensateSegments, compensateSegments);
  19652. buildPathSegments = mockFunction(fs.buildPathSegments, buildPathSegments);
  19653. buildArcPath = mockFunction(fs.buildArcPath, buildArcPath);
  19654. pathAttr = createPathAttr(baseAttr);
  19655. arcAttr = createArcAttr(baseAttr, buildArcPath);
  19656. rectAttr = createRectAttr(baseAttr);
  19657. return {
  19658. createElement: createElement,
  19659. baseAttr: baseAttr,
  19660. baseAnimate: baseAnimate,
  19661. getNextDefsSvgId: getNextDefsSvgId,
  19662. compensateSegments: compensateSegments,
  19663. buildPathSegments: buildPathSegments,
  19664. buildArcPath: buildArcPath
  19665. }
  19666. };
  19667. rendererNS.__restoreMockPrivateFunctions = function() {
  19668. function restoreFunction(func) {
  19669. return func._originalFunction || func
  19670. }
  19671. createElement = restoreFunction(createElement);
  19672. baseAttr = restoreFunction(baseAttr);
  19673. baseAnimate = restoreFunction(baseAnimate);
  19674. getNextDefsSvgId = restoreFunction(getNextDefsSvgId);
  19675. compensateSegments = restoreFunction(compensateSegments);
  19676. buildPathSegments = restoreFunction(buildPathSegments);
  19677. buildArcPath = restoreFunction(buildArcPath);
  19678. pathAttr = createPathAttr(baseAttr);
  19679. arcAttr = createArcAttr(baseAttr, buildArcPath);
  19680. rectAttr = createRectAttr(baseAttr)
  19681. };
  19682. function SvgElement() {
  19683. this.ctor.apply(this, arguments)
  19684. }
  19685. rendererNS.SvgElement = SvgElement;
  19686. SvgElement.prototype = {
  19687. ctor: function(renderer, tagName, type) {
  19688. var that = this;
  19689. that.renderer = renderer;
  19690. that.element = createElement(tagName);
  19691. that._settings = {};
  19692. that._styles = {};
  19693. if (tagName === "path")
  19694. that.type = type || "line";
  19695. if (tagName === "text") {
  19696. that.attr = textAttr;
  19697. that.css = textCss
  19698. }
  19699. else if (tagName === "path")
  19700. if (that.type === "arc") {
  19701. that.attr = arcAttr;
  19702. that.animate = arcAnimate
  19703. }
  19704. else {
  19705. that.attr = pathAttr;
  19706. that.animate = pathAnimate
  19707. }
  19708. else if (tagName === "rect") {
  19709. that.attr = rectAttr;
  19710. that.sharp = function() {
  19711. return this
  19712. }
  19713. }
  19714. that._$element = $(that.element)
  19715. },
  19716. dispose: function() {
  19717. this._$element.remove();
  19718. return this
  19719. },
  19720. append: function(parent) {
  19721. parent = parent || this.renderer.root;
  19722. (parent.element || parent).appendChild(this.element);
  19723. return this
  19724. },
  19725. remove: function() {
  19726. var elem = this.element,
  19727. parent = elem.parentNode;
  19728. parent && parent.removeChild(elem);
  19729. return this
  19730. },
  19731. clear: function() {
  19732. this._$element.empty();
  19733. return this
  19734. },
  19735. toBackground: function() {
  19736. var elem = this.element,
  19737. parent = elem.parentNode;
  19738. parent && parent.insertBefore(elem, parent.firstChild);
  19739. return this
  19740. },
  19741. toForeground: function() {
  19742. var elem = this.element,
  19743. parent = elem.parentNode;
  19744. parent && parent.appendChild(elem);
  19745. return this
  19746. },
  19747. css: baseCss,
  19748. attr: baseAttr,
  19749. sharp: function(pos) {
  19750. return this.attr({sharp: pos || true})
  19751. },
  19752. _applyTransformation: function() {
  19753. var tr = this._settings,
  19754. scaleXDefined,
  19755. scaleYDefined,
  19756. transformations = [],
  19757. rotateX,
  19758. rotateY,
  19759. sharpMode = tr.sharp,
  19760. strokeOdd = tr[KEY_STROKE_WIDTH] % 2,
  19761. correctionX = strokeOdd && (sharpMode === "h" || sharpMode === true) ? SHARPING_CORRECTION : 0,
  19762. correctionY = strokeOdd && (sharpMode === "v" || sharpMode === true) ? SHARPING_CORRECTION : 0;
  19763. if (!("rotateX" in tr))
  19764. rotateX = tr.x;
  19765. else
  19766. rotateX = tr.rotateX;
  19767. if (!("rotateY" in tr))
  19768. rotateY = tr.y;
  19769. else
  19770. rotateY = tr.rotateY;
  19771. transformations.push("translate(" + ((tr.translateX || 0) + correctionX) + "," + ((tr.translateY || 0) + correctionY) + ")");
  19772. if (tr.rotate)
  19773. transformations.push("rotate(" + tr.rotate + "," + (rotateX || 0) + "," + (rotateY || 0) + ")");
  19774. scaleXDefined = isDefined(tr.scaleX);
  19775. scaleYDefined = isDefined(tr.scaleY);
  19776. if (scaleXDefined || scaleYDefined)
  19777. transformations.push("scale(" + (scaleXDefined ? tr.scaleX : 1) + "," + (scaleYDefined ? tr.scaleY : 1) + ")");
  19778. if (transformations.length)
  19779. this.element.setAttribute("transform", transformations.join(" "))
  19780. },
  19781. move: function(x, y, animate, animOptions) {
  19782. var obj = {};
  19783. isDefined(x) && (obj.translateX = x);
  19784. isDefined(y) && (obj.translateY = y);
  19785. if (!animate)
  19786. this.attr(obj);
  19787. else
  19788. this.animate(obj, animOptions);
  19789. return this
  19790. },
  19791. rotate: function(angle, x, y, animate, animOptions) {
  19792. var obj = {rotate: angle || 0};
  19793. isDefined(x) && (obj.rotateX = x);
  19794. isDefined(y) && (obj.rotateY = y);
  19795. if (!animate)
  19796. this.attr(obj);
  19797. else
  19798. this.animate(obj, animOptions);
  19799. return this
  19800. },
  19801. getBBox: function() {
  19802. var elem = this.element,
  19803. transformation = this._settings,
  19804. bBox;
  19805. try {
  19806. bBox = elem.getBBox && elem.getBBox()
  19807. }
  19808. catch(e) {}
  19809. bBox = bBox || {
  19810. x: 0,
  19811. y: 0,
  19812. width: elem.offsetWidth || 0,
  19813. height: elem.offsetHeight || 0
  19814. };
  19815. if (transformation.rotate)
  19816. bBox = rotateBBox(bBox, [("rotateX" in transformation ? transformation.rotateX : transformation.x) || 0, ("rotateY" in transformation ? transformation.rotateY : transformation.y) || 0], -transformation.rotate);
  19817. else
  19818. bBox = normalizeBBox(bBox);
  19819. return bBox
  19820. },
  19821. markup: function() {
  19822. var temp = doc.createElement('div'),
  19823. node = this.element.cloneNode(true);
  19824. temp.appendChild(node);
  19825. return temp.innerHTML
  19826. },
  19827. getOffset: function() {
  19828. return this._$element.offset()
  19829. },
  19830. animate: baseAnimate,
  19831. stopAnimation: function(disableComplete) {
  19832. var animation = this.animation;
  19833. animation && animation.stop(true, disableComplete);
  19834. return this
  19835. },
  19836. setTitle: function(text) {
  19837. var titleElem = createElement('title');
  19838. titleElem.textContent = text || '';
  19839. this.element.appendChild(titleElem)
  19840. },
  19841. on: function() {
  19842. $.fn.on.apply(this._$element, arguments);
  19843. return this
  19844. },
  19845. off: function() {
  19846. $.fn.off.apply(this._$element, arguments);
  19847. return this
  19848. },
  19849. trigger: function() {
  19850. $.fn.trigger.apply(this._$element, arguments);
  19851. return this
  19852. },
  19853. data: function() {
  19854. $.fn.data.apply(this._$element, arguments);
  19855. return this
  19856. }
  19857. };
  19858. function SvgRenderer(options) {
  19859. var that = this;
  19860. that.root = that._createElement("svg", {
  19861. xmlns: "http://www.w3.org/2000/svg",
  19862. "xmlns:xlink": "http://www.w3.org/1999/xlink",
  19863. version: "1.1",
  19864. fill: NONE,
  19865. stroke: NONE,
  19866. "stroke-width": 0,
  19867. "class": options.cssClass
  19868. }).css({
  19869. "line-height": "normal",
  19870. "-ms-user-select": NONE,
  19871. "-moz-user-select": NONE,
  19872. "-webkit-user-select": NONE,
  19873. "-webkit-tap-highlight-color": "rgba(0, 0, 0, 0)",
  19874. display: "block",
  19875. overflow: "hidden"
  19876. });
  19877. that._defs = that._createElement("defs");
  19878. that._animationController = new rendererNS.AnimationController(that.root.element);
  19879. that._animation = {
  19880. enabled: true,
  19881. duration: 1000,
  19882. easing: "easeOutCubic"
  19883. }
  19884. }
  19885. rendererNS.SvgRenderer = SvgRenderer;
  19886. SvgRenderer.prototype = {
  19887. constructor: SvgRenderer,
  19888. setOptions: function(options) {
  19889. var that = this;
  19890. that.pathModified = !!options.pathModified;
  19891. that.rtl = !!options.rtl;
  19892. that.encodeHtml = !!options.encodeHtml,
  19893. that.updateAnimationOptions(options.animation || {});
  19894. that.root.attr({direction: that.rtl ? "rtl" : "ltr"})
  19895. },
  19896. _createElement: function(tagName, attr, type) {
  19897. var elem = new rendererNS.SvgElement(this, tagName, type);
  19898. attr && elem.attr(attr);
  19899. return elem
  19900. },
  19901. draw: function(container) {
  19902. var that = this;
  19903. if (!container || that.drawn)
  19904. return that;
  19905. that.root.append(container);
  19906. that._defs.append(that.root);
  19907. that.drawn = true;
  19908. return that
  19909. },
  19910. resize: function(width, height) {
  19911. if (width >= 0 && height >= 0)
  19912. this.root.attr({
  19913. width: width,
  19914. height: height
  19915. });
  19916. return this
  19917. },
  19918. clear: function() {
  19919. var that = this;
  19920. that.root.remove();
  19921. that._defs.remove();
  19922. that.drawn = null;
  19923. return this
  19924. },
  19925. dispose: function() {
  19926. var that = this,
  19927. key;
  19928. that.root.dispose();
  19929. that._defs.dispose();
  19930. that._animationController.dispose();
  19931. for (key in that)
  19932. that[key] = null;
  19933. return null
  19934. },
  19935. animationEnabled: function() {
  19936. return !!this._animation.enabled
  19937. },
  19938. updateAnimationOptions: function(newOptions) {
  19939. extend(this._animation, newOptions);
  19940. return this
  19941. },
  19942. stopAllAnimations: function(lock) {
  19943. this._animationController[lock ? "lock" : "stop"]();
  19944. return this
  19945. },
  19946. animateElement: function(element, params, options) {
  19947. this._animationController.animateElement(element, params, options);
  19948. return this
  19949. },
  19950. svg: function() {
  19951. return this.root.markup()
  19952. },
  19953. getRootOffset: function() {
  19954. return this.root.getOffset()
  19955. },
  19956. onEndAnimation: function(endAnimation) {
  19957. this._animationController.onEndAnimation(endAnimation)
  19958. },
  19959. rect: function(x, y, width, height) {
  19960. return this._createElement("rect", {
  19961. x: x || 0,
  19962. y: y || 0,
  19963. width: width || 0,
  19964. height: height || 0
  19965. })
  19966. },
  19967. circle: function(x, y, r) {
  19968. return this._createElement("circle", {
  19969. cx: x || 0,
  19970. cy: y || 0,
  19971. r: r || 0
  19972. })
  19973. },
  19974. g: function() {
  19975. return this._createElement("g")
  19976. },
  19977. image: function(x, y, w, h, href, location) {
  19978. var image = this._createElement("image", {
  19979. x: x || 0,
  19980. y: y || 0,
  19981. width: w || 0,
  19982. height: h || 0,
  19983. preserveAspectRatio: getPreserveAspectRatio(location)
  19984. });
  19985. image.element.setAttributeNS("http://www.w3.org/1999/xlink", "href", href || "");
  19986. return image
  19987. },
  19988. path: function(points, type) {
  19989. return this._createElement("path", {points: points || []}, type)
  19990. },
  19991. arc: function(x, y, innerRadius, outerRadius, startAngle, endAngle) {
  19992. return this._createElement("path", {
  19993. x: x || 0,
  19994. y: y || 0,
  19995. innerRadius: innerRadius || 0,
  19996. outerRadius: outerRadius || 0,
  19997. startAngle: startAngle || 0,
  19998. endAngle: endAngle || 0
  19999. }, "arc")
  20000. },
  20001. text: function(text, x, y) {
  20002. return this._createElement("text", {
  20003. text: text,
  20004. x: x || 0,
  20005. y: y || 0
  20006. })
  20007. },
  20008. pattern: function(color, hatching) {
  20009. hatching = hatching || {};
  20010. var that = this,
  20011. id,
  20012. d,
  20013. pattern,
  20014. rect,
  20015. path,
  20016. step = hatching.step || 6,
  20017. stepTo2 = step / 2,
  20018. stepBy15 = step * 1.5,
  20019. direction = (hatching.direction || "").toLowerCase();
  20020. if (direction !== "right" && direction !== "left")
  20021. return {
  20022. id: color,
  20023. append: function() {
  20024. return this
  20025. },
  20026. clear: function(){},
  20027. dispose: function(){},
  20028. remove: function(){}
  20029. };
  20030. id = getNextDefsSvgId();
  20031. d = direction === "right" ? "M " + stepTo2 + " " + -stepTo2 + " L " + -stepTo2 + " " + stepTo2 + " M 0 " + step + " L " + step + " 0 M " + stepBy15 + " " + stepTo2 + " L " + stepTo2 + " " + stepBy15 : "M 0 0 L " + step + " " + step + " M " + -stepTo2 + " " + stepTo2 + " L " + stepTo2 + " " + stepBy15 + " M " + stepTo2 + " " + -stepTo2 + " L " + stepBy15 + " " + stepTo2;
  20032. pattern = that._createElement("pattern", {
  20033. id: id,
  20034. width: step,
  20035. height: step,
  20036. patternUnits: "userSpaceOnUse"
  20037. }).append(that._defs);
  20038. pattern.id = getPatternUrl(id, that.pathModified);
  20039. rect = that.rect(0, 0, step, step).attr({
  20040. fill: color,
  20041. opacity: hatching.opacity
  20042. }).append(pattern);
  20043. path = that._createElement("path", {
  20044. d: d,
  20045. "stroke-width": hatching.width || 1,
  20046. stroke: color
  20047. }).append(pattern);
  20048. pattern.rect = rect;
  20049. pattern.path = path;
  20050. return pattern
  20051. },
  20052. clipRect: function(x, y, width, height) {
  20053. var that = this,
  20054. id = getNextDefsSvgId(),
  20055. clipPath = that._createElement("clipPath", {id: id}).append(that._defs),
  20056. rect = that.rect(x, y, width, height).append(clipPath);
  20057. rect.id = id;
  20058. rect.clipPath = clipPath;
  20059. rect.remove = function() {
  20060. throw"Not implemented";
  20061. };
  20062. rect.dispose = function() {
  20063. clipPath.dispose();
  20064. clipPath = null;
  20065. return this
  20066. };
  20067. return rect
  20068. },
  20069. shadowFilter: function(x, y, width, height, offsetX, offsetY, blur, color, opacity) {
  20070. var that = this,
  20071. id = getNextDefsSvgId(),
  20072. filter = that._createElement("filter", {
  20073. id: id,
  20074. x: x || 0,
  20075. y: y || 0,
  20076. width: width || 0,
  20077. height: height || 0
  20078. }).append(that._defs),
  20079. gaussianBlur = that._createElement("feGaussianBlur", {
  20080. "in": "SourceGraphic",
  20081. result: "gaussianBlurResult",
  20082. stdDeviation: blur || 0
  20083. }).append(filter),
  20084. offset = that._createElement("feOffset", {
  20085. "in": "gaussianBlurResult",
  20086. result: "offsetResult",
  20087. dx: offsetX || 0,
  20088. dy: offsetY || 0
  20089. }).append(filter),
  20090. flood = that._createElement("feFlood", {
  20091. result: "floodResult",
  20092. "flood-color": color || "",
  20093. "flood-opacity": opacity
  20094. }).append(filter),
  20095. composite = that._createElement("feComposite", {
  20096. "in": "floodResult",
  20097. in2: "offsetResult",
  20098. operator: "in",
  20099. result: "compositeResult"
  20100. }).append(filter),
  20101. finalComposite = that._createElement("feComposite", {
  20102. "in": "SourceGraphic",
  20103. in2: "compositeResult",
  20104. operator: "over"
  20105. }).append(filter);
  20106. filter.ref = getPatternUrl(id, that.pathModified);
  20107. filter.gaussianBlur = gaussianBlur;
  20108. filter.offset = offset;
  20109. filter.flood = flood;
  20110. filter.composite = composite;
  20111. filter.finalComposite = finalComposite;
  20112. filter.attr = function(attrs) {
  20113. var that = this,
  20114. filterAttrs = {},
  20115. offsetAttrs = {},
  20116. floodAttrs = {};
  20117. "x" in attrs && (filterAttrs.x = attrs.x);
  20118. "y" in attrs && (filterAttrs.y = attrs.y);
  20119. "width" in attrs && (filterAttrs.width = attrs.width);
  20120. "height" in attrs && (filterAttrs.height = attrs.height);
  20121. baseAttr.call(that, filterAttrs);
  20122. "blur" in attrs && that.gaussianBlur.attr({stdDeviation: attrs.blur});
  20123. "offsetX" in attrs && (offsetAttrs.dx = attrs.offsetX);
  20124. "offsetY" in attrs && (offsetAttrs.dy = attrs.offsetY);
  20125. that.offset.attr(offsetAttrs);
  20126. "color" in attrs && (floodAttrs["flood-color"] = attrs.color);
  20127. "opacity" in attrs && (floodAttrs["flood-opacity"] = attrs.opacity);
  20128. that.flood.attr(floodAttrs);
  20129. return that
  20130. };
  20131. return filter
  20132. }
  20133. };
  20134. rendererNS.rotateBBox = rotateBBox;
  20135. rendererNS._createArcAttr = createArcAttr;
  20136. rendererNS._createPathAttr = createPathAttr;
  20137. rendererNS._createRectAttr = createRectAttr
  20138. })(jQuery, DevExpress, document);
  20139. /*! Module viz-core, file vmlRenderer.js */
  20140. (function($, DX, doc) {
  20141. DX.viz.renderers = DX.viz.renderers || {};
  20142. var rendererNS = DX.viz.renderers,
  20143. math = Math,
  20144. mathMin = math.min,
  20145. mathMax = math.max,
  20146. mathFloor = math.floor,
  20147. mathSin = math.sin,
  20148. mathCos = math.cos,
  20149. baseElementPrototype = rendererNS.SvgElement.prototype,
  20150. documentFragment = doc.createDocumentFragment(),
  20151. DEFAULT_STYLE = {
  20152. behavior: "url(#default#VML)",
  20153. display: "inline-block",
  20154. position: "absolute"
  20155. },
  20156. DEFAULT_ATTRS = {xmlns: 'urn:schemas-microsoft-com:vml'},
  20157. INHERITABLE_PROPERTIES = {
  20158. stroke: true,
  20159. fill: true,
  20160. opacity: true,
  20161. 'stroke-width': true,
  20162. align: true,
  20163. dashStyle: true,
  20164. "stroke-opacity": true,
  20165. 'fill-opacity': true,
  20166. rotate: true,
  20167. rotateX: true,
  20168. rotateY: true
  20169. },
  20170. stub = function(){},
  20171. stubReturnedThis = function() {
  20172. return this
  20173. },
  20174. svgToVmlConv = {
  20175. circle: "oval",
  20176. g: "div",
  20177. path: "shape",
  20178. text: "span"
  20179. },
  20180. FONT_HEIGHT_OFFSET_K = 0.55 + 0.45 / 2,
  20181. DEFAULTS = {
  20182. scaleX: 1,
  20183. scaleY: 1
  20184. },
  20185. pathAttr = rendererNS._createPathAttr(vmlAttr),
  20186. arcAttr = rendererNS._createArcAttr(vmlAttr, buildArcPath),
  20187. rectAttr = rendererNS._createRectAttr(vmlAttr);
  20188. function isDefined(value) {
  20189. return value !== null && value !== undefined
  20190. }
  20191. function extend(a, b) {
  20192. for (var key in b)
  20193. a[key] = b[key];
  20194. return a
  20195. }
  20196. function inArray(array, elem) {
  20197. var i = 0;
  20198. for (; i < array.length; i++)
  20199. if (elem === array[i])
  20200. return i;
  20201. return -1
  20202. }
  20203. function buildArcPath(x, y, innerR, outerR, startAngleCos, startAngleSin, endAngleCos, endAngleSin, isCircle, longFlag, noArc) {
  20204. var xOuterStart = x + outerR * startAngleCos,
  20205. yOuterStart = y - outerR * startAngleSin,
  20206. xOuterEnd = x + outerR * endAngleCos,
  20207. yOuterEnd = y - outerR * endAngleSin,
  20208. xInnerStart = x + innerR * endAngleCos,
  20209. yInnerStart = y - innerR * endAngleSin,
  20210. xInnerEnd = x + innerR * startAngleCos,
  20211. yInnerEnd = y - innerR * startAngleSin;
  20212. return !noArc ? ['wr', mathFloor(x - innerR), mathFloor(y - innerR), mathFloor(x + innerR), mathFloor(y + innerR), mathFloor(xInnerStart), mathFloor(yInnerStart), mathFloor(xInnerEnd), mathFloor(yInnerEnd), isCircle ? 'wr ' : 'at ', mathFloor(x - outerR), mathFloor(y - outerR), mathFloor(x + outerR), mathFloor(y + outerR), mathFloor(xOuterStart), mathFloor(yOuterStart), mathFloor(xOuterEnd), mathFloor(yOuterEnd), 'x e'].join(" ") : "m 0 0 x e"
  20213. }
  20214. function getInheritSettings(settings) {
  20215. var result = {},
  20216. prop,
  20217. value;
  20218. for (prop in INHERITABLE_PROPERTIES) {
  20219. value = settings[prop];
  20220. value !== undefined && (result[prop] = value)
  20221. }
  20222. return result
  20223. }
  20224. function correctBoundingRectWithStrokeWidth(rect, strokeWidth) {
  20225. strokeWidth = Math.ceil(parseInt(strokeWidth) / 2);
  20226. if (strokeWidth && strokeWidth > 1) {
  20227. rect.left -= strokeWidth;
  20228. rect.top -= strokeWidth;
  20229. rect.right += strokeWidth;
  20230. rect.bottom += strokeWidth
  20231. }
  20232. return rect
  20233. }
  20234. function shapeBBox() {
  20235. var points = (this._settings.d || "").match(/[-0-9]+/g),
  20236. i,
  20237. value,
  20238. resultRect = {};
  20239. for (i = 0; i < points.length; i++) {
  20240. value = parseInt(points[i]);
  20241. if (i % 2) {
  20242. resultRect.top = resultRect.top === undefined || value < resultRect.top ? value : resultRect.top;
  20243. resultRect.bottom = resultRect.bottom === undefined || value > resultRect.bottom ? value : resultRect.bottom
  20244. }
  20245. else {
  20246. resultRect.left = resultRect.left === undefined || value < resultRect.left ? value : resultRect.left;
  20247. resultRect.right = resultRect.right === undefined || value > resultRect.right ? value : resultRect.right
  20248. }
  20249. }
  20250. resultRect.left = resultRect.left || 0;
  20251. resultRect.top = resultRect.top || 0;
  20252. resultRect.right = resultRect.right || 0;
  20253. resultRect.bottom = resultRect.bottom || 0;
  20254. return correctBoundingRectWithStrokeWidth(resultRect, this._fullSettings["stroke-width"])
  20255. }
  20256. function baseAttr(attrs, inh) {
  20257. var element = this.element,
  20258. settings = this._settings,
  20259. fullSettings = this._fullSettings,
  20260. value,
  20261. key,
  20262. params = {style: {}},
  20263. appliedAttr,
  20264. elem;
  20265. if (typeof attrs === "string") {
  20266. if (attrs in settings)
  20267. return settings[attrs];
  20268. if (attrs in DEFAULTS)
  20269. return DEFAULTS[attrs];
  20270. return 0
  20271. }
  20272. for (key in attrs) {
  20273. value = attrs[key];
  20274. if (value === undefined)
  20275. continue;
  20276. appliedAttr = fullSettings[key];
  20277. !inh && (settings[key] = value);
  20278. fullSettings[key] = value;
  20279. if (INHERITABLE_PROPERTIES[key])
  20280. value = value === null ? this._parent && this._parent._fullSettings[key] || value : value;
  20281. appliedAttr !== value && this.processAttr(element, key, value, params)
  20282. }
  20283. this._applyTransformation(params);
  20284. this.css(params.style);
  20285. for (var i = 0; i < this._children.length; i++) {
  20286. elem = this._children[i];
  20287. elem !== this._clipRect && elem.attr(extend(getInheritSettings(this._fullSettings), elem._settings), true);
  20288. elem._applyStyleSheet()
  20289. }
  20290. !inh && this._applyStyleSheet();
  20291. return this
  20292. }
  20293. function vmlAttr() {
  20294. var elem = this.element,
  20295. result = baseAttr.apply(this, arguments);
  20296. for (var i = 0; i < elem.childNodes.length; i++) {
  20297. elem.childNodes[i].xmlns = 'urn:schemas-microsoft-com:vml';
  20298. elem.childNodes[i].style.behavior = "url(#default#VML)";
  20299. elem.childNodes[i].style.display = "inline-block"
  20300. }
  20301. return result
  20302. }
  20303. function processVmlAttr(element, attr, value, params) {
  20304. switch (attr) {
  20305. case"stroke":
  20306. value = value || "none";
  20307. element.stroked = value === 'none' ? 'f' : 't';
  20308. attr += "color";
  20309. break;
  20310. case"fill":
  20311. value = value || "none";
  20312. element.filled = value === 'none' ? 'f' : 't';
  20313. attr += "color";
  20314. break;
  20315. case"stroke-width":
  20316. attr = "strokeweight";
  20317. value = value + 'px';
  20318. break;
  20319. case"stroke-linejoin":
  20320. element.stroke.joinstyle = value;
  20321. return;
  20322. case"stroke-linecap":
  20323. element.stroke.endcap = value === "butt" ? "flat" : value;
  20324. return;
  20325. case"opacity":
  20326. value = adjustOpacityValue(value);
  20327. element.fill.opacity = value;
  20328. element.stroke.opacity = value;
  20329. return;
  20330. case"fill-opacity":
  20331. element.fill.opacity = adjustOpacityValue(value);
  20332. return;
  20333. case"stroke-opacity":
  20334. element.stroke.opacity = adjustOpacityValue(value);
  20335. return;
  20336. case"dashStyle":
  20337. if (value === null)
  20338. element.stroke[attr] = "";
  20339. else {
  20340. value = value.toLowerCase();
  20341. if (value === "solid" || value === "none")
  20342. value = "";
  20343. else
  20344. value = value.replace(/longdash/g, "8,3,").replace(/dash/g, "4,3,").replace(/dot/g, "1,3,").replace(/,$/, "");
  20345. element.stroke[attr] = value
  20346. }
  20347. return;
  20348. case"d":
  20349. attr = "path";
  20350. value = (value + '').toLowerCase().replace("z", "x e").replace(/([.]\d+)/g, "");
  20351. break;
  20352. case"href":
  20353. attr = "src";
  20354. break;
  20355. case"width":
  20356. case"height":
  20357. case"visibility":
  20358. params.style[attr] = value || "";
  20359. return;
  20360. case"class":
  20361. attr += "Name";
  20362. break;
  20363. case"translateX":
  20364. case"translateY":
  20365. case"rotate":
  20366. case"rotateX":
  20367. case"rotateY":
  20368. case"scale":
  20369. case"scaleX":
  20370. case"scaleY":
  20371. case"x":
  20372. case"y":
  20373. return
  20374. }
  20375. element[attr] = value
  20376. }
  20377. function adjustOpacityValue(value) {
  20378. return value >= 0.002 ? value : value === null ? 1 : 0.002
  20379. }
  20380. function createElement(tagName) {
  20381. var element = document.createElement(tagName);
  20382. return documentFragment.appendChild(element)
  20383. }
  20384. var VmlElement = function() {
  20385. this.ctor.apply(this, arguments)
  20386. };
  20387. function processAttr(element, attr, value, params) {
  20388. if (!INHERITABLE_PROPERTIES[attr])
  20389. if (attr === "visibility")
  20390. params.style[attr] = value || "";
  20391. else if (attr === "width" || attr === "height")
  20392. params.style[attr] = value;
  20393. else if (attr === "clipId")
  20394. this.applyClipID(value);
  20395. else if (attr === "translateX" || attr === "translateY" || attr === "x" || attr === "y")
  20396. return;
  20397. else if (attr === "class")
  20398. element.className = value;
  20399. else
  20400. element[attr] = value
  20401. }
  20402. var elementMixin = {
  20403. div: {
  20404. processAttr: processAttr,
  20405. attr: baseAttr,
  20406. _applyTransformation: function(params) {
  20407. var style = params.style,
  20408. settings = this._settings,
  20409. fullSettings = this._fullSettings;
  20410. if (fullSettings.rotate) {
  20411. fullSettings.rotateX = fullSettings.rotateX || 0;
  20412. fullSettings.rotateY = fullSettings.rotateY || 0
  20413. }
  20414. style.left = (settings.x || 0) + (settings.translateX || 0);
  20415. style.top = (settings.y || 0) + (settings.translateY || 0)
  20416. },
  20417. _getBBox: function() {
  20418. var left = Infinity,
  20419. top = Infinity,
  20420. right = -Infinity,
  20421. bottom = -Infinity,
  20422. i = 0,
  20423. child,
  20424. children = this._children,
  20425. translateX,
  20426. translateY,
  20427. childBBox,
  20428. childSettings;
  20429. if (!children.length)
  20430. left = top = bottom = right = 0;
  20431. else
  20432. for (; i < children.length; i++) {
  20433. child = children[i];
  20434. if (child === this._clipRect)
  20435. continue;
  20436. translateX = child._fullSettings.translateX || 0;
  20437. translateY = child._fullSettings.translateY || 0;
  20438. childSettings = child._fullSettings;
  20439. childBBox = child._getBBox();
  20440. left = mathMin(left, childBBox.left + translateX);
  20441. right = mathMax(right, childBBox.right + translateX);
  20442. top = mathMin(top, childBBox.top + translateY);
  20443. bottom = mathMax(bottom, childBBox.bottom + translateY)
  20444. }
  20445. return {
  20446. left: left,
  20447. right: right,
  20448. top: top,
  20449. bottom: bottom
  20450. }
  20451. },
  20452. defaultAttrs: {},
  20453. defaultStyle: {position: "absolute"}
  20454. },
  20455. shape: {
  20456. defaultAttrs: extend({
  20457. coordsize: "1,1",
  20458. "stroke-linejoin": "miter"
  20459. }, DEFAULT_ATTRS),
  20460. defaultStyle: extend({
  20461. width: 1,
  20462. height: 1
  20463. }, DEFAULT_STYLE),
  20464. _getBBox: shapeBBox
  20465. },
  20466. image: {processAttr: function(element, attr, value, params) {
  20467. if (attr === "fill" || attr === "stroke")
  20468. return;
  20469. processVmlAttr(element, attr, value, params)
  20470. }},
  20471. oval: {
  20472. processAttr: function(element, attr, value, params) {
  20473. if (attr === "cx" || attr === "cy")
  20474. attr = attr[1];
  20475. else if (attr === "r") {
  20476. value *= 2;
  20477. processVmlAttr(element, "width", value, params);
  20478. attr = "height"
  20479. }
  20480. else if (attr === "x" || attr === "y")
  20481. return;
  20482. processVmlAttr(element, attr, value, params)
  20483. },
  20484. _getBBox: function() {
  20485. var settings = this._fullSettings,
  20486. x = settings.cx || 0,
  20487. y = settings.cy || 0,
  20488. r = settings.r || 0;
  20489. return correctBoundingRectWithStrokeWidth({
  20490. left: x - r,
  20491. top: y - r,
  20492. right: x + r,
  20493. bottom: y + r
  20494. }, settings["stroke-width"] || 1)
  20495. }
  20496. },
  20497. span: {
  20498. defaultAttrs: {},
  20499. defaultStyle: {
  20500. position: 'absolute',
  20501. whiteSpace: 'nowrap'
  20502. },
  20503. processAttr: function(element, attr, value, params) {
  20504. if (attr === "text") {
  20505. value = isDefined(value) ? value.toString().replace(/\r/g, "") : "";
  20506. if (this.renderer.encodeHtml)
  20507. value = value.replace(/</g, "&lt;").replace(/>/g, "&gt;");
  20508. element.innerHTML = value.replace(/\n/g, "<br/>");
  20509. this.css({filter: ""});
  20510. this._bbox = null
  20511. }
  20512. else
  20513. processAttr(element, attr, value, params)
  20514. },
  20515. attr: baseAttr,
  20516. _applyTransformation: function(params) {
  20517. this.element.offsetHeight;
  20518. var that = this,
  20519. style = params.style,
  20520. settings = that._fullSettings,
  20521. x = isDefined(settings.x) ? settings.x : 0,
  20522. y = isDefined(settings.y) ? settings.y : 0,
  20523. bbox = that._bbox || that.element.getBoundingClientRect(),
  20524. textHeight = bbox.bottom - bbox.top,
  20525. textWidth = bbox.right - bbox.left,
  20526. rotateAngle = settings.rotate,
  20527. cos = 1,
  20528. sin = 0,
  20529. rotateX = isDefined(settings.rotateX) ? settings.rotateX : x,
  20530. rotateY = isDefined(settings.rotateY) ? settings.rotateY : y,
  20531. radianAngle,
  20532. marginLeft = 0,
  20533. marginTop = 0,
  20534. fontHeightOffset = textHeight * FONT_HEIGHT_OFFSET_K,
  20535. filter = "",
  20536. alignMultiplier = {
  20537. center: 0.5,
  20538. right: 1
  20539. }[settings.align],
  20540. opacity = this._styles.opacity || settings.opacity || settings["fill-opacity"];
  20541. if (textHeight && textWidth) {
  20542. if (rotateAngle) {
  20543. radianAngle = rotateAngle * Math.PI / 180.0;
  20544. cos = mathCos(radianAngle);
  20545. sin = mathSin(radianAngle);
  20546. marginLeft = (x - rotateX) * cos - (y - rotateY) * sin + rotateX - x;
  20547. marginTop = (x - rotateX) * sin + (y - rotateY) * cos + rotateY - y;
  20548. filter = 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod="auto expand", M11 = ' + cos.toFixed(5) + ', M12 = ' + (-sin).toFixed(5) + ', M21 = ' + sin.toFixed(5) + ', M22 = ' + cos.toFixed(5) + ')'
  20549. }
  20550. if (rotateAngle < 90) {
  20551. marginTop -= fontHeightOffset * cos;
  20552. marginLeft -= (textHeight - fontHeightOffset) * sin
  20553. }
  20554. else if (rotateAngle < 180) {
  20555. marginTop += (textHeight - fontHeightOffset) * cos;
  20556. marginLeft += textWidth * cos - (textHeight - fontHeightOffset) * sin
  20557. }
  20558. else if (rotateAngle < 270) {
  20559. marginTop += (textHeight - fontHeightOffset) * cos + textWidth * sin;
  20560. marginLeft += textWidth * cos + fontHeightOffset * sin
  20561. }
  20562. else {
  20563. marginTop += textWidth * sin - fontHeightOffset * cos;
  20564. marginLeft += fontHeightOffset * sin
  20565. }
  20566. if (rotateAngle && this.renderer.rtl)
  20567. marginLeft -= textWidth - (textHeight * Math.abs(sin) + textWidth * Math.abs(cos));
  20568. if (alignMultiplier) {
  20569. marginLeft -= textWidth * alignMultiplier * cos;
  20570. marginTop -= textWidth * alignMultiplier * sin
  20571. }
  20572. if (isDefined(opacity))
  20573. filter += " progid:DXImageTransform.Microsoft.Alpha(Opacity=" + opacity * 100 + ")";
  20574. x += marginLeft;
  20575. y += marginTop;
  20576. this._bbox = bbox;
  20577. style.filter = (style.filter || "") + filter;
  20578. style.left = x + (settings.translateX || 0);
  20579. style.top = y + (settings.translateY || 0)
  20580. }
  20581. },
  20582. _getBBox: function textBBox() {
  20583. var element = this.element,
  20584. settings = this._fullSettings,
  20585. parentRect = (element.parentNode && element.parentNode.getBoundingClientRect ? element.parentNode : this.renderer.root.element).getBoundingClientRect(),
  20586. boundingRect = element.getBoundingClientRect(),
  20587. left = boundingRect.left - (settings.translateX || 0) - parentRect.left,
  20588. top = boundingRect.top - (settings.translateY || 0) - parentRect.top;
  20589. return {
  20590. left: left,
  20591. top: top,
  20592. right: left + element.offsetWidth,
  20593. bottom: top + element.offsetHeight
  20594. }
  20595. }
  20596. }
  20597. };
  20598. extend(VmlElement.prototype, baseElementPrototype);
  20599. extend(VmlElement.prototype, {
  20600. defaultStyle: DEFAULT_STYLE,
  20601. defaultAttrs: DEFAULT_ATTRS,
  20602. ctor: function(renderer, tagName, type) {
  20603. var that = this,
  20604. tagPrefix = '<';
  20605. that.renderer = renderer;
  20606. that.type = type;
  20607. that._children = [];
  20608. that._settings = {};
  20609. that._fullSettings = {};
  20610. that._styles = {};
  20611. if (tagName !== "div" && tagName !== "span")
  20612. tagPrefix = "<vml:";
  20613. if (tagName === "shape")
  20614. if (that.type === "arc")
  20615. that.attr = arcAttr;
  20616. else
  20617. that.attr = pathAttr;
  20618. else if (tagName === "rect")
  20619. that.attr = rectAttr;
  20620. extend(that, elementMixin[tagName]);
  20621. that.element = createElement(tagPrefix + tagName + "/>");
  20622. that.css(that.defaultStyle).attr(that.defaultAttrs);
  20623. that._$element = $(that.element)
  20624. },
  20625. dispose: function() {
  20626. this.remove();
  20627. this._$element.remove();
  20628. return this
  20629. },
  20630. attr: vmlAttr,
  20631. processAttr: processVmlAttr,
  20632. css: function(css) {
  20633. var elem = this.element,
  20634. value,
  20635. appliedValue,
  20636. key;
  20637. for (key in css) {
  20638. appliedValue = this._styles[key];
  20639. value = css[key];
  20640. if (!isDefined(value))
  20641. continue;
  20642. this._styles[key] = value;
  20643. if (appliedValue === value)
  20644. continue;
  20645. switch (key) {
  20646. case"fill":
  20647. key = "color";
  20648. break;
  20649. case"font-size":
  20650. key = "fontSize";
  20651. if (typeof value === "number")
  20652. value += "px";
  20653. break;
  20654. case"font-weight":
  20655. key = "fontWeight";
  20656. break;
  20657. case"z-index":
  20658. key = "zIndex";
  20659. break;
  20660. case"opacity":
  20661. continue
  20662. }
  20663. try {
  20664. elem.style[key] = value
  20665. }
  20666. catch(_) {
  20667. continue
  20668. }
  20669. }
  20670. return this
  20671. },
  20672. applyClipID: function(id) {
  20673. var clipRect,
  20674. cssValue,
  20675. renderer = this.renderer;
  20676. clipRect = renderer.getClipRect(id);
  20677. if (clipRect) {
  20678. cssValue = clipRect.getValue();
  20679. clipRect.addElement(this)
  20680. }
  20681. else
  20682. cssValue = "rect(-9999px 9999px 9999px -9999px)";
  20683. this._clipRect = this._clipRect || renderer.rect(0, 0, 0, 0).attr({
  20684. "class": "dxc-vml-clip",
  20685. fill: "none",
  20686. opacity: 0.001
  20687. });
  20688. this._clipRect.attr({
  20689. width: renderer.root.attr("width"),
  20690. height: renderer.root.attr("height")
  20691. });
  20692. this.css({
  20693. clip: cssValue,
  20694. width: renderer.root.attr("width"),
  20695. height: renderer.root.attr("height")
  20696. })
  20697. },
  20698. append: function(parent) {
  20699. parent = parent || this.renderer.root;
  20700. (parent.element || parent).appendChild(this.element);
  20701. if (parent._children) {
  20702. this._parent = parent;
  20703. if (inArray(parent._children, this) === -1)
  20704. parent._children.push(this);
  20705. this.attr(extend(getInheritSettings(parent._fullSettings), this._settings), true)
  20706. }
  20707. this._applyStyleSheet();
  20708. if (parent._clipRect && this !== parent._clipRect)
  20709. parent._clipRect.append(parent);
  20710. return this
  20711. },
  20712. _applyTransformation: function(params) {
  20713. var that = this,
  20714. style = params.style,
  20715. element = that.element,
  20716. settings = that._fullSettings,
  20717. x = that.type !== "arc" ? settings.x || settings.cx - settings.r || 0 : 0,
  20718. y = that.type !== "arc" ? settings.y || settings.cy - settings.r || 0 : 0;
  20719. if (settings.rotate) {
  20720. var radianAngle = settings.rotate * Math.PI / 180.0,
  20721. rotateX = isDefined(settings.rotateX) ? settings.rotateX : x,
  20722. rotateY = isDefined(settings.rotateY) ? settings.rotateY : y,
  20723. rx = x + (settings.width || 0 || parseInt(element.style.width || 0)) / 2,
  20724. ry = y + (settings.height || 0 || parseInt(element.style.height || 0)) / 2,
  20725. cos = mathCos(radianAngle),
  20726. sin = mathSin(radianAngle),
  20727. marginLeft = (rx - rotateX) * cos - (ry - rotateY) * sin + rotateX - rx,
  20728. marginTop = (rx - rotateX) * sin + (ry - rotateY) * cos + rotateY - ry;
  20729. x += marginLeft;
  20730. y += marginTop;
  20731. style.rotation = settings.rotate
  20732. }
  20733. style.left = x + (settings.translateX || 0);
  20734. style.top = y + (settings.translateY || 0)
  20735. },
  20736. remove: function() {
  20737. var that = this,
  20738. parent = that._parent;
  20739. if (parent)
  20740. parent._children.splice(inArray(parent._children, that), 1);
  20741. that._parent = null;
  20742. return baseElementPrototype.remove.call(that)
  20743. },
  20744. clear: function() {
  20745. this._children = [];
  20746. return baseElementPrototype.clear.call(this)
  20747. },
  20748. getBBox: function() {
  20749. var clientRect = this._getBBox(),
  20750. x = clientRect.left,
  20751. y = clientRect.top,
  20752. width = clientRect.right - x,
  20753. height = clientRect.bottom - y;
  20754. return {
  20755. x: x,
  20756. y: y,
  20757. width: width,
  20758. height: height,
  20759. isEmpty: !x && !y && !width && !height
  20760. }
  20761. },
  20762. _getBBox: function() {
  20763. var element = this.element,
  20764. settings = this._fullSettings,
  20765. x = settings.x || 0,
  20766. y = settings.y || 0,
  20767. width = parseInt(element.style.width || 0),
  20768. height = parseInt(element.style.height || 0);
  20769. return correctBoundingRectWithStrokeWidth({
  20770. left: x,
  20771. top: y,
  20772. right: x + width,
  20773. bottom: y + height
  20774. }, settings["stroke-width"] || 1)
  20775. },
  20776. _applyStyleSheet: function() {
  20777. if (this._useCSSTheme)
  20778. this.attr(getInheritSettings(this.element.currentStyle), true)
  20779. },
  20780. setTitle: function(text) {
  20781. this.element.setAttribute('title', text)
  20782. }
  20783. });
  20784. var ClipRect = function() {
  20785. this.ctor.apply(this, arguments)
  20786. };
  20787. extend(ClipRect.prototype, VmlElement.prototype);
  20788. extend(ClipRect.prototype, {
  20789. ctor: function(renderer, id) {
  20790. this._settings = this._fullSettings = {};
  20791. this.renderer = renderer;
  20792. this._children = [];
  20793. this._elements = [];
  20794. this.id = id
  20795. },
  20796. attr: function() {
  20797. var result = baseAttr.apply(this, arguments),
  20798. elements = this._elements.slice(),
  20799. element,
  20800. i;
  20801. if (result === this)
  20802. for (i = 0; i < elements.length; i++) {
  20803. element = elements[i];
  20804. if (element._fullSettings.clipId === this.id)
  20805. elements[i].applyClipID(this.id);
  20806. else
  20807. this.removeElement(element)
  20808. }
  20809. return result
  20810. },
  20811. processAttr: stub,
  20812. _applyTransformation: stub,
  20813. append: stubReturnedThis,
  20814. dispose: function() {
  20815. this._elements = null;
  20816. this.renderer.removeClipRect(this.id);
  20817. return this
  20818. },
  20819. addElement: function(element) {
  20820. var elements = this._elements;
  20821. if (inArray(elements, element) === -1)
  20822. elements.push(element)
  20823. },
  20824. removeElement: function(element) {
  20825. var index = inArray(this._elements, element);
  20826. index > -1 && this._elements.splice(index, 1)
  20827. },
  20828. getValue: function() {
  20829. var settings = this._settings,
  20830. left = (settings.x || 0) + (settings.translateX || 0),
  20831. top = (settings.y || 0) + (settings.translateY || 0);
  20832. return "rect(" + top + "px, " + (left + (settings.width || 0)) + "px, " + (top + (settings.height || 0)) + "px, " + left + "px)"
  20833. },
  20834. css: stubReturnedThis,
  20835. remove: stubReturnedThis
  20836. });
  20837. var VmlRenderer = function(options) {
  20838. var that = this;
  20839. that.root = that._createElement("div", {
  20840. fill: "none",
  20841. stroke: "none",
  20842. "stroke-width": 0
  20843. }).css({
  20844. position: "relative",
  20845. display: "inline-block",
  20846. overflow: "hidden"
  20847. });
  20848. that._clipRects = [];
  20849. that._animation = {enabled: false};
  20850. that._defs = {
  20851. clear: stubReturnedThis,
  20852. remove: stubReturnedThis,
  20853. append: stubReturnedThis,
  20854. dispose: stubReturnedThis
  20855. };
  20856. that.setOptions(options)
  20857. };
  20858. extend(VmlRenderer.prototype, rendererNS.SvgRenderer.prototype);
  20859. extend(VmlRenderer.prototype, {
  20860. constructor: VmlRenderer,
  20861. setOptions: function() {
  20862. rendererNS.SvgRenderer.prototype.setOptions.apply(this, arguments);
  20863. this.root.css({direction: this.rtl ? "rtl" : "ltr"})
  20864. },
  20865. _createElement: function(tagName, attr, type) {
  20866. tagName = svgToVmlConv[tagName] || tagName;
  20867. var elem = new rendererNS.VmlElement(this, tagName, type);
  20868. attr && elem.attr(attr);
  20869. return elem
  20870. },
  20871. dispose: function() {
  20872. this.root.dispose();
  20873. return null
  20874. },
  20875. shadowFilter: function() {
  20876. return {
  20877. ref: null,
  20878. append: stubReturnedThis,
  20879. dispose: stubReturnedThis,
  20880. attr: stubReturnedThis,
  20881. css: stubReturnedThis
  20882. }
  20883. },
  20884. clipRect: function(x, y, width, height) {
  20885. var clipRects = this._clipRects,
  20886. id = clipRects.length,
  20887. clipRect = new ClipRect(this, id).attr({
  20888. x: x || 0,
  20889. y: y || 0,
  20890. width: width || 0,
  20891. height: height || 0
  20892. });
  20893. clipRects.push(clipRect);
  20894. return clipRect
  20895. },
  20896. getClipRect: function(id) {
  20897. return this._clipRects[id]
  20898. },
  20899. removeClipRect: function(id) {
  20900. delete this._clipRects[id]
  20901. },
  20902. pattern: function(color) {
  20903. return {
  20904. id: color,
  20905. append: stubReturnedThis,
  20906. remove: stubReturnedThis,
  20907. dispose: stubReturnedThis
  20908. }
  20909. },
  20910. image: function(x, y, w, h, href, location) {
  20911. var image = this._createElement("image", {
  20912. x: x || 0,
  20913. y: y || 0,
  20914. width: w || 0,
  20915. height: h || 0,
  20916. location: location,
  20917. href: href
  20918. });
  20919. return image
  20920. },
  20921. updateAnimationOptions: stubReturnedThis,
  20922. stopAllAnimations: stubReturnedThis,
  20923. svg: function() {
  20924. return ""
  20925. },
  20926. onEndAnimation: function(callback) {
  20927. callback()
  20928. }
  20929. });
  20930. rendererNS.VmlRenderer = VmlRenderer;
  20931. rendererNS.VmlElement = VmlElement;
  20932. rendererNS._VmlClipRect = ClipRect
  20933. })(jQuery, DevExpress, document);
  20934. /*! Module viz-core, file animation.js */
  20935. (function(DX) {
  20936. var rendererNS = DX.viz.renderers,
  20937. noop = function(){},
  20938. easingFunctions = {
  20939. easeOutCubic: function(pos, start, end) {
  20940. return pos === 1 ? end : (1 - Math.pow(1 - pos, 3)) * (end - start) + +start
  20941. },
  20942. linear: function(pos, start, end) {
  20943. return pos === 1 ? end : pos * (end - start) + +start
  20944. }
  20945. };
  20946. rendererNS.easingFunctions = easingFunctions;
  20947. rendererNS.animationSvgStep = {
  20948. segments: function(elem, params, progress, easing, currentParams) {
  20949. var from = params.from,
  20950. to = params.to,
  20951. curSeg,
  20952. seg,
  20953. i,
  20954. j,
  20955. segments = [];
  20956. for (i = 0; i < from.length; i++) {
  20957. curSeg = from[i];
  20958. seg = [curSeg[0]];
  20959. if (curSeg.length > 1)
  20960. for (j = 1; j < curSeg.length; j++)
  20961. seg.push(easing(progress, curSeg[j], to[i][j]));
  20962. segments.push(seg)
  20963. }
  20964. currentParams.segments = params.end && progress === 1 ? params.end : segments;
  20965. elem.attr({segments: segments})
  20966. },
  20967. arc: function(elem, params, progress, easing) {
  20968. var from = params.from,
  20969. to = params.to,
  20970. current = {};
  20971. for (var i in from)
  20972. current[i] = easing(progress, from[i], to[i]);
  20973. elem.attr(current)
  20974. },
  20975. transform: function(elem, params, progress, easing, currentParams) {
  20976. var from = params.from,
  20977. to = params.to,
  20978. current = {};
  20979. for (var i in from)
  20980. current[i] = currentParams[i] = easing(progress, from[i], to[i]);
  20981. elem.attr(current)
  20982. },
  20983. base: function(elem, params, progress, easing, currentParams, attributeName) {
  20984. var obj = {};
  20985. obj[attributeName] = currentParams[attributeName] = easing(progress, params.from, params.to);
  20986. elem.attr(obj)
  20987. },
  20988. _: noop,
  20989. complete: function(element, currentSettings) {
  20990. element.attr(currentSettings)
  20991. }
  20992. };
  20993. function Animation(element, params, options) {
  20994. var that = this;
  20995. that._progress = 0;
  20996. that.element = element;
  20997. that.params = params;
  20998. that.options = options;
  20999. that.duration = options.partitionDuration ? options.duration * options.partitionDuration : options.duration;
  21000. that._animateStep = options.animateStep || rendererNS.animationSvgStep;
  21001. that._easing = easingFunctions[options.easing] || easingFunctions["easeOutCubic"];
  21002. that._currentParams = {};
  21003. that.tick = that._start
  21004. }
  21005. Animation.prototype = {
  21006. _calcProgress: function(now) {
  21007. return Math.min(1, (now - this._startTime) / this.duration)
  21008. },
  21009. _step: function(now) {
  21010. var that = this,
  21011. animateStep = that._animateStep,
  21012. attrName;
  21013. that._progress = that._calcProgress(now);
  21014. for (attrName in that.params) {
  21015. var anim = animateStep[attrName] || animateStep.base;
  21016. anim(that.element, that.params[attrName], that._progress, that._easing, that._currentParams, attrName)
  21017. }
  21018. that.options.step && that.options.step(that._easing(that._progress, 0, 1), that._progress);
  21019. if (that._progress === 1)
  21020. return that.stop();
  21021. return true
  21022. },
  21023. _start: function(now) {
  21024. this._startTime = now;
  21025. this.tick = this._step;
  21026. return true
  21027. },
  21028. _end: function(disableComplete) {
  21029. var that = this;
  21030. that.stop = noop;
  21031. that.tick = noop;
  21032. that._animateStep.complete && that._animateStep.complete(that.element, that._currentParams);
  21033. that.options.complete && !disableComplete && that.options.complete()
  21034. },
  21035. tick: function() {
  21036. return true
  21037. },
  21038. stop: function(breakAnimation, disableComplete) {
  21039. var that = this,
  21040. options = that.options;
  21041. if (!breakAnimation && options.repeatCount && --options.repeatCount > 0) {
  21042. that.tick = that._start;
  21043. return true
  21044. }
  21045. else
  21046. that._end(disableComplete)
  21047. }
  21048. };
  21049. function AnimationController(element) {
  21050. var that = this;
  21051. that._animationCount = 0;
  21052. that._timerId = null;
  21053. that._animations = {};
  21054. that.element = element
  21055. }
  21056. rendererNS.AnimationController = AnimationController;
  21057. AnimationController.prototype = {
  21058. _loop: function() {
  21059. var that = this,
  21060. animations = that._animations,
  21061. activeAnimation = 0,
  21062. now = (new Date).getTime(),
  21063. an,
  21064. endAnimation = that._endAnimation;
  21065. for (an in animations) {
  21066. if (!animations[an].tick(now))
  21067. delete animations[an];
  21068. activeAnimation++
  21069. }
  21070. if (activeAnimation === 0) {
  21071. that.stop();
  21072. that._endAnimationTimer = endAnimation && setTimeout(function() {
  21073. if (that._animationCount === 0) {
  21074. endAnimation();
  21075. that._endAnimation = null
  21076. }
  21077. });
  21078. return
  21079. }
  21080. that._timerId = DX.requestAnimationFrame.call(null, function() {
  21081. that._loop()
  21082. }, that.element)
  21083. },
  21084. addAnimation: function(animation) {
  21085. var that = this;
  21086. that._animations[that._animationCount++] = animation;
  21087. clearTimeout(that._endAnimationTimer);
  21088. if (!that._timerId) {
  21089. clearTimeout(that._startDelay);
  21090. that._startDelay = setTimeout(function() {
  21091. that._timerId = 1;
  21092. that._loop()
  21093. }, 0)
  21094. }
  21095. },
  21096. animateElement: function(elem, params, options) {
  21097. if (elem && params && options) {
  21098. elem.animation && elem.animation.stop(true);
  21099. this.addAnimation(elem.animation = new Animation(elem, params, options))
  21100. }
  21101. },
  21102. onEndAnimation: function(endAnimation) {
  21103. this._animationCount ? this._endAnimation = endAnimation : endAnimation()
  21104. },
  21105. dispose: function() {
  21106. this.stop();
  21107. this.element = null
  21108. },
  21109. stop: function() {
  21110. var that = this;
  21111. that._animations = {};
  21112. that._animationCount = 0;
  21113. DX.cancelAnimationFrame(that._timerId);
  21114. clearTimeout(that._startDelay);
  21115. clearTimeout(that._endAnimationTimer);
  21116. that._timerId = null
  21117. },
  21118. lock: function() {
  21119. var an,
  21120. animations = this._animations;
  21121. for (an in animations)
  21122. animations[an].stop(true, true);
  21123. this.stop()
  21124. }
  21125. };
  21126. rendererNS.Animation = Animation;
  21127. rendererNS.noop = noop
  21128. })(DevExpress);
  21129. /*! Module viz-core, file renderer.js */
  21130. (function($, DX, document) {
  21131. var renderers = DX.viz.renderers,
  21132. browser = DX.browser;
  21133. function isSvg() {
  21134. return !(browser.msie && browser.version < 9) || !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect
  21135. }
  21136. if (!isSvg()) {
  21137. if (document.namespaces && !document.namespaces.vml) {
  21138. document.namespaces.add('vml', 'urn:schemas-microsoft-com:vml');
  21139. document.createStyleSheet().cssText = 'vml\\:* { behavior:url(#default#VML); display: inline-block; } '
  21140. }
  21141. renderers.Renderer = renderers.VmlRenderer
  21142. }
  21143. else
  21144. renderers.Renderer = renderers.SvgRenderer;
  21145. renderers.isSvg = isSvg
  21146. })(jQuery, DevExpress, document);
  21147. /*! Module viz-core, file seriesConsts.js */
  21148. (function(DX) {
  21149. DX.viz.core.series = DX.viz.core.series || {};
  21150. DX.viz.core.series.helpers = DX.viz.core.series.helpers || {};
  21151. DX.viz.core.series.helpers.consts = {
  21152. events: {
  21153. mouseover: "mouseover",
  21154. mouseout: "mouseout",
  21155. mousemove: "mousemove",
  21156. touchstart: "touchstart",
  21157. touchmove: "touchmove",
  21158. touchend: "touchend",
  21159. mousedown: "mousedown",
  21160. mouseup: "mouseup",
  21161. click: "click",
  21162. selectSeries: "selectseries",
  21163. deselectSeries: "deselectseries",
  21164. selectPoint: "selectpoint",
  21165. deselectPoint: "deselectpoint",
  21166. showPointTooltip: "showpointtooltip",
  21167. hidePointTooltip: "hidepointtooltip"
  21168. },
  21169. states: {
  21170. hover: "hover",
  21171. normal: "normal",
  21172. selected: "selected",
  21173. normalMark: 0,
  21174. hoverMark: 1,
  21175. selectedMark: 2
  21176. },
  21177. animations: {
  21178. showDuration: {duration: 400},
  21179. hideGroup: {opacity: 0.0001},
  21180. showGroup: {opacity: 1}
  21181. },
  21182. pieLabelIndent: 30
  21183. }
  21184. })(DevExpress);
  21185. /*! Module viz-core, file seriesFamily.js */
  21186. (function($, DX, undefined) {
  21187. var utils = DX.utils,
  21188. _math = Math,
  21189. _round = _math.round,
  21190. _abs = _math.abs,
  21191. _pow = _math.pow,
  21192. _each = $.each;
  21193. DX.viz.core.series.helpers.SeriesFamily = DX.Class.inherit(function() {
  21194. var ctor = function(options) {
  21195. var debug = DX.utils.debug;
  21196. debug.assert(options.type, "type was not passed or empty");
  21197. var that = this,
  21198. stubFunction = $.noop;
  21199. that.type = options.type.toLowerCase();
  21200. that.pane = options.pane;
  21201. that.series = [];
  21202. that.updateOptions(options);
  21203. switch (that.type) {
  21204. case"bar":
  21205. that.adjustSeriesDimensions = adjustBarSeriesDimensions;
  21206. that.adjustSeriesValues = stubFunction;
  21207. that.updateSeriesValues = updateBarSeriesValues;
  21208. break;
  21209. case"rangebar":
  21210. that.adjustSeriesDimensions = adjustBarSeriesDimensions;
  21211. that.adjustSeriesValues = stubFunction;
  21212. that.updateSeriesValues = stubFunction;
  21213. break;
  21214. case"fullstackedbar":
  21215. that.fullStacked = true;
  21216. that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
  21217. that.adjustSeriesValues = adjustStackedSeriesValues;
  21218. that.updateSeriesValues = updateStackedSeriesValues;
  21219. break;
  21220. case"stackedbar":
  21221. that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
  21222. that.adjustSeriesValues = adjustStackedSeriesValues;
  21223. that.updateSeriesValues = updateStackedSeriesValues;
  21224. break;
  21225. case"fullstackedarea":
  21226. case"fullstackedline":
  21227. case"fullstackedspline":
  21228. case"fullstackedsplinearea":
  21229. that.fullStacked = true;
  21230. that.adjustSeriesDimensions = stubFunction;
  21231. that.adjustSeriesValues = adjustStackedSeriesValues;
  21232. that.updateSeriesValues = stubFunction;
  21233. break;
  21234. case"stackedarea":
  21235. case"stackedsplinearea":
  21236. case"stackedline":
  21237. case"stackedspline":
  21238. that.adjustSeriesDimensions = stubFunction;
  21239. that.adjustSeriesValues = adjustStackedSeriesValues;
  21240. that.updateSeriesValues = stubFunction;
  21241. break;
  21242. case"candlestick":
  21243. case"stock":
  21244. that.adjustSeriesDimensions = adjustCandlestickSeriesDimensions;
  21245. that.adjustSeriesValues = stubFunction;
  21246. that.updateSeriesValues = stubFunction;
  21247. break;
  21248. case"bubble":
  21249. that.adjustSeriesDimensions = adjustBubbleSeriesDimensions;
  21250. that.adjustSeriesValues = stubFunction;
  21251. that.updateSeriesValues = stubFunction;
  21252. break;
  21253. default:
  21254. that.adjustSeriesDimensions = stubFunction;
  21255. that.adjustSeriesValues = stubFunction;
  21256. that.updateSeriesValues = stubFunction;
  21257. break
  21258. }
  21259. };
  21260. var updateOptions = function(options) {
  21261. this.equalBarWidth = options.equalBarWidth;
  21262. this.minBubbleSize = options.minBubbleSize;
  21263. this.maxBubbleSize = options.maxBubbleSize
  21264. };
  21265. var dispose = function() {
  21266. this.series = null;
  21267. this.translators = null
  21268. };
  21269. var add = function(series) {
  21270. var that = this,
  21271. singleSeries,
  21272. i;
  21273. if (!$.isArray(series))
  21274. series = [series];
  21275. for (i = 0; i < series.length; i++) {
  21276. singleSeries = series[i];
  21277. if (singleSeries.type.toLowerCase() === that.type)
  21278. that.series.push(singleSeries)
  21279. }
  21280. };
  21281. function correctPointCoordinates(points, width, offset) {
  21282. _each(points, function(_, point) {
  21283. point.correctCoordinates({
  21284. width: width,
  21285. offset: offset
  21286. })
  21287. })
  21288. }
  21289. function getStacksWithArgument(stackKeepers, argument) {
  21290. var stacksWithArgument = [];
  21291. _each(stackKeepers, function(stackName, seriesInStack) {
  21292. _each(seriesInStack, function(_, singleSeries) {
  21293. var points = singleSeries.getPointsByArg(argument),
  21294. pointsLength = points.length,
  21295. i;
  21296. for (i = 0; i < pointsLength; ++i)
  21297. if (points[i] && points[i].value) {
  21298. stacksWithArgument.push(stackName);
  21299. return false
  21300. }
  21301. })
  21302. });
  21303. return stacksWithArgument
  21304. }
  21305. function correctPointCoordinatesForStacks(stackKeepers, stacksWithArgument, argument, middleIndex, width, spacing) {
  21306. _each(stackKeepers, function(stackName, seriesInStack) {
  21307. var stackIndex = $.inArray(stackName, stacksWithArgument),
  21308. offset;
  21309. if (stackIndex === -1)
  21310. return;
  21311. offset = (stackIndex - middleIndex + 0.5) * width - (middleIndex - stackIndex - 0.5) * spacing;
  21312. _each(seriesInStack, function(_, singleSeries) {
  21313. _each(singleSeries.getPointsByArg(argument) || [], function(_, point) {
  21314. if (point && point.value)
  21315. point.correctCoordinates({
  21316. width: width,
  21317. offset: offset
  21318. })
  21319. })
  21320. })
  21321. })
  21322. }
  21323. var adjustBarSeriesDimensionsCore = function(series, interval, stackCount, equalBarWidth, seriesStackIndexCallback) {
  21324. var spacing,
  21325. width,
  21326. maxWidth,
  21327. middleIndex,
  21328. stackIndex,
  21329. i,
  21330. points,
  21331. seriesOffset,
  21332. stackName,
  21333. argumentsKeeper = {},
  21334. stackKeepers = {},
  21335. stacksWithArgument,
  21336. count;
  21337. if (equalBarWidth) {
  21338. width = equalBarWidth.width && equalBarWidth.width < 0 ? 0 : equalBarWidth.width;
  21339. spacing = equalBarWidth.spacing && equalBarWidth.spacing < 0 ? 0 : equalBarWidth.spacing;
  21340. if (!spacing)
  21341. if (stackCount > 1) {
  21342. spacing = width ? _round((interval * 0.7 - width * stackCount) / (stackCount - 1)) : _round(interval * 0.7 / stackCount * 0.2);
  21343. if (spacing < 1)
  21344. spacing = 1
  21345. }
  21346. else
  21347. spacing = 0;
  21348. if (!width) {
  21349. width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);
  21350. if (width < 2)
  21351. width = 2
  21352. }
  21353. if (width * stackCount + spacing * (stackCount - 1) > interval) {
  21354. spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));
  21355. if (spacing < 1) {
  21356. spacing = 1;
  21357. maxWidth = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount)
  21358. }
  21359. }
  21360. middleIndex = stackCount / 2;
  21361. for (i = 0; i < series.length; i++) {
  21362. stackIndex = seriesStackIndexCallback(i);
  21363. points = series[i].getPoints();
  21364. seriesOffset = (stackIndex - middleIndex + 0.5) * (maxWidth || width) - (middleIndex - stackIndex - 0.5) * spacing;
  21365. correctPointCoordinates(points, width, seriesOffset)
  21366. }
  21367. }
  21368. else {
  21369. _each(series, function(i, singleSeries) {
  21370. stackName = singleSeries.getStackName && singleSeries.getStackName();
  21371. stackName = stackName || i.toString();
  21372. if (!stackKeepers[stackName])
  21373. stackKeepers[stackName] = [];
  21374. stackKeepers[stackName].push(singleSeries)
  21375. });
  21376. _each(series, function(i, singleSeries) {
  21377. _each(singleSeries.getPoints(), function(_, point) {
  21378. var argument = point.argument;
  21379. if (!argumentsKeeper.hasOwnProperty(argument))
  21380. argumentsKeeper[argument.valueOf()] = 1
  21381. })
  21382. });
  21383. for (var argument in argumentsKeeper) {
  21384. if (!argumentsKeeper.hasOwnProperty(argument))
  21385. continue;
  21386. stacksWithArgument = getStacksWithArgument(stackKeepers, argument);
  21387. count = stacksWithArgument.length;
  21388. spacing = _round(interval * 0.7 / count * 0.2);
  21389. if (spacing < 1)
  21390. spacing = 1;
  21391. width = _round((interval * 0.7 - spacing * (count - 1)) / count);
  21392. if (width < 2)
  21393. width = 2;
  21394. middleIndex = count / 2;
  21395. correctPointCoordinatesForStacks(stackKeepers, stacksWithArgument, argument, middleIndex, width, spacing)
  21396. }
  21397. }
  21398. };
  21399. function checkMinBarSize(value, minShownValue) {
  21400. return _abs(value) < minShownValue ? value >= 0 ? minShownValue : -minShownValue : value
  21401. }
  21402. function getValueType(value) {
  21403. return value >= 0 ? "positive" : "negative"
  21404. }
  21405. function getVisibleSeries(that) {
  21406. return $.map(that.series, function(s) {
  21407. return s.isVisible() ? s : null
  21408. })
  21409. }
  21410. function getAbsStackSumByArg(stackKeepers, stackName, argument) {
  21411. var positiveStackValue = (stackKeepers.positive[stackName] || {})[argument] || 0,
  21412. negativeStackValue = -(stackKeepers.negative[stackName] || {})[argument] || 0;
  21413. return positiveStackValue + negativeStackValue
  21414. }
  21415. var adjustBarSeriesDimensions = function(translators) {
  21416. var debug = DX.utils.debug;
  21417. debug.assert(translators, "translator was not passed or empty");
  21418. var that = this,
  21419. equalBarWidth = that.equalBarWidth,
  21420. series = getVisibleSeries(that);
  21421. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, equalBarWidth, function(seriesIndex) {
  21422. return seriesIndex
  21423. })
  21424. };
  21425. var adjustStackedBarSeriesDimensions = function(translators) {
  21426. var debug = DX.utils.debug;
  21427. debug.assert(translators, "translators was not passed or empty");
  21428. var that = this,
  21429. series = getVisibleSeries(that),
  21430. stackIndexes = {},
  21431. stackCount = 0,
  21432. equalBarWidth = that.equalBarWidth;
  21433. _each(series, function() {
  21434. var stackName = this.getStackName();
  21435. if (!stackIndexes.hasOwnProperty(stackName))
  21436. stackIndexes[stackName] = stackCount++
  21437. });
  21438. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), stackCount, equalBarWidth, function(seriesIndex) {
  21439. return stackIndexes[series[seriesIndex].getStackName()]
  21440. })
  21441. };
  21442. var adjustStackedSeriesValues = function() {
  21443. var that = this,
  21444. series = getVisibleSeries(that),
  21445. stackKeepers = {
  21446. positive: {},
  21447. negative: {}
  21448. },
  21449. holesStack = {
  21450. left: {},
  21451. right: {}
  21452. };
  21453. _each(series, function(seriesIndex, singleSeries) {
  21454. var points = singleSeries.getPoints(),
  21455. hole = false;
  21456. singleSeries._prevSeries = series[seriesIndex - 1],
  21457. singleSeries.holes = $.extend(true, {}, holesStack);
  21458. _each(points, function(index, point) {
  21459. var value = point.initialValue,
  21460. argument = point.argument.valueOf(),
  21461. stackName = singleSeries.getStackName(),
  21462. stacks = value >= 0 ? stackKeepers.positive : stackKeepers.negative,
  21463. currentStack;
  21464. stacks[stackName] = stacks[stackName] || {};
  21465. currentStack = stacks[stackName];
  21466. if (currentStack[argument]) {
  21467. point.correctValue(currentStack[argument]);
  21468. currentStack[argument] += value
  21469. }
  21470. else {
  21471. currentStack[argument] = value;
  21472. point.resetCorrection()
  21473. }
  21474. if (!point.hasValue()) {
  21475. var prevPoint = points[index - 1];
  21476. if (!hole && prevPoint && prevPoint.hasValue()) {
  21477. argument = prevPoint.argument.valueOf();
  21478. prevPoint._skipSetRightHole = true;
  21479. holesStack.right[argument] = (holesStack.right[argument] || 0) + (prevPoint.value - (isFinite(prevPoint.minValue) ? prevPoint.minValue : 0))
  21480. }
  21481. hole = true
  21482. }
  21483. else if (hole) {
  21484. hole = false;
  21485. holesStack.left[argument] = (holesStack.left[argument] || 0) + (point.value - (isFinite(point.minValue) ? point.minValue : 0));
  21486. point._skipSetLeftHole = true
  21487. }
  21488. })
  21489. });
  21490. _each(series, function(seriesIndex, singleSeries) {
  21491. var points = singleSeries.getPoints(),
  21492. holes = singleSeries.holes;
  21493. _each(points, function(index, point) {
  21494. var argument = point.argument.valueOf();
  21495. point.resetHoles();
  21496. !point._skipSetLeftHole && point.setHole(holes.left[argument] || holesStack.left[argument] && 0, "left");
  21497. !point._skipSetRightHole && point.setHole(holes.right[argument] || holesStack.right[argument] && 0, "right");
  21498. point._skipSetLeftHole = null;
  21499. point._skipSetRightHole = null
  21500. })
  21501. });
  21502. that._stackKeepers = stackKeepers;
  21503. setPercentStackedValues(series, stackKeepers, that.fullStacked, holesStack)
  21504. };
  21505. var setPercentStackedValues = function(series, stackKeepers, fullStacked, holeStack) {
  21506. _each(series, function(_, singleSeries) {
  21507. _each(singleSeries.getPoints(), function(_, point) {
  21508. var argument = point.argument.valueOf();
  21509. point.setPercentValue(getAbsStackSumByArg(stackKeepers, singleSeries.getStackName(), argument), fullStacked, holeStack.left[argument], holeStack.right[argument])
  21510. })
  21511. })
  21512. };
  21513. var updateStackedSeriesValues = function(translators) {
  21514. var that = this,
  21515. series = getVisibleSeries(that),
  21516. stack = that._stackKeepers,
  21517. stackKeepers = {
  21518. positive: {},
  21519. negative: {}
  21520. };
  21521. _each(series, function(_, singleSeries) {
  21522. var minBarSize = singleSeries.getOptions().minBarSize,
  21523. minShownBusinessValue = minBarSize && translators.val.getMinBarSize(minBarSize),
  21524. stackName = singleSeries.getStackName();
  21525. _each(singleSeries.getPoints(), function(index, point) {
  21526. if (!point.hasValue())
  21527. return;
  21528. var value = point.initialValue,
  21529. argument = point.argument.valueOf(),
  21530. updateValue,
  21531. valueType,
  21532. currentStack;
  21533. if (that.fullStacked)
  21534. value = _abs(value) / getAbsStackSumByArg(stack, stackName, argument) || 0;
  21535. updateValue = checkMinBarSize(value, minShownBusinessValue);
  21536. valueType = getValueType(updateValue);
  21537. currentStack = stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  21538. if (currentStack[argument]) {
  21539. point.minValue = currentStack[argument];
  21540. currentStack[argument] += updateValue
  21541. }
  21542. else
  21543. currentStack[argument] = updateValue;
  21544. point.value = currentStack[argument]
  21545. })
  21546. });
  21547. if (that.fullStacked)
  21548. updateFullStackedSeriesValues(series, stackKeepers)
  21549. };
  21550. var updateFullStackedSeriesValues = function(series, stackKeepers) {
  21551. _each(series, function(_, singleSeries) {
  21552. var stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default";
  21553. _each(singleSeries.getPoints(), function(index, point) {
  21554. var value = _abs(point.value),
  21555. argument = point.argument.valueOf(),
  21556. valueType = getValueType(value),
  21557. currentStack;
  21558. stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  21559. currentStack = stackKeepers[valueType][stackName];
  21560. point.value = point.value / currentStack[argument] || 0;
  21561. if (utils.isNumber(point.minValue))
  21562. point.minValue = point.minValue / currentStack[argument] || 0
  21563. })
  21564. })
  21565. };
  21566. var updateBarSeriesValues = function(translators) {
  21567. _each(this.series, function(_, singleSeries) {
  21568. var minBarSize = singleSeries.getOptions().minBarSize,
  21569. minShownBusinessValue = minBarSize && translators.val.getMinBarSize(minBarSize);
  21570. if (minShownBusinessValue)
  21571. _each(singleSeries.getPoints(), function(index, point) {
  21572. if (point.hasValue())
  21573. point.value = checkMinBarSize(point.initialValue, minShownBusinessValue)
  21574. })
  21575. })
  21576. };
  21577. var adjustCandlestickSeriesDimensions = function(translators) {
  21578. var debug = DX.utils.debug;
  21579. debug.assert(translators, "translator was not passed or empty");
  21580. var that = this,
  21581. series = getVisibleSeries(that);
  21582. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, true, function(seriesIndex) {
  21583. return seriesIndex
  21584. })
  21585. };
  21586. var getInterval = function(that, translators) {
  21587. var argTranslator = translators.arg;
  21588. that.interval = argTranslator.getInterval();
  21589. return that.interval
  21590. };
  21591. var adjustBubbleSeriesDimensions = function(translators) {
  21592. var debug = DX.utils.debug;
  21593. debug.assert(translators, "translator was not passed or empty");
  21594. var that = this,
  21595. series = getVisibleSeries(that),
  21596. visibleAreaX = translators.arg.getCanvasVisibleArea(),
  21597. visibleAreaY = translators.val.getCanvasVisibleArea(),
  21598. min = Math.min(visibleAreaX.max - visibleAreaX.min, visibleAreaY.max - visibleAreaY.min),
  21599. minBubbleArea = _pow(that.minBubbleSize, 2),
  21600. maxBubbleArea = _pow(min * that.maxBubbleSize, 2),
  21601. equalBubbleSize = (min * that.maxBubbleSize + that.minBubbleSize) / 2,
  21602. minPointSize = Infinity,
  21603. maxPointSize = 0,
  21604. pointSize,
  21605. bubbleArea,
  21606. sizeProportion,
  21607. sizeDispersion,
  21608. areaDispersion;
  21609. _each(series, function(_, seriesItem) {
  21610. _each(seriesItem.getPoints(), function(_, point) {
  21611. maxPointSize = maxPointSize > point.size ? maxPointSize : point.size;
  21612. minPointSize = minPointSize < point.size ? minPointSize : point.size
  21613. })
  21614. });
  21615. sizeDispersion = maxPointSize - minPointSize;
  21616. areaDispersion = _abs(maxBubbleArea - minBubbleArea);
  21617. minPointSize = minPointSize < 0 ? 0 : minPointSize;
  21618. _each(series, function(_, seriesItem) {
  21619. _each(seriesItem.getPoints(), function(_, point) {
  21620. if (maxPointSize === minPointSize)
  21621. pointSize = _round(equalBubbleSize);
  21622. else {
  21623. sizeProportion = _abs(point.size - minPointSize) / sizeDispersion;
  21624. bubbleArea = areaDispersion * sizeProportion + minBubbleArea;
  21625. pointSize = _round(Math.sqrt(bubbleArea))
  21626. }
  21627. point.correctCoordinates(pointSize)
  21628. })
  21629. })
  21630. };
  21631. return {
  21632. ctor: ctor,
  21633. dispose: dispose,
  21634. add: add,
  21635. updateOptions: updateOptions
  21636. }
  21637. }())
  21638. })(jQuery, DevExpress);
  21639. /*! Module viz-core, file baseSeries.js */
  21640. (function($, DX) {
  21641. var viz = DX.viz,
  21642. core = viz.core,
  21643. seriesNS = core.series,
  21644. utils = DX.utils,
  21645. _isDefined = utils.isDefined,
  21646. _each = $.each,
  21647. _extend = $.extend,
  21648. _isEmptyObject = $.isEmptyObject,
  21649. _Event = $.Event,
  21650. _noop = $.noop,
  21651. SELECTED_STATE = 2,
  21652. HOVER_STATE = 1,
  21653. NONE_MODE = "none",
  21654. INCLUDE_POINTS = "includepoints",
  21655. EXLUDE_POINTS = "excludepoints",
  21656. NEAREST_POINT = "nearestpoint",
  21657. APPLY_SELECTED = "applySelected",
  21658. APPLY_HOVER = "applyHover",
  21659. SYMBOL_POINT = "symbolPoint",
  21660. POLAR_SYMBOL_POINT = "polarSymbolPoint",
  21661. BAR_POINT = "barPoint",
  21662. POLAR_BAR_POINT = "polarBarPoint",
  21663. PIE_POINT = "piePoint",
  21664. HOVER = "hover",
  21665. NORMAL = "normal",
  21666. SELECTION = "selection",
  21667. getEmptyBusinessRange = function() {
  21668. return {
  21669. arg: {},
  21670. val: {}
  21671. }
  21672. };
  21673. function triggerEvent(element, event, point) {
  21674. element && element.trigger(event, point)
  21675. }
  21676. seriesNS.mixins = {
  21677. chart: {pointTypes: {
  21678. scatter: SYMBOL_POINT,
  21679. line: SYMBOL_POINT,
  21680. spline: SYMBOL_POINT,
  21681. stepline: SYMBOL_POINT,
  21682. stackedline: SYMBOL_POINT,
  21683. fullstackedline: SYMBOL_POINT,
  21684. stackedspline: SYMBOL_POINT,
  21685. fullstackedspline: SYMBOL_POINT,
  21686. stackedsplinearea: SYMBOL_POINT,
  21687. fullstackedsplinearea: SYMBOL_POINT,
  21688. area: SYMBOL_POINT,
  21689. splinearea: SYMBOL_POINT,
  21690. steparea: SYMBOL_POINT,
  21691. stackedarea: SYMBOL_POINT,
  21692. fullstackedarea: SYMBOL_POINT,
  21693. rangearea: "rangeSymbolPoint",
  21694. bar: BAR_POINT,
  21695. stackedbar: BAR_POINT,
  21696. fullstackedbar: BAR_POINT,
  21697. rangebar: "rangeBarPoint",
  21698. bubble: "bubblePoint",
  21699. stock: "stockPoint",
  21700. candlestick: "candlestickPoint"
  21701. }},
  21702. pie: {pointTypes: {
  21703. pie: PIE_POINT,
  21704. doughnut: PIE_POINT,
  21705. donut: PIE_POINT
  21706. }},
  21707. polar: {pointTypes: {
  21708. scatter: POLAR_SYMBOL_POINT,
  21709. line: POLAR_SYMBOL_POINT,
  21710. area: POLAR_SYMBOL_POINT,
  21711. bar: POLAR_BAR_POINT,
  21712. stackedbar: POLAR_BAR_POINT
  21713. }}
  21714. };
  21715. function includePointsMode(mode) {
  21716. return mode === INCLUDE_POINTS || mode === "allseriespoints"
  21717. }
  21718. function Series() {
  21719. this.ctor.apply(this, arguments)
  21720. }
  21721. function applyPointStyle(point, styleName) {
  21722. !point.isSelected() && point.applyStyle(styleName)
  21723. }
  21724. seriesNS.Series = Series;
  21725. Series.prototype = {
  21726. ctor: function(renderSettings, options) {
  21727. var that = this;
  21728. that.fullState = 0;
  21729. that._extGroups = renderSettings;
  21730. that._renderer = renderSettings.renderer;
  21731. that._group = renderSettings.renderer.g().attr({"class": "dxc-series"});
  21732. that.updateOptions(options)
  21733. },
  21734. update: function(data, options) {
  21735. this.updateOptions(options);
  21736. this.updateData(data)
  21737. },
  21738. _createLegendState: _noop,
  21739. getLegendStyles: function() {
  21740. return this._styles.legendStyles
  21741. },
  21742. _createStyles: function(options) {
  21743. var that = this,
  21744. mainSeriesColor = options.mainSeriesColor,
  21745. specialMainColor = that._getSpecialColor(mainSeriesColor);
  21746. that._styles = {
  21747. normal: that._parseStyle(options, mainSeriesColor, mainSeriesColor),
  21748. hover: that._parseStyle(options.hoverStyle || {}, specialMainColor, mainSeriesColor),
  21749. selection: that._parseStyle(options.selectionStyle || {}, specialMainColor, mainSeriesColor),
  21750. legendStyles: {
  21751. normal: that._createLegendState(options, mainSeriesColor),
  21752. hover: that._createLegendState(options.hoverStyle || {}, specialMainColor),
  21753. selection: that._createLegendState(options.selectionStyle || {}, specialMainColor)
  21754. }
  21755. }
  21756. },
  21757. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  21758. _each(this._points || [], function(_, point) {
  21759. point.setAdjustSeriesLabels(adjustSeriesLabels)
  21760. })
  21761. },
  21762. setClippingParams: function(baseId, wideId, forceClipping) {
  21763. this._paneClipRectID = baseId;
  21764. this._widePaneClipRectID = wideId;
  21765. this._forceClipping = forceClipping
  21766. },
  21767. applyClip: function() {
  21768. this._group.attr({clipId: this._paneClipRectID})
  21769. },
  21770. resetClip: function() {
  21771. this._group.attr({clipId: null})
  21772. },
  21773. getTagField: function() {
  21774. return this._options.tagField || "tag"
  21775. },
  21776. getValueFields: _noop,
  21777. getArgumentField: _noop,
  21778. getPoints: function() {
  21779. return this._points
  21780. },
  21781. _createPoint: function(data, pointsArray, index) {
  21782. data.index = index;
  21783. var that = this,
  21784. point = pointsArray[index],
  21785. pointsByArgument = that.pointsByArgument,
  21786. options;
  21787. if (that._checkData(data)) {
  21788. options = that._customizePoint(data) || that._getCreatingPointOptions();
  21789. if (point)
  21790. point.update(data, options);
  21791. else {
  21792. point = core.CoreFactory.createPoint(that, data, options);
  21793. pointsArray.push(point)
  21794. }
  21795. pointsByArgument[point.argument.valueOf()] = pointsByArgument[point.argument.valueOf()] || [];
  21796. pointsByArgument[point.argument.valueOf()].push(point);
  21797. return true
  21798. }
  21799. },
  21800. getRangeData: function(zoomArgs, calcIntervalFunction) {
  21801. return this._visible ? _extend(true, {}, this._getRangeData(zoomArgs, calcIntervalFunction)) : getEmptyBusinessRange()
  21802. },
  21803. _deleteGroup: function(groupName) {
  21804. var group = this[groupName];
  21805. if (group) {
  21806. group.dispose();
  21807. this[groupName] = null
  21808. }
  21809. },
  21810. _saveOldAnimationMethods: function() {
  21811. var that = this;
  21812. that._oldClearingAnimation = that._clearingAnimation;
  21813. that._oldUpdateElement = that._updateElement;
  21814. that._oldgetAffineCoordOptions = that._getAffineCoordOptions
  21815. },
  21816. _deleteOldAnimationMethods: function() {
  21817. this._oldClearingAnimation = null;
  21818. this._oldUpdateElement = null;
  21819. this._oldgetAffineCoordOptions = null
  21820. },
  21821. updateOptions: function(newOptions) {
  21822. var that = this,
  21823. widgetType = newOptions.widgetType,
  21824. oldType = that.type,
  21825. newType = newOptions.type;
  21826. that.type = newType && newType.toString().toLowerCase();
  21827. if (!that._checkType(widgetType) || that._checkPolarBarType(widgetType, newOptions)) {
  21828. that.dispose();
  21829. that.isUpdated = false;
  21830. return
  21831. }
  21832. if (oldType !== that.type) {
  21833. that._firstDrawing = true;
  21834. that._saveOldAnimationMethods();
  21835. that._resetType(oldType, widgetType);
  21836. that._setType(that.type, widgetType)
  21837. }
  21838. that._options = newOptions;
  21839. that._pointOptions = null;
  21840. that._deletePatterns();
  21841. that._patterns = [];
  21842. that.name = newOptions.name;
  21843. that.pane = newOptions.pane;
  21844. that.axis = newOptions.axis;
  21845. that.tag = newOptions.tag;
  21846. that._createStyles(newOptions);
  21847. that._updateOptions(newOptions);
  21848. that._visible = newOptions.visible;
  21849. that.isUpdated = true
  21850. },
  21851. _disposePoints: function(points) {
  21852. _each(points || [], function(_, p) {
  21853. p.dispose()
  21854. })
  21855. },
  21856. _correctPointsLength: function(length, points) {
  21857. this._disposePoints(this._oldPoints);
  21858. this._oldPoints = points.splice(length, points.length)
  21859. },
  21860. _getTicksForAggregation: function(min, max, screenDelta, pointSize) {
  21861. var types = {
  21862. axisType: "continuous",
  21863. dataType: utils.isDate(min) ? "datetime" : "numeric"
  21864. },
  21865. data = {
  21866. min: min,
  21867. max: max,
  21868. screenDelta: screenDelta
  21869. },
  21870. options = {
  21871. gridSpacingFactor: pointSize,
  21872. labelOptions: {},
  21873. stick: true
  21874. },
  21875. tickManager = new viz.core.tickManager.TickManager(types, data, options);
  21876. return {
  21877. ticks: tickManager.getTicks(true),
  21878. tickInterval: tickManager.getTickInterval()
  21879. }
  21880. },
  21881. _getRangeCorrector: _noop,
  21882. updateDataType: function(settings) {
  21883. var that = this;
  21884. that.argumentType = settings.argumentType;
  21885. that.valueType = settings.valueType;
  21886. that.argumentAxisType = settings.argumentAxisType;
  21887. that.valueAxisType = settings.valueAxisType;
  21888. that.showZero = settings.showZero;
  21889. return that
  21890. },
  21891. getOptions: function() {
  21892. return this._options
  21893. },
  21894. _resetRangeData: function() {
  21895. this._rangeData = getEmptyBusinessRange()
  21896. },
  21897. updateData: function(data) {
  21898. var that = this,
  21899. points = that._originalPoints || [],
  21900. lastPointIndex = 0,
  21901. options = that._options,
  21902. pointData,
  21903. rangeCorrector;
  21904. that._rangeErrorBarCorrector = rangeCorrector = that._getRangeCorrector();
  21905. that.pointsByArgument = {};
  21906. that._resetRangeData();
  21907. if (data && data.length)
  21908. that._canRenderCompleteHandle = true;
  21909. that._beginUpdateData(data);
  21910. _each(data, function(_, dataItem) {
  21911. pointData = that._getPointData(dataItem, options);
  21912. if (that._createPoint(pointData, points, lastPointIndex)) {
  21913. that._processRange(points[lastPointIndex], lastPointIndex > 0 ? points[lastPointIndex - 1] : null, rangeCorrector);
  21914. lastPointIndex++
  21915. }
  21916. });
  21917. that._disposePoints(that._aggregatedPoints);
  21918. that._aggregatedPoints = null;
  21919. that._points = that._originalPoints = points;
  21920. that._correctPointsLength(lastPointIndex, points);
  21921. that._endUpdateData()
  21922. },
  21923. getTeamplatedFields: function() {
  21924. var that = this,
  21925. fields = that.getValueFields(),
  21926. teampleteFields = [];
  21927. fields.push(that.getTagField());
  21928. _each(fields, function(_, field) {
  21929. var fieldsObject = {};
  21930. fieldsObject.teamplateField = field + that.name;
  21931. fieldsObject.originalField = field;
  21932. teampleteFields.push(fieldsObject)
  21933. });
  21934. return teampleteFields
  21935. },
  21936. resamplePoints: function(argTranslator, min, max) {
  21937. var that = this,
  21938. originalPoints = that.getAllPoints(),
  21939. minI,
  21940. maxI,
  21941. sizePoint,
  21942. tickObject,
  21943. ticks,
  21944. tickInterval;
  21945. if (originalPoints.length) {
  21946. _each(originalPoints, function(i, point) {
  21947. minI = point.argument - min <= 0 ? i : minI;
  21948. if (!maxI)
  21949. maxI = point.argument - max > 0 ? i : null
  21950. });
  21951. minI = minI ? minI : 1;
  21952. maxI = _isDefined(maxI) ? maxI : originalPoints.length - 1;
  21953. min = originalPoints[minI - 1].argument;
  21954. max = originalPoints[maxI].argument;
  21955. sizePoint = that._getPointSize();
  21956. if (that.argumentAxisType !== "discrete" && that.valueAxisType !== "discrete") {
  21957. tickObject = that._getTicksForAggregation(min, max, argTranslator.canvasLength, sizePoint);
  21958. ticks = tickObject.ticks;
  21959. tickInterval = tickObject.tickInterval;
  21960. if (ticks.length === 1) {
  21961. that._points = originalPoints;
  21962. return
  21963. }
  21964. }
  21965. else
  21966. ticks = argTranslator.canvasLength / sizePoint;
  21967. that._points = that._resample(ticks, tickInterval, argTranslator)
  21968. }
  21969. },
  21970. _removeOldSegments: function(startIndex) {
  21971. var that = this;
  21972. _each(that._graphics.splice(startIndex, that._graphics.length) || [], function(_, elem) {
  21973. that._removeElement(elem)
  21974. });
  21975. if (that._trackers)
  21976. _each(that._trackers.splice(startIndex, that._trackers.length) || [], function(_, elem) {
  21977. elem.remove()
  21978. })
  21979. },
  21980. draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
  21981. var that = this,
  21982. drawComplete;
  21983. if (that._oldClearingAnimation && animationEnabled && that._firstDrawing) {
  21984. drawComplete = function() {
  21985. that._draw(translators, true, hideLayoutLabels)
  21986. };
  21987. that._oldClearingAnimation(translators, drawComplete)
  21988. }
  21989. else
  21990. that._draw(translators, animationEnabled, hideLayoutLabels, legendCallback)
  21991. },
  21992. _clearSeries: function() {
  21993. var that = this;
  21994. that._deleteGroup("_elementsGroup");
  21995. that._deleteGroup("_bordersGroup");
  21996. that._deleteTrackers();
  21997. that._graphics = [];
  21998. that._trackers = []
  21999. },
  22000. _draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
  22001. var that = this,
  22002. points = that._points || [],
  22003. segment = [],
  22004. segmentCount = 0,
  22005. firstDrawing = that._firstDrawing,
  22006. closeSegment = points[0] && points[0].hasValue() && that._options.closed,
  22007. groupForPoint;
  22008. that._graphics = that._graphics || [];
  22009. that._prepareSeriesToDrawing();
  22010. if (!that._visible) {
  22011. animationEnabled = false;
  22012. that._group.remove();
  22013. return
  22014. }
  22015. that._group.append(that._extGroups.seriesGroup);
  22016. that.translators = translators;
  22017. that._createGroups(animationEnabled, undefined, firstDrawing);
  22018. that._segments = [];
  22019. that._drawedPoints = [];
  22020. that._firstDrawing = points.length ? false : true;
  22021. groupForPoint = {
  22022. markers: that._markersGroup,
  22023. labels: that._labelsGroup,
  22024. errorBars: that._errorBarGroup
  22025. };
  22026. _each(points, function(i, p) {
  22027. p.translate(translators);
  22028. if (p.hasValue()) {
  22029. that._drawPoint({
  22030. point: p,
  22031. groups: groupForPoint,
  22032. hasAnimation: animationEnabled,
  22033. firstDrawing: firstDrawing,
  22034. legendCallback: legendCallback
  22035. });
  22036. segment.push(p)
  22037. }
  22038. else if (segment.length) {
  22039. that._drawSegment(segment, animationEnabled, segmentCount++);
  22040. segment = []
  22041. }
  22042. });
  22043. segment.length && that._drawSegment(segment, animationEnabled, segmentCount++, closeSegment);
  22044. that._removeOldSegments(segmentCount);
  22045. that._defaultSegments = that._generateDefaultSegments();
  22046. hideLayoutLabels && that.hideLabels();
  22047. animationEnabled && that._animate(firstDrawing);
  22048. if (that.isSelected())
  22049. that._changeStyle(legendCallback, APPLY_SELECTED);
  22050. else if (that.isHovered())
  22051. that._changeStyle(legendCallback, APPLY_HOVER)
  22052. },
  22053. _checkType: function(widgetType) {
  22054. return !!seriesNS.mixins[widgetType][this.type]
  22055. },
  22056. _checkPolarBarType: function(widgetType, options) {
  22057. return widgetType === "polar" && options.spiderWidget && this.type.indexOf("bar") !== -1
  22058. },
  22059. _resetType: function(seriesType, widgetType) {
  22060. var that = this;
  22061. if (seriesType)
  22062. _each(seriesNS.mixins[widgetType][seriesType], function(methodName) {
  22063. delete that[methodName]
  22064. })
  22065. },
  22066. _setType: function(seriesType, widgetType) {
  22067. var that = this;
  22068. _each(seriesNS.mixins[widgetType][seriesType], function(methodName, method) {
  22069. that[methodName] = method
  22070. })
  22071. },
  22072. setSelectedState: function(state, mode, legendCallback) {
  22073. var that = this;
  22074. that.lastSelectionMode = (mode || that._options.selectionMode).toLowerCase();
  22075. if (state && !that.isSelected()) {
  22076. that.fullState = that.fullState | SELECTED_STATE;
  22077. that._nearestPoint && applyPointStyle(that._nearestPoint, "normal");
  22078. that._nearestPoint = null;
  22079. that._changeStyle(legendCallback, APPLY_SELECTED)
  22080. }
  22081. else if (!state && that.isSelected()) {
  22082. that.fullState = that.fullState & ~SELECTED_STATE;
  22083. if (that.isHovered())
  22084. that._changeStyle(legendCallback, APPLY_HOVER, SELECTION);
  22085. else
  22086. that._changeStyle(legendCallback, "resetItem")
  22087. }
  22088. },
  22089. setHoverState: function(state, mode, legendCallback) {
  22090. var that = this;
  22091. that.lastHoverMode = (mode || that._options.hoverMode).toLowerCase();
  22092. if (state && !that.isHovered()) {
  22093. that.fullState = that.fullState | HOVER_STATE;
  22094. !that.isSelected() && that._changeStyle(legendCallback, APPLY_HOVER)
  22095. }
  22096. else if (!state && that.isHovered()) {
  22097. that._nearestPoint = null;
  22098. that.fullState = that.fullState & ~HOVER_STATE;
  22099. !that.isSelected() && that._changeStyle(legendCallback, "resetItem")
  22100. }
  22101. },
  22102. isFullStackedSeries: function() {
  22103. return this.type.indexOf("fullstacked") === 0
  22104. },
  22105. isStackedSeries: function() {
  22106. return this.type.indexOf("stacked") === 0
  22107. },
  22108. isFinancialSeries: function() {
  22109. return this.type === "stock" || this.type === "candlestick"
  22110. },
  22111. _changeStyle: function(legendCallBack, legendAction, prevStyle) {
  22112. var that = this,
  22113. style = that._calcStyle(prevStyle),
  22114. pointStyle;
  22115. if (style.mode === NONE_MODE)
  22116. return;
  22117. legendCallBack && legendCallBack(legendAction);
  22118. if (includePointsMode(style.mode)) {
  22119. pointStyle = style.pointStyle;
  22120. _each(that._points || [], function(_, p) {
  22121. applyPointStyle(p, pointStyle)
  22122. })
  22123. }
  22124. that._applyStyle(style.series)
  22125. },
  22126. _calcStyle: function(prevStyle) {
  22127. var that = this,
  22128. styles = that._styles,
  22129. pointNormalState = false,
  22130. result;
  22131. switch (that.fullState & 3) {
  22132. case 0:
  22133. result = {
  22134. pointStyle: NORMAL,
  22135. mode: INCLUDE_POINTS,
  22136. series: styles.normal
  22137. };
  22138. break;
  22139. case 1:
  22140. pointNormalState = prevStyle === SELECTION && that.lastHoverMode === EXLUDE_POINTS || that.lastHoverMode === NEAREST_POINT && includePointsMode(that.lastSelectionMode);
  22141. result = {
  22142. pointStyle: pointNormalState ? NORMAL : HOVER,
  22143. mode: pointNormalState ? INCLUDE_POINTS : that.lastHoverMode,
  22144. series: styles.hover
  22145. };
  22146. break;
  22147. case 2:
  22148. result = {
  22149. pointStyle: SELECTION,
  22150. mode: that.lastSelectionMode,
  22151. series: styles.selection
  22152. };
  22153. break;
  22154. case 3:
  22155. pointNormalState = that.lastSelectionMode === EXLUDE_POINTS && includePointsMode(that.lastHoverMode);
  22156. result = {
  22157. pointStyle: pointNormalState ? NORMAL : SELECTION,
  22158. mode: pointNormalState ? INCLUDE_POINTS : that.lastSelectionMode,
  22159. series: styles.selection
  22160. }
  22161. }
  22162. return result
  22163. },
  22164. updateHover: function(x, y) {
  22165. var that = this,
  22166. currentNearestPoint = that._nearestPoint,
  22167. point = that.isHovered() && that.lastHoverMode === NEAREST_POINT && that.getNeighborPoint(x, y);
  22168. if (point !== currentNearestPoint && !that.isSelected()) {
  22169. currentNearestPoint && applyPointStyle(currentNearestPoint, "normal");
  22170. if (point) {
  22171. applyPointStyle(point, "hover");
  22172. that._nearestPoint = point
  22173. }
  22174. }
  22175. },
  22176. _getMainAxisName: function() {
  22177. return this._options.rotated ? "X" : "Y"
  22178. },
  22179. areLabelsVisible: function() {
  22180. return !_isDefined(this._options.maxLabelCount) || this._points.length <= this._options.maxLabelCount
  22181. },
  22182. getLabelVisibility: function() {
  22183. return this.areLabelsVisible() && this._options.label && this._options.label.visible
  22184. },
  22185. _customizePoint: function(pointData) {
  22186. var that = this,
  22187. options = that._options,
  22188. customizePoint = options.customizePoint,
  22189. customizeObject,
  22190. pointOptions,
  22191. customLabelOptions,
  22192. customOptions,
  22193. customizeLabel = options.customizeLabel,
  22194. useLabelCustomOptions,
  22195. usePointCustomOptions;
  22196. if (customizeLabel && customizeLabel.call) {
  22197. customizeObject = _extend({seriesName: that.name}, pointData);
  22198. customizeObject.series = that;
  22199. customLabelOptions = customizeLabel.call(customizeObject, customizeObject);
  22200. useLabelCustomOptions = customLabelOptions && !_isEmptyObject(customLabelOptions);
  22201. customLabelOptions = useLabelCustomOptions ? _extend(true, {}, options.label, customLabelOptions) : null
  22202. }
  22203. if (customizePoint && customizePoint.call) {
  22204. customizeObject = customizeObject || _extend({seriesName: that.name}, pointData);
  22205. customizeObject.series = that;
  22206. customOptions = customizePoint.call(customizeObject, customizeObject);
  22207. usePointCustomOptions = customOptions && !_isEmptyObject(customOptions)
  22208. }
  22209. if (useLabelCustomOptions || usePointCustomOptions) {
  22210. pointOptions = that._parsePointOptions(that._preparePointOptions(customOptions), customLabelOptions || options.label, true);
  22211. pointOptions.styles.useLabelCustomOptions = useLabelCustomOptions;
  22212. pointOptions.styles.usePointCustomOptions = usePointCustomOptions
  22213. }
  22214. return pointOptions
  22215. },
  22216. _getLabelOptions: function(labelOptions, defaultColor) {
  22217. var opt = labelOptions || {},
  22218. labelFont = opt.font || {},
  22219. labelBorder = opt.border || {},
  22220. labelConnector = opt.connector || {},
  22221. labelAttributes = {font: {
  22222. color: opt.backgroundColor === "none" && labelFont.color.toLowerCase() === "#ffffff" && opt.position !== "inside" ? defaultColor : labelFont.color,
  22223. family: labelFont.family,
  22224. weight: labelFont.weight,
  22225. size: labelFont.size,
  22226. opacity: labelFont.opacity
  22227. }},
  22228. backgroundAttr = {
  22229. fill: opt.backgroundColor || defaultColor,
  22230. "stroke-width": labelBorder.visible ? labelBorder.width || 0 : 0,
  22231. stroke: labelBorder.visible && labelBorder.width ? labelBorder.color : "none",
  22232. dashStyle: labelBorder.dashStyle
  22233. },
  22234. connectorAttr = {
  22235. stroke: labelConnector.visible && labelConnector.width ? labelConnector.color || defaultColor : "none",
  22236. "stroke-width": labelConnector.visible ? labelConnector.width || 0 : 0
  22237. };
  22238. return {
  22239. alignment: opt.alignment,
  22240. format: opt.format,
  22241. argumentFormat: opt.argumentFormat,
  22242. precision: opt.precision,
  22243. argumentPrecision: opt.argumentPrecision,
  22244. percentPrecision: opt.percentPrecision,
  22245. customizeText: $.isFunction(opt.customizeText) ? opt.customizeText : undefined,
  22246. attributes: labelAttributes,
  22247. visible: labelFont.size !== 0 ? opt.visible : false,
  22248. showForZeroValues: opt.showForZeroValues,
  22249. horizontalOffset: opt.horizontalOffset,
  22250. verticalOffset: opt.verticalOffset,
  22251. radialOffset: opt.radialOffset,
  22252. background: backgroundAttr,
  22253. position: opt.position,
  22254. connector: connectorAttr,
  22255. rotationAngle: opt.rotationAngle
  22256. }
  22257. },
  22258. show: function() {
  22259. if (!this._visible)
  22260. this._changeVisibility(true)
  22261. },
  22262. hide: function() {
  22263. if (this._visible)
  22264. this._changeVisibility(false)
  22265. },
  22266. _changeVisibility: function(visibility) {
  22267. var that = this;
  22268. that._visible = that._options.visible = visibility;
  22269. that._updatePointsVisibility();
  22270. that.hidePointTooltip();
  22271. that._options.visibilityChanged()
  22272. },
  22273. _updatePointsVisibility: $.noop,
  22274. hideLabels: function() {
  22275. _each(this._points, function(_, point) {
  22276. point._label.hide()
  22277. })
  22278. },
  22279. _parsePointOptions: function(pointOptions, labelOptions, isCustomPointOptions) {
  22280. var that = this,
  22281. options = that._options,
  22282. styles = that._createPointStyles(pointOptions, isCustomPointOptions),
  22283. parsedOptions = _extend(true, {}, pointOptions, {
  22284. type: options.type,
  22285. tag: that.tag,
  22286. rotated: options.rotated,
  22287. styles: styles,
  22288. widgetType: options.widgetType,
  22289. visibilityChanged: options.visibilityChanged
  22290. });
  22291. parsedOptions.label = that._getLabelOptions(labelOptions, styles.normal.fill);
  22292. parsedOptions.errorBars = options.valueErrorBar;
  22293. return parsedOptions
  22294. },
  22295. _resample: function(ticks, ticksInterval, argTranslator) {
  22296. var that = this,
  22297. fusPoints = [],
  22298. arrayFusPoints,
  22299. nowIndexTicks = 0,
  22300. lastPointIndex = 0,
  22301. originalPoints = that.getAllPoints(),
  22302. visibleArea;
  22303. if (that.argumentAxisType === "discrete" || that.valueAxisType === "discrete") {
  22304. visibleArea = argTranslator.getCanvasVisibleArea();
  22305. originalPoints = $.map(originalPoints, function(p) {
  22306. var pos = argTranslator.translate(p.argument),
  22307. result;
  22308. if (pos >= visibleArea.min && pos <= visibleArea.max)
  22309. result = p;
  22310. else {
  22311. p.setInvisibility();
  22312. result = null
  22313. }
  22314. return result
  22315. });
  22316. ticksInterval = originalPoints.length / ticks;
  22317. arrayFusPoints = $.map(originalPoints, function(point, index) {
  22318. if (Math.floor(nowIndexTicks) <= index) {
  22319. nowIndexTicks += ticksInterval;
  22320. return point
  22321. }
  22322. point.setInvisibility();
  22323. return null
  22324. });
  22325. return arrayFusPoints
  22326. }
  22327. that._aggregatedPoints = that._aggregatedPoints || [];
  22328. _each(originalPoints, function(_, point) {
  22329. point.setInvisibility();
  22330. switch (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval)) {
  22331. case true:
  22332. fusPoints.push(point);
  22333. break;
  22334. case"nextInterval":
  22335. var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
  22336. while (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === "nextInterval")
  22337. nowIndexTicks++;
  22338. fusPoints = [];
  22339. that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === true && fusPoints.push(point);
  22340. if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
  22341. lastPointIndex++
  22342. }
  22343. });
  22344. if (fusPoints.length) {
  22345. var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
  22346. if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
  22347. lastPointIndex++
  22348. }
  22349. that._correctPointsLength(lastPointIndex, that._aggregatedPoints);
  22350. that._endUpdateData();
  22351. return that._aggregatedPoints
  22352. },
  22353. _isInInterval: function(argument, ticks, nowIndexTicks, ticksInterval) {
  22354. var minTick = ticks[nowIndexTicks],
  22355. maxTick = ticks[nowIndexTicks + 1],
  22356. sumMinTickTicksInterval;
  22357. ticksInterval = $.isNumeric(ticksInterval) ? ticksInterval : utils.dateToMilliseconds(ticksInterval);
  22358. sumMinTickTicksInterval = utils.isDate(minTick) ? new Date(minTick.getTime() + ticksInterval) : minTick + ticksInterval;
  22359. if (argument >= minTick && argument < sumMinTickTicksInterval)
  22360. return true;
  22361. if (argument < minTick || maxTick === undefined)
  22362. return false;
  22363. return "nextInterval"
  22364. },
  22365. canRenderCompleteHandle: function() {
  22366. var result = this._canRenderCompleteHandle;
  22367. delete this._canRenderCompleteHandle;
  22368. return !!result
  22369. },
  22370. isHovered: function() {
  22371. return !!(this.fullState & 1)
  22372. },
  22373. isSelected: function() {
  22374. return !!(this.fullState & 2)
  22375. },
  22376. isVisible: function() {
  22377. return this._visible
  22378. },
  22379. getAllPoints: function() {
  22380. return (this._originalPoints || []).slice()
  22381. },
  22382. getPointByPos: function(pos) {
  22383. return (this._points || [])[pos]
  22384. },
  22385. getVisiblePoints: function() {
  22386. return (this._drawedPoints || []).slice()
  22387. },
  22388. setPointHoverState: function(point, legendCallback) {
  22389. point.fullState = point.fullState | HOVER_STATE;
  22390. if (!(this.isSelected() && includePointsMode(this.lastSelectionMode)) && !point.isSelected()) {
  22391. point.applyStyle(HOVER);
  22392. legendCallback && legendCallback("applyHover")
  22393. }
  22394. },
  22395. releasePointHoverState: function(point, legendCallback) {
  22396. var that = this;
  22397. point.fullState = point.fullState & ~HOVER_STATE;
  22398. if (!(that.isSelected() && includePointsMode(that.lastSelectionMode)) && !point.isSelected())
  22399. if (!(that.isHovered() && includePointsMode(that.lastHoverMode)) || that.isSelected() && that.lastSelectionMode === EXLUDE_POINTS) {
  22400. point.applyStyle(NORMAL);
  22401. legendCallback && legendCallback("resetItem")
  22402. }
  22403. },
  22404. setPointSelectedState: function(point, legendCallback) {
  22405. point.fullState = point.fullState | SELECTED_STATE;
  22406. point.applyStyle(SELECTION);
  22407. legendCallback && legendCallback("applySelected")
  22408. },
  22409. releasePointSelectedState: function(point, legendCallback) {
  22410. var that = this;
  22411. point.fullState = point.fullState & ~SELECTED_STATE;
  22412. if (that.isHovered() && includePointsMode(that.lastHoverMode) || point.isHovered()) {
  22413. point.applyStyle(HOVER);
  22414. legendCallback && legendCallback("applyHover")
  22415. }
  22416. else if (that.isSelected() && includePointsMode(that.lastSelectionMode)) {
  22417. point.applyStyle(SELECTION);
  22418. legendCallback && legendCallback("applySelected")
  22419. }
  22420. else {
  22421. point.applyStyle(NORMAL);
  22422. legendCallback && legendCallback("resetItem")
  22423. }
  22424. },
  22425. selectPoint: function(point) {
  22426. triggerEvent(this._extGroups.seriesGroup, new _Event("selectpoint"), point)
  22427. },
  22428. deselectPoint: function(point) {
  22429. triggerEvent(this._extGroups.seriesGroup, new _Event("deselectpoint"), point)
  22430. },
  22431. showPointTooltip: function(point) {
  22432. triggerEvent(this._extGroups.seriesGroup, new _Event("showpointtooltip"), point)
  22433. },
  22434. hidePointTooltip: function(point) {
  22435. triggerEvent(this._extGroups.seriesGroup, new _Event("hidepointtooltip"), point)
  22436. },
  22437. select: function() {
  22438. var that = this;
  22439. triggerEvent(that._extGroups.seriesGroup, new _Event("selectseries", {target: that}), that._options.selectionMode);
  22440. that._group.toForeground()
  22441. },
  22442. clearSelection: function clearSelection() {
  22443. var that = this;
  22444. triggerEvent(that._extGroups.seriesGroup, new _Event("deselectseries", {target: that}), that._options.selectionMode)
  22445. },
  22446. getPointByArg: function(arg) {
  22447. return this.getPointsByArg(arg)[0] || null
  22448. },
  22449. getPointsByArg: function(arg) {
  22450. return this.pointsByArgument[arg.valueOf()] || []
  22451. },
  22452. _deletePoints: function() {
  22453. var that = this;
  22454. that._disposePoints(that._originalPoints);
  22455. that._disposePoints(that._aggregatedPoints);
  22456. that._disposePoints(that._oldPoints);
  22457. that._points = null;
  22458. that._oldPoints = null;
  22459. that._aggregatedPoints = null;
  22460. that._originalPoints = null;
  22461. that._drawedPoints = null
  22462. },
  22463. _deletePatterns: function() {
  22464. _each(this._patterns || [], function(_, pattern) {
  22465. pattern && pattern.dispose()
  22466. });
  22467. this._patterns = null
  22468. },
  22469. _deleteTrackers: function() {
  22470. var that = this;
  22471. _each(that._trackers || [], function(_, tracker) {
  22472. tracker.remove()
  22473. });
  22474. that._trackersGroup && that._trackersGroup.dispose();
  22475. that._trackers = that._trackersGroup = null
  22476. },
  22477. dispose: function() {
  22478. var that = this;
  22479. that._deletePoints();
  22480. that._group.dispose();
  22481. that._labelsGroup && that._labelsGroup.dispose();
  22482. that._errorBarGroup && that._errorBarGroup.dispose();
  22483. that._deletePatterns();
  22484. that._deleteTrackers();
  22485. that._group = that._extGroups = that._markersGroup = that._elementsGroup = that._bordersGroup = that._labelsGroup = that._errorBarGroup = that._graphics = that._rangeData = that._renderer = that.translators = that._styles = that._options = that._pointOptions = that._drawedPoints = that._aggregatedPoints = that.pointsByArgument = that._segments = that._prevSeries = null
  22486. },
  22487. correctPosition: _noop,
  22488. drawTrackers: _noop,
  22489. getNeighborPoint: _noop,
  22490. areErrorBarsVisible: _noop,
  22491. getColor: function() {
  22492. return this.getLegendStyles().normal.fill
  22493. },
  22494. getOpacity: function() {
  22495. return this._options.opacity
  22496. },
  22497. getStackName: function() {
  22498. return this.type === "stackedbar" || this.type === "fullstackedbar" ? this._stackName : null
  22499. },
  22500. getPointByCoord: function(x, y) {
  22501. var point = this.getNeighborPoint(x, y);
  22502. return point && point.coordsIn(x, y) ? point : null
  22503. }
  22504. }
  22505. })(jQuery, DevExpress);
  22506. /*! Module viz-core, file rangeDataCalculator.js */
  22507. (function($, DX, undefined) {
  22508. var _math = Math,
  22509. _abs = _math.abs,
  22510. _min = _math.min,
  22511. _max = _math.max,
  22512. _each = $.each,
  22513. _isEmptyObject = $.isEmptyObject,
  22514. _isDefined = DX.utils.isDefined,
  22515. _isFinite = isFinite,
  22516. MIN_VISIBLE = "minVisible",
  22517. MAX_VISIBLE = "maxVisible",
  22518. DISCRETE = "discrete";
  22519. function _truncateValue(data, value) {
  22520. var min = data.min,
  22521. max = data.max;
  22522. data.min = value < min || !_isDefined(min) ? value : min;
  22523. data.max = value > max || !_isDefined(max) ? value : max
  22524. }
  22525. function _processValue(series, type, value, prevValue, calcInterval) {
  22526. var axis = type === "arg" ? "argument" : "value",
  22527. data = series._rangeData[type],
  22528. minInterval = data.interval,
  22529. interval;
  22530. if (series[axis + "AxisType"] === DISCRETE) {
  22531. data.categories = data.categories || [];
  22532. data.categories.push(value)
  22533. }
  22534. else {
  22535. _truncateValue(data, value);
  22536. if (type === "arg") {
  22537. interval = (_isDefined(prevValue) ? _abs(calcInterval ? calcInterval(value, prevValue) : value - prevValue) : interval) || minInterval;
  22538. data.interval = _isDefined(interval) && (interval < minInterval || !_isDefined(minInterval)) ? interval : minInterval
  22539. }
  22540. }
  22541. }
  22542. function _addToVisibleRange(series, value) {
  22543. var data = series._rangeData.val,
  22544. isDiscrete = series.valueAxisType === DISCRETE;
  22545. if (!isDiscrete) {
  22546. if (value < data.minVisible || !_isDefined(data.minVisible))
  22547. data.minVisible = value;
  22548. if (value > data.maxVisible || !_isDefined(data.maxVisible))
  22549. data.maxVisible = value
  22550. }
  22551. }
  22552. function _processRangeValue(series, val, minVal) {
  22553. var data = series._rangeData.val;
  22554. if (series.valueAxisType === DISCRETE) {
  22555. data.categories = data.categories || [];
  22556. data.categories.push(val, minVal)
  22557. }
  22558. else {
  22559. _truncateValue(data, val);
  22560. _truncateValue(data, minVal)
  22561. }
  22562. }
  22563. function _unique(array) {
  22564. var values = {};
  22565. return $.map(array, function(item) {
  22566. var result = !values[item] ? item : null;
  22567. values[item] = true;
  22568. return result
  22569. })
  22570. }
  22571. function _processZoomArgument(series, zoomArgs, isDiscrete) {
  22572. var data = series._rangeData.arg,
  22573. minArg,
  22574. maxArg;
  22575. if (isDiscrete) {
  22576. data.minVisible = zoomArgs.minArg;
  22577. data.maxVisible = zoomArgs.maxArg;
  22578. return
  22579. }
  22580. minArg = zoomArgs.minArg < zoomArgs.maxArg ? zoomArgs.minArg : zoomArgs.maxArg;
  22581. maxArg = zoomArgs.maxArg > zoomArgs.minArg ? zoomArgs.maxArg : zoomArgs.minArg;
  22582. data.min = minArg < data.min ? minArg : data.min;
  22583. data.max = maxArg > data.max ? maxArg : data.max;
  22584. data.minVisible = minArg;
  22585. data.maxVisible = maxArg
  22586. }
  22587. function _correctZoomValue(series, zoomArgs) {
  22588. var minVal,
  22589. maxVal;
  22590. if (_isDefined(zoomArgs.minVal) && _isDefined(zoomArgs.maxVal)) {
  22591. minVal = zoomArgs.minVal < zoomArgs.maxVal ? zoomArgs.minVal : zoomArgs.maxVal;
  22592. maxVal = zoomArgs.maxVal > zoomArgs.minVal ? zoomArgs.maxVal : zoomArgs.minVal
  22593. }
  22594. if (_isDefined(zoomArgs.minVal)) {
  22595. series._rangeData.val.min = minVal < series._rangeData.val.min ? minVal : series._rangeData.val.min;
  22596. series._rangeData.val.minVisible = minVal
  22597. }
  22598. if (_isDefined(zoomArgs.maxVal)) {
  22599. series._rangeData.val.max = maxVal > series._rangeData.val.max ? maxVal : series._rangeData.val.max;
  22600. series._rangeData.val.maxVisible = maxVal
  22601. }
  22602. }
  22603. function _processZoomValue(series, zoomArgs) {
  22604. var adjustOnZoom = zoomArgs.adjustOnZoom,
  22605. points = series._points || [],
  22606. lastVisibleIndex,
  22607. prevPointAdded = false,
  22608. rangeData = series._rangeData,
  22609. errorBarCorrector = series._rangeErrorBarCorrector;
  22610. _each(points, function(index, point) {
  22611. var arg = point.argument,
  22612. prevPoint = index > 0 ? points[index - 1] : null;
  22613. if (adjustOnZoom && series.argumentAxisType !== DISCRETE && arg >= rangeData.arg.minVisible && arg <= rangeData.arg.maxVisible) {
  22614. if (!prevPointAdded) {
  22615. if (prevPoint && prevPoint.hasValue()) {
  22616. _addToVisibleRange(series, prevPoint.value);
  22617. _correctMinMaxByErrorBar(rangeData.val, prevPoint, errorBarCorrector, MIN_VISIBLE, MAX_VISIBLE)
  22618. }
  22619. prevPointAdded = true
  22620. }
  22621. if (point.hasValue()) {
  22622. _addToVisibleRange(series, point.value);
  22623. _correctMinMaxByErrorBar(rangeData.val, point, errorBarCorrector, MIN_VISIBLE, MAX_VISIBLE)
  22624. }
  22625. lastVisibleIndex = index
  22626. }
  22627. });
  22628. if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
  22629. _addToVisibleRange(series, points[lastVisibleIndex + 1].value);
  22630. _correctZoomValue(series, zoomArgs)
  22631. }
  22632. function _processZoomRangeValue(series, zoomArgs, maxValueName, minValueName) {
  22633. var adjustOnZoom = zoomArgs.adjustOnZoom,
  22634. points = series._points || [],
  22635. argRangeData = series._rangeData.arg,
  22636. lastVisibleIndex,
  22637. prevPointAdded = false;
  22638. _each(points, function(index, point) {
  22639. var arg = point.argument,
  22640. prevPoint = index > 0 ? points[index - 1] : null;
  22641. if (adjustOnZoom && series.argumentAxisType !== DISCRETE && arg >= argRangeData.minVisible && arg <= argRangeData.maxVisible) {
  22642. if (!prevPointAdded) {
  22643. if (prevPoint && prevPoint.hasValue()) {
  22644. _addToVisibleRange(series, prevPoint[maxValueName]);
  22645. _addToVisibleRange(series, prevPoint[minValueName])
  22646. }
  22647. prevPointAdded = true
  22648. }
  22649. if (point.hasValue()) {
  22650. _addToVisibleRange(series, point[maxValueName]);
  22651. _addToVisibleRange(series, point[minValueName])
  22652. }
  22653. lastVisibleIndex = index
  22654. }
  22655. });
  22656. if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
  22657. _addToVisibleRange(series, points[lastVisibleIndex + 1].value);
  22658. _correctZoomValue(series, zoomArgs)
  22659. }
  22660. function _processNewInterval(series, calcInterval) {
  22661. var data = series._rangeData,
  22662. points = series._points || [],
  22663. isArgumentAxisDiscrete = series.argumentAxisType === DISCRETE;
  22664. delete data.arg.interval;
  22665. _each(points, function(index, point) {
  22666. var arg = point.argument,
  22667. prevPoint = index > 0 ? points[index - 1] : null,
  22668. prevArg = prevPoint && prevPoint.argument;
  22669. !isArgumentAxisDiscrete && _processValue(series, "arg", arg, prevArg, calcInterval)
  22670. })
  22671. }
  22672. function _fillRangeData(series) {
  22673. var data = series._rangeData;
  22674. data.arg.categories && (data.arg.categories = _unique(data.arg.categories));
  22675. data.val.categories && (data.val.categories = _unique(data.val.categories));
  22676. data.arg.axisType = series.argumentAxisType;
  22677. data.arg.dataType = series.argumentType;
  22678. data.val.axisType = series.valueAxisType;
  22679. data.val.dataType = series.valueType;
  22680. data.val.isValueRange = true
  22681. }
  22682. function processTwoValues(series, point, prevPoint, highValueName, lowValueName) {
  22683. var val = point[highValueName],
  22684. minVal = point[lowValueName],
  22685. arg = point.argument,
  22686. prevVal = prevPoint && prevPoint[highValueName],
  22687. prevMinVal = prevPoint && prevPoint[lowValueName],
  22688. prevArg = prevPoint && prevPoint.argument;
  22689. point.hasValue() && _processRangeValue(series, val, minVal, prevVal, prevMinVal);
  22690. _processValue(series, "arg", arg, prevArg)
  22691. }
  22692. function calculateRangeMinValue(series, zoomArgs) {
  22693. var data = series._rangeData.val,
  22694. minVisible = data[MIN_VISIBLE],
  22695. maxVisible = data[MAX_VISIBLE];
  22696. zoomArgs = zoomArgs || {};
  22697. if (data)
  22698. if (series.valueAxisType !== "logarithmic" && series.valueType !== "datetime" && series.showZero !== false) {
  22699. data[MIN_VISIBLE] = minVisible > (zoomArgs.minVal || 0) ? zoomArgs.minVal || 0 : minVisible;
  22700. data[MAX_VISIBLE] = maxVisible < (zoomArgs.maxVal || 0) ? zoomArgs.maxVal || 0 : maxVisible;
  22701. data.min = data.min > 0 ? 0 : data.min;
  22702. data.max = data.max < 0 ? 0 : data.max
  22703. }
  22704. }
  22705. function processFullStackedRange(series) {
  22706. var data = series._rangeData.val,
  22707. isRangeEmpty = _isEmptyObject(data);
  22708. data.percentStick = true;
  22709. !isRangeEmpty && (data.min = 0)
  22710. }
  22711. function _correctMinMaxByErrorBar(data, point, getMinMaxCorrector, minSelector, maxSelector) {
  22712. if (!getMinMaxCorrector)
  22713. return;
  22714. var correctionData = getMinMaxCorrector(point),
  22715. minError = _min.apply(undefined, correctionData),
  22716. maxError = _max.apply(undefined, correctionData);
  22717. if (_isFinite(minError) && data[minSelector] > minError)
  22718. data[minSelector] = minError;
  22719. if (_isFinite(maxError) && data[maxSelector] < maxError)
  22720. data[maxSelector] = maxError
  22721. }
  22722. function processRange(series, point, prevPoint, getMinMaxCorrector) {
  22723. var val = point.value,
  22724. arg = point.argument,
  22725. prevVal = prevPoint && prevPoint.value,
  22726. prevArg = prevPoint && prevPoint.argument;
  22727. point.hasValue() && _processValue(series, "val", val, prevVal);
  22728. _processValue(series, "arg", arg, prevArg);
  22729. _correctMinMaxByErrorBar(series._rangeData.val, point, getMinMaxCorrector, "min", "max")
  22730. }
  22731. function addLabelPaddings(series) {
  22732. var labelOptions = series.getOptions().label,
  22733. valueData;
  22734. if (series.areLabelsVisible() && labelOptions && labelOptions.visible && labelOptions.position !== "inside") {
  22735. valueData = series._rangeData.val;
  22736. if (valueData.min < 0)
  22737. valueData.minSpaceCorrection = true;
  22738. if (valueData.max > 0)
  22739. valueData.maxSpaceCorrection = true
  22740. }
  22741. }
  22742. function addRangeSeriesLabelPaddings(series) {
  22743. var data = series._rangeData.val;
  22744. if (series.areLabelsVisible() && series._options.label.visible && series._options.label.position !== "inside")
  22745. data.minSpaceCorrection = data.maxSpaceCorrection = true
  22746. }
  22747. function calculateRangeData(series, zoomArgs, calcIntervalFunction, maxValueName, minValueName) {
  22748. var valueData = series._rangeData.val,
  22749. isRangeSeries = !!maxValueName && !!minValueName,
  22750. isDiscrete = series.argumentAxisType === DISCRETE;
  22751. if (zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {
  22752. if (!isDiscrete) {
  22753. valueData[MIN_VISIBLE] = zoomArgs.minVal;
  22754. valueData[MAX_VISIBLE] = zoomArgs.maxVal
  22755. }
  22756. _processZoomArgument(series, zoomArgs, isDiscrete);
  22757. if (isRangeSeries)
  22758. _processZoomRangeValue(series, zoomArgs, maxValueName, minValueName);
  22759. else
  22760. _processZoomValue(series, zoomArgs)
  22761. }
  22762. else if (!zoomArgs && calcIntervalFunction)
  22763. _processNewInterval(series, calcIntervalFunction);
  22764. _fillRangeData(series)
  22765. }
  22766. DX.viz.core.series.helpers.rangeDataCalculator = {
  22767. processRange: processRange,
  22768. calculateRangeData: calculateRangeData,
  22769. addLabelPaddings: addLabelPaddings,
  22770. addRangeSeriesLabelPaddings: addRangeSeriesLabelPaddings,
  22771. processFullStackedRange: processFullStackedRange,
  22772. calculateRangeMinValue: calculateRangeMinValue,
  22773. processTwoValues: processTwoValues
  22774. }
  22775. })(jQuery, DevExpress);
  22776. /*! Module viz-core, file scatterSeries.js */
  22777. (function($, DX) {
  22778. var series = DX.viz.core.series,
  22779. rangeCalculator = series.helpers.rangeDataCalculator,
  22780. chartSeries = series.mixins.chart,
  22781. _each = $.each,
  22782. _extend = $.extend,
  22783. _map = $.map,
  22784. _noop = $.noop,
  22785. _utils = DX.utils,
  22786. _isDefined = _utils.isDefined,
  22787. _isString = _utils.isString,
  22788. math = Math,
  22789. _floor = math.floor,
  22790. _abs = math.abs,
  22791. _sqrt = math.sqrt,
  22792. _min = math.min,
  22793. _max = math.max,
  22794. DEFAULT_SYMBOL_POINT_SIZE = 2,
  22795. DEFAULT_TRACKER_WIDTH = 20,
  22796. DEFAULT_DURATION = 400,
  22797. HIGH_ERROR = "highError",
  22798. LOW_ERROR = "lowError",
  22799. ORIGINAL = "original",
  22800. VARIANCE = "variance",
  22801. STANDARD_DEVIATION = "stddeviation",
  22802. STANDARD_ERROR = "stderror",
  22803. PERCENT = "percent",
  22804. FIXED = "fixed",
  22805. UNDEFINED = "undefined",
  22806. DISCRETE = "discrete",
  22807. LOGARITHMIC = "logarithmic",
  22808. DATETIME = "datetime";
  22809. function sum(array) {
  22810. var summa = 0;
  22811. _each(array, function(_, value) {
  22812. summa += value
  22813. });
  22814. return summa
  22815. }
  22816. function toLowerCase(value) {
  22817. return value.toLowerCase()
  22818. }
  22819. function isErrorBarTypeCorrect(type) {
  22820. return $.inArray(type, [FIXED, PERCENT, VARIANCE, STANDARD_DEVIATION, STANDARD_ERROR, UNDEFINED]) !== -1
  22821. }
  22822. function variance(array, expectedValue) {
  22823. return sum($.map(array, function(value) {
  22824. return (value - expectedValue) * (value - expectedValue)
  22825. })) / array.length
  22826. }
  22827. var baseScatterMethods = {
  22828. _defaultDuration: DEFAULT_DURATION,
  22829. _defaultTrackerWidth: DEFAULT_TRACKER_WIDTH,
  22830. _applyStyle: _noop,
  22831. _updateOptions: _noop,
  22832. _parseStyle: _noop,
  22833. _prepareSegment: _noop,
  22834. _drawSegment: _noop,
  22835. _generateDefaultSegments: _noop,
  22836. _prepareSeriesToDrawing: function() {
  22837. var that = this;
  22838. that._deleteOldAnimationMethods();
  22839. that._firstDrawing && that._clearSeries();
  22840. that._disposePoints(that._oldPoints);
  22841. that._oldPoints = null
  22842. },
  22843. _createLegendState: function(styleOptions, defaultColor) {
  22844. return {
  22845. fill: styleOptions.color || defaultColor,
  22846. hatching: styleOptions.hatching
  22847. }
  22848. },
  22849. updateTeamplateFieldNames: function() {
  22850. var that = this,
  22851. options = that._options;
  22852. options.valueField = that.getValueFields()[0] + that.name;
  22853. options.tagField = that.getTagField() + that.name
  22854. },
  22855. _applyElementsClipRect: function(settings) {
  22856. settings.clipId = this._paneClipRectID
  22857. },
  22858. _applyMarkerClipRect: function(settings) {
  22859. settings.clipId = this._forceClipping ? this._paneClipRectID : null
  22860. },
  22861. _createGroup: function(groupName, parent, target, settings) {
  22862. var group = parent[groupName] = parent[groupName] || this._renderer.g();
  22863. group.attr(settings).append(target)
  22864. },
  22865. _applyClearingSettings: function(settings) {
  22866. settings.opacity = null;
  22867. settings.scale = null;
  22868. if (this._options.rotated)
  22869. settings.translateX = null;
  22870. else
  22871. settings.translateY = null
  22872. },
  22873. _createMarkerGroup: function() {
  22874. var that = this,
  22875. settings = that._getPointOptions().styles.normal;
  22876. settings["class"] = "dxc-markers";
  22877. settings.opacity = 1;
  22878. that._applyMarkerClipRect(settings);
  22879. that._createGroup("_markersGroup", that, that._group, settings)
  22880. },
  22881. _createLabelGroup: function() {
  22882. var that = this,
  22883. settings = {
  22884. "class": "dxc-labels",
  22885. visibility: that.getLabelVisibility() ? "visible" : "hidden"
  22886. };
  22887. that._applyElementsClipRect(settings);
  22888. that._applyClearingSettings(settings);
  22889. that._createGroup("_labelsGroup", that, that._extGroups.labelsGroup, settings)
  22890. },
  22891. areErrorBarsVisible: function() {
  22892. var errorBarOptions = this._options.valueErrorBar || {};
  22893. return this._errorBarsEnabled() && errorBarOptions.displayMode !== "none" && (isErrorBarTypeCorrect(toLowerCase(errorBarOptions.type + "")) || _isDefined(errorBarOptions.lowValueField) || _isDefined(errorBarOptions.highValueField))
  22894. },
  22895. _createErrorBarGroup: function(animationEnabled) {
  22896. var that = this,
  22897. errorBarOptions = that._options.valueErrorBar || {},
  22898. settings;
  22899. if (that.areErrorBarsVisible()) {
  22900. settings = {
  22901. "class": "dxc-error-bars",
  22902. stroke: errorBarOptions.color,
  22903. 'stroke-width': errorBarOptions.lineWidth,
  22904. opacity: animationEnabled ? 0.001 : errorBarOptions.opacity || 1,
  22905. "stroke-linecap": "square",
  22906. sharp: true,
  22907. clipId: that._forceClipping ? that._paneClipRectID : that._widePaneClipRectID
  22908. };
  22909. that._createGroup("_errorBarGroup", that, that._group, settings)
  22910. }
  22911. },
  22912. _createGroups: function(animationEnabled) {
  22913. var that = this;
  22914. that._createMarkerGroup();
  22915. that._createLabelGroup();
  22916. that._createErrorBarGroup(animationEnabled);
  22917. animationEnabled && that._labelsGroup && that._labelsGroup.attr({opacity: 0.001})
  22918. },
  22919. _getCreatingPointOptions: function() {
  22920. var that = this,
  22921. defaultPointOptions,
  22922. creatingPointOptions = that._predefinedPointOptions,
  22923. normalStyle;
  22924. if (!creatingPointOptions) {
  22925. defaultPointOptions = that._getPointOptions();
  22926. that._predefinedPointOptions = creatingPointOptions = _extend(true, {styles: {}}, defaultPointOptions);
  22927. normalStyle = defaultPointOptions.styles && defaultPointOptions.styles.normal || {};
  22928. creatingPointOptions.styles = creatingPointOptions.styles || {};
  22929. creatingPointOptions.styles.normal = {
  22930. "stroke-width": normalStyle["stroke-width"],
  22931. r: normalStyle.r,
  22932. opacity: normalStyle.opacity
  22933. }
  22934. }
  22935. return creatingPointOptions
  22936. },
  22937. _getSpecialColor: function(mainSeriesColor) {
  22938. return mainSeriesColor
  22939. },
  22940. _getPointOptions: function() {
  22941. return this._parsePointOptions(this._preparePointOptions(), this._options.label)
  22942. },
  22943. _preparePointOptions: function(customOptions) {
  22944. var point = this._options.point;
  22945. return customOptions ? _extend(true, {}, point, customOptions) : point
  22946. },
  22947. _parsePointStyle: function(style, defaultColor, defaultBorderColor) {
  22948. var border = style.border || {};
  22949. return {
  22950. fill: style.color || defaultColor,
  22951. stroke: border.color || defaultBorderColor,
  22952. "stroke-width": border.visible ? border.width : 0,
  22953. r: style.size / 2 + (border.visible && style.size !== 0 ? ~~(border.width / 2) || 0 : 0)
  22954. }
  22955. },
  22956. _createPointStyles: function(pointOptions) {
  22957. var that = this,
  22958. mainPointColor = pointOptions.color || that._options.mainSeriesColor,
  22959. containerColor = that._options.containerBackgroundColor,
  22960. normalStyle = that._parsePointStyle(pointOptions, mainPointColor, mainPointColor);
  22961. normalStyle.visibility = pointOptions.visible ? "visible" : "hidden";
  22962. return {
  22963. normal: normalStyle,
  22964. hover: that._parsePointStyle(pointOptions.hoverStyle, containerColor, mainPointColor),
  22965. selection: that._parsePointStyle(pointOptions.selectionStyle, containerColor, mainPointColor)
  22966. }
  22967. },
  22968. _checkData: function(data) {
  22969. return _isDefined(data.argument) && data.value !== undefined
  22970. },
  22971. _getRangeCorrector: function() {
  22972. var errorBars = this.getOptions().valueErrorBar || {},
  22973. mode = toLowerCase(errorBars.displayMode + "");
  22974. return errorBars ? function(point) {
  22975. var lowError = point.lowError,
  22976. highError = point.highError;
  22977. switch (mode) {
  22978. case"low":
  22979. return [lowError];
  22980. case"high":
  22981. return [highError];
  22982. case"none":
  22983. return [];
  22984. default:
  22985. return [lowError, highError]
  22986. }
  22987. } : undefined
  22988. },
  22989. _processRange: function(point, prevPoint, errorBarCorrector) {
  22990. rangeCalculator.processRange(this, point, prevPoint, errorBarCorrector)
  22991. },
  22992. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  22993. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  22994. rangeCalculator.addLabelPaddings(this);
  22995. return this._rangeData
  22996. },
  22997. _getPointData: function(data, options) {
  22998. var pointData = {
  22999. value: data[options.valueField || "val"],
  23000. argument: data[options.argumentField || "arg"],
  23001. tag: data[options.tagField || "tag"]
  23002. };
  23003. this._fillErrorBars(data, pointData, options);
  23004. return pointData
  23005. },
  23006. _errorBarsEnabled: function() {
  23007. return this.valueAxisType !== DISCRETE && this.valueAxisType !== LOGARITHMIC && this.valueType !== DATETIME
  23008. },
  23009. _fillErrorBars: function(data, pointData, options) {
  23010. var errorBars = options.valueErrorBar || {};
  23011. if (this._errorBarsEnabled()) {
  23012. pointData.lowError = data[errorBars.lowValueField || LOW_ERROR];
  23013. pointData.highError = data[errorBars.highValueField || HIGH_ERROR]
  23014. }
  23015. },
  23016. _drawPoint: function(options) {
  23017. var point = options.point;
  23018. if (point.isInVisibleArea()) {
  23019. point.clearVisibility();
  23020. point.draw(this._renderer, options.groups, options.hasAnimation, options.firstDrawing);
  23021. this._drawedPoints.push(point)
  23022. }
  23023. else
  23024. point.setInvisibility()
  23025. },
  23026. _clearingAnimation: function(translators, drawComplete) {
  23027. var that = this,
  23028. params = {opacity: 0.001},
  23029. options = {
  23030. duration: that._defaultDuration,
  23031. partitionDuration: 0.5
  23032. };
  23033. that._labelsGroup && that._labelsGroup.animate(params, options, function() {
  23034. that._markersGroup && that._markersGroup.animate(params, options, drawComplete)
  23035. })
  23036. },
  23037. _animateComplete: function() {
  23038. var that = this,
  23039. animationSettings = {duration: that._defaultDuration};
  23040. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, animationSettings);
  23041. that._errorBarGroup && that._errorBarGroup.animate({opacity: (that._options.valueErrorBar || {}).opacity || 1}, animationSettings)
  23042. },
  23043. _animate: function() {
  23044. var that = this,
  23045. lastPointIndex = that._drawedPoints.length - 1;
  23046. _each(that._drawedPoints || [], function(i, p) {
  23047. p.animate(i === lastPointIndex ? function() {
  23048. that._animateComplete()
  23049. } : undefined, {
  23050. translateX: p.x,
  23051. translateY: p.y
  23052. })
  23053. })
  23054. },
  23055. _getPointSize: function() {
  23056. return this._options.point.visible ? this._options.point.size : DEFAULT_SYMBOL_POINT_SIZE
  23057. },
  23058. _calcMedianValue: function(fusionPoints, valueField) {
  23059. var result,
  23060. allValue = _map(fusionPoints, function(point) {
  23061. return point[valueField]
  23062. });
  23063. allValue.sort(function(a, b) {
  23064. return a - b
  23065. });
  23066. result = allValue[_floor(allValue.length / 2)];
  23067. return _isDefined(result) ? result : null
  23068. },
  23069. _calcErrorBarValues: function(fusionPoints) {
  23070. if (!fusionPoints.length)
  23071. return {};
  23072. var lowValue = fusionPoints[0].lowError,
  23073. highValue = fusionPoints[0].highError,
  23074. i = 1,
  23075. length = fusionPoints.length,
  23076. lowError,
  23077. highError;
  23078. for (i; i < length; i++) {
  23079. lowError = fusionPoints[i].lowError;
  23080. highError = fusionPoints[i].highError;
  23081. if (_isDefined(lowError) && _isDefined(highError)) {
  23082. lowValue = _min(lowError, lowValue);
  23083. highValue = _max(highError, highValue)
  23084. }
  23085. }
  23086. return {
  23087. low: lowValue,
  23088. high: highValue
  23089. }
  23090. },
  23091. _fusionPoints: function(fusionPoints, tick, index) {
  23092. var errorBarValues = this._calcErrorBarValues(fusionPoints);
  23093. return {
  23094. value: this._calcMedianValue(fusionPoints, "value"),
  23095. argument: tick,
  23096. tag: null,
  23097. index: index,
  23098. seriesName: this.name,
  23099. lowError: errorBarValues.low,
  23100. highError: errorBarValues.high
  23101. }
  23102. },
  23103. _endUpdateData: function() {
  23104. delete this._predefinedPointOptions
  23105. },
  23106. getArgumentField: function() {
  23107. return this._options.argumentField || "arg"
  23108. },
  23109. getValueFields: function() {
  23110. var options = this._options,
  23111. errorBarsOptions = options.valueErrorBar || {},
  23112. valueFields = [options.valueField || "val"],
  23113. lowValueField = errorBarsOptions.lowValueField,
  23114. highValueField = errorBarsOptions.highValueField;
  23115. _isString(lowValueField) && valueFields.push(lowValueField);
  23116. _isString(highValueField) && valueFields.push(highValueField);
  23117. return valueFields
  23118. },
  23119. _calculateErrorBars: function(data) {
  23120. var that = this,
  23121. options = that._options,
  23122. errorBarsOptions = options.valueErrorBar || {},
  23123. errorBarType = toLowerCase(errorBarsOptions.type + ""),
  23124. floatErrorValue = parseFloat(errorBarsOptions.value),
  23125. valueField = that.getValueFields()[0],
  23126. value,
  23127. lowValueField = errorBarsOptions.lowValueField || LOW_ERROR,
  23128. highValueField = errorBarsOptions.highValueField || HIGH_ERROR,
  23129. valueArray,
  23130. valueArrayLength,
  23131. meanValue,
  23132. processDataItem,
  23133. addSubError = function(_i, item) {
  23134. value = item[valueField];
  23135. item[lowValueField] = value - floatErrorValue;
  23136. item[highValueField] = value + floatErrorValue
  23137. };
  23138. if (!that._errorBarsEnabled() || !isErrorBarTypeCorrect(errorBarType))
  23139. return;
  23140. switch (errorBarType) {
  23141. case FIXED:
  23142. processDataItem = addSubError;
  23143. break;
  23144. case PERCENT:
  23145. processDataItem = function(_, item) {
  23146. value = item[valueField];
  23147. var error = value * floatErrorValue / 100;
  23148. item[lowValueField] = value - error;
  23149. item[highValueField] = value + error
  23150. };
  23151. break;
  23152. case UNDEFINED:
  23153. processDataItem = function(_, item) {
  23154. item[lowValueField] = item[ORIGINAL + lowValueField];
  23155. item[highValueField] = item[ORIGINAL + highValueField]
  23156. };
  23157. break;
  23158. default:
  23159. valueArray = $.map(data, function(item) {
  23160. return item[valueField]
  23161. });
  23162. valueArrayLength = valueArray.length;
  23163. floatErrorValue = floatErrorValue || 1;
  23164. switch (errorBarType) {
  23165. case VARIANCE:
  23166. floatErrorValue = variance(valueArray, sum(valueArray) / valueArrayLength) * floatErrorValue;
  23167. processDataItem = addSubError;
  23168. break;
  23169. case STANDARD_DEVIATION:
  23170. meanValue = sum(valueArray) / valueArrayLength;
  23171. floatErrorValue = _sqrt(variance(valueArray, meanValue)) * floatErrorValue;
  23172. processDataItem = function(_, item) {
  23173. item[lowValueField] = meanValue - floatErrorValue;
  23174. item[highValueField] = meanValue + floatErrorValue
  23175. };
  23176. break;
  23177. case STANDARD_ERROR:
  23178. floatErrorValue = _sqrt(variance(valueArray, sum(valueArray) / valueArrayLength) / valueArrayLength) * floatErrorValue;
  23179. processDataItem = addSubError;
  23180. break
  23181. }
  23182. }
  23183. processDataItem && _each(data, processDataItem)
  23184. },
  23185. _beginUpdateData: function(data) {
  23186. this._calculateErrorBars(data)
  23187. }
  23188. };
  23189. chartSeries.scatter = _extend({}, baseScatterMethods, {
  23190. drawTrackers: function() {
  23191. var that = this,
  23192. trackers,
  23193. trackersGroup,
  23194. segments = that._segments || [],
  23195. rotated = that._options.rotated,
  23196. cat = [];
  23197. if (!that.isVisible())
  23198. return;
  23199. if (segments.length) {
  23200. trackers = that._trackers = that._trackers || [];
  23201. trackersGroup = that._trackersGroup = (that._trackersGroup || that._renderer.g().attr({
  23202. fill: "gray",
  23203. opacity: 0.001,
  23204. stroke: "gray",
  23205. "class": "dxc-trackers"
  23206. })).attr({clipId: this._paneClipRectID || null}).append(that._group);
  23207. _each(segments, function(i, segment) {
  23208. if (!trackers[i])
  23209. trackers[i] = that._drawTrackerElement(segment).data({series: that}).append(trackersGroup);
  23210. else
  23211. that._updateTrackerElement(segment, trackers[i])
  23212. })
  23213. }
  23214. that._trackersTranslator = cat;
  23215. _each(that.getVisiblePoints(), function(_, p) {
  23216. var pointCoord = parseInt(rotated ? p.vy : p.vx);
  23217. if (!cat[pointCoord])
  23218. cat[pointCoord] = p;
  23219. else
  23220. $.isArray(cat[pointCoord]) ? cat[pointCoord].push(p) : cat[pointCoord] = [cat[pointCoord], p]
  23221. })
  23222. },
  23223. getNeighborPoint: function(x, y) {
  23224. var pCoord = this._options.rotated ? y : x,
  23225. nCoord = pCoord,
  23226. cat = this._trackersTranslator,
  23227. point = null,
  23228. minDistance,
  23229. oppositeCoord = this._options.rotated ? x : y,
  23230. opositeCoordName = this._options.rotated ? "vx" : "vy";
  23231. if (this.isVisible() && cat) {
  23232. point = cat[pCoord];
  23233. do {
  23234. point = cat[nCoord] || cat[pCoord];
  23235. pCoord--;
  23236. nCoord++
  23237. } while ((pCoord >= 0 || nCoord < cat.length) && !point);
  23238. if ($.isArray(point)) {
  23239. minDistance = _abs(point[0][opositeCoordName] - oppositeCoord);
  23240. _each(point, function(i, p) {
  23241. var distance = _abs(p[opositeCoordName] - oppositeCoord);
  23242. if (minDistance >= distance) {
  23243. minDistance = distance;
  23244. point = p
  23245. }
  23246. })
  23247. }
  23248. }
  23249. return point
  23250. }
  23251. });
  23252. series.mixins.polar.scatter = _extend({}, baseScatterMethods, {
  23253. drawTrackers: function() {
  23254. chartSeries.scatter.drawTrackers.call(this);
  23255. var cat = this._trackersTranslator,
  23256. index;
  23257. if (!this.isVisible())
  23258. return;
  23259. _each(cat, function(i, category) {
  23260. if (category) {
  23261. index = i;
  23262. return false
  23263. }
  23264. });
  23265. cat[index + 360] = cat[index]
  23266. },
  23267. getNeighborPoint: function(x, y) {
  23268. var pos = this.translators.untranslate(x, y);
  23269. return chartSeries.scatter.getNeighborPoint.call(this, pos.phi, pos.r)
  23270. }
  23271. })
  23272. })(jQuery, DevExpress);
  23273. /*! Module viz-core, file lineSeries.js */
  23274. (function($, DX) {
  23275. var core = DX.viz.core,
  23276. series = core.series,
  23277. chartSeries = series.mixins.chart,
  23278. polarSeries = series.mixins.polar,
  23279. utils = DX.utils,
  23280. scatterSeries = chartSeries.scatter,
  23281. rangeCalculator = core.series.helpers.rangeDataCalculator,
  23282. CANVAS_POSITION_START = "canvas_position_start",
  23283. CANVAS_POSITION_TOP = "canvas_position_top",
  23284. DISCRETE = "discrete",
  23285. _extend = $.extend,
  23286. _map = $.map,
  23287. _each = $.each;
  23288. function clonePoint(point, newX, newY, newAngle) {
  23289. var p = utils.clone(point);
  23290. p.x = newX;
  23291. p.y = newY;
  23292. p.angle = newAngle;
  23293. return p
  23294. }
  23295. function getTangentPoint(point, prevPoint, centerPoint, tan, nextStepAngle) {
  23296. var currectAngle = point.angle + nextStepAngle,
  23297. cossin = utils.getCosAndSin(currectAngle),
  23298. x = centerPoint.x + (point.radius + tan * nextStepAngle) * cossin.cos,
  23299. y = centerPoint.y - (point.radius + tan * nextStepAngle) * cossin.sin;
  23300. return clonePoint(prevPoint, x, y, currectAngle)
  23301. }
  23302. var lineMethods = {
  23303. _createElementsGroup: function(elementsStyle) {
  23304. var that = this,
  23305. settings = _extend({"class": "dxc-elements"}, elementsStyle);
  23306. that._applyElementsClipRect(settings);
  23307. that._createGroup("_elementsGroup", that, that._group, settings)
  23308. },
  23309. _createBordersGroup: function(borderStyle) {
  23310. var that = this,
  23311. settings = _extend({"class": "dxc-borders"}, borderStyle);
  23312. that._applyElementsClipRect(settings);
  23313. that._createGroup("_bordersGroup", that, that._group, settings)
  23314. },
  23315. _createGroups: function(animationEnabled, style) {
  23316. var that = this;
  23317. style = style || that._styles.normal;
  23318. that._createElementsGroup(style.elements);
  23319. that._areBordersVisible() && that._createBordersGroup(style.border);
  23320. scatterSeries._createGroups.call(that, animationEnabled, {});
  23321. animationEnabled && that._markersGroup && that._markersGroup.attr({opacity: 0.001})
  23322. },
  23323. _areBordersVisible: function() {
  23324. return false
  23325. },
  23326. _getDefaultSegment: function(segment) {
  23327. return {line: _map(segment.line || [], function(pt) {
  23328. return pt.getDefaultCoords()
  23329. })}
  23330. },
  23331. _prepareSegment: function(points) {
  23332. return {line: points}
  23333. },
  23334. _parseLineOptions: function(options, defaultColor) {
  23335. return {
  23336. stroke: options.color || defaultColor,
  23337. "stroke-width": options.width,
  23338. dashStyle: options.dashStyle || 'solid'
  23339. }
  23340. },
  23341. _parseStyle: function(options, defaultColor) {
  23342. return {elements: this._parseLineOptions(options, defaultColor)}
  23343. },
  23344. _applyStyle: function(style) {
  23345. var that = this;
  23346. that._elementsGroup && that._elementsGroup.attr(style.elements);
  23347. _each(that._graphics || [], function(_, graphic) {
  23348. graphic.line && graphic.line.attr({'stroke-width': style.elements["stroke-width"]}).sharp()
  23349. })
  23350. },
  23351. _drawElement: function(segment, group) {
  23352. return {line: this._createMainElement(segment.line, {"stroke-width": this._styles.normal.elements["stroke-width"]}).append(group)}
  23353. },
  23354. _removeElement: function(element) {
  23355. element.line.remove()
  23356. },
  23357. _generateDefaultSegments: function() {
  23358. var that = this;
  23359. return _map(that._segments || [], function(segment) {
  23360. return that._getDefaultSegment(segment)
  23361. })
  23362. },
  23363. _updateElement: function(element, segment, animate, animateParams, complete) {
  23364. var params = {points: segment.line},
  23365. lineElement = element.line;
  23366. animate ? lineElement.animate(params, animateParams, complete) : lineElement.attr(params)
  23367. },
  23368. _clearingAnimation: function(translator, drawComplete) {
  23369. var that = this,
  23370. lastIndex = that._graphics.length - 1,
  23371. settings = {opacity: 0.001},
  23372. options = {
  23373. duration: that._defaultDuration,
  23374. partitionDuration: 0.5
  23375. };
  23376. that._labelsGroup && that._labelsGroup.animate(settings, options, function() {
  23377. that._markersGroup && that._markersGroup.animate(settings, options, function() {
  23378. _each(that._defaultSegments || [], function(i, segment) {
  23379. that._oldUpdateElement(that._graphics[i], segment, true, {partitionDuration: 0.5}, i === lastIndex ? drawComplete : undefined)
  23380. })
  23381. })
  23382. })
  23383. },
  23384. _animateComplete: function() {
  23385. var that = this;
  23386. scatterSeries._animateComplete.call(this);
  23387. that._markersGroup && that._markersGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  23388. },
  23389. _animate: function() {
  23390. var that = this,
  23391. lastIndex = that._graphics.length - 1;
  23392. _each(that._graphics || [], function(i, elem) {
  23393. that._updateElement(elem, that._segments[i], true, {complete: i === lastIndex ? function() {
  23394. that._animateComplete()
  23395. } : undefined})
  23396. })
  23397. },
  23398. _drawPoint: function(options) {
  23399. scatterSeries._drawPoint.call(this, {
  23400. point: options.point,
  23401. groups: options.groups
  23402. })
  23403. },
  23404. _createMainElement: function(points, settings) {
  23405. return this._renderer.path(points, "line").attr(settings).sharp()
  23406. },
  23407. _drawSegment: function(points, animationEnabled, segmentCount, lastSegment) {
  23408. var that = this,
  23409. segment = that._prepareSegment(points, that._options.rotated, lastSegment);
  23410. that._segments.push(segment);
  23411. if (!that._graphics[segmentCount])
  23412. that._graphics[segmentCount] = that._drawElement(animationEnabled ? that._getDefaultSegment(segment) : segment, that._elementsGroup);
  23413. else if (!animationEnabled)
  23414. that._updateElement(that._graphics[segmentCount], segment)
  23415. },
  23416. _getTrackerSettings: function() {
  23417. var that = this,
  23418. elements = that._styles.normal.elements;
  23419. return {
  23420. "stroke-width": elements["stroke-width"] > that._defaultTrackerWidth ? elements["stroke-width"] : that._defaultTrackerWidth,
  23421. fill: "none"
  23422. }
  23423. },
  23424. _getMainPointsFromSegment: function(segment) {
  23425. return segment.line
  23426. },
  23427. _drawTrackerElement: function(segment) {
  23428. return this._createMainElement(this._getMainPointsFromSegment(segment), this._getTrackerSettings(segment))
  23429. },
  23430. _updateTrackerElement: function(segment, element) {
  23431. var settings = this._getTrackerSettings(segment);
  23432. settings.points = this._getMainPointsFromSegment(segment);
  23433. element.attr(settings)
  23434. }
  23435. };
  23436. chartSeries.line = _extend({}, scatterSeries, lineMethods);
  23437. chartSeries.stepline = _extend({}, chartSeries.line, {
  23438. _calculateStepLinePoints: function(points) {
  23439. var segment = [];
  23440. _each(points, function(i, pt) {
  23441. var stepY,
  23442. point;
  23443. if (!i) {
  23444. segment.push(pt);
  23445. return
  23446. }
  23447. stepY = segment[segment.length - 1].y;
  23448. if (stepY !== pt.y) {
  23449. point = utils.clone(pt);
  23450. point.y = stepY;
  23451. segment.push(point)
  23452. }
  23453. segment.push(pt)
  23454. });
  23455. return segment
  23456. },
  23457. _prepareSegment: function(points) {
  23458. return chartSeries.line._prepareSegment(this._calculateStepLinePoints(points))
  23459. }
  23460. });
  23461. chartSeries.stackedline = _extend({}, chartSeries.line, {});
  23462. chartSeries.fullstackedline = _extend({}, chartSeries.line, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  23463. var that = this;
  23464. rangeCalculator.calculateRangeData(that, zoomArgs, calcIntervalFunction);
  23465. rangeCalculator.addLabelPaddings(that);
  23466. rangeCalculator.processFullStackedRange(that);
  23467. return that._rangeData
  23468. }});
  23469. chartSeries.spline = _extend({}, chartSeries.line, {
  23470. _calculateBezierPoints: function(src, rotated) {
  23471. var bezierPoints = [],
  23472. pointsCopy = src,
  23473. checkExtr = function(otherPointCoord, pointCoord, controlCoord) {
  23474. return otherPointCoord > pointCoord && controlCoord > otherPointCoord || otherPointCoord < pointCoord && controlCoord < otherPointCoord ? otherPointCoord : controlCoord
  23475. };
  23476. if (pointsCopy.length !== 1)
  23477. _each(pointsCopy, function(i, curPoint) {
  23478. var leftControlX,
  23479. leftControlY,
  23480. rightControlX,
  23481. rightControlY,
  23482. prevPoint,
  23483. nextPoint,
  23484. xCur,
  23485. yCur,
  23486. x1,
  23487. x2,
  23488. y1,
  23489. y2,
  23490. lambda = 0.5,
  23491. curIsExtremum,
  23492. leftPoint,
  23493. rightPoint,
  23494. a,
  23495. b,
  23496. c,
  23497. xc,
  23498. yc,
  23499. shift;
  23500. if (!i) {
  23501. bezierPoints.push(curPoint);
  23502. bezierPoints.push(curPoint);
  23503. return
  23504. }
  23505. prevPoint = pointsCopy[i - 1];
  23506. if (i < pointsCopy.length - 1) {
  23507. nextPoint = pointsCopy[i + 1];
  23508. xCur = curPoint.x;
  23509. yCur = curPoint.y;
  23510. x1 = prevPoint.x;
  23511. x2 = nextPoint.x;
  23512. y1 = prevPoint.y;
  23513. y2 = nextPoint.y;
  23514. curIsExtremum = !!(!rotated && (yCur <= prevPoint.y && yCur <= nextPoint.y || yCur >= prevPoint.y && yCur >= nextPoint.y) || rotated && (xCur <= prevPoint.x && xCur <= nextPoint.x || xCur >= prevPoint.x && xCur >= nextPoint.x));
  23515. if (curIsExtremum)
  23516. if (!rotated) {
  23517. rightControlY = leftControlY = yCur;
  23518. rightControlX = (xCur + nextPoint.x) / 2;
  23519. leftControlX = (xCur + prevPoint.x) / 2
  23520. }
  23521. else {
  23522. rightControlX = leftControlX = xCur;
  23523. rightControlY = (yCur + nextPoint.y) / 2;
  23524. leftControlY = (yCur + prevPoint.y) / 2
  23525. }
  23526. else {
  23527. a = y2 - y1;
  23528. b = x1 - x2;
  23529. c = y1 * x2 - x1 * y2;
  23530. if (!rotated) {
  23531. xc = xCur;
  23532. yc = -1 * (a * xc + c) / b;
  23533. shift = yc - yCur || 0;
  23534. y1 -= shift;
  23535. y2 -= shift
  23536. }
  23537. else {
  23538. yc = yCur;
  23539. xc = -1 * (b * yc + c) / a;
  23540. shift = xc - xCur || 0;
  23541. x1 -= shift;
  23542. x2 -= shift
  23543. }
  23544. rightControlX = (xCur + lambda * x2) / (1 + lambda);
  23545. rightControlY = (yCur + lambda * y2) / (1 + lambda);
  23546. leftControlX = (xCur + lambda * x1) / (1 + lambda);
  23547. leftControlY = (yCur + lambda * y1) / (1 + lambda)
  23548. }
  23549. if (!rotated) {
  23550. leftControlY = checkExtr(prevPoint.y, yCur, leftControlY);
  23551. rightControlY = checkExtr(nextPoint.y, yCur, rightControlY)
  23552. }
  23553. else {
  23554. leftControlX = checkExtr(prevPoint.x, xCur, leftControlX);
  23555. rightControlX = checkExtr(nextPoint.x, xCur, rightControlX)
  23556. }
  23557. leftPoint = clonePoint(curPoint, leftControlX, leftControlY);
  23558. rightPoint = clonePoint(curPoint, rightControlX, rightControlY);
  23559. bezierPoints.push(leftPoint, curPoint, rightPoint)
  23560. }
  23561. else {
  23562. bezierPoints.push(curPoint, curPoint);
  23563. return
  23564. }
  23565. });
  23566. else
  23567. bezierPoints.push(pointsCopy[0]);
  23568. return bezierPoints
  23569. },
  23570. _prepareSegment: function(points, rotated) {
  23571. return chartSeries.line._prepareSegment(this._calculateBezierPoints(points, rotated))
  23572. },
  23573. _createMainElement: function(points, settings) {
  23574. return this._renderer.path(points, "bezier").attr(settings).sharp()
  23575. }
  23576. });
  23577. polarSeries.line = _extend({}, polarSeries.scatter, lineMethods, {
  23578. _prepareSegment: function(points, rotated, lastSegment) {
  23579. var preparedPoints = [],
  23580. centerPoint = this.translators.translate(CANVAS_POSITION_START, CANVAS_POSITION_TOP),
  23581. i;
  23582. lastSegment && this._closeSegment(points);
  23583. if (this.argumentAxisType !== DISCRETE && this.valueAxisType !== DISCRETE) {
  23584. for (i = 1; i < points.length; i++)
  23585. preparedPoints = preparedPoints.concat(this._getTangentPoints(points[i], points[i - 1], centerPoint));
  23586. if (!preparedPoints.length)
  23587. preparedPoints = points
  23588. }
  23589. else
  23590. return chartSeries.line._prepareSegment.apply(this, arguments);
  23591. return {line: preparedPoints}
  23592. },
  23593. _getRemainingAngle: function(angle) {
  23594. var normAngle = utils.normalizeAngle(angle);
  23595. return angle >= 0 ? 360 - normAngle : -normAngle
  23596. },
  23597. _closeSegment: function(points) {
  23598. var point,
  23599. differenceAngle;
  23600. if (this._segments.length)
  23601. point = this._segments[0].line[0];
  23602. else
  23603. point = clonePoint(points[0], points[0].x, points[0].y, points[0].angle);
  23604. if (points[points.length - 1].angle !== point.angle) {
  23605. if (utils.normalizeAngle(Math.round(points[points.length - 1].angle)) === utils.normalizeAngle(Math.round(point.angle)))
  23606. point.angle = points[points.length - 1].angle;
  23607. else {
  23608. differenceAngle = points[points.length - 1].angle - point.angle;
  23609. point.angle = points[points.length - 1].angle + this._getRemainingAngle(differenceAngle)
  23610. }
  23611. points.push(point)
  23612. }
  23613. },
  23614. _getTangentPoints: function(point, prevPoint, centerPoint) {
  23615. var tangentPoints = [],
  23616. betweenAngle = Math.round(prevPoint.angle - point.angle),
  23617. tan = (prevPoint.radius - point.radius) / betweenAngle,
  23618. i;
  23619. if (betweenAngle === 0)
  23620. tangentPoints = [prevPoint, point];
  23621. else if (betweenAngle > 0)
  23622. for (i = betweenAngle; i >= 0; i--)
  23623. tangentPoints.push(getTangentPoint(point, prevPoint, centerPoint, tan, i));
  23624. else
  23625. for (i = 0; i >= betweenAngle; i--)
  23626. tangentPoints.push(getTangentPoint(point, prevPoint, centerPoint, tan, betweenAngle - i));
  23627. return tangentPoints
  23628. }
  23629. })
  23630. })(jQuery, DevExpress);
  23631. /*! Module viz-core, file areaSeries.js */
  23632. (function($, DX) {
  23633. var core = DX.viz.core,
  23634. utils = DX.utils,
  23635. series = core.series,
  23636. chartSeries = series.mixins.chart,
  23637. polarSeries = series.mixins.polar,
  23638. lineSeries = chartSeries.line,
  23639. rangeCalculator = core.series.helpers.rangeDataCalculator,
  23640. _map = $.map,
  23641. _extend = $.extend,
  23642. HOVER_COLOR_HIGHLIGHTING = 20;
  23643. var baseAreaMethods = {
  23644. _createBorderElement: lineSeries._createMainElement,
  23645. _createLegendState: function(styleOptions, defaultColor) {
  23646. var legendState = chartSeries.scatter._createLegendState.call(this, styleOptions, defaultColor);
  23647. legendState.opacity = styleOptions.opacity;
  23648. return legendState
  23649. },
  23650. _getSpecialColor: function(color) {
  23651. return this._options._IE8 ? new DX.Color(color).highlight(HOVER_COLOR_HIGHLIGHTING) : color
  23652. },
  23653. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  23654. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  23655. rangeCalculator.addLabelPaddings(this);
  23656. rangeCalculator.calculateRangeMinValue(this, zoomArgs);
  23657. return this._rangeData
  23658. },
  23659. _getDefaultSegment: function(segment) {
  23660. var defaultSegment = lineSeries._getDefaultSegment(segment);
  23661. defaultSegment.area = defaultSegment.line.concat(defaultSegment.line.slice().reverse());
  23662. return defaultSegment
  23663. },
  23664. _updateElement: function(element, segment, animate, animateParams, complete) {
  23665. var lineParams = {points: segment.line},
  23666. areaParams = {points: segment.area},
  23667. borderElement = element.line;
  23668. if (animate) {
  23669. borderElement && borderElement.animate(lineParams, animateParams);
  23670. element.area.animate(areaParams, animateParams, complete)
  23671. }
  23672. else {
  23673. borderElement && borderElement.attr(lineParams);
  23674. element.area.attr(areaParams)
  23675. }
  23676. },
  23677. _removeElement: function(element) {
  23678. element.line && element.line.remove();
  23679. element.area.remove()
  23680. },
  23681. _drawElement: function(segment) {
  23682. return {
  23683. line: this._bordersGroup && this._createBorderElement(segment.line, {"stroke-width": this._styles.normal.border["stroke-width"]}).append(this._bordersGroup),
  23684. area: this._createMainElement(segment.area).append(this._elementsGroup)
  23685. }
  23686. },
  23687. _applyStyle: function(style) {
  23688. var that = this;
  23689. that._elementsGroup && that._elementsGroup.attr(style.elements);
  23690. that._bordersGroup && that._bordersGroup.attr(style.border);
  23691. $.each(that._graphics || [], function(_, graphic) {
  23692. graphic.line && graphic.line.attr({'stroke-width': style.border["stroke-width"]}).sharp()
  23693. })
  23694. },
  23695. _createPattern: function(color, hatching, custom) {
  23696. if (hatching && utils.isObject(hatching)) {
  23697. var pattern = this._renderer.pattern(color, hatching);
  23698. pattern._custom = custom;
  23699. this._patterns.push(pattern);
  23700. return pattern.id
  23701. }
  23702. return color
  23703. },
  23704. _parseStyle: function(options, defaultColor, defaultBorderColor) {
  23705. var borderOptions = options.border || {},
  23706. borderStyle = lineSeries._parseLineOptions(borderOptions, defaultBorderColor);
  23707. borderStyle["stroke-width"] = borderOptions.visible ? borderStyle["stroke-width"] : 0;
  23708. return {
  23709. border: borderStyle,
  23710. elements: {
  23711. stroke: "none",
  23712. fill: this._createPattern(options.color || defaultColor, options.hatching),
  23713. opacity: options.opacity
  23714. }
  23715. }
  23716. },
  23717. _areBordersVisible: function() {
  23718. var options = this._options;
  23719. return options.border.visible || options.hoverStyle.border.visible || options.selectionStyle.border.visible
  23720. },
  23721. _createMainElement: function(points, settings) {
  23722. return this._renderer.path(points, "area").attr(settings)
  23723. },
  23724. _getTrackerSettings: function(segment) {
  23725. return {"stroke-width": segment.singlePointSegment ? this._defaultTrackerWidth : 0}
  23726. },
  23727. _getMainPointsFromSegment: function(segment) {
  23728. return segment.area
  23729. }
  23730. };
  23731. chartSeries.area = _extend({}, lineSeries, baseAreaMethods, {
  23732. _prepareSegment: function(points, rotated) {
  23733. var processedPoints = this._processSinglePointsAreaSegment(points, rotated);
  23734. return {
  23735. line: processedPoints,
  23736. area: _map(processedPoints, function(pt) {
  23737. return pt.getCoords()
  23738. }).concat(_map(processedPoints.slice().reverse(), function(pt) {
  23739. return pt.getCoords(true)
  23740. })),
  23741. singlePointSegment: processedPoints !== points
  23742. }
  23743. },
  23744. _processSinglePointsAreaSegment: function(points, rotated) {
  23745. if (points.length === 1) {
  23746. var p = points[0],
  23747. p1 = utils.clone(p);
  23748. p1[rotated ? "y" : "x"] += 1;
  23749. p1.argument = null;
  23750. return [p, p1]
  23751. }
  23752. return points
  23753. }
  23754. });
  23755. polarSeries.area = _extend({}, polarSeries.line, baseAreaMethods, {
  23756. _prepareSegment: function(points, rotated, lastSegment) {
  23757. lastSegment && polarSeries.line._closeSegment.call(this, points);
  23758. var preparedPoints = chartSeries.area._prepareSegment.call(this, points);
  23759. return preparedPoints
  23760. },
  23761. _processSinglePointsAreaSegment: function(points) {
  23762. return polarSeries.line._prepareSegment.call(this, points).line
  23763. }
  23764. });
  23765. chartSeries.steparea = _extend({}, chartSeries.area, {_prepareSegment: function(points, rotated) {
  23766. points = chartSeries.area._processSinglePointsAreaSegment(points, rotated);
  23767. return chartSeries.area._prepareSegment.call(this, chartSeries.stepline._calculateStepLinePoints(points))
  23768. }});
  23769. chartSeries.splinearea = _extend({}, chartSeries.area, {
  23770. _areaPointsToSplineAreaPoints: function(areaPoints) {
  23771. var lastFwPoint = areaPoints[areaPoints.length / 2 - 1],
  23772. firstBwPoint = areaPoints[areaPoints.length / 2];
  23773. areaPoints.splice(areaPoints.length / 2, 0, {
  23774. x: lastFwPoint.x,
  23775. y: lastFwPoint.y
  23776. }, {
  23777. x: firstBwPoint.x,
  23778. y: firstBwPoint.y
  23779. });
  23780. if (lastFwPoint.defaultCoords)
  23781. areaPoints[areaPoints.length / 2].defaultCoords = true;
  23782. if (firstBwPoint.defaultCoords)
  23783. areaPoints[areaPoints.length / 2 - 1].defaultCoords = true
  23784. },
  23785. _prepareSegment: function(points, rotated) {
  23786. var areaSeries = chartSeries.area,
  23787. processedPoints = areaSeries._processSinglePointsAreaSegment(points, rotated),
  23788. areaSegment = areaSeries._prepareSegment.call(this, chartSeries.spline._calculateBezierPoints(processedPoints, rotated));
  23789. this._areaPointsToSplineAreaPoints(areaSegment.area);
  23790. areaSegment.singlePointSegment = processedPoints !== points;
  23791. return areaSegment
  23792. },
  23793. _getDefaultSegment: function(segment) {
  23794. var areaDefaultSegment = chartSeries.area._getDefaultSegment(segment);
  23795. this._areaPointsToSplineAreaPoints(areaDefaultSegment.area);
  23796. return areaDefaultSegment
  23797. },
  23798. _createMainElement: function(points, settings) {
  23799. return this._renderer.path(points, "bezierarea").attr(settings)
  23800. },
  23801. _createBorderElement: chartSeries.spline._createMainElement
  23802. })
  23803. })(jQuery, DevExpress);
  23804. /*! Module viz-core, file barSeries.js */
  23805. (function($, DX) {
  23806. var viz = DX.viz,
  23807. series = viz.core.series,
  23808. chartSeries = series.mixins.chart,
  23809. polarSeries = series.mixins.polar,
  23810. scatterSeries = chartSeries.scatter,
  23811. areaSeries = chartSeries.area,
  23812. _extend = $.extend,
  23813. _each = $.each,
  23814. DEFAULT_BAR_POINT_SIZE = 3;
  23815. var baseBarSeriesMethods = {
  23816. _getSpecialColor: areaSeries._getSpecialColor,
  23817. _createPattern: areaSeries._createPattern,
  23818. _updateOptions: function(options) {
  23819. this._stackName = "axis_" + (options.axis || "default") + "_stack_" + (options.stack || "default")
  23820. },
  23821. _parsePointStyle: function(style, defaultColor, defaultBorderColor, isCustomPointOptions) {
  23822. var color = this._createPattern(style.color || defaultColor, style.hatching, isCustomPointOptions),
  23823. base = scatterSeries._parsePointStyle.call(this, style, color, defaultBorderColor);
  23824. base.fill = color;
  23825. base.dashStyle = style.border && style.border.dashStyle || "solid";
  23826. delete base.r;
  23827. return base
  23828. },
  23829. _applyMarkerClipRect: function(settings) {
  23830. settings.clipId = null
  23831. },
  23832. _clearingAnimation: function(translators, drawComplete) {
  23833. var that = this,
  23834. settings = that._oldgetAffineCoordOptions(translators) || that._getAffineCoordOptions(translators);
  23835. that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {
  23836. duration: that._defaultDuration,
  23837. partitionDuration: 0.5
  23838. }, function() {
  23839. that._markersGroup.animate(settings, {partitionDuration: 0.5}, function() {
  23840. that._markersGroup.attr({
  23841. scaleX: null,
  23842. scaleY: null,
  23843. translateX: 0,
  23844. translateY: 0
  23845. });
  23846. drawComplete()
  23847. })
  23848. })
  23849. },
  23850. _createGroups: function(animationEnabled, style, firstDrawing) {
  23851. var that = this,
  23852. settings = {};
  23853. scatterSeries._createGroups.apply(that, arguments);
  23854. if (animationEnabled && firstDrawing)
  23855. settings = this._getAffineCoordOptions(that.translators, true);
  23856. else if (!animationEnabled)
  23857. settings = {
  23858. scaleX: 1,
  23859. scaleY: 1,
  23860. translateX: 0,
  23861. translateY: 0
  23862. };
  23863. that._markersGroup.attr(settings)
  23864. },
  23865. _drawPoint: function(options) {
  23866. options.hasAnimation = options.hasAnimation && !options.firstDrawing;
  23867. options.firstDrawing = false;
  23868. scatterSeries._drawPoint.call(this, options)
  23869. },
  23870. _getMainColor: function() {
  23871. return this._options.mainSeriesColor
  23872. },
  23873. _createPointStyles: function(pointOptions, isCustomPointOptions) {
  23874. var that = this,
  23875. mainColor = pointOptions.color || that._getMainColor(),
  23876. specialMainColor = that._getSpecialColor(mainColor);
  23877. return {
  23878. normal: that._parsePointStyle(pointOptions, mainColor, mainColor, isCustomPointOptions),
  23879. hover: that._parsePointStyle(pointOptions.hoverStyle || {}, specialMainColor, mainColor, isCustomPointOptions),
  23880. selection: that._parsePointStyle(pointOptions.selectionStyle || {}, specialMainColor, mainColor, isCustomPointOptions)
  23881. }
  23882. },
  23883. _updatePointsVisibility: function() {
  23884. var visibility = this._options.visible;
  23885. $.each(this._points, function(_, point) {
  23886. point._options.visible = visibility
  23887. })
  23888. },
  23889. _preparePointOptions: function(customOptions) {
  23890. var options = this._options;
  23891. return customOptions ? _extend(true, {}, options, customOptions) : options
  23892. },
  23893. _animate: function(firstDrawing) {
  23894. var that = this,
  23895. complete = function() {
  23896. that._animateComplete()
  23897. },
  23898. animateFunc = function(drawedPoints, complete) {
  23899. var lastPointIndex = drawedPoints.length - 1;
  23900. _each(drawedPoints || [], function(i, point) {
  23901. point.animate(i === lastPointIndex ? complete : undefined, point.getMarkerCoords())
  23902. })
  23903. };
  23904. that._animatePoints(firstDrawing, complete, animateFunc)
  23905. },
  23906. _getPointSize: function() {
  23907. return DEFAULT_BAR_POINT_SIZE
  23908. },
  23909. _beginUpdateData: function(data) {
  23910. scatterSeries._beginUpdateData.call(this, data);
  23911. this._patterns = $.map(this._patterns, function(pattern) {
  23912. if (pattern._custom) {
  23913. pattern.remove();
  23914. return null
  23915. }
  23916. else
  23917. return pattern
  23918. })
  23919. }
  23920. };
  23921. chartSeries.bar = _extend({}, scatterSeries, baseBarSeriesMethods, {
  23922. _getAffineCoordOptions: function(translators) {
  23923. var rotated = this._options.rotated,
  23924. direction = rotated ? "x" : "y",
  23925. settings = {
  23926. scaleX: rotated ? 0.001 : 1,
  23927. scaleY: rotated ? 1 : 0.001
  23928. };
  23929. settings["translate" + direction.toUpperCase()] = translators[direction].translate("canvas_position_default");
  23930. return settings
  23931. },
  23932. _getRangeData: function() {
  23933. var rangeData = areaSeries._getRangeData.apply(this, arguments);
  23934. rangeData.arg.stick = false;
  23935. return rangeData
  23936. },
  23937. _animatePoints: function(firstDrawing, complete, animateFunc) {
  23938. var that = this;
  23939. that._markersGroup.animate({
  23940. scaleX: 1,
  23941. scaleY: 1,
  23942. translateY: 0,
  23943. translateX: 0
  23944. }, undefined, complete);
  23945. if (!firstDrawing)
  23946. animateFunc(that._drawedPoints, complete)
  23947. }
  23948. });
  23949. polarSeries.bar = _extend({}, polarSeries.scatter, baseBarSeriesMethods, {
  23950. _animatePoints: function(firstDrawing, complete, animateFunc) {
  23951. animateFunc(this._drawedPoints, complete)
  23952. },
  23953. _createGroups: function() {
  23954. scatterSeries._createGroups.apply(this, arguments)
  23955. },
  23956. _drawPoint: function(point, groups, animationEnabled) {
  23957. scatterSeries._drawPoint.call(this, point, groups, animationEnabled)
  23958. },
  23959. _parsePointStyle: function(style) {
  23960. var base = baseBarSeriesMethods._parsePointStyle.apply(this, arguments);
  23961. base.opacity = style.opacity;
  23962. return base
  23963. },
  23964. _createMarkerGroup: function() {
  23965. var that = this,
  23966. markersSettings = that._getPointOptions().styles.normal,
  23967. groupSettings;
  23968. markersSettings["class"] = "dxc-markers";
  23969. that._applyMarkerClipRect(markersSettings);
  23970. groupSettings = _extend({}, markersSettings);
  23971. delete groupSettings.opacity;
  23972. that._createGroup("_markersGroup", that, that._group, groupSettings)
  23973. },
  23974. _createLegendState: areaSeries._createLegendState,
  23975. _getRangeData: areaSeries._getRangeData
  23976. })
  23977. })(jQuery, DevExpress);
  23978. /*! Module viz-core, file rangeSeries.js */
  23979. (function($, DX) {
  23980. var core = DX.viz.core,
  23981. series = core.series.mixins.chart,
  23982. _extend = $.extend,
  23983. _isDefined = DX.utils.isDefined,
  23984. _noop = $.noop,
  23985. rangeCalculator = core.series.helpers.rangeDataCalculator,
  23986. areaSeries = series.area;
  23987. var baseRangeSeries = {
  23988. _beginUpdateData: _noop,
  23989. areErrorBarsVisible: _noop,
  23990. _createErrorBarGroup: _noop,
  23991. _checkData: function(data) {
  23992. return _isDefined(data.argument) && data.value !== undefined && data.minValue !== undefined
  23993. },
  23994. updateTeamplateFieldNames: function() {
  23995. var that = this,
  23996. options = that._options,
  23997. valueFields = that.getValueFields(),
  23998. name = that.name;
  23999. options.rangeValue1Field = valueFields[0] + name;
  24000. options.rangeValue2Field = valueFields[1] + name;
  24001. options.tagField = that.getTagField() + name
  24002. },
  24003. _processRange: function(point, prevPoint) {
  24004. rangeCalculator.processTwoValues(this, point, prevPoint, "value", "minValue")
  24005. },
  24006. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  24007. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction, "value", "minValue");
  24008. rangeCalculator.addRangeSeriesLabelPaddings(this);
  24009. return this._rangeData
  24010. },
  24011. _getPointData: function(data, options) {
  24012. return {
  24013. tag: data[options.tagField || "tag"],
  24014. minValue: data[options.rangeValue1Field || "val1"],
  24015. value: data[options.rangeValue2Field || "val2"],
  24016. argument: data[options.argumentField || "arg"]
  24017. }
  24018. },
  24019. _fusionPoints: function(fusionPoints, tick) {
  24020. var calcMedianValue = series.scatter._calcMedianValue,
  24021. value = calcMedianValue.call(this, fusionPoints, "value"),
  24022. minValue = calcMedianValue.call(this, fusionPoints, "minValue");
  24023. if (value === null || minValue === null)
  24024. value = minValue = null;
  24025. return {
  24026. minValue: minValue,
  24027. value: value,
  24028. argument: tick,
  24029. tag: null
  24030. }
  24031. },
  24032. getValueFields: function() {
  24033. return [this._options.rangeValue1Field || "val1", this._options.rangeValue2Field || "val2"]
  24034. }
  24035. };
  24036. series.rangebar = _extend({}, series.bar, baseRangeSeries);
  24037. series.rangearea = _extend({}, areaSeries, {
  24038. _drawPoint: function(options) {
  24039. var point = options.point;
  24040. if (point.isInVisibleArea()) {
  24041. point.clearVisibility();
  24042. point.draw(this._renderer, options.groups);
  24043. this._drawedPoints.push(point);
  24044. if (!point.visibleTopMarker)
  24045. point.hideMarker("top");
  24046. if (!point.visibleBottomMarker)
  24047. point.hideMarker("bottom")
  24048. }
  24049. else
  24050. point.setInvisibility()
  24051. },
  24052. _prepareSegment: function(points, rotated) {
  24053. var processedPoints = this._processSinglePointsAreaSegment(points, rotated),
  24054. processedMinPointsCoords = $.map(processedPoints, function(pt) {
  24055. return pt.getCoords(true)
  24056. });
  24057. return {
  24058. line: processedPoints,
  24059. bottomLine: processedMinPointsCoords,
  24060. area: $.map(processedPoints, function(pt) {
  24061. return pt.getCoords()
  24062. }).concat(processedMinPointsCoords.slice().reverse()),
  24063. singlePointSegment: processedPoints !== points
  24064. }
  24065. },
  24066. _getDefaultSegment: function(segment) {
  24067. var defaultSegment = areaSeries._getDefaultSegment.call(this, segment);
  24068. defaultSegment.bottomLine = defaultSegment.line;
  24069. return defaultSegment
  24070. },
  24071. _removeElement: function(element) {
  24072. areaSeries._removeElement.call(this, element);
  24073. element.bottomLine && element.bottomLine.remove()
  24074. },
  24075. _drawElement: function(segment, group) {
  24076. var that = this,
  24077. drawnElement = areaSeries._drawElement.call(that, segment, group);
  24078. drawnElement.bottomLine = that._bordersGroup && that._createBorderElement(segment.bottomLine, {"stroke-width": that._styles.normal.border["stroke-width"]}).append(that._bordersGroup);
  24079. return drawnElement
  24080. },
  24081. _applyStyle: function(style) {
  24082. var that = this,
  24083. elementsGroup = that._elementsGroup,
  24084. bordersGroup = that._bordersGroup;
  24085. elementsGroup && elementsGroup.attr(style.elements);
  24086. bordersGroup && bordersGroup.attr(style.border);
  24087. $.each(that._graphics || [], function(_, graphic) {
  24088. graphic.line && graphic.line.attr({"stroke-width": style.border["stroke-width"]});
  24089. graphic.bottomLine && graphic.bottomLine.attr({"stroke-width": style.border["stroke-width"]})
  24090. })
  24091. },
  24092. _updateElement: function(element, segment, animate, animateParams, complete) {
  24093. areaSeries._updateElement.call(this, element, segment, animate, animateParams, complete);
  24094. var bottomLineParams = {points: segment.bottomLine},
  24095. bottomBorderElement = element.bottomLine;
  24096. if (bottomBorderElement)
  24097. animate ? bottomBorderElement.animate(bottomLineParams, animateParams) : bottomBorderElement.attr(bottomLineParams)
  24098. }
  24099. }, baseRangeSeries)
  24100. })(jQuery, DevExpress);
  24101. /*! Module viz-core, file bubbleSeries.js */
  24102. (function($, DX) {
  24103. var mixins = DX.viz.core.series.mixins,
  24104. series = mixins.chart,
  24105. scatterSeries = series.scatter,
  24106. barSeries = series.bar,
  24107. _isDefined = DX.utils.isDefined,
  24108. _extend = $.extend,
  24109. _each = $.each,
  24110. _noop = $.noop;
  24111. series.bubble = _extend({}, scatterSeries, {
  24112. _fillErrorBars: _noop,
  24113. _getRangeCorrector: _noop,
  24114. _calculateErrorBars: _noop,
  24115. _getMainColor: barSeries._getMainColor,
  24116. _createPointStyles: barSeries._createPointStyles,
  24117. _createPattern: barSeries._createPattern,
  24118. _updatePointsVisibility: barSeries._updatePointsVisibility,
  24119. _preparePointOptions: barSeries._preparePointOptions,
  24120. _getSpecialColor: barSeries._getSpecialColor,
  24121. _applyMarkerClipRect: series.line._applyElementsClipRect,
  24122. _parsePointStyle: mixins.polar.bar._parsePointStyle,
  24123. _createLegendState: series.area._createLegendState,
  24124. _createMarkerGroup: mixins.polar.bar._createMarkerGroup,
  24125. areErrorBarsVisible: _noop,
  24126. _createErrorBarGroup: _noop,
  24127. _checkData: function(data) {
  24128. return _isDefined(data.argument) && _isDefined(data.size) && data.value !== undefined
  24129. },
  24130. _getPointData: function(data, options) {
  24131. var pointData = scatterSeries._getPointData.call(this, data, options);
  24132. pointData.size = data[options.sizeField || "size"];
  24133. return pointData
  24134. },
  24135. _fusionPoints: function(fusionPoints, tick) {
  24136. var calcMedianValue = scatterSeries._calcMedianValue;
  24137. return {
  24138. size: calcMedianValue.call(this, fusionPoints, "size"),
  24139. value: calcMedianValue.call(this, fusionPoints, "value"),
  24140. argument: tick,
  24141. tag: null
  24142. }
  24143. },
  24144. getValueFields: function() {
  24145. var options = this._options;
  24146. return [options.valueField || "val", options.sizeField || "size"]
  24147. },
  24148. updateTeamplateFieldNames: function() {
  24149. var that = this,
  24150. options = that._options,
  24151. valueFields = that.getValueFields(),
  24152. name = that.name;
  24153. options.valueField = valueFields[0] + name;
  24154. options.sizeField = valueFields[1] + name;
  24155. options.tagField = that.getTagField() + name
  24156. },
  24157. _clearingAnimation: function(translators, drawComplete) {
  24158. var that = this,
  24159. partitionDuration = 0.5,
  24160. lastPointIndex = that._drawedPoints.length - 1,
  24161. labelsGroup = that._labelsGroup;
  24162. labelsGroup && labelsGroup.animate({opacity: 0.001}, {
  24163. duration: that._defaultDuration,
  24164. partitionDuration: partitionDuration
  24165. }, function() {
  24166. _each(that._drawedPoints || [], function(i, p) {
  24167. p.animate(i === lastPointIndex ? drawComplete : undefined, {r: 0}, partitionDuration)
  24168. })
  24169. })
  24170. },
  24171. _animate: function() {
  24172. var that = this,
  24173. lastPointIndex = that._drawedPoints.length - 1,
  24174. labelsGroup = that._labelsGroup,
  24175. labelAnimFunc = function() {
  24176. labelsGroup && labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  24177. };
  24178. _each(that._drawedPoints || [], function(i, p) {
  24179. p.animate(i === lastPointIndex ? labelAnimFunc : undefined, {
  24180. r: p.bubbleSize,
  24181. translateX: p.x,
  24182. translateY: p.y
  24183. })
  24184. })
  24185. },
  24186. _beginUpdateData: barSeries._beginUpdateData
  24187. })
  24188. })(jQuery, DevExpress);
  24189. /*! Module viz-core, file pieSeries.js */
  24190. (function($, DX) {
  24191. var mixins = DX.viz.core.series.mixins,
  24192. pieSeries = mixins.pie,
  24193. _utils = DX.utils,
  24194. scatterSeries = mixins.chart.scatter,
  24195. barSeries = mixins.chart.bar,
  24196. _extend = $.extend,
  24197. _each = $.each,
  24198. _noop = $.noop,
  24199. _map = $.map,
  24200. _isFinite = isFinite,
  24201. _max = Math.max;
  24202. pieSeries.pie = _extend({}, barSeries, {
  24203. _createLabelGroup: scatterSeries._createLabelGroup,
  24204. _createGroups: scatterSeries._createGroups,
  24205. _createErrorBarGroup: _noop,
  24206. _drawPoint: function(options) {
  24207. var point = options.point,
  24208. legendCallback = options.legendCallback;
  24209. scatterSeries._drawPoint.call(this, options);
  24210. !point.isVisible() && point.setInvisibility();
  24211. legendCallback && point.isSelected() && legendCallback(point)("applySelected")
  24212. },
  24213. adjustLabels: function() {
  24214. var that = this,
  24215. points = that._points || [],
  24216. maxLabelLength,
  24217. labelsBBoxes = [];
  24218. _each(points, function(_, point) {
  24219. if (point._label.isVisible() && point._label.getLayoutOptions().position !== "inside") {
  24220. point.setLabelEllipsis();
  24221. labelsBBoxes.push(point._label.getBoundingRect().width)
  24222. }
  24223. });
  24224. if (labelsBBoxes.length)
  24225. maxLabelLength = _max.apply(null, labelsBBoxes);
  24226. _each(points, function(_, point) {
  24227. if (point._label.isVisible() && point._label.getLayoutOptions().position !== "inside") {
  24228. point._maxLabelLength = maxLabelLength;
  24229. point.updateLabelCoord()
  24230. }
  24231. })
  24232. },
  24233. _processRange: _noop,
  24234. _applyElementsClipRect: _noop,
  24235. getColor: _noop,
  24236. areErrorBarsVisible: _noop,
  24237. _prepareSeriesToDrawing: _noop,
  24238. _endUpdateData: scatterSeries._prepareSeriesToDrawing,
  24239. resetLabelSetups: function() {
  24240. _each(this._points || [], function(_, point) {
  24241. point._label.clearVisibility()
  24242. })
  24243. },
  24244. drawLabelsWOPoints: function(translators) {
  24245. var that = this,
  24246. options = that._options,
  24247. points = that._points || [],
  24248. labelsGroup;
  24249. if (options.label.position === "inside")
  24250. return false;
  24251. that._createGroups();
  24252. labelsGroup = that._labelsGroup;
  24253. _each(points, function(_, point) {
  24254. point.drawLabel(translators, that._renderer, labelsGroup)
  24255. });
  24256. return true
  24257. },
  24258. _getCreatingPointOptions: function() {
  24259. return this._getPointOptions()
  24260. },
  24261. _updateOptions: function(options) {
  24262. this.labelSpace = 0;
  24263. this.innerRadius = this.type === "pie" ? 0 : options.innerRadius
  24264. },
  24265. _checkData: function(data) {
  24266. var base = barSeries._checkData(data);
  24267. return this._options.paintNullPoints ? base : base && data.value !== null
  24268. },
  24269. _createMarkerGroup: function() {
  24270. var that = this;
  24271. if (!that._markersGroup)
  24272. that._markersGroup = that._renderer.g().attr({"class": "dxc-markers"}).append(that._group)
  24273. },
  24274. _getMainColor: function() {
  24275. return this._options.mainSeriesColor()
  24276. },
  24277. _getPointOptions: function() {
  24278. return this._parsePointOptions(this._preparePointOptions(), this._options.label)
  24279. },
  24280. _getRangeData: function() {
  24281. return this._rangeData
  24282. },
  24283. _getArrangeTotal: function(points) {
  24284. var total = 0;
  24285. _each(points, function(_, point) {
  24286. if (point.isVisible())
  24287. total += point.initialValue
  24288. });
  24289. return total
  24290. },
  24291. _createPointStyles: function(pointOptions) {
  24292. var that = this,
  24293. mainColor = pointOptions.color || that._getMainColor(),
  24294. specialMainColor = that._getSpecialColor(mainColor);
  24295. return {
  24296. normal: that._parsePointStyle(pointOptions, mainColor, mainColor),
  24297. hover: that._parsePointStyle(pointOptions.hoverStyle, specialMainColor, mainColor),
  24298. selection: that._parsePointStyle(pointOptions.selectionStyle, specialMainColor, mainColor),
  24299. legendStyles: {
  24300. normal: that._createLegendState(pointOptions, mainColor),
  24301. hover: that._createLegendState(pointOptions.hoverStyle, specialMainColor),
  24302. selection: that._createLegendState(pointOptions.selectionStyle, specialMainColor)
  24303. }
  24304. }
  24305. },
  24306. _getArrangeMinShownValue: function(points, total) {
  24307. var minSegmentSize = this._options.minSegmentSize,
  24308. totalMinSegmentSize = 0,
  24309. totalNotMinValues = 0;
  24310. total = total || points.length;
  24311. _each(points, function(_, point) {
  24312. if (point.isVisible())
  24313. if (point.initialValue < minSegmentSize * total / 360)
  24314. totalMinSegmentSize += minSegmentSize;
  24315. else
  24316. totalNotMinValues += point.initialValue
  24317. });
  24318. return totalMinSegmentSize < 360 ? minSegmentSize * totalNotMinValues / (360 - totalMinSegmentSize) : 0
  24319. },
  24320. _applyArrangeCorrection: function(points, minShownValue, total) {
  24321. var options = this._options,
  24322. isClockWise = options.segmentsDirection !== "anticlockwise",
  24323. shiftedAngle = _isFinite(options.startAngle) ? _utils.normalizeAngle(options.startAngle) : 0,
  24324. minSegmentSize = options.minSegmentSize,
  24325. percent,
  24326. correction = 0,
  24327. zeroTotalCorrection = 0;
  24328. if (total === 0) {
  24329. total = points.length;
  24330. zeroTotalCorrection = 1
  24331. }
  24332. _each(isClockWise ? points : points.concat([]).reverse(), function(_, point) {
  24333. var val = point.isVisible() ? zeroTotalCorrection || point.initialValue : 0,
  24334. updatedZeroValue;
  24335. if (minSegmentSize && point.isVisible() && val < minShownValue)
  24336. updatedZeroValue = minShownValue;
  24337. percent = val / total;
  24338. point.correctValue(correction, percent, zeroTotalCorrection + (updatedZeroValue || 0));
  24339. point.shiftedAngle = shiftedAngle;
  24340. correction = correction + (updatedZeroValue || val)
  24341. });
  24342. this._rangeData = {val: {
  24343. min: 0,
  24344. max: correction
  24345. }}
  24346. },
  24347. arrangePoints: function() {
  24348. var that = this,
  24349. originalPoints = that._originalPoints || [],
  24350. minSegmentSize = that._options.minSegmentSize,
  24351. minShownValue,
  24352. pointIndex = 0,
  24353. total,
  24354. isAllPointsNegative = _max.apply(null, _map(originalPoints, function(p) {
  24355. return p.value
  24356. })) <= 0,
  24357. points = that._originalPoints = that._points = _map(originalPoints, function(point) {
  24358. if (point.value === null || !isAllPointsNegative && point.value < 0 || point.value === 0 && !minSegmentSize) {
  24359. point.dispose();
  24360. return null
  24361. }
  24362. else {
  24363. point.index = pointIndex++;
  24364. return point
  24365. }
  24366. });
  24367. total = that._getArrangeTotal(points);
  24368. if (minSegmentSize)
  24369. minShownValue = this._getArrangeMinShownValue(points, total);
  24370. that._applyArrangeCorrection(points, minShownValue, total)
  24371. },
  24372. correctPosition: function(correction) {
  24373. var debug = DX.utils.debug;
  24374. debug.assert(correction, "correction was not passed");
  24375. debug.assertParam(correction.centerX, "correction.centerX was not passed");
  24376. debug.assertParam(correction.centerY, "correction.centerY was not passed");
  24377. debug.assertParam(correction.radiusInner, "correction.radiusInner was not passed");
  24378. debug.assertParam(correction.radiusOuter, "correction.radiusOuter was not passed");
  24379. _each(this._points, function(_, point) {
  24380. point.correctPosition(correction)
  24381. });
  24382. this._centerX = correction.centerX;
  24383. this._centerY = correction.centerY;
  24384. this._radiusOuter = correction.radiusOuter
  24385. },
  24386. _animate: function(firstDrawing) {
  24387. var that = this,
  24388. index = 0,
  24389. timeThreshold = 0.2,
  24390. points = that._points,
  24391. pointsCount = points && points.length,
  24392. duration = 1 / (timeThreshold * (pointsCount - 1) + 1),
  24393. completeFunc = function() {
  24394. that._animateComplete()
  24395. },
  24396. animateP = function() {
  24397. points[index] && points[index].animate(index === pointsCount - 1 ? completeFunc : undefined, duration, stepFunc);
  24398. index++
  24399. },
  24400. stepFunc = function(_, progress) {
  24401. if (progress >= timeThreshold) {
  24402. this.step = null;
  24403. animateP()
  24404. }
  24405. };
  24406. if (firstDrawing)
  24407. animateP();
  24408. else
  24409. $.each(points, function(i, p) {
  24410. p.animate(i === pointsCount - 1 ? completeFunc : undefined)
  24411. })
  24412. },
  24413. getVisiblePoints: function() {
  24414. return _map(this._points, function(p) {
  24415. return p.isVisible() ? p : null
  24416. })
  24417. },
  24418. getPointByCoord: function(x, y) {
  24419. var points = this._points;
  24420. for (var i = 0; i < points.length; i++)
  24421. if (points[i].coordsIn(x, y))
  24422. return points[i]
  24423. },
  24424. _beginUpdateData: function() {
  24425. this._deletePatterns();
  24426. this._patterns = []
  24427. },
  24428. getCenter: function() {
  24429. return {
  24430. x: this._centerX,
  24431. y: this._centerY
  24432. }
  24433. }
  24434. });
  24435. pieSeries.doughnut = pieSeries.donut = pieSeries.pie
  24436. })(jQuery, DevExpress);
  24437. /*! Module viz-core, file financialSeries.js */
  24438. (function($, DX) {
  24439. var viz = DX.viz,
  24440. seriesNS = viz.core.series,
  24441. series = seriesNS.mixins.chart,
  24442. scatterSeries = series.scatter,
  24443. barSeries = series.bar,
  24444. rangeCalculator = seriesNS.helpers.rangeDataCalculator,
  24445. _isDefined = DX.utils.isDefined,
  24446. _extend = $.extend,
  24447. _each = $.each,
  24448. _noop = $.noop,
  24449. DEFAULT_FINANCIAL_POINT_SIZE = 10;
  24450. series.stock = _extend({}, scatterSeries, {
  24451. _animate: _noop,
  24452. _applyMarkerClipRect: function(settings) {
  24453. settings.clipId = this._forceClipping ? this._paneClipRectID : this._widePaneClipRectID
  24454. },
  24455. _updatePointsVisibility: barSeries._updatePointsVisibility,
  24456. _preparePointOptions: barSeries._preparePointOptions,
  24457. _getRangeCorrector: _noop,
  24458. _createErrorBarGroup: _noop,
  24459. areErrorBarsVisible: _noop,
  24460. _createMarkerGroup: function() {
  24461. var that = this,
  24462. markersGroup,
  24463. styles = that._getPointOptions().styles,
  24464. defaultStyle = styles.normal,
  24465. defaultPositiveStyle = styles.positive.normal,
  24466. reductionStyle = styles.reduction.normal,
  24467. reductionPositiveStyle = styles.reductionPositive.normal,
  24468. markerSettings = {"class": "dxc-markers"};
  24469. that._applyMarkerClipRect(markerSettings);
  24470. defaultStyle["class"] = "default-markers";
  24471. defaultPositiveStyle["class"] = "default-positive-markers";
  24472. reductionStyle["class"] = "reduction-markers";
  24473. reductionPositiveStyle["class"] = "reduction-positive-markers";
  24474. that._createGroup("_markersGroup", that, that._group, markerSettings);
  24475. markersGroup = that._markersGroup;
  24476. that._createGroup("defaultMarkersGroup", markersGroup, markersGroup, defaultStyle);
  24477. that._createGroup("reductionMarkersGroup", markersGroup, markersGroup, reductionStyle);
  24478. that._createGroup("defaultPositiveMarkersGroup", markersGroup, markersGroup, defaultPositiveStyle);
  24479. that._createGroup("reductionPositiveMarkersGroup", markersGroup, markersGroup, reductionPositiveStyle)
  24480. },
  24481. _createGroups: function() {
  24482. scatterSeries._createGroups.call(this, false)
  24483. },
  24484. _clearingAnimation: function(translators, drawComplete) {
  24485. drawComplete()
  24486. },
  24487. _getCreatingPointOptions: function() {
  24488. var that = this,
  24489. defaultPointOptions,
  24490. creatingPointOptions = that._predefinedPointOptions;
  24491. if (!creatingPointOptions) {
  24492. defaultPointOptions = this._getPointOptions();
  24493. that._predefinedPointOptions = creatingPointOptions = _extend(true, {styles: {}}, defaultPointOptions);
  24494. creatingPointOptions.styles.normal = creatingPointOptions.styles.positive.normal = creatingPointOptions.styles.reduction.normal = creatingPointOptions.styles.reductionPositive.normal = {"stroke-width": defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal["stroke-width"]}
  24495. }
  24496. return creatingPointOptions
  24497. },
  24498. _checkData: function(data) {
  24499. return _isDefined(data.argument) && data.highValue !== undefined && data.lowValue !== undefined && data.openValue !== undefined && data.closeValue !== undefined
  24500. },
  24501. _processRange: function(point, prevPoint) {
  24502. rangeCalculator.processTwoValues(this, point, prevPoint, "highValue", "lowValue")
  24503. },
  24504. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  24505. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction, "highValue", "lowValue");
  24506. rangeCalculator.addRangeSeriesLabelPaddings(this);
  24507. return this._rangeData
  24508. },
  24509. _getPointData: function(data, options) {
  24510. var that = this,
  24511. level,
  24512. openValueField = options.openValueField || "open",
  24513. closeValueField = options.closeValueField || "close",
  24514. highValueField = options.highValueField || "high",
  24515. lowValueField = options.lowValueField || "low",
  24516. reductionValue;
  24517. that.level = options.reduction.level;
  24518. switch ((that.level || "").toLowerCase()) {
  24519. case"open":
  24520. level = openValueField;
  24521. break;
  24522. case"high":
  24523. level = highValueField;
  24524. break;
  24525. case"low":
  24526. level = lowValueField;
  24527. break;
  24528. default:
  24529. level = closeValueField;
  24530. that.level = "close";
  24531. break
  24532. }
  24533. reductionValue = data[level];
  24534. return {
  24535. argument: data[options.argumentField || "date"],
  24536. highValue: data[highValueField],
  24537. lowValue: data[lowValueField],
  24538. closeValue: data[closeValueField],
  24539. openValue: data[openValueField],
  24540. reductionValue: reductionValue,
  24541. tag: data[options.tagField || "tag"],
  24542. isReduction: that._checkReduction(reductionValue)
  24543. }
  24544. },
  24545. _parsePointStyle: function(style, defaultColor, innerColor) {
  24546. return {
  24547. stroke: style.color || defaultColor,
  24548. "stroke-width": style.width,
  24549. fill: style.color || innerColor
  24550. }
  24551. },
  24552. updateTeamplateFieldNames: function() {
  24553. var that = this,
  24554. options = that._options,
  24555. valueFields = that.getValueFields(),
  24556. name = that.name;
  24557. options.openValueField = valueFields[0] + name;
  24558. options.highValueField = valueFields[1] + name;
  24559. options.lowValueField = valueFields[2] + name;
  24560. options.closeValueField = valueFields[3] + name;
  24561. options.tagField = that.getTagField() + name
  24562. },
  24563. _getDefaultStyle: function(options, isCustomPointOptions) {
  24564. var that = this,
  24565. mainPointColor = options.color || that._options.mainSeriesColor;
  24566. return {
  24567. normal: that._parsePointStyle(options, mainPointColor, mainPointColor, isCustomPointOptions),
  24568. hover: that._parsePointStyle(options.hoverStyle, mainPointColor, mainPointColor, isCustomPointOptions),
  24569. selection: that._parsePointStyle(options.selectionStyle, mainPointColor, mainPointColor, isCustomPointOptions)
  24570. }
  24571. },
  24572. _getReductionStyle: function(options, isCustomPointOptions) {
  24573. var that = this,
  24574. reductionColor = options.reduction.color;
  24575. return {
  24576. normal: that._parsePointStyle({
  24577. color: reductionColor,
  24578. width: options.width,
  24579. hatching: options.hatching
  24580. }, reductionColor, reductionColor, isCustomPointOptions),
  24581. hover: that._parsePointStyle(options.hoverStyle, reductionColor, reductionColor, isCustomPointOptions),
  24582. selection: that._parsePointStyle(options.selectionStyle, reductionColor, reductionColor, isCustomPointOptions)
  24583. }
  24584. },
  24585. _createPointStyles: function(pointOptions, isCustomPointOptions) {
  24586. var that = this,
  24587. innerColor = that._options.innerColor,
  24588. styles = that._getDefaultStyle(pointOptions, isCustomPointOptions),
  24589. positiveStyle,
  24590. reductionStyle,
  24591. reductionPositiveStyle;
  24592. positiveStyle = _extend(true, {}, styles);
  24593. reductionStyle = that._getReductionStyle(pointOptions, isCustomPointOptions);
  24594. reductionPositiveStyle = _extend(true, {}, reductionStyle);
  24595. positiveStyle.normal.fill = positiveStyle.hover.fill = positiveStyle.selection.fill = innerColor;
  24596. reductionPositiveStyle.normal.fill = reductionPositiveStyle.hover.fill = reductionPositiveStyle.selection.fill = innerColor;
  24597. styles.positive = positiveStyle;
  24598. styles.reduction = reductionStyle;
  24599. styles.reductionPositive = reductionPositiveStyle;
  24600. return styles
  24601. },
  24602. _endUpdateData: function() {
  24603. delete this.prevLevelValue;
  24604. delete this._predefinedPointOptions
  24605. },
  24606. _checkReduction: function(value) {
  24607. var that = this,
  24608. result = false;
  24609. if (value !== null) {
  24610. if (_isDefined(that.prevLevelValue))
  24611. result = value < that.prevLevelValue;
  24612. that.prevLevelValue = value
  24613. }
  24614. return result
  24615. },
  24616. _fusionPoints: function(fusionPoints, tick) {
  24617. var fusedPointData = {},
  24618. reductionLevel,
  24619. highValue = -Infinity,
  24620. lowValue = +Infinity,
  24621. openValue,
  24622. closeValue;
  24623. if (!fusionPoints.length)
  24624. return {};
  24625. _each(fusionPoints, function(_, point) {
  24626. if (!point.hasValue())
  24627. return;
  24628. highValue = Math.max(highValue, point.highValue);
  24629. lowValue = Math.min(lowValue, point.lowValue);
  24630. openValue = openValue !== undefined ? openValue : point.openValue;
  24631. closeValue = point.closeValue !== undefined ? point.closeValue : closeValue
  24632. });
  24633. fusedPointData.argument = tick;
  24634. fusedPointData.openValue = openValue;
  24635. fusedPointData.closeValue = closeValue;
  24636. fusedPointData.highValue = highValue;
  24637. fusedPointData.lowValue = lowValue;
  24638. fusedPointData.tag = null;
  24639. switch ((this.level || "").toLowerCase()) {
  24640. case"open":
  24641. reductionLevel = openValue;
  24642. break;
  24643. case"high":
  24644. reductionLevel = highValue;
  24645. break;
  24646. case"low":
  24647. reductionLevel = lowValue;
  24648. break;
  24649. default:
  24650. reductionLevel = closeValue;
  24651. break
  24652. }
  24653. fusedPointData.reductionValue = reductionLevel;
  24654. fusedPointData.isReduction = this._checkReduction(reductionLevel);
  24655. return fusedPointData
  24656. },
  24657. _getPointSize: function() {
  24658. return DEFAULT_FINANCIAL_POINT_SIZE
  24659. },
  24660. getValueFields: function() {
  24661. var options = this._options;
  24662. return [options.openValueField || "open", options.highValueField || "high", options.lowValueField || "low", options.closeValueField || "close"]
  24663. },
  24664. getArgumentField: function() {
  24665. return this._options.argumentField || "date"
  24666. },
  24667. _beginUpdateData: _noop
  24668. });
  24669. series.candlestick = _extend({}, series.stock, {
  24670. _createPattern: barSeries._createPattern,
  24671. _beginUpdateData: barSeries._beginUpdateData,
  24672. _parsePointStyle: function(style, defaultColor, innerColor, isCustomPointOptions) {
  24673. var color = this._createPattern(style.color || innerColor, style.hatching, isCustomPointOptions),
  24674. base = series.stock._parsePointStyle.call(this, style, defaultColor, color);
  24675. base.fill = color;
  24676. return base
  24677. }
  24678. })
  24679. })(jQuery, DevExpress);
  24680. /*! Module viz-core, file stackedSeries.js */
  24681. (function($, DX) {
  24682. var core = DX.viz.core,
  24683. series = core.series,
  24684. chartSeries = series.mixins.chart,
  24685. polarSeries = series.mixins.polar,
  24686. areaSeries = chartSeries.area,
  24687. barSeries = chartSeries.bar,
  24688. lineSeries = chartSeries.line,
  24689. rangeCalculator = core.series.helpers.rangeDataCalculator,
  24690. _extend = $.extend,
  24691. utils = DX.utils,
  24692. _noop = $.noop,
  24693. baseStackedSeries = {
  24694. _processRange: _noop,
  24695. _getRangeCorrector: _noop,
  24696. _fillErrorBars: _noop,
  24697. _calculateErrorBars: _noop,
  24698. _processStackedRange: function() {
  24699. var that = this,
  24700. prevPoint;
  24701. that._resetRangeData();
  24702. $.each(that.getAllPoints(), function(i, p) {
  24703. rangeCalculator.processRange(that, p, prevPoint);
  24704. prevPoint = p
  24705. })
  24706. },
  24707. _getRangeData: function() {
  24708. this._processStackedRange();
  24709. return areaSeries._getRangeData.apply(this, arguments)
  24710. }
  24711. },
  24712. baseFullStackedSeries = _extend({}, baseStackedSeries, {
  24713. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  24714. var that = this;
  24715. that._processStackedRange();
  24716. rangeCalculator.calculateRangeData(that, zoomArgs, calcIntervalFunction);
  24717. rangeCalculator.addLabelPaddings(that);
  24718. rangeCalculator.processFullStackedRange(that);
  24719. rangeCalculator.calculateRangeMinValue(that, zoomArgs);
  24720. return that._rangeData
  24721. },
  24722. isFullStackedSeries: function() {
  24723. return true
  24724. }
  24725. });
  24726. chartSeries.stackedline = _extend({}, lineSeries, baseStackedSeries, {_getRangeData: function() {
  24727. this._processStackedRange();
  24728. return lineSeries._getRangeData.apply(this, arguments)
  24729. }});
  24730. chartSeries.stackedspline = _extend({}, chartSeries.spline, baseStackedSeries, {_getRangeData: chartSeries.stackedline._getRangeData});
  24731. chartSeries.fullstackedline = _extend({}, lineSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  24732. var that = this;
  24733. that._processStackedRange();
  24734. rangeCalculator.calculateRangeData(that, zoomArgs, calcIntervalFunction);
  24735. rangeCalculator.addLabelPaddings(that);
  24736. rangeCalculator.processFullStackedRange(that);
  24737. return that._rangeData
  24738. }});
  24739. chartSeries.fullstackedspline = _extend({}, chartSeries.spline, baseFullStackedSeries, {_getRangeData: chartSeries.fullstackedline._getRangeData});
  24740. chartSeries.stackedbar = _extend({}, barSeries, baseStackedSeries, {_getRangeData: function() {
  24741. this._processStackedRange();
  24742. return barSeries._getRangeData.apply(this, arguments)
  24743. }});
  24744. chartSeries.fullstackedbar = _extend({}, barSeries, baseFullStackedSeries, {_getRangeData: function() {
  24745. var rangeData = baseFullStackedSeries._getRangeData.apply(this, arguments);
  24746. rangeData.arg.stick = false;
  24747. return rangeData
  24748. }});
  24749. function clonePoint(point, value, minValue, position) {
  24750. point = utils.clone(point);
  24751. point.value = value;
  24752. point.minValue = minValue;
  24753. point.translate();
  24754. point.argument = point.argument + position;
  24755. return point
  24756. }
  24757. function preparePointsForStackedAreaSegment(points) {
  24758. points = $.map(points, function(p) {
  24759. var result = [p];
  24760. if (p.leftHole)
  24761. result = [clonePoint(p, p.leftHole, p.minLeftHole, "left"), p];
  24762. if (p.rightHole)
  24763. result.push(clonePoint(p, p.rightHole, p.minRightHole, "right"));
  24764. return result
  24765. });
  24766. return points
  24767. }
  24768. chartSeries.stackedarea = _extend({}, areaSeries, baseStackedSeries, {_prepareSegment: function(points, rotated) {
  24769. return areaSeries._prepareSegment.call(this, preparePointsForStackedAreaSegment(points, this._prevSeries), rotated)
  24770. }});
  24771. function getPointsByArgFromPrevSeries(prevSeries, argument) {
  24772. var result;
  24773. while (prevSeries) {
  24774. result = prevSeries._segmentByArg[argument];
  24775. if (result)
  24776. break;
  24777. prevSeries = prevSeries._prevSeries
  24778. }
  24779. return result
  24780. }
  24781. chartSeries.stackedsplinearea = _extend({}, chartSeries.splinearea, baseStackedSeries, {_prepareSegment: function(points, rotated) {
  24782. var that = this,
  24783. areaSegment;
  24784. points = preparePointsForStackedAreaSegment(points, that._prevSeries);
  24785. if (!this._prevSeries || points.length === 1)
  24786. areaSegment = chartSeries.splinearea._prepareSegment.call(this, points, rotated);
  24787. else {
  24788. var fwPoints = chartSeries.spline._calculateBezierPoints(points, rotated),
  24789. bwPoints = $.map(points, function(p) {
  24790. var point = p.getCoords(true);
  24791. point.argument = p.argument;
  24792. return point
  24793. }),
  24794. prevSeriesFwPoints = $.map(that._prevSeries._segments, function(seg) {
  24795. return seg.line
  24796. }),
  24797. pointByArg = {};
  24798. $.each(prevSeriesFwPoints, function(_, p) {
  24799. if (p.argument !== null) {
  24800. var argument = p.argument.valueOf();
  24801. if (!pointByArg[argument])
  24802. pointByArg[argument] = [p];
  24803. else
  24804. pointByArg[argument].push(p)
  24805. }
  24806. });
  24807. that._prevSeries._segmentByArg = pointByArg;
  24808. bwPoints = chartSeries.spline._calculateBezierPoints(bwPoints, rotated);
  24809. $.each(bwPoints, function(i, p) {
  24810. var argument = p.argument.valueOf(),
  24811. prevSeriesPoints;
  24812. if (i % 3 === 0) {
  24813. prevSeriesPoints = pointByArg[argument] || getPointsByArgFromPrevSeries(that._prevSeries, argument);
  24814. if (prevSeriesPoints) {
  24815. bwPoints[i - 1] && prevSeriesPoints[0] && (bwPoints[i - 1] = prevSeriesPoints[0]);
  24816. bwPoints[i + 1] && (bwPoints[i + 1] = prevSeriesPoints[2] || p)
  24817. }
  24818. }
  24819. });
  24820. areaSegment = {
  24821. line: fwPoints,
  24822. area: fwPoints.concat(bwPoints.reverse())
  24823. };
  24824. that._areaPointsToSplineAreaPoints(areaSegment.area)
  24825. }
  24826. return areaSegment
  24827. }});
  24828. chartSeries.fullstackedarea = _extend({}, areaSeries, baseFullStackedSeries, {_prepareSegment: chartSeries.stackedarea._prepareSegment});
  24829. chartSeries.fullstackedsplinearea = _extend({}, chartSeries.splinearea, baseFullStackedSeries, {_prepareSegment: chartSeries.stackedsplinearea._prepareSegment});
  24830. polarSeries.stackedbar = _extend({}, polarSeries.bar, baseStackedSeries, {_getRangeData: function() {
  24831. this._processStackedRange();
  24832. return polarSeries.bar._getRangeData.apply(this, arguments)
  24833. }})
  24834. })(jQuery, DevExpress);
  24835. /*! Module viz-core, file basePoint.js */
  24836. (function($, DX) {
  24837. var seriesNS = DX.viz.core.series,
  24838. statesConsts = seriesNS.helpers.consts.states,
  24839. _each = $.each,
  24840. _extend = $.extend,
  24841. _isDefined = DX.utils.isDefined,
  24842. seiresMixins = seriesNS.mixins,
  24843. _noop = $.noop;
  24844. function Point() {
  24845. this.ctor.apply(this, arguments)
  24846. }
  24847. seriesNS.points = {Point: Point};
  24848. Point.prototype = {
  24849. ctor: function(series, dataItem, options) {
  24850. this.series = series;
  24851. this.update(dataItem, options);
  24852. this._emptySettings = {
  24853. fill: null,
  24854. stroke: null,
  24855. dashStyle: null
  24856. }
  24857. },
  24858. getColor: function() {
  24859. return this._styles.normal.fill || this.series.getColor()
  24860. },
  24861. _getStyle: function() {
  24862. var that = this,
  24863. styles = that._styles,
  24864. style;
  24865. if (that.isSelected())
  24866. style = styles.selection;
  24867. else if (that.isHovered())
  24868. style = styles.hover;
  24869. else {
  24870. that.fullState = statesConsts.normalMark;
  24871. style = styles.normal
  24872. }
  24873. that._currentStyle = style;
  24874. return style
  24875. },
  24876. update: function(dataItem, options) {
  24877. this.updateOptions(options);
  24878. this.updateData(dataItem)
  24879. },
  24880. updateData: function(dataItem) {
  24881. var that = this;
  24882. that.argument = that.initialArgument = that.originalArgument = dataItem.argument;
  24883. that.tag = dataItem.tag;
  24884. that.index = dataItem.index;
  24885. that.lowError = dataItem.lowError;
  24886. that.highError = dataItem.highError;
  24887. that._updateData(dataItem);
  24888. !that.hasValue() && that.setInvisibility();
  24889. that._fillStyle();
  24890. that._updateLabelData()
  24891. },
  24892. deleteMarker: function() {
  24893. var that = this;
  24894. if (that.graphic)
  24895. that.graphic.dispose();
  24896. that.graphic = null
  24897. },
  24898. _drawErrorBar: _noop,
  24899. draw: function(renderer, groups, animationEnabled, firstDrawing) {
  24900. var that = this;
  24901. if (that._needDeletingOnDraw) {
  24902. that.deleteMarker();
  24903. that._needDeletingOnDraw = false
  24904. }
  24905. if (that._needClearingOnDraw) {
  24906. that.clearMarker();
  24907. that._needClearingOnDraw = false
  24908. }
  24909. if (!that._hasGraphic())
  24910. that._getMarkerVisibility() && that._drawMarker(renderer, groups.markers, animationEnabled, firstDrawing);
  24911. else
  24912. that._updateMarker(animationEnabled, undefined, groups.markers);
  24913. that._drawLabel(renderer, groups.labels);
  24914. that._drawErrorBar(renderer, groups.errorBars, animationEnabled)
  24915. },
  24916. applyStyle: function(style) {
  24917. var that = this;
  24918. if (that.graphic) {
  24919. if (style === "normal") {
  24920. if (that.isHovered()) {
  24921. that.applyStyle("hover");
  24922. return
  24923. }
  24924. that.clearMarker()
  24925. }
  24926. else
  24927. that.graphic.toForeground();
  24928. that._currentStyle = that._styles[style];
  24929. that._updateMarker(true, that._currentStyle)
  24930. }
  24931. },
  24932. setHoverState: function() {
  24933. this.series.setPointHoverState(this)
  24934. },
  24935. releaseHoverState: function(callback) {
  24936. var that = this;
  24937. that.series.releasePointHoverState(that, callback);
  24938. if (that.graphic)
  24939. !that.isSelected() && that.graphic.toBackground()
  24940. },
  24941. setSelectedState: function() {
  24942. this.series.setPointSelectedState(this)
  24943. },
  24944. releaseSelectedState: function() {
  24945. this.series.releasePointSelectedState(this)
  24946. },
  24947. select: function() {
  24948. this.series.selectPoint(this)
  24949. },
  24950. clearSelection: function() {
  24951. this.series.deselectPoint(this)
  24952. },
  24953. showTooltip: function() {
  24954. this.series.showPointTooltip(this)
  24955. },
  24956. hideTooltip: function() {
  24957. this.series.hidePointTooltip(this)
  24958. },
  24959. _checkLabelsChanging: function(oldType, newType) {
  24960. if (oldType) {
  24961. var isNewRange = ~newType.indexOf("range"),
  24962. isOldRange = ~oldType.indexOf("range");
  24963. return isOldRange && !isNewRange || !isOldRange && isNewRange
  24964. }
  24965. else
  24966. return false
  24967. },
  24968. updateOptions: function(newOptions) {
  24969. if (!_isDefined(newOptions))
  24970. return;
  24971. var that = this,
  24972. oldOptions = that._options,
  24973. widgetType = newOptions.widgetType,
  24974. oldType = oldOptions && oldOptions.type,
  24975. newType = newOptions.type;
  24976. if (seiresMixins[widgetType].pointTypes[oldType] !== seiresMixins[widgetType].pointTypes[newType]) {
  24977. that._needDeletingOnDraw = true;
  24978. that._needClearingOnDraw = false;
  24979. that._checkLabelsChanging(oldType, newType) && that.deleteLabel();
  24980. that._resetType(oldType, widgetType);
  24981. that._setType(newType, widgetType)
  24982. }
  24983. else {
  24984. that._needDeletingOnDraw = that._checkSymbol(oldOptions, newOptions);
  24985. that._needClearingOnDraw = that._checkCustomize(oldOptions, newOptions)
  24986. }
  24987. that._options = newOptions;
  24988. that._fillStyle();
  24989. that._updateLabelOptions(seiresMixins[widgetType].pointTypes[newType])
  24990. },
  24991. translate: function(translators) {
  24992. var that = this;
  24993. that.translators = translators || that.translators;
  24994. that.translators && that.hasValue() && that._translate(that.translators)
  24995. },
  24996. _checkCustomize: function(oldOptions, newOptions) {
  24997. return oldOptions.styles.usePointCustomOptions && !newOptions.styles.usePointCustomOptions
  24998. },
  24999. _getCustomLabelVisibility: function() {
  25000. return this._styles.useLabelCustomOptions ? !!this._options.label.visible : null
  25001. },
  25002. getBoundingRect: function() {
  25003. return this._getGraphicBbox()
  25004. },
  25005. _resetType: function(type, widgetType) {
  25006. var that = this;
  25007. if (type)
  25008. _each(seriesNS.points.mixins[seiresMixins[widgetType].pointTypes[type]], function(methodName) {
  25009. delete that[methodName]
  25010. })
  25011. },
  25012. _setType: function(type, widgetType) {
  25013. var that = this;
  25014. _each(seriesNS.points.mixins[seiresMixins[widgetType].pointTypes[type]], function(methodName, method) {
  25015. that[methodName] = method
  25016. })
  25017. },
  25018. isInVisibleArea: function() {
  25019. return this.inVisibleArea
  25020. },
  25021. isSelected: function() {
  25022. return !!(this.fullState & statesConsts.selectedMark)
  25023. },
  25024. isHovered: function() {
  25025. return !!(this.fullState & statesConsts.hoverMark)
  25026. },
  25027. getOptions: function() {
  25028. return this._options
  25029. },
  25030. animate: function(complete, settings, partitionDuration) {
  25031. if (!this.graphic) {
  25032. complete && complete();
  25033. return
  25034. }
  25035. this.graphic.animate(settings, {partitionDuration: partitionDuration}, complete)
  25036. },
  25037. getCoords: function(min) {
  25038. var that = this;
  25039. if (!min)
  25040. return {
  25041. x: that.x,
  25042. y: that.y
  25043. };
  25044. if (!that._options.rotated)
  25045. return {
  25046. x: that.x,
  25047. y: that.minY
  25048. };
  25049. return {
  25050. x: that.minX,
  25051. y: that.y
  25052. }
  25053. },
  25054. getDefaultCoords: function() {
  25055. var that = this;
  25056. return !that._options.rotated ? {
  25057. x: that.x,
  25058. y: that.defaultY
  25059. } : {
  25060. x: that.defaultX,
  25061. y: that.y
  25062. }
  25063. },
  25064. _calculateVisibility: function(x, y, width, height) {
  25065. var that = this,
  25066. visibleAreaX,
  25067. visibleAreaY,
  25068. rotated = that._options.rotated;
  25069. if (that.translators) {
  25070. visibleAreaX = that.translators.x.getCanvasVisibleArea();
  25071. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  25072. if (visibleAreaX.min > x + (width || 0) || visibleAreaX.max < x || visibleAreaY.min > y + (height || 0) || visibleAreaY.max < y || rotated && _isDefined(width) && width !== 0 && (visibleAreaX.min === x + width || visibleAreaX.max === x) || !rotated && _isDefined(height) && height !== 0 && (visibleAreaY.min === y + height || visibleAreaY.max === y))
  25073. that.inVisibleArea = false;
  25074. else
  25075. that.inVisibleArea = true
  25076. }
  25077. },
  25078. correctPosition: _noop,
  25079. hasValue: function() {
  25080. return this.value !== null && this.minValue !== null
  25081. },
  25082. getBoundaryCoords: function() {
  25083. return this.getBoundingRect()
  25084. },
  25085. getCrosshairCoords: _noop,
  25086. getPointRadius: _noop,
  25087. _populatePointShape: _noop,
  25088. _checkSymbol: _noop,
  25089. getMarkerCoords: _noop,
  25090. hide: _noop,
  25091. show: _noop,
  25092. hideMarker: _noop,
  25093. setInvisibility: _noop,
  25094. clearVisibility: _noop,
  25095. isVisible: _noop,
  25096. resetCorrection: _noop,
  25097. correctValue: _noop,
  25098. setPercentValue: _noop,
  25099. correctCoordinates: _noop,
  25100. coordsIn: _noop,
  25101. getTooltipParams: _noop,
  25102. setLabelEllipsis: _noop,
  25103. updateLabelCoord: _noop,
  25104. drawLabel: _noop,
  25105. dispose: function() {
  25106. var that = this;
  25107. that.deleteMarker();
  25108. that.deleteLabel();
  25109. that._errorBar && this._errorBar.dispose();
  25110. that._options = that._styles = that.series = that.translators = that._errorBar = null
  25111. },
  25112. getTooltipFormatObject: function(tooltip) {
  25113. var that = this,
  25114. tooltipFormatObject = that._getFormatObject(tooltip),
  25115. sharedTooltipValuesArray = [],
  25116. tooltipStackPointsFormatObject = [];
  25117. if (that.stackPoints) {
  25118. _each(that.stackPoints, function(_, point) {
  25119. if (!point.isVisible())
  25120. return;
  25121. var formatObject = point._getFormatObject(tooltip);
  25122. tooltipStackPointsFormatObject.push(formatObject);
  25123. sharedTooltipValuesArray.push(formatObject.seriesName + ": " + formatObject.valueText)
  25124. });
  25125. _extend(tooltipFormatObject, {
  25126. points: tooltipStackPointsFormatObject,
  25127. valueText: sharedTooltipValuesArray.join("\n"),
  25128. stackName: that.stackPoints.stackName
  25129. })
  25130. }
  25131. return tooltipFormatObject
  25132. },
  25133. setHole: function(holeValue, position) {
  25134. var that = this,
  25135. minValue = isFinite(that.minValue) ? that.minValue : 0;
  25136. if (_isDefined(holeValue))
  25137. if (position === "left") {
  25138. that.leftHole = that.value - holeValue;
  25139. that.minLeftHole = minValue - holeValue
  25140. }
  25141. else {
  25142. that.rightHole = that.value - holeValue;
  25143. that.minRightHole = minValue - holeValue
  25144. }
  25145. },
  25146. resetHoles: function() {
  25147. this.leftHole = null;
  25148. this.minLeftHole = null;
  25149. this.rightHole = null;
  25150. this.minRightHole = null
  25151. },
  25152. getLabel: function() {
  25153. return this._label
  25154. }
  25155. }
  25156. })(jQuery, DevExpress);
  25157. /*! Module viz-core, file label.js */
  25158. (function(DX, $, undefined) {
  25159. var _degreesToRadians = DX.utils.degreesToRadians,
  25160. _patchFontOptions = DX.viz.core.utils.patchFontOptions,
  25161. _round = Math.round,
  25162. _abs = Math.abs,
  25163. _min = Math.min,
  25164. _max = Math.max,
  25165. _ceil = Math.ceil,
  25166. _getCosAndSin = DX.utils.getCosAndSin,
  25167. _rotateBBox = DX.viz.renderers.rotateBBox,
  25168. LABEL_BACKGROUND_PADDING_X = 8,
  25169. LABEL_BACKGROUND_PADDING_Y = 4;
  25170. function getClosestCoord(point, coords) {
  25171. var closestDistase = Infinity,
  25172. closestCoord;
  25173. $.each(coords, function(_, coord) {
  25174. var x = point[0] - coord[0],
  25175. y = point[1] - coord[1],
  25176. distance = x * x + y * y;
  25177. if (distance < closestDistase) {
  25178. closestDistase = distance;
  25179. closestCoord = coord
  25180. }
  25181. });
  25182. return closestCoord
  25183. }
  25184. var barPointStrategy = {
  25185. isLabelInside: function(labelPoint, figure) {
  25186. return labelPoint.x >= figure.x && labelPoint.x <= figure.x + figure.width && labelPoint.y >= figure.y && labelPoint.y <= figure.y + figure.height
  25187. },
  25188. prepareLabelPoints: function(points, center, angle, hasBackground) {
  25189. return !hasBackground ? points : [center]
  25190. },
  25191. getFigureCenter: function(figure) {
  25192. return [figure.x + figure.width / 2, figure.y + figure.height / 2]
  25193. },
  25194. findFigurePoint: function(figure, labelPoint) {
  25195. var figureCenter = barPointStrategy.getFigureCenter(figure),
  25196. point = getClosestCoord(labelPoint, [[figure.x, figureCenter[1]], [figureCenter[0], figure.y + figure.height], [figure.x + figure.width, figureCenter[1]], [figureCenter[0], figure.y]]);
  25197. return [_round(point[0]), _round(point[1])]
  25198. }
  25199. };
  25200. var symbolPointStrategy = {
  25201. isLabelInside: function() {
  25202. return false
  25203. },
  25204. prepareLabelPoints: barPointStrategy.prepareLabelPoints,
  25205. getFigureCenter: function(figure) {
  25206. return [figure.x, figure.y]
  25207. },
  25208. findFigurePoint: function(figure, labelPoint) {
  25209. var angle = Math.atan2(figure.y - labelPoint[1], labelPoint[0] - figure.x);
  25210. return [_round(figure.x + figure.r * Math.cos(angle)), _round(figure.y - figure.r * Math.sin(angle))]
  25211. }
  25212. };
  25213. var piePointStrategy = {
  25214. isLabelInside: function(_0, _1, isOutside) {
  25215. return !isOutside
  25216. },
  25217. prepareLabelPoints: function(points, center, angle) {
  25218. var rotatedPoints = [],
  25219. x0 = center[0],
  25220. y0 = center[1],
  25221. cossin = _getCosAndSin(angle || 0);
  25222. $.each(points, function(_, point) {
  25223. rotatedPoints.push([_round((point[0] - x0) * cossin.cos + (point[1] - y0) * cossin.sin + x0), _round(-(point[0] - x0) * cossin.sin + (point[1] - y0) * cossin.cos + y0)])
  25224. });
  25225. return rotatedPoints
  25226. },
  25227. getFigureCenter: symbolPointStrategy.getFigureCenter,
  25228. findFigurePoint: function(figure, labelPoint) {
  25229. var x = figure.x + (figure.y - labelPoint[1]) / Math.tan(_degreesToRadians(figure.angle)),
  25230. point = [figure.x, figure.y];
  25231. if (figure.x <= x && x <= labelPoint[0] || figure.x >= x && x >= labelPoint[0])
  25232. point.push(_round(x), labelPoint[1]);
  25233. return point
  25234. }
  25235. };
  25236. function selectStrategy(figure) {
  25237. return figure.angle !== undefined && piePointStrategy || figure.r !== undefined && symbolPointStrategy || barPointStrategy
  25238. }
  25239. function disposeItem(obj, field) {
  25240. obj[field] && obj[field].dispose();
  25241. obj[field] = null
  25242. }
  25243. function checkBackground(background) {
  25244. return background && (background.fill && background.fill !== "none" || background["stroke-width"] > 0 && background.stroke && background.stroke !== "none")
  25245. }
  25246. function checkConnector(connector) {
  25247. return connector && connector["stroke-width"] > 0 && connector.stroke && connector.stroke !== "none"
  25248. }
  25249. function formatValue(value, format, precision) {
  25250. return DX.formatHelper.format(value, format, precision)
  25251. }
  25252. function formatText(data, options) {
  25253. var format = options.format,
  25254. precision = options.precision;
  25255. data.valueText = formatValue(data.value, format, precision);
  25256. data.argumentText = formatValue(data.argument, options.argumentFormat, options.argumentPrecision);
  25257. if (data.percent !== undefined)
  25258. data.percentText = formatValue(data.percent, "percent", options.percentPrecision);
  25259. if (data.total !== undefined)
  25260. data.totalText = formatValue(data.total, format, precision);
  25261. if (data.openValue !== undefined)
  25262. data.openValueText = formatValue(data.openValue, format, precision);
  25263. if (data.closeValue !== undefined)
  25264. data.closeValueText = formatValue(data.closeValue, format, precision);
  25265. if (data.lowValue !== undefined)
  25266. data.lowValueText = formatValue(data.lowValue, format, precision);
  25267. if (data.highValue !== undefined)
  25268. data.highValueText = formatValue(data.highValue, format, precision);
  25269. if (data.reductionValue !== undefined)
  25270. data.reductionValueText = formatValue(data.reductionValue, format, precision);
  25271. return options.customizeText ? options.customizeText.call(data, data) : data.valueText
  25272. }
  25273. function Label(){}
  25274. Label.prototype = {
  25275. constructor: Label,
  25276. _setVisibility: function(value, state) {
  25277. this._group && this._group.attr({visibility: value});
  25278. this._visible = state
  25279. },
  25280. clearVisibility: function() {
  25281. this._setVisibility(null, true)
  25282. },
  25283. hide: function() {
  25284. this._setVisibility("hidden", false)
  25285. },
  25286. show: function() {
  25287. this._setVisibility("visible", true)
  25288. },
  25289. isVisible: function() {
  25290. return this._visible
  25291. },
  25292. setColor: function(color) {
  25293. this._color = color
  25294. },
  25295. setOptions: function(options) {
  25296. this._options = options
  25297. },
  25298. setData: function(data) {
  25299. this._data = data
  25300. },
  25301. setDataField: function(fieldName, fieldValue) {
  25302. this._data = this._data || {};
  25303. this._data[fieldName] = fieldValue
  25304. },
  25305. getData: function() {
  25306. return this._data
  25307. },
  25308. setFigureToDrawConnector: function(figure) {
  25309. this._figure = figure
  25310. },
  25311. dispose: function() {
  25312. var that = this;
  25313. disposeItem(that, "_group");
  25314. that._data = that._options = that._textContent = that._visible = that._insideGroup = that._text = that._background = that._connector = that._figure = null
  25315. },
  25316. draw: function(renderer, container, customVisibility) {
  25317. var that = this,
  25318. options = that._options || {},
  25319. text = that._textContent = formatText(that._data, that._options) || null;
  25320. that.clearVisibility();
  25321. if (text) {
  25322. if (!that._group) {
  25323. that._group = renderer.g().append(container);
  25324. that._insideGroup = renderer.g().append(that._group);
  25325. that._text = renderer.text("", 0, 0).append(that._insideGroup)
  25326. }
  25327. that._text.css(options.attributes ? _patchFontOptions(options.attributes.font) : {});
  25328. if (checkBackground(options.background)) {
  25329. that._background = that._background || renderer.rect().append(that._insideGroup).toBackground();
  25330. that._background.attr(options.background);
  25331. that._color && that._background.attr({fill: that._color})
  25332. }
  25333. else
  25334. disposeItem(that, "_background");
  25335. if (checkConnector(options.connector)) {
  25336. that._connector = that._connector || renderer.path([], "line").sharp().append(that._group).toBackground();
  25337. that._connector.attr(options.connector);
  25338. that._color && that._connector.attr({stroke: that._color})
  25339. }
  25340. else
  25341. disposeItem(that, "_connector");
  25342. that._updateText(text);
  25343. if (customVisibility !== null)
  25344. customVisibility ? that.show() : that.hide()
  25345. }
  25346. else
  25347. that.hide();
  25348. return that
  25349. },
  25350. _updateText: function(text) {
  25351. var that = this,
  25352. bbox = that._text.attr({text: text}).getBBox();
  25353. that._textSize = [bbox.width, bbox.height];
  25354. if (that._background) {
  25355. bbox.x -= LABEL_BACKGROUND_PADDING_X;
  25356. bbox.y -= LABEL_BACKGROUND_PADDING_Y;
  25357. bbox.width += 2 * LABEL_BACKGROUND_PADDING_X;
  25358. bbox.height += 2 * LABEL_BACKGROUND_PADDING_Y;
  25359. that._background.attr(bbox)
  25360. }
  25361. that._labelSize = [bbox.width / 2, bbox.height / 2];
  25362. if (that._options.rotationAngle) {
  25363. that._insideGroup.rotate(that._options.rotationAngle, bbox.x + bbox.width / 2, bbox.y + bbox.height / 2);
  25364. bbox = _rotateBBox(bbox, [bbox.x + bbox.width / 2, bbox.y + bbox.height / 2], -that._options.rotationAngle)
  25365. }
  25366. that._bbox = bbox
  25367. },
  25368. _getConnectorPoints: function() {
  25369. var that = this,
  25370. figure = that._figure,
  25371. strategy = selectStrategy(figure),
  25372. bbox = that.getBoundingRect(),
  25373. labelPoint,
  25374. figurePoint,
  25375. xc,
  25376. yc,
  25377. points = [];
  25378. if (!strategy.isLabelInside(bbox, figure, that._options.position !== "inside")) {
  25379. xc = bbox.x + bbox.width / 2;
  25380. yc = bbox.y + bbox.height / 2;
  25381. points = strategy.prepareLabelPoints([[xc, yc - that._labelSize[1]], [xc + that._labelSize[0], yc], [xc, yc + that._labelSize[1]], [xc - that._labelSize[0], yc]], [xc, yc], -that._options.rotationAngle || 0, !!that._background);
  25382. labelPoint = getClosestCoord(strategy.getFigureCenter(figure), points);
  25383. labelPoint = [_round(labelPoint[0]), _round(labelPoint[1])];
  25384. figurePoint = strategy.findFigurePoint(figure, labelPoint);
  25385. points = figurePoint.concat(labelPoint)
  25386. }
  25387. return points
  25388. },
  25389. fit: function(size) {
  25390. var that = this;
  25391. if (!that._textContent)
  25392. return that;
  25393. var cossin = _getCosAndSin(-that._options.rotationAngle || 0),
  25394. textSize = _min(_abs(that._textSize[0] / cossin.cos), _abs(that._textSize[1] / cossin.sin)),
  25395. requiredTextSize = _min(_abs(size.width / cossin.cos), _abs(size.height / cossin.sin)),
  25396. text = that._textContent,
  25397. i,
  25398. ii,
  25399. line,
  25400. lines,
  25401. lineLength,
  25402. requiredLineLength;
  25403. if (textSize > requiredTextSize) {
  25404. lines = text.split("<br/>");
  25405. for (i = 0, ii = lines.length, lineLength = 0; i < ii; ++i) {
  25406. line = lines[i] = lines[i].replace(/<[^>]+>/g, '');
  25407. lineLength = _max(lineLength, line.length)
  25408. }
  25409. requiredLineLength = _ceil(lineLength * requiredTextSize / textSize);
  25410. for (i = 0; i < ii; ++i)
  25411. lines[i] = (line = lines[i]).length > requiredLineLength ? line.substr(0, requiredLineLength - 4) + "..." : line;
  25412. text = lines.join("<br/>")
  25413. }
  25414. that._updateText(text);
  25415. return that
  25416. },
  25417. shift: function(x, y) {
  25418. var that = this;
  25419. if (that._textContent) {
  25420. that._insideGroup.attr({
  25421. translateX: that._x = _round(x - that._bbox.x),
  25422. translateY: that._y = _round(y - that._bbox.y)
  25423. });
  25424. if (that._connector)
  25425. that._connector.attr({points: that._getConnectorPoints()})
  25426. }
  25427. return that
  25428. },
  25429. getBoundingRect: function() {
  25430. var bbox = this._bbox;
  25431. return this._textContent ? {
  25432. x: bbox.x + this._x,
  25433. y: bbox.y + this._y,
  25434. width: bbox.width,
  25435. height: bbox.height
  25436. } : {}
  25437. },
  25438. getLayoutOptions: function() {
  25439. var options = this._options;
  25440. return {
  25441. alignment: options.alignment,
  25442. background: checkBackground(options.background),
  25443. horizontalOffset: options.horizontalOffset,
  25444. verticalOffset: options.verticalOffset,
  25445. radialOffset: options.radialOffset,
  25446. position: options.position
  25447. }
  25448. }
  25449. };
  25450. DX.viz.core.series.points.Label = Label;
  25451. Label._DEBUG_formatText = formatText
  25452. })(DevExpress, jQuery);
  25453. /*! Module viz-core, file symbolPoint.js */
  25454. (function($, DX) {
  25455. var core = DX.viz.core,
  25456. seriesNS = core.series,
  25457. _extend = $.extend,
  25458. _isDefined = DX.utils.isDefined,
  25459. _math = Math,
  25460. _round = _math.round,
  25461. _floor = _math.floor,
  25462. _ceil = _math.ceil,
  25463. _abs = _math.abs,
  25464. DEFAULT_IMAGE_WIDTH = 20,
  25465. DEFAULT_IMAGE_HEIGHT = 20,
  25466. LABEL_OFFSET = 10,
  25467. CANVAS_POSITION_DEFAULT = "canvas_position_default";
  25468. function getSquareMarkerCoords(radius) {
  25469. return [-radius, -radius, radius, -radius, radius, radius, -radius, radius, -radius, -radius]
  25470. }
  25471. function getPolygonMarkerCoords(radius) {
  25472. var r = _ceil(radius);
  25473. return [-r, 0, 0, -r, r, 0, 0, r, -r, 0]
  25474. }
  25475. function getCrossMarkerCoords(radius) {
  25476. var r = _ceil(radius),
  25477. floorHalfRadius = _floor(r / 2),
  25478. ceilHalfRadius = _ceil(r / 2);
  25479. return [-r, -floorHalfRadius, -floorHalfRadius, -r, 0, -ceilHalfRadius, floorHalfRadius, -r, r, -floorHalfRadius, ceilHalfRadius, 0, r, floorHalfRadius, floorHalfRadius, r, 0, ceilHalfRadius, -floorHalfRadius, r, -r, floorHalfRadius, -ceilHalfRadius, 0]
  25480. }
  25481. function getTriangleDownMarkerCoords(radius) {
  25482. return [-radius, -radius, radius, -radius, 0, radius, -radius, -radius]
  25483. }
  25484. function getTriangleUpMarkerCoords(radius) {
  25485. return [-radius, radius, radius, radius, 0, -radius, -radius, radius]
  25486. }
  25487. seriesNS.points.mixins = seriesNS.points.mixins || {};
  25488. seriesNS.points.mixins.symbolPoint = {
  25489. deleteLabel: function() {
  25490. this._label.dispose();
  25491. this._label = null
  25492. },
  25493. _hasGraphic: function() {
  25494. return this.graphic
  25495. },
  25496. clearVisibility: function() {
  25497. var that = this,
  25498. graphic = that.graphic;
  25499. if (graphic && graphic.attr("visibility"))
  25500. graphic.attr({visibility: null});
  25501. that._label.clearVisibility()
  25502. },
  25503. isVisible: function() {
  25504. return this.inVisibleArea && this.series.isVisible()
  25505. },
  25506. setInvisibility: function() {
  25507. var that = this,
  25508. graphic = that.graphic;
  25509. if (graphic && graphic.attr("visibility") !== "hidden")
  25510. graphic.attr({visibility: "hidden"});
  25511. that._errorBar && that._errorBar.attr({visibility: "hidden"});
  25512. that._label.hide()
  25513. },
  25514. clearMarker: function() {
  25515. var graphic = this.graphic;
  25516. graphic && graphic.attr(this._emptySettings)
  25517. },
  25518. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  25519. this.adjustSeriesLabels = adjustSeriesLabels
  25520. },
  25521. _createLabel: function() {
  25522. this._label = core.CoreFactory.createLabel()
  25523. },
  25524. _updateLabelData: function() {
  25525. this._label.setData(this._getLabelFormatObject())
  25526. },
  25527. _updateLabelOptions: function() {
  25528. !this._label && this._createLabel();
  25529. this._label.setOptions(this._options.label)
  25530. },
  25531. _checkImage: function(image) {
  25532. return _isDefined(image) && (typeof image === "string" || _isDefined(image.url))
  25533. },
  25534. _fillStyle: function() {
  25535. this._styles = this._options.styles
  25536. },
  25537. _checkSymbol: function(oldOptions, newOptions) {
  25538. var oldSymbol = oldOptions.symbol,
  25539. newSymbol = newOptions.symbol,
  25540. symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
  25541. imageChanged = this._checkImage(oldOptions.image) !== this._checkImage(newOptions.image);
  25542. return !!(symbolChanged || imageChanged)
  25543. },
  25544. _populatePointShape: function(symbol, radius) {
  25545. switch (symbol) {
  25546. case"square":
  25547. return getSquareMarkerCoords(radius);
  25548. case"polygon":
  25549. return getPolygonMarkerCoords(radius);
  25550. case"triangle":
  25551. case"triangleDown":
  25552. return getTriangleDownMarkerCoords(radius);
  25553. case"triangleUp":
  25554. return getTriangleUpMarkerCoords(radius);
  25555. case"cross":
  25556. return getCrossMarkerCoords(radius)
  25557. }
  25558. },
  25559. correctValue: function(correction) {
  25560. var that = this;
  25561. if (that.hasValue()) {
  25562. that.value = that.initialValue + correction;
  25563. that.minValue = correction;
  25564. that.translate()
  25565. }
  25566. },
  25567. resetCorrection: function() {
  25568. this.value = this.initialValue;
  25569. this.minValue = CANVAS_POSITION_DEFAULT
  25570. },
  25571. _getTranslates: function(animationEnabled) {
  25572. var translateX = this.x,
  25573. translateY = this.y;
  25574. if (animationEnabled)
  25575. if (this._options.rotated)
  25576. translateX = this.defaultX;
  25577. else
  25578. translateY = this.defaultY;
  25579. return {
  25580. x: translateX,
  25581. y: translateY
  25582. }
  25583. },
  25584. _createImageMarker: function(renderer, settings, options) {
  25585. var width = options.width || DEFAULT_IMAGE_WIDTH,
  25586. height = options.height || DEFAULT_IMAGE_HEIGHT;
  25587. return renderer.image(-_round(width * 0.5), -_round(height * 0.5), width, height, options.url ? options.url.toString() : options.toString(), "center").attr({
  25588. translateX: settings.translateX,
  25589. translateY: settings.translateY,
  25590. visibility: settings.visibility
  25591. })
  25592. },
  25593. _createSymbolMarker: function(renderer, pointSettings) {
  25594. var marker,
  25595. options = this._options;
  25596. switch (options.symbol) {
  25597. case"circle":
  25598. delete pointSettings.points;
  25599. marker = renderer.circle().attr(pointSettings);
  25600. break;
  25601. case"square":
  25602. case"polygon":
  25603. case"triangle":
  25604. case"triangleDown":
  25605. case"triangleUp":
  25606. case"cross":
  25607. marker = renderer.path([], "area").attr(pointSettings).sharp();
  25608. break
  25609. }
  25610. return marker
  25611. },
  25612. _createMarker: function(renderer, group, image, settings, animationEnabled) {
  25613. var that = this,
  25614. marker = that._checkImage(image) ? that._createImageMarker(renderer, settings, image) : that._createSymbolMarker(renderer, settings, animationEnabled);
  25615. if (marker)
  25616. marker.data({point: that}).append(group);
  25617. return marker
  25618. },
  25619. _getSymbolBbox: function(x, y, r) {
  25620. return {
  25621. x: x - r,
  25622. y: y - r,
  25623. width: r * 2,
  25624. height: r * 2
  25625. }
  25626. },
  25627. _getImageBbox: function(x, y) {
  25628. var image = this._options.image,
  25629. width = image.width || DEFAULT_IMAGE_WIDTH,
  25630. height = image.height || DEFAULT_IMAGE_HEIGHT;
  25631. return {
  25632. x: x - _round(width / 2),
  25633. y: y - _round(height / 2),
  25634. width: width,
  25635. height: height
  25636. }
  25637. },
  25638. _getGraphicBbox: function() {
  25639. var that = this,
  25640. options = that._options,
  25641. x = that.x,
  25642. y = that.y,
  25643. bbox;
  25644. if (options.visible)
  25645. bbox = that._checkImage(options.image) ? that._getImageBbox(x, y) : that._getSymbolBbox(x, y, options.styles.normal.r);
  25646. else
  25647. bbox = {
  25648. x: x,
  25649. y: y,
  25650. width: 0,
  25651. height: 0
  25652. };
  25653. return bbox
  25654. },
  25655. _getVisibleArea: function() {
  25656. var translators = this.translators,
  25657. visibleX,
  25658. visibleY;
  25659. if (translators) {
  25660. visibleX = translators.x.getCanvasVisibleArea();
  25661. visibleY = translators.y.getCanvasVisibleArea();
  25662. return {
  25663. minX: visibleX.min,
  25664. maxX: visibleX.max,
  25665. minY: visibleY.min,
  25666. maxY: visibleY.max
  25667. }
  25668. }
  25669. },
  25670. _isLabelInsidePoint: $.noop,
  25671. _getShiftLabelCoords: function(label) {
  25672. var coord = this._addLabelAlignmentAndOffset(label, this._getLabelCoords(label));
  25673. return this._checkLabelPosition(label, coord)
  25674. },
  25675. _drawLabel: function(renderer, group) {
  25676. var that = this,
  25677. customVisibility = that._getCustomLabelVisibility(),
  25678. coord,
  25679. label = that._label;
  25680. if ((that.series.getLabelVisibility() || customVisibility !== null) && that.hasValue() && that._showForZeroValues()) {
  25681. label.draw(renderer, group, customVisibility);
  25682. if (!that._isLabelInsidePoint(label)) {
  25683. coord = that._getShiftLabelCoords(label);
  25684. label.setFigureToDrawConnector(that._getLabelConnector());
  25685. label.shift(_round(coord.x), _round(coord.y))
  25686. }
  25687. }
  25688. else
  25689. label.hide()
  25690. },
  25691. _showForZeroValues: function() {
  25692. return true
  25693. },
  25694. _getLabelConnector: function() {
  25695. var bbox = this._getGraphicBbox(),
  25696. w2 = bbox.width / 2,
  25697. h2 = bbox.height / 2;
  25698. return {
  25699. x: bbox.x + w2,
  25700. y: bbox.y + h2,
  25701. r: this._options.visible ? Math.max(w2, h2) : 0
  25702. }
  25703. },
  25704. _getPositionFromLocation: function() {
  25705. return {
  25706. x: this.x,
  25707. y: this.y
  25708. }
  25709. },
  25710. _isPointInVisibleArea: function(visibleArea, graphicBbox) {
  25711. return visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x && visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y
  25712. },
  25713. _checkLabelPosition: function(label, coord, pointPosition) {
  25714. var that = this,
  25715. visibleArea = that._getVisibleArea(),
  25716. labelBbox = label.getBoundingRect(),
  25717. graphicBbox = that._getGraphicBbox(pointPosition),
  25718. offset = LABEL_OFFSET;
  25719. if (that._isPointInVisibleArea(visibleArea, graphicBbox))
  25720. if (!that._options.rotated) {
  25721. if (visibleArea.minX > coord.x && that.adjustSeriesLabels)
  25722. coord.x = visibleArea.minX;
  25723. if (visibleArea.maxX < coord.x + labelBbox.width && that.adjustSeriesLabels)
  25724. coord.x = visibleArea.maxX - labelBbox.width;
  25725. if (visibleArea.minY > coord.y)
  25726. coord.y = graphicBbox.y + graphicBbox.height + offset;
  25727. if (visibleArea.maxY < coord.y + labelBbox.height)
  25728. coord.y = graphicBbox.y - labelBbox.height - offset
  25729. }
  25730. else {
  25731. if (visibleArea.minX > coord.x)
  25732. coord.x = graphicBbox.x + graphicBbox.width + offset;
  25733. if (visibleArea.maxX < coord.x + labelBbox.width)
  25734. coord.x = graphicBbox.x - offset - labelBbox.width;
  25735. if (visibleArea.minY > coord.y && that.adjustSeriesLabels)
  25736. coord.y = visibleArea.minY;
  25737. if (visibleArea.maxY < coord.y + labelBbox.height && that.adjustSeriesLabels)
  25738. coord.y = visibleArea.maxY - labelBbox.height
  25739. }
  25740. return coord
  25741. },
  25742. _addLabelAlignmentAndOffset: function(label, coord) {
  25743. var labelBBox = label.getBoundingRect(),
  25744. labelOptions = label.getLayoutOptions();
  25745. if (!this._options.rotated)
  25746. if (labelOptions.alignment === "left")
  25747. coord.x += labelBBox.width / 2;
  25748. else if (labelOptions.alignment === "right")
  25749. coord.x -= labelBBox.width / 2;
  25750. coord.x += labelOptions.horizontalOffset;
  25751. coord.y += labelOptions.verticalOffset;
  25752. return coord
  25753. },
  25754. _getLabelCoords: function(label, pointPosition) {
  25755. return this._getLabelCoordOfPosition(label, this._getLabelPosition(pointPosition), pointPosition)
  25756. },
  25757. _getLabelCoordOfPosition: function(label, position, pointPosition) {
  25758. var that = this,
  25759. labelBBox = label.getBoundingRect(),
  25760. graphicBbox = that._getGraphicBbox(pointPosition),
  25761. offset = LABEL_OFFSET,
  25762. centerY = graphicBbox.height / 2 - labelBBox.height / 2,
  25763. centerX = graphicBbox.width / 2 - labelBBox.width / 2,
  25764. x = graphicBbox.x,
  25765. y = graphicBbox.y;
  25766. switch (position) {
  25767. case"left":
  25768. x -= labelBBox.width + offset;
  25769. y += centerY;
  25770. break;
  25771. case"right":
  25772. x += graphicBbox.width + offset;
  25773. y += centerY;
  25774. break;
  25775. case"top":
  25776. x += centerX;
  25777. y -= labelBBox.height + offset;
  25778. break;
  25779. case"bottom":
  25780. x += centerX;
  25781. y += graphicBbox.height + offset;
  25782. break;
  25783. case"inside":
  25784. x += centerX;
  25785. y += centerY;
  25786. break
  25787. }
  25788. return {
  25789. x: x,
  25790. y: y
  25791. }
  25792. },
  25793. _drawMarker: function(renderer, group, animationEnabled) {
  25794. var that = this,
  25795. options = that._options,
  25796. translates = that._getTranslates(animationEnabled),
  25797. style = that._getStyle();
  25798. that.graphic = that._createMarker(renderer, group, options.image, _extend({
  25799. translateX: translates.x,
  25800. translateY: translates.y,
  25801. points: that._populatePointShape(options.symbol, style.r)
  25802. }, style), animationEnabled)
  25803. },
  25804. _getErrorBarSettings: function() {
  25805. return {visibility: "visible"}
  25806. },
  25807. _drawErrorBar: function(renderer, group) {
  25808. var that = this,
  25809. errorBarOptions = that._options.errorBars || {},
  25810. points = [],
  25811. settings,
  25812. pos = that._errorBarPos,
  25813. high = that._highErrorCoord,
  25814. low = that._lowErrorCoord,
  25815. displayMode = (errorBarOptions.displayMode + "").toLowerCase(),
  25816. isHighDisplayMode = displayMode === "high",
  25817. isLowDisplayMode = displayMode === "low",
  25818. edgeLength = _floor(parseInt(errorBarOptions.edgeLength) / 2),
  25819. highErrorOnly = (isHighDisplayMode || !_isDefined(low)) && _isDefined(high) && !isLowDisplayMode,
  25820. lowErrorOnly = (isLowDisplayMode || !_isDefined(high)) && _isDefined(low) && !isHighDisplayMode;
  25821. highErrorOnly && (low = that._baseErrorBarPos);
  25822. lowErrorOnly && (high = that._baseErrorBarPos);
  25823. if (displayMode !== "none" && _isDefined(high) && _isDefined(low) && _isDefined(pos)) {
  25824. !lowErrorOnly && points.push([pos - edgeLength, high, pos + edgeLength, high]);
  25825. points.push([pos, high, pos, low]);
  25826. !highErrorOnly && points.push([pos + edgeLength, low, pos - edgeLength, low]);
  25827. that._options.rotated && $.each(points, function(_, p) {
  25828. p.reverse()
  25829. });
  25830. settings = that._getErrorBarSettings(errorBarOptions);
  25831. if (!that._errorBar)
  25832. that._errorBar = renderer.path(points, "line").attr(settings).append(group);
  25833. else {
  25834. settings.points = points;
  25835. that._errorBar.attr(settings)
  25836. }
  25837. }
  25838. else
  25839. that._errorBar && that._errorBar.attr({visibility: "hidden"})
  25840. },
  25841. getTooltipParams: function() {
  25842. var that = this,
  25843. graphic = that.graphic;
  25844. return {
  25845. x: that.x,
  25846. y: that.y,
  25847. offset: graphic ? graphic.getBBox().height / 2 : 0
  25848. }
  25849. },
  25850. hasValue: function() {
  25851. return this.value !== null && this.minValue !== null
  25852. },
  25853. setPercentValue: function(total, fullStacked, leftHoleTotal, rightHoleTotal) {
  25854. var that = this,
  25855. valuePercent = _abs(that.value / total || 0),
  25856. minValuePercent = _abs(that.minValue / total || 0),
  25857. percent = valuePercent - minValuePercent;
  25858. that._label.setDataField("percent", percent);
  25859. that._label.setDataField("total", total);
  25860. if (that.series.isFullStackedSeries() && that.hasValue()) {
  25861. if (that.leftHole) {
  25862. that.leftHole /= total - leftHoleTotal;
  25863. that.minLeftHole /= total - leftHoleTotal
  25864. }
  25865. if (that.rightHole) {
  25866. that.rightHole /= total - rightHoleTotal;
  25867. that.minRightHole /= total - rightHoleTotal
  25868. }
  25869. that.value = valuePercent;
  25870. that.minValue = !minValuePercent ? that.minValue : minValuePercent;
  25871. that.translate()
  25872. }
  25873. },
  25874. _storeTrackerR: function() {
  25875. var that = this,
  25876. navigator = window.navigator,
  25877. r = that._options.styles.normal.r,
  25878. minTrackerSize;
  25879. navigator = that.__debug_navigator || navigator;
  25880. that.__debug_browserNavigator = navigator;
  25881. minTrackerSize = "ontouchstart" in window || navigator.msPointerEnabled && navigator.msMaxTouchPoints || navigator.pointerEnabled && navigator.maxTouchPoints ? 20 : 6;
  25882. that._options.trackerR = r < minTrackerSize ? minTrackerSize : r;
  25883. return that._options.trackerR
  25884. },
  25885. _translateErrorBars: function(valueTranslator) {
  25886. var that = this,
  25887. options = that._options,
  25888. errorBars = options.errorBars || {};
  25889. _isDefined(that.lowError) && (that._lowErrorCoord = valueTranslator.translate(that.lowError));
  25890. _isDefined(that.highError) && (that._highErrorCoord = valueTranslator.translate(that.highError));
  25891. that._errorBarPos = _floor(that._options.rotated ? that.vy : that.vx);
  25892. that._baseErrorBarPos = errorBars.type === "stdDeviation" ? that._lowErrorCoord + (that._highErrorCoord - that._lowErrorCoord) / 2 : that._options.rotated ? that.vx : that.vy
  25893. },
  25894. _translate: function(translators) {
  25895. var that = this,
  25896. valueAxis = that._options.rotated ? "x" : "y",
  25897. upperValueAxis = valueAxis.toUpperCase(),
  25898. valueTranslator = translators[valueAxis],
  25899. argumentAxis = that._options.rotated ? "y" : "x";
  25900. that["v" + valueAxis] = that[valueAxis] = valueTranslator.translate(that.value);
  25901. that["v" + argumentAxis] = that[argumentAxis] = translators[argumentAxis].translate(that.argument);
  25902. that["min" + upperValueAxis] = valueTranslator.translate(that.minValue);
  25903. that["default" + upperValueAxis] = valueTranslator.translate(CANVAS_POSITION_DEFAULT);
  25904. that._translateErrorBars(valueTranslator);
  25905. that._calculateVisibility(that.x, that.y)
  25906. },
  25907. _updateData: function(data) {
  25908. var that = this;
  25909. that.value = that.initialValue = that.originalValue = data.value;
  25910. that.minValue = that.initialMinValue = that.originalMinValue = _isDefined(data.minValue) ? data.minValue : CANVAS_POSITION_DEFAULT
  25911. },
  25912. _getImageSettings: function(image) {
  25913. return {
  25914. href: image.url || image.toString(),
  25915. width: image.width || DEFAULT_IMAGE_WIDTH,
  25916. height: image.height || DEFAULT_IMAGE_HEIGHT
  25917. }
  25918. },
  25919. getCrosshairCoords: function() {
  25920. return {
  25921. x: this.vx,
  25922. y: this.vy
  25923. }
  25924. },
  25925. getPointRadius: function() {
  25926. var style = this._currentStyle || this._getStyle(),
  25927. options = this._options,
  25928. r = style.r,
  25929. extraSpace,
  25930. symbol = options.symbol,
  25931. isSquare = symbol === "square",
  25932. isTriangle = symbol === "triangle" || symbol === "triangleDown" || symbol === "triangleUp";
  25933. if (options.visible && !options.image && r) {
  25934. extraSpace = style["stroke-width"] / 2;
  25935. return (isSquare || isTriangle ? 1.4 * r : r) + extraSpace
  25936. }
  25937. return 0
  25938. },
  25939. _updateMarker: function(animationEnabled, style) {
  25940. var that = this,
  25941. options = that._options,
  25942. settings,
  25943. image = options.image,
  25944. visibility = !that.isVisible() ? {visibility: "hidden"} : {};
  25945. style = style || that._getStyle();
  25946. if (that._checkImage(image))
  25947. settings = _extend({}, {visibility: style.visibility}, visibility, that._getImageSettings(image));
  25948. else
  25949. settings = _extend({}, style, visibility, {points: that._populatePointShape(options.symbol, style.r)});
  25950. if (!animationEnabled) {
  25951. settings.translateX = that.x;
  25952. settings.translateY = that.y
  25953. }
  25954. that.graphic.attr(settings).sharp()
  25955. },
  25956. _getLabelFormatObject: function() {
  25957. var that = this;
  25958. return {
  25959. argument: that.initialArgument,
  25960. value: that.initialValue,
  25961. originalArgument: that.originalArgument,
  25962. originalValue: that.originalValue,
  25963. seriesName: that.series.name,
  25964. lowErrorValue: that.lowError,
  25965. highErrorValue: that.highError,
  25966. point: that
  25967. }
  25968. },
  25969. _getLabelPosition: function() {
  25970. var rotated = this._options.rotated;
  25971. if (this.series.isFullStackedSeries() || this.initialValue > 0)
  25972. return rotated ? "right" : "top";
  25973. else
  25974. return rotated ? "left" : "bottom"
  25975. },
  25976. _getFormatObject: function(tooltip) {
  25977. var that = this,
  25978. labelFormatObject = that._label.getData();
  25979. return _extend({}, labelFormatObject, {
  25980. argumentText: tooltip.formatValue(that.initialArgument, "argument"),
  25981. valueText: tooltip.formatValue(that.initialValue)
  25982. }, _isDefined(labelFormatObject.percent) ? {percentText: tooltip.formatValue(labelFormatObject.percent, "percent")} : {}, _isDefined(labelFormatObject.total) ? {totalText: tooltip.formatValue(labelFormatObject.total)} : {})
  25983. },
  25984. _getMarkerVisibility: function() {
  25985. return this._options.visible
  25986. },
  25987. coordsIn: function(x, y) {
  25988. var trackerRadius = this._storeTrackerR();
  25989. return x >= this.x - trackerRadius && x <= this.x + trackerRadius && y >= this.y - trackerRadius && y <= this.y + trackerRadius
  25990. }
  25991. }
  25992. })(jQuery, DevExpress);
  25993. /*! Module viz-core, file barPoint.js */
  25994. (function($, DX) {
  25995. var points = DX.viz.core.series.points.mixins,
  25996. _extend = $.extend,
  25997. _math = Math,
  25998. _floor = _math.floor,
  25999. _abs = _math.abs,
  26000. _min = _math.min,
  26001. CANVAS_POSITION_DEFAULT = "canvas_position_default",
  26002. DEFAULT_BAR_TRACKER_SIZE = 9,
  26003. CORRECTING_BAR_TRACKER_VALUE = 4,
  26004. RIGHT = "right",
  26005. LEFT = "left",
  26006. TOP = "top",
  26007. BOTTOM = "bottom";
  26008. points.barPoint = _extend({}, points.symbolPoint, {
  26009. correctCoordinates: function(correctOptions) {
  26010. var correction = _floor(correctOptions.offset - correctOptions.width / 2),
  26011. rotated = this._options.rotated,
  26012. valueSelector = rotated ? "height" : "width",
  26013. correctionSelector = (rotated ? "y" : "x") + "Correction";
  26014. this[valueSelector] = correctOptions.width;
  26015. this[correctionSelector] = correction
  26016. },
  26017. _getGraphicBbox: function() {
  26018. var that = this,
  26019. bbox = {};
  26020. bbox.x = that.x;
  26021. bbox.y = that.y;
  26022. bbox.width = that.width;
  26023. bbox.height = that.height;
  26024. return bbox
  26025. },
  26026. _getLabelConnector: function() {
  26027. return this._getGraphicBbox()
  26028. },
  26029. _getLabelPosition: function() {
  26030. var that = this,
  26031. position,
  26032. translators = that.translators,
  26033. initialValue = that.initialValue,
  26034. invertX = translators.x.getBusinessRange().invert,
  26035. invertY = translators.y.getBusinessRange().invert,
  26036. isDiscreteValue = that.series.valueAxisType === "discrete",
  26037. isFullStacked = that.series.isFullStackedSeries(),
  26038. notVerticalInverted = !isDiscreteValue && (initialValue >= 0 && !invertY || initialValue < 0 && invertY) || isDiscreteValue && !invertY || isFullStacked,
  26039. notHorizontalInverted = !isDiscreteValue && (initialValue >= 0 && !invertX || initialValue < 0 && invertX) || isDiscreteValue && !invertX || isFullStacked;
  26040. if (!that._options.rotated)
  26041. position = notVerticalInverted ? TOP : BOTTOM;
  26042. else
  26043. position = notHorizontalInverted ? RIGHT : LEFT;
  26044. return position
  26045. },
  26046. _getLabelCoords: function(label) {
  26047. var that = this,
  26048. coords;
  26049. if (that.initialValue === 0 && that.series.isFullStackedSeries())
  26050. if (!this._options.rotated)
  26051. coords = that._getLabelCoordOfPosition(label, TOP);
  26052. else
  26053. coords = that._getLabelCoordOfPosition(label, RIGHT);
  26054. else if (label.getLayoutOptions().position === "inside")
  26055. coords = that._getLabelCoordOfPosition(label, "inside");
  26056. else
  26057. coords = points.symbolPoint._getLabelCoords.call(this, label);
  26058. return coords
  26059. },
  26060. _checkLabelPosition: function(label, coord) {
  26061. var that = this,
  26062. visibleArea = that._getVisibleArea(),
  26063. rotated = that._options.rotated,
  26064. graphicBbox = that._getGraphicBbox(),
  26065. labelBbox = label.getBoundingRect();
  26066. if (that._isPointInVisibleArea(visibleArea, graphicBbox))
  26067. return that._moveLabelOnCanvas(coord, visibleArea, labelBbox, that.adjustSeriesLabels || rotated, that.adjustSeriesLabels || !rotated);
  26068. return coord
  26069. },
  26070. _isLabelInsidePoint: function(label) {
  26071. var that = this,
  26072. graphicBbox = that._getGraphicBbox(),
  26073. labelBbox = label.getBoundingRect();
  26074. if (that._options.resolveLabelsOverlapping && label.getLayoutOptions().position === "inside")
  26075. if (labelBbox.width > graphicBbox.width || labelBbox.height > graphicBbox.height) {
  26076. label.hide();
  26077. return true
  26078. }
  26079. return false
  26080. },
  26081. _moveLabelOnCanvas: function(coord, visibleArea, labelBbox, horizontalAdjust, verticalAdjust) {
  26082. var x = coord.x,
  26083. y = coord.y;
  26084. if (visibleArea.minX > x && horizontalAdjust)
  26085. x = visibleArea.minX;
  26086. if (visibleArea.maxX < x + labelBbox.width && horizontalAdjust)
  26087. x = visibleArea.maxX - labelBbox.width;
  26088. if (visibleArea.minY > y && verticalAdjust)
  26089. y = visibleArea.minY;
  26090. if (visibleArea.maxY < y + labelBbox.height && verticalAdjust)
  26091. y = visibleArea.maxY - labelBbox.height;
  26092. return {
  26093. x: x,
  26094. y: y
  26095. }
  26096. },
  26097. _showForZeroValues: function() {
  26098. return this._options.label.showForZeroValues || this.initialValue
  26099. },
  26100. _drawMarker: function(renderer, group, animationEnabled) {
  26101. var that = this,
  26102. style = that._getStyle(),
  26103. x = that.x,
  26104. y = that.y,
  26105. width = that.width,
  26106. height = that.height,
  26107. r = that._options.cornerRadius;
  26108. if (animationEnabled)
  26109. if (that._options.rotated) {
  26110. width = 0;
  26111. x = that.defaultX
  26112. }
  26113. else {
  26114. height = 0;
  26115. y = that.defaultY
  26116. }
  26117. that.graphic = renderer.rect(x, y, width, height).attr({
  26118. rx: r,
  26119. ry: r
  26120. }).attr(style).data({point: that}).append(group)
  26121. },
  26122. _getSettingsForTracker: function() {
  26123. var that = this,
  26124. y = that.y,
  26125. height = that.height,
  26126. x = that.x,
  26127. width = that.width;
  26128. if (that._options.rotated) {
  26129. if (width === 1) {
  26130. width = DEFAULT_BAR_TRACKER_SIZE;
  26131. x -= CORRECTING_BAR_TRACKER_VALUE
  26132. }
  26133. }
  26134. else if (height === 1) {
  26135. height = DEFAULT_BAR_TRACKER_SIZE;
  26136. y -= CORRECTING_BAR_TRACKER_VALUE
  26137. }
  26138. return {
  26139. x: x,
  26140. y: y,
  26141. width: width,
  26142. height: height
  26143. }
  26144. },
  26145. getGraphicSettings: function() {
  26146. var graphic = this.graphic;
  26147. return {
  26148. x: graphic.attr("x"),
  26149. y: graphic.attr("y"),
  26150. height: graphic.attr("height"),
  26151. width: graphic.attr("width")
  26152. }
  26153. },
  26154. _getEdgeTooltipParams: function(x, y, width, height) {
  26155. var isPositive = this.value >= 0,
  26156. invertedY = this.translators.y.getBusinessRange().invert,
  26157. invertedX = this.translators.x.getBusinessRange().invert,
  26158. xCoord,
  26159. yCoord;
  26160. if (this._options.rotated) {
  26161. yCoord = y + height / 2;
  26162. if (invertedX)
  26163. xCoord = isPositive ? x : x + width;
  26164. else
  26165. xCoord = isPositive ? x + width : x
  26166. }
  26167. else {
  26168. xCoord = x + width / 2;
  26169. if (invertedY)
  26170. yCoord = isPositive ? y + height : y;
  26171. else
  26172. yCoord = isPositive ? y : y + height
  26173. }
  26174. return {
  26175. x: xCoord,
  26176. y: yCoord,
  26177. offset: 0
  26178. }
  26179. },
  26180. getTooltipParams: function(location) {
  26181. var x = this.x,
  26182. y = this.y,
  26183. width = this.width,
  26184. height = this.height;
  26185. return location === 'edge' ? this._getEdgeTooltipParams(x, y, width, height) : {
  26186. x: x + width / 2,
  26187. y: y + height / 2,
  26188. offset: 0
  26189. }
  26190. },
  26191. _truncateCoord: function(coord, minBounce, maxBounce) {
  26192. if (coord < minBounce)
  26193. return minBounce;
  26194. if (coord > maxBounce)
  26195. return maxBounce;
  26196. return coord
  26197. },
  26198. _translateErrorBars: function(valueTranslator, argVisibleArea) {
  26199. points.symbolPoint._translateErrorBars.call(this, valueTranslator);
  26200. if (this._errorBarPos < argVisibleArea.min || this._errorBarPos > argVisibleArea.max)
  26201. this._errorBarPos = undefined
  26202. },
  26203. _translate: function(translators) {
  26204. var that = this,
  26205. rotated = that._options.rotated,
  26206. valAxis = rotated ? "x" : "y",
  26207. argAxis = rotated ? "y" : "x",
  26208. valIntervalName = rotated ? "width" : "height",
  26209. argIntervalName = rotated ? "height" : "width",
  26210. argTranslator = translators[argAxis],
  26211. valTranslator = translators[valAxis],
  26212. argVisibleArea = argTranslator.getCanvasVisibleArea(),
  26213. valVisibleArea = valTranslator.getCanvasVisibleArea(),
  26214. arg,
  26215. minArg,
  26216. val,
  26217. minVal;
  26218. arg = minArg = argTranslator.translate(that.argument) + (that[argAxis + "Correction"] || 0);
  26219. val = valTranslator.translate(that.value);
  26220. minVal = valTranslator.translate(that.minValue);
  26221. that["v" + valAxis] = val;
  26222. that["v" + argAxis] = arg + that[argIntervalName] / 2;
  26223. that[valIntervalName] = _abs(val - minVal);
  26224. that._calculateVisibility(rotated ? _min(val, minVal) : _min(arg, minArg), rotated ? _min(arg, minArg) : _min(val, minVal), that.width, that.height);
  26225. val = that._truncateCoord(val, valVisibleArea.min, valVisibleArea.max);
  26226. minVal = that._truncateCoord(minVal, valVisibleArea.min, valVisibleArea.max);
  26227. that[argAxis] = arg;
  26228. that["min" + argAxis.toUpperCase()] = minArg;
  26229. that[valIntervalName] = _abs(val - minVal);
  26230. that[valAxis] = _min(val, minVal) + (that[valAxis + "Correction"] || 0);
  26231. that["min" + valAxis.toUpperCase()] = minVal + (that[valAxis + "Correction"] || 0);
  26232. that["default" + valAxis.toUpperCase()] = valTranslator.translate(CANVAS_POSITION_DEFAULT);
  26233. that._translateErrorBars(valTranslator, argVisibleArea);
  26234. if (that.inVisibleArea) {
  26235. if (that[argAxis] < argVisibleArea.min) {
  26236. that[argIntervalName] = that[argIntervalName] - (argVisibleArea.min - that[argAxis]);
  26237. that[argAxis] = argVisibleArea.min;
  26238. that["min" + argAxis.toUpperCase()] = argVisibleArea.min
  26239. }
  26240. if (that[argAxis] + that[argIntervalName] > argVisibleArea.max)
  26241. that[argIntervalName] = argVisibleArea.max - that[argAxis]
  26242. }
  26243. },
  26244. _updateMarker: function(animationEnabled, style) {
  26245. this.graphic.attr(_extend({}, style || this._getStyle(), !animationEnabled ? this.getMarkerCoords() : {}))
  26246. },
  26247. getMarkerCoords: function() {
  26248. return {
  26249. x: this.x,
  26250. y: this.y,
  26251. width: this.width,
  26252. height: this.height
  26253. }
  26254. },
  26255. coordsIn: function(x, y) {
  26256. var that = this;
  26257. return x >= that.x && x <= that.x + that.width && y >= that.y && y <= that.y + that.height
  26258. }
  26259. })
  26260. })(jQuery, DevExpress);
  26261. /*! Module viz-core, file bubblePoint.js */
  26262. (function($, DX) {
  26263. var points = DX.viz.core.series.points.mixins,
  26264. _extend = $.extend,
  26265. MIN_BUBBLE_HEIGHT = 20;
  26266. points.bubblePoint = _extend({}, points.symbolPoint, {
  26267. correctCoordinates: function(diameter) {
  26268. this.bubbleSize = diameter / 2
  26269. },
  26270. _drawMarker: function(renderer, group, animationEnabled) {
  26271. var that = this,
  26272. attr = _extend({
  26273. translateX: that.x,
  26274. translateY: that.y
  26275. }, that._getStyle());
  26276. that.graphic = renderer.circle(0, 0, animationEnabled ? 0 : that.bubbleSize).attr(attr).data({point: that}).append(group)
  26277. },
  26278. getTooltipParams: function(location) {
  26279. var that = this,
  26280. graphic = that.graphic,
  26281. height;
  26282. if (!graphic)
  26283. return;
  26284. height = graphic.getBBox().height;
  26285. return {
  26286. x: that.x,
  26287. y: height < MIN_BUBBLE_HEIGHT || location === 'edge' ? this.y - height / 2 : this.y,
  26288. offset: 0
  26289. }
  26290. },
  26291. _getLabelFormatObject: function() {
  26292. var formatObject = points.symbolPoint._getLabelFormatObject.call(this);
  26293. formatObject.size = this.initialSize;
  26294. return formatObject
  26295. },
  26296. _updateData: function(data) {
  26297. points.symbolPoint._updateData.call(this, data);
  26298. this.size = this.initialSize = data.size
  26299. },
  26300. _getGraphicBbox: function() {
  26301. var that = this;
  26302. return that._getSymbolBbox(that.x, that.y, that.bubbleSize)
  26303. },
  26304. _updateMarker: function(animationEnabled, style) {
  26305. var that = this;
  26306. style = style || that._getStyle();
  26307. if (!animationEnabled)
  26308. style = $.extend({
  26309. r: that.bubbleSize,
  26310. translateX: that.x,
  26311. translateY: that.y
  26312. }, style);
  26313. that.graphic.attr(style)
  26314. },
  26315. _getFormatObject: function(tooltip) {
  26316. var formatObject = points.symbolPoint._getFormatObject.call(this, tooltip);
  26317. formatObject.sizeText = tooltip.formatValue(this.initialSize);
  26318. return formatObject
  26319. },
  26320. _storeTrackerR: function() {
  26321. return this.bubbleSize
  26322. },
  26323. _getLabelCoords: function(label) {
  26324. var coords;
  26325. if (label.getLayoutOptions().position === "inside")
  26326. coords = this._getLabelCoordOfPosition(label, "inside");
  26327. else
  26328. coords = points.symbolPoint._getLabelCoords.call(this, label);
  26329. return coords
  26330. }
  26331. })
  26332. })(jQuery, DevExpress);
  26333. /*! Module viz-core, file piePoint.js */
  26334. (function($, DX) {
  26335. var CONNECTOR_LENGTH = 20,
  26336. series = DX.viz.core.series,
  26337. points = series.points.mixins,
  26338. _extend = $.extend,
  26339. _round = Math.round,
  26340. _sqrt = Math.sqrt,
  26341. _acos = Math.acos,
  26342. DEG = 180 / Math.PI,
  26343. _abs = Math.abs,
  26344. _normalizeAngle = DX.utils.normalizeAngle,
  26345. _getCosAndSin = DX.utils.getCosAndSin,
  26346. _isDefined = DX.utils.isDefined,
  26347. INDENT_FROM_PIE = series.helpers.consts.pieLabelIndent;
  26348. function getVerticallyShiftedAngularCoords(bbox, dy, center) {
  26349. var isPositive = bbox.x + bbox.width / 2 >= center.x,
  26350. dx1 = (isPositive ? bbox.x : bbox.x + bbox.width) - center.x,
  26351. dy1 = bbox.y - center.y,
  26352. dy2 = dy1 + dy,
  26353. dx2 = _round(_sqrt(dx1 * dx1 + dy1 * dy1 - dy2 * dy2)),
  26354. dx = (isPositive ? +dx2 : -dx2) || dx1;
  26355. return {
  26356. x: center.x + (isPositive ? dx : dx - bbox.width),
  26357. y: bbox.y + dy
  26358. }
  26359. }
  26360. DX.viz.core.utils.getVerticallyShiftedAngularCoords = getVerticallyShiftedAngularCoords;
  26361. points.piePoint = _extend({}, points.symbolPoint, {
  26362. _updateData: function(data) {
  26363. var that = this;
  26364. points.symbolPoint._updateData.call(this, data);
  26365. that._visible = true;
  26366. that.minValue = that.initialMinValue = that.originalMinValue = _isDefined(data.minValue) ? data.minValue : 0
  26367. },
  26368. animate: function(complete, duration, step) {
  26369. var that = this;
  26370. that.graphic.animate({
  26371. x: that.centerX,
  26372. y: that.centerY,
  26373. outerRadius: that.radiusOuter,
  26374. innerRadius: that.radiusInner,
  26375. startAngle: that.toAngle,
  26376. endAngle: that.fromAngle
  26377. }, {
  26378. partitionDuration: duration,
  26379. step: step
  26380. }, complete)
  26381. },
  26382. correctPosition: function(correction) {
  26383. var that = this;
  26384. that.radiusInner = correction.radiusInner;
  26385. that.radiusOuter = correction.radiusOuter;
  26386. that.centerX = correction.centerX;
  26387. that.centerY = correction.centerY
  26388. },
  26389. correctValue: function(correction, percent, base) {
  26390. var that = this;
  26391. that.value = (base || that.initialValue) + correction;
  26392. that.minValue = correction;
  26393. that.percent = percent;
  26394. that._label.setDataField("percent", percent)
  26395. },
  26396. _updateLabelData: function() {
  26397. this._label.setData(this._getLabelFormatObject())
  26398. },
  26399. _updateLabelOptions: function() {
  26400. var that = this;
  26401. !that._label && that._createLabel();
  26402. that._label.setOptions(that._options.label)
  26403. },
  26404. _getShiftLabelCoords: function() {
  26405. var that = this,
  26406. bbox = that._label.getBoundingRect(),
  26407. coord = that._getLabelCoords(that._label),
  26408. visibleArea = that._getVisibleArea();
  26409. if (that._isLabelDrawingWithoutPoints)
  26410. return that._checkLabelPosition(coord, bbox, visibleArea);
  26411. else
  26412. return that._getLabelExtraCoord(coord, that._checkVerticalLabelPosition(coord, bbox, visibleArea), bbox)
  26413. },
  26414. _getLabelPosition: function(options) {
  26415. return options.position
  26416. },
  26417. _getLabelCoords: function(label) {
  26418. var that = this,
  26419. bbox = label.getBoundingRect(),
  26420. options = label.getLayoutOptions(),
  26421. angleFunctions = _getCosAndSin(that.middleAngle),
  26422. position = that._getLabelPosition(options),
  26423. radiusInner = that.radiusInner,
  26424. radiusOuter = that.radiusOuter,
  26425. rad,
  26426. x;
  26427. if (position === 'inside') {
  26428. rad = radiusInner + (radiusOuter - radiusInner) / 2 + options.radialOffset;
  26429. x = that.centerX + rad * angleFunctions.cos - bbox.width / 2
  26430. }
  26431. else {
  26432. rad = radiusOuter + options.radialOffset + INDENT_FROM_PIE;
  26433. if (angleFunctions.cos > 0.1)
  26434. x = that.centerX + rad * angleFunctions.cos;
  26435. else if (angleFunctions.cos < -0.1)
  26436. x = that.centerX + rad * angleFunctions.cos - bbox.width;
  26437. else
  26438. x = that.centerX + rad * angleFunctions.cos - bbox.width / 2
  26439. }
  26440. return {
  26441. x: x,
  26442. y: _round(that.centerY - rad * angleFunctions.sin - bbox.height / 2)
  26443. }
  26444. },
  26445. _getColumnsCoord: function(coord) {
  26446. var that = this,
  26447. label = that._label,
  26448. bbox = label.getBoundingRect(),
  26449. options = label.getLayoutOptions(),
  26450. rad = that.radiusOuter + options.radialOffset,
  26451. canvas = that.series.canvas,
  26452. rightBorderX = canvas.width - canvas.right - bbox.width,
  26453. leftBorderX = canvas.left,
  26454. angleOfPoint = _normalizeAngle(that.middleAngle),
  26455. x;
  26456. if (options.position !== 'columns')
  26457. return coord;
  26458. rad += CONNECTOR_LENGTH;
  26459. if (angleOfPoint < 90 || angleOfPoint >= 270) {
  26460. x = that._maxLabelLength ? that.centerX + rad + that._maxLabelLength - bbox.width : rightBorderX;
  26461. x = x > rightBorderX ? rightBorderX : x
  26462. }
  26463. else {
  26464. x = that._maxLabelLength ? that.centerX - rad - that._maxLabelLength : leftBorderX;
  26465. x = x < leftBorderX ? leftBorderX : x
  26466. }
  26467. coord.x = x;
  26468. return coord
  26469. },
  26470. drawLabel: function(translators, renderer, group) {
  26471. this.translate(translators);
  26472. this._isLabelDrawingWithoutPoints = true;
  26473. this._drawLabel(renderer, group);
  26474. this._isLabelDrawingWithoutPoints = false
  26475. },
  26476. updateLabelCoord: function() {
  26477. var that = this,
  26478. bbox = that._label.getBoundingRect(),
  26479. coord = that._getColumnsCoord(bbox);
  26480. coord = that._checkHorizontalLabelPosition(coord, bbox, that._getVisibleArea());
  26481. that._label.shift(_round(coord.x), _round(bbox.y))
  26482. },
  26483. _checkVerticalLabelPosition: function(coord, box, visibleArea) {
  26484. var x = coord.x,
  26485. y = coord.y;
  26486. if (coord.y + box.height > visibleArea.maxY)
  26487. y = visibleArea.maxY - box.height;
  26488. else if (coord.y < visibleArea.minY)
  26489. y = visibleArea.minY;
  26490. return {
  26491. x: x,
  26492. y: y
  26493. }
  26494. },
  26495. _getLabelExtraCoord: function(coord, shiftCoord, box) {
  26496. return coord.y !== shiftCoord.y ? getVerticallyShiftedAngularCoords({
  26497. x: coord.x,
  26498. y: coord.y,
  26499. width: box.width,
  26500. height: box.height
  26501. }, shiftCoord.y - coord.y, {
  26502. x: this.centerX,
  26503. y: this.centerY
  26504. }) : coord
  26505. },
  26506. _checkHorizontalLabelPosition: function(coord, box, visibleArea) {
  26507. var x = coord.x,
  26508. y = coord.y;
  26509. if (coord.x + box.width > visibleArea.maxX)
  26510. x = visibleArea.maxX - box.width;
  26511. else if (coord.x < visibleArea.minX)
  26512. x = visibleArea.minX;
  26513. return {
  26514. x: x,
  26515. y: y
  26516. }
  26517. },
  26518. setLabelEllipsis: function() {
  26519. var that = this,
  26520. bbox = that._label.getBoundingRect(),
  26521. coord = that._checkHorizontalLabelPosition(bbox, bbox, that._getVisibleArea());
  26522. that._label.fit({
  26523. width: bbox.width - _abs(coord.x - bbox.x),
  26524. height: bbox.height - _abs(coord.y - bbox.y)
  26525. })
  26526. },
  26527. _getVisibleArea: function() {
  26528. var canvas = this.series.canvas;
  26529. return {
  26530. minX: canvas.left,
  26531. maxX: canvas.width - canvas.right,
  26532. minY: canvas.top,
  26533. maxY: canvas.height - canvas.bottom
  26534. }
  26535. },
  26536. _checkLabelPosition: function(coord, bbox, visibleArea) {
  26537. coord = this._checkHorizontalLabelPosition(coord, bbox, visibleArea);
  26538. return this._checkVerticalLabelPosition(coord, bbox, visibleArea)
  26539. },
  26540. getBoundaryCoords: function() {
  26541. var that = this,
  26542. rad = that.radiusOuter,
  26543. seriesStyle = that._options.styles.normal,
  26544. strokeWidthBy2 = seriesStyle["stroke-width"] / 2,
  26545. borderWidth = that.series.getOptions().containerBackgroundColor === seriesStyle.stroke ? _round(strokeWidthBy2) : _round(-strokeWidthBy2),
  26546. angleFunctions = _getCosAndSin(_round(that.middleAngle));
  26547. return {
  26548. x: _round(that.centerX + (rad - borderWidth) * angleFunctions.cos),
  26549. y: _round(that.centerY - (rad - borderWidth) * angleFunctions.sin)
  26550. }
  26551. },
  26552. _getLabelConnector: function() {
  26553. var coords = this.getBoundaryCoords();
  26554. coords.angle = this.middleAngle;
  26555. return coords
  26556. },
  26557. _drawMarker: function(renderer, group, animationEnabled, firstDrawing) {
  26558. var that = this,
  26559. radiusOuter = that.radiusOuter,
  26560. radiusInner = that.radiusInner,
  26561. fromAngle = that.fromAngle,
  26562. toAngle = that.toAngle;
  26563. if (animationEnabled) {
  26564. radiusInner = radiusOuter = 0;
  26565. if (!firstDrawing)
  26566. fromAngle = toAngle = that.shiftedAngle
  26567. }
  26568. that.graphic = renderer.arc(that.centerX, that.centerY, radiusInner, radiusOuter, toAngle, fromAngle).attr({"stroke-linejoin": "round"}).attr(that._getStyle()).data({point: that}).sharp().append(group)
  26569. },
  26570. getTooltipParams: function() {
  26571. var that = this,
  26572. angleFunctions = _getCosAndSin(that.middleAngle),
  26573. radiusInner = that.radiusInner,
  26574. radiusOuter = that.radiusOuter;
  26575. return {
  26576. x: that.centerX + (radiusInner + (radiusOuter - radiusInner) / 2) * angleFunctions.cos,
  26577. y: that.centerY - (radiusInner + (radiusOuter - radiusInner) / 2) * angleFunctions.sin,
  26578. offset: 0
  26579. }
  26580. },
  26581. _translate: function(translator) {
  26582. var that = this,
  26583. angle = that.shiftedAngle || 0,
  26584. value = that.value,
  26585. minValue = that.minValue;
  26586. that.fromAngle = translator.translate(minValue) + angle;
  26587. that.toAngle = translator.translate(value) + angle;
  26588. that.middleAngle = translator.translate((value - minValue) / 2 + minValue) + angle;
  26589. if (!that.isVisible())
  26590. that.middleAngle = that.toAngle = that.fromAngle = that.fromAngle || angle
  26591. },
  26592. _getMarkerVisibility: function() {
  26593. return true
  26594. },
  26595. _updateMarker: function(animationEnabled, style) {
  26596. var that = this;
  26597. style = style || that._getStyle();
  26598. if (!animationEnabled)
  26599. style = _extend({
  26600. x: that.centerX,
  26601. y: that.centerY,
  26602. outerRadius: that.radiusOuter,
  26603. innerRadius: that.radiusInner,
  26604. startAngle: that.toAngle,
  26605. endAngle: that.fromAngle
  26606. }, style);
  26607. that.graphic.attr(style).sharp()
  26608. },
  26609. getLegendStyles: function() {
  26610. return this._styles.legendStyles
  26611. },
  26612. isInVisibleArea: function() {
  26613. return true
  26614. },
  26615. hide: function() {
  26616. var that = this;
  26617. if (that._visible) {
  26618. that._visible = false;
  26619. that.hideTooltip();
  26620. that._options.visibilityChanged(that)
  26621. }
  26622. },
  26623. show: function() {
  26624. var that = this;
  26625. if (!that._visible) {
  26626. that._visible = true;
  26627. that._options.visibilityChanged(that)
  26628. }
  26629. },
  26630. setInvisibility: function() {
  26631. this._label.hide()
  26632. },
  26633. isVisible: function() {
  26634. return this._visible
  26635. },
  26636. _getFormatObject: function(tooltip) {
  26637. var formatObject = points.symbolPoint._getFormatObject.call(this, tooltip),
  26638. percent = this.percent;
  26639. formatObject.percent = percent;
  26640. formatObject.percentText = tooltip.formatValue(percent, "percent");
  26641. return formatObject
  26642. },
  26643. getColor: function() {
  26644. return this._styles.normal.fill
  26645. },
  26646. coordsIn: function(x, y) {
  26647. var that = this,
  26648. lx = x - that.centerX,
  26649. ly = y - that.centerY,
  26650. r = _sqrt(lx * lx + ly * ly),
  26651. fromAngle = that.fromAngle % 360,
  26652. toAngle = that.toAngle % 360,
  26653. angle;
  26654. if (r < that.radiusInner || r > that.radiusOuter || r === 0)
  26655. return false;
  26656. angle = _acos(lx / r) * DEG * (ly > 0 ? -1 : 1);
  26657. if (angle < 0)
  26658. angle += 360;
  26659. if (fromAngle === toAngle && _abs(that.toAngle - that.fromAngle) > 1E-4)
  26660. return true;
  26661. else
  26662. return fromAngle >= toAngle ? angle <= fromAngle && angle >= toAngle : !(angle >= fromAngle && angle <= toAngle)
  26663. }
  26664. })
  26665. })(jQuery, DevExpress);
  26666. /*! Module viz-core, file rangeSymbolPoint.js */
  26667. (function($, DX) {
  26668. var core = DX.viz.core,
  26669. points = core.series.points.mixins,
  26670. _extend = $.extend,
  26671. _isDefined = DX.utils.isDefined,
  26672. _math = Math,
  26673. _abs = _math.abs,
  26674. _min = _math.min,
  26675. _max = _math.max,
  26676. _round = _math.round,
  26677. DEFAULT_IMAGE_WIDTH = 20,
  26678. DEFAULT_IMAGE_HEIGHT = 20;
  26679. points.rangeSymbolPoint = _extend({}, points.symbolPoint, {
  26680. deleteLabel: function() {
  26681. var that = this;
  26682. that._topLabel.dispose();
  26683. that._topLabel = null;
  26684. that._bottomLabel.dispose();
  26685. that._bottomLabel = null
  26686. },
  26687. hideMarker: function(type) {
  26688. var graphic = this.graphic,
  26689. marker = graphic && graphic[type + "Marker"],
  26690. label = this["_" + type + "Label"];
  26691. if (marker && marker.attr("visibility") !== "hidden")
  26692. marker.attr({visibility: "hidden"});
  26693. label.hide()
  26694. },
  26695. setInvisibility: function() {
  26696. this.hideMarker("top");
  26697. this.hideMarker("bottom")
  26698. },
  26699. clearVisibility: function() {
  26700. var that = this,
  26701. graphic = that.graphic,
  26702. topMarker = graphic && graphic.topMarker,
  26703. bottomMarker = graphic && graphic.bottomMarker;
  26704. if (topMarker && topMarker.attr("visibility"))
  26705. topMarker.attr({visibility: null});
  26706. if (bottomMarker && bottomMarker.attr("visibility"))
  26707. bottomMarker.attr({visibility: null});
  26708. that._topLabel.clearVisibility();
  26709. that._bottomLabel.clearVisibility()
  26710. },
  26711. clearMarker: function() {
  26712. var that = this,
  26713. graphic = that.graphic,
  26714. topMarker = graphic && graphic.topMarker,
  26715. bottomMarker = graphic && graphic.bottomMarker,
  26716. emptySettings = that._emptySettings;
  26717. topMarker && topMarker.attr(emptySettings);
  26718. bottomMarker && bottomMarker.attr(emptySettings)
  26719. },
  26720. _getLabelPosition: function(markerType) {
  26721. var position,
  26722. labelsInside = this._options.label.position === "inside";
  26723. if (!this._options.rotated)
  26724. position = markerType === "top" ^ labelsInside ? "top" : "bottom";
  26725. else
  26726. position = markerType === "top" ^ labelsInside ? "right" : "left";
  26727. return position
  26728. },
  26729. _getLabelMinFormatObject: function() {
  26730. var that = this;
  26731. return {
  26732. index: 0,
  26733. argument: that.initialArgument,
  26734. value: that.initialMinValue,
  26735. seriesName: that.series.name,
  26736. originalValue: that.originalMinValue,
  26737. originalArgument: that.originalArgument,
  26738. point: that
  26739. }
  26740. },
  26741. _updateLabelData: function() {
  26742. var maxFormatObject = this._getLabelFormatObject();
  26743. maxFormatObject.index = 1;
  26744. this._topLabel.setData(maxFormatObject);
  26745. this._bottomLabel.setData(this._getLabelMinFormatObject())
  26746. },
  26747. _updateLabelOptions: function() {
  26748. var that = this,
  26749. options = this._options.label;
  26750. (!that._topLabel || !that._bottomLabel) && that._createLabel();
  26751. that._topLabel.setOptions(options);
  26752. that._bottomLabel.setOptions(options)
  26753. },
  26754. _createLabel: function() {
  26755. this._topLabel = core.CoreFactory.createLabel();
  26756. this._bottomLabel = core.CoreFactory.createLabel()
  26757. },
  26758. _getGraphicBbox: function(location) {
  26759. location = location || this._labelLocation;
  26760. var options = this._options,
  26761. images = this._getImage(options.image),
  26762. image = location === "top" ? this._checkImage(images.top) : this._checkImage(images.bottom),
  26763. bbox,
  26764. coord = this._getPositionFromLocation(location);
  26765. if (options.visible)
  26766. bbox = image ? this._getImageBbox(coord.x, coord.y) : this._getSymbolBbox(coord.x, coord.y, options.styles.normal.r);
  26767. else
  26768. bbox = {
  26769. x: coord.x,
  26770. y: coord.y,
  26771. width: 0,
  26772. height: 0
  26773. };
  26774. return bbox
  26775. },
  26776. _getPositionFromLocation: function(location) {
  26777. var x,
  26778. y,
  26779. isTop = location === "top";
  26780. if (!this._options.rotated) {
  26781. x = this.x;
  26782. y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)
  26783. }
  26784. else {
  26785. x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);
  26786. y = this.y
  26787. }
  26788. return {
  26789. x: x,
  26790. y: y
  26791. }
  26792. },
  26793. _checkOverlay: function(bottomCoord, topCoord, topValue) {
  26794. return bottomCoord < topCoord + topValue
  26795. },
  26796. _getOverlayCorrections: function(type, topCoords, bottomCoords) {
  26797. var isVertical = type === "vertical",
  26798. coordSelector = isVertical ? "y" : "x",
  26799. valueSelector = isVertical ? "height" : "width",
  26800. visibleArea = this.translators[coordSelector].getCanvasVisibleArea(),
  26801. minBound = visibleArea.min,
  26802. maxBound = visibleArea.max,
  26803. delta = _round((topCoords[coordSelector] + topCoords[valueSelector] - bottomCoords[coordSelector]) / 2),
  26804. coord1 = topCoords[coordSelector] - delta,
  26805. coord2 = bottomCoords[coordSelector] + delta;
  26806. if (coord1 < minBound) {
  26807. delta = minBound - topCoords[coordSelector];
  26808. coord1 += delta;
  26809. coord2 += delta
  26810. }
  26811. else if (coord2 + bottomCoords[valueSelector] > maxBound) {
  26812. delta = -(bottomCoords[coordSelector] + bottomCoords[valueSelector] - maxBound);
  26813. coord1 += delta;
  26814. coord2 += delta
  26815. }
  26816. return {
  26817. coord1: coord1,
  26818. coord2: coord2
  26819. }
  26820. },
  26821. _checkLabelsOverlay: function(topLocation) {
  26822. var that = this,
  26823. topCoords = that._topLabel.getBoundingRect(),
  26824. bottomCoords = that._bottomLabel.getBoundingRect(),
  26825. corrections = {};
  26826. if (!that._options.rotated) {
  26827. if (topLocation === "top") {
  26828. if (this._checkOverlay(bottomCoords.y, topCoords.y, topCoords.height)) {
  26829. corrections = this._getOverlayCorrections("vertical", topCoords, bottomCoords);
  26830. that._topLabel.shift(topCoords.x, corrections.coord1);
  26831. that._bottomLabel.shift(bottomCoords.x, corrections.coord2)
  26832. }
  26833. }
  26834. else if (this._checkOverlay(topCoords.y, bottomCoords.y, bottomCoords.height)) {
  26835. corrections = this._getOverlayCorrections("vertical", bottomCoords, topCoords);
  26836. that._topLabel.shift(topCoords.x, corrections.coord2);
  26837. that._bottomLabel.shift(bottomCoords.x, corrections.coord1)
  26838. }
  26839. }
  26840. else if (topLocation === "top") {
  26841. if (this._checkOverlay(topCoords.x, bottomCoords.x, bottomCoords.width)) {
  26842. corrections = this._getOverlayCorrections("horizontal", bottomCoords, topCoords);
  26843. that._topLabel.shift(corrections.coord2, topCoords.y);
  26844. that._bottomLabel.shift(corrections.coord1, bottomCoords.y)
  26845. }
  26846. }
  26847. else if (this._checkOverlay(bottomCoords.x, topCoords.x, topCoords.width)) {
  26848. corrections = this._getOverlayCorrections("horizontal", topCoords, bottomCoords);
  26849. that._topLabel.shift(corrections.coord1, topCoords.y);
  26850. that._bottomLabel.shift(corrections.coord2, bottomCoords.y)
  26851. }
  26852. },
  26853. _drawLabel: function(renderer, group) {
  26854. var that = this,
  26855. coord,
  26856. labels = [],
  26857. notInverted = that._options.rotated ? that.x >= that.minX : that.y < that.minY,
  26858. customVisibility = that._getCustomLabelVisibility();
  26859. that._topLabel.pointPosition = notInverted ? "top" : "bottom";
  26860. that._bottomLabel.pointPosition = notInverted ? "bottom" : "top";
  26861. if ((that.series.getLabelVisibility() || customVisibility !== null) && that.hasValue()) {
  26862. that.visibleTopMarker !== false && labels.push(that._topLabel);
  26863. that.visibleBottomMarker !== false && labels.push(that._bottomLabel);
  26864. $.each(labels, function(_, label) {
  26865. var pointPosition = label.pointPosition;
  26866. label.draw(renderer, group, customVisibility);
  26867. coord = that._addLabelAlignmentAndOffset(label, that._getLabelCoords(label, pointPosition));
  26868. coord = that._checkLabelPosition(label, coord, pointPosition);
  26869. that._labelLocation = label.pointPosition;
  26870. label.setFigureToDrawConnector(that._getLabelConnector());
  26871. that._labelLocation = null;
  26872. label.shift(_round(coord.x), _round(coord.y))
  26873. });
  26874. that._checkLabelsOverlay(that._topLabel.pointPosition)
  26875. }
  26876. else {
  26877. that._topLabel.hide();
  26878. that._bottomLabel.hide()
  26879. }
  26880. },
  26881. _getImage: function(imageOption) {
  26882. var image = {};
  26883. if (_isDefined(imageOption))
  26884. if (typeof imageOption === "string")
  26885. image.top = image.bottom = imageOption;
  26886. else {
  26887. image.top = {
  26888. url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMaxPoint,
  26889. width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMaxPoint,
  26890. height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMaxPoint
  26891. };
  26892. image.bottom = {
  26893. url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMinPoint,
  26894. width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMinPoint,
  26895. height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMinPoint
  26896. }
  26897. }
  26898. return image
  26899. },
  26900. _checkSymbol: function(oldOptions, newOptions) {
  26901. var that = this,
  26902. oldSymbol = oldOptions.symbol,
  26903. newSymbol = newOptions.symbol,
  26904. symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
  26905. oldImages = that._getImage(oldOptions.image),
  26906. newImages = that._getImage(newOptions.image),
  26907. topImageChanged = that._checkImage(oldImages.top) !== that._checkImage(newImages.top),
  26908. bottomImageChanged = that._checkImage(oldImages.bottom) !== that._checkImage(newImages.bottom);
  26909. return symbolChanged || topImageChanged || bottomImageChanged
  26910. },
  26911. _getSettingsForTwoMarkers: function(style) {
  26912. var that = this,
  26913. options = that._options,
  26914. settings = {},
  26915. x = options.rotated ? _min(that.x, that.minX) : that.x,
  26916. y = options.rotated ? that.y : _min(that.y, that.minY),
  26917. radius = style.r,
  26918. points = that._populatePointShape(options.symbol, radius);
  26919. settings.top = _extend({
  26920. translateX: x + that.width,
  26921. translateY: y,
  26922. r: radius
  26923. }, style);
  26924. settings.bottom = _extend({
  26925. translateX: x,
  26926. translateY: y + that.height,
  26927. r: radius
  26928. }, style);
  26929. if (points)
  26930. settings.top.points = settings.bottom.points = points;
  26931. return settings
  26932. },
  26933. _hasGraphic: function() {
  26934. return this.graphic && this.graphic.topMarker && this.graphic.bottomMarker
  26935. },
  26936. _drawOneMarker: function(renderer, markerType, imageSettings, settings) {
  26937. var that = this,
  26938. graphic = that.graphic;
  26939. if (graphic[markerType])
  26940. that._updateOneMarker(markerType, settings);
  26941. else
  26942. graphic[markerType] = that._createMarker(renderer, graphic, imageSettings, settings)
  26943. },
  26944. _drawMarker: function(renderer, group, animationEnabled, firstDrawing, style) {
  26945. var that = this,
  26946. settings = that._getSettingsForTwoMarkers(style || that._getStyle()),
  26947. image = that._getImage(that._options.image);
  26948. if (that._checkImage(image.top))
  26949. settings.top = that._getImageSettings(settings.top, image.top);
  26950. if (that._checkImage(image.bottom))
  26951. settings.bottom = that._getImageSettings(settings.bottom, image.bottom);
  26952. that.graphic = that.graphic || renderer.g().append(group);
  26953. that.visibleTopMarker && that._drawOneMarker(renderer, 'topMarker', image.top, settings.top);
  26954. that.visibleBottomMarker && that._drawOneMarker(renderer, 'bottomMarker', image.bottom, settings.bottom)
  26955. },
  26956. _getSettingsForTracker: function(radius) {
  26957. var that = this,
  26958. rotated = that._options.rotated;
  26959. return {
  26960. translateX: rotated ? _min(that.x, that.minX) - radius : that.x - radius,
  26961. translateY: rotated ? that.y - radius : _min(that.y, that.minY) - radius,
  26962. width: that.width + 2 * radius,
  26963. height: that.height + 2 * radius
  26964. }
  26965. },
  26966. isInVisibleArea: function() {
  26967. var that = this,
  26968. rotated = that._options.rotated,
  26969. argument = !rotated ? that.x : that.y,
  26970. maxValue = !rotated ? _max(that.minY, that.y) : _max(that.minX, that.x),
  26971. minValue = !rotated ? _min(that.minY, that.y) : _min(that.minX, that.x),
  26972. translators = that.translators,
  26973. notVisibleByArg,
  26974. notVisibleByVal,
  26975. tmp,
  26976. visibleTopMarker = true,
  26977. visibleBottomMarker = true,
  26978. visibleRangeArea = true,
  26979. visibleArgArea,
  26980. visibleValArea;
  26981. if (translators) {
  26982. visibleArgArea = translators[!rotated ? "x" : "y"].getCanvasVisibleArea();
  26983. visibleValArea = translators[!rotated ? "y" : "x"].getCanvasVisibleArea();
  26984. notVisibleByArg = visibleArgArea.max < argument || visibleArgArea.min > argument;
  26985. notVisibleByVal = visibleValArea.min > minValue && visibleValArea.min > maxValue || visibleValArea.max < minValue && visibleValArea.max < maxValue;
  26986. if (notVisibleByArg || notVisibleByVal)
  26987. visibleTopMarker = visibleBottomMarker = visibleRangeArea = false;
  26988. else {
  26989. visibleTopMarker = visibleValArea.min <= minValue && visibleValArea.max > minValue;
  26990. visibleBottomMarker = visibleValArea.min < maxValue && visibleValArea.max >= maxValue;
  26991. if (rotated) {
  26992. tmp = visibleTopMarker;
  26993. visibleTopMarker = visibleBottomMarker;
  26994. visibleBottomMarker = tmp
  26995. }
  26996. }
  26997. }
  26998. that.visibleTopMarker = visibleTopMarker;
  26999. that.visibleBottomMarker = visibleBottomMarker;
  27000. return visibleRangeArea
  27001. },
  27002. getTooltipParams: function() {
  27003. var that = this,
  27004. x,
  27005. y,
  27006. min,
  27007. max,
  27008. minValue,
  27009. translators = that.translators,
  27010. visibleAreaX = translators.x.getCanvasVisibleArea(),
  27011. visibleAreaY = translators.y.getCanvasVisibleArea();
  27012. if (!that._options.rotated) {
  27013. minValue = _min(that.y, that.minY);
  27014. x = that.x;
  27015. min = visibleAreaY.min > minValue ? visibleAreaY.min : minValue;
  27016. max = visibleAreaY.max < minValue + that.height ? visibleAreaY.max : minValue + that.height;
  27017. y = min + (max - min) / 2
  27018. }
  27019. else {
  27020. minValue = _min(that.x, that.minX);
  27021. y = that.y;
  27022. min = visibleAreaX.min > minValue ? visibleAreaX.min : minValue;
  27023. max = visibleAreaX.max < minValue + that.width ? visibleAreaX.max : minValue + that.width;
  27024. x = min + (max - min) / 2
  27025. }
  27026. return {
  27027. x: x,
  27028. y: y,
  27029. offset: 0
  27030. }
  27031. },
  27032. _translate: function(translators) {
  27033. var that = this,
  27034. rotated = that._options.rotated;
  27035. that.minX = that.minY = translators.y.translate(that.minValue);
  27036. points.symbolPoint._translate.call(that, translators);
  27037. that.height = rotated ? 0 : _abs(that.minY - that.y);
  27038. that.width = rotated ? _abs(that.x - that.minX) : 0
  27039. },
  27040. _updateData: function(data) {
  27041. var that = this;
  27042. points.symbolPoint._updateData.call(that, data);
  27043. that.minValue = that.initialMinValue = that.originalMinValue = data.minValue
  27044. },
  27045. _getImageSettings: function(settings, image) {
  27046. return {
  27047. href: image.url || image.toString(),
  27048. width: image.width || DEFAULT_IMAGE_WIDTH,
  27049. height: image.height || DEFAULT_IMAGE_HEIGHT,
  27050. translateX: settings.translateX,
  27051. translateY: settings.translateY
  27052. }
  27053. },
  27054. getCrosshairCoords: function(x, y) {
  27055. var coords;
  27056. if (this._options.rotated)
  27057. coords = {
  27058. y: this.vy,
  27059. x: Math.abs(this.vx - x) < Math.abs(this.minX - x) ? this.vx : this.minX
  27060. };
  27061. else
  27062. coords = {
  27063. x: this.vx,
  27064. y: Math.abs(this.vy - y) < Math.abs(this.minY - y) ? this.vy : this.minY
  27065. };
  27066. return coords
  27067. },
  27068. _updateOneMarker: function(markerType, settings) {
  27069. this.graphic && this.graphic[markerType] && this.graphic[markerType].attr(settings)
  27070. },
  27071. _updateMarker: function(animationEnabled, style) {
  27072. this._drawMarker(undefined, undefined, false, false, style)
  27073. },
  27074. _getFormatObject: function(tooltip) {
  27075. var that = this,
  27076. initialMinValue = that.initialMinValue,
  27077. initialValue = that.initialValue,
  27078. initialArgument = that.initialArgument,
  27079. minValue = tooltip.formatValue(initialMinValue),
  27080. value = tooltip.formatValue(initialValue);
  27081. return {
  27082. argument: initialArgument,
  27083. argumentText: tooltip.formatValue(initialArgument, "argument"),
  27084. valueText: minValue + " - " + value,
  27085. rangeValue1Text: minValue,
  27086. rangeValue2Text: value,
  27087. rangeValue1: initialMinValue,
  27088. rangeValue2: initialValue,
  27089. seriesName: that.series.name,
  27090. point: that,
  27091. originalMinValue: that.originalMinValue,
  27092. originalValue: that.originalValue,
  27093. originalArgument: that.originalArgument
  27094. }
  27095. },
  27096. getLabel: function() {
  27097. return [this._topLabel, this._bottomLabel]
  27098. },
  27099. getBoundingRect: $.noop,
  27100. coordsIn: function(x, y) {
  27101. var trackerRadius = this._storeTrackerR(),
  27102. xCond = x >= this.x - trackerRadius && x <= this.x + trackerRadius,
  27103. yCond = y >= this.y - trackerRadius && y <= this.y + trackerRadius;
  27104. if (this._options.rotated)
  27105. return yCond && (xCond || x >= this.minX - trackerRadius && x <= this.minX + trackerRadius);
  27106. else
  27107. return xCond && (yCond || y >= this.minY - trackerRadius && y <= this.minY + trackerRadius)
  27108. }
  27109. })
  27110. })(jQuery, DevExpress);
  27111. /*! Module viz-core, file rangeBarPoint.js */
  27112. (function($, DX) {
  27113. var points = DX.viz.core.series.points.mixins,
  27114. rangeSymbolPointMethods = points.rangeSymbolPoint,
  27115. _extend = $.extend;
  27116. points.rangeBarPoint = _extend({}, points.barPoint, {
  27117. deleteLabel: rangeSymbolPointMethods.deleteLabel,
  27118. _getFormatObject: rangeSymbolPointMethods._getFormatObject,
  27119. clearVisibility: function() {
  27120. var graphic = this.graphic;
  27121. if (graphic && graphic.attr("visibility"))
  27122. graphic.attr({visibility: null});
  27123. this._topLabel.clearVisibility();
  27124. this._bottomLabel.clearVisibility()
  27125. },
  27126. setInvisibility: function() {
  27127. var graphic = this.graphic;
  27128. if (graphic && graphic.attr("visibility") !== "hidden")
  27129. graphic.attr({visibility: "hidden"});
  27130. this._topLabel.hide();
  27131. this._bottomLabel.hide()
  27132. },
  27133. getTooltipParams: function(location) {
  27134. var edgeLocation = location === 'edge',
  27135. x,
  27136. y;
  27137. if (this._options.rotated) {
  27138. x = edgeLocation ? this.x + this.width : this.x + this.width / 2;
  27139. y = this.y + this.height / 2
  27140. }
  27141. else {
  27142. x = this.x + this.width / 2;
  27143. y = edgeLocation ? this.y : this.y + this.height / 2
  27144. }
  27145. return {
  27146. x: x,
  27147. y: y,
  27148. offset: 0
  27149. }
  27150. },
  27151. _translate: function(translator) {
  27152. var that = this,
  27153. barMethods = points.barPoint;
  27154. barMethods._translate.call(that, translator);
  27155. if (that._options.rotated)
  27156. that.width = that.width || 1;
  27157. else
  27158. that.height = that.height || 1
  27159. },
  27160. _updateData: rangeSymbolPointMethods._updateData,
  27161. _getLabelPosition: rangeSymbolPointMethods._getLabelPosition,
  27162. _getLabelMinFormatObject: rangeSymbolPointMethods._getLabelMinFormatObject,
  27163. _updateLabelData: rangeSymbolPointMethods._updateLabelData,
  27164. _updateLabelOptions: rangeSymbolPointMethods._updateLabelOptions,
  27165. getCrosshairCoords: rangeSymbolPointMethods.getCrosshairCoords,
  27166. _createLabel: rangeSymbolPointMethods._createLabel,
  27167. _checkOverlay: rangeSymbolPointMethods._checkOverlay,
  27168. _checkLabelsOverlay: rangeSymbolPointMethods._checkLabelsOverlay,
  27169. _getOverlayCorrections: rangeSymbolPointMethods._getOverlayCorrections,
  27170. _drawLabel: rangeSymbolPointMethods._drawLabel,
  27171. _getLabelCoords: rangeSymbolPointMethods._getLabelCoords,
  27172. _getGraphicBbox: function(location) {
  27173. location = location || this._labelLocation;
  27174. var isTop = location === "top",
  27175. bbox = points.barPoint._getGraphicBbox.call(this);
  27176. if (!this._options.rotated) {
  27177. bbox.y = isTop ? bbox.y : bbox.y + bbox.height;
  27178. bbox.height = 0
  27179. }
  27180. else {
  27181. bbox.x = isTop ? bbox.x + bbox.width : bbox.x;
  27182. bbox.width = 0
  27183. }
  27184. return bbox
  27185. },
  27186. getLabel: rangeSymbolPointMethods.getLabel,
  27187. getBoundingRect: $.noop
  27188. })
  27189. })(jQuery, DevExpress);
  27190. /*! Module viz-core, file candlestickPoint.js */
  27191. (function($, DX) {
  27192. var viz = DX.viz,
  27193. points = viz.core.series.points.mixins,
  27194. _isNumeric = $.isNumeric,
  27195. _extend = $.extend,
  27196. _math = Math,
  27197. _abs = _math.abs,
  27198. _min = _math.min,
  27199. _max = _math.max,
  27200. _round = _math.round,
  27201. DEFAULT_FINANCIAL_TRACKER_MARGIN = 2;
  27202. points.candlestickPoint = _extend({}, points.barPoint, {
  27203. _getContinuousPoints: function(minValueName, maxValueName) {
  27204. var that = this,
  27205. x = that.x,
  27206. createPoint = that._options.rotated ? function(x, y) {
  27207. return [y, x]
  27208. } : function(x, y) {
  27209. return [x, y]
  27210. },
  27211. width = that.width,
  27212. min = that[minValueName],
  27213. max = that[maxValueName],
  27214. points;
  27215. if (min === max)
  27216. points = [].concat(createPoint(x, that.highY)).concat(createPoint(x, that.lowY)).concat(createPoint(x, that.closeY)).concat(createPoint(x - width / 2, that.closeY)).concat(createPoint(x + width / 2, that.closeY)).concat(createPoint(x, that.closeY));
  27217. else
  27218. points = [].concat(createPoint(x, that.highY)).concat(createPoint(x, max)).concat(createPoint(x + width / 2, max)).concat(createPoint(x + width / 2, min)).concat(createPoint(x, min)).concat(createPoint(x, that.lowY)).concat(createPoint(x, min)).concat(createPoint(x - width / 2, min)).concat(createPoint(x - width / 2, max)).concat(createPoint(x, max));
  27219. return points
  27220. },
  27221. _getCategoryPoints: function(y) {
  27222. var that = this,
  27223. x = that.x,
  27224. createPoint = that._options.rotated ? function(x, y) {
  27225. return [y, x]
  27226. } : function(x, y) {
  27227. return [x, y]
  27228. };
  27229. return [].concat(createPoint(x, that.highY)).concat(createPoint(x, that.lowY)).concat(createPoint(x, y)).concat(createPoint(x - that.width / 2, y)).concat(createPoint(x + that.width / 2, y)).concat(createPoint(x, y))
  27230. },
  27231. _getPoints: function() {
  27232. var that = this,
  27233. points,
  27234. minValueName,
  27235. maxValueName,
  27236. openValue = that.openValue,
  27237. closeValue = that.closeValue;
  27238. if (_isNumeric(openValue) && _isNumeric(closeValue)) {
  27239. minValueName = openValue > closeValue ? "closeY" : "openY";
  27240. maxValueName = openValue > closeValue ? "openY" : "closeY";
  27241. points = that._getContinuousPoints(minValueName, maxValueName)
  27242. }
  27243. else if (openValue === closeValue)
  27244. points = [that.x, that.highY, that.x, that.lowY];
  27245. else
  27246. points = that._getCategoryPoints(_isNumeric(openValue) ? that.openY : that.closeY);
  27247. return points
  27248. },
  27249. getColor: function() {
  27250. var that = this;
  27251. return that._isReduction ? that._options.reduction.color : that._styles.normal.stroke || that.series.getColor()
  27252. },
  27253. _drawMarkerInGroup: function(group, attributes, renderer) {
  27254. var that = this;
  27255. that.graphic = renderer.path(that._getPoints(), "area").attr({"stroke-linecap": "square"}).attr(attributes).data({point: that}).sharp().append(group)
  27256. },
  27257. _fillStyle: function() {
  27258. var that = this,
  27259. styles = that._options.styles;
  27260. if (that._isReduction && that._isPositive)
  27261. that._styles = styles.reductionPositive;
  27262. else if (that._isReduction)
  27263. that._styles = styles.reduction;
  27264. else if (that._isPositive)
  27265. that._styles = styles.positive;
  27266. else
  27267. that._styles = styles
  27268. },
  27269. _getMinTrackerWidth: function() {
  27270. return 2 + 2 * this._styles.normal['stroke-width']
  27271. },
  27272. correctCoordinates: function(correctOptions) {
  27273. var minWidth = this._getMinTrackerWidth(),
  27274. maxWidth = 10,
  27275. width = correctOptions.width;
  27276. width = width < minWidth ? minWidth : width > maxWidth ? maxWidth : width;
  27277. this.width = width + width % 2;
  27278. this.xCorrection = correctOptions.offset
  27279. },
  27280. _getMarkerGroup: function(group) {
  27281. var that = this,
  27282. markerGroup;
  27283. if (that._isReduction && that._isPositive)
  27284. markerGroup = group.reductionPositiveMarkersGroup;
  27285. else if (that._isReduction)
  27286. markerGroup = group.reductionMarkersGroup;
  27287. else if (that._isPositive)
  27288. markerGroup = group.defaultPositiveMarkersGroup;
  27289. else
  27290. markerGroup = group.defaultMarkersGroup;
  27291. return markerGroup
  27292. },
  27293. _drawMarker: function(renderer, group) {
  27294. this._drawMarkerInGroup(this._getMarkerGroup(group), this._getStyle(), renderer)
  27295. },
  27296. _getSettingsForTracker: function() {
  27297. var that = this,
  27298. highY = that.highY,
  27299. lowY = that.lowY,
  27300. rotated = that._options.rotated,
  27301. x,
  27302. y,
  27303. width,
  27304. height;
  27305. if (highY === lowY) {
  27306. highY = rotated ? highY + DEFAULT_FINANCIAL_TRACKER_MARGIN : highY - DEFAULT_FINANCIAL_TRACKER_MARGIN;
  27307. lowY = rotated ? lowY - DEFAULT_FINANCIAL_TRACKER_MARGIN : lowY + DEFAULT_FINANCIAL_TRACKER_MARGIN
  27308. }
  27309. if (rotated) {
  27310. x = _min(lowY, highY);
  27311. y = that.x - that.width / 2;
  27312. width = _abs(lowY - highY);
  27313. height = that.width
  27314. }
  27315. else {
  27316. x = that.x - that.width / 2;
  27317. y = _min(lowY, highY);
  27318. width = that.width;
  27319. height = _abs(lowY - highY)
  27320. }
  27321. return {
  27322. x: x,
  27323. y: y,
  27324. width: width,
  27325. height: height
  27326. }
  27327. },
  27328. _getGraphicBbox: function() {
  27329. var that = this,
  27330. rotated = that._options.rotated,
  27331. x = that.x,
  27332. width = that.width,
  27333. lowY = that.lowY,
  27334. highY = that.highY;
  27335. return {
  27336. x: !rotated ? x - _round(width / 2) : lowY,
  27337. y: !rotated ? highY : x - _round(width / 2),
  27338. width: !rotated ? width : highY - lowY,
  27339. height: !rotated ? lowY - highY : width
  27340. }
  27341. },
  27342. getTooltipParams: function(location) {
  27343. var that = this;
  27344. if (that.graphic) {
  27345. var x,
  27346. y,
  27347. min,
  27348. max,
  27349. minValue = _min(that.lowY, that.highY),
  27350. maxValue = _max(that.lowY, that.highY),
  27351. visibleAreaX = that.translators.x.getCanvasVisibleArea(),
  27352. visibleAreaY = that.translators.y.getCanvasVisibleArea(),
  27353. edgeLocation = location === 'edge';
  27354. if (!that._options.rotated) {
  27355. min = _max(visibleAreaY.min, minValue);
  27356. max = _min(visibleAreaY.max, maxValue);
  27357. x = that.x;
  27358. y = edgeLocation ? min : min + (max - min) / 2
  27359. }
  27360. else {
  27361. min = _max(visibleAreaX.min, minValue);
  27362. max = _min(visibleAreaX.max, maxValue);
  27363. y = that.x;
  27364. x = edgeLocation ? max : min + (max - min) / 2
  27365. }
  27366. return {
  27367. x: x,
  27368. y: y,
  27369. offset: 0
  27370. }
  27371. }
  27372. },
  27373. hasValue: function() {
  27374. return this.highValue !== null && this.lowValue !== null
  27375. },
  27376. _translate: function() {
  27377. var that = this,
  27378. rotated = that._options.rotated,
  27379. translators = that.translators,
  27380. argTranslator = rotated ? translators.y : translators.x,
  27381. valTranslator = rotated ? translators.x : translators.y,
  27382. centerValue,
  27383. height;
  27384. that.vx = that.vy = that.x = argTranslator.translate(that.argument) + (that.xCorrection || 0);
  27385. that.openY = that.openValue !== null ? valTranslator.translate(that.openValue) : null;
  27386. that.highY = valTranslator.translate(that.highValue);
  27387. that.lowY = valTranslator.translate(that.lowValue);
  27388. that.closeY = that.closeValue !== null ? valTranslator.translate(that.closeValue) : null;
  27389. height = _abs(that.lowY - that.highY);
  27390. centerValue = _min(that.lowY, that.highY) + _abs(that.lowY - that.highY) / 2;
  27391. that._calculateVisibility(!rotated ? that.x : centerValue, !rotated ? centerValue : that.x)
  27392. },
  27393. getCrosshairCoords: function(x, y) {
  27394. var coords,
  27395. valueCoord = this._options.rotated ? x : y,
  27396. value = Math.abs(this.lowY - valueCoord) < Math.abs(this.closeY - valueCoord) ? this.lowY : this.closeY;
  27397. value = Math.abs(value - valueCoord) < Math.abs(this.openY - valueCoord) ? value : this.openY;
  27398. value = Math.abs(value - valueCoord) < Math.abs(this.highY - valueCoord) ? value : this.highY;
  27399. if (this._options.rotated)
  27400. coords = {
  27401. y: this.vy,
  27402. x: value
  27403. };
  27404. else
  27405. coords = {
  27406. x: this.vx,
  27407. y: value
  27408. };
  27409. return coords
  27410. },
  27411. _updateData: function(data) {
  27412. var that = this,
  27413. label = that._label,
  27414. reductionColor = this._options.reduction.color;
  27415. that.value = that.initialValue = data.reductionValue;
  27416. that.originalValue = data.value;
  27417. that.lowValue = that.originalLowValue = data.lowValue;
  27418. that.highValue = that.originalHighValue = data.highValue;
  27419. that.openValue = that.originalOpenValue = data.openValue;
  27420. that.closeValue = that.originalCloseValue = data.closeValue;
  27421. that._isPositive = data.openValue < data.closeValue;
  27422. that._isReduction = data.isReduction;
  27423. if (that._isReduction)
  27424. label.setColor(reductionColor)
  27425. },
  27426. _updateMarker: function(animationEnabled, style, group) {
  27427. var that = this,
  27428. graphic = that.graphic;
  27429. graphic.attr({points: that._getPoints()}).attr(style || that._getStyle()).sharp();
  27430. group && graphic.append(that._getMarkerGroup(group))
  27431. },
  27432. _getLabelFormatObject: function() {
  27433. var that = this;
  27434. return {
  27435. openValue: that.openValue,
  27436. highValue: that.highValue,
  27437. lowValue: that.lowValue,
  27438. closeValue: that.closeValue,
  27439. reductionValue: that.initialValue,
  27440. argument: that.initialArgument,
  27441. value: that.initialValue,
  27442. seriesName: that.series.name,
  27443. originalOpenValue: that.originalOpenValue,
  27444. originalCloseValue: that.originalCloseValue,
  27445. originalLowValue: that.originalLowValue,
  27446. originalHighValue: that.originalHighValue,
  27447. originalArgument: that.originalArgument,
  27448. point: that
  27449. }
  27450. },
  27451. _getFormatObject: function(tooltip) {
  27452. var that = this,
  27453. highValue = tooltip.formatValue(that.highValue),
  27454. openValue = tooltip.formatValue(that.openValue),
  27455. closeValue = tooltip.formatValue(that.closeValue),
  27456. lowValue = tooltip.formatValue(that.lowValue),
  27457. symbolMethods = points.symbolPoint,
  27458. formatObject = symbolMethods._getFormatObject.call(that, tooltip);
  27459. return _extend({}, formatObject, {
  27460. valueText: "h: " + highValue + (openValue !== "" ? " o: " + openValue : "") + (closeValue !== "" ? " c: " + closeValue : "") + " l: " + lowValue,
  27461. highValueText: highValue,
  27462. openValueText: openValue,
  27463. closeValueText: closeValue,
  27464. lowValueText: lowValue
  27465. })
  27466. }
  27467. })
  27468. })(jQuery, DevExpress);
  27469. /*! Module viz-core, file stockPoint.js */
  27470. (function($, DX) {
  27471. var points = DX.viz.core.series.points.mixins,
  27472. _extend = $.extend,
  27473. _isNumeric = $.isNumeric;
  27474. points.stockPoint = _extend({}, points.candlestickPoint, {
  27475. _getPoints: function() {
  27476. var that = this,
  27477. createPoint = that._options.rotated ? function(x, y) {
  27478. return [y, x]
  27479. } : function(x, y) {
  27480. return [x, y]
  27481. },
  27482. openYExist = _isNumeric(that.openY),
  27483. closeYExist = _isNumeric(that.closeY),
  27484. x = that.x,
  27485. width = that.width,
  27486. points;
  27487. points = [].concat(createPoint(x, that.highY));
  27488. openYExist && (points = points.concat(createPoint(x, that.openY)));
  27489. openYExist && (points = points.concat(createPoint(x - width / 2, that.openY)));
  27490. openYExist && (points = points.concat(createPoint(x, that.openY)));
  27491. closeYExist && (points = points.concat(createPoint(x, that.closeY)));
  27492. closeYExist && (points = points.concat(createPoint(x + width / 2, that.closeY)));
  27493. closeYExist && (points = points.concat(createPoint(x, that.closeY)));
  27494. points = points.concat(createPoint(x, that.lowY));
  27495. return points
  27496. },
  27497. _drawMarkerInGroup: function(group, attributes, renderer) {
  27498. this.graphic = renderer.path(this._getPoints(), "line").attr({"stroke-linecap": "square"}).attr(attributes).data({point: this}).sharp().append(group)
  27499. },
  27500. _getMinTrackerWidth: function() {
  27501. var width = 2 + this._styles.normal['stroke-width'];
  27502. return width + width % 2
  27503. }
  27504. })
  27505. })(jQuery, DevExpress);
  27506. /*! Module viz-core, file polarPoint.js */
  27507. (function($, DX, undefined) {
  27508. var _extend = $.extend,
  27509. viz = DX.viz,
  27510. points = viz.core.series.points.mixins,
  27511. utils = DX.utils,
  27512. isDefined = utils.isDefined,
  27513. normalizeAngle = utils.normalizeAngle,
  27514. _math = Math,
  27515. _max = _math.max,
  27516. ERROR_BARS_ANGLE_OFFSET = 90,
  27517. CANVAS_POSITION_START = "canvas_position_start",
  27518. CANVAS_POSITION_TOP = "canvas_position_top",
  27519. CANVAS_POSITION_END = "canvas_position_end",
  27520. CANVAS_POSITION_DEFAULT = "canvas_position_default";
  27521. points.polarSymbolPoint = _extend({}, points.symbolPoint, {
  27522. _getLabelCoords: points.piePoint._getLabelCoords,
  27523. _moveLabelOnCanvas: points.barPoint._moveLabelOnCanvas,
  27524. _getLabelPosition: function() {
  27525. return "outside"
  27526. },
  27527. _translate: function(translator) {
  27528. var that = this,
  27529. coord = translator.translate(that.argument, that.value),
  27530. center = translator.translate(CANVAS_POSITION_START, CANVAS_POSITION_TOP);
  27531. that.vx = normalizeAngle(coord.angle);
  27532. that.vy = that.radiusOuter = coord.radius;
  27533. that.radius = coord.radius;
  27534. that.middleAngle = -coord.angle;
  27535. that.angle = -coord.angle;
  27536. that.x = coord.x;
  27537. that.y = coord.y;
  27538. that.defaultX = that.centerX = center.x;
  27539. that.defaultY = that.centerY = center.y;
  27540. that._translateErrorBars(translator);
  27541. that.inVisibleArea = true
  27542. },
  27543. _translateErrorBars: function(translator) {
  27544. var that = this;
  27545. isDefined(that.lowError) && (that._lowErrorCoord = that.centerY - translator.translate(that.argument, that.lowError).radius);
  27546. isDefined(that.highError) && (that._highErrorCoord = that.centerY - translator.translate(that.argument, that.highError).radius);
  27547. that._errorBarPos = that.centerX;
  27548. that._baseErrorBarPos = (that._options.errorBars || {}).type === "stdDeviation" ? that._lowErrorCoord + (that._highErrorCoord - that._lowErrorCoord) / 2 : that.centerY - that.radius
  27549. },
  27550. _getTranslates: function(animationEnabled) {
  27551. return animationEnabled ? this.getDefaultCoords() : {
  27552. x: this.x,
  27553. y: this.y
  27554. }
  27555. },
  27556. getDefaultCoords: function() {
  27557. var cossin = utils.getCosAndSin(-this.angle),
  27558. radius = this.translators.translate(CANVAS_POSITION_START, CANVAS_POSITION_DEFAULT).radius,
  27559. x = this.defaultX + radius * cossin.cos,
  27560. y = this.defaultY + radius * cossin.sin;
  27561. return {
  27562. x: x,
  27563. y: y
  27564. }
  27565. },
  27566. _addLabelAlignmentAndOffset: function(label, coord) {
  27567. return coord
  27568. },
  27569. _getVisibleArea: function() {
  27570. var canvas = this.translators.canvas;
  27571. return {
  27572. minX: canvas.left,
  27573. maxX: canvas.width - canvas.right,
  27574. minY: canvas.top,
  27575. maxY: canvas.height - canvas.bottom
  27576. }
  27577. },
  27578. _checkLabelPosition: function(label, coord) {
  27579. var that = this,
  27580. visibleArea = that._getVisibleArea(),
  27581. graphicBbox = that._getGraphicBbox();
  27582. if (that._isPointInVisibleArea(visibleArea, graphicBbox))
  27583. coord = that._moveLabelOnCanvas(coord, visibleArea, label.getBoundingRect(), true, true);
  27584. return coord
  27585. },
  27586. _getErrorBarSettings: function(errorBarOptions, animationEnabled) {
  27587. var settings = points.symbolPoint._getErrorBarSettings.call(this, errorBarOptions, animationEnabled);
  27588. settings.rotate = ERROR_BARS_ANGLE_OFFSET - this.angle;
  27589. settings.rotateX = this.centerX;
  27590. settings.rotateY = this.centerY;
  27591. return settings
  27592. },
  27593. getCoords: function(min) {
  27594. return min ? this.getDefaultCoords() : {
  27595. x: this.x,
  27596. y: this.y
  27597. }
  27598. }
  27599. });
  27600. points.polarBarPoint = _extend({}, points.barPoint, {
  27601. _translateErrorBars: points.polarSymbolPoint._translateErrorBars,
  27602. _getErrorBarSettings: points.polarSymbolPoint._getErrorBarSettings,
  27603. _getVisibleArea: points.polarSymbolPoint._getVisibleArea,
  27604. _moveLabelOnCanvas: points.barPoint._moveLabelOnCanvas,
  27605. _getLabelCoords: points.piePoint._getLabelCoords,
  27606. _getLabelConnector: points.piePoint._getLabelConnector,
  27607. getBoundaryCoords: points.piePoint.getBoundaryCoords,
  27608. getTooltipParams: points.piePoint.getTooltipParams,
  27609. _getLabelPosition: points.piePoint._getLabelPosition,
  27610. _translate: function(translator) {
  27611. var that = this,
  27612. maxRadius = translator.translate(CANVAS_POSITION_TOP, CANVAS_POSITION_END).radius;
  27613. that.radiusInner = translator.translate(that.argument, that.minValue).radius;
  27614. points.polarSymbolPoint._translate.call(that, translator);
  27615. if (that.radiusInner === null)
  27616. that.radiusInner = that.radius = maxRadius;
  27617. else if (that.radius === null)
  27618. this.radius = this.value >= 0 ? maxRadius : 0;
  27619. that.radiusOuter = _max(that.radiusInner, that.radius);
  27620. that.radiusInner = that.defaultRadius = _math.min(that.radiusInner, that.radius);
  27621. that.middleAngle = that.angle = -utils.normalizeAngle(that.middleAngleCorrection - that.angle)
  27622. },
  27623. _checkVisibility: function(translator) {
  27624. return translator.checkVisibility(this.radius, this.radiusInner)
  27625. },
  27626. getMarkerCoords: function() {
  27627. return {
  27628. x: this.centerX,
  27629. y: this.centerY,
  27630. outerRadius: this.radiusOuter,
  27631. innerRadius: this.defaultRadius,
  27632. startAngle: this.middleAngle - this.interval / 2,
  27633. endAngle: this.middleAngle + this.interval / 2
  27634. }
  27635. },
  27636. _drawMarker: function(renderer, group, animationEnabled) {
  27637. var that = this,
  27638. styles = that._getStyle(),
  27639. coords = that.getMarkerCoords(),
  27640. innerRadius = coords.innerRadius,
  27641. outerRadius = coords.outerRadius,
  27642. start = that.translators.translate(that.argument, CANVAS_POSITION_DEFAULT),
  27643. x = coords.x,
  27644. y = coords.y;
  27645. if (animationEnabled) {
  27646. innerRadius = 0;
  27647. outerRadius = 0;
  27648. x = start.x;
  27649. y = start.y
  27650. }
  27651. that.graphic = renderer.arc(x, y, innerRadius, outerRadius, coords.startAngle, coords.endAngle).attr(styles).data({point: that}).append(group)
  27652. },
  27653. _checkLabelPosition: function(label, coord) {
  27654. var that = this,
  27655. visibleArea = that._getVisibleArea(),
  27656. angleFunctions = utils.getCosAndSin(that.middleAngle),
  27657. x = that.centerX + that.defaultRadius * angleFunctions.cos,
  27658. y = that.centerY - that.defaultRadius * angleFunctions.sin;
  27659. if (x > visibleArea.minX && x < visibleArea.maxX && y > visibleArea.minY && y < visibleArea.maxY)
  27660. coord = that._moveLabelOnCanvas(coord, visibleArea, label.getBoundingRect(), true, true);
  27661. return coord
  27662. },
  27663. _addLabelAlignmentAndOffset: function(label, coord) {
  27664. return coord
  27665. },
  27666. correctCoordinates: function(correctOptions) {
  27667. this.middleAngleCorrection = correctOptions.offset;
  27668. this.interval = correctOptions.width
  27669. },
  27670. coordsIn: function(x, y) {
  27671. var val = this.translators.untranslate(x, y),
  27672. coords = this.getMarkerCoords(),
  27673. isBetweenAngles = coords.startAngle < coords.endAngle ? -val.phi >= coords.startAngle && -val.phi <= coords.endAngle : -val.phi <= coords.startAngle && -val.phi >= coords.endAngle;
  27674. return val.r >= coords.innerRadius && val.r <= coords.outerRadius && isBetweenAngles
  27675. }
  27676. })
  27677. })(jQuery, DevExpress);
  27678. /*! Module viz-core, file dataValidator.js */
  27679. (function($, DX, undefined) {
  27680. var viz = DX.viz,
  27681. parseUtils = new viz.core.ParseUtils,
  27682. STRING = "string",
  27683. NUMERIC = "numeric",
  27684. DATETIME = "datetime",
  27685. DISCRETE = "discrete",
  27686. CONTINUOUS = "continuous",
  27687. LOGARITHMIC = "logarithmic",
  27688. VALUE_TYPE = "valueType",
  27689. ARGUMENT_TYPE = "argumentType",
  27690. axisTypeParser = viz.core.utils.enumParser([STRING, NUMERIC, DATETIME]),
  27691. utils = DX.utils,
  27692. _each = $.each,
  27693. _isDefined = utils.isDefined;
  27694. function groupingValues(data, others, valueField, index) {
  27695. if (!_isDefined(index) || index < 0)
  27696. return;
  27697. _each(data.slice(index), function(_, cell) {
  27698. if (!_isDefined(cell[valueField]))
  27699. return;
  27700. others[valueField] += cell[valueField];
  27701. cell[valueField] = undefined;
  27702. cell["original" + valueField] = undefined
  27703. })
  27704. }
  27705. function mergeSort(data, field) {
  27706. function merge_sort(array, low, high, field) {
  27707. if (low < high) {
  27708. var mid = Math.floor((low + high) / 2);
  27709. merge_sort(array, low, mid, field);
  27710. merge_sort(array, mid + 1, high, field);
  27711. merge(array, low, mid, high, field)
  27712. }
  27713. }
  27714. var n = data.length;
  27715. merge_sort(data, 0, n - 1, field);
  27716. return data
  27717. }
  27718. function merge(array, low, mid, high, field) {
  27719. var newArray = new Array(high - low + 1),
  27720. countL = low,
  27721. countR = mid + 1,
  27722. k,
  27723. i = 0;
  27724. while (countL <= mid && countR <= high) {
  27725. if (array[countL][field] <= array[countR][field] || !_isDefined(array[countR][field])) {
  27726. newArray[i] = array[countL];
  27727. countL++
  27728. }
  27729. else {
  27730. newArray[i] = array[countR];
  27731. countR++
  27732. }
  27733. i++
  27734. }
  27735. if (countL > mid)
  27736. for (k = countR; k <= high; k++, i++)
  27737. newArray[i] = array[k];
  27738. else
  27739. for (k = countL; k <= mid; k++, i++)
  27740. newArray[i] = array[k];
  27741. for (k = 0; k <= high - low; k++)
  27742. array[k + low] = newArray[k];
  27743. return array
  27744. }
  27745. function DataValidator(data, groups, incidentOccured, dataPrepareOptions) {
  27746. var that = this;
  27747. groups = groups || [[]];
  27748. that._nullData = !data;
  27749. that.groups = groups;
  27750. that.data = data || [];
  27751. that._parsers = {};
  27752. that._errorShowList = {};
  27753. that._skipFields = {};
  27754. that.options = dataPrepareOptions || {};
  27755. that.incidentOccured = incidentOccured;
  27756. that.userArgumentCategories = that.groups.argumentOptions && that.groups.argumentOptions.categories || [];
  27757. if (!incidentOccured)
  27758. that.incidentOccured = $.noop
  27759. }
  27760. viz.core.DataValidator = DataValidator;
  27761. DataValidator.prototype = {
  27762. ctor: DataValidator,
  27763. validate: function validate() {
  27764. var that = this,
  27765. dataLength;
  27766. that._data = that.data;
  27767. that.groups.argumentType = null;
  27768. that.groups.argumentAxisType = null;
  27769. _each(that.groups, function(_, group) {
  27770. group.valueType = null;
  27771. group.valueAxisType = null;
  27772. _each(group, function(_, series) {
  27773. series.updateDataType({})
  27774. });
  27775. group.valueAxis && group.valueAxis.resetTypes(VALUE_TYPE)
  27776. });
  27777. if (that.groups.argumentAxes)
  27778. _each(that.groups.argumentAxes, function(_, axis) {
  27779. axis.resetTypes(ARGUMENT_TYPE)
  27780. });
  27781. that._checkType();
  27782. that._checkAxisType();
  27783. if (!utils.isArray(that.data) || that._nullData)
  27784. that._incorrectDataMessage();
  27785. if (that.options.convertToAxisDataType) {
  27786. that._createParser();
  27787. that._parse()
  27788. }
  27789. that._groupData();
  27790. that._sort();
  27791. dataLength = that._data.length;
  27792. _each(that._skipFields, function(field, fieldValue) {
  27793. if (fieldValue === dataLength)
  27794. that.incidentOccured("W2002", [field])
  27795. });
  27796. return that._data
  27797. },
  27798. _checkValueTypeOfGroup: function(group, cell) {
  27799. var that = this;
  27800. _each(group, function(_, series) {
  27801. _each(series.getValueFields(), function(_, field) {
  27802. group.valueType = that._getType(cell[field], group.valueType)
  27803. })
  27804. });
  27805. return group.valueType
  27806. },
  27807. _checkArgumentTypeOfGroup: function(group, cell) {
  27808. var that = this;
  27809. _each(group, function(_, series) {
  27810. that.groups.argumentType = that._getType(cell[series.getArgumentField()], that.groups.argumentType)
  27811. });
  27812. return that.groups.argumentType
  27813. },
  27814. _checkType: function _checkType() {
  27815. var that = this,
  27816. groupsWithUndefinedValueType = [],
  27817. groupsWithUndefinedArgumentType = [],
  27818. groups = that.groups,
  27819. argumentTypeGroup = groups.argumentOptions && axisTypeParser(groups.argumentOptions.argumentType);
  27820. _each(groups, function(_, group) {
  27821. if (!group.length)
  27822. return null;
  27823. var valueTypeGroup = group.valueOptions && axisTypeParser(group.valueOptions.valueType);
  27824. group.valueType = valueTypeGroup;
  27825. groups.argumentType = argumentTypeGroup;
  27826. !valueTypeGroup && groupsWithUndefinedValueType.push(group);
  27827. !argumentTypeGroup && groupsWithUndefinedArgumentType.push(group)
  27828. });
  27829. if (groupsWithUndefinedValueType.length || groupsWithUndefinedArgumentType.length)
  27830. _each(that.data, function(_, cell) {
  27831. var defineVal,
  27832. defineArg;
  27833. if (!utils.isObject(cell))
  27834. return;
  27835. _each(groupsWithUndefinedValueType, function(_, group) {
  27836. defineVal = that._checkValueTypeOfGroup(group, cell)
  27837. });
  27838. _each(groupsWithUndefinedArgumentType, function(_, group) {
  27839. defineArg = that._checkArgumentTypeOfGroup(group, cell)
  27840. });
  27841. if (!that.options.checkTypeForAllData && defineVal && defineArg)
  27842. return false
  27843. })
  27844. },
  27845. _checkAxisType: function _checkAxisType() {
  27846. var that = this,
  27847. groups = that.groups,
  27848. argumentOptions = groups.argumentOptions || {};
  27849. _each(groups, function(_, group) {
  27850. _each(group, function(_, series) {
  27851. var optionsSeries = {},
  27852. valueOptions = group.valueOptions || {},
  27853. valueCategories = valueOptions.categories || [];
  27854. optionsSeries.argumentAxisType = that._correctAxisType(groups.argumentType, argumentOptions.type, !!that.userArgumentCategories.length);
  27855. optionsSeries.valueAxisType = that._correctAxisType(group.valueType, valueOptions.type, !!valueCategories.length);
  27856. groups.argumentAxisType = groups.argumentAxisType || optionsSeries.argumentAxisType;
  27857. group.valueAxisType = group.valueAxisType || optionsSeries.valueAxisType;
  27858. optionsSeries.argumentType = groups.argumentType;
  27859. optionsSeries.valueType = group.valueType;
  27860. optionsSeries.showZero = valueOptions.showZero;
  27861. series.updateDataType(optionsSeries)
  27862. });
  27863. if (group.valueAxis) {
  27864. group.valueAxis.setTypes(group.valueAxisType, group.valueType, VALUE_TYPE);
  27865. group.valueAxis.validate(false)
  27866. }
  27867. });
  27868. if (that.groups.argumentAxes)
  27869. _each(that.groups.argumentAxes, function(_, axis) {
  27870. axis.setTypes(that.groups.argumentAxisType, that.groups.argumentType, ARGUMENT_TYPE);
  27871. axis.validate(true)
  27872. })
  27873. },
  27874. _createParser: function _createParser() {
  27875. var that = this,
  27876. groups = that.groups;
  27877. _each(groups, function(_, group) {
  27878. _each(group, function(_, series) {
  27879. that._parsers[series.getArgumentField()] = that._createParserUnit(groups.argumentType, groups.argumentAxisType === LOGARITHMIC ? that._filterForLogAxis : null);
  27880. _each(series.getValueFields(), function(_, field) {
  27881. that._parsers[field] = that._createParserUnit(group.valueType, group.valueAxisType === LOGARITHMIC ? that._filterForLogAxis : null, series.getOptions().ignoreEmptyPoints)
  27882. });
  27883. if (series.getTagField())
  27884. that._parsers[series.getTagField()] = null
  27885. })
  27886. })
  27887. },
  27888. _parse: function _parse() {
  27889. var that = this,
  27890. parsedData = [];
  27891. _each(that.data, function(_, cell) {
  27892. var parserObject = {};
  27893. if (!utils.isObject(cell)) {
  27894. cell && that._incorrectDataMessage();
  27895. return
  27896. }
  27897. _each(that._parsers, function(field, parser) {
  27898. parserObject[field] = parser ? parser(cell[field], field) : cell[field];
  27899. parserObject["original" + field] = cell[field]
  27900. });
  27901. parsedData.push(parserObject)
  27902. });
  27903. this._data = parsedData
  27904. },
  27905. _groupMinSlices: function(argumentField, valueField, smallValuesGrouping) {
  27906. smallValuesGrouping = smallValuesGrouping || {};
  27907. var that = this,
  27908. mode = smallValuesGrouping.mode,
  27909. count = smallValuesGrouping.topCount,
  27910. threshold = smallValuesGrouping.threshold,
  27911. name = smallValuesGrouping.groupName || "others",
  27912. others = {},
  27913. data = that._data.slice(),
  27914. index;
  27915. if (!mode || mode === "none")
  27916. return;
  27917. others[argumentField] = name + "";
  27918. others[valueField] = 0;
  27919. data.sort(function(a, b) {
  27920. if (_isDefined(b[valueField]) && _isDefined(a[valueField]))
  27921. return b[valueField] - a[valueField];
  27922. else if (!_isDefined(b[valueField]) && a[valueField])
  27923. return -1;
  27924. else if (!_isDefined(a[valueField]) && b[valueField])
  27925. return 1
  27926. });
  27927. if (mode === "smallValueThreshold") {
  27928. _each(data, function(i, cell) {
  27929. if (_isDefined(index) || !_isDefined(cell[valueField]))
  27930. return;
  27931. if (threshold > cell[valueField])
  27932. index = i
  27933. });
  27934. groupingValues(data, others, valueField, index)
  27935. }
  27936. else if (mode === "topN")
  27937. groupingValues(data, others, valueField, count);
  27938. others[valueField] && that._data.push(others)
  27939. },
  27940. _groupData: function() {
  27941. var that = this,
  27942. groups = that.groups,
  27943. isPie = groups.length && groups[0].length && (groups[0][0].type === "pie" || groups[0][0].type === "doughnut" || groups[0][0].type === "donut"),
  27944. argumentField,
  27945. valueFields;
  27946. if (!isPie)
  27947. return;
  27948. _each(groups, function(_, group) {
  27949. _each(group, function(_, series) {
  27950. argumentField = series.getArgumentField();
  27951. valueFields = series.getValueFields();
  27952. if (groups.argumentAxisType === DISCRETE)
  27953. that._groupSameArguments(argumentField, valueFields);
  27954. that._groupMinSlices(argumentField, valueFields[0], series.getOptions().smallValuesGrouping)
  27955. })
  27956. })
  27957. },
  27958. _groupSameArguments: function(argumentField, valueFields) {
  27959. var that = this,
  27960. argument,
  27961. dataOfArguments = {},
  27962. parsedData = that._data;
  27963. _each(parsedData, function(i, cell) {
  27964. if (!_isDefined(cell[argumentField]) || !_isDefined(cell[valueFields[0]]))
  27965. return;
  27966. argument = cell[argumentField];
  27967. if (_isDefined(dataOfArguments[argument])) {
  27968. var data = parsedData[dataOfArguments[argument]];
  27969. _each(valueFields, function(_, field) {
  27970. data[field] += cell[field];
  27971. cell[field] = undefined;
  27972. cell["original" + field] = undefined
  27973. })
  27974. }
  27975. else
  27976. dataOfArguments[argument] = i
  27977. })
  27978. },
  27979. _getType: function _getType(unit, type) {
  27980. if (type === STRING || utils.isString(unit))
  27981. return STRING;
  27982. if (type === DATETIME || utils.isDate(unit))
  27983. return DATETIME;
  27984. if (utils.isNumber(unit))
  27985. return NUMERIC;
  27986. return type
  27987. },
  27988. _correctAxisType: function _correctAxisType(type, axisType, hasCategories) {
  27989. if (type === STRING && (axisType === CONTINUOUS || axisType === LOGARITHMIC))
  27990. this.incidentOccured("E2002");
  27991. if (axisType === LOGARITHMIC)
  27992. return LOGARITHMIC;
  27993. axisType = (hasCategories || axisType === DISCRETE || type === STRING) && DISCRETE;
  27994. return axisType || CONTINUOUS
  27995. },
  27996. _filterForLogAxis: function(val, field) {
  27997. if (val <= 0) {
  27998. this.incidentOccured("E2004", [field]);
  27999. return null
  28000. }
  28001. return val
  28002. },
  28003. _createParserUnit: function _createParserUnit(type, filter, ignoreEmptyPoints) {
  28004. var that = this,
  28005. parser = type ? parseUtils.getParser(type, undefined, true) : function(unit) {
  28006. return unit
  28007. };
  28008. return function(unit, field) {
  28009. var parseUnit = parser(unit);
  28010. if (filter)
  28011. parseUnit = filter.call(that, parseUnit, field);
  28012. parseUnit === null && ignoreEmptyPoints && (parseUnit = undefined);
  28013. if (parseUnit === undefined) {
  28014. that._addSkipFields(field);
  28015. that._validUnit(unit, field, type)
  28016. }
  28017. return parseUnit
  28018. }
  28019. },
  28020. _validUnit: function _validUnit(unit, field) {
  28021. if (!unit)
  28022. return;
  28023. if (!utils.isNumber(unit) && !utils.isDate(unit) && !utils.isString(unit)) {
  28024. this.incidentOccured("E2003", [field]);
  28025. return
  28026. }
  28027. this.incidentOccured("E2004", [field])
  28028. },
  28029. _sort: function _sort() {
  28030. var that = this,
  28031. sortingMethod = that.options.sortingMethod,
  28032. data = that._data,
  28033. groups = that.groups,
  28034. hash = {},
  28035. argumentField = groups.length && groups[0].length && groups[0][0].getArgumentField();
  28036. if (utils.isFunction(sortingMethod))
  28037. data.sort(sortingMethod);
  28038. else if (that.userArgumentCategories.length) {
  28039. _each(that.userArgumentCategories, function(index, value) {
  28040. hash[value] = index
  28041. });
  28042. data.sort(function sortCat(a, b) {
  28043. a = a[argumentField];
  28044. b = b[argumentField];
  28045. return hash[a] - hash[b]
  28046. })
  28047. }
  28048. else if (sortingMethod === true && groups.argumentType !== STRING)
  28049. mergeSort(data, argumentField)
  28050. },
  28051. _addSkipFields: function _addSkipFields(field) {
  28052. this._skipFields[field] = (this._skipFields[field] || 0) + 1
  28053. },
  28054. _incorrectDataMessage: function() {
  28055. if (this._erorrDataSource !== true) {
  28056. this._erorrDataSource = true;
  28057. this.incidentOccured("E2001")
  28058. }
  28059. }
  28060. }
  28061. })(jQuery, DevExpress);
  28062. /*! Module viz-core, file default.js */
  28063. (function(DX, undefined) {
  28064. var WHITE = "#ffffff",
  28065. BLACK = "#000000",
  28066. LIGHT_GREY = "#d3d3d3",
  28067. GREY_GREEN = "#303030",
  28068. RED = "#ff0000";
  28069. DX.viz.core.registerTheme({
  28070. name: "generic.light",
  28071. font: {
  28072. color: '#767676',
  28073. family: "'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
  28074. weight: 400,
  28075. size: 12,
  28076. cursor: 'default'
  28077. },
  28078. redrawOnResize: true,
  28079. backgroundColor: WHITE,
  28080. primaryTitleColor: "#232323",
  28081. secondaryTitleColor: "#767676",
  28082. axisColor: LIGHT_GREY,
  28083. axisLabelColor: "#a8a8a8",
  28084. title: {font: {
  28085. family: "'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
  28086. weight: 200
  28087. }},
  28088. loadingIndicator: {text: "Loading..."},
  28089. tooltip: {
  28090. enabled: false,
  28091. border: {
  28092. width: 1,
  28093. color: LIGHT_GREY,
  28094. dashStyle: 'solid',
  28095. visible: true
  28096. },
  28097. font: {color: '#232323'},
  28098. color: WHITE,
  28099. arrowLength: 10,
  28100. paddingLeftRight: 18,
  28101. paddingTopBottom: 15,
  28102. shared: false,
  28103. location: 'center',
  28104. format: '',
  28105. argumentFormat: '',
  28106. precision: 0,
  28107. argumentPrecision: 0,
  28108. percentPrecision: 0,
  28109. shadow: {
  28110. opacity: 0.4,
  28111. offsetX: 0,
  28112. offsetY: 4,
  28113. blur: 2,
  28114. color: BLACK
  28115. }
  28116. },
  28117. legend: {
  28118. hoverMode: 'includePoints',
  28119. verticalAlignment: 'top',
  28120. horizontalAlignment: 'right',
  28121. position: 'outside',
  28122. visible: true,
  28123. margin: 10,
  28124. markerSize: 12,
  28125. border: {
  28126. visible: false,
  28127. width: 1,
  28128. cornerRadius: 0,
  28129. dashStyle: 'solid'
  28130. },
  28131. paddingLeftRight: 20,
  28132. paddingTopBottom: 15,
  28133. columnCount: 0,
  28134. rowCount: 0,
  28135. columnItemSpacing: 20,
  28136. rowItemSpacing: 8
  28137. },
  28138. "chart:common": {
  28139. animation: {
  28140. enabled: true,
  28141. duration: 1000,
  28142. easing: 'easeOutCubic',
  28143. maxPointCountSupported: 300
  28144. },
  28145. commonSeriesSettings: {
  28146. border: {
  28147. visible: false,
  28148. width: 2
  28149. },
  28150. showInLegend: true,
  28151. visible: true,
  28152. hoverMode: 'nearestPoint',
  28153. selectionMode: 'includePoints',
  28154. hoverStyle: {
  28155. hatching: {
  28156. direction: 'right',
  28157. width: 2,
  28158. step: 6,
  28159. opacity: 0.75
  28160. },
  28161. border: {
  28162. visible: false,
  28163. width: 3
  28164. }
  28165. },
  28166. selectionStyle: {
  28167. hatching: {
  28168. direction: 'right',
  28169. width: 2,
  28170. step: 6,
  28171. opacity: 0.5
  28172. },
  28173. border: {
  28174. visible: false,
  28175. width: 3
  28176. }
  28177. },
  28178. valueErrorBar: {
  28179. displayMode: "auto",
  28180. value: 1,
  28181. color: BLACK,
  28182. lineWidth: 2,
  28183. edgeLength: 8
  28184. },
  28185. label: {
  28186. visible: false,
  28187. alignment: 'center',
  28188. rotationAngle: 0,
  28189. horizontalOffset: 0,
  28190. verticalOffset: 0,
  28191. radialOffset: 0,
  28192. format: '',
  28193. argumentFormat: '',
  28194. precision: 0,
  28195. argumentPrecision: 0,
  28196. percentPrecision: 0,
  28197. showForZeroValues: true,
  28198. customizeText: undefined,
  28199. maxLabelCount: undefined,
  28200. position: 'outside',
  28201. font: {color: WHITE},
  28202. border: {
  28203. visible: false,
  28204. width: 1,
  28205. color: LIGHT_GREY,
  28206. dashStyle: 'solid'
  28207. },
  28208. connector: {
  28209. visible: false,
  28210. width: 1
  28211. }
  28212. }
  28213. },
  28214. seriesSelectionMode: 'single',
  28215. pointSelectionMode: 'single',
  28216. equalRowHeight: true,
  28217. dataPrepareSettings: {
  28218. checkTypeForAllData: false,
  28219. convertToAxisDataType: true,
  28220. sortingMethod: true
  28221. },
  28222. title: {
  28223. font: {size: 28},
  28224. margin: 10
  28225. },
  28226. adaptiveLayout: {
  28227. width: 80,
  28228. height: 80,
  28229. keepLabels: true
  28230. },
  28231. _rtl: {legend: {itemTextPosition: 'left'}},
  28232. resolveLabelOverlapping: "none"
  28233. },
  28234. "chart:common:axis": {
  28235. visible: false,
  28236. setTicksAtUnitBeginning: true,
  28237. valueMarginsEnabled: true,
  28238. placeholderSize: null,
  28239. logarithmBase: 10,
  28240. discreteAxisDivisionMode: 'betweenLabels',
  28241. width: 1,
  28242. label: {
  28243. visible: true,
  28244. precision: 0,
  28245. format: ""
  28246. },
  28247. grid: {
  28248. visible: false,
  28249. width: 1
  28250. },
  28251. minorGrid: {
  28252. visible: false,
  28253. width: 1,
  28254. opacity: 0.3
  28255. },
  28256. tick: {visible: false},
  28257. minorTick: {
  28258. visible: false,
  28259. opacity: 0.3
  28260. },
  28261. stripStyle: {
  28262. paddingLeftRight: 10,
  28263. paddingTopBottom: 5
  28264. },
  28265. constantLineStyle: {
  28266. width: 1,
  28267. color: BLACK,
  28268. dashStyle: "solid",
  28269. label: {
  28270. visible: true,
  28271. position: "inside"
  28272. }
  28273. }
  28274. },
  28275. chart: {
  28276. commonSeriesSettings: {
  28277. type: 'line',
  28278. stack: 'default',
  28279. point: {
  28280. visible: true,
  28281. symbol: 'circle',
  28282. size: 12,
  28283. border: {
  28284. visible: false,
  28285. width: 1
  28286. },
  28287. hoverMode: 'onlyPoint',
  28288. selectionMode: 'onlyPoint',
  28289. hoverStyle: {
  28290. border: {
  28291. visible: true,
  28292. width: 4
  28293. },
  28294. size: 12
  28295. },
  28296. selectionStyle: {
  28297. border: {
  28298. visible: true,
  28299. width: 4
  28300. },
  28301. size: 12
  28302. }
  28303. },
  28304. scatter: {},
  28305. line: {
  28306. width: 2,
  28307. dashStyle: 'solid',
  28308. hoverStyle: {
  28309. width: 3,
  28310. hatching: {direction: 'none'}
  28311. },
  28312. selectionStyle: {width: 3}
  28313. },
  28314. stackedline: {
  28315. width: 2,
  28316. dashStyle: 'solid',
  28317. hoverStyle: {
  28318. width: 3,
  28319. hatching: {direction: 'none'}
  28320. },
  28321. selectionStyle: {width: 3}
  28322. },
  28323. stackedspline: {
  28324. width: 2,
  28325. dashStyle: 'solid',
  28326. hoverStyle: {
  28327. width: 3,
  28328. hatching: {direction: 'none'}
  28329. },
  28330. selectionStyle: {width: 3}
  28331. },
  28332. fullstackedline: {
  28333. width: 2,
  28334. dashStyle: 'solid',
  28335. hoverStyle: {
  28336. width: 3,
  28337. hatching: {direction: 'none'}
  28338. },
  28339. selectionStyle: {width: 3}
  28340. },
  28341. fullstackedspline: {
  28342. width: 2,
  28343. dashStyle: 'solid',
  28344. hoverStyle: {
  28345. width: 3,
  28346. hatching: {direction: 'none'}
  28347. },
  28348. selectionStyle: {width: 3}
  28349. },
  28350. stepline: {
  28351. width: 2,
  28352. dashStyle: 'solid',
  28353. hoverStyle: {
  28354. width: 3,
  28355. hatching: {direction: 'none'}
  28356. },
  28357. selectionStyle: {width: 3}
  28358. },
  28359. area: {
  28360. point: {visible: false},
  28361. opacity: 0.5
  28362. },
  28363. stackedarea: {
  28364. point: {visible: false},
  28365. opacity: 0.5
  28366. },
  28367. fullstackedarea: {
  28368. point: {visible: false},
  28369. opacity: 0.5
  28370. },
  28371. fullstackedsplinearea: {
  28372. point: {visible: false},
  28373. opacity: 0.5
  28374. },
  28375. steparea: {
  28376. border: {
  28377. visible: true,
  28378. width: 2
  28379. },
  28380. point: {visible: false},
  28381. hoverStyle: {border: {
  28382. visible: true,
  28383. width: 3
  28384. }},
  28385. selectionStyle: {border: {
  28386. visible: true,
  28387. width: 3
  28388. }},
  28389. opacity: 0.5
  28390. },
  28391. spline: {
  28392. width: 2,
  28393. hoverStyle: {
  28394. width: 3,
  28395. hatching: {direction: 'none'}
  28396. },
  28397. selectionStyle: {width: 3}
  28398. },
  28399. splinearea: {
  28400. point: {visible: false},
  28401. opacity: 0.5
  28402. },
  28403. stackedsplinearea: {
  28404. point: {visible: false},
  28405. opacity: 0.5
  28406. },
  28407. bar: {
  28408. cornerRadius: 0,
  28409. point: {
  28410. hoverStyle: {border: {visible: false}},
  28411. selectionStyle: {border: {visible: false}}
  28412. }
  28413. },
  28414. stackedbar: {
  28415. cornerRadius: 0,
  28416. point: {
  28417. hoverStyle: {border: {visible: false}},
  28418. selectionStyle: {border: {visible: false}}
  28419. },
  28420. label: {position: "inside"}
  28421. },
  28422. fullstackedbar: {
  28423. cornerRadius: 0,
  28424. point: {
  28425. hoverStyle: {border: {visible: false}},
  28426. selectionStyle: {border: {visible: false}}
  28427. },
  28428. label: {position: "inside"}
  28429. },
  28430. rangebar: {
  28431. cornerRadius: 0,
  28432. point: {
  28433. hoverStyle: {border: {visible: false}},
  28434. selectionStyle: {border: {visible: false}}
  28435. }
  28436. },
  28437. rangearea: {
  28438. point: {visible: false},
  28439. opacity: 0.5
  28440. },
  28441. rangesplinearea: {
  28442. point: {visible: false},
  28443. opacity: 0.5
  28444. },
  28445. bubble: {
  28446. opacity: 0.5,
  28447. point: {
  28448. hoverStyle: {border: {visible: false}},
  28449. selectionStyle: {border: {visible: false}}
  28450. }
  28451. },
  28452. candlestick: {
  28453. width: 1,
  28454. reduction: {color: RED},
  28455. hoverStyle: {
  28456. width: 3,
  28457. hatching: {direction: 'none'}
  28458. },
  28459. selectionStyle: {width: 3},
  28460. point: {border: {visible: true}}
  28461. },
  28462. stock: {
  28463. width: 1,
  28464. reduction: {color: RED},
  28465. hoverStyle: {
  28466. width: 3,
  28467. hatching: {direction: 'none'}
  28468. },
  28469. selectionStyle: {width: 3},
  28470. point: {border: {visible: true}}
  28471. }
  28472. },
  28473. crosshair: {
  28474. enabled: false,
  28475. color: '#f78119',
  28476. width: 1,
  28477. dashStyle: 'solid',
  28478. label: {
  28479. visible: false,
  28480. font: {
  28481. color: WHITE,
  28482. size: 12
  28483. }
  28484. },
  28485. verticalLine: {visible: true},
  28486. horizontalLine: {visible: true}
  28487. },
  28488. commonAxisSettings: {
  28489. multipleAxesSpacing: 5,
  28490. label: {
  28491. overlappingBehavior: {
  28492. mode: 'auto',
  28493. rotationAngle: 90,
  28494. staggeringSpacing: 5
  28495. },
  28496. indentFromAxis: 10
  28497. },
  28498. title: {
  28499. font: {size: 16},
  28500. margin: 6
  28501. },
  28502. constantLineStyle: {
  28503. paddingLeftRight: 10,
  28504. paddingTopBottom: 10
  28505. }
  28506. },
  28507. horizontalAxis: {
  28508. position: 'bottom',
  28509. axisDivisionFactor: 50,
  28510. label: {alignment: "center"},
  28511. stripStyle: {label: {
  28512. horizontalAlignment: 'center',
  28513. verticalAlignment: 'top'
  28514. }},
  28515. constantLineStyle: {label: {
  28516. horizontalAlignment: 'right',
  28517. verticalAlignment: 'top'
  28518. }},
  28519. constantLines: {}
  28520. },
  28521. verticalAxis: {
  28522. position: 'left',
  28523. axisDivisionFactor: 30,
  28524. label: {
  28525. alignment: 'right',
  28526. overlappingBehavior: {mode: 'enlargeTickInterval'}
  28527. },
  28528. stripStyle: {label: {
  28529. horizontalAlignment: 'left',
  28530. verticalAlignment: 'center'
  28531. }},
  28532. constantLineStyle: {label: {
  28533. horizontalAlignment: 'left',
  28534. verticalAlignment: 'top'
  28535. }},
  28536. constantLines: {}
  28537. },
  28538. argumentAxis: {},
  28539. valueAxis: {grid: {visible: true}},
  28540. commonPaneSettings: {
  28541. backgroundColor: 'none',
  28542. border: {
  28543. color: LIGHT_GREY,
  28544. width: 1,
  28545. visible: false,
  28546. top: true,
  28547. bottom: true,
  28548. left: true,
  28549. right: true,
  28550. dashStyle: 'solid'
  28551. }
  28552. },
  28553. scrollBar: {
  28554. visible: false,
  28555. offset: 5,
  28556. color: "gray",
  28557. width: 10
  28558. },
  28559. useAggregation: false,
  28560. adjustOnZoom: true,
  28561. rotated: false,
  28562. zoomingMode: 'none',
  28563. scrollingMode: 'none',
  28564. synchronizeMultiAxes: true,
  28565. equalBarWidth: true,
  28566. minBubbleSize: 12,
  28567. maxBubbleSize: 0.2
  28568. },
  28569. pie: {
  28570. commonSeriesSettings: {
  28571. type: 'pie',
  28572. pie: {
  28573. border: {
  28574. visible: false,
  28575. width: 2,
  28576. color: WHITE
  28577. },
  28578. hoverStyle: {
  28579. hatching: {
  28580. direction: 'right',
  28581. width: 4,
  28582. step: 10,
  28583. opacity: 0.75
  28584. },
  28585. border: {
  28586. visible: false,
  28587. width: 2
  28588. }
  28589. },
  28590. selectionStyle: {
  28591. hatching: {
  28592. direction: 'right',
  28593. width: 4,
  28594. step: 10,
  28595. opacity: 0.5
  28596. },
  28597. border: {
  28598. visible: false,
  28599. width: 2
  28600. }
  28601. }
  28602. },
  28603. doughnut: {
  28604. innerRadius: 0.5,
  28605. border: {
  28606. visible: false,
  28607. width: 2,
  28608. color: WHITE
  28609. },
  28610. hoverStyle: {
  28611. hatching: {
  28612. direction: 'right',
  28613. width: 4,
  28614. step: 10,
  28615. opacity: 0.75
  28616. },
  28617. border: {
  28618. visible: false,
  28619. width: 2
  28620. }
  28621. },
  28622. selectionStyle: {
  28623. hatching: {
  28624. direction: 'right',
  28625. width: 4,
  28626. step: 10,
  28627. opacity: 0.5
  28628. },
  28629. border: {
  28630. visible: false,
  28631. width: 2
  28632. }
  28633. }
  28634. },
  28635. donut: {
  28636. innerRadius: 0.5,
  28637. border: {
  28638. visible: false,
  28639. width: 2,
  28640. color: WHITE
  28641. },
  28642. hoverStyle: {
  28643. hatching: {
  28644. direction: 'right',
  28645. width: 4,
  28646. step: 10,
  28647. opacity: 0.75
  28648. },
  28649. border: {
  28650. visible: false,
  28651. width: 2
  28652. }
  28653. },
  28654. selectionStyle: {
  28655. hatching: {
  28656. direction: 'right',
  28657. width: 4,
  28658. step: 10,
  28659. opacity: 0.5
  28660. },
  28661. border: {
  28662. visible: false,
  28663. width: 2
  28664. }
  28665. }
  28666. }
  28667. },
  28668. legend: {
  28669. hoverMode: 'markPoint',
  28670. backgroundColor: "none"
  28671. },
  28672. adaptiveLayout: {keepLabels: false}
  28673. },
  28674. pieIE8: {commonSeriesSettings: {
  28675. pie: {
  28676. hoverStyle: {border: {
  28677. visible: true,
  28678. color: WHITE
  28679. }},
  28680. selectionStyle: {border: {
  28681. visible: true,
  28682. color: WHITE
  28683. }}
  28684. },
  28685. donut: {
  28686. hoverStyle: {border: {
  28687. visible: true,
  28688. color: WHITE
  28689. }},
  28690. selectionStyle: {border: {
  28691. visible: true,
  28692. color: WHITE
  28693. }}
  28694. },
  28695. doughnut: {
  28696. hoverStyle: {border: {
  28697. visible: true,
  28698. color: WHITE
  28699. }},
  28700. selectionStyle: {border: {
  28701. visible: true,
  28702. color: WHITE
  28703. }}
  28704. }
  28705. }},
  28706. gauge: {
  28707. scale: {
  28708. majorTick: {
  28709. visible: true,
  28710. length: 5,
  28711. width: 2,
  28712. showCalculatedTicks: true,
  28713. useTicksAutoArrangement: true
  28714. },
  28715. minorTick: {
  28716. visible: false,
  28717. length: 3,
  28718. width: 1,
  28719. showCalculatedTicks: true
  28720. },
  28721. label: {visible: true}
  28722. },
  28723. rangeContainer: {
  28724. offset: 0,
  28725. width: 5,
  28726. backgroundColor: '#808080'
  28727. },
  28728. valueIndicators: {
  28729. _default: {color: '#c2c2c2'},
  28730. rangebar: {
  28731. space: 2,
  28732. size: 10,
  28733. color: '#cbc5cf',
  28734. backgroundColor: 'none',
  28735. text: {
  28736. indent: 0,
  28737. font: {
  28738. size: 14,
  28739. color: null
  28740. }
  28741. }
  28742. },
  28743. twocolorneedle: {secondColor: '#e18e92'},
  28744. trianglemarker: {
  28745. space: 2,
  28746. length: 14,
  28747. width: 13,
  28748. color: '#8798a5'
  28749. },
  28750. textcloud: {
  28751. arrowLength: 5,
  28752. horizontalOffset: 6,
  28753. verticalOffset: 3,
  28754. color: '#679ec5',
  28755. text: {font: {
  28756. color: WHITE,
  28757. size: 18
  28758. }}
  28759. }
  28760. },
  28761. title: {
  28762. layout: {
  28763. horizontalAlignment: 'center',
  28764. verticalAlignment: 'top',
  28765. overlay: 0
  28766. },
  28767. font: {size: 16}
  28768. },
  28769. subtitle: {font: {size: 14}},
  28770. indicator: {
  28771. hasPositiveMeaning: true,
  28772. layout: {
  28773. horizontalAlignment: 'center',
  28774. verticalAlignment: 'bottom',
  28775. overlay: 0
  28776. },
  28777. text: {font: {size: 18}}
  28778. },
  28779. _circular: {
  28780. scale: {
  28781. orientation: 'outside',
  28782. label: {indentFromTick: 10}
  28783. },
  28784. rangeContainer: {orientation: 'outside'},
  28785. valueIndicatorType: 'rectangleneedle',
  28786. subvalueIndicatorType: 'trianglemarker',
  28787. valueIndicators: {
  28788. _type: 'rectangleneedle',
  28789. _default: {
  28790. offset: 20,
  28791. indentFromCenter: 0,
  28792. width: 2,
  28793. spindleSize: 14,
  28794. spindleGapSize: 10
  28795. },
  28796. triangleneedle: {width: 4},
  28797. twocolorneedle: {
  28798. space: 2,
  28799. secondFraction: 0.4
  28800. },
  28801. rangebar: {offset: 30},
  28802. trianglemarker: {offset: 6},
  28803. textcloud: {offset: -6}
  28804. }
  28805. },
  28806. _linear: {
  28807. scale: {
  28808. horizontalOrientation: 'right',
  28809. verticalOrientation: 'bottom',
  28810. label: {indentFromTick: -10}
  28811. },
  28812. rangeContainer: {
  28813. horizontalOrientation: 'right',
  28814. verticalOrientation: 'bottom'
  28815. },
  28816. valueIndicatorType: 'rangebar',
  28817. subvalueIndicatorType: 'trianglemarker',
  28818. valueIndicators: {
  28819. _type: 'rectangle',
  28820. _default: {
  28821. offset: 2.5,
  28822. length: 15,
  28823. width: 15
  28824. },
  28825. rectangle: {width: 10},
  28826. rangebar: {
  28827. offset: 10,
  28828. horizontalOrientation: 'right',
  28829. verticalOrientation: 'bottom'
  28830. },
  28831. trianglemarker: {
  28832. offset: -1,
  28833. horizontalOrientation: 'left',
  28834. verticalOrientation: 'top'
  28835. },
  28836. textcloud: {
  28837. offset: -1,
  28838. horizontalOrientation: 'left',
  28839. verticalOrientation: 'top'
  28840. }
  28841. }
  28842. }
  28843. },
  28844. barGauge: {
  28845. backgroundColor: '#e0e0e0',
  28846. relativeInnerRadius: 0.3,
  28847. barSpacing: 4,
  28848. label: {
  28849. indent: 20,
  28850. connectorWidth: 2,
  28851. font: {size: 16}
  28852. },
  28853. title: {
  28854. layout: {
  28855. horizontalAlignment: 'center',
  28856. verticalAlignment: 'top',
  28857. overlay: 0
  28858. },
  28859. font: {size: 16}
  28860. },
  28861. subtitle: {font: {size: 14}},
  28862. indicator: {
  28863. hasPositiveMeaning: true,
  28864. layout: {
  28865. horizontalAlignment: 'center',
  28866. verticalAlignment: 'bottom',
  28867. overlay: 0
  28868. },
  28869. text: {font: {size: 18}}
  28870. }
  28871. },
  28872. rangeSelector: {
  28873. scale: {
  28874. showCustomBoundaryTicks: true,
  28875. showMinorTicks: true,
  28876. useTicksAutoArrangement: true,
  28877. setTicksAtUnitBeginning: true,
  28878. label: {
  28879. visible: true,
  28880. topIndent: 7,
  28881. font: {size: 11}
  28882. },
  28883. tick: {
  28884. width: 1,
  28885. color: BLACK,
  28886. opacity: 0.1
  28887. },
  28888. marker: {
  28889. visible: true,
  28890. separatorHeight: 33,
  28891. topIndent: 10,
  28892. textLeftIndent: 7,
  28893. textTopIndent: 11,
  28894. label: {}
  28895. },
  28896. logarithmBase: 10
  28897. },
  28898. selectedRangeColor: "#606060",
  28899. sliderMarker: {
  28900. visible: true,
  28901. paddingTopBottom: 2,
  28902. paddingLeftRight: 4,
  28903. color: '#606060',
  28904. invalidRangeColor: RED,
  28905. font: {
  28906. color: WHITE,
  28907. size: 11
  28908. }
  28909. },
  28910. sliderHandle: {
  28911. width: 1,
  28912. color: BLACK,
  28913. opacity: 0.2
  28914. },
  28915. shutter: {opacity: 0.75},
  28916. background: {
  28917. color: "#c0bae1",
  28918. visible: true,
  28919. image: {location: 'full'}
  28920. },
  28921. behavior: {
  28922. snapToTicks: true,
  28923. animationEnabled: true,
  28924. moveSelectedRangeByClick: true,
  28925. manualRangeSelectionEnabled: true,
  28926. allowSlidersSwap: true,
  28927. callSelectedRangeChanged: "onMovingComplete"
  28928. },
  28929. redrawOnResize: true,
  28930. chart: {
  28931. useAggregation: false,
  28932. equalBarWidth: true,
  28933. minBubbleSize: 12,
  28934. maxBubbleSize: 0.2,
  28935. topIndent: 0.1,
  28936. bottomIndent: 0,
  28937. valueAxis: {
  28938. inverted: false,
  28939. logarithmBase: 10
  28940. },
  28941. commonSeriesSettings: {
  28942. type: "area",
  28943. point: {visible: false}
  28944. }
  28945. }
  28946. },
  28947. map: {
  28948. background: {
  28949. borderWidth: 1,
  28950. borderColor: '#cacaca'
  28951. },
  28952. areaSettings: {
  28953. borderWidth: 1,
  28954. borderColor: WHITE,
  28955. color: '#d2d2d2',
  28956. hoveredBorderColor: GREY_GREEN,
  28957. selectedBorderWidth: 2,
  28958. selectedBorderColor: GREY_GREEN,
  28959. label: {
  28960. enabled: false,
  28961. stroke: WHITE,
  28962. 'stroke-width': 2,
  28963. 'stroke-opacity': 0.5,
  28964. font: {
  28965. color: '#2b2b2b',
  28966. size: 16,
  28967. opacity: 0.5
  28968. }
  28969. }
  28970. },
  28971. markerSettings: {
  28972. label: {
  28973. enabled: true,
  28974. stroke: WHITE,
  28975. 'stroke-width': 1,
  28976. 'stroke-opacity': 0.5,
  28977. font: {
  28978. color: '#2b2b2b',
  28979. size: 12
  28980. }
  28981. },
  28982. _dot: {
  28983. borderWidth: 2,
  28984. borderColor: WHITE,
  28985. color: '#ba4d51',
  28986. size: 8,
  28987. selectedStep: 2,
  28988. backStep: 18,
  28989. backColor: WHITE,
  28990. backOpacity: 0.32,
  28991. shadow: true
  28992. },
  28993. _bubble: {
  28994. minSize: 20,
  28995. maxSize: 50,
  28996. color: '#ba4d51',
  28997. hoveredBorderWidth: 1,
  28998. hoveredBorderColor: GREY_GREEN,
  28999. selectedBorderWidth: 2,
  29000. selectedBorderColor: GREY_GREEN
  29001. },
  29002. _pie: {
  29003. size: 50,
  29004. hoveredBorderWidth: 1,
  29005. hoveredBorderColor: GREY_GREEN,
  29006. selectedBorderWidth: 2,
  29007. selectedBorderColor: GREY_GREEN
  29008. },
  29009. _image: {size: 20}
  29010. },
  29011. legend: {
  29012. verticalAlignment: 'bottom',
  29013. horizontalAlignment: 'right',
  29014. position: 'inside',
  29015. backgroundOpacity: 0.65,
  29016. border: {
  29017. visible: true,
  29018. color: '#cacaca'
  29019. },
  29020. paddingLeftRight: 16,
  29021. paddingTopBottom: 12,
  29022. markerColor: '#ba4d51'
  29023. },
  29024. controlBar: {
  29025. borderColor: '#5d5d5d',
  29026. borderWidth: 3,
  29027. color: WHITE,
  29028. margin: 20,
  29029. opacity: 0.3
  29030. },
  29031. _rtl: {legend: {itemTextPosition: 'left'}}
  29032. },
  29033. sparkline: {
  29034. lineColor: '#666666',
  29035. lineWidth: 2,
  29036. areaOpacity: 0.2,
  29037. minColor: '#e8c267',
  29038. maxColor: '#e55253',
  29039. barPositiveColor: '#a9a9a9',
  29040. barNegativeColor: '#d7d7d7',
  29041. winColor: '#a9a9a9',
  29042. lossColor: '#d7d7d7',
  29043. firstLastColor: '#666666',
  29044. pointSymbol: 'circle',
  29045. pointColor: WHITE,
  29046. pointSize: 4,
  29047. type: "line",
  29048. argumentField: "arg",
  29049. valueField: "val",
  29050. winlossThreshold: 0,
  29051. showFirstLast: true,
  29052. showMinMax: false,
  29053. tooltip: {enabled: true}
  29054. },
  29055. bullet: {
  29056. color: '#e8c267',
  29057. targetColor: '#666666',
  29058. targetWidth: 4,
  29059. showTarget: true,
  29060. showZeroLevel: true,
  29061. tooltip: {enabled: true}
  29062. },
  29063. polar: {
  29064. commonSeriesSettings: {
  29065. type: 'scatter',
  29066. closed: true,
  29067. point: {
  29068. visible: true,
  29069. symbol: 'circle',
  29070. size: 12,
  29071. border: {
  29072. visible: false,
  29073. width: 1
  29074. },
  29075. hoverMode: 'onlyPoint',
  29076. selectionMode: 'onlyPoint',
  29077. hoverStyle: {
  29078. border: {
  29079. visible: true,
  29080. width: 4
  29081. },
  29082. size: 12
  29083. },
  29084. selectionStyle: {
  29085. border: {
  29086. visible: true,
  29087. width: 4
  29088. },
  29089. size: 12
  29090. }
  29091. },
  29092. scatter: {},
  29093. line: {
  29094. width: 2,
  29095. dashStyle: 'solid',
  29096. hoverStyle: {
  29097. width: 3,
  29098. hatching: {direction: 'none'}
  29099. },
  29100. selectionStyle: {width: 3}
  29101. },
  29102. area: {
  29103. point: {visible: false},
  29104. opacity: 0.5
  29105. },
  29106. stackedline: {width: 2},
  29107. bar: {opacity: 0.8},
  29108. stackedbar: {opacity: 0.8}
  29109. },
  29110. adaptiveLayout: {
  29111. width: 170,
  29112. height: 170,
  29113. keepLabels: true
  29114. },
  29115. equalBarWidth: true,
  29116. commonAxisSettings: {
  29117. visible: true,
  29118. label: {
  29119. overlappingBehavior: {mode: 'enlargeTickInterval'},
  29120. indentFromAxis: 5
  29121. },
  29122. grid: {visible: true},
  29123. minorGrid: {visible: true},
  29124. tick: {visible: true},
  29125. title: {
  29126. font: {size: 16},
  29127. margin: 10
  29128. }
  29129. },
  29130. argumentAxis: {
  29131. startAngle: 0,
  29132. firstPointOnStartAngle: false,
  29133. period: undefined
  29134. },
  29135. valueAxis: {tick: {visible: false}},
  29136. horizontalAxis: {
  29137. position: 'top',
  29138. axisDivisionFactor: 50,
  29139. label: {alignment: "center"}
  29140. },
  29141. verticalAxis: {
  29142. position: 'top',
  29143. axisDivisionFactor: 30,
  29144. label: {alignment: "right"}
  29145. }
  29146. }
  29147. });
  29148. DX.viz.core.registerTheme({
  29149. name: "generic.dark",
  29150. font: {color: '#808080'},
  29151. backgroundColor: GREY_GREEN,
  29152. primaryTitleColor: "#dbdbdb",
  29153. secondaryTitleColor: "#a3a3a3",
  29154. axisColor: "#555555",
  29155. axisLabelColor: "#707070",
  29156. tooltip: {
  29157. color: '#2b2b2b',
  29158. border: {color: '#494949'},
  29159. font: {color: '#929292'}
  29160. },
  29161. "chart:common": {commonSeriesSettings: {
  29162. label: {border: {color: '#494949'}},
  29163. valueErrorBar: {color: WHITE}
  29164. }},
  29165. "chart:common:axis": {constantLineStyle: {color: WHITE}},
  29166. chart: {
  29167. crosshair: {color: '#515151'},
  29168. commonPaneSettings: {border: {color: '#494949'}}
  29169. },
  29170. pieIE8: {commonSeriesSettings: {
  29171. pie: {
  29172. hoverStyle: {border: {color: '#2b2b2b'}},
  29173. selectionStyle: {border: {color: '#2b2b2b'}}
  29174. },
  29175. donut: {
  29176. hoverStyle: {border: {color: '#2b2b2b'}},
  29177. selectionStyle: {border: {color: '#2b2b2b'}}
  29178. },
  29179. doughnut: {
  29180. hoverStyle: {border: {color: '#2b2b2b'}},
  29181. selectionStyle: {border: {color: '#2b2b2b'}}
  29182. }
  29183. }},
  29184. gauge: {
  29185. rangeContainer: {backgroundColor: '#b5b5b5'},
  29186. valueIndicators: {
  29187. _default: {color: '#b5b5b5'},
  29188. rangebar: {color: '#84788b'},
  29189. twocolorneedle: {secondColor: '#ba544d'},
  29190. trianglemarker: {color: '#b7918f'},
  29191. textcloud: {color: '#ba544d'}
  29192. }
  29193. },
  29194. barGauge: {backgroundColor: "#3c3c3c"},
  29195. rangeSelector: {
  29196. selectedRangeColor: '#b5b5b5',
  29197. scale: {tick: {
  29198. color: WHITE,
  29199. opacity: 0.05
  29200. }},
  29201. sliderMarker: {
  29202. color: '#b5b5b5',
  29203. font: {color: GREY_GREEN}
  29204. },
  29205. sliderHandle: {
  29206. color: WHITE,
  29207. opacity: 0.2
  29208. },
  29209. shutter: {
  29210. color: '#2b2b2b',
  29211. opacity: 0.9
  29212. }
  29213. },
  29214. map: {
  29215. background: {borderColor: '#3f3f3f'},
  29216. areaSettings: {
  29217. borderColor: GREY_GREEN,
  29218. color: '#686868',
  29219. hoveredBorderColor: WHITE,
  29220. selectedBorderColor: WHITE,
  29221. label: {
  29222. stroke: BLACK,
  29223. font: {color: WHITE}
  29224. }
  29225. },
  29226. markerSettings: {
  29227. label: {
  29228. stroke: BLACK,
  29229. font: {color: WHITE}
  29230. },
  29231. _bubble: {
  29232. hoveredBorderColor: WHITE,
  29233. selectedBorderColor: WHITE
  29234. },
  29235. _pie: {
  29236. hoveredBorderColor: WHITE,
  29237. selectedBorderColor: WHITE
  29238. }
  29239. },
  29240. legend: {
  29241. border: {color: '#3f3f3f'},
  29242. font: {color: WHITE}
  29243. },
  29244. controlBar: {
  29245. borderColor: '#c7c7c7',
  29246. color: GREY_GREEN
  29247. }
  29248. },
  29249. sparkline: {
  29250. lineColor: '#c7c7c7',
  29251. firstLastColor: '#c7c7c7',
  29252. barPositiveColor: '#b8b8b8',
  29253. barNegativeColor: '#8e8e8e',
  29254. winColor: '#b8b8b8',
  29255. lossColor: '#8e8e8e',
  29256. pointColor: GREY_GREEN
  29257. },
  29258. bullet: {targetColor: '#8e8e8e'}
  29259. }, "generic.light");
  29260. DX.viz.core.currentTheme("generic.light");
  29261. DX.viz.core.registerThemeAlias("desktop.light", "generic.light");
  29262. DX.viz.core.registerThemeAlias("desktop.dark", "generic.dark")
  29263. })(DevExpress);
  29264. /*! Module viz-core, file android.js */
  29265. (function(DX) {
  29266. var ANDROID5_LIGHT = "android5.light",
  29267. registerThemeAlias = DX.viz.core.registerThemeAlias;
  29268. DX.viz.core.registerTheme({
  29269. name: ANDROID5_LIGHT,
  29270. backgroundColor: "#ffffff",
  29271. primaryTitleColor: "#232323",
  29272. secondaryTitleColor: "#767676",
  29273. axisColor: "#d3d3d3",
  29274. axisLabelColor: "#a8a8a8",
  29275. tooltip: {
  29276. color: "#e8e8e8",
  29277. font: {color: "#808080"}
  29278. },
  29279. legend: {font: {color: "#000000"}},
  29280. pieIE8: {commonSeriesSettings: {
  29281. pie: {
  29282. hoverStyle: {border: {color: '#e8e8e8'}},
  29283. selectionStyle: {border: {color: '#e8e8e8'}}
  29284. },
  29285. donut: {
  29286. hoverStyle: {border: {color: '#e8e8e8'}},
  29287. selectionStyle: {border: {color: '#e8e8e8'}}
  29288. },
  29289. doughnut: {
  29290. hoverStyle: {border: {color: '#e8e8e8'}},
  29291. selectionStyle: {border: {color: '#e8e8e8'}}
  29292. }
  29293. }}
  29294. }, "generic.light");
  29295. registerThemeAlias("android", ANDROID5_LIGHT);
  29296. registerThemeAlias("android.holo-dark", ANDROID5_LIGHT);
  29297. registerThemeAlias("android.holo-light", ANDROID5_LIGHT);
  29298. registerThemeAlias("android.dark", ANDROID5_LIGHT);
  29299. registerThemeAlias("android.light", ANDROID5_LIGHT)
  29300. })(DevExpress);
  29301. /*! Module viz-core, file ios.js */
  29302. (function(DX) {
  29303. var IOS7_DEFAULT = "ios7.default",
  29304. core = DX.viz.core;
  29305. core.registerTheme({
  29306. name: IOS7_DEFAULT,
  29307. backgroundColor: "#ffffff",
  29308. primaryTitleColor: "#000000",
  29309. secondaryTitleColor: "#767676",
  29310. axisColor: "#ececec",
  29311. axisLabelColor: "#b8b8b8",
  29312. legend: {font: {color: '#000000'}},
  29313. tooltip: {font: {color: '#808080'}},
  29314. "chart:common": {commonSeriesSettings: {label: {border: {color: '#d3d3d3'}}}},
  29315. chart: {commonPaneSettings: {border: {color: '#d3d3d3'}}}
  29316. }, "generic.light");
  29317. core.registerThemeAlias("ios", IOS7_DEFAULT)
  29318. })(DevExpress);
  29319. /*! Module viz-core, file win8.js */
  29320. (function(DX) {
  29321. var core = DX.viz.core,
  29322. registerTheme = core.registerTheme,
  29323. registerThemeSchemeAlias = core.registerThemeSchemeAlias,
  29324. BLACK = "#000000",
  29325. WHITE = "#ffffff";
  29326. registerTheme({
  29327. name: "win8.black",
  29328. backgroundColor: BLACK,
  29329. primaryTitleColor: WHITE,
  29330. secondaryTitleColor: "#d8d8d8",
  29331. axisColor: "#4c4c4c",
  29332. axisLabelColor: "#a0a0a0",
  29333. title: {font: {color: WHITE}},
  29334. legend: {font: {color: WHITE}},
  29335. tooltip: {
  29336. color: BLACK,
  29337. font: {color: WHITE}
  29338. },
  29339. "chart:common": {commonSeriesSettings: {label: {border: {color: '#454545'}}}},
  29340. chart: {commonPaneSettings: {border: {color: '#454545'}}},
  29341. pieIE8: {commonSeriesSettings: {
  29342. pie: {
  29343. hoverStyle: {border: {color: BLACK}},
  29344. selectionStyle: {border: {color: BLACK}}
  29345. },
  29346. donut: {
  29347. hoverStyle: {border: {color: BLACK}},
  29348. selectionStyle: {border: {color: BLACK}}
  29349. },
  29350. doughnut: {
  29351. hoverStyle: {border: {color: BLACK}},
  29352. selectionStyle: {border: {color: BLACK}}
  29353. }
  29354. }},
  29355. barGauge: {backgroundColor: "#2b3036"},
  29356. rangeSelector: {scale: {tick: {opacity: 0.15}}}
  29357. }, "generic.dark");
  29358. registerTheme({
  29359. name: "win8.white",
  29360. backgroundColor: WHITE,
  29361. primaryTitleColor: BLACK,
  29362. secondaryTitleColor: "#767676",
  29363. axisColor: "#ececec",
  29364. axisLabelColor: "#b8b8b8",
  29365. title: {font: {color: '#808080'}},
  29366. legend: {font: {color: BLACK}},
  29367. tooltip: {font: {color: '#808080'}}
  29368. }, "generic.light");
  29369. registerThemeSchemeAlias("win8.dark", "win8.black");
  29370. registerThemeSchemeAlias("win8.light", "win8.white")
  29371. })(DevExpress);
  29372. /*! Module viz-core, file themeManager.js */
  29373. (function($, DX, undefined) {
  29374. var viz = DX.viz,
  29375. Palette = viz.core.Palette,
  29376. utils = DX.utils,
  29377. _findTheme = DX.viz.core.findTheme,
  29378. _isString = utils.isString,
  29379. _isDefined = utils.isDefined,
  29380. HOVER_COLOR_HIGHLIGHTING = 20,
  29381. HIGHLIGHTING_STEP = 50,
  29382. FONT = "font",
  29383. COMMON_AXIS_SETTINGS = "commonAxisSettings",
  29384. PIE_FONT_FIELDS = ["legend." + FONT, "title." + FONT, "tooltip." + FONT, "loadingIndicator." + FONT, "commonSeriesSettings.label." + FONT],
  29385. POLAR_FONT_FIELDS = PIE_FONT_FIELDS.concat([COMMON_AXIS_SETTINGS + ".label." + FONT, COMMON_AXIS_SETTINGS + ".title." + FONT]),
  29386. CHART_FONT_FIELDS = POLAR_FONT_FIELDS.concat(["crosshair.label." + FONT]),
  29387. chartToFontFieldsMap = {
  29388. pie: PIE_FONT_FIELDS,
  29389. chart: CHART_FONT_FIELDS,
  29390. polar: POLAR_FONT_FIELDS
  29391. };
  29392. viz.charts = viz.charts || {};
  29393. viz.charts.ThemeManager = viz.core.BaseThemeManager.inherit(function() {
  29394. var ctor = function(options, themeGroupName) {
  29395. var that = this,
  29396. themeObj;
  29397. that.callBase.apply(that, arguments);
  29398. options = options || {};
  29399. that._userOptions = options;
  29400. that._mergeAxisTitleOptions = [];
  29401. that._themeSection = themeGroupName;
  29402. that._fontFields = chartToFontFieldsMap[themeGroupName];
  29403. that._IE8 = DX.browser.msie && DX.browser.version < 9;
  29404. themeObj = options.theme && _findTheme(_isString(options.theme) ? options.theme : options.theme.name) || {};
  29405. that.palette = new Palette(options.palette, {
  29406. stepHighlight: HIGHLIGHTING_STEP,
  29407. theme: themeObj.name
  29408. });
  29409. that._callback = $.noop
  29410. };
  29411. var dispose = function() {
  29412. var that = this;
  29413. that.palette.dispose();
  29414. that.palette = that._userOptions = that._mergedSettings = null;
  29415. return that.callBase.apply(that, arguments)
  29416. };
  29417. var resetPalette = function() {
  29418. this.palette.reset()
  29419. };
  29420. var updatePalette = function(palette) {
  29421. this.palette = new Palette(palette || this._theme.defaultPalette, {
  29422. stepHighlight: HIGHLIGHTING_STEP,
  29423. theme: this.themeName
  29424. })
  29425. };
  29426. var processTitleOptions = function(options) {
  29427. return _isString(options) ? {text: options} : options
  29428. };
  29429. var processAxisOptions = function(axisOptions) {
  29430. if (!axisOptions)
  29431. return;
  29432. axisOptions = $.extend(true, {}, axisOptions);
  29433. axisOptions.title = processTitleOptions(axisOptions.title);
  29434. if (axisOptions.type === "logarithmic" && axisOptions.logarithmBase <= 0 || axisOptions.logarithmBase && !$.isNumeric(axisOptions.logarithmBase)) {
  29435. axisOptions.logarithmBase = undefined;
  29436. axisOptions.logarithmBaseError = true
  29437. }
  29438. if (axisOptions.label) {
  29439. if (axisOptions.label.alignment)
  29440. axisOptions.label["userAlignment"] = true;
  29441. if (_isString(axisOptions.label.overlappingBehavior))
  29442. axisOptions.label.overlappingBehavior = {mode: axisOptions.label.overlappingBehavior};
  29443. if (!axisOptions.label.overlappingBehavior || !axisOptions.label.overlappingBehavior.mode)
  29444. axisOptions.label.overlappingBehavior = axisOptions.label.overlappingBehavior || {}
  29445. }
  29446. return axisOptions
  29447. };
  29448. var applyParticularAxisOptions = function(name, userOptions, rotated) {
  29449. var theme = this._theme,
  29450. position = !(rotated ^ name === "valueAxis") ? "horizontalAxis" : "verticalAxis",
  29451. commonAxisSettings = processAxisOptions(this._userOptions["commonAxisSettings"], name);
  29452. return $.extend(true, {}, theme.commonAxisSettings, theme[position], theme[name], commonAxisSettings, processAxisOptions(userOptions, name))
  29453. };
  29454. var mergeOptions = function(name, userOptions) {
  29455. userOptions = userOptions || this._userOptions[name];
  29456. var theme = this._theme[name],
  29457. result = this._mergedSettings[name];
  29458. if (result)
  29459. return result;
  29460. if ($.isPlainObject(theme) && $.isPlainObject(userOptions))
  29461. result = $.extend(true, {}, theme, userOptions);
  29462. else
  29463. result = _isDefined(userOptions) ? userOptions : theme;
  29464. this._mergedSettings[name] = result;
  29465. return result
  29466. };
  29467. var applyParticularTheme = {
  29468. base: mergeOptions,
  29469. argumentAxis: applyParticularAxisOptions,
  29470. valueAxisRangeSelector: function() {
  29471. return mergeOptions.call(this, "valueAxis")
  29472. },
  29473. valueAxis: applyParticularAxisOptions,
  29474. title: function(name) {
  29475. var userOptions = processTitleOptions(this._userOptions[name]);
  29476. return mergeOptions.call(this, name, userOptions)
  29477. },
  29478. series: function(name, userOptions) {
  29479. var theme = this._theme,
  29480. userCommonSettings = this._userOptions.commonSeriesSettings || {},
  29481. themeCommonSettings = theme.commonSeriesSettings,
  29482. type = ((userOptions.type || userCommonSettings.type || themeCommonSettings.type) + "").toLowerCase(),
  29483. settings,
  29484. palette = this.palette,
  29485. isBar = ~type.indexOf("bar"),
  29486. isLine = ~type.indexOf("line"),
  29487. isArea = ~type.indexOf("area"),
  29488. isBubble = type === "bubble",
  29489. mainSeriesColor,
  29490. resolveLabelsOverlapping = this.getOptions("resolveLabelsOverlapping"),
  29491. resolveLabelOverlapping = this.getOptions("resolveLabelOverlapping"),
  29492. containerBackgroundColor = this.getOptions("containerBackgroundColor"),
  29493. seriesVisibility;
  29494. if (isBar || isBubble) {
  29495. userOptions = $.extend(true, {}, userCommonSettings, userCommonSettings[type], userOptions);
  29496. seriesVisibility = userOptions.visible;
  29497. userCommonSettings = {type: {}};
  29498. $.extend(true, userOptions, userOptions.point);
  29499. userOptions.visible = seriesVisibility
  29500. }
  29501. settings = $.extend(true, {}, themeCommonSettings, themeCommonSettings[type], userCommonSettings, userCommonSettings[type], userOptions);
  29502. settings.type = type;
  29503. settings.widgetType = this._themeSection.split(".").slice(-1)[0];
  29504. settings.containerBackgroundColor = containerBackgroundColor;
  29505. if (settings.widgetType !== "pie")
  29506. mainSeriesColor = settings.color || palette.getNextColor();
  29507. else
  29508. mainSeriesColor = function() {
  29509. return palette.getNextColor()
  29510. };
  29511. settings.mainSeriesColor = mainSeriesColor;
  29512. settings._IE8 = this._IE8;
  29513. settings.resolveLabelOverlapping = resolveLabelOverlapping;
  29514. settings.resolveLabelsOverlapping = resolveLabelsOverlapping;
  29515. if (settings.label && (isLine || isArea && type !== "rangearea" || type === "scatter"))
  29516. settings.label.position = "outside";
  29517. return settings
  29518. },
  29519. pieSegment: function(name, seriesSettings, segmentSettings) {
  29520. var settings = $.extend(true, {}, seriesSettings, segmentSettings),
  29521. mainColor = new DX.Color(settings.color || this.palette.getNextColor());
  29522. settings.color = mainColor.toHex();
  29523. settings.border.color = settings.border.color || mainColor.toHex();
  29524. settings.hoverStyle.color = settings.hoverStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
  29525. settings.hoverStyle.border.color = settings.hoverStyle.border.color || mainColor.toHex();
  29526. settings.selectionStyle.color = settings.selectionStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
  29527. settings.selectionStyle.border.color = settings.selectionStyle.border.color || mainColor.toHex();
  29528. return settings
  29529. },
  29530. animation: function(name) {
  29531. var userOptions = this._userOptions[name];
  29532. userOptions = $.isPlainObject(userOptions) ? userOptions : _isDefined(userOptions) ? {enabled: !!userOptions} : {};
  29533. return mergeOptions.call(this, name, userOptions)
  29534. }
  29535. };
  29536. return {
  29537. _themeSection: "chart",
  29538. ctor: ctor,
  29539. dispose: dispose,
  29540. resetPalette: resetPalette,
  29541. getOptions: function(name) {
  29542. return (applyParticularTheme[name] || applyParticularTheme.base).apply(this, arguments)
  29543. },
  29544. refresh: function() {
  29545. this._mergedSettings = {};
  29546. return this.callBase.apply(this, arguments)
  29547. },
  29548. resetOptions: function(name) {
  29549. this._mergedSettings[name] = null
  29550. },
  29551. update: function(options) {
  29552. this._userOptions = options
  29553. },
  29554. updatePalette: updatePalette
  29555. }
  29556. }())
  29557. })(jQuery, DevExpress);
  29558. /*! Module viz-core, file factory.js */
  29559. (function($, DX) {
  29560. var viz = DX.viz,
  29561. charts = viz.charts,
  29562. series = charts.series;
  29563. charts.factory = function() {
  29564. var createSeriesFamily = function(options) {
  29565. return new series.SeriesFamily(options)
  29566. };
  29567. var createThemeManager = function(options, groupName) {
  29568. return new charts.ThemeManager(options, groupName)
  29569. };
  29570. var createTracker = function(options, name) {
  29571. return name === "dxPieChart" ? new charts.PieTracker(options) : new charts.ChartTracker(options)
  29572. };
  29573. var createTitle = function(renderer, options, group) {
  29574. return new charts.ChartTitle(renderer, options, group)
  29575. };
  29576. var createChartLayoutManager = function(options) {
  29577. return new charts.LayoutManager(options)
  29578. };
  29579. var createCrosshair = function(renderer, options, params, group) {
  29580. return new charts.Crosshair(renderer, options, params, group)
  29581. };
  29582. return {
  29583. createSeriesFamily: createSeriesFamily,
  29584. createThemeManager: createThemeManager,
  29585. createTracker: createTracker,
  29586. createChartLayoutManager: createChartLayoutManager,
  29587. createTitle: createTitle,
  29588. createCrosshair: createCrosshair,
  29589. createScrollBar: function(renderer, group) {
  29590. return new DevExpress.viz.charts.ScrollBar(renderer, group)
  29591. }
  29592. }
  29593. }()
  29594. })(jQuery, DevExpress);
  29595. /*! Module viz-core, file baseWidget.js */
  29596. (function(DX, $, undefined) {
  29597. var core = DX.viz.core,
  29598. _windowResizeCallbacks = DX.utils.windowResizeCallbacks,
  29599. _Number = Number,
  29600. _stringFormat = DX.utils.stringFormat,
  29601. _isFunction = DX.utils.isFunction,
  29602. _parseScalar = core.utils.parseScalar,
  29603. OPTION_RTL_ENABLED = "rtlEnabled",
  29604. OPTION_LOADING_INDICATOR = "loadingIndicator";
  29605. function defaultIncidentOccured(options) {
  29606. var args = [options.id];
  29607. args.push.apply(args, options.args || []);
  29608. DX.log.apply(null, args)
  29609. }
  29610. function getTrue() {
  29611. return true
  29612. }
  29613. function getFalse() {
  29614. return false
  29615. }
  29616. function areCanvasesDifferent(canvas1, canvas2) {
  29617. return !(canvas1.width === canvas2.width && canvas1.height === canvas2.height && canvas1.left === canvas2.left && canvas1.top === canvas2.top && canvas1.right === canvas2.right && canvas1.bottom === canvas2.bottom)
  29618. }
  29619. function createResizeHandler(callback) {
  29620. var $window = $(window),
  29621. width,
  29622. height,
  29623. timeout;
  29624. handler.dispose = function() {
  29625. clearTimeout(timeout);
  29626. return this
  29627. };
  29628. return handler;
  29629. function handler() {
  29630. width = $window.width();
  29631. height = $window.height();
  29632. clearTimeout(timeout);
  29633. timeout = setTimeout(trigger, 100)
  29634. }
  29635. function trigger() {
  29636. $window.width() === width && $window.height() === height && callback()
  29637. }
  29638. }
  29639. core.DEBUG_createResizeHandler = createResizeHandler;
  29640. core.BaseWidget = DX.DOMComponent.inherit({
  29641. _eventsMap: {
  29642. onIncidentOccurred: {
  29643. name: 'incidentOccured',
  29644. deprecated: 'incidentOccured',
  29645. deprecatedContext: $.noop,
  29646. deprecatedArgs: function(arg) {
  29647. return [arg.target]
  29648. }
  29649. },
  29650. onDrawn: {
  29651. name: 'drawn',
  29652. deprecated: 'drawn',
  29653. deprecatedContext: $.noop,
  29654. deprecatedArgs: function(arg) {
  29655. return [arg.component]
  29656. }
  29657. },
  29658. incidentOccured: {newName: 'onIncidentOccurred'},
  29659. drawn: {newName: 'onDrawn'},
  29660. onTooltipShown: {name: 'tooltipShown'},
  29661. onTooltipHidden: {name: 'tooltipHidden'},
  29662. onLoadingIndicatorReady: {name: "loadingIndicatorReady"}
  29663. },
  29664. _setDeprecatedOptions: function() {
  29665. this.callBase.apply(this, arguments);
  29666. $.extend(this._deprecatedOptions, {
  29667. incidentOccured: {
  29668. since: '14.2',
  29669. message: "Use the 'onIncidentOccurred' option instead"
  29670. },
  29671. drawn: {
  29672. since: '14.2',
  29673. message: "Use the 'onDrawn' option instead"
  29674. }
  29675. })
  29676. },
  29677. _setDefaultOptions: function() {
  29678. this.callBase.apply(this, arguments);
  29679. this.option({incidentOccured: defaultIncidentOccured})
  29680. },
  29681. _init: function() {
  29682. var that = this;
  29683. that.callBase.apply(that, arguments);
  29684. that._themeManager = that._createThemeManager();
  29685. that._themeManager.setCallback(function() {
  29686. that._handleThemeOptions()
  29687. });
  29688. that._renderer = new DX.viz.renderers.Renderer({cssClass: that._rootClassPrefix + " " + that._rootClass});
  29689. that._initIncidentOccured();
  29690. that._renderVisibilityChange();
  29691. that._initEventTrigger();
  29692. that._initTooltip();
  29693. that._initCore();
  29694. that._setThemeAndRtl();
  29695. that._initSize();
  29696. that._setupResizeHandler();
  29697. that._initLoadingIndicator()
  29698. },
  29699. _initTooltip: function() {
  29700. this._tooltip = new core.Tooltip({
  29701. cssClass: this._rootClassPrefix + "-tooltip",
  29702. eventTrigger: this._eventTrigger
  29703. })
  29704. },
  29705. _getAnimationOptions: $.noop,
  29706. _initSize: function() {
  29707. var canvas = null;
  29708. if (this._isContainerVisible()) {
  29709. canvas = this._calculateCanvas();
  29710. if (canvas)
  29711. this._updateSize(canvas, true)
  29712. }
  29713. if (!canvas)
  29714. this._setHiddenState()
  29715. },
  29716. _setHiddenState: function() {
  29717. var that = this;
  29718. that._clean = that._render = $.noop;
  29719. that._canvas = null;
  29720. that._incidentOccured('W2001', [that.NAME])
  29721. },
  29722. _setVisibleState: function() {
  29723. delete this._clean;
  29724. delete this._render
  29725. },
  29726. _updateSize: function(canvas, isDrawRequired) {
  29727. var that = this;
  29728. that._renderer.resize(canvas.width, canvas.height);
  29729. isDrawRequired && that._renderer.draw(that._$element[0]);
  29730. that._canvas = canvas;
  29731. that._applySize();
  29732. that._updateLoadingIndicatorCanvas()
  29733. },
  29734. _updateCanvasAndResize: function() {
  29735. var that = this,
  29736. canvas = that._calculateCanvas();
  29737. if (canvas)
  29738. if (areCanvasesDifferent(canvas, that._canvas) || that.__forceRender) {
  29739. that._updateSize(canvas);
  29740. that._resize()
  29741. }
  29742. return canvas
  29743. },
  29744. render: function() {
  29745. var that = this,
  29746. canvas,
  29747. visible = that._isContainerVisible();
  29748. if (that._canvas) {
  29749. if (visible)
  29750. canvas = that._updateCanvasAndResize();
  29751. if (!canvas) {
  29752. that._clean();
  29753. that._renderer.clear();
  29754. that._setHiddenState()
  29755. }
  29756. }
  29757. else {
  29758. if (visible) {
  29759. canvas = that._calculateCanvas();
  29760. if (canvas) {
  29761. that._setVisibleState();
  29762. that._updateSize(canvas, true);
  29763. that._render()
  29764. }
  29765. }
  29766. if (!canvas)
  29767. that._setHiddenState()
  29768. }
  29769. },
  29770. _handleResize: function() {
  29771. if (this._canvas)
  29772. this._updateCanvasAndResize()
  29773. },
  29774. _dispose: function() {
  29775. var that = this;
  29776. that.callBase.apply(that, arguments);
  29777. that._removeResizeHandler();
  29778. that._eventTrigger.dispose();
  29779. that._disposeCore();
  29780. that._disposeLoadingIndicator();
  29781. that._renderer.dispose();
  29782. that._tooltip && that._tooltip.dispose();
  29783. that._themeManager.dispose();
  29784. that._themeManager = that._renderer = that._eventTrigger = that._tooltip = null
  29785. },
  29786. _initEventTrigger: function() {
  29787. var that = this;
  29788. that._eventTrigger = createEventTrigger(that._eventsMap, function(name, deprecatedName) {
  29789. var data = {callback: that._createActionByOption(name)};
  29790. that._suppressDeprecatedWarnings();
  29791. if (that.option(name) === undefined)
  29792. data.deprecatedCallback = that.option(deprecatedName);
  29793. that._resumeDeprecatedWarnings();
  29794. return data
  29795. })
  29796. },
  29797. _isContainerVisible: function() {
  29798. return this._$element.is(':visible')
  29799. },
  29800. _calculateCanvas: function() {
  29801. var that = this,
  29802. size = that.option('size') || {},
  29803. margin = that.option('margin') || {},
  29804. defaultCanvas = that._getDefaultSize() || {},
  29805. canvas = {};
  29806. if (size.width <= 0 || size.height <= 0)
  29807. canvas = null;
  29808. else {
  29809. canvas.width = size.width > 0 ? _Number(size.width) : that._$element.width() || defaultCanvas.width;
  29810. canvas.height = size.height > 0 ? _Number(size.height) : that._$element.height() || defaultCanvas.height;
  29811. canvas.left = margin.left > 0 ? _Number(margin.left) : defaultCanvas.left || 0;
  29812. canvas.top = margin.top > 0 ? _Number(margin.top) : defaultCanvas.top || 0;
  29813. canvas.right = margin.right > 0 ? _Number(margin.right) : defaultCanvas.right || 0;
  29814. canvas.bottom = margin.bottom > 0 ? _Number(margin.bottom) : defaultCanvas.bottom || 0;
  29815. canvas = canvas.width - canvas.left - canvas.right > 0 && canvas.height - canvas.top - canvas.bottom > 0 ? canvas : null
  29816. }
  29817. return canvas
  29818. },
  29819. DEBUG_getCanvas: function() {
  29820. return this._canvas
  29821. },
  29822. DEBUG_getEventTrigger: function() {
  29823. return this._eventTrigger
  29824. },
  29825. _getOption: function(name, isScalar) {
  29826. var theme = this._themeManager.theme(name),
  29827. option = this.option(name);
  29828. return isScalar ? option !== undefined ? option : theme : $.extend(true, {}, theme, option)
  29829. },
  29830. _setupResizeHandler: function() {
  29831. if (_parseScalar(this._getOption('redrawOnResize', true), true))
  29832. this._addResizeHandler();
  29833. else
  29834. this._removeResizeHandler()
  29835. },
  29836. _addResizeHandler: function() {
  29837. var that = this;
  29838. if (!that._resizeHandler) {
  29839. that._resizeHandler = createResizeHandler(function() {
  29840. that._handleResize()
  29841. });
  29842. _windowResizeCallbacks.add(that._resizeHandler)
  29843. }
  29844. },
  29845. _removeResizeHandler: function() {
  29846. if (this._resizeHandler) {
  29847. _windowResizeCallbacks.remove(this._resizeHandler);
  29848. this._resizeHandler.dispose();
  29849. this._resizeHandler = null
  29850. }
  29851. },
  29852. _optionChanged: function(args) {
  29853. var that = this;
  29854. if (!that._eventTrigger.update(args.name))
  29855. switch (args.name) {
  29856. case'size':
  29857. case'margin':
  29858. that.render();
  29859. break;
  29860. case'redrawOnResize':
  29861. that._setupResizeHandler();
  29862. break;
  29863. case OPTION_LOADING_INDICATOR:
  29864. that._handleLoadingIndicatorOptionChanged();
  29865. break;
  29866. case"theme":
  29867. case OPTION_RTL_ENABLED:
  29868. that._setThemeAndRtl();
  29869. break;
  29870. case"encodeHtml":
  29871. case"pathModified":
  29872. that._handleThemeOptions();
  29873. break;
  29874. case"tooltip":
  29875. that._setTooltipOptions();
  29876. break;
  29877. default:
  29878. that._invalidate();
  29879. that.callBase.apply(that, arguments)
  29880. }
  29881. },
  29882. _handleThemeOptions: function() {
  29883. var that = this,
  29884. options = {
  29885. rtl: that.option(OPTION_RTL_ENABLED),
  29886. encodeHtml: that.option("encodeHtml"),
  29887. pathModified: that.option("pathModified"),
  29888. animation: that._getAnimationOptions()
  29889. };
  29890. that._renderer.setOptions(options);
  29891. that._setTooltipRendererOptions(options);
  29892. that._setTooltipOptions();
  29893. that._updateLoadingIndicatorOptions();
  29894. that._handleThemeOptionsCore()
  29895. },
  29896. _handleThemeOptionsCore: function() {
  29897. this._initialized && this._refresh()
  29898. },
  29899. _visibilityChanged: function() {
  29900. this.render()
  29901. },
  29902. _initIncidentOccured: function() {
  29903. var that = this;
  29904. that._incidentOccured = function(errorOrWarningId, options) {
  29905. that._eventTrigger('incidentOccured', {target: {
  29906. id: errorOrWarningId,
  29907. type: errorOrWarningId[0] === 'E' ? 'error' : 'warning',
  29908. args: options,
  29909. text: _stringFormat.apply(null, [DX.ERROR_MESSAGES[errorOrWarningId]].concat(options ? options.slice(0) : [])),
  29910. widget: that.NAME,
  29911. version: DX.VERSION
  29912. }})
  29913. }
  29914. },
  29915. _setThemeAndRtl: function() {
  29916. this._themeManager.setTheme(this.option("theme"), this.option(OPTION_RTL_ENABLED))
  29917. },
  29918. _setTooltipRendererOptions: function(options) {
  29919. this._tooltip.setRendererOptions(options)
  29920. },
  29921. _setTooltipOptions: function() {
  29922. this._tooltip.update(this._getOption("tooltip"))
  29923. },
  29924. _initLoadingIndicator: function() {
  29925. if (this._getOption(OPTION_LOADING_INDICATOR).show) {
  29926. this.showLoadingIndicator();
  29927. this._loadIndicator.forceShow()
  29928. }
  29929. },
  29930. _handleLoadingIndicatorOptionChanged: function() {
  29931. var that = this;
  29932. if (!that._skipOptionChanged) {
  29933. that._updateLoadingIndicatorOptions();
  29934. if (that._getOption(OPTION_LOADING_INDICATOR).show)
  29935. that.showLoadingIndicator();
  29936. else
  29937. that.hideLoadingIndicator()
  29938. }
  29939. },
  29940. _updateLoadingIndicatorCanvas: function() {
  29941. this._loadIndicator && this._canvas && this._loadIndicator.applyCanvas(this._canvas)
  29942. },
  29943. _updateLoadingIndicatorOptions: function() {
  29944. this._loadIndicator && this._loadIndicator.applyOptions(this._getOption(OPTION_LOADING_INDICATOR))
  29945. },
  29946. _endLoading: function(complete) {
  29947. if (this._loadIndicator) {
  29948. this._resetIsReady();
  29949. this._loadIndicator.endLoading(complete)
  29950. }
  29951. else
  29952. complete && complete()
  29953. },
  29954. _reappendLoadingIndicator: function() {
  29955. this._loadIndicator && this._loadIndicator.toForeground()
  29956. },
  29957. _disposeLoadingIndicator: function() {
  29958. if (this._loadIndicator) {
  29959. this._loadIndicator.dispose();
  29960. this._loadIndicator = null
  29961. }
  29962. },
  29963. _scheduleLoadingIndicatorHiding: function() {
  29964. this._loadIndicator && this._loadIndicator.scheduleHiding()
  29965. },
  29966. _fulfillLoadingIndicatorHiding: function() {
  29967. this._loadIndicator && this._loadIndicator.fulfillHiding() && this._toggleLoadingIndicatorState(false)
  29968. },
  29969. _normalizeHtml: function(html) {
  29970. var re = /xmlns="[\s\S]*?"/gi,
  29971. first = true;
  29972. html = html.replace(re, function(match) {
  29973. if (!first)
  29974. return "";
  29975. first = false;
  29976. return match
  29977. });
  29978. return html.replace(/xmlns:NS1="[\s\S]*?"/gi, "").replace(/NS1:xmlns:xlink="([\s\S]*?)"/gi, 'xmlns:xlink="$1"')
  29979. },
  29980. _dataIsReady: getTrue,
  29981. _resetIsReady: function() {
  29982. this.isReady = getFalse
  29983. },
  29984. _drawn: function() {
  29985. var that = this;
  29986. that.isReady = getFalse;
  29987. that._dataIsReady() && that._renderer.onEndAnimation(function() {
  29988. that.isReady = getTrue
  29989. });
  29990. that._eventTrigger('drawn', {})
  29991. },
  29992. _toggleLoadingIndicatorState: function(state) {
  29993. if (Boolean(this._getOption(OPTION_LOADING_INDICATOR).show) !== state) {
  29994. this._skipOptionChanged = true;
  29995. this.option(OPTION_LOADING_INDICATOR, {show: state});
  29996. this._skipOptionChanged = false
  29997. }
  29998. },
  29999. _handleLoadingIndicatorShown: function() {
  30000. this._tooltip.hide()
  30001. },
  30002. showLoadingIndicator: function() {
  30003. var that = this;
  30004. if (!that._loadIndicator) {
  30005. that._loadIndicator = new core.LoadIndicator({
  30006. container: that._$element,
  30007. eventTrigger: that._eventTrigger
  30008. });
  30009. that._updateLoadingIndicatorCanvas();
  30010. that._updateLoadingIndicatorOptions()
  30011. }
  30012. that._toggleLoadingIndicatorState(true);
  30013. that._loadIndicator.show();
  30014. that._handleLoadingIndicatorShown()
  30015. },
  30016. hideLoadingIndicator: function() {
  30017. var that = this;
  30018. if (that._loadIndicator) {
  30019. that._toggleLoadingIndicatorState(false);
  30020. that._loadIndicator.hide()
  30021. }
  30022. },
  30023. svg: function() {
  30024. return this._normalizeHtml(this._renderer.svg())
  30025. },
  30026. isReady: getFalse
  30027. });
  30028. function createEventTrigger(eventsMap, callbackGetter) {
  30029. var triggers = {},
  30030. timers = {};
  30031. $.each(eventsMap, function(name, info) {
  30032. if (info.name)
  30033. createItem(name)
  30034. });
  30035. trigger.update = function(name) {
  30036. var eventInfo = eventsMap[name];
  30037. if (eventInfo)
  30038. createItem(eventInfo.newName || name);
  30039. return !!eventInfo
  30040. };
  30041. trigger.dispose = function() {
  30042. $.each(timers, function(timer) {
  30043. clearTimeout(timer)
  30044. });
  30045. eventsMap = callbackGetter = triggers = timers = null
  30046. };
  30047. return trigger;
  30048. function trigger(eventName, arg, complete) {
  30049. triggers[eventName](arg, complete)
  30050. }
  30051. function createItem(name) {
  30052. var eventInfo = eventsMap[name],
  30053. data = callbackGetter(name, eventInfo.deprecated);
  30054. triggers[eventInfo.name] = createCallback(data.callback, _isFunction(data.deprecatedCallback) && data.deprecatedCallback, eventInfo.deprecatedContext, eventInfo.deprecatedArgs)
  30055. }
  30056. function createCallback(callback, deprectatedCallback, deprecatedContext, deprecatedArgs) {
  30057. return function(arg, complete) {
  30058. var timer = setTimeout(function() {
  30059. callback(arg);
  30060. deprectatedCallback && deprectatedCallback.apply(deprecatedContext(arg), deprecatedArgs(arg));
  30061. complete && complete();
  30062. delete timers[timer]
  30063. });
  30064. timers[timer] = 1
  30065. }
  30066. }
  30067. }
  30068. core.DEBUG_createEventTrigger = createEventTrigger
  30069. })(DevExpress, jQuery);
  30070. /*! Module viz-core, file CoreFactory.js */
  30071. (function(DX, undefined) {
  30072. var viz = DX.viz,
  30073. core = viz.core,
  30074. seriesNS = core.series;
  30075. core.CoreFactory = {
  30076. createSeries: function(renderSettings, options) {
  30077. return new seriesNS.Series(renderSettings, options)
  30078. },
  30079. createPoint: function(series, data, options) {
  30080. return new seriesNS.points.Point(series, data, options)
  30081. },
  30082. createLabel: function() {
  30083. return new core.series.points.Label
  30084. },
  30085. createTranslator1D: function(fromValue, toValue, fromAngle, toAngle) {
  30086. return (new core.Translator1D).setDomain(fromValue, toValue).setCodomain(fromAngle, toAngle)
  30087. },
  30088. createTranslator2D: function(range, canvas, options) {
  30089. return new core.Translator2D(range, canvas, options)
  30090. },
  30091. createTickManager: function(types, data, options) {
  30092. return new core.tickManager.TickManager(types, data, options)
  30093. },
  30094. createLegend: function(settings) {
  30095. return new core.Legend(settings)
  30096. },
  30097. createSeriesFamily: function(options) {
  30098. return new seriesNS.helpers.SeriesFamily(options)
  30099. },
  30100. createDataValidator: function(data, groups, incidentOccured, dataPrepareOptions) {
  30101. return new core.DataValidator(data, groups, incidentOccured, dataPrepareOptions)
  30102. }
  30103. }
  30104. })(DevExpress);
  30105. DevExpress.MOD_VIZ_CORE = true
  30106. }
  30107. if (!DevExpress.MOD_VIZ_CHARTS) {
  30108. if (!DevExpress.MOD_VIZ_CORE)
  30109. throw Error('Required module is not referenced: viz-core');
  30110. /*! Module viz-charts, file chartTitle.js */
  30111. (function($, DX, undefined) {
  30112. var viz = DX.viz,
  30113. vizUtils = viz.core.utils,
  30114. isDefined = DX.utils.isDefined,
  30115. DEFAULT_MARGIN = 10;
  30116. function parseMargins(options) {
  30117. options.margin = isDefined(options.margin) ? options.margin : {};
  30118. if (typeof options.margin === 'number') {
  30119. options.margin = options.margin >= 0 ? options.margin : DEFAULT_MARGIN;
  30120. options.margin = {
  30121. top: options.margin,
  30122. bottom: options.margin,
  30123. left: options.margin,
  30124. right: options.margin
  30125. }
  30126. }
  30127. else {
  30128. options.margin.top = options.margin.top >= 0 ? options.margin.top : DEFAULT_MARGIN;
  30129. options.margin.bottom = options.margin.bottom >= 0 ? options.margin.bottom : DEFAULT_MARGIN;
  30130. options.margin.left = options.margin.left >= 0 ? options.margin.left : DEFAULT_MARGIN;
  30131. options.margin.right = options.margin.right >= 0 ? options.margin.right : DEFAULT_MARGIN
  30132. }
  30133. }
  30134. function parseAlignments(options) {
  30135. options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();
  30136. options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();
  30137. if (options.verticalAlignment !== 'top' && options.verticalAlignment !== 'bottom')
  30138. options.verticalAlignment = 'top';
  30139. if (options.horizontalAlignment !== 'left' && options.horizontalAlignment !== 'center' && options.horizontalAlignment !== 'right')
  30140. options.horizontalAlignment = 'center'
  30141. }
  30142. function ChartTitle(renderer, options, group) {
  30143. var that = this;
  30144. that.update(options);
  30145. that.renderer = renderer;
  30146. that.titleGroup = group
  30147. }
  30148. viz.charts.ChartTitle = ChartTitle;
  30149. ChartTitle.prototype = {
  30150. dispose: function() {
  30151. var that = this;
  30152. that.renderer = null;
  30153. that.clipRect = null;
  30154. that.title = null;
  30155. that.innerTitleGroup = null;
  30156. that.titleGroup = null;
  30157. that.options = null
  30158. },
  30159. update: function(options) {
  30160. var that = this;
  30161. if (options) {
  30162. parseAlignments(options);
  30163. that.horizontalAlignment = options.horizontalAlignment;
  30164. that.verticalAlignment = options.verticalAlignment;
  30165. parseMargins(options);
  30166. that.margin = options.margin;
  30167. that.options = options
  30168. }
  30169. },
  30170. _setBoundingRect: function() {
  30171. var that = this,
  30172. options = that.options,
  30173. margin = that.changedMargin || that.margin,
  30174. box;
  30175. if (!that.innerTitleGroup)
  30176. return;
  30177. box = that.innerTitleGroup.getBBox();
  30178. box.height += margin.top + margin.bottom;
  30179. box.width += margin.left + margin.right;
  30180. box.x -= margin.left;
  30181. box.y -= margin.top;
  30182. if (isDefined(options.placeholderSize))
  30183. box.height = options.placeholderSize;
  30184. that.boundingRect = box
  30185. },
  30186. draw: function(size) {
  30187. var that = this,
  30188. titleOptions = that.options,
  30189. renderer = that.renderer;
  30190. if (!titleOptions.text)
  30191. return that;
  30192. size && that.setSize(size);
  30193. that.changedMargin = null;
  30194. if (!that.innerTitleGroup) {
  30195. that.innerTitleGroup = renderer.g();
  30196. that.clipRect = that.createClipRect();
  30197. that.titleGroup && that.clipRect && that.titleGroup.attr({clipId: that.clipRect.id})
  30198. }
  30199. else
  30200. that.innerTitleGroup.clear();
  30201. that.innerTitleGroup.append(that.titleGroup);
  30202. that.title = renderer.text(titleOptions.text, 0, 0).css(vizUtils.patchFontOptions(titleOptions.font)).attr({align: that.horizontalAlignment}).append(that.innerTitleGroup);
  30203. that.title.text = titleOptions.text;
  30204. that._correctTitleLength();
  30205. that._setClipRectSettings();
  30206. return that
  30207. },
  30208. _correctTitleLength: function() {
  30209. var that = this,
  30210. text = that.title.text,
  30211. lineLength,
  30212. box;
  30213. that.title.attr({text: text});
  30214. that._setBoundingRect();
  30215. box = that.getLayoutOptions();
  30216. if (that._width > box.width || text.indexOf("<br/>") !== -1)
  30217. return;
  30218. lineLength = text.length * that._width / box.width;
  30219. that.title.attr({text: text.substr(0, ~~lineLength - 1 - 3) + "..."});
  30220. that.title.setTitle(text);
  30221. that._setBoundingRect()
  30222. },
  30223. changeSize: function(size) {
  30224. var that = this,
  30225. margin = $.extend(true, {}, that.margin);
  30226. if (margin.top + margin.bottom < size.height) {
  30227. if (that.innerTitleGroup) {
  30228. that.options._incidentOccured("W2103");
  30229. that.innerTitleGroup.dispose();
  30230. that.innerTitleGroup = null
  30231. }
  30232. if (that.clipRect) {
  30233. that.clipRect.dispose();
  30234. that.clipRect = null
  30235. }
  30236. }
  30237. else if (size.height > 0) {
  30238. vizUtils.decreaseGaps(margin, ["top", "bottom"], size.height);
  30239. size.height && (that.changedMargin = margin)
  30240. }
  30241. that._correctTitleLength();
  30242. that._setBoundingRect();
  30243. that._setClipRectSettings();
  30244. return that
  30245. },
  30246. getLayoutOptions: function() {
  30247. var options = this.options,
  30248. boundingRect = this.innerTitleGroup ? this.boundingRect : {
  30249. width: 0,
  30250. height: 0,
  30251. x: 0,
  30252. y: 0
  30253. };
  30254. boundingRect.verticalAlignment = options.verticalAlignment;
  30255. boundingRect.horizontalAlignment = options.horizontalAlignment;
  30256. boundingRect.cutLayoutSide = options.verticalAlignment;
  30257. return boundingRect
  30258. },
  30259. getBBox: function() {
  30260. var bbox = $.extend({}, this.getLayoutOptions());
  30261. bbox.x = this._x;
  30262. bbox.y = this._y;
  30263. return bbox
  30264. },
  30265. setSize: function(size) {
  30266. this._width = size.width || this._width;
  30267. return this
  30268. },
  30269. shift: function(x, y) {
  30270. var that = this,
  30271. box = that.getLayoutOptions();
  30272. that._x = x;
  30273. that._y = y;
  30274. x -= box.x;
  30275. y -= box.y;
  30276. that.innerTitleGroup && that.innerTitleGroup.move(x, y);
  30277. that.clipRect && that.clipRect.attr({
  30278. translateX: x,
  30279. translateY: y
  30280. });
  30281. return that
  30282. },
  30283. createClipRect: function() {
  30284. if (isDefined(this.options.placeholderSize))
  30285. return this.renderer.clipRect(0, 0, 0, 0)
  30286. },
  30287. _setClipRectSettings: function() {
  30288. var bbox = this.getLayoutOptions(),
  30289. clipRect = this.clipRect;
  30290. if (clipRect)
  30291. clipRect.attr({
  30292. x: bbox.x,
  30293. y: bbox.y,
  30294. width: bbox.width,
  30295. height: bbox.height
  30296. })
  30297. }
  30298. };
  30299. DX.viz.charts.ChartTitle.__DEFAULT_MARGIN = DEFAULT_MARGIN
  30300. })(jQuery, DevExpress);
  30301. /*! Module viz-charts, file axesConstants.js */
  30302. (function($, DX, undefined) {
  30303. var _map = $.map;
  30304. function getFormatObject(value, options, axisMinMax) {
  30305. var formatObject = {
  30306. value: value,
  30307. valueText: DX.formatHelper.format(value, options.format, options.precision) || ""
  30308. };
  30309. if (axisMinMax) {
  30310. formatObject.min = axisMinMax.min;
  30311. formatObject.max = axisMinMax.max
  30312. }
  30313. return formatObject
  30314. }
  30315. DX.viz.charts.axes = {};
  30316. DX.viz.charts.axes.constants = {
  30317. logarithmic: "logarithmic",
  30318. discrete: "discrete",
  30319. numeric: "numeric",
  30320. left: "left",
  30321. right: "right",
  30322. top: "top",
  30323. bottom: "bottom",
  30324. center: "center",
  30325. canvasPositionPrefix: "canvas_position_",
  30326. canvasPositionTop: "canvas_position_top",
  30327. canvasPositionBottom: "canvas_position_bottom",
  30328. canvasPositionLeft: "canvas_position_left",
  30329. canvasPositionRight: "canvas_position_right",
  30330. canvasPositionStart: "canvas_position_start",
  30331. canvasPositionEnd: "canvas_position_end",
  30332. horizontal: "horizontal",
  30333. vertical: "vertical",
  30334. halfTickLength: 4,
  30335. convertTicksToValues: function(ticks) {
  30336. return _map(ticks || [], function(item) {
  30337. return item.value
  30338. })
  30339. },
  30340. convertValuesToTicks: function(values) {
  30341. return _map(values || [], function(item) {
  30342. return {value: item}
  30343. })
  30344. },
  30345. validateOverlappingMode: function(mode) {
  30346. return mode !== "ignore" ? "enlargeTickInterval" : "ignore"
  30347. },
  30348. formatLabel: function(value, options, axisMinMax) {
  30349. var formatObject = getFormatObject(value, options, axisMinMax);
  30350. return $.isFunction(options.customizeText) ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText
  30351. },
  30352. formatHint: function(value, options, axisMinMax) {
  30353. var formatObject = getFormatObject(value, options, axisMinMax);
  30354. return $.isFunction(options.customizeHint) ? options.customizeHint.call(formatObject, formatObject) : undefined
  30355. }
  30356. }
  30357. })(jQuery, DevExpress);
  30358. /*! Module viz-charts, file xyAxes.js */
  30359. (function($, DX, undefined) {
  30360. var viz = DX.viz,
  30361. core = viz.core,
  30362. axes = viz.charts.axes,
  30363. constants = axes.constants,
  30364. _abs = Math.abs,
  30365. _extend = $.extend,
  30366. CANVAS_POSITION_PREFIX = constants.canvasPositionPrefix,
  30367. TOP = constants.top,
  30368. BOTTOM = constants.bottom,
  30369. LEFT = constants.left,
  30370. RIGHT = constants.right,
  30371. CENTER = constants.center;
  30372. axes.xyAxes = {};
  30373. axes.xyAxes.linear = {
  30374. _getSharpParam: function(oposite) {
  30375. return this._isHorizontal ^ oposite ? "h" : "v"
  30376. },
  30377. _createAxisElement: function() {
  30378. var axisCoord = this._axisPosition,
  30379. canvas = this._getCanvasStartEnd(),
  30380. points = this._isHorizontal ? [canvas.start, axisCoord, canvas.end, axisCoord] : [axisCoord, canvas.start, axisCoord, canvas.end];
  30381. return this._renderer.path(points, "line")
  30382. },
  30383. _getTranslatedCoord: function(value, offset) {
  30384. return this._translator.translate(value, offset)
  30385. },
  30386. _getCanvasStartEnd: function() {
  30387. return {
  30388. start: this._translator.translateSpecialCase(constants.canvasPositionStart),
  30389. end: this._translator.translateSpecialCase(constants.canvasPositionEnd)
  30390. }
  30391. },
  30392. _getScreenDelta: function() {
  30393. return _abs(this._translator.translateSpecialCase(constants.canvasPositionStart) - this._translator.translateSpecialCase(constants.canvasPositionEnd))
  30394. },
  30395. _initAxisPositions: function() {
  30396. var that = this,
  30397. position = that._options.position,
  30398. delta = 0;
  30399. if (that.delta)
  30400. delta = that.delta[position] || 0;
  30401. that._axisPosition = that._additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + position) + delta
  30402. },
  30403. _drawTitle: function() {
  30404. var that = this,
  30405. options = that._options,
  30406. titleOptions = options.title,
  30407. attr = {
  30408. opacity: titleOptions.opacity,
  30409. align: CENTER
  30410. };
  30411. if (!titleOptions.text || !that._axisTitleGroup)
  30412. return;
  30413. that._title = that._renderer.text(titleOptions.text, 0, 0).css(core.utils.patchFontOptions(titleOptions.font)).attr(attr).append(that._axisTitleGroup)
  30414. },
  30415. _adjustConstantLineLabels: function() {
  30416. var that = this,
  30417. options = that._options,
  30418. isHorizontal = that._isHorizontal,
  30419. lines = that._constantLines,
  30420. labels = that._constantLineLabels,
  30421. label,
  30422. line,
  30423. lineBox,
  30424. linesOptions,
  30425. labelOptions,
  30426. box,
  30427. x,
  30428. y,
  30429. i,
  30430. padding = isHorizontal ? {
  30431. top: 0,
  30432. bottom: 0
  30433. } : {
  30434. left: 0,
  30435. right: 0
  30436. },
  30437. paddingTopBottom,
  30438. paddingLeftRight,
  30439. labelVerticalAlignment,
  30440. labelHorizontalAlignment,
  30441. labelIsInside,
  30442. labelHeight,
  30443. labelWidth,
  30444. delta = 0;
  30445. if (labels === undefined && lines === undefined)
  30446. return;
  30447. for (i = 0; i < labels.length; i++) {
  30448. x = y = 0;
  30449. linesOptions = options.constantLines[i];
  30450. paddingTopBottom = linesOptions.paddingTopBottom;
  30451. paddingLeftRight = linesOptions.paddingLeftRight;
  30452. labelOptions = linesOptions.label;
  30453. labelVerticalAlignment = labelOptions.verticalAlignment;
  30454. labelHorizontalAlignment = labelOptions.horizontalAlignment;
  30455. labelIsInside = labelOptions.position === "inside";
  30456. label = labels[i];
  30457. if (label !== null) {
  30458. line = lines[i];
  30459. box = label.getBBox();
  30460. lineBox = line.getBBox();
  30461. labelHeight = box.height;
  30462. labelWidth = box.width;
  30463. if (isHorizontal)
  30464. if (labelIsInside) {
  30465. if (labelHorizontalAlignment === LEFT)
  30466. x -= paddingLeftRight;
  30467. else
  30468. x += paddingLeftRight;
  30469. switch (labelVerticalAlignment) {
  30470. case CENTER:
  30471. y += lineBox.y + lineBox.height / 2 - box.y - labelHeight / 2;
  30472. break;
  30473. case BOTTOM:
  30474. y += lineBox.y + lineBox.height - box.y - labelHeight - paddingTopBottom;
  30475. break;
  30476. default:
  30477. y += lineBox.y - box.y + paddingTopBottom;
  30478. break
  30479. }
  30480. }
  30481. else if (labelVerticalAlignment === BOTTOM) {
  30482. delta = that.delta && that.delta[BOTTOM] || 0;
  30483. y += paddingTopBottom - box.y + that._additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + BOTTOM) + delta;
  30484. if (padding[BOTTOM] < labelHeight + paddingTopBottom)
  30485. padding[BOTTOM] = labelHeight + paddingTopBottom
  30486. }
  30487. else {
  30488. delta = that.delta && that.delta[TOP] || 0;
  30489. y -= paddingTopBottom + box.y + labelHeight - that._additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + TOP) - delta;
  30490. if (padding[TOP] < paddingTopBottom + labelHeight)
  30491. padding[TOP] = paddingTopBottom + labelHeight
  30492. }
  30493. else if (labelIsInside) {
  30494. switch (labelHorizontalAlignment) {
  30495. case CENTER:
  30496. x += lineBox.x + labelWidth / 2 - box.x - labelWidth / 2;
  30497. break;
  30498. case RIGHT:
  30499. x -= paddingLeftRight;
  30500. break;
  30501. default:
  30502. x += paddingLeftRight;
  30503. break
  30504. }
  30505. if (labelVerticalAlignment === BOTTOM)
  30506. y += lineBox.y - box.y + paddingTopBottom;
  30507. else
  30508. y += lineBox.y - box.y - labelHeight - paddingTopBottom
  30509. }
  30510. else {
  30511. y += lineBox.y + lineBox.height / 2 - box.y - labelHeight / 2;
  30512. if (labelHorizontalAlignment === RIGHT) {
  30513. x += paddingLeftRight;
  30514. if (padding[RIGHT] < paddingLeftRight + labelWidth)
  30515. padding[RIGHT] = paddingLeftRight + labelWidth
  30516. }
  30517. else {
  30518. x -= paddingLeftRight;
  30519. if (padding[LEFT] < paddingLeftRight + labelWidth)
  30520. padding[LEFT] = paddingLeftRight + labelWidth
  30521. }
  30522. }
  30523. label.move(x, y)
  30524. }
  30525. }
  30526. that.padding = padding
  30527. },
  30528. _checkAlignmentConstantLineLabels: function(labelOptions) {
  30529. var position = labelOptions.position,
  30530. verticalAlignment = (labelOptions.verticalAlignment || "").toLowerCase(),
  30531. horizontalAlignment = (labelOptions.horizontalAlignment || "").toLowerCase();
  30532. if (this._isHorizontal)
  30533. if (position === "outside") {
  30534. verticalAlignment = verticalAlignment === BOTTOM ? BOTTOM : TOP;
  30535. horizontalAlignment = CENTER
  30536. }
  30537. else {
  30538. verticalAlignment = verticalAlignment === CENTER ? CENTER : verticalAlignment === BOTTOM ? BOTTOM : TOP;
  30539. horizontalAlignment = horizontalAlignment === LEFT ? LEFT : RIGHT
  30540. }
  30541. else if (position === "outside") {
  30542. verticalAlignment = CENTER;
  30543. horizontalAlignment = horizontalAlignment === LEFT ? LEFT : RIGHT
  30544. }
  30545. else {
  30546. verticalAlignment = verticalAlignment === BOTTOM ? BOTTOM : TOP;
  30547. horizontalAlignment = horizontalAlignment === RIGHT ? RIGHT : horizontalAlignment === CENTER ? CENTER : LEFT
  30548. }
  30549. labelOptions.verticalAlignment = verticalAlignment;
  30550. labelOptions.horizontalAlignment = horizontalAlignment
  30551. },
  30552. _getConstantLineLabelsCoords: function(value, lineLabelOptions) {
  30553. var that = this,
  30554. additionalTranslator = that._additionalTranslator,
  30555. align = CENTER,
  30556. x = value,
  30557. y = value;
  30558. if (that._isHorizontal)
  30559. y = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.verticalAlignment);
  30560. else
  30561. x = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.horizontalAlignment);
  30562. switch (lineLabelOptions.horizontalAlignment) {
  30563. case LEFT:
  30564. align = !that._isHorizontal && lineLabelOptions.position === "inside" ? LEFT : RIGHT;
  30565. break;
  30566. case CENTER:
  30567. align = CENTER;
  30568. break;
  30569. case RIGHT:
  30570. align = !that._isHorizontal && lineLabelOptions.position === "inside" ? RIGHT : LEFT;
  30571. break
  30572. }
  30573. return {
  30574. x: x,
  30575. y: y,
  30576. align: align
  30577. }
  30578. },
  30579. _getAdjustedStripLabelCoords: function(stripOptions, label, rect) {
  30580. var x = 0,
  30581. y = 0,
  30582. horizontalAlignment = stripOptions.label.horizontalAlignment,
  30583. verticalAlignment = stripOptions.label.verticalAlignment,
  30584. box = label.getBBox(),
  30585. rectBox = rect.getBBox();
  30586. if (horizontalAlignment === LEFT)
  30587. x += stripOptions.paddingLeftRight;
  30588. else if (horizontalAlignment === RIGHT)
  30589. x -= stripOptions.paddingLeftRight;
  30590. if (verticalAlignment === TOP)
  30591. y += rectBox.y - box.y + stripOptions.paddingTopBottom;
  30592. else if (verticalAlignment === CENTER)
  30593. y += rectBox.y + rectBox.height / 2 - box.y - box.height / 2;
  30594. else if (verticalAlignment === BOTTOM)
  30595. y -= stripOptions.paddingTopBottom;
  30596. return {
  30597. x: x,
  30598. y: y
  30599. }
  30600. },
  30601. _adjustTitle: function() {
  30602. var that = this,
  30603. options = that._options,
  30604. position = options.position,
  30605. title = that._title,
  30606. margin = options.title.margin,
  30607. boxGroup,
  30608. boxTitle,
  30609. params,
  30610. centerPosition = that._translator.translateSpecialCase(CANVAS_POSITION_PREFIX + CENTER),
  30611. axisElementsGroup = that._axisElementsGroup,
  30612. heightTitle,
  30613. axisPosition = that._axisPosition,
  30614. noLabels;
  30615. if (!title || !axisElementsGroup)
  30616. return;
  30617. boxTitle = title.getBBox();
  30618. boxGroup = axisElementsGroup.getBBox();
  30619. noLabels = boxGroup.isEmpty;
  30620. heightTitle = boxTitle.height;
  30621. if (that._isHorizontal)
  30622. if (position === BOTTOM)
  30623. params = {
  30624. y: (noLabels ? axisPosition : boxGroup.y + boxGroup.height) - boxTitle.y + margin,
  30625. x: centerPosition
  30626. };
  30627. else
  30628. params = {
  30629. y: (noLabels ? axisPosition : boxGroup.y) - heightTitle - boxTitle.y - margin,
  30630. x: centerPosition
  30631. };
  30632. else {
  30633. if (position === LEFT)
  30634. params = {
  30635. x: (noLabels ? axisPosition : boxGroup.x) - heightTitle - boxTitle.y - margin,
  30636. y: centerPosition
  30637. };
  30638. else
  30639. params = {
  30640. x: (noLabels ? axisPosition : boxGroup.x + boxGroup.width) + heightTitle + boxTitle.y + margin,
  30641. y: centerPosition
  30642. };
  30643. params.rotate = options.position === LEFT ? 270 : 90
  30644. }
  30645. title.attr(params)
  30646. },
  30647. coordsIn: function(x, y) {
  30648. var rect = this.getBoundingRect();
  30649. return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height
  30650. },
  30651. _getTicksOptions: function() {
  30652. var options = this._options;
  30653. return {
  30654. base: options.type === constants.logarithmic ? options.logarithmBase : undefined,
  30655. tickInterval: this._translator.getBusinessRange().stubData ? null : options.tickInterval,
  30656. gridSpacingFactor: options.axisDivisionFactor,
  30657. incidentOccured: options.incidentOccured,
  30658. setTicksAtUnitBeginning: options.setTicksAtUnitBeginning,
  30659. showMinorTicks: options.minorTick.visible || options.minorGrid.visible,
  30660. minorTickInterval: options.minorTickInterval,
  30661. minorTickCount: options.minorTickCount
  30662. }
  30663. },
  30664. _getOverlappingBehaviorOptions: function() {
  30665. var that = this,
  30666. options = that._options,
  30667. getText = function() {
  30668. return ""
  30669. },
  30670. overlappingBehavior = options.label.overlappingBehavior ? _extend({}, options.label.overlappingBehavior) : null;
  30671. if (overlappingBehavior) {
  30672. if (!that._isHorizontal)
  30673. overlappingBehavior.mode = constants.validateOverlappingMode(overlappingBehavior.mode);
  30674. if (overlappingBehavior.mode !== "rotate")
  30675. overlappingBehavior.rotationAngle = 0
  30676. }
  30677. if (!that._translator.getBusinessRange().stubData)
  30678. getText = function(value, labelOptions) {
  30679. return constants.formatLabel(value, labelOptions, {
  30680. min: options.min,
  30681. max: options.max
  30682. })
  30683. };
  30684. return {
  30685. hasLabelFormat: that._hasLabelFormat,
  30686. labelOptions: options.label,
  30687. overlappingBehavior: overlappingBehavior,
  30688. isHorizontal: that._isHorizontal,
  30689. textOptions: that._textOptions,
  30690. textFontStyles: that._textFontStyles,
  30691. textSpacing: options.label.minSpacing,
  30692. getText: getText,
  30693. renderText: function(text, x, y, options) {
  30694. return that._renderer.text(text, x, y, options).append(that._renderer.root)
  30695. },
  30696. translate: function(value, useAdditionalTranslator) {
  30697. return useAdditionalTranslator ? that._additionalTranslator.translate(value) : that._translator.translate(value)
  30698. },
  30699. isInverted: that._translator.getBusinessRange().invert
  30700. }
  30701. },
  30702. _getSpiderCategoryOption: $.noop,
  30703. _getMinMax: function() {
  30704. return {
  30705. min: this._options.min,
  30706. max: this._options.max
  30707. }
  30708. },
  30709. _getStick: function() {
  30710. return !this._options.valueMarginsEnabled
  30711. },
  30712. _getStripLabelCoords: function(stripLabelOptions, stripFrom, stripTo) {
  30713. var that = this,
  30714. additionalTranslator = that._additionalTranslator,
  30715. isHorizontal = that._isHorizontal,
  30716. align = isHorizontal ? CENTER : LEFT,
  30717. x,
  30718. y;
  30719. if (isHorizontal) {
  30720. if (stripLabelOptions.horizontalAlignment === CENTER) {
  30721. x = stripFrom + (stripTo - stripFrom) / 2;
  30722. align = CENTER
  30723. }
  30724. else if (stripLabelOptions.horizontalAlignment === LEFT) {
  30725. x = stripFrom;
  30726. align = LEFT
  30727. }
  30728. else if (stripLabelOptions.horizontalAlignment === RIGHT) {
  30729. x = stripTo;
  30730. align = RIGHT
  30731. }
  30732. y = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.verticalAlignment)
  30733. }
  30734. else {
  30735. x = additionalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.horizontalAlignment);
  30736. align = stripLabelOptions.horizontalAlignment;
  30737. if (stripLabelOptions.verticalAlignment === TOP)
  30738. y = stripFrom;
  30739. else if (stripLabelOptions.verticalAlignment === CENTER)
  30740. y = stripTo + (stripFrom - stripTo) / 2;
  30741. else if (stripLabelOptions.verticalAlignment === BOTTOM)
  30742. y = stripTo
  30743. }
  30744. return {
  30745. x: x,
  30746. y: y,
  30747. align: align
  30748. }
  30749. },
  30750. _getTranslatedValue: function(value, y, offset) {
  30751. return {
  30752. x: this._translator.translate(value, offset),
  30753. y: y
  30754. }
  30755. },
  30756. _getSkippedCategory: function() {
  30757. var that = this,
  30758. options = that._options,
  30759. categories = that._translator.getVisibleCategories() || that._translator.getBusinessRange().categories,
  30760. categoryToSkip;
  30761. if (categories && !!that._tickOffset && !options.valueMarginsEnabled)
  30762. categoryToSkip = options.inverted ? categories[0] : categories[categories.length - 1];
  30763. return categoryToSkip
  30764. }
  30765. }
  30766. })(jQuery, DevExpress);
  30767. /*! Module viz-charts, file polarAxes.js */
  30768. (function($, DX, undefined) {
  30769. var viz = DX.viz,
  30770. core = viz.core,
  30771. utils = DX.utils,
  30772. constants = viz.charts.axes.constants,
  30773. _math = Math,
  30774. _abs = _math.abs,
  30775. _round = _math.round,
  30776. _extend = $.extend,
  30777. _noop = $.noop,
  30778. _map = $.map,
  30779. HALF_PI_ANGLE = 90;
  30780. viz.charts.axes.polarAxes = {};
  30781. function getPolarQuarter(angle) {
  30782. var quarter;
  30783. angle = utils.normalizeAngle(angle);
  30784. if (angle >= 315 && angle <= 360 || angle < 45 && angle >= 0)
  30785. quarter = 1;
  30786. else if (angle >= 45 && angle < 135)
  30787. quarter = 2;
  30788. else if (angle >= 135 && angle < 225)
  30789. quarter = 3;
  30790. else if (angle >= 225 && angle < 315)
  30791. quarter = 4;
  30792. return quarter
  30793. }
  30794. viz.charts.axes.polarAxes.circular = {
  30795. _overlappingBehaviorType: "circular",
  30796. _createAxisElement: function() {
  30797. var additionalTranslator = this._additionalTranslator;
  30798. return this._renderer.circle(additionalTranslator.getCenter().x, additionalTranslator.getCenter().y, additionalTranslator.getRadius())
  30799. },
  30800. _setBoundingRect: function() {
  30801. this.boundingRect = {
  30802. width: 0,
  30803. height: 0
  30804. }
  30805. },
  30806. _getTicksOptions: viz.charts.axes.xyAxes.linear._getTicksOptions,
  30807. _getOverlappingBehaviorOptions: function() {
  30808. var that = this,
  30809. additionalTranslator = that._additionalTranslator,
  30810. startAngle = additionalTranslator.getStartAngle(),
  30811. options = viz.charts.axes.xyAxes.linear._getOverlappingBehaviorOptions.call(that),
  30812. translator = that._translator,
  30813. indentFromAxis = that._options.label.indentFromAxis || 0;
  30814. if (options.overlappingBehavior)
  30815. options.overlappingBehavior = {mode: constants.validateOverlappingMode(options.overlappingBehavior.mode)};
  30816. options.translate = function(value) {
  30817. return core.utils.convertPolarToXY(additionalTranslator.getCenter(), startAngle, translator.translate(value), additionalTranslator.translate(constants.canvasPositionBottom))
  30818. };
  30819. options.addMinMax = {min: true};
  30820. options.isInverted = translator.getBusinessRange().invert;
  30821. options.circularRadius = additionalTranslator.getRadius() + indentFromAxis;
  30822. options.circularStartAngle = options.circularEndAngle = startAngle;
  30823. options.isHorizontal = false;
  30824. return options
  30825. },
  30826. _getSpiderCategoryOption: function() {
  30827. return this._options.firstPointOnStartAngle
  30828. },
  30829. _getMinMax: function() {
  30830. var options = this._options;
  30831. return {
  30832. min: undefined,
  30833. max: utils.isNumber(options.period) && options.argumentType === constants.numeric ? options.period : undefined
  30834. }
  30835. },
  30836. _getStick: function() {
  30837. return this._options.firstPointOnStartAngle || this._options.type !== constants.discrete
  30838. },
  30839. measureLabels: function() {
  30840. var that = this,
  30841. options = that._options,
  30842. indentFromAxis = options.label.indentFromAxis || 0,
  30843. widthAxis = options.visible ? options.width : 0,
  30844. maxLabelParams;
  30845. if (!that._axisElementsGroup || !that._options.label.visible)
  30846. return {
  30847. height: widthAxis,
  30848. width: widthAxis
  30849. };
  30850. that._updateTickManager();
  30851. maxLabelParams = that._tickManager.getMaxLabelParams();
  30852. return {
  30853. height: maxLabelParams.height + indentFromAxis + constants.halfTickLength,
  30854. width: maxLabelParams.width + indentFromAxis + constants.halfTickLength
  30855. }
  30856. },
  30857. _getTranslatedCoord: function(value, offset) {
  30858. return this._translator.translate(value, offset) - HALF_PI_ANGLE
  30859. },
  30860. _getCanvasStartEnd: function() {
  30861. return {
  30862. start: 0 - HALF_PI_ANGLE,
  30863. end: 360 - HALF_PI_ANGLE
  30864. }
  30865. },
  30866. _createStrip: function(fromAngle, toAngle, attr) {
  30867. var center = this._additionalTranslator.getCenter(),
  30868. r = this._additionalTranslator.getRadius();
  30869. return this._renderer.arc(center.x, center.y, 0, r, -toAngle, -fromAngle).attr(attr)
  30870. },
  30871. _getStripLabelCoords: function(_, stripFrom, stripTo) {
  30872. var that = this,
  30873. angle = stripFrom + (stripTo - stripFrom) / 2,
  30874. cossin = utils.getCosAndSin(-angle),
  30875. halfRad = that._additionalTranslator.getRadius() / 2,
  30876. center = that._additionalTranslator.getCenter(),
  30877. x = _round(center.x + halfRad * cossin.cos),
  30878. y = _round(center.y - halfRad * cossin.sin);
  30879. return {
  30880. x: x,
  30881. y: y,
  30882. align: constants.center
  30883. }
  30884. },
  30885. _createConstantLine: function(value, attr) {
  30886. var center = this._additionalTranslator.getCenter(),
  30887. r = this._additionalTranslator.getRadius();
  30888. return this._createPathElement([center.x, center.y, center.x + r, center.y], attr).rotate(value, center.x, center.y)
  30889. },
  30890. _getConstantLineLabelsCoords: function(value) {
  30891. var that = this,
  30892. cossin = utils.getCosAndSin(-value),
  30893. halfRad = that._additionalTranslator.getRadius() / 2,
  30894. center = that._additionalTranslator.getCenter(),
  30895. x = _round(center.x + halfRad * cossin.cos),
  30896. y = _round(center.y - halfRad * cossin.sin);
  30897. return {
  30898. x: x,
  30899. y: y,
  30900. align: constants.center
  30901. }
  30902. },
  30903. _checkAlignmentConstantLineLabels: _noop,
  30904. _getScreenDelta: function() {
  30905. return 2 * Math.PI * this._additionalTranslator.getRadius()
  30906. },
  30907. _getTickCoord: function(tick) {
  30908. var center = this._additionalTranslator.getCenter(),
  30909. r = this._additionalTranslator.getRadius();
  30910. return {
  30911. x1: center.x + r - constants.halfTickLength,
  30912. y1: center.y,
  30913. x2: center.x + r + constants.halfTickLength,
  30914. y2: center.y,
  30915. angle: tick.angle
  30916. }
  30917. },
  30918. _getLabelAdjustedCoord: function(tick) {
  30919. var that = this,
  30920. pos = tick.labelPos,
  30921. cossin = utils.getCosAndSin(pos.angle),
  30922. cos = cossin.cos,
  30923. sin = cossin.sin,
  30924. box = tick.label.getBBox(),
  30925. halfWidth = box.width / 2,
  30926. halfHeight = box.height / 2,
  30927. indentFromAxis = that._options.label.indentFromAxis || 0,
  30928. x = pos.x + indentFromAxis * cos,
  30929. y = pos.y + (pos.y - box.y - halfHeight) + indentFromAxis * sin;
  30930. switch (getPolarQuarter(pos.angle)) {
  30931. case 1:
  30932. x += halfWidth;
  30933. y += halfHeight * sin;
  30934. break;
  30935. case 2:
  30936. x += halfWidth * cos;
  30937. y += halfHeight;
  30938. break;
  30939. case 3:
  30940. x += -halfWidth;
  30941. y += halfHeight * sin;
  30942. break;
  30943. case 4:
  30944. x += halfWidth * cos;
  30945. y += -halfHeight;
  30946. break
  30947. }
  30948. return {
  30949. x: x,
  30950. y: y
  30951. }
  30952. },
  30953. _getGridLineDrawer: function() {
  30954. var that = this,
  30955. r = that._additionalTranslator.getRadius(),
  30956. center = that._additionalTranslator.getCenter();
  30957. return function(tick) {
  30958. return that._createPathElement([center.x, center.y, center.x + r, center.y], tick.gridStyle).rotate(tick.angle, center.x, center.y)
  30959. }
  30960. },
  30961. _getTranslatedValue: function(value, _, offset) {
  30962. var additionalTranslator = this._additionalTranslator,
  30963. startAngle = additionalTranslator.getStartAngle(),
  30964. angle = this._translator.translate(value, -offset),
  30965. coords = core.utils.convertPolarToXY(additionalTranslator.getCenter(), startAngle, angle, additionalTranslator.translate(constants.canvasPositionBottom));
  30966. return {
  30967. x: coords.x,
  30968. y: coords.y,
  30969. angle: angle + startAngle - HALF_PI_ANGLE
  30970. }
  30971. },
  30972. _getAdjustedStripLabelCoords: function(_, label) {
  30973. var y,
  30974. box = label.getBBox();
  30975. y = label.attr("y") - box.y - box.height / 2;
  30976. return {
  30977. x: 0,
  30978. y: y
  30979. }
  30980. },
  30981. coordsIn: function(x, y) {
  30982. return core.utils.convertXYToPolar(this._additionalTranslator.getCenter(), x, y).r > this._additionalTranslator.getRadius()
  30983. },
  30984. _rotateTick: function(tick, angle) {
  30985. var center = this._additionalTranslator.getCenter();
  30986. tick.graphic.rotate(angle, center.x, center.y)
  30987. }
  30988. };
  30989. viz.charts.axes.polarAxes.circularSpider = _extend({}, viz.charts.axes.polarAxes.circular, {
  30990. _createAxisElement: function() {
  30991. var points = _map(this.getSpiderTicks(), function(tick) {
  30992. return {
  30993. x: tick.posX,
  30994. y: tick.posY
  30995. }
  30996. });
  30997. return this._renderer.path(points, "area")
  30998. },
  30999. _getStick: function() {
  31000. return true
  31001. },
  31002. _getSpiderCategoryOption: function() {
  31003. return true
  31004. },
  31005. getSpiderTicks: function() {
  31006. var that = this;
  31007. that._spiderTicks = constants.convertValuesToTicks(that._tickManager.getFullTicks());
  31008. that._initTicks(that._spiderTicks, {}, {});
  31009. return that._spiderTicks
  31010. },
  31011. _createStrip: function(fromAngle, toAngle, attr) {
  31012. var center = this._additionalTranslator.getCenter(),
  31013. spiderTicks = this.getSpiderTicks(),
  31014. firstTick,
  31015. lastTick,
  31016. points = _map(spiderTicks, function(tick, i) {
  31017. var result = [],
  31018. nextTick;
  31019. if (tick.angle >= fromAngle && tick.angle <= toAngle) {
  31020. if (!firstTick) {
  31021. firstTick = spiderTicks[i - 1] || spiderTicks[spiderTicks.length - 1];
  31022. result.push((tick.posX + firstTick.posX) / 2, (tick.posY + firstTick.posY) / 2)
  31023. }
  31024. result.push(tick.posX, tick.posY);
  31025. nextTick = spiderTicks[i + 1] || spiderTicks[0];
  31026. lastTick = {
  31027. x: (tick.posX + nextTick.posX) / 2,
  31028. y: (tick.posY + nextTick.posY) / 2
  31029. }
  31030. }
  31031. else
  31032. result = null;
  31033. return result
  31034. });
  31035. points.push(lastTick.x, lastTick.y);
  31036. points.push(center.x, center.y);
  31037. return this._renderer.path(points, "area").attr(attr)
  31038. },
  31039. _getTranslatedCoord: function(value, offset) {
  31040. return this._translator.translate(value, offset) - HALF_PI_ANGLE
  31041. },
  31042. _setTickOffset: function() {
  31043. this._tickOffset = false
  31044. }
  31045. });
  31046. viz.charts.axes.polarAxes.linear = {
  31047. _overlappingBehaviorType: "linear",
  31048. _getMinMax: viz.charts.axes.polarAxes.circular._getMinMax,
  31049. _getStick: viz.charts.axes.xyAxes.linear._getStick,
  31050. _getTicksOptions: viz.charts.axes.xyAxes.linear._getTicksOptions,
  31051. _getSpiderCategoryOption: $.noop,
  31052. _createAxisElement: function() {
  31053. var additionalTranslator = this._additionalTranslator,
  31054. centerCoord = additionalTranslator.getCenter(),
  31055. points = [centerCoord.x, centerCoord.y, centerCoord.x + additionalTranslator.getRadius(), centerCoord.y];
  31056. return this._renderer.path(points, "line").rotate(additionalTranslator.getStartAngle() - HALF_PI_ANGLE, centerCoord.x, centerCoord.y)
  31057. },
  31058. _setBoundingRect: viz.charts.axes.polarAxes.circular._setBoundingRect,
  31059. _getScreenDelta: function() {
  31060. return this._additionalTranslator.getRadius()
  31061. },
  31062. _getTickCoord: function(tick) {
  31063. return {
  31064. x1: tick.posX - constants.halfTickLength,
  31065. y1: tick.posY,
  31066. x2: tick.posX + constants.halfTickLength,
  31067. y2: tick.posY,
  31068. angle: tick.angle + HALF_PI_ANGLE
  31069. }
  31070. },
  31071. _getOverlappingBehaviorOptions: function() {
  31072. var that = this,
  31073. translator = that._translator,
  31074. orthTranslator = that._additionalTranslator,
  31075. options = viz.charts.axes.xyAxes.linear._getOverlappingBehaviorOptions.call(this),
  31076. startAngle = utils.normalizeAngle(that._additionalTranslator.getStartAngle());
  31077. if (options.overlappingBehavior)
  31078. options.overlappingBehavior = {mode: constants.validateOverlappingMode(options.overlappingBehavior.mode)};
  31079. options.isHorizontal = startAngle > 45 && startAngle < 135 || startAngle > 225 && startAngle < 315 ? true : false;
  31080. options.isInverted = translator.getBusinessRange().invert;
  31081. options.translate = function(value) {
  31082. return core.utils.convertPolarToXY(orthTranslator.getCenter(), that._options.startAngle, orthTranslator.translate(constants.canvasPositionTop), translator.translate(value)).x
  31083. };
  31084. return options
  31085. },
  31086. _getLabelAdjustedCoord: function(tick) {
  31087. var that = this,
  31088. pos = tick.labelPos,
  31089. cossin = utils.getCosAndSin(pos.angle),
  31090. indentFromAxis = that._options.label.indentFromAxis || 0,
  31091. box = tick.label.getBBox(),
  31092. x,
  31093. y;
  31094. x = pos.x - _abs(indentFromAxis * cossin.sin) + _abs(box.width / 2 * cossin.cos);
  31095. y = pos.y + (pos.y - box.y) - _abs(box.height / 2 * cossin.sin) + _abs(indentFromAxis * cossin.cos);
  31096. return {
  31097. x: x,
  31098. y: y
  31099. }
  31100. },
  31101. _getGridLineDrawer: function() {
  31102. var that = this,
  31103. pos = that._additionalTranslator.getCenter();
  31104. return function(tick) {
  31105. return that._renderer.circle(pos.x, pos.y, utils.getDistance(pos.x, pos.y, tick.posX, tick.posY)).attr(tick.gridStyle).sharp()
  31106. }
  31107. },
  31108. _getTranslatedValue: function(value, _, offset) {
  31109. var additionalTranslator = this._additionalTranslator,
  31110. startAngle = additionalTranslator.getStartAngle(),
  31111. angle = additionalTranslator.translate(constants.canvasPositionStart),
  31112. xy = core.utils.convertPolarToXY(additionalTranslator.getCenter(), startAngle, angle, this._translator.translate(value, offset));
  31113. return {
  31114. x: xy.x,
  31115. y: xy.y,
  31116. angle: angle + startAngle - HALF_PI_ANGLE
  31117. }
  31118. },
  31119. _getTranslatedCoord: function(value, offset) {
  31120. return this._translator.translate(value, offset)
  31121. },
  31122. _getCanvasStartEnd: function() {
  31123. return {
  31124. start: 0,
  31125. end: this._additionalTranslator.getRadius()
  31126. }
  31127. },
  31128. _createStrip: function(fromPoint, toPoint, attr) {
  31129. var center = this._additionalTranslator.getCenter();
  31130. return this._renderer.arc(center.x, center.y, fromPoint, toPoint, 0, 360).attr(attr)
  31131. },
  31132. _getAdjustedStripLabelCoords: viz.charts.axes.polarAxes.circular._getAdjustedStripLabelCoords,
  31133. _getStripLabelCoords: function(_, stripFrom, stripTo) {
  31134. var that = this,
  31135. labelPos = stripFrom + (stripTo - stripFrom) / 2,
  31136. center = that._additionalTranslator.getCenter(),
  31137. y = _round(center.y - labelPos);
  31138. return {
  31139. x: center.x,
  31140. y: y,
  31141. align: constants.center
  31142. }
  31143. },
  31144. _createConstantLine: function(value, attr) {
  31145. var center = this._additionalTranslator.getCenter();
  31146. return this._renderer.circle(center.x, center.y, value).attr(attr).sharp()
  31147. },
  31148. _getConstantLineLabelsCoords: function(value) {
  31149. var that = this,
  31150. center = that._additionalTranslator.getCenter(),
  31151. y = _round(center.y - value);
  31152. return {
  31153. x: center.x,
  31154. y: y,
  31155. align: constants.center
  31156. }
  31157. },
  31158. _checkAlignmentConstantLineLabels: _noop,
  31159. _rotateTick: function(tick, angle) {
  31160. tick.graphic.rotate(angle, tick.posX, tick.posY)
  31161. }
  31162. };
  31163. viz.charts.axes.polarAxes.linearSpider = _extend({}, viz.charts.axes.polarAxes.linear, {
  31164. _createPathElement: function(points, attr) {
  31165. return this._renderer.path(points, "area").attr(attr).sharp()
  31166. },
  31167. setSpiderTicks: function(ticks) {
  31168. this._spiderTicks = ticks
  31169. },
  31170. _getGridLineDrawer: function() {
  31171. var that = this,
  31172. pos = that._additionalTranslator.getCenter();
  31173. return function(tick) {
  31174. var radius = utils.getDistance(pos.x, pos.y, tick.posX, tick.posY);
  31175. return that._createPathElement(that._getGridPoints(pos, radius), tick.gridStyle)
  31176. }
  31177. },
  31178. _getGridPoints: function(pos, radius) {
  31179. return _map(this._spiderTicks, function(tick) {
  31180. var cossin = utils.getCosAndSin(tick.angle);
  31181. return {
  31182. x: _round(pos.x + radius * cossin.cos),
  31183. y: _round(pos.y + radius * cossin.sin)
  31184. }
  31185. })
  31186. },
  31187. _createStrip: function(fromPoint, toPoint, attr) {
  31188. var center = this._additionalTranslator.getCenter(),
  31189. innerPoints = this._getGridPoints(center, toPoint),
  31190. outerPoints = this._getGridPoints(center, fromPoint);
  31191. return this._renderer.path([outerPoints, innerPoints.reverse()], "area").attr(attr)
  31192. },
  31193. _createConstantLine: function(value, attr) {
  31194. var center = this._additionalTranslator.getCenter(),
  31195. points = this._getGridPoints(center, value);
  31196. return this._createPathElement(points, attr)
  31197. }
  31198. })
  31199. })(jQuery, DevExpress);
  31200. /*! Module viz-charts, file baseAxis.js */
  31201. (function($, DX, undefined) {
  31202. var viz = DX.viz,
  31203. core = viz.core,
  31204. utils = DX.utils,
  31205. constants = viz.charts.axes.constants,
  31206. _isDefined = utils.isDefined,
  31207. _isNumber = utils.isNumber,
  31208. _getSignificantDigitPosition = utils.getSignificantDigitPosition,
  31209. _roundValue = utils.roundValue,
  31210. _math = Math,
  31211. _abs = _math.abs,
  31212. _round = _math.round,
  31213. _extend = $.extend,
  31214. _each = $.each,
  31215. _noop = $.noop,
  31216. WIDGET_CLASS = "dxc",
  31217. DEFAULT_AXIS_LABEL_SPACING = 5,
  31218. MAX_GRID_BORDER_ADHENSION = 4,
  31219. LABEL_BACKGROUND_PADDING_X = 8,
  31220. LABEL_BACKGROUND_PADDING_Y = 4,
  31221. Axis;
  31222. function validateAxisOptions(options, isHorizontal) {
  31223. var labelOptions = options.label,
  31224. position = options.position,
  31225. defaultPosition = isHorizontal ? constants.bottom : constants.left,
  31226. secondaryPosition = isHorizontal ? constants.top : constants.right;
  31227. if (position !== defaultPosition && position !== secondaryPosition)
  31228. position = defaultPosition;
  31229. if (position === constants.right && !labelOptions.userAlignment)
  31230. labelOptions.alignment = constants.left;
  31231. options.position = position;
  31232. options.hoverMode = options.hoverMode ? options.hoverMode.toLowerCase() : "none";
  31233. labelOptions.minSpacing = _isDefined(labelOptions.minSpacing) ? labelOptions.minSpacing : DEFAULT_AXIS_LABEL_SPACING
  31234. }
  31235. Axis = DX.viz.charts.axes.Axis = function(renderSettings) {
  31236. var that = this;
  31237. that._renderer = renderSettings.renderer;
  31238. that._isHorizontal = renderSettings.isHorizontal;
  31239. that._incidentOccured = renderSettings.incidentOccured;
  31240. that._stripsGroup = renderSettings.stripsGroup;
  31241. that._labelAxesGroup = renderSettings.labelAxesGroup;
  31242. that._constantLinesGroup = renderSettings.constantLinesGroup;
  31243. that._axesContainerGroup = renderSettings.axesContainerGroup;
  31244. that._gridContainerGroup = renderSettings.gridGroup;
  31245. that._axisClass = renderSettings.axisClass;
  31246. that._setType(renderSettings.axesType, renderSettings.drawingType);
  31247. that._createAxisGroups();
  31248. that._tickManager = that._createTickManager()
  31249. };
  31250. Axis.prototype = {
  31251. constructor: Axis,
  31252. dispose: function() {
  31253. var that = this;
  31254. that._axisElementsGroup && that._axisElementsGroup.dispose();
  31255. that._stripLabels = that._strips = null;
  31256. that._title = null;
  31257. that._axisStripGroup = that._axisConstantLineGroup = that._axisLabelGroup = null;
  31258. that._axisLineGroup = that._axisElementsGroup = that._axisGridGroup = null;
  31259. that._axisGroup = that._axisTitleGroup = null;
  31260. that._axesContainerGroup = that._stripsGroup = that._constantLinesGroup = null;
  31261. that._renderer = that._options = that._textOptions = that._textFontStyles = null;
  31262. that._translator = that._additionalTranslator = null;
  31263. that._majorTicks = that._minorTicks = null;
  31264. that._tickManager = null
  31265. },
  31266. getOptions: function() {
  31267. return this._options
  31268. },
  31269. setPane: function(pane) {
  31270. this.pane = pane;
  31271. this._options.pane = pane
  31272. },
  31273. setTypes: function(type, axisType, typeSelector) {
  31274. this._options.type = type || this._options.type;
  31275. this._options[typeSelector] = axisType || this._options[typeSelector]
  31276. },
  31277. resetTypes: function(typeSelector) {
  31278. this._options.type = this._initTypes.type;
  31279. this._options[typeSelector] = this._initTypes[typeSelector]
  31280. },
  31281. getTranslator: function() {
  31282. return this._translator
  31283. },
  31284. updateOptions: function(options) {
  31285. var that = this,
  31286. labelOpt = options.label;
  31287. that._options = options;
  31288. that._initTypes = {
  31289. type: options.type,
  31290. argumentType: options.argumentType,
  31291. valueType: options.valueType
  31292. };
  31293. validateAxisOptions(options, that._isHorizontal);
  31294. that._setTickOffset();
  31295. that.pane = options.pane;
  31296. that.name = options.name;
  31297. that.priority = options.priority;
  31298. that._virtual = options.virtual;
  31299. that._hasLabelFormat = labelOpt.format !== "" && _isDefined(labelOpt.format);
  31300. that._textOptions = {
  31301. align: labelOpt.alignment,
  31302. opacity: labelOpt.opacity
  31303. };
  31304. that._textFontStyles = core.utils.patchFontOptions(labelOpt.font);
  31305. if (options.type === constants.logarithmic) {
  31306. if (options.logarithmBaseError) {
  31307. that._incidentOccured("E2104");
  31308. delete options.logarithmBaseError
  31309. }
  31310. that.calcInterval = function(value, prevValue) {
  31311. return utils.getLog(value / prevValue, options.logarithmBase)
  31312. }
  31313. }
  31314. },
  31315. updateSize: function(clearAxis) {
  31316. var that = this,
  31317. options = that._options,
  31318. direction = that._isHorizontal ? "horizontal" : "vertical";
  31319. if (options.title.text && that._axisTitleGroup) {
  31320. that._incidentOccured("W2105", [direction]);
  31321. that._axisTitleGroup.dispose();
  31322. that._axisTitleGroup = null
  31323. }
  31324. if (clearAxis && that._axisElementsGroup && options.label.visible && !that._translator.getBusinessRange().stubData) {
  31325. that._incidentOccured("W2106", [direction]);
  31326. that._axisElementsGroup.dispose();
  31327. that._axisElementsGroup = null
  31328. }
  31329. that._setBoundingRect()
  31330. },
  31331. _updateTranslatorInterval: function() {
  31332. var that = this,
  31333. i,
  31334. majorTicks,
  31335. majorTicksLength,
  31336. translator = that._translator,
  31337. businessRange = translator.getBusinessRange();
  31338. if (!businessRange.categories && !businessRange.isSynchronized) {
  31339. that.getMajorTicks(true);
  31340. businessRange.addRange(that._tickManager.getTickBounds());
  31341. translator.reinit()
  31342. }
  31343. that._majorTicks = majorTicks = that.getMajorTicks();
  31344. if (!businessRange.categories) {
  31345. majorTicksLength = majorTicks.length;
  31346. for (i = 0; i < majorTicksLength - 1; i++)
  31347. businessRange.addRange({interval: _abs(majorTicks[i].value - majorTicks[i + 1].value)})
  31348. }
  31349. that._decimatedTicks = businessRange.categories ? that.getDecimatedTicks() : [];
  31350. that._minorTicks = that.getMinorTicks()
  31351. },
  31352. setTranslator: function(translator, additionalTranslator) {
  31353. var that = this,
  31354. range = translator.getBusinessRange();
  31355. this._minBound = range.minVisible;
  31356. this._maxBound = range.maxVisible;
  31357. that._translator = translator;
  31358. that._additionalTranslator = additionalTranslator;
  31359. that.resetTicks();
  31360. that._updateTranslatorInterval()
  31361. },
  31362. resetTicks: function() {
  31363. this._deleteLabels();
  31364. this._majorTicks = this._minorTicks = null
  31365. },
  31366. getCurrentLabelPos: function() {
  31367. var that = this,
  31368. options = that._options,
  31369. position = options.position,
  31370. labelOffset = options.label.indentFromAxis,
  31371. axisPosition = that._axisPosition;
  31372. return position === constants.top || position === constants.left ? axisPosition - labelOffset : axisPosition + labelOffset
  31373. },
  31374. getUntranslatedValue: function(pos) {
  31375. var that = this,
  31376. translator = that._translator,
  31377. value = translator.untranslate(pos);
  31378. if (_isDefined(value))
  31379. return constants.formatLabel(_isNumber(value) ? _roundValue(value, _getSignificantDigitPosition(translator.getBusinessRange().interval)) : value, that._options.label);
  31380. return null
  31381. },
  31382. _drawAxis: function() {
  31383. var that = this,
  31384. options = that._options,
  31385. axis = that._createAxis({
  31386. "stroke-width": options.width,
  31387. stroke: options.color,
  31388. "stroke-opacity": options.opacity
  31389. });
  31390. axis.append(that._axisLineGroup)
  31391. },
  31392. _correctMinForTicks: function(min, max, screenDelta) {
  31393. var digitPosition = _getSignificantDigitPosition(_abs(max - min) / screenDelta),
  31394. newMin = _roundValue(Number(min), digitPosition),
  31395. correctingValue;
  31396. if (newMin < min) {
  31397. correctingValue = _math.pow(10, -digitPosition);
  31398. newMin = utils.applyPrecisionByMinDelta(newMin, correctingValue, newMin + correctingValue)
  31399. }
  31400. if (newMin > max)
  31401. newMin = min;
  31402. return newMin
  31403. },
  31404. _getTickManagerData: function() {
  31405. var that = this,
  31406. options = that._options,
  31407. screenDelta = that._getScreenDelta(),
  31408. min = that._minBound,
  31409. max = that._maxBound,
  31410. categories = that._translator.getVisibleCategories() || that._translator.getBusinessRange().categories,
  31411. customTicks = $.isArray(categories) ? categories : that._majorTicks && constants.convertTicksToValues(that._majorTicks),
  31412. customMinorTicks = that._minorTicks && constants.convertTicksToValues(that._minorTicks);
  31413. if (_isNumber(min) && options.type !== constants.logarithmic)
  31414. min = that._correctMinForTicks(min, max, screenDelta);
  31415. return {
  31416. min: min,
  31417. max: max,
  31418. customTicks: customTicks,
  31419. customMinorTicks: customMinorTicks,
  31420. screenDelta: screenDelta
  31421. }
  31422. },
  31423. _getTickManagerTypes: function() {
  31424. return {
  31425. axisType: this._options.type,
  31426. dataType: this._options.dataType
  31427. }
  31428. },
  31429. _createTickManager: function() {
  31430. return DX.viz.core.CoreFactory.createTickManager({}, {}, {overlappingBehaviorType: this._overlappingBehaviorType})
  31431. },
  31432. _getMarginsOptions: function() {
  31433. var range = this._translator.getBusinessRange();
  31434. return {
  31435. stick: range.stick,
  31436. minStickValue: range.minStickValue,
  31437. maxStickValue: range.maxStickValue,
  31438. percentStick: range.percentStick,
  31439. minValueMargin: this._options.minValueMargin,
  31440. maxValueMargin: this._options.maxValueMargin,
  31441. minSpaceCorrection: range.minSpaceCorrection,
  31442. maxSpaceCorrection: range.maxSpaceCorrection
  31443. }
  31444. },
  31445. _updateTickManager: function() {
  31446. var overlappingOptions = this._getOverlappingBehaviorOptions(),
  31447. options;
  31448. options = _extend(true, {}, this._getMarginsOptions(), overlappingOptions, this._getTicksOptions());
  31449. this._tickManager.update(this._getTickManagerTypes(), this._getTickManagerData(), options)
  31450. },
  31451. _correctLabelAlignment: function() {
  31452. var that = this,
  31453. labelOptions = that._options.label,
  31454. overlappingBehavior = that._tickManager.getOverlappingBehavior();
  31455. if (overlappingBehavior && overlappingBehavior.mode === "rotate") {
  31456. that._textOptions.rotate = overlappingBehavior.rotationAngle;
  31457. if (!labelOptions.userAlignment)
  31458. that._textOptions.align = constants.left
  31459. }
  31460. else if (!labelOptions.userAlignment)
  31461. that._textOptions.align = labelOptions.alignment
  31462. },
  31463. _correctLabelFormat: function() {
  31464. this._options.label = this._tickManager.getOptions().labelOptions
  31465. },
  31466. getTicksValues: function() {
  31467. return {
  31468. majorTicksValues: constants.convertTicksToValues(this._majorTicks || this.getMajorTicks()),
  31469. minorTicksValues: constants.convertTicksToValues(this._minorTicks || this.getMinorTicks())
  31470. }
  31471. },
  31472. getMajorTicks: function(withoutOverlappingBehavior) {
  31473. var that = this,
  31474. majorTicks;
  31475. that._updateTickManager();
  31476. that._textOptions.rotate = 0;
  31477. majorTicks = constants.convertValuesToTicks(that._tickManager.getTicks(withoutOverlappingBehavior));
  31478. that._correctLabelAlignment();
  31479. that._correctLabelFormat();
  31480. return majorTicks
  31481. },
  31482. getMinorTicks: function() {
  31483. return constants.convertValuesToTicks(this._tickManager.getMinorTicks())
  31484. },
  31485. getDecimatedTicks: function() {
  31486. return constants.convertValuesToTicks(this._tickManager.getDecimatedTicks())
  31487. },
  31488. setTicks: function(ticks) {
  31489. this.resetTicks();
  31490. this._majorTicks = constants.convertValuesToTicks(ticks.majorTicks);
  31491. this._minorTicks = constants.convertValuesToTicks(ticks.minorTicks)
  31492. },
  31493. _deleteLabels: function() {
  31494. this._axisElementsGroup && this._axisElementsGroup.clear()
  31495. },
  31496. _drawTicks: function(ticks) {
  31497. var that = this,
  31498. group = that._axisLineGroup;
  31499. _each(ticks || [], function(_, tick) {
  31500. var coord = that._getTickCoord(tick),
  31501. points;
  31502. if (coord) {
  31503. points = that._isHorizontal ? [coord.x1, coord.y1, coord.x2, coord.y2] : [coord.y1, coord.x1, coord.y2, coord.x2];
  31504. tick.graphic = that._createPathElement(points, tick.tickStyle).append(group);
  31505. coord.angle && that._rotateTick(tick, coord.angle)
  31506. }
  31507. })
  31508. },
  31509. _createPathElement: function(points, attr, oposite) {
  31510. return this._renderer.path(points, "line").attr(attr).sharp(this._getSharpParam(oposite))
  31511. },
  31512. _createAxis: function(options) {
  31513. return this._createAxisElement().attr(options).sharp(this._getSharpParam(true))
  31514. },
  31515. _getTickCoord: function(tick) {
  31516. var coords;
  31517. if (_isDefined(tick.posX) && _isDefined(tick.posY))
  31518. coords = {
  31519. x1: tick.posX,
  31520. y1: tick.posY - constants.halfTickLength,
  31521. x2: tick.posX,
  31522. y2: tick.posY + constants.halfTickLength
  31523. };
  31524. else
  31525. coords = null;
  31526. return coords
  31527. },
  31528. setPercentLabelFormat: function() {
  31529. if (!this._hasLabelFormat)
  31530. this._options.label.format = "percent"
  31531. },
  31532. resetAutoLabelFormat: function() {
  31533. if (!this._hasLabelFormat)
  31534. delete this._options.label.format
  31535. },
  31536. _drawLabels: function() {
  31537. var that = this,
  31538. renderer = that._renderer,
  31539. group = that._axisElementsGroup,
  31540. emptyStrRegExp = /^\s+$/;
  31541. _each(that._majorTicks, function(_, tick) {
  31542. var text = tick.labelText,
  31543. xCoord,
  31544. yCoord;
  31545. if (_isDefined(text) && text !== "" && !emptyStrRegExp.test(text)) {
  31546. xCoord = that._isHorizontal ? tick.labelPos.x : tick.labelPos.y;
  31547. yCoord = that._isHorizontal ? tick.labelPos.y : tick.labelPos.x;
  31548. if (!tick.label)
  31549. tick.label = renderer.text(text, xCoord, yCoord).css(tick.labelFontStyle).attr(tick.labelStyle).append(group);
  31550. else
  31551. tick.label.css(tick.labelFontStyle).attr(tick.labelStyle).attr({
  31552. text: text,
  31553. x: xCoord,
  31554. y: yCoord
  31555. });
  31556. tick.label.data({argument: tick.value})
  31557. }
  31558. })
  31559. },
  31560. getMultipleAxesSpacing: function() {
  31561. return this._options.multipleAxesSpacing || 0
  31562. },
  31563. _drawTitle: _noop,
  31564. _getGridLineDrawer: function(borderOptions) {
  31565. var that = this,
  31566. translator = that._translator,
  31567. additionalTranslator = that._additionalTranslator,
  31568. isHorizontal = that._isHorizontal,
  31569. canvasStart = isHorizontal ? constants.left : constants.top,
  31570. canvasEnd = isHorizontal ? constants.right : constants.bottom,
  31571. positionFrom = additionalTranslator.translateSpecialCase(constants.canvasPositionStart),
  31572. positionTo = additionalTranslator.translateSpecialCase(constants.canvasPositionEnd),
  31573. firstBorderLinePosition = borderOptions.visible && borderOptions[canvasStart] ? translator.translateSpecialCase(constants.canvasPositionPrefix + canvasStart) : undefined,
  31574. lastBorderLinePosition = borderOptions.visible && borderOptions[canvasEnd] ? translator.translateSpecialCase(constants.canvasPositionPrefix + canvasEnd) : undefined,
  31575. getPoints = isHorizontal ? function(tick) {
  31576. return tick.posX !== null ? [tick.posX, positionFrom, tick.posX, positionTo] : null
  31577. } : function(tick) {
  31578. return tick.posX !== null ? [positionFrom, tick.posX, positionTo, tick.posX] : null
  31579. };
  31580. return function(tick) {
  31581. var points;
  31582. if (_abs(tick.posX - firstBorderLinePosition) < MAX_GRID_BORDER_ADHENSION || _abs(tick.posX - lastBorderLinePosition) < MAX_GRID_BORDER_ADHENSION)
  31583. return;
  31584. points = getPoints(tick);
  31585. return points && that._createPathElement(points, tick.gridStyle)
  31586. }
  31587. },
  31588. _drawGrids: function(ticks, borderOptions) {
  31589. var that = this,
  31590. group = that._axisGridGroup,
  31591. drawLine = that._getGridLineDrawer(borderOptions || {visible: false});
  31592. _each(ticks || [], function(_, tick) {
  31593. tick.grid = drawLine(tick);
  31594. tick.grid && tick.grid.append(group)
  31595. })
  31596. },
  31597. _getConstantLinePos: function(lineValue, canvasStart, canvasEnd) {
  31598. var parsedValue = this._validateUnit(lineValue, "E2105", "constantLine"),
  31599. value = this._getTranslatedCoord(parsedValue);
  31600. if (!_isDefined(value) || value < _math.min(canvasStart, canvasEnd) || value > _math.max(canvasStart, canvasEnd))
  31601. return {};
  31602. return {
  31603. value: value,
  31604. parsedValue: parsedValue
  31605. }
  31606. },
  31607. _createConstantLine: function(value, attr) {
  31608. var that = this,
  31609. additionalTranslator = this._additionalTranslator,
  31610. positionFrom = additionalTranslator.translateSpecialCase(constants.canvasPositionStart),
  31611. positionTo = additionalTranslator.translateSpecialCase(constants.canvasPositionEnd),
  31612. points = this._isHorizontal ? [value, positionTo, value, positionFrom] : [positionFrom, value, positionTo, value];
  31613. return that._createPathElement(points, attr)
  31614. },
  31615. _drawConstantLinesAndLabels: function(lineOptions, canvasStart, canvasEnd) {
  31616. if (!_isDefined(lineOptions.value))
  31617. return;
  31618. var that = this,
  31619. pos = that._getConstantLinePos(lineOptions.value, canvasStart, canvasEnd),
  31620. labelOptions = lineOptions.label || {},
  31621. value = pos.value,
  31622. attr = {
  31623. stroke: lineOptions.color,
  31624. "stroke-width": lineOptions.width,
  31625. dashStyle: lineOptions.dashStyle
  31626. };
  31627. if (!_isDefined(value)) {
  31628. that._constantLines.push(null);
  31629. if (labelOptions.visible)
  31630. that._constantLineLabels.push(null);
  31631. return
  31632. }
  31633. that._constantLines.push(that._createConstantLine(value, attr).append(that._axisConstantLineGroup));
  31634. that._constantLineLabels.push(labelOptions.visible ? that._drawConstantLineLabels(pos.parsedValue, labelOptions, value) : null)
  31635. },
  31636. _drawConstantLine: function() {
  31637. var that = this,
  31638. options = that._options,
  31639. data = options.constantLines,
  31640. canvas = that._getCanvasStartEnd();
  31641. if (that._translator.getBusinessRange().stubData)
  31642. return;
  31643. that._constantLines = [];
  31644. that._constantLineLabels = [];
  31645. _each(data, function(_, dataItem) {
  31646. that._drawConstantLinesAndLabels(dataItem, canvas.start, canvas.end)
  31647. })
  31648. },
  31649. _drawConstantLineLabels: function(parsedValue, lineLabelOptions, value) {
  31650. var that = this,
  31651. text = lineLabelOptions.text,
  31652. options = that._options,
  31653. labelOptions = options.label,
  31654. coords;
  31655. that._checkAlignmentConstantLineLabels(lineLabelOptions);
  31656. text = _isDefined(text) ? text : constants.formatLabel(parsedValue, labelOptions);
  31657. coords = that._getConstantLineLabelsCoords(value, lineLabelOptions);
  31658. return that._renderer.text(text, coords.x, coords.y).css(core.utils.patchFontOptions(_extend({}, labelOptions.font, lineLabelOptions.font))).attr({align: coords.align}).append(that._axisConstantLineGroup)
  31659. },
  31660. _adjustConstantLineLabels: _noop,
  31661. _getStripPos: function(startValue, endValue, canvasStart, canvasEnd, range) {
  31662. var isContinous = !!(range.minVisible || range.maxVisible),
  31663. categories = range.categories || [],
  31664. start,
  31665. end,
  31666. firstValue = startValue,
  31667. lastValue = endValue,
  31668. startCategoryIndex,
  31669. endCategoryIndex,
  31670. min = range.minVisible;
  31671. if (!isContinous) {
  31672. startCategoryIndex = $.inArray(startValue, categories);
  31673. endCategoryIndex = $.inArray(endValue, categories);
  31674. if (startCategoryIndex === -1 || endCategoryIndex === -1)
  31675. return {
  31676. stripFrom: 0,
  31677. stripTo: 0
  31678. };
  31679. if (startCategoryIndex > endCategoryIndex) {
  31680. firstValue = endValue;
  31681. lastValue = startValue
  31682. }
  31683. }
  31684. start = this._getTranslatedCoord(this._validateUnit(firstValue, "E2105", "strip"), -1);
  31685. end = this._getTranslatedCoord(this._validateUnit(lastValue, "E2105", "strip"), 1);
  31686. if (!_isDefined(start) && isContinous)
  31687. start = startValue < min ? canvasStart : canvasEnd;
  31688. if (!_isDefined(end) && isContinous)
  31689. end = endValue < min ? canvasStart : canvasEnd;
  31690. return start < end ? {
  31691. stripFrom: start,
  31692. stripTo: end
  31693. } : {
  31694. stripFrom: end,
  31695. stripTo: start
  31696. }
  31697. },
  31698. _createStrip: function(fromPoint, toPoint, attr) {
  31699. var x,
  31700. y,
  31701. width,
  31702. height,
  31703. additionalTranslator = this._additionalTranslator,
  31704. positionFrom = additionalTranslator.translateSpecialCase(constants.canvasPositionStart),
  31705. positionTo = additionalTranslator.translateSpecialCase(constants.canvasPositionEnd);
  31706. if (this._isHorizontal) {
  31707. x = fromPoint;
  31708. y = _math.min(positionFrom, positionTo);
  31709. width = toPoint - fromPoint;
  31710. height = _abs(positionFrom - positionTo)
  31711. }
  31712. else {
  31713. x = _math.min(positionFrom, positionTo);
  31714. y = fromPoint;
  31715. width = _abs(positionFrom - positionTo);
  31716. height = _abs(fromPoint - toPoint)
  31717. }
  31718. return this._renderer.rect(x, y, width, height).attr(attr)
  31719. },
  31720. _drawStrip: function() {
  31721. var that = this,
  31722. options = that._options,
  31723. stripData = options.strips,
  31724. canvas = this._getCanvasStartEnd(),
  31725. i,
  31726. stripOptions,
  31727. stripPos,
  31728. stripLabelOptions,
  31729. attr,
  31730. range = that._translator.getBusinessRange();
  31731. if (range.stubData)
  31732. return;
  31733. that._strips = [];
  31734. that._stripLabels = [];
  31735. for (i = 0; i < stripData.length; i++) {
  31736. stripOptions = stripData[i];
  31737. stripLabelOptions = stripOptions.label || {};
  31738. attr = {fill: stripOptions.color};
  31739. if (_isDefined(stripOptions.startValue) && _isDefined(stripOptions.endValue) && _isDefined(stripOptions.color)) {
  31740. stripPos = that._getStripPos(stripOptions.startValue, stripOptions.endValue, canvas.start, canvas.end, range);
  31741. if (stripPos.stripTo - stripPos.stripFrom === 0 || !_isDefined(stripPos.stripTo) || !_isDefined(stripPos.stripFrom)) {
  31742. that._strips.push(null);
  31743. if (stripLabelOptions.text)
  31744. that._stripLabels.push(null);
  31745. continue
  31746. }
  31747. that._strips.push(that._createStrip(stripPos.stripFrom, stripPos.stripTo, attr).append(that._axisStripGroup));
  31748. that._stripLabels.push(stripLabelOptions.text ? that._drawStripLabel(stripLabelOptions, stripPos.stripFrom, stripPos.stripTo) : null)
  31749. }
  31750. }
  31751. },
  31752. _drawStripLabel: function(stripLabelOptions, stripFrom, stripTo) {
  31753. var that = this,
  31754. options = that._options,
  31755. coords = that._getStripLabelCoords(stripLabelOptions, stripFrom, stripTo);
  31756. return that._renderer.text(stripLabelOptions.text, coords.x, coords.y).css(core.utils.patchFontOptions(_extend({}, options.label.font, stripLabelOptions.font))).attr({align: coords.align}).append(that._axisLabelGroup)
  31757. },
  31758. _adjustStripLabels: function() {
  31759. var that = this,
  31760. labels = that._stripLabels,
  31761. rects = that._strips,
  31762. i,
  31763. coords;
  31764. if (labels === undefined && rects === undefined)
  31765. return;
  31766. for (i = 0; i < labels.length; i++)
  31767. if (labels[i] !== null) {
  31768. coords = that._getAdjustedStripLabelCoords(that._options.strips[i], labels[i], rects[i]);
  31769. labels[i].move(coords.x, coords.y)
  31770. }
  31771. },
  31772. _initAxisPositions: _noop,
  31773. _adjustLabels: function() {
  31774. var that = this,
  31775. options = that._options,
  31776. majorTicks = that._majorTicks,
  31777. majorTicksLength = majorTicks.length,
  31778. isHorizontal = that._isHorizontal,
  31779. overlappingBehavior = that._tickManager ? that._tickManager.getOverlappingBehavior() : options.label.overlappingBehavior,
  31780. position = options.position,
  31781. label,
  31782. labelHeight,
  31783. isNeedLabelAdjustment,
  31784. staggeringSpacing,
  31785. i,
  31786. box,
  31787. hasLabels = false,
  31788. boxAxis = that._axisElementsGroup && that._axisElementsGroup.getBBox() || {};
  31789. _each(majorTicks, function(_, tick) {
  31790. if (tick.label) {
  31791. tick.label.attr(that._getLabelAdjustedCoord(tick, boxAxis));
  31792. hasLabels = true
  31793. }
  31794. });
  31795. isNeedLabelAdjustment = hasLabels && isHorizontal && overlappingBehavior && overlappingBehavior.mode === "stagger";
  31796. if (isNeedLabelAdjustment) {
  31797. labelHeight = 0;
  31798. for (i = 0; i < majorTicksLength; i = i + 2) {
  31799. label = majorTicks[i].label;
  31800. box = label && label.getBBox() || {};
  31801. if (box.height > labelHeight)
  31802. labelHeight = box.height
  31803. }
  31804. staggeringSpacing = overlappingBehavior.staggeringSpacing;
  31805. labelHeight = _round(labelHeight) + staggeringSpacing;
  31806. for (i = 1; i < majorTicksLength; i = i + 2) {
  31807. label = majorTicks[i].label;
  31808. if (label)
  31809. if (position === constants.bottom)
  31810. label.move(0, labelHeight);
  31811. else if (position === constants.top)
  31812. label.move(0, -labelHeight)
  31813. }
  31814. for (i = 0; i < majorTicksLength; i++)
  31815. majorTicks[i].label && majorTicks[i].label.rotate(0)
  31816. }
  31817. },
  31818. _getLabelAdjustedCoord: function(tick, boxAxis) {
  31819. var that = this,
  31820. options = that._options,
  31821. box = tick.label.getBBox(),
  31822. x,
  31823. y,
  31824. isHorizontal = that._isHorizontal,
  31825. position = options.position,
  31826. shift = that.padding && that.padding[position] || 0,
  31827. textOptions = that._textOptions,
  31828. labelSettingsY = tick.label.attr("y");
  31829. if (isHorizontal && position === constants.bottom)
  31830. y = 2 * labelSettingsY - box.y + shift;
  31831. else if (!isHorizontal) {
  31832. if (position === constants.left)
  31833. if (textOptions.align === constants.right)
  31834. x = box.x + box.width - shift;
  31835. else if (textOptions.align === constants.center)
  31836. x = box.x + box.width / 2 - shift - (boxAxis.width / 2 || 0);
  31837. else
  31838. x = box.x - shift - (boxAxis.width || 0);
  31839. else if (textOptions.align === constants.center)
  31840. x = box.x + box.width / 2 + (boxAxis.width / 2 || 0) + shift;
  31841. else if (textOptions.align === constants.right)
  31842. x = box.x + box.width + (boxAxis.width || 0) + shift;
  31843. else
  31844. x = box.x + shift;
  31845. y = labelSettingsY + ~~(labelSettingsY - box.y - box.height / 2)
  31846. }
  31847. else if (isHorizontal && position === constants.top)
  31848. y = 2 * labelSettingsY - box.y - box.height - shift;
  31849. return {
  31850. x: x,
  31851. y: y
  31852. }
  31853. },
  31854. _adjustTitle: _noop,
  31855. _createAxisGroups: function() {
  31856. var that = this,
  31857. renderer = that._renderer,
  31858. classSelector = WIDGET_CLASS + "-" + that._axisClass + "-";
  31859. that._axisGroup = renderer.g().attr({"class": classSelector + "axis"});
  31860. that._axisStripGroup = renderer.g().attr({"class": classSelector + "strips"});
  31861. that._axisGridGroup = renderer.g().attr({"class": classSelector + "grid"});
  31862. that._axisElementsGroup = renderer.g().attr({"class": classSelector + "elements"}).append(that._axisGroup);
  31863. that._axisLineGroup = renderer.g().attr({"class": classSelector + "line"}).append(that._axisGroup);
  31864. that._axisTitleGroup = renderer.g().attr({"class": classSelector + "title"}).append(that._axisGroup);
  31865. that._axisConstantLineGroup = renderer.g().attr({"class": classSelector + "constant-lines"});
  31866. that._axisLabelGroup = renderer.g().attr({"class": classSelector + "axis-labels"})
  31867. },
  31868. _clearAxisGroups: function(adjustAxis) {
  31869. var that = this,
  31870. classSelector = WIDGET_CLASS + "-" + that._axisClass + "-";
  31871. that._axisGroup.remove();
  31872. that._axisStripGroup.remove();
  31873. that._axisLabelGroup.remove();
  31874. that._axisConstantLineGroup.remove();
  31875. that._axisGridGroup.remove();
  31876. if (that._axisTitleGroup)
  31877. that._axisTitleGroup.clear();
  31878. else if (!adjustAxis)
  31879. that._axisTitleGroup = that._renderer.g().attr({"class": classSelector + "title"}).append(that._axisGroup);
  31880. if (that._axisElementsGroup)
  31881. that._axisElementsGroup.clear();
  31882. else if (!adjustAxis)
  31883. that._axisElementsGroup = that._renderer.g().attr({"class": classSelector + "elements"}).append(that._axisGroup);
  31884. that._axisLineGroup.clear();
  31885. that._axisStripGroup.clear();
  31886. that._axisGridGroup.clear();
  31887. that._axisConstantLineGroup.clear();
  31888. that._axisLabelGroup.clear()
  31889. },
  31890. _initTicks: function(ticks, tickOptions, gridOptions, withLabels) {
  31891. var that = this,
  31892. options = that._options,
  31893. tickStyle = {
  31894. stroke: tickOptions.color,
  31895. "stroke-width": 1,
  31896. "stroke-opacity": tickOptions.opacity
  31897. },
  31898. gridStyle = {
  31899. stroke: gridOptions.color,
  31900. "stroke-width": gridOptions.width,
  31901. "stroke-opacity": gridOptions.opacity
  31902. },
  31903. currentLabelConst = that.getCurrentLabelPos(),
  31904. categoryToSkip = that._getSkippedCategory();
  31905. _each(ticks || [], function(_, tick) {
  31906. var coord;
  31907. if (!(categoryToSkip && categoryToSkip === tick.value)) {
  31908. coord = that._getTranslatedValue(tick.value, that._axisPosition, that._tickOffset);
  31909. tick.posX = coord.x;
  31910. tick.posY = coord.y;
  31911. tick.angle = coord.angle
  31912. }
  31913. tick.tickStyle = tickStyle;
  31914. tick.gridStyle = gridStyle;
  31915. if (withLabels) {
  31916. tick.labelText = constants.formatLabel(tick.value, options.label, {
  31917. min: that._minBound,
  31918. max: that._maxBound
  31919. });
  31920. tick.labelPos = that._getTranslatedValue(tick.value, currentLabelConst);
  31921. tick.labelStyle = that._textOptions;
  31922. tick.labelFontStyle = that._textFontStyles;
  31923. tick.labelHint = constants.formatHint(tick.value, options.label, {
  31924. min: that._minBound,
  31925. max: that._maxBound
  31926. })
  31927. }
  31928. })
  31929. },
  31930. _setTickOffset: function() {
  31931. var options = this._options,
  31932. discreteAxisDivisionMode = options.discreteAxisDivisionMode;
  31933. this._tickOffset = +(discreteAxisDivisionMode !== "crossLabels" || !discreteAxisDivisionMode)
  31934. },
  31935. drawGrids: function(borderOptions) {
  31936. var that = this,
  31937. options = that._options;
  31938. borderOptions = borderOptions || {};
  31939. that._axisGridGroup.append(that._gridContainerGroup);
  31940. if (options.grid.visible)
  31941. that._drawGrids(that._majorTicks.concat(that._decimatedTicks), borderOptions);
  31942. options.minorGrid.visible && that._drawGrids(that._minorTicks, borderOptions)
  31943. },
  31944. draw: function(adjustAxis) {
  31945. var that = this,
  31946. options = that._options,
  31947. areLabelsVisible;
  31948. if (that._axisGroup)
  31949. that._clearAxisGroups(adjustAxis);
  31950. areLabelsVisible = options.label.visible && that._axisElementsGroup && !that._translator.getBusinessRange().stubData;
  31951. that._updateTranslatorInterval();
  31952. that._initAxisPositions();
  31953. that._initTicks(that._majorTicks, options.tick, options.grid, areLabelsVisible);
  31954. that._initTicks(that._decimatedTicks, options.tick, options.grid, false);
  31955. that._initTicks(that._minorTicks, options.minorTick, options.minorGrid);
  31956. if (!that._virtual) {
  31957. options.visible && that._drawAxis();
  31958. if (options.tick.visible) {
  31959. that._drawTicks(that._majorTicks);
  31960. that._drawTicks(that._decimatedTicks)
  31961. }
  31962. options.minorTick.visible && that._drawTicks(that._minorTicks);
  31963. areLabelsVisible && that._drawLabels();
  31964. that._drawTitle()
  31965. }
  31966. options.strips && that._drawStrip();
  31967. options.constantLines && that._drawConstantLine();
  31968. that._axisStripGroup.append(that._stripsGroup);
  31969. that._axisConstantLineGroup.append(that._constantLinesGroup);
  31970. that._axisGroup.append(that._axesContainerGroup);
  31971. that._axisLabelGroup.append(that._labelAxesGroup);
  31972. that._adjustConstantLineLabels();
  31973. areLabelsVisible && that._adjustLabels();
  31974. that._createHints();
  31975. that._adjustStripLabels();
  31976. that._adjustTitle();
  31977. that._setBoundingRect()
  31978. },
  31979. _createHints: function() {
  31980. var that = this;
  31981. _each(that._majorTicks || [], function(_, tick) {
  31982. var labelHint = tick.labelHint;
  31983. if (_isDefined(labelHint) && labelHint !== "")
  31984. tick.label.setTitle(labelHint)
  31985. })
  31986. },
  31987. _setBoundingRect: function() {
  31988. var that = this,
  31989. options = that._options,
  31990. axisBox = that._axisElementsGroup ? that._axisElementsGroup.getBBox() : {
  31991. x: 0,
  31992. y: 0,
  31993. width: 0,
  31994. height: 0,
  31995. isEmpty: true
  31996. },
  31997. lineBox = that._axisLineGroup.getBBox(),
  31998. placeholderSize = options.placeholderSize,
  31999. start,
  32000. isHorizontal = that._isHorizontal,
  32001. coord = isHorizontal ? "y" : "x",
  32002. side = isHorizontal ? "height" : "width",
  32003. shiftCoords = options.crosshairEnabled ? isHorizontal ? LABEL_BACKGROUND_PADDING_Y : LABEL_BACKGROUND_PADDING_X : 0,
  32004. axisTitleBox = that._title && that._axisTitleGroup ? that._axisTitleGroup.getBBox() : axisBox;
  32005. if (axisBox.isEmpty && axisTitleBox.isEmpty && !placeholderSize) {
  32006. that.boundingRect = axisBox;
  32007. return
  32008. }
  32009. start = lineBox[coord] || that._axisPosition;
  32010. if (options.position === (isHorizontal && constants.bottom || constants.right)) {
  32011. axisBox[side] = placeholderSize || axisTitleBox[coord] + axisTitleBox[side] - start + shiftCoords;
  32012. axisBox[coord] = start
  32013. }
  32014. else {
  32015. axisBox[side] = placeholderSize || lineBox[side] + start - axisTitleBox[coord] + shiftCoords;
  32016. axisBox[coord] = axisTitleBox.isEmpty ? start : axisTitleBox[coord] - shiftCoords
  32017. }
  32018. that.boundingRect = axisBox
  32019. },
  32020. getBoundingRect: function() {
  32021. return this._axisElementsGroup ? this.boundingRect : {
  32022. x: 0,
  32023. y: 0,
  32024. width: 0,
  32025. height: 0
  32026. }
  32027. },
  32028. shift: function(x, y) {
  32029. var settings = {};
  32030. if (x)
  32031. settings.translateX = x;
  32032. if (y)
  32033. settings.translateY = y;
  32034. this._axisGroup.attr(settings)
  32035. },
  32036. applyClipRects: function(elementsClipID, canvasClipID) {
  32037. this._axisGroup.attr({clipId: canvasClipID});
  32038. this._axisStripGroup.attr({clipId: elementsClipID})
  32039. },
  32040. validate: function(isArgumentAxis) {
  32041. var that = this,
  32042. options = that._options,
  32043. parseUtils = new core.ParseUtils,
  32044. dataType = isArgumentAxis ? options.argumentType : options.valueType,
  32045. parser = dataType ? parseUtils.getParser(dataType, "axis") : function(unit) {
  32046. return unit
  32047. };
  32048. that.parser = parser;
  32049. options.dataType = dataType;
  32050. if (options.min !== undefined)
  32051. options.min = that._validateUnit(options.min, "E2106");
  32052. if (options.max !== undefined)
  32053. options.max = that._validateUnit(options.max, "E2106");
  32054. if (that._minBound !== undefined)
  32055. that._minBound = that._validateUnit(that._minBound);
  32056. if (that._maxBound !== undefined)
  32057. that._maxBound = that._validateUnit(that._maxBound)
  32058. },
  32059. _validateUnit: function(unit, idError, parameters) {
  32060. var that = this;
  32061. unit = that.parser(unit);
  32062. if (unit === undefined && idError)
  32063. that._incidentOccured(idError, [parameters]);
  32064. return unit
  32065. },
  32066. zoom: function(min, max, skipAdjusting) {
  32067. var that = this,
  32068. minOpt = that._options.min,
  32069. maxOpt = that._options.max;
  32070. skipAdjusting = skipAdjusting || that._options.type === constants.discrete;
  32071. min = that._validateUnit(min);
  32072. max = that._validateUnit(max);
  32073. if (!skipAdjusting) {
  32074. if (minOpt !== undefined) {
  32075. min = minOpt > min ? minOpt : min;
  32076. max = minOpt > max ? minOpt : max
  32077. }
  32078. if (maxOpt !== undefined) {
  32079. max = maxOpt < max ? maxOpt : max;
  32080. min = maxOpt < min ? maxOpt : min
  32081. }
  32082. }
  32083. that._zoomArgs = {
  32084. min: min,
  32085. max: max
  32086. };
  32087. return that._zoomArgs
  32088. },
  32089. resetZoom: function() {
  32090. this._zoomArgs = null
  32091. },
  32092. getRangeData: function() {
  32093. var that = this,
  32094. options = that._options,
  32095. minMax = that._getMinMax(),
  32096. min = minMax.min,
  32097. max = minMax.max,
  32098. zoomArgs = that._zoomArgs || {},
  32099. type = options.type,
  32100. rangeMin,
  32101. rangeMax,
  32102. rangeMinVisible,
  32103. rangeMaxVisible;
  32104. if (type === constants.logarithmic) {
  32105. min = min <= 0 ? undefined : min;
  32106. max = max <= 0 ? undefined : max
  32107. }
  32108. if (type !== constants.discrete) {
  32109. rangeMin = min;
  32110. rangeMax = max;
  32111. if (_isDefined(min) && _isDefined(max)) {
  32112. rangeMin = min < max ? min : max;
  32113. rangeMax = max > min ? max : min
  32114. }
  32115. rangeMinVisible = _isDefined(zoomArgs.min) ? zoomArgs.min : rangeMin;
  32116. rangeMaxVisible = _isDefined(zoomArgs.max) ? zoomArgs.max : rangeMax
  32117. }
  32118. else {
  32119. rangeMinVisible = _isDefined(zoomArgs.min) ? zoomArgs.min : min;
  32120. rangeMaxVisible = _isDefined(zoomArgs.max) ? zoomArgs.max : max
  32121. }
  32122. return {
  32123. min: rangeMin,
  32124. max: rangeMax,
  32125. stick: that._getStick(),
  32126. categories: options.categories,
  32127. dataType: options.dataType,
  32128. axisType: type,
  32129. base: options.logarithmBase,
  32130. invert: options.inverted,
  32131. addSpiderCategory: that._getSpiderCategoryOption(),
  32132. minVisible: rangeMinVisible,
  32133. maxVisible: rangeMaxVisible
  32134. }
  32135. },
  32136. _setType: function(axesType, drawingType) {
  32137. var that = this;
  32138. _each(DX.viz.charts.axes[axesType][drawingType], function(methodName, method) {
  32139. that[methodName] = method
  32140. })
  32141. },
  32142. _getSharpParam: function() {
  32143. return true
  32144. },
  32145. getSpiderTicks: _noop,
  32146. setSpiderTicks: _noop,
  32147. measureLabels: _noop,
  32148. coordsIn: _noop,
  32149. _getSkippedCategory: _noop
  32150. }
  32151. })(jQuery, DevExpress);
  32152. /*! Module viz-charts, file scrollBar.js */
  32153. (function($, DX, math) {
  32154. var MIN_SCROLL_BAR_SIZE = 2,
  32155. isDefined = DX.utils.isDefined,
  32156. _min = math.min,
  32157. _max = math.max;
  32158. DX.viz.charts.ScrollBar = function(renderer, group) {
  32159. this._translator = DX.viz.core.CoreFactory.createTranslator2D({}, {}, {});
  32160. this._scroll = renderer.rect().append(group);
  32161. this._addEvents()
  32162. };
  32163. function _getXCoord(canvas, pos, offset, width) {
  32164. var x = 0;
  32165. if (pos === "right")
  32166. x = canvas.width - canvas.right + offset;
  32167. else if (pos === "left")
  32168. x = canvas.left - offset - width;
  32169. return x
  32170. }
  32171. function _getYCoord(canvas, pos, offset, width) {
  32172. var y = 0;
  32173. if (pos === "top")
  32174. y = canvas.top - offset;
  32175. else if (pos === "bottom")
  32176. y = canvas.height - canvas.bottom + width + offset;
  32177. return y
  32178. }
  32179. DX.viz.charts.ScrollBar.prototype = {
  32180. _addEvents: function() {
  32181. var that = this,
  32182. $scroll = $(that._scroll.element),
  32183. startPosX = 0,
  32184. startPosY = 0,
  32185. scrollChangeHandler = function(e) {
  32186. var dX = (startPosX - e.pageX) * that._scale,
  32187. dY = (startPosY - e.pageY) * that._scale;
  32188. $scroll.trigger(new $.Event("dxc-scroll-move", $.extend(e, {
  32189. type: "dxc-scroll-move",
  32190. pointers: [{
  32191. pageX: startPosX + dX,
  32192. pageY: startPosY + dY
  32193. }]
  32194. })))
  32195. };
  32196. $scroll.on("dxpointerdown", function(e) {
  32197. startPosX = e.pageX;
  32198. startPosY = e.pageY;
  32199. $scroll.trigger(new $.Event("dxc-scroll-start", {pointers: [{
  32200. pageX: startPosX,
  32201. pageY: startPosY
  32202. }]}));
  32203. $(document).on("dxpointermove", scrollChangeHandler)
  32204. });
  32205. $(document).on("dxpointerup", function() {
  32206. $(document).off("dxpointermove", scrollChangeHandler)
  32207. })
  32208. },
  32209. update: function(options) {
  32210. var that = this,
  32211. position = options.position,
  32212. isVertical = options.rotated,
  32213. defaultPosition = isVertical ? "right" : "top",
  32214. secondaryPosition = isVertical ? "left" : "bottom";
  32215. if (position !== defaultPosition && position !== secondaryPosition)
  32216. position = defaultPosition;
  32217. that._scroll.attr({
  32218. rotate: !options.rotated ? -90 : 0,
  32219. rotateX: 0,
  32220. rotateY: 0,
  32221. fill: options.color,
  32222. width: options.width,
  32223. opacity: options.opacity
  32224. });
  32225. that._layoutOptions = {
  32226. width: options.width,
  32227. offset: options.offset,
  32228. vertical: isVertical,
  32229. position: position
  32230. };
  32231. return that
  32232. },
  32233. init: function(range, canvas) {
  32234. var that = this;
  32235. that._translateWithOffset = range.axisType === "discrete" && !range.stick && 1 || 0;
  32236. that._translator.update($.extend({}, range, {
  32237. minVisible: null,
  32238. maxVisible: null,
  32239. visibleCategories: null
  32240. }), $.extend({}, canvas), {direction: that._layoutOptions.vertical ? "vertical" : "horizontal"});
  32241. return that
  32242. },
  32243. getOptions: function() {
  32244. return this._layoutOptions
  32245. },
  32246. shift: function(x, y) {
  32247. this._scroll.attr({
  32248. translateX: x,
  32249. translateY: y
  32250. })
  32251. },
  32252. setPane: function(panes) {
  32253. var position = this._layoutOptions.position,
  32254. pane;
  32255. if (position === "left" || position === "top")
  32256. pane = panes[0];
  32257. else
  32258. pane = panes[panes.length - 1];
  32259. this.pane = pane.name;
  32260. this._canvas = pane.canvas;
  32261. return this
  32262. },
  32263. getMultipleAxesSpacing: function() {
  32264. return 0
  32265. },
  32266. getBoundingRect: function() {
  32267. var options = this._layoutOptions,
  32268. isVertical = options.vertical,
  32269. offset = options.offset,
  32270. width = options.width,
  32271. pos = options.position,
  32272. size = width + offset,
  32273. canvas = this._canvas;
  32274. return isVertical ? {
  32275. x: _getXCoord(canvas, pos, offset, width),
  32276. y: canvas.top,
  32277. width: size,
  32278. height: canvas.height - canvas.top - canvas.bottom
  32279. } : {
  32280. x: canvas.left,
  32281. y: _getYCoord(canvas, pos, offset, width),
  32282. width: canvas.width - canvas.left - canvas.right,
  32283. height: size
  32284. }
  32285. },
  32286. applyLayout: function() {
  32287. var canvas = this._canvas,
  32288. options = this._layoutOptions,
  32289. pos = options.position,
  32290. offset = options.offset,
  32291. width = options.width;
  32292. this.shift(_getXCoord(canvas, pos, offset, width), _getYCoord(canvas, pos, offset, width))
  32293. },
  32294. setPosition: function(min, max) {
  32295. var that = this,
  32296. translator = that._translator,
  32297. minPoint = isDefined(min) ? translator.translate(min, -that._translateWithOffset) : translator.translate("canvas_position_start"),
  32298. maxPoint = isDefined(max) ? translator.translate(max, that._translateWithOffset) : translator.translate("canvas_position_end");
  32299. that._offset = _min(minPoint, maxPoint);
  32300. that._scale = translator.getScale(min, max);
  32301. that._applyPosition(_min(minPoint, maxPoint), _max(minPoint, maxPoint))
  32302. },
  32303. transform: function(translate, scale) {
  32304. var x = this._translator.getCanvasVisibleArea().min,
  32305. dx = x - (x * scale - translate),
  32306. lx = this._offset + dx / (this._scale * scale);
  32307. this._applyPosition(lx, lx + this._translator.canvasLength / (this._scale * scale))
  32308. },
  32309. dispose: function() {
  32310. this._scroll.dispose();
  32311. this._scroll = this._translator = null
  32312. },
  32313. _applyPosition: function(x1, x2) {
  32314. var that = this,
  32315. visibleArea = that._translator.getCanvasVisibleArea(),
  32316. height;
  32317. x1 = _max(x1, visibleArea.min);
  32318. x1 = _min(x1, visibleArea.max);
  32319. x2 = _min(x2, visibleArea.max);
  32320. x2 = _max(x2, visibleArea.min);
  32321. height = math.abs(x2 - x1);
  32322. that._scroll.attr({
  32323. y: x1,
  32324. height: height < MIN_SCROLL_BAR_SIZE ? MIN_SCROLL_BAR_SIZE : height
  32325. })
  32326. }
  32327. }
  32328. })(jQuery, DevExpress, Math);
  32329. /*! Module viz-charts, file baseChart.js */
  32330. (function($, DX, undefined) {
  32331. var ui = DX.ui,
  32332. charts = DX.viz.charts,
  32333. utils = DX.utils,
  32334. ACTIONS_BY_PRIORITY = ['reinit', '_reinitDataSource', '_dataInit', 'force_render', "_resize"],
  32335. core = DX.viz.core,
  32336. _each = $.each,
  32337. _map = $.map,
  32338. _extend = $.extend,
  32339. DEFAULT_ANIMATION_OPTIONS = {asyncSeriesRendering: true},
  32340. _isDefined = utils.isDefined,
  32341. DEFAULT_OPACITY = 0.3;
  32342. function createEventMapObject(name, deprecatedArgs) {
  32343. return {
  32344. name: name,
  32345. deprecated: name,
  32346. deprecatedContext: function(arg) {
  32347. return arg.target
  32348. },
  32349. deprecatedArgs: deprecatedArgs || function(arg) {
  32350. return [arg.target, arg.jQueryEvent]
  32351. }
  32352. }
  32353. }
  32354. function checkHeightLabelsInCanvas(points, canvas, isRotated) {
  32355. var commonLabelSize = 0,
  32356. canvasSize = canvas.end - canvas.start,
  32357. label,
  32358. bbox;
  32359. for (var i = 0; i < points.length; i++) {
  32360. label = points[i].getLabel();
  32361. if (label.isVisible()) {
  32362. bbox = label.getBoundingRect();
  32363. commonLabelSize += isRotated ? bbox.width : bbox.height
  32364. }
  32365. else
  32366. points[i] = null
  32367. }
  32368. if (canvasSize > 0)
  32369. while (commonLabelSize > canvasSize)
  32370. commonLabelSize -= killSmallValues(points, isRotated)
  32371. }
  32372. function killSmallValues(points, isRotated) {
  32373. var smallestValuePoint = {originalValue: Infinity},
  32374. label,
  32375. bbox,
  32376. indexOfPoint;
  32377. _each(points, function(index, point) {
  32378. if (point && smallestValuePoint.originalValue >= point.originalValue) {
  32379. smallestValuePoint = point;
  32380. indexOfPoint = index
  32381. }
  32382. });
  32383. if (indexOfPoint !== null) {
  32384. label = points[indexOfPoint].getLabel();
  32385. bbox = label.getBoundingRect();
  32386. label.hide();
  32387. points[indexOfPoint] = null;
  32388. return isRotated ? bbox.width : bbox.height
  32389. }
  32390. return 0
  32391. }
  32392. function resolveLabelOverlappingInOneDirection(points, canvas, isRotated, shiftFunction) {
  32393. var stubCanvas = {
  32394. start: isRotated ? canvas.left : canvas.top,
  32395. end: isRotated ? canvas.width - canvas.right : canvas.height - canvas.bottom
  32396. };
  32397. checkHeightLabelsInCanvas(points, stubCanvas, isRotated);
  32398. var rollingStocks = $.map(points, function(point) {
  32399. return point && new RollingStock(point, isRotated, shiftFunction)
  32400. });
  32401. rollingStocks.sort(function(a, b) {
  32402. return a.getPointPosition() - b.getPointPosition()
  32403. });
  32404. if (!checkStackOverlap(rollingStocks))
  32405. return;
  32406. rollingStocks.reverse();
  32407. moveRollingStock(rollingStocks, stubCanvas)
  32408. }
  32409. function overlapRollingStock(firstRolling, secondRolling) {
  32410. if (!firstRolling || !secondRolling)
  32411. return;
  32412. return firstRolling.getBoundingRect().end > secondRolling.getBoundingRect().start
  32413. }
  32414. function checkStackOverlap(rollingStocks) {
  32415. var i,
  32416. j,
  32417. currentRollingStock,
  32418. nextRollingStock,
  32419. overlap;
  32420. for (i = 0; i < rollingStocks.length; i++) {
  32421. currentRollingStock = rollingStocks[i];
  32422. for (j = i + 1; j < rollingStocks.length; j++) {
  32423. nextRollingStock = rollingStocks[j];
  32424. if (overlapRollingStock(currentRollingStock, nextRollingStock)) {
  32425. currentRollingStock.toChain(nextRollingStock);
  32426. overlap = true;
  32427. rollingStocks[j] = null
  32428. }
  32429. }
  32430. }
  32431. return overlap
  32432. }
  32433. function moveRollingStock(rollingStocks, canvas) {
  32434. var i,
  32435. j,
  32436. currentRollingStock,
  32437. nextRollingStock,
  32438. currentBBox,
  32439. nextBBox;
  32440. for (i = 0; i < rollingStocks.length; i++) {
  32441. currentRollingStock = rollingStocks[i];
  32442. if (rollingStocksIsOut(currentRollingStock, canvas)) {
  32443. currentBBox = currentRollingStock.getBoundingRect();
  32444. for (j = i + 1; j < rollingStocks.length; j++) {
  32445. nextRollingStock = rollingStocks[j];
  32446. if (!nextRollingStock)
  32447. continue;
  32448. nextBBox = nextRollingStock.getBoundingRect();
  32449. if (nextBBox.end > currentBBox.start - (currentBBox.end - canvas.end)) {
  32450. nextRollingStock.toChain(currentRollingStock);
  32451. rollingStocks[i] = currentRollingStock = null;
  32452. break
  32453. }
  32454. }
  32455. }
  32456. currentRollingStock && currentRollingStock.setRollingStockInCanvas(canvas)
  32457. }
  32458. }
  32459. function rollingStocksIsOut(rollingStock, canvas) {
  32460. return rollingStock && rollingStock.getBoundingRect().end > canvas.end
  32461. }
  32462. function RollingStock(point, isRotated, shiftFunction) {
  32463. var label = point.getLabel(),
  32464. bbox = label.getBoundingRect();
  32465. this.labels = [label];
  32466. this.points = [point];
  32467. this.shiftFunction = shiftFunction;
  32468. this._bbox = {
  32469. start: isRotated ? bbox.x : bbox.y,
  32470. width: isRotated ? bbox.width : bbox.height,
  32471. end: isRotated ? bbox.x + bbox.width : bbox.y + bbox.height
  32472. };
  32473. this._pointPositionInitialize = isRotated ? point.getBoundaryCoords().x : point.getBoundaryCoords().y;
  32474. return this
  32475. }
  32476. RollingStock.prototype = {
  32477. toChain: function(nextRollingStock) {
  32478. var nextRollingStockBBox = nextRollingStock.getBoundingRect();
  32479. nextRollingStock.shift(nextRollingStockBBox.start - this._bbox.end);
  32480. this._changeBoxWidth(nextRollingStockBBox.width);
  32481. this.labels = this.labels.concat(nextRollingStock.labels);
  32482. this.points = this.points.concat(nextRollingStock.points)
  32483. },
  32484. getBoundingRect: function() {
  32485. return this._bbox
  32486. },
  32487. shift: function(shiftLength) {
  32488. var shiftFunction = this.shiftFunction;
  32489. _each(this.labels, function(index, label) {
  32490. var bbox = label.getBoundingRect(),
  32491. coords = shiftFunction(bbox, shiftLength, label);
  32492. label.shift(coords.x, coords.y)
  32493. });
  32494. this._bbox.end -= shiftLength;
  32495. this._bbox.start -= shiftLength
  32496. },
  32497. setRollingStockInCanvas: function(canvas) {
  32498. if (this._bbox.end > canvas.end)
  32499. this.shift(this._bbox.end - canvas.end)
  32500. },
  32501. getPointPosition: function() {
  32502. return this._pointPositionInitialize
  32503. },
  32504. _changeBoxWidth: function(width) {
  32505. this._bbox.end += width;
  32506. this._bbox.width += width
  32507. }
  32508. };
  32509. function getLegendFields(name) {
  32510. return {
  32511. nameField: name + 'Name',
  32512. colorField: name + 'Color',
  32513. indexField: name + 'Index'
  32514. }
  32515. }
  32516. function getLegendSettings(legendDataField) {
  32517. var formatObjectFields = getLegendFields(legendDataField);
  32518. return {
  32519. getFormatObject: function(data) {
  32520. var res = {};
  32521. res[formatObjectFields.indexField] = data.id;
  32522. res[formatObjectFields.colorField] = data.states.normal.fill;
  32523. res[formatObjectFields.nameField] = data.text;
  32524. return res
  32525. },
  32526. textField: formatObjectFields.nameField
  32527. }
  32528. }
  32529. function checkOverlapping(firstRect, secondRect) {
  32530. return (firstRect.x <= secondRect.x && secondRect.x <= firstRect.x + firstRect.width || firstRect.x >= secondRect.x && firstRect.x <= secondRect.x + secondRect.width) && (firstRect.y <= secondRect.y && secondRect.y <= firstRect.y + firstRect.height || firstRect.y >= secondRect.y && firstRect.y <= secondRect.y + secondRect.height)
  32531. }
  32532. charts.overlapping = {resolveLabelOverlappingInOneDirection: resolveLabelOverlappingInOneDirection};
  32533. charts.BaseChart = core.BaseWidget.inherit({
  32534. _eventsMap: $.extend({}, core.BaseWidget.prototype._eventsMap, {
  32535. onSeriesClick: createEventMapObject("seriesClick"),
  32536. onPointClick: createEventMapObject("pointClick"),
  32537. onArgumentAxisClick: createEventMapObject("argumentAxisClick", function(arg) {
  32538. return [arg.target, arg.argument, arg.jQueryEvent]
  32539. }),
  32540. onLegendClick: createEventMapObject("legendClick"),
  32541. onSeriesSelectionChanged: createEventMapObject('seriesSelectionChanged'),
  32542. onPointSelectionChanged: createEventMapObject('pointSelectionChanged'),
  32543. onSeriesHoverChanged: createEventMapObject('seriesHoverChanged'),
  32544. onPointHoverChanged: createEventMapObject('pointHoverChanged'),
  32545. onTooltipShown: createEventMapObject('tooltipShown'),
  32546. onTooltipHidden: createEventMapObject('tooltipHidden'),
  32547. onDone: createEventMapObject("done"),
  32548. seriesClick: {newName: 'onSeriesClick'},
  32549. pointClick: {newName: 'onPointClick'},
  32550. argumentAxisClick: {newName: 'onArgumentAxisClick'},
  32551. legendClick: {newName: 'onLegendClick'},
  32552. pointHoverChanged: {newName: 'onPointHoverChanged'},
  32553. seriesSelectionChanged: {newName: 'onSeriesSelectionChanged'},
  32554. pointSelectionChanged: {newName: 'onPointSelectionChanged'},
  32555. seriesHoverChanged: {newName: 'onSeriesHoverChanged'},
  32556. tooltipShown: {newName: 'onTooltipShown'},
  32557. tooltipHidden: {newName: 'onTooltipHidden'},
  32558. done: {newName: 'onDone'}
  32559. }),
  32560. _setDeprecatedOptions: function() {
  32561. this.callBase();
  32562. $.extend(this._deprecatedOptions, {
  32563. seriesClick: {
  32564. since: '14.2',
  32565. message: "Use the 'onSeriesClick' option instead"
  32566. },
  32567. pointClick: {
  32568. since: '14.2',
  32569. message: "Use the 'onPointClick' option instead"
  32570. },
  32571. argumentAxisClick: {
  32572. since: '14.2',
  32573. message: "Use the 'onArgumentAxisClick' option instead"
  32574. },
  32575. legendClick: {
  32576. since: '14.2',
  32577. message: "Use the 'onLegendClick' option instead"
  32578. },
  32579. seriesSelectionChanged: {
  32580. since: '14.2',
  32581. message: "Use the 'onSeriesSelectionChanged' option instead"
  32582. },
  32583. pointSelectionChanged: {
  32584. since: '14.2',
  32585. message: "Use the 'onPointSelectionChanged' option instead"
  32586. },
  32587. seriesHoverChanged: {
  32588. since: '14.2',
  32589. message: "Use the 'onSeriesHoverChanged' option instead"
  32590. },
  32591. pointHoverChanged: {
  32592. since: '14.2',
  32593. message: "Use the 'onPointHoverChanged' option instead"
  32594. },
  32595. tooltipShown: {
  32596. since: '14.2',
  32597. message: "Use the 'onTooltipShown' option instead"
  32598. },
  32599. tooltipHidden: {
  32600. since: '14.2',
  32601. message: "Use the 'onTooltipHidden' option instead"
  32602. },
  32603. done: {
  32604. since: '14.2',
  32605. message: "Use the 'onDone' option instead"
  32606. }
  32607. })
  32608. },
  32609. _rootClassPrefix: "dxc",
  32610. _rootClass: "dxc-chart",
  32611. _init: function() {
  32612. var that = this;
  32613. that.callBase.apply(that, arguments);
  32614. that._reinit()
  32615. },
  32616. _createThemeManager: function() {
  32617. var option = this.option(),
  32618. themeManager = charts.factory.createThemeManager(option, this._chartType);
  32619. themeManager.setTheme(option.theme, option.rtlEnabled);
  32620. return themeManager
  32621. },
  32622. _initCore: function() {
  32623. var that = this;
  32624. that._canvasClipRect = that._renderer.clipRect();
  32625. that._createHtmlStructure();
  32626. that._createLegend();
  32627. that._needHandleRenderComplete = true;
  32628. that.layoutManager = charts.factory.createChartLayoutManager(that._layoutManagerOptions());
  32629. that._createScrollBar();
  32630. that._$element.on('contextmenu', function(event) {
  32631. that.eventType = 'contextmenu';
  32632. if (ui.events.isTouchEvent(event) || ui.events.isPointerEvent(event))
  32633. event.preventDefault()
  32634. }).on('MSHoldVisual', function(event) {
  32635. that.eventType = 'MSHoldVisual';
  32636. event.preventDefault()
  32637. })
  32638. },
  32639. _layoutManagerOptions: function() {
  32640. return this._themeManager.getOptions("adaptiveLayout")
  32641. },
  32642. _reinit: function(needRedraw) {
  32643. var that = this;
  32644. charts._setCanvasValues(that._canvas);
  32645. that._createTracker();
  32646. that._reinitAxes();
  32647. that._reinitDataSource();
  32648. if (!that.series)
  32649. that._dataSpecificInit();
  32650. that._correctAxes();
  32651. needRedraw && that._endLoading(function() {
  32652. that._render({force: true})
  32653. })
  32654. },
  32655. _createHtmlStructure: function() {
  32656. var that = this,
  32657. renderer = that._renderer;
  32658. that._backgroundRect = renderer.rect(0, 0, 0, 0).attr({
  32659. fill: "gray",
  32660. opacity: 0.0001
  32661. });
  32662. that._panesBackgroundGroup = renderer.g().attr({'class': 'dxc-background'});
  32663. that._titleGroup = renderer.g().attr({'class': 'dxc-title'});
  32664. that._legendGroup = renderer.g().attr({
  32665. 'class': 'dxc-legend',
  32666. clipId: that._getCanvasClipRectID()
  32667. });
  32668. that._stripsGroup = renderer.g().attr({'class': 'dxc-strips-group'});
  32669. that._constantLinesGroup = renderer.g().attr({'class': 'dxc-constant-lines-group'});
  32670. that._axesGroup = renderer.g().attr({'class': 'dxc-axes-group'});
  32671. that._gridGroup = renderer.g().attr({'class': 'dxc-grids-group'});
  32672. that._panesBorderGroup = renderer.g().attr({'class': 'dxc-border'});
  32673. that._labelAxesGroup = renderer.g().attr({'class': 'dxc-strips-labels-group'});
  32674. that._scrollBarGroup = renderer.g().attr({'class': 'dxc-scroll-bar'});
  32675. that._seriesGroup = renderer.g().attr({'class': 'dxc-series-group'});
  32676. that._labelsGroup = renderer.g().attr({'class': 'dxc-labels-group'});
  32677. that._crosshairCursorGroup = renderer.g().attr({'class': 'dxc-crosshair-cursor'})
  32678. },
  32679. _disposeObjectsInArray: function(propName, fieldNames) {
  32680. $.each(this[propName] || [], function(_, item) {
  32681. if (fieldNames && item)
  32682. $.each(fieldNames, function(_, field) {
  32683. item[field] && item[field].dispose()
  32684. });
  32685. else
  32686. item && item.dispose()
  32687. });
  32688. this[propName] = null
  32689. },
  32690. _disposeCore: function() {
  32691. var that = this,
  32692. disposeObject = function(propName) {
  32693. if (that[propName]) {
  32694. that[propName].dispose();
  32695. that[propName] = null
  32696. }
  32697. },
  32698. disposeObjectsInArray = this._disposeObjectsInArray;
  32699. clearTimeout(that._delayedRedraw);
  32700. that._renderer.stopAllAnimations();
  32701. disposeObjectsInArray.call(that, "businessRanges", ["arg", "val"]);
  32702. that.translators = null;
  32703. disposeObjectsInArray.call(that, "series");
  32704. disposeObject("layoutManager");
  32705. disposeObject("tracker");
  32706. disposeObject("chartTitle");
  32707. disposeObject("_crosshair");
  32708. that.paneAxis = null;
  32709. that._userOptions = null;
  32710. that._canvas = null;
  32711. disposeObject("_canvasClipRect");
  32712. disposeObject("_panesBackgroundGroup");
  32713. disposeObject("_titleGroup");
  32714. disposeObject("_scrollBarGroup");
  32715. disposeObject("_legendGroup");
  32716. disposeObject("_stripsGroup");
  32717. disposeObject("_constantLinesGroup");
  32718. disposeObject("_axesGroup");
  32719. disposeObject("_gridGroup");
  32720. disposeObject("_labelAxesGroup");
  32721. disposeObject("_panesBorderGroup");
  32722. disposeObject("_seriesGroup");
  32723. disposeObject("_labelsGroup");
  32724. disposeObject("_crosshairCursorGroup")
  32725. },
  32726. _getAnimationOptions: function() {
  32727. return $.extend({}, DEFAULT_ANIMATION_OPTIONS, this._themeManager.getOptions("animation"))
  32728. },
  32729. _getDefaultSize: function() {
  32730. return {
  32731. width: 400,
  32732. height: 400
  32733. }
  32734. },
  32735. _getOption: function(name) {
  32736. return this._themeManager.getOptions(name)
  32737. },
  32738. _reinitDataSource: function() {
  32739. this._refreshDataSource()
  32740. },
  32741. _applySize: $.noop,
  32742. _resize: function() {
  32743. if (this._updateLockCount)
  32744. this._processRefreshData("_resize");
  32745. else
  32746. this._render(this.__renderOptions || {
  32747. animate: false,
  32748. isResize: true,
  32749. updateTracker: false
  32750. })
  32751. },
  32752. _createTracker: function() {
  32753. var that = this,
  32754. themeManager = that._themeManager;
  32755. if (that.tracker)
  32756. that.tracker.dispose();
  32757. that.tracker = charts.factory.createTracker({
  32758. seriesSelectionMode: themeManager.getOptions('seriesSelectionMode'),
  32759. pointSelectionMode: themeManager.getOptions('pointSelectionMode'),
  32760. seriesGroup: that._seriesGroup,
  32761. renderer: that._renderer,
  32762. tooltip: that._tooltip,
  32763. eventTrigger: that._eventTrigger
  32764. }, that.NAME)
  32765. },
  32766. _getTrackerSettings: function() {
  32767. var that = this;
  32768. return {
  32769. series: that.series,
  32770. legend: that.legend,
  32771. legendCallback: $.proxy(that.legend.getActionCallback, that.legend)
  32772. }
  32773. },
  32774. _updateTracker: function() {
  32775. this.tracker.update(this._getTrackerSettings())
  32776. },
  32777. _render: function(_options) {
  32778. var that = this,
  32779. drawOptions,
  32780. originalCanvas;
  32781. if (!that._initialized)
  32782. return;
  32783. if (!that._canvas)
  32784. return;
  32785. that._resetIsReady();
  32786. drawOptions = that._prepareDrawOptions(_options);
  32787. clearTimeout(that._delayedRedraw);
  32788. originalCanvas = that._canvas;
  32789. that._canvas = $.extend({}, that._canvas);
  32790. if (drawOptions.recreateCanvas)
  32791. that.__currentCanvas = that._canvas;
  32792. else
  32793. that._canvas = that.__currentCanvas;
  32794. that.DEBUG_canvas = that._canvas;
  32795. if (drawOptions.recreateCanvas) {
  32796. that._reappendLoadingIndicator();
  32797. that._updateCanvasClipRect()
  32798. }
  32799. that._renderer.stopAllAnimations(true);
  32800. charts._setCanvasValues(that._canvas);
  32801. that._cleanGroups(drawOptions);
  32802. that._renderElements(drawOptions);
  32803. that._canvas = originalCanvas
  32804. },
  32805. _renderElements: function(drawOptions) {
  32806. var that = this,
  32807. preparedOptions = that._prepareToRender(drawOptions),
  32808. isRotated = that._isRotated(),
  32809. isLegendInside = that._isLegendInside(),
  32810. trackerCanvases = [],
  32811. layoutTargets = that._getLayoutTargets(),
  32812. dirtyCanvas = $.extend({}, that._canvas),
  32813. argBusinessRange,
  32814. zoomMinArg,
  32815. zoomMaxArg;
  32816. !drawOptions.isResize && that._scheduleLoadingIndicatorHiding();
  32817. that.DEBUG_dirtyCanvas = dirtyCanvas;
  32818. that._renderTitleAndLegend(drawOptions, isLegendInside);
  32819. that._renderAxes(drawOptions, preparedOptions, isRotated);
  32820. if (drawOptions.drawTitle && drawOptions.drawLegend && drawOptions.adjustAxes && that.layoutManager.needMoreSpaceForPanesCanvas(that._getLayoutTargets(), isRotated)) {
  32821. that.layoutManager.updateDrawnElements(that._getAxesForTransform(isRotated), that._canvas, dirtyCanvas, that._getLayoutTargets(), isRotated);
  32822. if (that.chartTitle)
  32823. that.layoutManager.correctSizeElement(that.chartTitle, that._canvas);
  32824. that._updateCanvasClipRect(dirtyCanvas);
  32825. that._updateAxesLayout(drawOptions, preparedOptions, isRotated)
  32826. }
  32827. drawOptions.drawTitle && drawOptions.drawLegend && drawOptions.adjustAxes && that.layoutManager.placeDrawnElements(that._canvas);
  32828. that._applyClipRects(preparedOptions);
  32829. that._appendSeriesGroups();
  32830. that._createCrosshairCursor();
  32831. $.each(layoutTargets, function() {
  32832. var canvas = this.canvas;
  32833. trackerCanvases.push({
  32834. left: canvas.left,
  32835. right: canvas.width - canvas.right,
  32836. top: canvas.top,
  32837. bottom: canvas.height - canvas.bottom
  32838. })
  32839. });
  32840. if (that._scrollBar) {
  32841. argBusinessRange = that.businessRanges[0].arg;
  32842. if (argBusinessRange.categories && argBusinessRange.categories.length <= 1)
  32843. zoomMinArg = zoomMaxArg = undefined;
  32844. else {
  32845. zoomMinArg = argBusinessRange.minVisible;
  32846. zoomMaxArg = argBusinessRange.maxVisible
  32847. }
  32848. that._scrollBar.init(argBusinessRange, layoutTargets[0].canvas).setPosition(zoomMinArg, zoomMaxArg)
  32849. }
  32850. drawOptions.updateTracker && that._updateTracker();
  32851. that.tracker.setCanvases({
  32852. left: 0,
  32853. right: that._canvas.width,
  32854. top: 0,
  32855. bottom: that._canvas.height
  32856. }, trackerCanvases);
  32857. that._updateLegendPosition(drawOptions, isLegendInside);
  32858. var timeout = that._getSeriesRenderTimeout(drawOptions);
  32859. if (timeout >= 0)
  32860. that._delayedRedraw = setTimeout(renderSeries, timeout);
  32861. else
  32862. renderSeries();
  32863. function renderSeries() {
  32864. that._renderSeries(drawOptions, isRotated, isLegendInside)
  32865. }
  32866. },
  32867. _createCrosshairCursor: $.noop,
  32868. _appendSeriesGroups: function() {
  32869. var that = this,
  32870. root = that._renderer.root;
  32871. that._seriesGroup.append(root);
  32872. that._labelsGroup.append(root);
  32873. that._appendAdditionalSeriesGroups()
  32874. },
  32875. _renderSeries: function(drawOptions, isRotated, isLegendInside) {
  32876. var that = this,
  32877. themeManager = that._themeManager,
  32878. resolveLabelOverlapping = themeManager.getOptions("resolveLabelOverlapping");
  32879. drawOptions.hideLayoutLabels = that.layoutManager.needMoreSpaceForPanesCanvas(that._getLayoutTargets(), that._isRotated()) && !themeManager.getOptions("adaptiveLayout").keepLabels;
  32880. that._drawSeries(drawOptions, isRotated);
  32881. resolveLabelOverlapping !== "none" && that._resolveLabelOverlapping(resolveLabelOverlapping);
  32882. that._adjustSeries();
  32883. that._renderTrackers(isLegendInside);
  32884. if (that._dataSource && that._dataSource.isLoaded())
  32885. that._fulfillLoadingIndicatorHiding();
  32886. that.tracker.repairTooltip();
  32887. that._drawn();
  32888. that._renderCompleteHandler()
  32889. },
  32890. _getAnimateOption: function(series, drawOptions) {
  32891. return drawOptions.animate && series.getPoints().length <= drawOptions.animationPointsLimit && this._renderer.animationEnabled()
  32892. },
  32893. _resolveLabelOverlapping: function(resolveLabelOverlapping) {
  32894. var func;
  32895. switch (resolveLabelOverlapping) {
  32896. case"stack":
  32897. func = this._resolveLabelOverlappingStack;
  32898. break;
  32899. case"hide":
  32900. func = this._resolveLabelOverlappingHide;
  32901. break;
  32902. case"shift":
  32903. func = this._resolveLabelOverlappingShift;
  32904. break
  32905. }
  32906. $.isFunction(func) && func.call(this)
  32907. },
  32908. _getVisibleSeries: function() {
  32909. return $.grep(this.getAllSeries(), function(series) {
  32910. return series.isVisible()
  32911. })
  32912. },
  32913. _resolveLabelOverlappingHide: function() {
  32914. var labels = $.map(this._getVisibleSeries(), function(series) {
  32915. return $.map(series.getVisiblePoints(), function(point) {
  32916. return point.getLabel()
  32917. })
  32918. }),
  32919. currenctLabel,
  32920. nextLabel,
  32921. currenctLabelRect,
  32922. nextLabelRect,
  32923. i,
  32924. j;
  32925. for (i = 0; i < labels.length; i++) {
  32926. currenctLabel = labels[i];
  32927. currenctLabelRect = currenctLabel.getBoundingRect();
  32928. if (!currenctLabel.isVisible())
  32929. continue;
  32930. for (j = i + 1; j < labels.length; j++) {
  32931. nextLabel = labels[j];
  32932. nextLabelRect = nextLabel.getBoundingRect();
  32933. if (checkOverlapping(currenctLabelRect, nextLabelRect))
  32934. nextLabel.hide()
  32935. }
  32936. }
  32937. },
  32938. _cleanGroups: function(drawOptions) {
  32939. var that = this;
  32940. that._stripsGroup.remove();
  32941. that._constantLinesGroup.remove();
  32942. that._axesGroup.remove();
  32943. that._gridGroup.remove();
  32944. that._labelAxesGroup.remove();
  32945. that._labelsGroup.remove();
  32946. that._crosshairCursorGroup.remove();
  32947. if (!drawOptions || drawOptions.drawLegend)
  32948. that._legendGroup.remove().clear();
  32949. if (!drawOptions || drawOptions.drawTitle)
  32950. that._titleGroup.remove().clear();
  32951. that._stripsGroup.clear();
  32952. that._constantLinesGroup.clear();
  32953. that._axesGroup.clear();
  32954. that._gridGroup.clear();
  32955. that._labelAxesGroup.clear();
  32956. that._labelsGroup.clear();
  32957. that._crosshairCursorGroup.clear()
  32958. },
  32959. _drawTitle: function() {
  32960. var that = this,
  32961. options = that._themeManager.getOptions("title"),
  32962. width = that._canvas.width - that._canvas.left - that._canvas.right;
  32963. options._incidentOccured = that._incidentOccured;
  32964. if (that.chartTitle)
  32965. that.chartTitle.update(options, width);
  32966. else
  32967. that.chartTitle = charts.factory.createTitle(that._renderer, options, that._titleGroup)
  32968. },
  32969. _createLegend: function() {
  32970. var legendSettings = getLegendSettings(this._legendDataField);
  32971. this.legend = core.CoreFactory.createLegend({
  32972. renderer: this._renderer,
  32973. group: this._legendGroup,
  32974. backgroundClass: 'dxc-border',
  32975. itemGroupClass: 'dxc-item',
  32976. textField: legendSettings.textField,
  32977. getFormatObject: legendSettings.getFormatObject
  32978. })
  32979. },
  32980. _updateLegend: function() {
  32981. var that = this,
  32982. themeManager = that._themeManager,
  32983. legendOptions = themeManager.getOptions('legend'),
  32984. legendData = that._getLegendData();
  32985. legendOptions.containerBackgroundColor = themeManager.getOptions("containerBackgroundColor");
  32986. legendOptions._incidentOccured = that._incidentOccured;
  32987. that.legend.update(legendData, legendOptions)
  32988. },
  32989. _prepareDrawOptions: function(drawOptions) {
  32990. var animationOptions = this._getAnimationOptions(),
  32991. options;
  32992. options = $.extend({}, {
  32993. force: false,
  32994. adjustAxes: true,
  32995. drawLegend: true,
  32996. drawTitle: true,
  32997. adjustSeriesLabels: true,
  32998. animate: animationOptions.enabled,
  32999. animationPointsLimit: animationOptions.maxPointCountSupported,
  33000. asyncSeriesRendering: animationOptions.asyncSeriesRendering,
  33001. updateTracker: true
  33002. }, drawOptions, this.__renderOptions);
  33003. if (!_isDefined(options.recreateCanvas))
  33004. options.recreateCanvas = options.adjustAxes && options.drawLegend && options.drawTitle;
  33005. return options
  33006. },
  33007. _processRefreshData: function(newRefreshAction) {
  33008. var currentRefreshActionPosition = $.inArray(this._currentRefreshData, ACTIONS_BY_PRIORITY),
  33009. newRefreshActionPosition = $.inArray(newRefreshAction, ACTIONS_BY_PRIORITY);
  33010. if (!this._currentRefreshData || currentRefreshActionPosition >= 0 && newRefreshActionPosition < currentRefreshActionPosition)
  33011. this._currentRefreshData = newRefreshAction
  33012. },
  33013. _getLegendData: function() {
  33014. var that = this;
  33015. return _map(this._getLegendTargets(), function(item) {
  33016. var style = item.getLegendStyles(),
  33017. textOpacity,
  33018. opacity = style.normal.opacity;
  33019. if (!item.isVisible()) {
  33020. if (!_isDefined(opacity) || opacity > DEFAULT_OPACITY)
  33021. opacity = DEFAULT_OPACITY;
  33022. textOpacity = DEFAULT_OPACITY
  33023. }
  33024. return {
  33025. text: item[that._legendItemTextField],
  33026. id: item.index,
  33027. textOpacity: textOpacity,
  33028. states: {
  33029. hover: style.hover,
  33030. selection: style.selection,
  33031. normal: _extend({}, style.normal, {opacity: opacity})
  33032. }
  33033. }
  33034. })
  33035. },
  33036. _seriesVisibilityChanged: function() {
  33037. this._specialProcessSeries();
  33038. this._populateBusinessRange();
  33039. this._renderer.stopAllAnimations(true);
  33040. this._updateLegend();
  33041. this._render({
  33042. force: true,
  33043. asyncSeriesRendering: false,
  33044. updateTracker: false
  33045. })
  33046. },
  33047. _disposeSeries: function() {
  33048. var that = this;
  33049. $.each(that.series || [], function(_, series) {
  33050. series.dispose()
  33051. });
  33052. that.series = null;
  33053. $.each(that.seriesFamilies || [], function(_, family) {
  33054. family.dispose()
  33055. });
  33056. that.seriesFamilies = null;
  33057. that._needHandleRenderComplete = true
  33058. },
  33059. _optionChanged: function(args) {
  33060. var that = this,
  33061. themeManager = that._themeManager,
  33062. name = args.name;
  33063. themeManager.resetOptions(name);
  33064. themeManager.update(that._options);
  33065. that._scheduleLoadingIndicatorHiding();
  33066. if (name === 'animation') {
  33067. that._renderer.updateAnimationOptions(that._getAnimationOptions());
  33068. return
  33069. }
  33070. switch (name) {
  33071. case'size':
  33072. case'margin':
  33073. that._invalidate();
  33074. break;
  33075. case'dataSource':
  33076. that._needHandleRenderComplete = true;
  33077. that._processRefreshData('_reinitDataSource');
  33078. break;
  33079. case'palette':
  33080. themeManager.updatePalette(that.option(name));
  33081. that._refreshSeries('_dataInit');
  33082. break;
  33083. case'series':
  33084. case'commonSeriesSettings':
  33085. case'containerBackgroundColor':
  33086. case'dataPrepareSettings':
  33087. that._refreshSeries('_dataInit');
  33088. break;
  33089. case'legend':
  33090. case'seriesTemplate':
  33091. that._processRefreshData('_dataInit');
  33092. break;
  33093. case'title':
  33094. that._processRefreshData('force_render');
  33095. break;
  33096. case'valueAxis':
  33097. case'argumentAxis':
  33098. case'commonAxisSettings':
  33099. case'panes':
  33100. case'defaultPane':
  33101. that._refreshSeries('reinit');
  33102. that.paneAxis = {};
  33103. break;
  33104. case'rotated':
  33105. that._createScrollBar();
  33106. that._refreshSeries('reinit');
  33107. break;
  33108. case'customizePoint':
  33109. case'customizeLabel':
  33110. that._refreshSeries('reinit');
  33111. break;
  33112. case'scrollBar':
  33113. that._createScrollBar();
  33114. that._processRefreshData('force_render');
  33115. break;
  33116. case'tooltip':
  33117. that._organizeStackPoints();
  33118. break;
  33119. default:
  33120. that._processRefreshData('reinit')
  33121. }
  33122. that.callBase.apply(that, arguments)
  33123. },
  33124. _handleThemeOptionsCore: function() {
  33125. var that = this;
  33126. if (that._initialized) {
  33127. that._scheduleLoadingIndicatorHiding();
  33128. that._refreshSeries('reinit');
  33129. that.beginUpdate();
  33130. that._invalidate();
  33131. that.endUpdate()
  33132. }
  33133. },
  33134. _refreshSeries: function(actionName) {
  33135. this._disposeSeries();
  33136. this._processRefreshData(actionName)
  33137. },
  33138. _refresh: function() {
  33139. var that = this;
  33140. that._renderer.stopAllAnimations(true);
  33141. if (that._currentRefreshData) {
  33142. switch (that._currentRefreshData) {
  33143. case'force_render':
  33144. that._render({force: true});
  33145. break;
  33146. case'reinit':
  33147. that._reinit(true);
  33148. break;
  33149. default:
  33150. that[that._currentRefreshData] && that[that._currentRefreshData]()
  33151. }
  33152. delete that._currentRefreshData
  33153. }
  33154. else
  33155. that._render({force: true})
  33156. },
  33157. _dataSourceOptions: function() {
  33158. return {paginate: false}
  33159. },
  33160. _updateCanvasClipRect: function(canvas) {
  33161. var that = this,
  33162. width,
  33163. height;
  33164. canvas = canvas || that._canvas;
  33165. width = Math.max(canvas.width - canvas.left - canvas.right, 0);
  33166. height = Math.max(canvas.height - canvas.top - canvas.bottom, 0);
  33167. that._canvasClipRect.attr({
  33168. x: canvas.left,
  33169. y: canvas.top,
  33170. width: width,
  33171. height: height
  33172. });
  33173. that._backgroundRect.attr({
  33174. x: canvas.left,
  33175. y: canvas.top,
  33176. width: width,
  33177. height: height
  33178. }).append(that._renderer.root).toBackground()
  33179. },
  33180. _getCanvasClipRectID: function() {
  33181. return this._canvasClipRect.id
  33182. },
  33183. _dataSourceChangedHandler: function() {
  33184. this._resetZoom();
  33185. this._scheduleLoadingIndicatorHiding();
  33186. this._dataInit()
  33187. },
  33188. _dataInit: function() {
  33189. clearTimeout(this._delayedRedraw);
  33190. this._dataSpecificInit(true)
  33191. },
  33192. _dataSpecificInit: function(needRedraw) {
  33193. this.series = this.series || this._populateSeries();
  33194. this._repopulateSeries();
  33195. this._seriesPopulatedHandler(needRedraw)
  33196. },
  33197. _seriesPopulatedHandler: function(needRedraw) {
  33198. var that = this;
  33199. that._seriesPopulatedHandlerCore();
  33200. that._populateBusinessRange();
  33201. that._updateLegend();
  33202. needRedraw && that._endLoading(function() {
  33203. that._render({force: true})
  33204. })
  33205. },
  33206. _repopulateSeries: function() {
  33207. var that = this,
  33208. parsedData,
  33209. themeManager = that._themeManager,
  33210. data = that._dataSource && that._dataSource.items(),
  33211. dataValidatorOptions = themeManager.getOptions('dataPrepareSettings'),
  33212. seriesTemplate = themeManager.getOptions('seriesTemplate');
  33213. if (that._dataSource && seriesTemplate) {
  33214. that._templatedSeries = utils.processSeriesTemplate(seriesTemplate, that._dataSource.items());
  33215. that._populateSeries();
  33216. delete that._templatedSeries;
  33217. data = that.teamplateData || data
  33218. }
  33219. that._groupSeries();
  33220. that._dataValidator = DX.viz.core.CoreFactory.createDataValidator(data, that._groupedSeries, that._incidentOccured, dataValidatorOptions);
  33221. parsedData = that._dataValidator.validate();
  33222. themeManager.resetPalette();
  33223. $.each(that.series, function(_, singleSeries) {
  33224. singleSeries.updateData(parsedData);
  33225. that._processSingleSeries(singleSeries)
  33226. });
  33227. that._organizeStackPoints()
  33228. },
  33229. _organizeStackPoints: function() {
  33230. var that = this,
  33231. themeManager = that._themeManager,
  33232. sharedTooltip = themeManager.getOptions("tooltip").shared,
  33233. stackPoints = {};
  33234. $.each(that.series || [], function(_, singleSeries) {
  33235. that._resetStackPoints(singleSeries);
  33236. sharedTooltip && that._prepareStackPoints(singleSeries, stackPoints, true)
  33237. })
  33238. },
  33239. _renderCompleteHandler: function() {
  33240. var that = this,
  33241. allSeriesInited = true;
  33242. if (that._needHandleRenderComplete) {
  33243. $.each(that.series, function(_, s) {
  33244. allSeriesInited = allSeriesInited && s.canRenderCompleteHandle()
  33245. });
  33246. if (allSeriesInited) {
  33247. that._needHandleRenderComplete = false;
  33248. that._eventTrigger("done", {target: that})
  33249. }
  33250. }
  33251. },
  33252. _renderTitleAndLegend: function(drawOptions, legendHasInsidePosition) {
  33253. var that = this,
  33254. titleOptions = that._themeManager.getOptions("title"),
  33255. drawTitle = titleOptions.text && drawOptions.drawTitle,
  33256. drawLegend = drawOptions.drawLegend && that.legend && !legendHasInsidePosition,
  33257. drawElements = [];
  33258. if (drawTitle) {
  33259. that._titleGroup.append(that._renderer.root);
  33260. that._drawTitle();
  33261. drawElements.push(that.chartTitle)
  33262. }
  33263. if (drawLegend) {
  33264. that._legendGroup.append(that._renderer.root);
  33265. drawElements.push(that.legend)
  33266. }
  33267. drawElements.length && that.layoutManager.drawElements(drawElements, that._canvas);
  33268. if (drawTitle)
  33269. that.layoutManager.correctSizeElement(that.chartTitle, that._canvas)
  33270. },
  33271. _prepareStackPoints: $.noop,
  33272. _resetStackPoints: $.noop,
  33273. _resetZoom: $.noop,
  33274. _dataIsReady: function() {
  33275. return this._isDataSourceReady()
  33276. },
  33277. getAllSeries: function getAllSeries() {
  33278. return this.series.slice()
  33279. },
  33280. getSeriesByName: function getSeriesByName(name) {
  33281. var found = null;
  33282. $.each(this.series, function(i, singleSeries) {
  33283. if (singleSeries.name === name) {
  33284. found = singleSeries;
  33285. return false
  33286. }
  33287. });
  33288. return found
  33289. },
  33290. getSeriesByPos: function getSeriesByPos(pos) {
  33291. return this.series[pos]
  33292. },
  33293. clearSelection: function clearSelection() {
  33294. this.tracker.clearSelection()
  33295. },
  33296. hideTooltip: function() {
  33297. this.tracker._hideTooltip()
  33298. },
  33299. render: function(renderOptions) {
  33300. var that = this;
  33301. that.__renderOptions = renderOptions;
  33302. that.__forceRender = renderOptions && renderOptions.force;
  33303. that.callBase.apply(that, arguments);
  33304. that.__renderOptions = that.__forceRender = null;
  33305. return that
  33306. },
  33307. getSize: function() {
  33308. var canvas = this._canvas || {};
  33309. return {
  33310. width: canvas.width,
  33311. height: canvas.height
  33312. }
  33313. }
  33314. }).include(ui.DataHelperMixin)
  33315. })(jQuery, DevExpress);
  33316. /*! Module viz-charts, file advancedChart.js */
  33317. (function($, DX, undefined) {
  33318. var charts = DX.viz.charts,
  33319. utils = DX.utils,
  33320. core = DX.viz.core,
  33321. DEFAULT_AXIS_NAME = "defaultAxisName",
  33322. _isArray = utils.isArray,
  33323. _isDefined = utils.isDefined,
  33324. _each = $.each,
  33325. _extend = $.extend,
  33326. _map = $.map,
  33327. MIN = 'min',
  33328. MAX = 'max';
  33329. function prepareAxis(axisOptions) {
  33330. return _isArray(axisOptions) ? axisOptions.length === 0 ? [{}] : axisOptions : [axisOptions]
  33331. }
  33332. function unique(array) {
  33333. var values = {},
  33334. i,
  33335. len = array.length;
  33336. for (i = 0; i < len; i++)
  33337. values[array[i]] = true;
  33338. return _map(values, function(_, key) {
  33339. return key
  33340. })
  33341. }
  33342. function prepareVisibleArea(visibleArea, axisRange, useAggregation, aggregationRange) {
  33343. visibleArea.minVal = axisRange.min;
  33344. visibleArea.maxVal = axisRange.max;
  33345. if (useAggregation && !visibleArea.adjustOnZoom) {
  33346. visibleArea.minVal = _isDefined(visibleArea.minVal) ? visibleArea.minVal : aggregationRange.val.min;
  33347. visibleArea.maxVal = _isDefined(visibleArea.maxVal) ? visibleArea.maxVal : aggregationRange.val.max
  33348. }
  33349. }
  33350. function setTemplateFields(data, templateData, series) {
  33351. _each(data, function(_, data) {
  33352. _each(series.getTeamplatedFields(), function(_, field) {
  33353. data[field.teamplateField] = data[field.originalField]
  33354. });
  33355. templateData.push(data)
  33356. });
  33357. series.updateTeamplateFieldNames()
  33358. }
  33359. charts.AdvancedChart = charts.BaseChart.inherit({
  33360. _dispose: function() {
  33361. var that = this,
  33362. disposeObjectsInArray = this._disposeObjectsInArray;
  33363. that.callBase();
  33364. that.panes = null;
  33365. if (that.legend) {
  33366. that.legend.dispose();
  33367. that.legend = null
  33368. }
  33369. disposeObjectsInArray.call(that, "panesBackground");
  33370. disposeObjectsInArray.call(that, "seriesFamilies");
  33371. that._disposeAxes()
  33372. },
  33373. _reinitAxes: function() {
  33374. this.translators = {};
  33375. this.panes = this._createPanes();
  33376. this._populateAxes()
  33377. },
  33378. _populateSeries: function() {
  33379. var that = this,
  33380. themeManager = that._themeManager,
  33381. hasSeriesTemplate = !!themeManager.getOptions("seriesTemplate"),
  33382. series = hasSeriesTemplate ? that._templatedSeries : that.option("series"),
  33383. allSeriesOptions = _isArray(series) ? series : series ? [series] : [],
  33384. data,
  33385. extraOptions = that._getExtraOptions(),
  33386. particularSeriesOptions,
  33387. particularSeries,
  33388. rotated = that._isRotated(),
  33389. i;
  33390. that.teamplateData = [];
  33391. that._disposeSeries();
  33392. that.series = [];
  33393. themeManager.resetPalette();
  33394. for (i = 0; i < allSeriesOptions.length; i++) {
  33395. particularSeriesOptions = _extend(true, {}, allSeriesOptions[i], extraOptions);
  33396. data = particularSeriesOptions.data;
  33397. particularSeriesOptions.data = null;
  33398. particularSeriesOptions.rotated = rotated;
  33399. particularSeriesOptions.customizePoint = themeManager.getOptions("customizePoint");
  33400. particularSeriesOptions.customizeLabel = themeManager.getOptions("customizeLabel");
  33401. particularSeriesOptions.visibilityChanged = $.proxy(that._seriesVisibilityChanged, that);
  33402. particularSeriesOptions.resolveLabelsOverlapping = themeManager.getOptions("resolveLabelsOverlapping");
  33403. particularSeriesOptions.incidentOccured = that._incidentOccured;
  33404. if (!particularSeriesOptions.name)
  33405. particularSeriesOptions.name = "Series " + (i + 1).toString();
  33406. var seriesTheme = themeManager.getOptions("series", particularSeriesOptions);
  33407. if (!that._checkPaneName(seriesTheme))
  33408. continue;
  33409. particularSeries = core.CoreFactory.createSeries({
  33410. renderer: that._renderer,
  33411. seriesGroup: that._seriesGroup,
  33412. labelsGroup: that._labelsGroup
  33413. }, seriesTheme);
  33414. if (!particularSeries.isUpdated)
  33415. that._incidentOccured("E2101", [seriesTheme.type]);
  33416. else {
  33417. particularSeries.index = that.series.length;
  33418. that.series.push(particularSeries);
  33419. if (hasSeriesTemplate)
  33420. setTemplateFields(data, that.teamplateData, particularSeries)
  33421. }
  33422. }
  33423. return that.series
  33424. },
  33425. _populateAxes: function() {
  33426. var that = this,
  33427. valueAxes = [],
  33428. argumentAxes,
  33429. panes = that.panes,
  33430. rotated = that._isRotated(),
  33431. valueAxisOptions = that.option("valueAxis") || {},
  33432. argumentOption = that.option("argumentAxis") || {},
  33433. argumentAxesOptions = prepareAxis(argumentOption)[0],
  33434. valueAxesOptions = prepareAxis(valueAxisOptions),
  33435. axisNames = [],
  33436. valueAxesCounter = 0,
  33437. paneWithNonVirtualAxis,
  33438. crosshairOptions = that._getOption("crosshair") || {},
  33439. crosshairEnabled = crosshairOptions.enabled,
  33440. horCrosshairEnabled = crosshairEnabled && crosshairOptions.horizontalLine.visible,
  33441. verCrosshairEnabled = crosshairEnabled && crosshairOptions.verticalLine.visible;
  33442. function getNextAxisName() {
  33443. return DEFAULT_AXIS_NAME + valueAxesCounter++
  33444. }
  33445. that._disposeAxes();
  33446. if (rotated)
  33447. paneWithNonVirtualAxis = argumentAxesOptions.position === "right" ? panes[panes.length - 1].name : panes[0].name;
  33448. else
  33449. paneWithNonVirtualAxis = argumentAxesOptions.position === "top" ? panes[0].name : panes[panes.length - 1].name;
  33450. argumentAxes = _map(panes, function(pane) {
  33451. return that._createAxis("argumentAxis", argumentAxesOptions, {
  33452. virtual: pane.name !== paneWithNonVirtualAxis,
  33453. pane: pane.name,
  33454. crosshairEnabled: rotated ? horCrosshairEnabled : verCrosshairEnabled
  33455. }, rotated)
  33456. });
  33457. _each(valueAxesOptions, function(priority, axisOptions) {
  33458. var axisPanes = [],
  33459. name = axisOptions.name;
  33460. if (name && $.inArray(name, axisNames) !== -1) {
  33461. that._incidentOccured("E2102");
  33462. return
  33463. }
  33464. name && axisNames.push(name);
  33465. if (axisOptions.pane)
  33466. axisPanes.push(axisOptions.pane);
  33467. if (axisOptions.panes && axisOptions.panes.length)
  33468. axisPanes = axisPanes.concat(axisOptions.panes.slice(0));
  33469. axisPanes = unique(axisPanes);
  33470. if (!axisPanes.length)
  33471. axisPanes.push(undefined);
  33472. _each(axisPanes, function(_, pane) {
  33473. valueAxes.push(that._createAxis("valueAxis", axisOptions, {
  33474. name: name || getNextAxisName(),
  33475. pane: pane,
  33476. priority: priority,
  33477. crosshairEnabled: rotated ? verCrosshairEnabled : horCrosshairEnabled
  33478. }, rotated))
  33479. })
  33480. });
  33481. that._valueAxes = valueAxes;
  33482. that._argumentAxes = argumentAxes
  33483. },
  33484. _prepareStackPoints: function(singleSeries, stackPoints, isSharedTooltip) {
  33485. var points = singleSeries.getPoints(),
  33486. stackName = singleSeries.getStackName();
  33487. _each(points, function(_, point) {
  33488. var argument = point.argument;
  33489. if (!stackPoints[argument]) {
  33490. stackPoints[argument] = {};
  33491. stackPoints[argument][null] = []
  33492. }
  33493. if (stackName && !_isArray(stackPoints[argument][stackName])) {
  33494. stackPoints[argument][stackName] = [];
  33495. _each(stackPoints[argument][null], function(_, point) {
  33496. if (!point.stackName)
  33497. stackPoints[argument][stackName].push(point)
  33498. })
  33499. }
  33500. if (stackName) {
  33501. stackPoints[argument][stackName].push(point);
  33502. stackPoints[argument][null].push(point)
  33503. }
  33504. else
  33505. _each(stackPoints[argument], function(_, stack) {
  33506. stack.push(point)
  33507. });
  33508. if (isSharedTooltip) {
  33509. point.stackPoints = stackPoints[argument][stackName];
  33510. point.stackName = stackName
  33511. }
  33512. })
  33513. },
  33514. _resetStackPoints: function(singleSeries) {
  33515. _each(singleSeries.getPoints(), function(_, point) {
  33516. point.stackPoints = null;
  33517. point.stackName = null
  33518. })
  33519. },
  33520. _disposeAxes: function() {
  33521. var disposeObjectsInArray = this._disposeObjectsInArray;
  33522. disposeObjectsInArray.call(this, "_argumentAxes");
  33523. disposeObjectsInArray.call(this, "_valueAxes")
  33524. },
  33525. _drawAxes: function(panesBorderOptions, drawOptions, adjustUnits) {
  33526. var that = this,
  33527. drawAxes = function(axes) {
  33528. _each(axes, function(_, axis) {
  33529. axis.draw(adjustUnits)
  33530. })
  33531. },
  33532. drawStaticAxisElements = function(axes) {
  33533. _each(axes, function(_i, axis) {
  33534. axis.drawGrids(panesBorderOptions[axis.pane])
  33535. })
  33536. };
  33537. that._reinitTranslators();
  33538. that._prepareAxesAndDraw(drawAxes, drawStaticAxisElements, drawOptions)
  33539. },
  33540. _appendAdditionalSeriesGroups: function() {
  33541. var that = this,
  33542. root = that._renderer.root;
  33543. that._crosshairCursorGroup.append(root);
  33544. that._legendGroup.append(root);
  33545. that._scrollBar && that._scrollBarGroup.append(root)
  33546. },
  33547. _getLegendTargets: function() {
  33548. return _map(this.series, function(item) {
  33549. if (item.getOptions().showInLegend)
  33550. return item
  33551. })
  33552. },
  33553. _legendItemTextField: "name",
  33554. _seriesPopulatedHandlerCore: function() {
  33555. this._processSeriesFamilies();
  33556. this._processValueAxisFormat()
  33557. },
  33558. _renderTrackers: function() {
  33559. var that = this,
  33560. i;
  33561. for (i = 0; i < that.series.length; ++i)
  33562. that.series[i].drawTrackers()
  33563. },
  33564. _specialProcessSeries: function() {
  33565. this._processSeriesFamilies()
  33566. },
  33567. _processSeriesFamilies: function() {
  33568. var that = this,
  33569. types = [],
  33570. families = [],
  33571. paneSeries,
  33572. themeManager = that._themeManager,
  33573. familyOptions = {
  33574. equalBarWidth: that._getEqualBarWidth(),
  33575. minBubbleSize: themeManager.getOptions("minBubbleSize"),
  33576. maxBubbleSize: themeManager.getOptions("maxBubbleSize")
  33577. };
  33578. if (that.seriesFamilies && that.seriesFamilies.length) {
  33579. _each(that.seriesFamilies, function(_, family) {
  33580. family.updateOptions(familyOptions);
  33581. family.adjustSeriesValues()
  33582. });
  33583. return
  33584. }
  33585. _each(that.series, function(_, item) {
  33586. if ($.inArray(item.type, types) === -1)
  33587. types.push(item.type)
  33588. });
  33589. _each(that._getLayoutTargets(), function(_, pane) {
  33590. paneSeries = that._getSeriesForPane(pane.name);
  33591. _each(types, function(_, type) {
  33592. var family = core.CoreFactory.createSeriesFamily({
  33593. type: type,
  33594. pane: pane.name,
  33595. equalBarWidth: familyOptions.equalBarWidth,
  33596. minBubbleSize: familyOptions.minBubbleSize,
  33597. maxBubbleSize: familyOptions.maxBubbleSize
  33598. });
  33599. family.add(paneSeries);
  33600. family.adjustSeriesValues();
  33601. families.push(family)
  33602. })
  33603. });
  33604. that.seriesFamilies = families
  33605. },
  33606. _appendAxesGroups: function() {
  33607. var that = this,
  33608. root = that._renderer.root;
  33609. that._stripsGroup.append(root);
  33610. that._gridGroup.append(root);
  33611. that._axesGroup.append(root);
  33612. that._constantLinesGroup.append(root);
  33613. that._labelAxesGroup.append(root)
  33614. },
  33615. _updateAxesLayout: function(drawOptions, panesBorderOptions, rotated) {
  33616. this.layoutManager.updatePanesCanvases(this._getLayoutTargets(), this._canvas, rotated);
  33617. this._drawAxes(panesBorderOptions, drawOptions, true)
  33618. },
  33619. _populateBusinessRange: function(visibleArea) {
  33620. var that = this,
  33621. businessRanges = [],
  33622. themeManager = that._themeManager,
  33623. rotated = that._isRotated(),
  33624. useAggregation = themeManager.getOptions('useAggregation'),
  33625. argAxes = that._argumentAxes,
  33626. lastArgAxis = argAxes[argAxes.length - 1],
  33627. calcInterval = lastArgAxis.calcInterval,
  33628. argRange = new core.Range({rotated: !!rotated}),
  33629. argBusinessRange;
  33630. that._disposeObjectsInArray("businessRanges", ["arg", "val"]);
  33631. _each(argAxes, function(_, axis) {
  33632. argRange.addRange(axis.getRangeData())
  33633. });
  33634. _each(that._groupedSeries, function(_, group) {
  33635. var groupRange = new core.Range({
  33636. rotated: !!rotated,
  33637. isValueRange: true,
  33638. pane: group.valueAxis.pane,
  33639. axis: group.valueAxis.name
  33640. }),
  33641. groupAxisRange = group.valueAxis.getRangeData();
  33642. groupRange.addRange(groupAxisRange);
  33643. _each(group, function(_, series) {
  33644. visibleArea && prepareVisibleArea(visibleArea, groupAxisRange, useAggregation, series._originalBusinessRange);
  33645. var seriesRange = series.getRangeData(visibleArea, calcInterval);
  33646. groupRange.addRange(seriesRange.val);
  33647. argRange.addRange(seriesRange.arg)
  33648. });
  33649. if (!groupRange.isDefined())
  33650. groupRange.setStubData(group.valueAxis.getOptions().valueType === 'datetime' ? 'datetime' : undefined);
  33651. if (group.valueAxis.getOptions().showZero)
  33652. groupRange.correctValueZeroLevel();
  33653. groupRange.checkZeroStick();
  33654. businessRanges.push({
  33655. val: groupRange,
  33656. arg: argRange
  33657. })
  33658. });
  33659. if (!argRange.isDefined())
  33660. argRange.setStubData(argAxes[0].getOptions().argumentType);
  33661. if (visibleArea && visibleArea.notApplyMargins && argRange.axisType !== "discrete") {
  33662. argBusinessRange = argAxes[0].getTranslator().getBusinessRange();
  33663. argRange.addRange({
  33664. min: argBusinessRange.min,
  33665. max: argBusinessRange.max,
  33666. stick: true
  33667. })
  33668. }
  33669. that._correctBusinessRange(argRange, lastArgAxis);
  33670. that.businessRanges = businessRanges
  33671. },
  33672. _correctBusinessRange: function(range, lastArgAxis) {
  33673. var setTicksAtUnitBeginning = lastArgAxis.getOptions().setTicksAtUnitBeginning,
  33674. tickIntervalRange = {},
  33675. tickInterval = lastArgAxis.getOptions().tickInterval,
  33676. originInterval = tickInterval;
  33677. tickInterval = $.isNumeric(tickInterval) ? tickInterval : utils.dateToMilliseconds(tickInterval);
  33678. if (tickInterval && _isDefined(range[MIN]) && _isDefined(range[MAX]) && tickInterval >= Math.abs(range[MAX] - range[MIN])) {
  33679. if (utils.isDate(range[MIN])) {
  33680. if (!$.isNumeric(originInterval)) {
  33681. tickIntervalRange[MIN] = utils.addInterval(range[MIN], originInterval, true);
  33682. tickIntervalRange[MAX] = utils.addInterval(range[MAX], originInterval, false)
  33683. }
  33684. else {
  33685. tickIntervalRange[MIN] = new Date(range[MIN].valueOf() - tickInterval);
  33686. tickIntervalRange[MAX] = new Date(range[MAX].valueOf() + tickInterval)
  33687. }
  33688. if (setTicksAtUnitBeginning) {
  33689. utils.correctDateWithUnitBeginning(tickIntervalRange[MAX], originInterval);
  33690. utils.correctDateWithUnitBeginning(tickIntervalRange[MIN], originInterval)
  33691. }
  33692. }
  33693. else {
  33694. tickIntervalRange[MIN] = range[MIN] - tickInterval;
  33695. tickIntervalRange[MAX] = range[MAX] + tickInterval
  33696. }
  33697. range.addRange(tickIntervalRange)
  33698. }
  33699. },
  33700. _getArgumentAxes: function() {
  33701. return this._argumentAxes
  33702. },
  33703. _getValueAxes: function() {
  33704. return this._valueAxes
  33705. },
  33706. _processValueAxisFormat: function() {
  33707. var that = this,
  33708. valueAxes = that._valueAxes,
  33709. axesWithFullStackedFormat = [];
  33710. _each(that.series, function() {
  33711. if (this.isFullStackedSeries() && $.inArray(this.axis, axesWithFullStackedFormat) === -1)
  33712. axesWithFullStackedFormat.push(this.axis)
  33713. });
  33714. _each(valueAxes, function() {
  33715. if ($.inArray(this.name, axesWithFullStackedFormat) !== -1)
  33716. this.setPercentLabelFormat();
  33717. else
  33718. this.resetAutoLabelFormat()
  33719. })
  33720. },
  33721. _createAxis: function(typeSelector, userOptions, axisOptions, rotated) {
  33722. var that = this,
  33723. renderingSettings = _extend({
  33724. renderer: that._renderer,
  33725. incidentOccured: that._incidentOccured,
  33726. axisClass: typeSelector === "argumentAxis" ? "arg" : "val",
  33727. stripsGroup: that._stripsGroup,
  33728. labelAxesGroup: that._labelAxesGroup,
  33729. constantLinesGroup: that._constantLinesGroup,
  33730. axesContainerGroup: that._axesGroup,
  33731. gridGroup: that._gridGroup
  33732. }, that._getAxisRenderingOptions(typeSelector, userOptions, rotated)),
  33733. axis;
  33734. userOptions = that._prepareStripsAndConstantLines(typeSelector, userOptions, rotated);
  33735. axis = new charts.axes.Axis(renderingSettings);
  33736. axis.updateOptions(_extend(true, {}, userOptions, axisOptions, that._prepareAxisOptions(typeSelector, userOptions)));
  33737. return axis
  33738. },
  33739. _getTrackerSettings: function() {
  33740. return _extend(this.callBase(), {argumentAxis: this._argumentAxes})
  33741. },
  33742. _prepareStripsAndConstantLines: function(typeSelector, userOptions, rotated) {
  33743. userOptions = this._themeManager.getOptions(typeSelector, userOptions, rotated);
  33744. if (userOptions.strips)
  33745. _each(userOptions.strips, function(i) {
  33746. userOptions.strips[i] = _extend(true, {}, userOptions.stripStyle, userOptions.strips[i])
  33747. });
  33748. if (userOptions.constantLines)
  33749. _each(userOptions.constantLines, function(i, line) {
  33750. userOptions.constantLines[i] = _extend(true, {}, userOptions.constantLineStyle, line)
  33751. });
  33752. return userOptions
  33753. },
  33754. _legendDataField: 'series',
  33755. _adjustSeries: $.noop
  33756. })
  33757. })(jQuery, DevExpress);
  33758. /*! Module viz-charts, file chart.js */
  33759. (function($, DX, undefined) {
  33760. var viz = DX.viz,
  33761. core = viz.core,
  33762. charts = viz.charts,
  33763. utils = DX.utils,
  33764. MAX_ADJUSTMENT_ATTEMPTS = 5,
  33765. DEFAULT_PANE_NAME = "default",
  33766. ASYNC_SERIES_RENDERING_DELAY = 25,
  33767. DEFAULT_PANES = [{
  33768. name: DEFAULT_PANE_NAME,
  33769. border: {}
  33770. }],
  33771. _map = $.map,
  33772. _each = $.each,
  33773. _extend = $.extend,
  33774. _isArray = utils.isArray,
  33775. _isDefined = utils.isDefined;
  33776. function getFirstAxisNameForPane(axes, paneName) {
  33777. var result;
  33778. for (var i = 0; i < axes.length; i++)
  33779. if (axes[i].pane === paneName) {
  33780. result = axes[i].name;
  33781. break
  33782. }
  33783. if (!result)
  33784. result = axes[0].name;
  33785. return result
  33786. }
  33787. function hideGridsOnNonFirstValueAxisForPane(valAxes, paneName, synchronizeMultiAxes) {
  33788. var axesForPane = [],
  33789. firstShownAxis;
  33790. _each(valAxes, function(_, axis) {
  33791. if (axis.pane === paneName)
  33792. axesForPane.push(axis)
  33793. });
  33794. if (axesForPane.length > 1 && synchronizeMultiAxes)
  33795. _each(axesForPane, function(_, axis) {
  33796. var gridOpt = axis.getOptions().grid,
  33797. minorGridOpt = axis.getOptions().minorGrid;
  33798. if (firstShownAxis && gridOpt && gridOpt.visible) {
  33799. gridOpt.visible = false;
  33800. minorGridOpt && (minorGridOpt.visible = false)
  33801. }
  33802. else
  33803. firstShownAxis = firstShownAxis ? firstShownAxis : gridOpt && gridOpt.visible
  33804. })
  33805. }
  33806. function getPaneForAxis(paneAxis, axisNameWithoutPane) {
  33807. var result;
  33808. _each(paneAxis, function(paneName, pane) {
  33809. _each(pane, function(axisName) {
  33810. if (axisNameWithoutPane === axisName) {
  33811. result = paneName;
  33812. return false
  33813. }
  33814. })
  33815. });
  33816. return result
  33817. }
  33818. function findAxisOptions(valueAxes, valueAxesOptions, axisName) {
  33819. var result,
  33820. axInd;
  33821. for (axInd = 0; axInd < valueAxesOptions.length; axInd++)
  33822. if (valueAxesOptions[axInd].name === axisName) {
  33823. result = valueAxesOptions[axInd];
  33824. result.priority = axInd;
  33825. break
  33826. }
  33827. if (!result)
  33828. for (axInd = 0; axInd < valueAxes.length; axInd++)
  33829. if (valueAxes[axInd].name === axisName) {
  33830. result = valueAxes[axInd].getOptions();
  33831. result.priority = valueAxes[axInd].priority;
  33832. break
  33833. }
  33834. return result
  33835. }
  33836. function findAxis(paneName, axisName, axes) {
  33837. var axis,
  33838. i;
  33839. for (i = 0; i < axes.length; i++) {
  33840. axis = axes[i];
  33841. if (axis.name === axisName && axis.pane === paneName)
  33842. return axis
  33843. }
  33844. }
  33845. function prepareSegmentRectPoints(left, top, width, height, borderOptions) {
  33846. var maxSW = ~~((width < height ? width : height) / 2),
  33847. sw = borderOptions.width || 0,
  33848. newSW = sw < maxSW ? sw : maxSW;
  33849. left = left + newSW / 2;
  33850. top = top + newSW / 2;
  33851. width = width - newSW;
  33852. height = height - newSW;
  33853. var right = left + width,
  33854. bottom = top + height,
  33855. points = [],
  33856. segments = [],
  33857. segmentSequence,
  33858. visiblyOpt = 0,
  33859. prevSegmentVisibility = 0;
  33860. var allSegment = {
  33861. top: [[left, top], [right, top]],
  33862. right: [[right, top], [right, bottom]],
  33863. bottom: [[right, bottom], [left, bottom]],
  33864. left: [[left, bottom], [left, top]]
  33865. };
  33866. _each(allSegment, function(seg) {
  33867. var visibility = !!borderOptions[seg];
  33868. visiblyOpt = visiblyOpt * 2 + ~~visibility
  33869. });
  33870. switch (visiblyOpt) {
  33871. case 13:
  33872. case 9:
  33873. segmentSequence = ['left', 'top', 'right', 'bottom'];
  33874. break;
  33875. case 11:
  33876. segmentSequence = ['bottom', 'left', 'top', 'right'];
  33877. break;
  33878. default:
  33879. segmentSequence = ['top', 'right', 'bottom', 'left']
  33880. }
  33881. _each(segmentSequence, function(_, seg) {
  33882. var segmentVisibility = !!borderOptions[seg];
  33883. if (!prevSegmentVisibility && segments.length) {
  33884. points.push(segments);
  33885. segments = []
  33886. }
  33887. if (segmentVisibility)
  33888. _each(allSegment[seg].slice(prevSegmentVisibility), function(_, segment) {
  33889. segments = segments.concat(segment)
  33890. });
  33891. prevSegmentVisibility = ~~segmentVisibility
  33892. });
  33893. segments.length && points.push(segments);
  33894. points.length === 1 && (points = points[0]);
  33895. return {
  33896. points: points,
  33897. pathType: visiblyOpt === 15 ? "area" : "line"
  33898. }
  33899. }
  33900. function applyClipSettings(clipRects, settings) {
  33901. _each(clipRects || [], function(_, c) {
  33902. c && c.attr(settings)
  33903. })
  33904. }
  33905. function reinitTranslators(translators) {
  33906. _each(translators, function(_, axisTrans) {
  33907. _each(axisTrans, function(_, translator) {
  33908. translator.arg.reinit();
  33909. translator.val.reinit()
  33910. })
  33911. })
  33912. }
  33913. charts._test_prepareSegmentRectPoints = function() {
  33914. var original = prepareSegmentRectPoints.original || prepareSegmentRectPoints;
  33915. if (arguments[0])
  33916. prepareSegmentRectPoints = arguments[0];
  33917. prepareSegmentRectPoints.original = original;
  33918. prepareSegmentRectPoints.restore = function() {
  33919. prepareSegmentRectPoints = original
  33920. };
  33921. return prepareSegmentRectPoints
  33922. };
  33923. DX.registerComponent("dxChart", viz.charts, charts.AdvancedChart.inherit({
  33924. _chartType: "chart",
  33925. _setDefaultOptions: function() {
  33926. this.callBase();
  33927. this.option({defaultPane: DEFAULT_PANE_NAME})
  33928. },
  33929. _initCore: function() {
  33930. this.__ASYNC_SERIES_RENDERING_DELAY = ASYNC_SERIES_RENDERING_DELAY;
  33931. this.paneAxis = {};
  33932. this._panesClipRects = {};
  33933. this.callBase()
  33934. },
  33935. _disposeCore: function() {
  33936. var that = this,
  33937. disposeObjectsInArray = this._disposeObjectsInArray,
  33938. panesClipRects = that._panesClipRects;
  33939. that.callBase();
  33940. disposeObjectsInArray.call(panesClipRects, "fixed");
  33941. disposeObjectsInArray.call(panesClipRects, "base");
  33942. disposeObjectsInArray.call(panesClipRects, "wide");
  33943. that._panesClipRects = null
  33944. },
  33945. _correctAxes: function() {
  33946. this.series && this._correctValueAxes()
  33947. },
  33948. _getExtraOptions: $.noop,
  33949. _processSingleSeries: $.noop,
  33950. _groupSeries: function() {
  33951. var that = this,
  33952. panes = that.panes,
  33953. valAxes = that._valueAxes,
  33954. paneList = _map(panes, function(pane) {
  33955. return pane.name
  33956. }),
  33957. series = that.series,
  33958. paneAxis = that.paneAxis,
  33959. synchronizeMultiAxes = that._themeManager.getOptions("synchronizeMultiAxes"),
  33960. groupedSeries = that._groupedSeries = [];
  33961. _each(series, function(i, particularSeries) {
  33962. particularSeries.axis = particularSeries.axis || getFirstAxisNameForPane(valAxes, particularSeries.pane);
  33963. if (particularSeries.axis) {
  33964. paneAxis[particularSeries.pane] = paneAxis[particularSeries.pane] || {};
  33965. paneAxis[particularSeries.pane][particularSeries.axis] = true
  33966. }
  33967. });
  33968. _each(valAxes, function(_, axis) {
  33969. if (axis.name && axis.pane && $.inArray(axis.pane, paneList) !== -1) {
  33970. paneAxis[axis.pane] = paneAxis[axis.pane] || {};
  33971. paneAxis[axis.pane][axis.name] = true
  33972. }
  33973. });
  33974. that._correctValueAxes();
  33975. _each(paneAxis, function(paneName, pane) {
  33976. hideGridsOnNonFirstValueAxisForPane(valAxes, paneName, synchronizeMultiAxes);
  33977. _each(pane, function(axisName) {
  33978. var group = [];
  33979. _each(series, function(_, particularSeries) {
  33980. if (particularSeries.pane === paneName && particularSeries.axis === axisName)
  33981. group.push(particularSeries)
  33982. });
  33983. groupedSeries.push(group);
  33984. group.valueAxis = findAxis(paneName, axisName, valAxes);
  33985. group.valueOptions = group.valueAxis.getOptions()
  33986. })
  33987. });
  33988. groupedSeries.argumentAxes = that._argumentAxes;
  33989. groupedSeries.argumentOptions = groupedSeries.argumentAxes[0].getOptions()
  33990. },
  33991. _cleanPanesClipRects: function(clipArrayName) {
  33992. var that = this,
  33993. clipArray = that._panesClipRects[clipArrayName];
  33994. _each(clipArray || [], function(_, clipRect) {
  33995. clipRect && clipRect.dispose()
  33996. });
  33997. that._panesClipRects[clipArrayName] = []
  33998. },
  33999. _createPanes: function() {
  34000. var that = this,
  34001. panes = that.option("panes"),
  34002. panesNameCounter = 0,
  34003. bottomPaneName;
  34004. if (panes && _isArray(panes) && !panes.length || $.isEmptyObject(panes))
  34005. panes = DEFAULT_PANES;
  34006. that._cleanPanesClipRects("fixed");
  34007. that._cleanPanesClipRects("base");
  34008. that._cleanPanesClipRects("wide");
  34009. that.defaultPane = that.option("defaultPane");
  34010. panes = _extend(true, [], _isArray(panes) ? panes : panes ? [panes] : []);
  34011. _each(panes, function(_, pane) {
  34012. pane.name = !_isDefined(pane.name) ? DEFAULT_PANE_NAME + panesNameCounter++ : pane.name
  34013. });
  34014. if (!that._doesPaneExists(panes, that.defaultPane) && panes.length > 0) {
  34015. bottomPaneName = panes[panes.length - 1].name;
  34016. that._incidentOccured("W2101", [that.defaultPane, bottomPaneName]);
  34017. that.defaultPane = bottomPaneName
  34018. }
  34019. panes = that._isRotated() ? panes.reverse() : panes;
  34020. return panes
  34021. },
  34022. _doesPaneExists: function(panes, paneName) {
  34023. var found = false;
  34024. _each(panes, function(_, pane) {
  34025. if (pane.name === paneName) {
  34026. found = true;
  34027. return false
  34028. }
  34029. });
  34030. return found
  34031. },
  34032. _getAxisRenderingOptions: function(typeSelector, axisOptions, rotated) {
  34033. return {
  34034. axesType: "xyAxes",
  34035. drawingType: "linear",
  34036. isHorizontal: typeSelector === "argumentAxis" ? !rotated : rotated
  34037. }
  34038. },
  34039. _prepareAxisOptions: $.noop,
  34040. _checkPaneName: function(seriesTheme) {
  34041. var paneList = _map(this.panes, function(pane) {
  34042. return pane.name
  34043. });
  34044. seriesTheme.pane = seriesTheme.pane || this.defaultPane;
  34045. return $.inArray(seriesTheme.pane, paneList) !== -1
  34046. },
  34047. _correctValueAxes: function() {
  34048. var that = this,
  34049. rotated = that._isRotated(),
  34050. valueAxisOptions = that.option("valueAxis") || {},
  34051. valueAxesOptions = _isArray(valueAxisOptions) ? valueAxisOptions : [valueAxisOptions],
  34052. valueAxes = that._valueAxes || [],
  34053. defaultAxisName = valueAxes[0].name,
  34054. paneAxis = that.paneAxis || {},
  34055. panes = that.panes,
  34056. i,
  34057. neededAxis = {};
  34058. _each(valueAxes, function(_, axis) {
  34059. if (axis.pane)
  34060. return;
  34061. var pane = getPaneForAxis(that.paneAxis, axis.name);
  34062. if (!pane) {
  34063. pane = that.defaultPane;
  34064. paneAxis[pane] = paneAxis[pane] || {};
  34065. paneAxis[pane][axis.name] = true
  34066. }
  34067. axis.setPane(pane)
  34068. });
  34069. for (i = 0; i < panes.length; i++)
  34070. if (!paneAxis[panes[i].name]) {
  34071. paneAxis[panes[i].name] = {};
  34072. paneAxis[panes[i].name][defaultAxisName] = true
  34073. }
  34074. _each(that.paneAxis, function(paneName, axisNames) {
  34075. _each(axisNames, function(axisName) {
  34076. neededAxis[axisName + "-" + paneName] = true;
  34077. if (!findAxis(paneName, axisName, valueAxes)) {
  34078. var axisOptions = findAxisOptions(valueAxes, valueAxesOptions, axisName);
  34079. if (!axisOptions) {
  34080. that._incidentOccured("W2102", [axisName]);
  34081. axisOptions = {
  34082. name: axisName,
  34083. priority: valueAxes.length
  34084. }
  34085. }
  34086. valueAxes.push(that._createAxis("valueAxis", axisOptions, {
  34087. pane: paneName,
  34088. name: axisName
  34089. }, rotated))
  34090. }
  34091. })
  34092. });
  34093. valueAxes = $.grep(valueAxes, function(elem) {
  34094. return !!neededAxis[elem.name + "-" + elem.pane]
  34095. });
  34096. valueAxes.sort(function(a, b) {
  34097. return a.priority - b.priority
  34098. });
  34099. that._valueAxes = valueAxes
  34100. },
  34101. _getSeriesForPane: function(paneName) {
  34102. var paneSeries = [];
  34103. _each(this.series, function(_, oneSeries) {
  34104. if (oneSeries.pane === paneName)
  34105. paneSeries.push(oneSeries)
  34106. });
  34107. return paneSeries
  34108. },
  34109. _createTranslator: function(range, canvas, options) {
  34110. return core.CoreFactory.createTranslator2D(range, canvas, options)
  34111. },
  34112. _createPanesBorderOptions: function() {
  34113. var commonBorderOptions = this._themeManager.getOptions("commonPaneSettings").border,
  34114. panesBorderOptions = {};
  34115. _each(this.panes, function(_, pane) {
  34116. panesBorderOptions[pane.name] = _extend(true, {}, commonBorderOptions, pane.border)
  34117. });
  34118. return panesBorderOptions
  34119. },
  34120. _createScrollBar: function() {
  34121. var that = this,
  34122. scrollBarOptions = that._themeManager.getOptions("scrollBar") || {},
  34123. scrollBarGroup = that._scrollBarGroup;
  34124. if (scrollBarOptions.visible) {
  34125. scrollBarOptions.rotated = that._isRotated();
  34126. that._scrollBar = (that._scrollBar || charts.factory.createScrollBar(that._renderer, scrollBarGroup)).update(scrollBarOptions)
  34127. }
  34128. else {
  34129. scrollBarGroup.remove();
  34130. that._scrollBar && that._scrollBar.dispose();
  34131. that._scrollBar = null
  34132. }
  34133. },
  34134. _prepareToRender: function(drawOptions) {
  34135. var that = this,
  34136. panesBorderOptions = that._createPanesBorderOptions();
  34137. that._createPanesBackground();
  34138. that._appendAxesGroups();
  34139. that._transformed && that._resetTransform();
  34140. that._createTranslators(drawOptions);
  34141. that._options.useAggregation && _each(that.series, function(_, series) {
  34142. series._originalBusinessRange = series._originalBusinessRange || series.getRangeData();
  34143. series.resamplePoints(that._getTranslator(series.pane, series.axis).arg, that._zoomMinArg, that._zoomMaxArg)
  34144. });
  34145. if (_isDefined(that._zoomMinArg) || _isDefined(that._zoomMaxArg))
  34146. that._populateBusinessRange({
  34147. adjustOnZoom: that._themeManager.getOptions("adjustOnZoom"),
  34148. minArg: that._zoomMinArg,
  34149. maxArg: that._zoomMaxArg,
  34150. notApplyMargins: that._notApplyMargins
  34151. });
  34152. if (that._options.useAggregation || _isDefined(that._zoomMinArg) || _isDefined(that._zoomMaxArg))
  34153. that._updateTranslators();
  34154. return panesBorderOptions
  34155. },
  34156. _isLegendInside: function() {
  34157. return this.legend && this.legend.getPosition() === "inside"
  34158. },
  34159. _renderAxes: function(drawOptions, panesBorderOptions, rotated) {
  34160. if (drawOptions && drawOptions.recreateCanvas)
  34161. this.layoutManager.updatePanesCanvases(this.panes, this._canvas, rotated);
  34162. this._drawAxes(panesBorderOptions, drawOptions)
  34163. },
  34164. _isRotated: function() {
  34165. return this._themeManager.getOptions("rotated")
  34166. },
  34167. _getLayoutTargets: function() {
  34168. return this.panes
  34169. },
  34170. _applyClipRects: function(panesBorderOptions) {
  34171. var that = this,
  34172. canvasClipRectID = that._getCanvasClipRectID(),
  34173. i;
  34174. that._drawPanesBorders(panesBorderOptions);
  34175. that._createClipRectsForPanes();
  34176. for (i = 0; i < that._argumentAxes.length; i++)
  34177. that._argumentAxes[i].applyClipRects(that._getElementsClipRectID(that._argumentAxes[i].pane), canvasClipRectID);
  34178. for (i = 0; i < that._valueAxes.length; i++)
  34179. that._valueAxes[i].applyClipRects(that._getElementsClipRectID(that._valueAxes[i].pane), canvasClipRectID);
  34180. that._fillPanesBackground()
  34181. },
  34182. _getSeriesRenderTimeout: function(drawOptions) {
  34183. return drawOptions.asyncSeriesRendering ? ASYNC_SERIES_RENDERING_DELAY : undefined
  34184. },
  34185. _updateLegendPosition: function(drawOptions, legendHasInsidePosition) {
  34186. var that = this;
  34187. if (drawOptions.drawLegend && that.legend && legendHasInsidePosition) {
  34188. var panes = that.panes,
  34189. newCanvas = _extend({}, panes[0].canvas),
  34190. layoutManager = charts.factory.createChartLayoutManager();
  34191. newCanvas.right = panes[panes.length - 1].canvas.right;
  34192. newCanvas.bottom = panes[panes.length - 1].canvas.bottom;
  34193. that._legendGroup.append(that._renderer.root);
  34194. layoutManager.drawElements([that.legend], newCanvas);
  34195. layoutManager.placeDrawnElements(newCanvas)
  34196. }
  34197. },
  34198. _drawSeries: function(drawOptions, rotated) {
  34199. var that = this;
  34200. _each(that.seriesFamilies || [], function(_, seriesFamily) {
  34201. var translators = that._getTranslator(seriesFamily.pane) || {};
  34202. seriesFamily.updateSeriesValues(translators);
  34203. seriesFamily.adjustSeriesDimensions(translators)
  34204. });
  34205. _each(that.series, function(_, particularSeries) {
  34206. that._applyPaneClipRect(particularSeries);
  34207. particularSeries.setAdjustSeriesLabels(drawOptions.adjustSeriesLabels);
  34208. var tr = that._getTranslator(particularSeries.pane, particularSeries.axis),
  34209. translators = {};
  34210. translators[rotated ? "x" : "y"] = tr.val;
  34211. translators[rotated ? "y" : "x"] = tr.arg;
  34212. particularSeries.draw(translators, that._getAnimateOption(particularSeries, drawOptions), drawOptions.hideLayoutLabels, that.legend && that.legend.getActionCallback(particularSeries))
  34213. })
  34214. },
  34215. _applyPaneClipRect: function(seriesOptions) {
  34216. var that = this,
  34217. paneIndex = that._getPaneIndex(seriesOptions.pane),
  34218. panesClipRects = that._panesClipRects,
  34219. wideClipRect = panesClipRects.wide[paneIndex];
  34220. seriesOptions.setClippingParams(panesClipRects.base[paneIndex].id, wideClipRect && wideClipRect.id, that._getPaneBorderVisibility(paneIndex))
  34221. },
  34222. _createTranslators: function(drawOptions) {
  34223. var that = this,
  34224. rotated = that._isRotated(),
  34225. translators;
  34226. if (!drawOptions.recreateCanvas)
  34227. return;
  34228. that.translators = translators = {};
  34229. that.layoutManager.updatePanesCanvases(that.panes, that._canvas, rotated);
  34230. _each(that.paneAxis, function(paneName, pane) {
  34231. translators[paneName] = translators[paneName] || {};
  34232. _each(pane, function(axisName) {
  34233. var translator = that._createTranslator(new core.Range(that._getBusinessRange(paneName, axisName).val), that._getCanvasForPane(paneName), rotated ? {direction: "horizontal"} : {});
  34234. translator.pane = paneName;
  34235. translator.axis = axisName;
  34236. translators[paneName][axisName] = {val: translator}
  34237. })
  34238. });
  34239. _each(that._argumentAxes, function(_, axis) {
  34240. var translator = that._createTranslator(new core.Range(that._getBusinessRange(axis.pane).arg), that._getCanvasForPane(axis.pane), !rotated ? {direction: "horizontal"} : {});
  34241. _each(translators[axis.pane], function(valAxis, paneAxisTran) {
  34242. paneAxisTran.arg = translator
  34243. })
  34244. })
  34245. },
  34246. _updateTranslators: function() {
  34247. var that = this;
  34248. _each(that.translators, function(pane, axisTrans) {
  34249. _each(axisTrans, function(axis, translator) {
  34250. translator.arg.updateBusinessRange(new core.Range(that._getBusinessRange(pane).arg));
  34251. delete translator.arg._originalBusinessRange;
  34252. translator.val.updateBusinessRange(new core.Range(that._getBusinessRange(pane, axis).val));
  34253. delete translator.val._originalBusinessRange
  34254. })
  34255. })
  34256. },
  34257. _getAxesForTransform: function(rotated) {
  34258. return {
  34259. verticalAxes: !rotated ? this._getValueAxes() : this._getArgumentAxes(),
  34260. horizontalAxes: !rotated ? this._getArgumentAxes() : this._getValueAxes()
  34261. }
  34262. },
  34263. _reinitTranslators: function() {
  34264. var that = this;
  34265. _each(that._argumentAxes, function(_, axis) {
  34266. var translator = that._getTranslator(axis.pane);
  34267. if (translator) {
  34268. translator.arg.reinit();
  34269. axis.setTranslator(translator.arg, translator.val)
  34270. }
  34271. });
  34272. _each(that._valueAxes, function(_, axis) {
  34273. var translator = that._getTranslator(axis.pane, axis.name);
  34274. if (translator) {
  34275. translator.val.reinit();
  34276. axis.setTranslator(translator.val, translator.arg)
  34277. }
  34278. })
  34279. },
  34280. _prepareAxesAndDraw: function(drawAxes, drawStaticAxisElements, drawOptions) {
  34281. var that = this,
  34282. i = 0,
  34283. layoutManager = that.layoutManager,
  34284. rotated = that._isRotated(),
  34285. adjustmentCounter = 0,
  34286. synchronizeMultiAxes = that._themeManager.getOptions('synchronizeMultiAxes'),
  34287. layoutTargets = that._getLayoutTargets(),
  34288. verticalAxes = rotated ? that._argumentAxes : that._valueAxes,
  34289. horizontalAxes = rotated ? that._valueAxes : that._argumentAxes,
  34290. hElements = horizontalAxes,
  34291. vElements = verticalAxes;
  34292. if (that._scrollBar) {
  34293. that._scrollBar.setPane(layoutTargets);
  34294. if (rotated)
  34295. vElements = [that._scrollBar].concat(vElements);
  34296. else
  34297. hElements = hElements.concat([that._scrollBar])
  34298. }
  34299. do {
  34300. for (i = 0; i < that._argumentAxes.length; i++)
  34301. that._argumentAxes[i].resetTicks();
  34302. for (i = 0; i < that._valueAxes.length; i++)
  34303. that._valueAxes[i].resetTicks();
  34304. if (synchronizeMultiAxes)
  34305. charts.multiAxesSynchronizer.synchronize(that._valueAxes);
  34306. drawAxes(horizontalAxes);
  34307. layoutManager.requireAxesRedraw = false;
  34308. if (drawOptions.adjustAxes) {
  34309. layoutManager.applyHorizontalAxesLayout(hElements, layoutTargets, rotated);
  34310. !layoutManager.stopDrawAxes && reinitTranslators(that.translators)
  34311. }
  34312. drawAxes(verticalAxes);
  34313. if (drawOptions.adjustAxes && !layoutManager.stopDrawAxes) {
  34314. layoutManager.applyVerticalAxesLayout(vElements, layoutTargets, rotated);
  34315. !layoutManager.stopDrawAxes && reinitTranslators(that.translators)
  34316. }
  34317. adjustmentCounter = adjustmentCounter + 1
  34318. } while (!layoutManager.stopDrawAxes && layoutManager.requireAxesRedraw && adjustmentCounter < MAX_ADJUSTMENT_ATTEMPTS);
  34319. drawStaticAxisElements(verticalAxes);
  34320. drawStaticAxisElements(horizontalAxes);
  34321. that._scrollBar && that._scrollBar.applyLayout();
  34322. that.__axisAdjustmentsCount = adjustmentCounter
  34323. },
  34324. _getPanesParameters: function() {
  34325. var that = this,
  34326. panes = that.panes,
  34327. i,
  34328. params = [];
  34329. for (i = 0; i < panes.length; i++)
  34330. if (that._getPaneBorderVisibility(i))
  34331. params.push({
  34332. coords: panes[i].borderCoords,
  34333. clipRect: that._panesClipRects.fixed[i]
  34334. });
  34335. return params
  34336. },
  34337. _createCrosshairCursor: function() {
  34338. var that = this,
  34339. options = that._themeManager.getOptions("crosshair") || {},
  34340. axes = !that._isRotated() ? [that._argumentAxes, that._valueAxes] : [that._valueAxes, that._argumentAxes],
  34341. parameters = {
  34342. canvas: that._getCommonCanvas(),
  34343. panes: that._getPanesParameters(),
  34344. axes: axes
  34345. };
  34346. if (!options || !options.enabled)
  34347. return;
  34348. if (!that._crosshair)
  34349. that._crosshair = charts.factory.createCrosshair(that._renderer, options, parameters, that._crosshairCursorGroup);
  34350. else
  34351. that._crosshair.update(options, parameters);
  34352. that._crosshair.render()
  34353. },
  34354. _getCommonCanvas: function() {
  34355. var i,
  34356. canvas,
  34357. commonCanvas,
  34358. panes = this.panes;
  34359. for (i = 0; i < panes.length; i++) {
  34360. canvas = panes[i].canvas;
  34361. if (!commonCanvas)
  34362. commonCanvas = _extend({}, canvas);
  34363. else {
  34364. commonCanvas.right = canvas.right;
  34365. commonCanvas.bottom = canvas.bottom
  34366. }
  34367. }
  34368. return commonCanvas
  34369. },
  34370. _createPanesBackground: function() {
  34371. var that = this,
  34372. defaultBackgroundColor = that._themeManager.getOptions("commonPaneSettings").backgroundColor,
  34373. backgroundColor,
  34374. renderer = that._renderer,
  34375. rect,
  34376. i,
  34377. rects = [];
  34378. that._panesBackgroundGroup && that._panesBackgroundGroup.clear();
  34379. for (i = 0; i < that.panes.length; i++) {
  34380. backgroundColor = that.panes[i].backgroundColor || defaultBackgroundColor;
  34381. if (!backgroundColor || backgroundColor === "none") {
  34382. rects.push(null);
  34383. continue
  34384. }
  34385. rect = renderer.rect(0, 0, 0, 0).attr({
  34386. fill: backgroundColor,
  34387. "stroke-width": 0
  34388. }).append(that._panesBackgroundGroup);
  34389. rects.push(rect)
  34390. }
  34391. that.panesBackground = rects;
  34392. that._panesBackgroundGroup.append(renderer.root)
  34393. },
  34394. _fillPanesBackground: function() {
  34395. var that = this,
  34396. bc;
  34397. _each(that.panes, function(i, pane) {
  34398. bc = pane.borderCoords;
  34399. if (that.panesBackground[i] !== null)
  34400. that.panesBackground[i].attr({
  34401. x: bc.left,
  34402. y: bc.top,
  34403. width: bc.width,
  34404. height: bc.height
  34405. })
  34406. })
  34407. },
  34408. _calcPaneBorderCoords: function(pane) {
  34409. var canvas = pane.canvas,
  34410. bc = pane.borderCoords = pane.borderCoords || {};
  34411. bc.left = canvas.left;
  34412. bc.top = canvas.top;
  34413. bc.right = canvas.width - canvas.right;
  34414. bc.bottom = canvas.height - canvas.bottom;
  34415. bc.width = Math.max(bc.right - bc.left, 0);
  34416. bc.height = Math.max(bc.bottom - bc.top, 0)
  34417. },
  34418. _drawPanesBorders: function(panesBorderOptions) {
  34419. var that = this,
  34420. rotated = that._isRotated();
  34421. that._panesBorderGroup && that._panesBorderGroup.remove().clear();
  34422. _each(that.panes, function(i, pane) {
  34423. var bc,
  34424. borderOptions = panesBorderOptions[pane.name],
  34425. segmentRectParams,
  34426. attr = {
  34427. fill: "none",
  34428. stroke: borderOptions.color,
  34429. "stroke-opacity": borderOptions.opacity,
  34430. "stroke-width": borderOptions.width,
  34431. dashStyle: borderOptions.dashStyle,
  34432. "stroke-linecap": "square"
  34433. };
  34434. that._calcPaneBorderCoords(pane, rotated);
  34435. if (!borderOptions.visible)
  34436. return;
  34437. bc = pane.borderCoords;
  34438. segmentRectParams = prepareSegmentRectPoints(bc.left, bc.top, bc.width, bc.height, borderOptions);
  34439. that._renderer.path(segmentRectParams.points, segmentRectParams.pathType).attr(attr).append(that._panesBorderGroup)
  34440. });
  34441. that._panesBorderGroup.append(that._renderer.root)
  34442. },
  34443. _createClipRect: function(clipArray, index, left, top, width, height) {
  34444. var that = this,
  34445. clipRect = clipArray[index];
  34446. if (!clipRect) {
  34447. clipRect = that._renderer.clipRect(left, top, width, height);
  34448. clipArray[index] = clipRect
  34449. }
  34450. else
  34451. clipRect.attr({
  34452. x: left,
  34453. y: top,
  34454. width: width,
  34455. height: height
  34456. })
  34457. },
  34458. _createClipRectsForPanes: function() {
  34459. var that = this,
  34460. canvas = that._canvas;
  34461. _each(that.panes, function(i, pane) {
  34462. var needWideClipRect = false,
  34463. bc = pane.borderCoords,
  34464. left = bc.left,
  34465. top = bc.top,
  34466. width = bc.width,
  34467. height = bc.height,
  34468. panesClipRects = that._panesClipRects;
  34469. that._createClipRect(panesClipRects.fixed, i, left, top, width, height);
  34470. that._createClipRect(panesClipRects.base, i, left, top, width, height);
  34471. _each(that.series, function(_, series) {
  34472. if (series.pane === pane.name && (series.isFinancialSeries() || series.areErrorBarsVisible()))
  34473. needWideClipRect = true
  34474. });
  34475. if (needWideClipRect) {
  34476. if (that._isRotated()) {
  34477. top = 0;
  34478. height = canvas.height
  34479. }
  34480. else {
  34481. left = 0;
  34482. width = canvas.width
  34483. }
  34484. that._createClipRect(panesClipRects.wide, i, left, top, width, height)
  34485. }
  34486. else
  34487. panesClipRects.wide.push(null)
  34488. })
  34489. },
  34490. _getPaneIndex: function(paneName) {
  34491. var paneIndex;
  34492. _each(this.panes, function(index, pane) {
  34493. if (pane.name === paneName) {
  34494. paneIndex = index;
  34495. return false
  34496. }
  34497. });
  34498. return paneIndex
  34499. },
  34500. _getPaneBorderVisibility: function(paneIndex) {
  34501. var commonPaneBorderVisible = this._themeManager.getOptions("commonPaneSettings").border.visible,
  34502. pane = this.panes[paneIndex] || {},
  34503. paneBorder = pane.border || {};
  34504. return "visible" in paneBorder ? paneBorder.visible : commonPaneBorderVisible
  34505. },
  34506. _getElementsClipRectID: function(paneName) {
  34507. return this._panesClipRects.fixed[this._getPaneIndex(paneName)].id
  34508. },
  34509. _getTranslator: function(paneName, axisName) {
  34510. var paneTrans = this.translators[paneName],
  34511. foundTranslator = null;
  34512. if (!paneTrans)
  34513. return foundTranslator;
  34514. foundTranslator = paneTrans[axisName];
  34515. if (!foundTranslator)
  34516. _each(paneTrans, function(axis, trans) {
  34517. foundTranslator = trans;
  34518. return false
  34519. });
  34520. return foundTranslator
  34521. },
  34522. _getCanvasForPane: function(paneName) {
  34523. var panes = this.panes,
  34524. panesNumber = panes.length,
  34525. i;
  34526. for (i = 0; i < panesNumber; i++)
  34527. if (panes[i].name === paneName)
  34528. return panes[i].canvas
  34529. },
  34530. _getBusinessRange: function(paneName, axisName) {
  34531. var ranges = this.businessRanges || [],
  34532. rangesNumber = ranges.length,
  34533. foundRange,
  34534. i;
  34535. for (i = 0; i < rangesNumber; i++)
  34536. if (ranges[i].val.pane === paneName && ranges[i].val.axis === axisName) {
  34537. foundRange = ranges[i];
  34538. break
  34539. }
  34540. if (!foundRange)
  34541. for (i = 0; i < rangesNumber; i++)
  34542. if (ranges[i].val.pane === paneName) {
  34543. foundRange = ranges[i];
  34544. break
  34545. }
  34546. return foundRange
  34547. },
  34548. _transformArgument: function(translate, scale) {
  34549. var that = this,
  34550. rotated = that._isRotated(),
  34551. settings,
  34552. clipSettings,
  34553. panesClipRects = that._panesClipRects;
  34554. if (!that._transformed) {
  34555. that._transformed = true;
  34556. that._labelsGroup.remove();
  34557. that._resetIsReady();
  34558. _each(that.series || [], function(i, s) {
  34559. s.applyClip()
  34560. })
  34561. }
  34562. if (rotated) {
  34563. settings = {
  34564. translateY: translate,
  34565. scaleY: scale
  34566. };
  34567. clipSettings = {
  34568. translateY: -translate / scale,
  34569. scaleY: 1 / scale
  34570. }
  34571. }
  34572. else {
  34573. settings = {
  34574. translateX: translate,
  34575. scaleX: scale
  34576. };
  34577. clipSettings = {
  34578. translateX: -translate / scale,
  34579. scaleX: 1 / scale
  34580. }
  34581. }
  34582. applyClipSettings(panesClipRects.base, clipSettings);
  34583. applyClipSettings(panesClipRects.wide, clipSettings);
  34584. that._seriesGroup.attr(settings);
  34585. that._scrollBar && that._scrollBar.transform(-translate, scale)
  34586. },
  34587. _resetTransform: function() {
  34588. var that = this,
  34589. settings = {
  34590. translateX: 0,
  34591. translateY: 0,
  34592. scaleX: null,
  34593. scaleY: null
  34594. },
  34595. panesClipRects = that._panesClipRects;
  34596. applyClipSettings(panesClipRects.base, settings);
  34597. applyClipSettings(panesClipRects.wide, settings);
  34598. that._seriesGroup.attr(settings);
  34599. _each(that.series || [], function(i, s) {
  34600. s.resetClip()
  34601. });
  34602. that._transformed = false
  34603. },
  34604. _getTrackerSettings: function() {
  34605. var that = this,
  34606. themeManager = that._themeManager;
  34607. return _extend(this.callBase(), {
  34608. chart: that,
  34609. zoomingMode: themeManager.getOptions("zoomingMode"),
  34610. scrollingMode: themeManager.getOptions("scrollingMode"),
  34611. rotated: that._isRotated(),
  34612. crosshair: that._crosshair
  34613. })
  34614. },
  34615. _resolveLabelOverlappingStack: function() {
  34616. var that = this,
  34617. stackPoints = {},
  34618. isRotated = that._isRotated(),
  34619. shiftDirection = isRotated ? function(box, length) {
  34620. return {
  34621. x: box.x - length,
  34622. y: box.y
  34623. }
  34624. } : function(box, length) {
  34625. return {
  34626. x: box.x,
  34627. y: box.y - length
  34628. }
  34629. };
  34630. _each(this._getVisibleSeries(), function(_, particularSeries) {
  34631. that._prepareStackPoints(particularSeries, stackPoints)
  34632. });
  34633. _each(stackPoints, function(_, stacks) {
  34634. _each(stacks, function(_, points) {
  34635. charts.overlapping.resolveLabelOverlappingInOneDirection(points, that._getCommonCanvas(), isRotated, shiftDirection)
  34636. })
  34637. })
  34638. },
  34639. _getEqualBarWidth: function() {
  34640. return this._themeManager.getOptions("equalBarWidth")
  34641. },
  34642. zoomArgument: function(min, max, gesturesUsed) {
  34643. var that = this,
  34644. zoomArg;
  34645. if (!_isDefined(min) && !_isDefined(max))
  34646. return;
  34647. zoomArg = that._argumentAxes[0].zoom(min, max, gesturesUsed);
  34648. that._zoomMinArg = zoomArg.min;
  34649. that._zoomMaxArg = zoomArg.max;
  34650. that._notApplyMargins = gesturesUsed;
  34651. that._render({
  34652. force: true,
  34653. drawTitle: false,
  34654. drawLegend: false,
  34655. adjustAxes: false,
  34656. animate: false,
  34657. adjustSeriesLabels: false,
  34658. asyncSeriesRendering: false,
  34659. updateTracker: false
  34660. })
  34661. },
  34662. _resetZoom: function() {
  34663. var that = this;
  34664. that._zoomMinArg = that._zoomMaxArg = undefined;
  34665. that._argumentAxes[0] && that._argumentAxes[0].resetZoom()
  34666. },
  34667. getVisibleArgumentBounds: function() {
  34668. var range = this._argumentAxes[0].getTranslator().getBusinessRange(),
  34669. isDiscrete = range.axisType === "discrete",
  34670. categories = range.categories;
  34671. return {
  34672. minVisible: isDiscrete ? range.minVisible || categories[0] : range.minVisible,
  34673. maxVisible: isDiscrete ? range.maxVisible || categories[categories.length - 1] : range.maxVisible
  34674. }
  34675. }
  34676. }))
  34677. })(jQuery, DevExpress);
  34678. /*! Module viz-charts, file pieChart.js */
  34679. (function($, DX, undefined) {
  34680. var viz = DX.viz,
  34681. core = viz.core,
  34682. charts = viz.charts,
  34683. utils = DX.utils,
  34684. _extend = $.extend,
  34685. _noop = $.noop,
  34686. _getVerticallyShiftedAngularCoords = DX.viz.core.utils.getVerticallyShiftedAngularCoords;
  34687. DX.registerComponent("dxPieChart", viz.charts, charts.BaseChart.inherit({
  34688. _chartType: 'pie',
  34689. _reinitAxes: _noop,
  34690. _correctAxes: _noop,
  34691. _layoutManagerOptions: function() {
  34692. var diameter = this._themeManager.getOptions('diameter');
  34693. if (utils.isNumber(diameter)) {
  34694. if (diameter > 1)
  34695. diameter = 1;
  34696. else if (diameter < 0)
  34697. diameter = 0
  34698. }
  34699. else
  34700. diameter = undefined;
  34701. return _extend(true, {}, this.callBase(), {piePercentage: diameter})
  34702. },
  34703. _groupSeries: function() {
  34704. this.series.valueOptions = {valueType: "numeric"};
  34705. this._groupedSeries = [this.series];
  34706. this._groupedSeries.argumentOptions = this.series[0] && this.series[0].getOptions()
  34707. },
  34708. _populateBusinessRange: function() {
  34709. var businessRanges = [],
  34710. series = this.series,
  34711. singleSeries = series[0],
  34712. range = new core.Range,
  34713. singleSeriesRange;
  34714. this._disposeObjectsInArray("businessRanges");
  34715. if (singleSeries) {
  34716. singleSeriesRange = singleSeries.getRangeData();
  34717. range.addRange(singleSeriesRange.val);
  34718. if (!range.isDefined())
  34719. range.setStubData();
  34720. businessRanges.push(range)
  34721. }
  34722. this.businessRanges = businessRanges
  34723. },
  34724. _specialProcessSeries: function() {
  34725. this.series[0].arrangePoints()
  34726. },
  34727. _createTranslator: function(range) {
  34728. return core.CoreFactory.createTranslator1D(range.min, range.max, 360, 0)
  34729. },
  34730. _populateSeries: function() {
  34731. var that = this,
  34732. themeManager = that._themeManager,
  34733. hasSeriesTemplate = !!themeManager.getOptions("seriesTemplate"),
  34734. seriesOptions = hasSeriesTemplate ? that._templatedSeries : that.option("series"),
  34735. allSeriesOptions = $.isArray(seriesOptions) ? seriesOptions : seriesOptions ? [seriesOptions] : [],
  34736. data,
  34737. particularSeriesOptions,
  34738. particularSeries,
  34739. seriesTheme;
  34740. that._disposeSeries();
  34741. that.series = [];
  34742. themeManager.resetPalette();
  34743. if (allSeriesOptions.length) {
  34744. particularSeriesOptions = _extend(true, {}, allSeriesOptions[0]);
  34745. if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))
  34746. particularSeriesOptions.type = "";
  34747. data = particularSeriesOptions.data;
  34748. particularSeriesOptions.data = null;
  34749. particularSeriesOptions.incidentOccured = that._incidentOccured;
  34750. seriesTheme = themeManager.getOptions("series", particularSeriesOptions, true);
  34751. seriesTheme.visibilityChanged = $.proxy(that._seriesVisibilityChanged, that);
  34752. seriesTheme.customizePoint = themeManager.getOptions("customizePoint");
  34753. seriesTheme.customizeLabel = themeManager.getOptions("customizeLabel");
  34754. particularSeries = core.CoreFactory.createSeries({
  34755. renderer: that._renderer,
  34756. seriesGroup: that._seriesGroup,
  34757. labelsGroup: that._labelsGroup
  34758. }, seriesTheme);
  34759. if (!particularSeries.isUpdated)
  34760. that._incidentOccured("E2101", [seriesTheme.type]);
  34761. else {
  34762. that._processSingleSeries(particularSeries);
  34763. that.series.push(particularSeries)
  34764. }
  34765. particularSeriesOptions.data = data
  34766. }
  34767. return that.series
  34768. },
  34769. _processSingleSeries: function(singleSeries) {
  34770. singleSeries.arrangePoints()
  34771. },
  34772. _seriesPopulatedHandlerCore: _noop,
  34773. _getLegendTargets: function() {
  34774. return this.series[0] ? this.series[0].getPoints() : []
  34775. },
  34776. _legendItemTextField: "argument",
  34777. _prepareToRender: _noop,
  34778. _isLegendInside: _noop,
  34779. _renderAxes: _noop,
  34780. _isRotated: _noop,
  34781. _getLayoutTargets: function() {
  34782. return [{canvas: this._canvas}]
  34783. },
  34784. _getAxesForTransform: function() {
  34785. return {
  34786. verticalAxes: [],
  34787. horizontalAxes: []
  34788. }
  34789. },
  34790. _updateAxesLayout: _noop,
  34791. _applyClipRects: _noop,
  34792. _appendAdditionalSeriesGroups: _noop,
  34793. _getSeriesRenderTimeout: _noop,
  34794. _drawSeries: function(drawOptions) {
  34795. var that = this,
  34796. singleSeries = that.getSeries(),
  34797. legend = that.legend,
  34798. getActionCallbackProxy = $.proxy(legend.getActionCallback, legend);
  34799. if (singleSeries) {
  34800. that.layoutManager.applyPieChartSeriesLayout(that._canvas, singleSeries, true);
  34801. singleSeries.canvas = that._canvas;
  34802. singleSeries.resetLabelSetups();
  34803. if (singleSeries.drawLabelsWOPoints(that._createTranslator(that.businessRanges[0], that._canvas)))
  34804. that.layoutManager.applyPieChartSeriesLayout(that._canvas, singleSeries, drawOptions.hideLayoutLabels);
  34805. singleSeries.draw(that._createTranslator(that.businessRanges[0], that._canvas), that._getAnimateOption(singleSeries, drawOptions), drawOptions.hideLayoutLabels, getActionCallbackProxy)
  34806. }
  34807. },
  34808. _adjustSeries: function() {
  34809. var singleSeries = this.getSeries();
  34810. singleSeries && singleSeries.adjustLabels()
  34811. },
  34812. _updateLegendPosition: _noop,
  34813. _renderTrackers: _noop,
  34814. _createScrollBar: _noop,
  34815. _resolveLabelOverlappingShift: function() {
  34816. var series = this.series[0],
  34817. center = series.getCenter(),
  34818. lPoints = [],
  34819. rPoints = [];
  34820. $.each(series.getVisiblePoints(), function(_, point) {
  34821. var angle = utils.normalizeAngle(point.middleAngle);
  34822. (angle <= 90 || angle >= 270 ? rPoints : lPoints).push(point)
  34823. });
  34824. charts.overlapping.resolveLabelOverlappingInOneDirection(lPoints, this._canvas, false, shiftFunction);
  34825. charts.overlapping.resolveLabelOverlappingInOneDirection(rPoints, this._canvas, false, shiftFunction);
  34826. function shiftFunction(box, length) {
  34827. return _getVerticallyShiftedAngularCoords(box, -length, center)
  34828. }
  34829. },
  34830. getSeries: function getSeries() {
  34831. return this.series && this.series[0]
  34832. },
  34833. _legendDataField: 'point'
  34834. }))
  34835. })(jQuery, DevExpress);
  34836. /*! Module viz-charts, file polarChart.js */
  34837. (function($, DX, undefined) {
  34838. var charts = DX.viz.charts,
  34839. core = DX.viz.core,
  34840. DEFAULT_PANE_NAME = 'default';
  34841. var PolarChart = charts.AdvancedChart.inherit({
  34842. _chartType: 'polar',
  34843. _createPanes: function() {
  34844. return [{name: DEFAULT_PANE_NAME}]
  34845. },
  34846. _checkPaneName: function() {
  34847. return true
  34848. },
  34849. _getAxisRenderingOptions: function(typeSelector) {
  34850. var isArgumentAxis = typeSelector === "argumentAxis",
  34851. type = isArgumentAxis ? "circular" : "linear",
  34852. useSpiderWeb = this.option("useSpiderWeb");
  34853. if (useSpiderWeb)
  34854. type += "Spider";
  34855. return {
  34856. axesType: "polarAxes",
  34857. drawingType: type,
  34858. isHorizontal: true
  34859. }
  34860. },
  34861. _prepareAxisOptions: function(typeSelector, axisOptions) {
  34862. return {type: this.option("useSpiderWeb") && typeSelector === "argumentAxis" ? "discrete" : axisOptions.type}
  34863. },
  34864. _getExtraOptions: function() {
  34865. return {spiderWidget: this.option("useSpiderWeb")}
  34866. },
  34867. _correctAxes: $.noop,
  34868. _groupSeries: function() {
  34869. this._groupedSeries = [this.series];
  34870. this._groupedSeries[0].valueAxis = this._valueAxes[0];
  34871. this._groupedSeries[0].valueOptions = this._valueAxes[0].getOptions();
  34872. this._groupedSeries.argumentAxes = this._argumentAxes;
  34873. this._groupedSeries.argumentOptions = this._argumentAxes[0].getOptions()
  34874. },
  34875. _processSingleSeries: $.noop,
  34876. _prepareToRender: function() {
  34877. this._appendAxesGroups();
  34878. return {}
  34879. },
  34880. _isLegendInside: $.noop,
  34881. _renderAxes: function(drawOptions) {
  34882. this._drawAxes({}, drawOptions)
  34883. },
  34884. _reinitTranslators: function() {
  34885. var that = this,
  34886. valueAxes = that._valueAxes,
  34887. argumentAxes = that._argumentAxes,
  34888. translator = that._createTranslator({
  34889. arg: new core.Range(that.businessRanges[0].arg),
  34890. val: new core.Range(that.businessRanges[0].val)
  34891. }),
  34892. argTranslator = translator.getComponent("arg"),
  34893. valTranslator = translator.getComponent("val"),
  34894. i = 0;
  34895. that.translator = translator;
  34896. argumentAxes[0].setTranslator(argTranslator, valTranslator);
  34897. for (i; i < valueAxes.length; i++)
  34898. valueAxes[i].setTranslator(valTranslator, argTranslator)
  34899. },
  34900. _prepareAxesAndDraw: function(drawAxes, drawStaticAxisElements) {
  34901. var that = this,
  34902. valueAxes = that._valueAxes,
  34903. argAxes = that._argumentAxes,
  34904. argumentAxis = argAxes[0];
  34905. that._calcCanvas(argumentAxis.measureLabels());
  34906. that.translator.reinit();
  34907. drawAxes(argAxes);
  34908. $.each(valueAxes, function(_, valAxis) {
  34909. valAxis.setSpiderTicks(argumentAxis.getSpiderTicks())
  34910. });
  34911. drawAxes(valueAxes);
  34912. drawStaticAxisElements(argAxes);
  34913. drawStaticAxisElements(valueAxes)
  34914. },
  34915. _calcCanvas: function(measure) {
  34916. var canvas = this.translator.canvas;
  34917. canvas.left += measure.width;
  34918. canvas.right += measure.width;
  34919. canvas.top += measure.height;
  34920. canvas.bottom += measure.height
  34921. },
  34922. _isRotated: $.noop,
  34923. _getLayoutTargets: function() {
  34924. return [{canvas: this._canvas}]
  34925. },
  34926. _getAxesForTransform: function() {
  34927. var argAxes = this._getArgumentAxes();
  34928. return {
  34929. verticalAxes: argAxes,
  34930. horizontalAxes: argAxes
  34931. }
  34932. },
  34933. _applyClipRects: $.noop,
  34934. _getSeriesRenderTimeout: $.noop,
  34935. _drawSeries: function(drawOptions) {
  34936. var that = this,
  34937. i,
  34938. seriesFamilies = that.seriesFamilies || [],
  34939. series = that.series;
  34940. if (!series.length)
  34941. return;
  34942. for (i = 0; i < seriesFamilies.length; i++) {
  34943. var translators = {};
  34944. translators.val = that.translator;
  34945. translators.arg = that.translator;
  34946. seriesFamilies[i].updateSeriesValues(translators);
  34947. seriesFamilies[i].adjustSeriesDimensions(translators)
  34948. }
  34949. for (i = 0; i < series.length; i++)
  34950. series[i].draw(that.translator, that._getAnimateOption(series[i], drawOptions), drawOptions.hideLayoutLabels, that.legend && that.legend.getActionCallback(series[i]))
  34951. },
  34952. _updateLegendPosition: $.noop,
  34953. _createScrollBar: $.noop,
  34954. _createTranslator: function(br) {
  34955. var themeManager = this._themeManager,
  34956. axisUserOptions = this.option("argumentAxis"),
  34957. axisOptions = themeManager.getOptions("argumentAxis", axisUserOptions) || {};
  34958. return new core.PolarTranslator(br, $.extend(true, {}, this._canvas), {startAngle: axisOptions.startAngle})
  34959. },
  34960. _getSeriesForPane: function() {
  34961. return this.series
  34962. },
  34963. _getEqualBarWidth: function() {
  34964. return !!this._themeManager.getOptions("equalBarWidth")
  34965. }
  34966. });
  34967. DX.registerComponent('dxPolarChart', charts, PolarChart)
  34968. })(jQuery, DevExpress);
  34969. /*! Module viz-charts, file layoutManager.js */
  34970. (function($, DX, undefined) {
  34971. var _isNumber = DX.utils.isNumber,
  34972. _decreaseGaps = DX.viz.core.utils.decreaseGaps,
  34973. _round = Math.round,
  34974. _min = Math.min,
  34975. _max = Math.max,
  34976. _floor = Math.floor,
  34977. _sqrt = Math.sqrt,
  34978. _each = $.each,
  34979. _extend = $.extend;
  34980. function correctElementsPosition(elements, direction, canvas) {
  34981. _each(elements, function(_, element) {
  34982. var options = element.getLayoutOptions(),
  34983. side = options.cutLayoutSide;
  34984. canvas[side] -= options[direction]
  34985. })
  34986. }
  34987. function placeElementAndCutCanvas(elements, canvas) {
  34988. _each(elements, function(_, element) {
  34989. var shiftX,
  34990. shiftY,
  34991. options = element.getLayoutOptions(),
  34992. length = getLength(options.cutLayoutSide);
  34993. if (!options.width)
  34994. return;
  34995. switch (options.horizontalAlignment) {
  34996. case"left":
  34997. shiftX = canvas.left;
  34998. break;
  34999. case"center":
  35000. shiftX = (canvas.width - canvas.left - canvas.right - options.width) / 2 + canvas.left;
  35001. break;
  35002. case"right":
  35003. shiftX = canvas.width - canvas.right - options.width;
  35004. break
  35005. }
  35006. switch (options.verticalAlignment) {
  35007. case"top":
  35008. shiftY = canvas.top;
  35009. break;
  35010. case"bottom":
  35011. shiftY = canvas.height - canvas.bottom - options.height;
  35012. break
  35013. }
  35014. element.shift(_round(shiftX), _round(shiftY));
  35015. canvas[options.cutLayoutSide] += options[length];
  35016. setCanvasValues(canvas)
  35017. })
  35018. }
  35019. function getLength(side) {
  35020. return side === 'left' || side === 'right' ? 'width' : 'height'
  35021. }
  35022. function setCanvasValues(canvas) {
  35023. if (canvas) {
  35024. canvas.originalTop = canvas.top;
  35025. canvas.originalBottom = canvas.bottom;
  35026. canvas.originalLeft = canvas.left;
  35027. canvas.originalRight = canvas.right
  35028. }
  35029. }
  35030. function updateElements(elements, length, otherLength, dirtyCanvas, canvas, needRemoveSpace) {
  35031. _each(elements, function(_, element) {
  35032. var options = element.getLayoutOptions(),
  35033. side = options.cutLayoutSide,
  35034. freeSpaceWidth = dirtyCanvas.width - dirtyCanvas.left - dirtyCanvas.right,
  35035. freeSpaceHeight = dirtyCanvas.height - dirtyCanvas.top - dirtyCanvas.bottom,
  35036. updateObject = {};
  35037. element.setSize({
  35038. width: freeSpaceWidth,
  35039. height: freeSpaceHeight
  35040. });
  35041. updateObject[otherLength] = 0;
  35042. updateObject[length] = needRemoveSpace[length];
  35043. element.changeSize(updateObject);
  35044. canvas[side] -= options[length] - element.getLayoutOptions()[length];
  35045. needRemoveSpace[length] -= options[length] - element.getLayoutOptions()[length]
  35046. })
  35047. }
  35048. function updateAxis(axes, side, needRemoveSpace) {
  35049. if (axes && needRemoveSpace[side] > 0) {
  35050. _each(axes, function(i, axis) {
  35051. var bbox = axis.getBoundingRect();
  35052. axis.updateSize();
  35053. needRemoveSpace[side] -= bbox[side] - axis.getBoundingRect()[side]
  35054. });
  35055. if (needRemoveSpace[side] > 0)
  35056. _each(axes, function(_, axis) {
  35057. axis.updateSize(true)
  35058. })
  35059. }
  35060. }
  35061. function getNearestCoord(firstCoord, secondCoord, pointCenterCoord) {
  35062. var nearestCoord;
  35063. if (pointCenterCoord < firstCoord)
  35064. nearestCoord = firstCoord;
  35065. else if (secondCoord < pointCenterCoord)
  35066. nearestCoord = secondCoord;
  35067. else
  35068. nearestCoord = pointCenterCoord;
  35069. return nearestCoord
  35070. }
  35071. function getLengthFromCenter(x, y, paneCenterX, paneCenterY) {
  35072. return _sqrt((x - paneCenterX) * (x - paneCenterX) + (y - paneCenterY) * (y - paneCenterY))
  35073. }
  35074. function getInnerRadius(series) {
  35075. var innerRadius;
  35076. if (series.type === "pie")
  35077. innerRadius = 0;
  35078. else {
  35079. innerRadius = _isNumber(series.innerRadius) ? Number(series.innerRadius) : 0.5;
  35080. innerRadius = innerRadius < 0.2 ? 0.2 : innerRadius;
  35081. innerRadius = innerRadius > 0.8 ? 0.8 : innerRadius
  35082. }
  35083. return innerRadius
  35084. }
  35085. function isValidBox(box) {
  35086. return !!(box.x || box.y || box.width || box.height)
  35087. }
  35088. function correctDeltaMarginValue(panes, marginSides) {
  35089. var canvas,
  35090. deltaSide,
  35091. requireAxesRedraw = false;
  35092. _each(panes, function(_, pane) {
  35093. canvas = pane.canvas;
  35094. _each(marginSides, function(_, side) {
  35095. deltaSide = "delta" + side;
  35096. canvas[deltaSide] = _max(canvas[deltaSide] - (canvas[side.toLowerCase()] - canvas["original" + side]), 0);
  35097. if (canvas[deltaSide] > 0)
  35098. requireAxesRedraw = true
  35099. })
  35100. });
  35101. return requireAxesRedraw
  35102. }
  35103. function getPane(name, panes) {
  35104. var findPane = panes[0];
  35105. _each(panes, function(_, pane) {
  35106. if (name === pane.name)
  35107. findPane = pane
  35108. });
  35109. return findPane
  35110. }
  35111. function applyFoundExceedings(panes, rotated) {
  35112. var stopDrawAxes = false,
  35113. maxLeft = 0,
  35114. maxRight = 0,
  35115. maxTop = 0,
  35116. maxBottom = 0;
  35117. _each(panes, function(_, pane) {
  35118. maxLeft = _max(maxLeft, pane.canvas.deltaLeft);
  35119. maxRight = _max(maxRight, pane.canvas.deltaRight);
  35120. maxTop = _max(maxTop, pane.canvas.deltaTop);
  35121. maxBottom = _max(maxBottom, pane.canvas.deltaBottom)
  35122. });
  35123. if (rotated)
  35124. _each(panes, function(_, pane) {
  35125. pane.canvas.top += maxTop;
  35126. pane.canvas.bottom += maxBottom;
  35127. pane.canvas.right += pane.canvas.deltaRight;
  35128. pane.canvas.left += pane.canvas.deltaLeft
  35129. });
  35130. else
  35131. _each(panes, function(_, pane) {
  35132. pane.canvas.top += pane.canvas.deltaTop;
  35133. pane.canvas.bottom += pane.canvas.deltaBottom;
  35134. pane.canvas.right += maxRight;
  35135. pane.canvas.left += maxLeft
  35136. });
  35137. _each(panes, function(_, pane) {
  35138. if (pane.canvas.top + pane.canvas.bottom > pane.canvas.height)
  35139. stopDrawAxes = true;
  35140. if (pane.canvas.left + pane.canvas.right > pane.canvas.width)
  35141. stopDrawAxes = true
  35142. });
  35143. return stopDrawAxes
  35144. }
  35145. function LayoutManager(options) {
  35146. this._verticalElements = [];
  35147. this._horizontalElements = [];
  35148. this._options = options
  35149. }
  35150. LayoutManager.prototype = {
  35151. constructor: LayoutManager,
  35152. dispose: function() {
  35153. this._verticalElements = this._horizontalElements = this._options = null
  35154. },
  35155. drawElements: function(elements, canvas) {
  35156. var horizontalElements = [],
  35157. verticalElements = [];
  35158. _each(elements, function(_, element) {
  35159. var options,
  35160. length;
  35161. element.setSize({
  35162. width: canvas.width - canvas.left - canvas.right,
  35163. height: canvas.height - canvas.top - canvas.bottom
  35164. });
  35165. element.draw();
  35166. options = element.getLayoutOptions();
  35167. if (options) {
  35168. length = getLength(options.cutLayoutSide);
  35169. (length === 'width' ? horizontalElements : verticalElements).push(element);
  35170. canvas[options.cutLayoutSide] += options[length];
  35171. setCanvasValues(canvas)
  35172. }
  35173. });
  35174. this._horizontalElements = horizontalElements;
  35175. this._verticalElements = verticalElements;
  35176. return this
  35177. },
  35178. placeDrawnElements: function(canvas) {
  35179. correctElementsPosition(this._horizontalElements, 'width', canvas);
  35180. placeElementAndCutCanvas(this._horizontalElements, canvas);
  35181. correctElementsPosition(this._verticalElements, 'height', canvas);
  35182. placeElementAndCutCanvas(this._verticalElements, canvas);
  35183. return this
  35184. },
  35185. updatePanesCanvases: function(panes, canvas, rotated) {
  35186. var weightSum = 0;
  35187. _each(panes, function(_, pane) {
  35188. pane.weight = pane.weight || 1;
  35189. weightSum += pane.weight
  35190. });
  35191. var distributedSpace = 0,
  35192. padding = panes.padding || 10,
  35193. paneSpace = rotated ? canvas.width - canvas.left - canvas.right : canvas.height - canvas.top - canvas.bottom,
  35194. oneWeight = (paneSpace - padding * (panes.length - 1)) / weightSum,
  35195. startName = rotated ? "left" : "top",
  35196. endName = rotated ? "right" : "bottom";
  35197. _each(panes, function(_, pane) {
  35198. var calcLength = _round(pane.weight * oneWeight);
  35199. pane.canvas = pane.canvas || {};
  35200. _extend(pane.canvas, {
  35201. deltaLeft: 0,
  35202. deltaRight: 0,
  35203. deltaTop: 0,
  35204. deltaBottom: 0
  35205. }, canvas);
  35206. pane.canvas[startName] = canvas[startName] + distributedSpace;
  35207. pane.canvas[endName] = canvas[endName] + (paneSpace - calcLength - distributedSpace);
  35208. distributedSpace = distributedSpace + calcLength + padding;
  35209. setCanvasValues(pane.canvas)
  35210. })
  35211. },
  35212. applyVerticalAxesLayout: function(axes, panes, rotated) {
  35213. this._applyAxesLayout(axes, panes, rotated)
  35214. },
  35215. applyHorizontalAxesLayout: function(axes, panes, rotated) {
  35216. axes.reverse();
  35217. this._applyAxesLayout(axes, panes, rotated);
  35218. axes.reverse()
  35219. },
  35220. _applyAxesLayout: function(axes, panes, rotated) {
  35221. var that = this,
  35222. canvas,
  35223. axisPosition,
  35224. box,
  35225. delta,
  35226. axis,
  35227. axisLength,
  35228. direction,
  35229. directionMultiplier,
  35230. someDirection = [],
  35231. pane,
  35232. i;
  35233. _each(panes, function(_, pane) {
  35234. _extend(pane.canvas, {
  35235. deltaLeft: 0,
  35236. deltaRight: 0,
  35237. deltaTop: 0,
  35238. deltaBottom: 0
  35239. })
  35240. });
  35241. for (i = 0; i < axes.length; i++) {
  35242. axis = axes[i];
  35243. axisPosition = axis.getOptions().position || "left";
  35244. axis.delta = {};
  35245. box = axis.getBoundingRect();
  35246. pane = getPane(axis.pane, panes);
  35247. canvas = pane.canvas;
  35248. if (!isValidBox(box))
  35249. continue;
  35250. direction = "delta" + axisPosition.slice(0, 1).toUpperCase() + axisPosition.slice(1);
  35251. switch (axisPosition) {
  35252. case"right":
  35253. directionMultiplier = 1;
  35254. canvas.deltaLeft += axis.padding ? axis.padding.left : 0;
  35255. break;
  35256. case"left":
  35257. directionMultiplier = -1;
  35258. canvas.deltaRight += axis.padding ? axis.padding.right : 0;
  35259. break;
  35260. case"top":
  35261. directionMultiplier = -1;
  35262. canvas.deltaBottom += axis.padding ? axis.padding.bottom : 0;
  35263. break;
  35264. case"bottom":
  35265. directionMultiplier = 1;
  35266. canvas.deltaTop += axis.padding ? axis.padding.top : 0;
  35267. break
  35268. }
  35269. switch (axisPosition) {
  35270. case"right":
  35271. case"left":
  35272. if (!box.isEmpty) {
  35273. delta = box.y + box.height - (canvas.height - canvas.originalBottom);
  35274. if (delta > 0) {
  35275. that.requireAxesRedraw = true;
  35276. canvas.deltaBottom += delta
  35277. }
  35278. delta = canvas.originalTop - box.y;
  35279. if (delta > 0) {
  35280. that.requireAxesRedraw = true;
  35281. canvas.deltaTop += delta
  35282. }
  35283. }
  35284. axisLength = box.width;
  35285. someDirection = ["Left", "Right"];
  35286. break;
  35287. case"top":
  35288. case"bottom":
  35289. if (!box.isEmpty) {
  35290. delta = box.x + box.width - (canvas.width - canvas.originalRight);
  35291. if (delta > 0) {
  35292. that.requireAxesRedraw = true;
  35293. canvas.deltaRight += delta
  35294. }
  35295. delta = canvas.originalLeft - box.x;
  35296. if (delta > 0) {
  35297. that.requireAxesRedraw = true;
  35298. canvas.deltaLeft += delta
  35299. }
  35300. }
  35301. someDirection = ["Bottom", "Top"];
  35302. axisLength = box.height;
  35303. break
  35304. }
  35305. if (!axis.delta[axisPosition] && canvas[direction] > 0)
  35306. canvas[direction] += axis.getMultipleAxesSpacing();
  35307. axis.delta[axisPosition] = axis.delta[axisPosition] || 0;
  35308. axis.delta[axisPosition] += canvas[direction] * directionMultiplier;
  35309. canvas[direction] += axisLength
  35310. }
  35311. that.requireAxesRedraw = correctDeltaMarginValue(panes, someDirection) || that.requireAxesRedraw;
  35312. that.stopDrawAxes = applyFoundExceedings(panes, rotated)
  35313. },
  35314. applyPieChartSeriesLayout: function(canvas, singleSeries, hideLayoutLabels) {
  35315. var paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,
  35316. paneSpaceWidth = canvas.width - canvas.left - canvas.right,
  35317. paneCenterX = paneSpaceWidth / 2 + canvas.left,
  35318. paneCenterY = paneSpaceHeight / 2 + canvas.top,
  35319. piePercentage = this._options.piePercentage,
  35320. accessibleRadius = _isNumber(piePercentage) ? piePercentage * _min(canvas.height, canvas.width) / 2 : _min(paneSpaceWidth, paneSpaceHeight) / 2,
  35321. minR = 0.7 * accessibleRadius,
  35322. innerRadius = getInnerRadius(singleSeries);
  35323. if (!hideLayoutLabels && !_isNumber(piePercentage))
  35324. _each(singleSeries.getPoints(), function(_, point) {
  35325. if (point._label.isVisible() && point.isVisible()) {
  35326. var labelBBox = point._label.getBoundingRect(),
  35327. nearestX = getNearestCoord(labelBBox.x, labelBBox.x + labelBBox.width, paneCenterX),
  35328. nearestY = getNearestCoord(labelBBox.y, labelBBox.y + labelBBox.height, paneCenterY),
  35329. minRadiusWithLabels = _max(getLengthFromCenter(nearestX, nearestY, paneCenterX, paneCenterY) - DX.viz.core.series.helpers.consts.pieLabelIndent, minR);
  35330. accessibleRadius = _min(accessibleRadius, minRadiusWithLabels)
  35331. }
  35332. });
  35333. singleSeries.correctPosition({
  35334. centerX: _floor(paneCenterX),
  35335. centerY: _floor(paneCenterY),
  35336. radiusInner: _floor(accessibleRadius * innerRadius),
  35337. radiusOuter: _floor(accessibleRadius)
  35338. })
  35339. },
  35340. updateDrawnElements: function(axes, canvas, dirtyCanvas, panes, rotated) {
  35341. var needRemoveSpace,
  35342. saveDirtyCanvas = _extend({}, dirtyCanvas);
  35343. needRemoveSpace = this.needMoreSpaceForPanesCanvas(panes, rotated);
  35344. if (!needRemoveSpace)
  35345. return;
  35346. needRemoveSpace.height = _decreaseGaps(dirtyCanvas, ["top", "bottom"], needRemoveSpace.height);
  35347. needRemoveSpace.width = _decreaseGaps(dirtyCanvas, ["left", "right"], needRemoveSpace.width);
  35348. canvas.top -= saveDirtyCanvas.top - dirtyCanvas.top;
  35349. canvas.bottom -= saveDirtyCanvas.bottom - dirtyCanvas.bottom;
  35350. canvas.left -= saveDirtyCanvas.left - dirtyCanvas.left;
  35351. canvas.right -= saveDirtyCanvas.right - dirtyCanvas.right;
  35352. updateElements(this._horizontalElements, "width", "height", dirtyCanvas, canvas, needRemoveSpace);
  35353. updateElements(this._verticalElements, "height", "width", dirtyCanvas, canvas, needRemoveSpace);
  35354. updateAxis(axes.verticalAxes, "width", needRemoveSpace);
  35355. updateAxis(axes.horizontalAxes, "height", needRemoveSpace)
  35356. },
  35357. needMoreSpaceForPanesCanvas: function(panes, rotated) {
  35358. var options = this._options,
  35359. width = options.width,
  35360. height = options.height,
  35361. piePercentage = options.piePercentage,
  35362. percentageIsValid = _isNumber(piePercentage),
  35363. needHorizontalSpace = 0,
  35364. needVerticalSpace = 0;
  35365. _each(panes, function(_, pane) {
  35366. var paneCanvas = pane.canvas,
  35367. minSize = percentageIsValid ? _min(paneCanvas.width, paneCanvas.height) * piePercentage : undefined,
  35368. needPaneHorizonralSpace = (percentageIsValid ? minSize : width) - (paneCanvas.width - paneCanvas.left - paneCanvas.right),
  35369. needPaneVerticalSpace = (percentageIsValid ? minSize : height) - (paneCanvas.height - paneCanvas.top - paneCanvas.bottom);
  35370. if (rotated) {
  35371. needHorizontalSpace += needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0;
  35372. needVerticalSpace = _max(needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0, needVerticalSpace)
  35373. }
  35374. else {
  35375. needHorizontalSpace = _max(needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0, needHorizontalSpace);
  35376. needVerticalSpace += needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0
  35377. }
  35378. });
  35379. return needHorizontalSpace > 0 || needVerticalSpace > 0 ? {
  35380. width: needHorizontalSpace,
  35381. height: needVerticalSpace
  35382. } : false
  35383. },
  35384. correctSizeElement: function(element, canvas) {
  35385. element.setSize({
  35386. width: canvas.width - canvas.right - canvas.left,
  35387. height: canvas.width - canvas.right - canvas.left
  35388. });
  35389. element.changeSize({
  35390. width: 0,
  35391. height: 0
  35392. })
  35393. }
  35394. };
  35395. DX.viz.charts._setCanvasValues = setCanvasValues;
  35396. DX.viz.charts.LayoutManager = LayoutManager
  35397. })(jQuery, DevExpress);
  35398. /*! Module viz-charts, file multiAxesSynchronizer.js */
  35399. (function($, DX, undefined) {
  35400. var Range = DX.viz.core.Range,
  35401. utils = DX.utils,
  35402. _adjustValue = utils.adjustValue,
  35403. _applyPrecisionByMinDelta = utils.applyPrecisionByMinDelta,
  35404. _isDefined = utils.isDefined,
  35405. _math = Math,
  35406. _floor = _math.floor,
  35407. _max = _math.max,
  35408. _each = $.each,
  35409. MIN_RANGE_FOR_ADJUST_BOUNDS = 0.1;
  35410. var getValueAxesPerPanes = function(valueAxes) {
  35411. var result = {};
  35412. _each(valueAxes, function(_, axis) {
  35413. var pane = axis.pane;
  35414. if (!result[pane])
  35415. result[pane] = [];
  35416. result[pane].push(axis)
  35417. });
  35418. return result
  35419. };
  35420. var restoreOriginalBusinessRange = function(axis) {
  35421. var businessRange,
  35422. translator = axis.getTranslator();
  35423. if (!translator._originalBusinessRange)
  35424. translator._originalBusinessRange = new Range(translator.getBusinessRange());
  35425. else {
  35426. businessRange = new Range(translator._originalBusinessRange);
  35427. translator.updateBusinessRange(businessRange)
  35428. }
  35429. };
  35430. var linearConvertor = {
  35431. transform: function(v, b) {
  35432. return utils.getLog(v, b)
  35433. },
  35434. addInterval: function(v, i) {
  35435. return v + i
  35436. },
  35437. getInterval: function(base, tickInterval) {
  35438. return tickInterval
  35439. },
  35440. adjustValue: _floor
  35441. };
  35442. var logConvertor = {
  35443. transform: function(v, b) {
  35444. return utils.raiseTo(v, b)
  35445. },
  35446. addInterval: function(v, i) {
  35447. return v * i
  35448. },
  35449. getInterval: function(base, tickInterval) {
  35450. return _math.pow(base, tickInterval)
  35451. },
  35452. adjustValue: _adjustValue
  35453. };
  35454. var convertAxisInfo = function(axisInfo, convertor) {
  35455. if (!axisInfo.isLogarithmic)
  35456. return;
  35457. var base = axisInfo.logarithmicBase,
  35458. tickValues = axisInfo.tickValues,
  35459. tick,
  35460. ticks = [],
  35461. interval,
  35462. i;
  35463. axisInfo.minValue = convertor.transform(axisInfo.minValue, base);
  35464. axisInfo.oldMinValue = convertor.transform(axisInfo.oldMinValue, base);
  35465. axisInfo.maxValue = convertor.transform(axisInfo.maxValue, base);
  35466. axisInfo.oldMaxValue = convertor.transform(axisInfo.oldMaxValue, base);
  35467. axisInfo.tickInterval = _math.round(axisInfo.tickInterval);
  35468. if (axisInfo.tickInterval < 1)
  35469. axisInfo.tickInterval = 1;
  35470. interval = convertor.getInterval(base, axisInfo.tickInterval);
  35471. tick = convertor.transform(tickValues[0], base);
  35472. for (i = 0; i < tickValues.length; i++) {
  35473. ticks.push(convertor.adjustValue(tick));
  35474. tick = convertor.addInterval(tick, interval)
  35475. }
  35476. ticks.tickInterval = axisInfo.tickInterval;
  35477. axisInfo.tickValues = ticks
  35478. };
  35479. var populateAxesInfo = function(axes) {
  35480. return $.map(axes, function(axis) {
  35481. restoreOriginalBusinessRange(axis);
  35482. var ticksValues = axis.getTicksValues(),
  35483. majorTicks = ticksValues.majorTicksValues,
  35484. options = axis.getOptions(),
  35485. minValue,
  35486. maxValue,
  35487. axisInfo = null,
  35488. businessRange,
  35489. tickInterval,
  35490. synchronizedValue;
  35491. if (majorTicks && majorTicks.length > 0 && utils.isNumber(majorTicks[0]) && options.type !== "discrete") {
  35492. businessRange = axis.getTranslator().getBusinessRange();
  35493. tickInterval = axis._tickManager.getTickInterval();
  35494. minValue = businessRange.minVisible;
  35495. maxValue = businessRange.maxVisible;
  35496. synchronizedValue = options.synchronizedValue;
  35497. if (minValue === maxValue && _isDefined(synchronizedValue)) {
  35498. minValue = majorTicks[0] - 1;
  35499. maxValue = majorTicks[0] + 1;
  35500. tickInterval = 1
  35501. }
  35502. axisInfo = {
  35503. axis: axis,
  35504. isLogarithmic: options.type === "logarithmic",
  35505. logarithmicBase: businessRange.base,
  35506. tickValues: majorTicks,
  35507. minorValues: ticksValues.minorTicksValues,
  35508. minValue: minValue,
  35509. oldMinValue: minValue,
  35510. maxValue: maxValue,
  35511. oldMaxValue: maxValue,
  35512. inverted: businessRange.invert,
  35513. tickInterval: tickInterval,
  35514. synchronizedValue: synchronizedValue
  35515. };
  35516. if (businessRange.stubData) {
  35517. axisInfo.stubData = true;
  35518. axisInfo.tickInterval = axisInfo.tickInterval || options.tickInterval;
  35519. axisInfo.isLogarithmic = false
  35520. }
  35521. convertAxisInfo(axisInfo, linearConvertor);
  35522. DX.utils.debug.assert(axisInfo.tickInterval !== undefined && axisInfo.tickInterval !== null, "tickInterval was not provided")
  35523. }
  35524. return axisInfo
  35525. })
  35526. };
  35527. var updateTickValues = function(axesInfo) {
  35528. var maxTicksCount = 0;
  35529. _each(axesInfo, function(_, axisInfo) {
  35530. maxTicksCount = _max(maxTicksCount, axisInfo.tickValues.length)
  35531. });
  35532. _each(axesInfo, function(_, axisInfo) {
  35533. var ticksMultiplier,
  35534. ticksCount,
  35535. additionalStartTicksCount = 0,
  35536. synchronizedValue = axisInfo.synchronizedValue,
  35537. tickValues = axisInfo.tickValues,
  35538. tickInterval = axisInfo.tickInterval;
  35539. if (_isDefined(synchronizedValue)) {
  35540. axisInfo.baseTickValue = axisInfo.invertedBaseTickValue = synchronizedValue;
  35541. axisInfo.tickValues = [axisInfo.baseTickValue]
  35542. }
  35543. else {
  35544. if (tickValues.length > 1 && tickInterval) {
  35545. ticksMultiplier = _floor((maxTicksCount + 1) / tickValues.length);
  35546. ticksCount = ticksMultiplier > 1 ? _floor((maxTicksCount + 1) / ticksMultiplier) : maxTicksCount;
  35547. additionalStartTicksCount = _floor((ticksCount - tickValues.length) / 2);
  35548. while (additionalStartTicksCount > 0 && tickValues[0] !== 0) {
  35549. tickValues.unshift(_applyPrecisionByMinDelta(tickValues[0], tickInterval, tickValues[0] - tickInterval));
  35550. additionalStartTicksCount--
  35551. }
  35552. while (tickValues.length < ticksCount)
  35553. tickValues.push(_applyPrecisionByMinDelta(tickValues[0], tickInterval, tickValues[tickValues.length - 1] + tickInterval));
  35554. axisInfo.tickInterval = tickInterval / ticksMultiplier
  35555. }
  35556. axisInfo.baseTickValue = tickValues[0];
  35557. axisInfo.invertedBaseTickValue = tickValues[tickValues.length - 1]
  35558. }
  35559. })
  35560. };
  35561. var getAxisRange = function(axisInfo) {
  35562. return axisInfo.maxValue - axisInfo.minValue || 1
  35563. };
  35564. var getMainAxisInfo = function(axesInfo) {
  35565. for (var i = 0; i < axesInfo.length; i++)
  35566. if (!axesInfo[i].stubData)
  35567. return axesInfo[i];
  35568. return null
  35569. };
  35570. var correctMinMaxValues = function(axesInfo) {
  35571. var mainAxisInfo = getMainAxisInfo(axesInfo),
  35572. mainAxisInfoTickInterval = mainAxisInfo.tickInterval;
  35573. _each(axesInfo, function(_, axisInfo) {
  35574. var scale,
  35575. move,
  35576. mainAxisBaseValueOffset,
  35577. valueFromAxisInfo;
  35578. if (axisInfo !== mainAxisInfo) {
  35579. if (mainAxisInfoTickInterval && axisInfo.tickInterval) {
  35580. if (axisInfo.stubData && _isDefined(axisInfo.synchronizedValue)) {
  35581. axisInfo.oldMinValue = axisInfo.minValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.minValue) / mainAxisInfoTickInterval * axisInfo.tickInterval;
  35582. axisInfo.oldMaxValue = axisInfo.maxValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.maxValue) / mainAxisInfoTickInterval * axisInfo.tickInterval
  35583. }
  35584. scale = mainAxisInfoTickInterval / getAxisRange(mainAxisInfo) / axisInfo.tickInterval * getAxisRange(axisInfo);
  35585. axisInfo.maxValue = axisInfo.minValue + getAxisRange(axisInfo) / scale
  35586. }
  35587. if (mainAxisInfo.inverted && !axisInfo.inverted || !mainAxisInfo.inverted && axisInfo.inverted)
  35588. mainAxisBaseValueOffset = mainAxisInfo.maxValue - mainAxisInfo.invertedBaseTickValue;
  35589. else
  35590. mainAxisBaseValueOffset = mainAxisInfo.baseTickValue - mainAxisInfo.minValue;
  35591. valueFromAxisInfo = getAxisRange(axisInfo);
  35592. move = (mainAxisBaseValueOffset / getAxisRange(mainAxisInfo) - (axisInfo.baseTickValue - axisInfo.minValue) / valueFromAxisInfo) * valueFromAxisInfo;
  35593. axisInfo.minValue -= move;
  35594. axisInfo.maxValue -= move
  35595. }
  35596. })
  35597. };
  35598. var calculatePaddings = function(axesInfo) {
  35599. var minPadding,
  35600. maxPadding,
  35601. startPadding = 0,
  35602. endPadding = 0;
  35603. _each(axesInfo, function(_, axisInfo) {
  35604. var inverted = axisInfo.inverted;
  35605. minPadding = axisInfo.minValue > axisInfo.oldMinValue ? (axisInfo.minValue - axisInfo.oldMinValue) / getAxisRange(axisInfo) : 0;
  35606. maxPadding = axisInfo.maxValue < axisInfo.oldMaxValue ? (axisInfo.oldMaxValue - axisInfo.maxValue) / getAxisRange(axisInfo) : 0;
  35607. startPadding = _max(startPadding, inverted ? maxPadding : minPadding);
  35608. endPadding = _max(endPadding, inverted ? minPadding : maxPadding)
  35609. });
  35610. return {
  35611. start: startPadding,
  35612. end: endPadding
  35613. }
  35614. };
  35615. var correctMinMaxValuesByPaddings = function(axesInfo, paddings) {
  35616. _each(axesInfo, function(_, info) {
  35617. var range = getAxisRange(info),
  35618. inverted = info.inverted;
  35619. info.minValue -= paddings[inverted ? "end" : "start"] * range;
  35620. info.maxValue += paddings[inverted ? "start" : "end"] * range;
  35621. if (range > MIN_RANGE_FOR_ADJUST_BOUNDS) {
  35622. info.minValue = _math.min(info.minValue, _adjustValue(info.minValue));
  35623. info.maxValue = _max(info.maxValue, _adjustValue(info.maxValue))
  35624. }
  35625. })
  35626. };
  35627. var updateTickValuesIfSyncronizedValueUsed = function(axesInfo) {
  35628. var hasSyncronizedValue = false;
  35629. _each(axesInfo, function(_, info) {
  35630. hasSyncronizedValue = hasSyncronizedValue || _isDefined(info.synchronizedValue)
  35631. });
  35632. _each(axesInfo, function(_, info) {
  35633. var lastTickValue,
  35634. tickInterval = info.tickInterval,
  35635. tickValues = info.tickValues,
  35636. maxValue = info.maxValue,
  35637. minValue = info.minValue;
  35638. if (hasSyncronizedValue && tickInterval) {
  35639. while (tickValues[0] - tickInterval >= minValue)
  35640. tickValues.unshift(_adjustValue(tickValues[0] - tickInterval));
  35641. lastTickValue = tickValues[tickValues.length - 1];
  35642. while ((lastTickValue = lastTickValue + tickInterval) <= maxValue)
  35643. tickValues.push(utils.isExponential(lastTickValue) ? _adjustValue(lastTickValue) : _applyPrecisionByMinDelta(minValue, tickInterval, lastTickValue))
  35644. }
  35645. while (tickValues[0] < minValue)
  35646. tickValues.shift();
  35647. while (tickValues[tickValues.length - 1] > maxValue)
  35648. tickValues.pop()
  35649. })
  35650. };
  35651. var applyMinMaxValues = function(axesInfo) {
  35652. _each(axesInfo, function(_, info) {
  35653. var axis = info.axis,
  35654. range = axis.getTranslator().getBusinessRange();
  35655. if (range.min === range.minVisible)
  35656. range.min = info.minValue;
  35657. if (range.max === range.maxVisible)
  35658. range.max = info.maxValue;
  35659. range.minVisible = info.minValue;
  35660. range.maxVisible = info.maxValue;
  35661. if (_isDefined(info.stubData))
  35662. range.stubData = info.stubData;
  35663. if (range.min > range.minVisible)
  35664. range.min = range.minVisible;
  35665. if (range.max < range.maxVisible)
  35666. range.max = range.maxVisible;
  35667. range.isSynchronized = true;
  35668. axis.getTranslator().updateBusinessRange(range);
  35669. axis.setTicks({
  35670. majorTicks: info.tickValues,
  35671. minorTicks: info.minorValues
  35672. })
  35673. })
  35674. };
  35675. var correctAfterSynchronize = function(axesInfo) {
  35676. var invalidAxisInfo = [],
  35677. correctValue,
  35678. validAxisInfo;
  35679. _each(axesInfo, function(i, info) {
  35680. if (info.oldMaxValue - info.oldMinValue === 0)
  35681. invalidAxisInfo.push(info);
  35682. else if (!_isDefined(correctValue) && !_isDefined(info.synchronizedValue)) {
  35683. correctValue = _math.abs((info.maxValue - info.minValue) / (info.tickValues[_floor(info.tickValues.length / 2)] || info.maxValue));
  35684. validAxisInfo = info
  35685. }
  35686. });
  35687. if (!_isDefined(correctValue))
  35688. return;
  35689. _each(invalidAxisInfo, function(i, info) {
  35690. var firstTick = info.tickValues[0],
  35691. correctedTick = firstTick * correctValue,
  35692. tickValues = validAxisInfo.tickValues,
  35693. centralTick = tickValues[_floor(tickValues.length / 2)];
  35694. if (firstTick > 0) {
  35695. info.maxValue = correctedTick;
  35696. info.minValue = 0
  35697. }
  35698. else if (firstTick < 0) {
  35699. info.minValue = correctedTick;
  35700. info.maxValue = 0
  35701. }
  35702. else if (firstTick === 0) {
  35703. info.maxValue = validAxisInfo.maxValue - centralTick;
  35704. info.minValue = validAxisInfo.minValue - centralTick
  35705. }
  35706. })
  35707. };
  35708. DX.viz.charts.multiAxesSynchronizer = {synchronize: function(valueAxes) {
  35709. _each(getValueAxesPerPanes(valueAxes), function(_, axes) {
  35710. var axesInfo,
  35711. paddings;
  35712. if (axes.length > 1) {
  35713. axesInfo = populateAxesInfo(axes);
  35714. if (axesInfo.length === 0 || !getMainAxisInfo(axesInfo))
  35715. return;
  35716. updateTickValues(axesInfo);
  35717. correctMinMaxValues(axesInfo);
  35718. paddings = calculatePaddings(axesInfo);
  35719. correctMinMaxValuesByPaddings(axesInfo, paddings);
  35720. correctAfterSynchronize(axesInfo);
  35721. updateTickValuesIfSyncronizedValueUsed(axesInfo);
  35722. _each(axesInfo, function() {
  35723. convertAxisInfo(this, logConvertor)
  35724. });
  35725. applyMinMaxValues(axesInfo)
  35726. }
  35727. })
  35728. }}
  35729. })(jQuery, DevExpress);
  35730. /*! Module viz-charts, file tracker.js */
  35731. (function($, DX, math) {
  35732. var charts = DX.viz.charts,
  35733. eventsConsts = DX.viz.core.series.helpers.consts.events,
  35734. utils = DX.utils,
  35735. isDefined = utils.isDefined,
  35736. _floor = math.floor,
  35737. _each = $.each,
  35738. MULTIPLE_MODE = 'multiple',
  35739. ALL_ARGUMENTS_POINTS_MODE = 'allargumentpoints',
  35740. ALL_SERIES_POINTS_MODE = 'allseriespoints',
  35741. NONE_MODE = 'none',
  35742. POINTER_ACTION = "dxpointerdown dxpointermove",
  35743. POINT_SELECTION_CHANGED = "pointSelectionChanged",
  35744. LEGEND_CLICK = "legendClick",
  35745. SERIES_CLICK = "seriesClick",
  35746. POINT_CLICK = "pointClick",
  35747. RELEASE_POINT_SELECTED_STATE = "releasePointSelectedState",
  35748. SET_POINT_SELECTED_STATE = "setPointSelectedState",
  35749. DELAY = 100;
  35750. function processMode(mode) {
  35751. return (mode + "").toLowerCase()
  35752. }
  35753. function getNonVirtualAxis(axisArray) {
  35754. var axis;
  35755. _each(axisArray, function(_, a) {
  35756. if (!a._virtual) {
  35757. axis = a;
  35758. return false
  35759. }
  35760. });
  35761. return axis
  35762. }
  35763. function eventCanceled(event, target) {
  35764. return event.cancel || !target.getOptions()
  35765. }
  35766. var baseTrackerPrototype = {
  35767. ctor: function(options) {
  35768. var that = this,
  35769. data = {tracker: that};
  35770. if (processMode(options.pointSelectionMode) === MULTIPLE_MODE) {
  35771. that._setSelectedPoint = that._selectPointMultipleMode;
  35772. that._releaseSelectedPoint = that._releaseSelectedPointMultipleMode
  35773. }
  35774. else {
  35775. that._setSelectedPoint = that._selectPointSingleMode;
  35776. that._releaseSelectedPoint = that._releaseSelectedPointSingleMode
  35777. }
  35778. if (processMode(options.seriesSelectionMode) === MULTIPLE_MODE) {
  35779. that._releaseSelectedSeries = that._releaseSelectedSeriesMultipleMode;
  35780. that._setSelectedSeries = that._setSelectedSeriesMultipleMode
  35781. }
  35782. else {
  35783. that._releaseSelectedSeries = that._releaseSelectedSeriesSingleMode;
  35784. that._setSelectedSeries = that._setSelectedSeriesSingleMode
  35785. }
  35786. that._renderer = options.renderer;
  35787. that._tooltip = options.tooltip;
  35788. that._eventTrigger = options.eventTrigger;
  35789. options.seriesGroup.off().on(eventsConsts.selectSeries, data, that._selectSeries).on(eventsConsts.deselectSeries, data, that._deselectSeries).on(eventsConsts.selectPoint, data, that._selectPoint).on(eventsConsts.deselectPoint, data, that._deselectPoint).on(eventsConsts.showPointTooltip, data, that._showPointTooltip).on(eventsConsts.hidePointTooltip, data, that._hidePointTooltip);
  35790. that._renderer.root.off(POINTER_ACTION).off("dxclick dxhold").on(POINTER_ACTION, data, that._pointerHandler).on("dxclick", data, that._clickHandler).on("dxhold", {timeout: 300}, $.noop)
  35791. },
  35792. update: function(options) {
  35793. var that = this;
  35794. if (that._storedSeries !== options.series) {
  35795. that._storedSeries = options.series || [];
  35796. that._clean()
  35797. }
  35798. else {
  35799. that._hideTooltip(that.pointAtShownTooltip);
  35800. that._clearHover();
  35801. that.clearSelection()
  35802. }
  35803. that._legend = options.legend;
  35804. that.legendCallback = options.legendCallback;
  35805. that._prepare(that._renderer.root)
  35806. },
  35807. setCanvases: function(mainCanvas, paneCanvases) {
  35808. this._mainCanvas = mainCanvas;
  35809. this._canvases = paneCanvases
  35810. },
  35811. repairTooltip: function() {
  35812. var point = this.pointAtShownTooltip;
  35813. if (point && !point.isVisible())
  35814. this._hideTooltip(point, true);
  35815. else
  35816. this._showTooltip(point)
  35817. },
  35818. _prepare: function(root) {
  35819. root.off("dxmousewheel").on("dxmousewheel", {tracker: this}, function(e) {
  35820. e.data.tracker._pointerOut()
  35821. })
  35822. },
  35823. _selectPointMultipleMode: function(point) {
  35824. var that = this;
  35825. that._selectedPoint = that._selectedPoint || [];
  35826. if ($.inArray(point, that._selectedPoint) < 0) {
  35827. that._selectedPoint.push(point);
  35828. that._setPointState(point, SET_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point))
  35829. }
  35830. },
  35831. _releaseSelectedPointMultipleMode: function(point) {
  35832. var that = this,
  35833. points = that._selectedPoint || [],
  35834. pointIndex = $.inArray(point, points);
  35835. if (pointIndex >= 0) {
  35836. that._setPointState(point, RELEASE_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point));
  35837. points.splice(pointIndex, 1)
  35838. }
  35839. else if (!point)
  35840. _each(points, function(_, point) {
  35841. that._releaseSelectedPoint(point)
  35842. })
  35843. },
  35844. _selectPointSingleMode: function(point) {
  35845. var that = this;
  35846. if (that._selectedPoint !== point) {
  35847. that._releaseSelectedPoint();
  35848. that._selectedPoint = point;
  35849. that._setPointState(point, SET_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point))
  35850. }
  35851. },
  35852. _releaseSelectedPointSingleMode: function() {
  35853. var that = this,
  35854. point = that._selectedPoint;
  35855. if (point) {
  35856. that._setPointState(point, RELEASE_POINT_SELECTED_STATE, processMode(point.getOptions().selectionMode), POINT_SELECTION_CHANGED, that.legendCallback(point));
  35857. that._selectedPoint = null
  35858. }
  35859. },
  35860. _setPointState: function(point, action, mode, eventName, legendCallback) {
  35861. var that = this;
  35862. switch (mode) {
  35863. case ALL_ARGUMENTS_POINTS_MODE:
  35864. that._toAllArgumentPoints(point.argument, action, eventName);
  35865. break;
  35866. case ALL_SERIES_POINTS_MODE:
  35867. _each(point.series.getPoints(), function(_, point) {
  35868. point.series[action](point);
  35869. that._eventTrigger(eventName, {target: point})
  35870. });
  35871. break;
  35872. case NONE_MODE:
  35873. break;
  35874. default:
  35875. point.series[action](point, legendCallback);
  35876. that._eventTrigger(eventName, {target: point})
  35877. }
  35878. },
  35879. _toAllArgumentPoints: function(argument, func, eventName) {
  35880. var that = this;
  35881. _each(that._storedSeries, function(_, series) {
  35882. var neighborPoints = series.getPointsByArg(argument);
  35883. _each(neighborPoints || [], function(_, point) {
  35884. series[func](point);
  35885. eventName && that._eventTrigger(eventName, {target: point})
  35886. })
  35887. })
  35888. },
  35889. _setHoveredPoint: function(point, mode) {
  35890. var that = this;
  35891. var debug = DX.utils.debug;
  35892. debug.assert(point.series, 'series was not assigned to point or empty');
  35893. if (that.hoveredPoint === point || !point.series)
  35894. return;
  35895. that._releaseHoveredPoint();
  35896. if (point && point.getOptions() && mode !== NONE_MODE) {
  35897. that.hoveredPoint = point;
  35898. that._setPointState(point, 'setPointHoverState', mode || processMode(point.getOptions().hoverMode), "pointHoverChanged", that.legendCallback(point))
  35899. }
  35900. },
  35901. _releaseHoveredPoint: function() {
  35902. var that = this,
  35903. point = that.hoveredPoint,
  35904. mode;
  35905. if (!point || !point.getOptions())
  35906. return;
  35907. mode = processMode(point.getOptions().hoverMode);
  35908. if (mode === ALL_SERIES_POINTS_MODE)
  35909. _each(point.series.getPoints(), function(_, point) {
  35910. point.series.releasePointHoverState(point);
  35911. that._eventTrigger("pointHoverChanged", {target: point})
  35912. });
  35913. else if (mode === ALL_ARGUMENTS_POINTS_MODE)
  35914. that._toAllArgumentPoints(point.argument, 'releasePointHoverState', "pointHoverChanged");
  35915. else {
  35916. point.releaseHoverState(that.legendCallback(point));
  35917. that._eventTrigger("pointHoverChanged", {target: point})
  35918. }
  35919. if (that._tooltip.isEnabled())
  35920. that._hideTooltip(point);
  35921. that.hoveredPoint = null
  35922. },
  35923. _setSelectedSeriesMultipleMode: function(series, mode) {
  35924. var that = this;
  35925. that._selectedSeries = that._selectedSeries || [];
  35926. if ($.inArray(series, that._selectedSeries) < 0) {
  35927. that._selectedSeries.push(series);
  35928. series.setSelectedState(true, mode, that.legendCallback(series));
  35929. that._eventTrigger("seriesSelectionChanged", {target: series})
  35930. }
  35931. },
  35932. _setSelectedSeriesSingleMode: function(series, mode) {
  35933. var that = this;
  35934. if (series !== that._selectedSeries || series.lastSelectionMode !== mode) {
  35935. this._releaseSelectedSeries();
  35936. that._selectedSeries = series;
  35937. series.setSelectedState(true, mode, that.legendCallback(series));
  35938. that._eventTrigger("seriesSelectionChanged", {target: series})
  35939. }
  35940. },
  35941. _releaseSelectedSeriesMultipleMode: function(series) {
  35942. var that = this,
  35943. selectedSeries = that._selectedSeries || [],
  35944. seriesIndex = $.inArray(series, selectedSeries);
  35945. if (seriesIndex >= 0) {
  35946. series.setSelectedState(false, undefined, that.legendCallback(series));
  35947. that._eventTrigger("seriesSelectionChanged", {target: series});
  35948. selectedSeries.splice(seriesIndex, 1)
  35949. }
  35950. else if (!series)
  35951. _each(selectedSeries, function(_, series) {
  35952. that._releaseSelectedSeries(series)
  35953. })
  35954. },
  35955. _releaseSelectedSeriesSingleMode: function() {
  35956. var that = this,
  35957. series = that._selectedSeries;
  35958. if (series) {
  35959. series.setSelectedState(false, undefined, that.legendCallback(series));
  35960. that._eventTrigger("seriesSelectionChanged", {target: series});
  35961. that._selectedSeries = null
  35962. }
  35963. },
  35964. _setHoveredSeries: function(series, mode) {
  35965. var that = this;
  35966. if (mode !== NONE_MODE && that.hoveredSeries !== series || series.lastHoverMode !== mode) {
  35967. that._clearHover();
  35968. series.setHoverState(true, mode, that.legendCallback(series));
  35969. that._eventTrigger("seriesHoverChanged", {target: series})
  35970. }
  35971. that.hoveredSeries = series;
  35972. if (mode === NONE_MODE)
  35973. $(series).trigger('NoneMode')
  35974. },
  35975. _releaseHoveredSeries: function() {
  35976. var that = this;
  35977. if (that.hoveredSeries) {
  35978. that.hoveredSeries.setHoverState(false, undefined, that.legendCallback(that.hoveredSeries));
  35979. that._eventTrigger("seriesHoverChanged", {target: that.hoveredSeries});
  35980. that.hoveredSeries = null
  35981. }
  35982. },
  35983. _selectSeries: function(event, mode) {
  35984. event.data.tracker._setSelectedSeries(event.target, mode)
  35985. },
  35986. _deselectSeries: function(event, mode) {
  35987. event.data.tracker._releaseSelectedSeries(event.target, mode)
  35988. },
  35989. _selectPoint: function(event, point) {
  35990. event.data.tracker._setSelectedPoint(point)
  35991. },
  35992. _deselectPoint: function(event, point) {
  35993. event.data.tracker._releaseSelectedPoint(point)
  35994. },
  35995. clearSelection: function() {
  35996. this._releaseSelectedPoint();
  35997. this._releaseSelectedSeries()
  35998. },
  35999. _clean: function() {
  36000. var that = this;
  36001. that._selectedPoint = that._selectedSeries = that.hoveredPoint = that.hoveredSeries = null;
  36002. that._hideTooltip(that.pointAtShownTooltip)
  36003. },
  36004. _clearHover: function() {
  36005. this._releaseHoveredSeries();
  36006. this._releaseHoveredPoint()
  36007. },
  36008. _hideTooltip: function(point, silent) {
  36009. var that = this;
  36010. if (!that._tooltip || point && that.pointAtShownTooltip !== point)
  36011. return;
  36012. if (!silent && that.pointAtShownTooltip)
  36013. that.pointAtShownTooltip = null;
  36014. that._tooltip.hide()
  36015. },
  36016. _showTooltip: function(point) {
  36017. var that = this,
  36018. tooltipFormatObject,
  36019. eventData;
  36020. if (point && point.getOptions()) {
  36021. tooltipFormatObject = point.getTooltipFormatObject(that._tooltip);
  36022. if (!isDefined(tooltipFormatObject.valueText) && !tooltipFormatObject.points || !point.isVisible())
  36023. return;
  36024. if (!that.pointAtShownTooltip || that.pointAtShownTooltip !== point)
  36025. eventData = {target: point};
  36026. var coords = point.getTooltipParams(that._tooltip.getLocation()),
  36027. rootOffset = that._renderer.getRootOffset();
  36028. coords.x += rootOffset.left;
  36029. coords.y += rootOffset.top;
  36030. if (!that._tooltip.show(tooltipFormatObject, coords, eventData))
  36031. return;
  36032. that.pointAtShownTooltip = point
  36033. }
  36034. },
  36035. _showPointTooltip: function(event, point) {
  36036. var that = event.data.tracker,
  36037. pointWithTooltip = that.pointAtShownTooltip;
  36038. if (pointWithTooltip && pointWithTooltip !== point)
  36039. that._hideTooltip(pointWithTooltip);
  36040. that._showTooltip(point)
  36041. },
  36042. _hidePointTooltip: function(event, point) {
  36043. event.data.tracker._hideTooltip(point)
  36044. },
  36045. _enableOutHandler: function() {
  36046. if (this._outHandler)
  36047. return;
  36048. var that = this,
  36049. handler = function(e) {
  36050. var rootOffset = that._renderer.getRootOffset(),
  36051. x = _floor(e.pageX - rootOffset.left),
  36052. y = _floor(e.pageY - rootOffset.top);
  36053. if (!that._inCanvas(that._mainCanvas, x, y)) {
  36054. that._pointerOut();
  36055. that._disableOutHandler()
  36056. }
  36057. };
  36058. $(document).on(POINTER_ACTION, handler);
  36059. this._outHandler = handler
  36060. },
  36061. _disableOutHandler: function() {
  36062. this._outHandler && $(document).off(POINTER_ACTION, this._outHandler);
  36063. this._outHandler = null
  36064. },
  36065. _pointerOut: function() {
  36066. this._clearHover();
  36067. this._tooltip.isEnabled() && this._hideTooltip(this.pointAtShownTooltip)
  36068. },
  36069. _inCanvas: function(canvas, x, y) {
  36070. return x >= canvas.left && x <= canvas.right && y >= canvas.top && y <= canvas.bottom
  36071. },
  36072. dispose: function() {
  36073. var that = this;
  36074. that._disableOutHandler();
  36075. _each(that, function(k) {
  36076. that[k] = null
  36077. })
  36078. }
  36079. };
  36080. charts.ChartTracker = function(options) {
  36081. this.ctor(options)
  36082. };
  36083. $.extend(charts.ChartTracker.prototype, baseTrackerPrototype, {
  36084. ctor: function(options) {
  36085. var that = this;
  36086. baseTrackerPrototype.ctor.call(that, options)
  36087. },
  36088. _pointClick: function(point, event) {
  36089. var that = this,
  36090. eventTrigger = that._eventTrigger,
  36091. series = point.series;
  36092. eventTrigger(POINT_CLICK, {
  36093. target: point,
  36094. jQueryEvent: event
  36095. }, function() {
  36096. !eventCanceled(event, series) && eventTrigger(SERIES_CLICK, {
  36097. target: series,
  36098. jQueryEvent: event
  36099. })
  36100. })
  36101. },
  36102. __trackerDelay: DELAY,
  36103. _legendClick: function(series, event) {
  36104. var that = this,
  36105. evetArgs = {
  36106. target: series,
  36107. jQueryEvent: event
  36108. },
  36109. eventTrigger = that._eventTrigger;
  36110. eventTrigger(LEGEND_CLICK, evetArgs, function() {
  36111. !eventCanceled(event, series) && eventTrigger(SERIES_CLICK, evetArgs)
  36112. })
  36113. },
  36114. update: function(options) {
  36115. var that = this;
  36116. that._zoomingMode = (options.zoomingMode + '').toLowerCase();
  36117. that._scrollingMode = (options.scrollingMode + '').toLowerCase();
  36118. baseTrackerPrototype.update.call(this, options);
  36119. that._argumentAxis = getNonVirtualAxis(options.argumentAxis || []);
  36120. that._axisHoverEnabled = that._argumentAxis && processMode(that._argumentAxis.getOptions().hoverMode) === ALL_ARGUMENTS_POINTS_MODE;
  36121. that._chart = options.chart;
  36122. that._rotated = options.rotated;
  36123. that._crosshair = options.crosshair
  36124. },
  36125. _getAxisArgument: function(event) {
  36126. var $target = $(event.target);
  36127. return event.target.tagName === "tspan" ? $target.parent().data('argument') : $target.data('argument')
  36128. },
  36129. _getCanvas: function(x, y) {
  36130. var that = this,
  36131. canvases = that._canvases || [];
  36132. for (var i = 0; i < canvases.length; i++) {
  36133. var c = canvases[i];
  36134. if (that._inCanvas(c, x, y))
  36135. return c
  36136. }
  36137. return null
  36138. },
  36139. _focusOnCanvas: function(canvas) {
  36140. if (!canvas && this._stickedSeries)
  36141. this._pointerOut()
  36142. },
  36143. _resetHoveredArgument: function() {
  36144. if (isDefined(this.hoveredArgument)) {
  36145. this._toAllArgumentPoints(this.hoveredArgument, 'releasePointHoverState');
  36146. this.hoveredArgument = null
  36147. }
  36148. },
  36149. _hideCrosshair: function() {
  36150. this._crosshair && this._crosshair.hide()
  36151. },
  36152. _moveCrosshair: function(point, x, y) {
  36153. if (point && this._crosshair && point.isVisible()) {
  36154. var coords = point.getCrosshairCoords(x, y),
  36155. r = point.getPointRadius();
  36156. this._crosshair.shift(coords.x, coords.y, r)
  36157. }
  36158. },
  36159. _prepare: function(root) {
  36160. var that = this,
  36161. touchScrollingEnabled = that._scrollingMode === 'all' || that._scrollingMode === 'touch',
  36162. touchZoomingEnabled = that._zoomingMode === 'all' || that._zoomingMode === 'touch',
  36163. cssValue = (!touchScrollingEnabled ? "pan-x pan-y " : '') + (!touchZoomingEnabled ? "pinch-zoom" : '') || "none",
  36164. rootStyles = {
  36165. 'touch-action': cssValue,
  36166. '-ms-touch-action': cssValue
  36167. },
  36168. wheelzoomingEnabled = that._zoomingMode === "all" || that._zoomingMode === "mouse";
  36169. root.off("dxmousewheel dxc-scroll-start dxc-scroll-move");
  36170. baseTrackerPrototype._prepare.call(that, root);
  36171. if (!that._gestureEndHandler) {
  36172. that._gestureEndHandler = function() {
  36173. that._gestureEnd && that._gestureEnd()
  36174. };
  36175. $(document).on("dxpointerup", that._gestureEndHandler)
  36176. }
  36177. wheelzoomingEnabled && root.on("dxmousewheel", function(e) {
  36178. var rootOffset = that._renderer.getRootOffset(),
  36179. x = that._rotated ? e.pageY - rootOffset.top : e.pageX - rootOffset.left,
  36180. scale = that._argumentAxis.getTranslator().getMinScale(e.delta > 0),
  36181. translate = x - x * scale,
  36182. zoom = that._argumentAxis.getTranslator().zoom(-translate, scale);
  36183. that._pointerOut();
  36184. that._chart.zoomArgument(zoom.min, zoom.max, true);
  36185. e.preventDefault();
  36186. e.stopPropagation()
  36187. });
  36188. root.on("dxc-scroll-start", function(e) {
  36189. that._gestureStart(that._getGestureParams(e, {
  36190. left: 0,
  36191. top: 0
  36192. }))
  36193. }).on("dxc-scroll-move", function(e) {
  36194. that._gestureChange(that._getGestureParams(e, {
  36195. left: 0,
  36196. top: 0
  36197. })) && e.preventDefault()
  36198. });
  36199. root.css(rootStyles)
  36200. },
  36201. _getGestureParams: function(e, offset) {
  36202. var that = this,
  36203. x1,
  36204. x2,
  36205. touches = e.pointers.length,
  36206. left,
  36207. right,
  36208. eventCoordField = that._rotated ? "pageY" : "pageX";
  36209. offset = that._rotated ? offset.top : offset.left;
  36210. if (touches === 2)
  36211. x1 = e.pointers[0][eventCoordField] - offset,
  36212. x2 = e.pointers[1][eventCoordField] - offset;
  36213. else if (touches === 1)
  36214. x1 = x2 = e.pointers[0][eventCoordField] - offset;
  36215. left = math.min(x1, x2);
  36216. right = math.max(x1, x2);
  36217. return {
  36218. center: left + (right - left) / 2,
  36219. distance: right - left,
  36220. touches: touches,
  36221. scale: 1,
  36222. pointerType: e.pointerType
  36223. }
  36224. },
  36225. _gestureStart: function(gestureParams) {
  36226. var that = this;
  36227. that._startGesture = that._startGesture || gestureParams;
  36228. if (that._startGesture.touches !== gestureParams.touches)
  36229. that._startGesture = gestureParams
  36230. },
  36231. _gestureChange: function(gestureParams) {
  36232. var that = this,
  36233. startGesture = that._startGesture,
  36234. gestureChanged = false,
  36235. scrollingEnabled = that._scrollingMode === 'all' || that._scrollingMode !== 'none' && that._scrollingMode === gestureParams.pointerType,
  36236. zoommingEnabled = that._zoomingMode === 'all' || that._zoomingMode === 'touch';
  36237. if (!startGesture)
  36238. return gestureChanged;
  36239. if (startGesture.touches === 1 && math.abs(startGesture.center - gestureParams.center) < 3) {
  36240. that._gestureStart(gestureParams);
  36241. return gestureChanged
  36242. }
  36243. if (startGesture.touches === 2 && zoommingEnabled) {
  36244. gestureChanged = true;
  36245. startGesture.scale = gestureParams.distance / startGesture.distance;
  36246. startGesture.scroll = gestureParams.center - startGesture.center + (startGesture.center - startGesture.center * startGesture.scale)
  36247. }
  36248. else if (startGesture.touches === 1 && scrollingEnabled) {
  36249. gestureChanged = true;
  36250. startGesture.scroll = gestureParams.center - startGesture.center
  36251. }
  36252. if (gestureChanged) {
  36253. startGesture.changed = gestureChanged;
  36254. that._chart._transformArgument(startGesture.scroll, startGesture.scale)
  36255. }
  36256. return gestureChanged
  36257. },
  36258. _gestureEnd: function() {
  36259. var that = this,
  36260. startGesture = that._startGesture,
  36261. zoom,
  36262. renderer = that._renderer;
  36263. that._startGesture = null;
  36264. function complete() {
  36265. that._chart.zoomArgument(zoom.min, zoom.max, true)
  36266. }
  36267. if (startGesture && startGesture.changed) {
  36268. zoom = that._argumentAxis._translator.zoom(-startGesture.scroll, startGesture.scale);
  36269. if (renderer.animationEnabled() && (-startGesture.scroll !== zoom.translate || startGesture.scale !== zoom.scale)) {
  36270. var translateDelta = -(startGesture.scroll + zoom.translate),
  36271. scaleDelta = startGesture.scale - zoom.scale;
  36272. renderer.root.animate({_: 0}, {
  36273. step: function(pos) {
  36274. var translateValue = -startGesture.scroll - translateDelta * pos;
  36275. var scaleValue = startGesture.scale - scaleDelta * pos;
  36276. that._chart._transformArgument(-translateValue, scaleValue)
  36277. },
  36278. complete: complete,
  36279. duration: 250
  36280. })
  36281. }
  36282. else
  36283. complete()
  36284. }
  36285. },
  36286. _clean: function() {
  36287. var that = this;
  36288. baseTrackerPrototype._clean.call(that);
  36289. that._resetTimer();
  36290. that._stickedSeries = null
  36291. },
  36292. _getSeriesForShared: function(x, y) {
  36293. var that = this,
  36294. points = [],
  36295. point = null,
  36296. distance = Infinity;
  36297. if (that._tooltip.isShared() && !that.hoveredSeries) {
  36298. _each(that._storedSeries, function(_, series) {
  36299. var point = series.getNeighborPoint(x, y);
  36300. point && points.push(point)
  36301. });
  36302. _each(points, function(_, p) {
  36303. var coords = p.getCrosshairCoords(x, y),
  36304. d = math.sqrt((x - coords.x) * (x - coords.x) + (y - coords.y) * (y - coords.y));
  36305. if (d < distance) {
  36306. point = p;
  36307. distance = d
  36308. }
  36309. })
  36310. }
  36311. return point && point.series
  36312. },
  36313. _setTimeout: function(callback, keeper) {
  36314. var that = this;
  36315. if (that._timeoutKeeper !== keeper) {
  36316. that._resetTimer();
  36317. that._hoverTimeout = setTimeout(function() {
  36318. callback();
  36319. that._timeoutKeeper = null
  36320. }, DELAY);
  36321. that._timeoutKeeper = keeper
  36322. }
  36323. },
  36324. _resetTimer: function() {
  36325. clearTimeout(this._hoverTimeout);
  36326. this._timeoutKeeper = this._hoverTimeout = null
  36327. },
  36328. _pointerHandler: function(e) {
  36329. var that = e.data.tracker,
  36330. rootOffset = that._renderer.getRootOffset(),
  36331. x = _floor(e.pageX - rootOffset.left),
  36332. y = _floor(e.pageY - rootOffset.top),
  36333. canvas = that._getCanvas(x, y),
  36334. series = $(e.target).data("series"),
  36335. point = $(e.target).data("point") || series && series.getPointByCoord(x, y);
  36336. that._enableOutHandler();
  36337. that._x = x;
  36338. that._y = y;
  36339. if (e.type === "dxpointerdown")
  36340. canvas && that._gestureStart(that._getGestureParams(e, rootOffset));
  36341. else if (that._startGesture && canvas)
  36342. if (that._gestureChange(that._getGestureParams(e, rootOffset))) {
  36343. that._pointerOut();
  36344. e.preventDefault();
  36345. return
  36346. }
  36347. if (that._legend.coordsIn(x, y)) {
  36348. var item = that._legend.getItemByCoord(x, y);
  36349. if (item) {
  36350. series = that._storedSeries[item.id];
  36351. that._setHoveredSeries(series, that._legend._options.hoverMode);
  36352. that._stickedSeries = series
  36353. }
  36354. else
  36355. that._clearHover();
  36356. that._hideCrosshair();
  36357. return
  36358. }
  36359. if (that._axisHoverEnabled && that._argumentAxis.coordsIn(x, y)) {
  36360. var argument = that._getAxisArgument(e),
  36361. argumentDefined = isDefined(argument);
  36362. if (argumentDefined && that.hoveredArgument !== argument) {
  36363. that._clearHover();
  36364. that._resetHoveredArgument();
  36365. that._toAllArgumentPoints(argument, "setPointHoverState");
  36366. that.hoveredArgument = argument
  36367. }
  36368. else if (!argumentDefined)
  36369. that._resetHoveredArgument();
  36370. return
  36371. }
  36372. that._resetHoveredArgument();
  36373. that._focusOnCanvas(canvas);
  36374. if (!canvas && !point)
  36375. return;
  36376. if (!series && !point)
  36377. that._stickedSeries = that._stickedSeries || that._getSeriesForShared(x, y);
  36378. if (series && !point) {
  36379. point = series.getNeighborPoint(x, y);
  36380. if (series !== that.hoveredSeries) {
  36381. that._setTimeout(function() {
  36382. that._setHoveredSeries(series, series.getOptions().hoverMode);
  36383. that._stickedSeries = series;
  36384. that._pointerComplete(point)
  36385. }, series);
  36386. return
  36387. }
  36388. }
  36389. else if (point) {
  36390. if (that.hoveredSeries)
  36391. that._setTimeout(function() {
  36392. that._pointerOnPoint(point)
  36393. }, point);
  36394. else
  36395. that._pointerOnPoint(point);
  36396. return
  36397. }
  36398. else if (that._stickedSeries) {
  36399. series = that._stickedSeries;
  36400. point = series.getNeighborPoint(x, y);
  36401. that.hoveredSeries && that._releaseHoveredSeries();
  36402. point && that._setHoveredPoint(point)
  36403. }
  36404. that._pointerComplete(point)
  36405. },
  36406. _pointerOnPoint: function(point) {
  36407. var that = this;
  36408. that._stickedSeries = point.series;
  36409. that._setHoveredPoint(point);
  36410. that.hoveredSeries && that._releaseHoveredSeries();
  36411. that._pointerComplete(point)
  36412. },
  36413. _pointerComplete: function(point) {
  36414. var that = this;
  36415. that.hoveredSeries && that.hoveredSeries.updateHover(that._x, that._y);
  36416. that._resetTimer();
  36417. that._moveCrosshair(point, that._x, that._y);
  36418. that.pointAtShownTooltip !== point && that._tooltip.isEnabled() && that._showTooltip(point)
  36419. },
  36420. _pointerOut: function() {
  36421. var that = this;
  36422. that._stickedSeries = null;
  36423. that._hideCrosshair();
  36424. that._resetHoveredArgument();
  36425. that._resetTimer();
  36426. baseTrackerPrototype._pointerOut.call(that)
  36427. },
  36428. _clickHandler: function(e) {
  36429. var that = e.data.tracker,
  36430. rootOffset = that._renderer.getRootOffset(),
  36431. x = _floor(e.pageX - rootOffset.left),
  36432. y = _floor(e.pageY - rootOffset.top),
  36433. point = $(e.target).data("point"),
  36434. series = that._stickedSeries || $(e.target).data("series") || point && point.series,
  36435. axis = that._argumentAxis;
  36436. if (that._legend.coordsIn(x, y)) {
  36437. var item = that._legend.getItemByCoord(x, y);
  36438. if (item) {
  36439. series = that._storedSeries[item.id];
  36440. that._legendClick(series, e)
  36441. }
  36442. return
  36443. }
  36444. if (axis && axis.coordsIn(x, y)) {
  36445. var argument = that._getAxisArgument(e);
  36446. if (isDefined(argument)) {
  36447. that._eventTrigger("argumentAxisClick", {
  36448. argument: argument,
  36449. jQueryEvent: e
  36450. });
  36451. return
  36452. }
  36453. }
  36454. if (series) {
  36455. point = point || series.getPointByCoord(x, y);
  36456. if (point)
  36457. that._pointClick(point, e);
  36458. else
  36459. $(e.target).data("series") && that._eventTrigger(SERIES_CLICK, {
  36460. target: series,
  36461. jQueryEvent: e
  36462. })
  36463. }
  36464. },
  36465. dispose: function() {
  36466. this._gestureEndHandler && $(document).off("dxpointerup", this._gestureEndHandler);
  36467. this._resetTimer();
  36468. baseTrackerPrototype.dispose.call(this)
  36469. }
  36470. });
  36471. charts.PieTracker = function(options) {
  36472. this.ctor(options)
  36473. };
  36474. $.extend(charts.PieTracker.prototype, baseTrackerPrototype, {
  36475. _legendClick: function(point, event) {
  36476. var that = this,
  36477. eventArg = {
  36478. target: point,
  36479. jQueryEvent: event
  36480. },
  36481. eventTrigger = that._eventTrigger;
  36482. eventTrigger(LEGEND_CLICK, eventArg, function() {
  36483. !eventCanceled(event, point) && eventTrigger(POINT_CLICK, eventArg)
  36484. })
  36485. },
  36486. _pointerHandler: function(e) {
  36487. var that = e.data.tracker,
  36488. rootOffset = that._renderer.getRootOffset(),
  36489. x = _floor(e.pageX - rootOffset.left),
  36490. y = _floor(e.pageY - rootOffset.top),
  36491. series = that._storedSeries[0],
  36492. point = $(e.target).data("point") || series && series.getPointByCoord(x, y),
  36493. item,
  36494. mode;
  36495. that._enableOutHandler();
  36496. if (that._legend.coordsIn(x, y)) {
  36497. item = that._legend.getItemByCoord(x, y);
  36498. if (item) {
  36499. point = series.getPoints()[item.id];
  36500. mode = that._legend._options.hoverMode
  36501. }
  36502. }
  36503. if (point && point !== that.hoveredPoint) {
  36504. that._tooltip.isEnabled() && that._showTooltip(point);
  36505. that._setHoveredPoint(point, mode)
  36506. }
  36507. else if (!point)
  36508. that._pointerOut()
  36509. },
  36510. _clickHandler: function(e) {
  36511. var that = e.data.tracker,
  36512. rootOffset = that._renderer.getRootOffset(),
  36513. x = _floor(e.pageX - rootOffset.left),
  36514. y = _floor(e.pageY - rootOffset.top),
  36515. storedSeries = that._storedSeries[0],
  36516. point;
  36517. if (that._legend.coordsIn(x, y)) {
  36518. var item = that._legend.getItemByCoord(x, y);
  36519. if (item) {
  36520. point = storedSeries.getPoints()[item.id];
  36521. that._legendClick(point, e)
  36522. }
  36523. }
  36524. else {
  36525. point = $(e.target).data("point") || storedSeries && storedSeries.getPointByCoord(x, y);
  36526. point && that._eventTrigger(POINT_CLICK, {
  36527. target: point,
  36528. jQueryEvent: e
  36529. })
  36530. }
  36531. }
  36532. })
  36533. })(jQuery, DevExpress, Math);
  36534. /*! Module viz-charts, file crosshair.js */
  36535. (function($, DX, undefined) {
  36536. var _math = Math,
  36537. mathAbs = _math.abs,
  36538. mathMin = _math.min,
  36539. mathMax = _math.max,
  36540. _round = _math.round,
  36541. HORIZONTAL = "horizontal",
  36542. VERTICAL = "vertical",
  36543. LABEL_BACKGROUND_PADDING_X = 8,
  36544. LABEL_BACKGROUND_PADDING_Y = 4,
  36545. CENTER = "center",
  36546. RIGHT = "right",
  36547. LEFT = "left",
  36548. TOP = "top",
  36549. BOTTOM = "bottom",
  36550. _isDefined = DX.utils.isDefined;
  36551. function Crosshair() {
  36552. this.ctor.apply(this, arguments)
  36553. }
  36554. DX.viz.charts.Crosshair = Crosshair;
  36555. Crosshair.prototype = {
  36556. ctor: function(renderer, options, params, group) {
  36557. var that = this;
  36558. that._renderer = renderer;
  36559. that._crosshairGroup = group;
  36560. that._options = {};
  36561. that._init(options, params)
  36562. },
  36563. update: function(options, params) {
  36564. this._init(options, params)
  36565. },
  36566. dispose: function() {
  36567. var that = this;
  36568. that._renderer = null;
  36569. that._crosshairGroup = null;
  36570. that._options = null;
  36571. that._axes = null;
  36572. that._canvas = null;
  36573. that._horizontalGroup = null;
  36574. that._verticalGroup = null;
  36575. that._horizontal = null;
  36576. that._vertical = null;
  36577. that._circle = null;
  36578. that._panes = null
  36579. },
  36580. _init: function(options, params) {
  36581. var that = this,
  36582. canvas = params.canvas;
  36583. that._canvas = {
  36584. top: canvas.top,
  36585. bottom: canvas.height - canvas.bottom,
  36586. left: canvas.left,
  36587. right: canvas.width - canvas.right,
  36588. width: canvas.width,
  36589. height: canvas.height
  36590. };
  36591. that._axes = params.axes;
  36592. that._panes = params.panes;
  36593. that._prepareOptions(options, HORIZONTAL);
  36594. that._prepareOptions(options, VERTICAL)
  36595. },
  36596. _prepareOptions: function(options, direction) {
  36597. this._options[direction] = {
  36598. visible: options[direction + "Line"].visible,
  36599. line: {
  36600. stroke: options[direction + "Line"].color || options.color,
  36601. "stroke-width": options[direction + "Line"].width || options.width,
  36602. dashStyle: options[direction + "Line"].dashStyle || options.dashStyle,
  36603. opacity: options[direction + "Line"].opacity || options.opacity,
  36604. "stroke-linecap": "butt"
  36605. },
  36606. label: $.extend(true, {}, options.label, options[direction + "Line"].label)
  36607. }
  36608. },
  36609. _createLines: function(options, sharpParam, group) {
  36610. var lines = [],
  36611. canvas = this._canvas,
  36612. points = [canvas.left, canvas.top, canvas.left, canvas.top];
  36613. for (var i = 0; i < 2; i++)
  36614. lines.push(this._renderer.path(points, "line").attr(options).sharp(sharpParam).append(group));
  36615. return lines
  36616. },
  36617. render: function() {
  36618. var that = this,
  36619. renderer = that._renderer,
  36620. options = that._options,
  36621. verticalOptions = options.vertical,
  36622. horizontalOptions = options.horizontal,
  36623. extraOptions = horizontalOptions.visible ? horizontalOptions.line : verticalOptions.line,
  36624. circleOptions = {
  36625. stroke: extraOptions.stroke,
  36626. "stroke-width": extraOptions["stroke-width"],
  36627. dashStyle: extraOptions.dashStyle,
  36628. opacity: extraOptions.opacity
  36629. },
  36630. canvas = that._canvas;
  36631. that._horizontal = {};
  36632. that._vertical = {};
  36633. that._horizontalGroup = renderer.g().append(that._crosshairGroup);
  36634. that._verticalGroup = renderer.g().append(that._crosshairGroup);
  36635. if (verticalOptions.visible) {
  36636. that._vertical.lines = that._createLines(verticalOptions.line, "h", that._verticalGroup);
  36637. that._vertical.labels = that._createLabels(that._axes[0], verticalOptions, false, that._verticalGroup)
  36638. }
  36639. if (horizontalOptions.visible) {
  36640. that._horizontal.lines = that._createLines(horizontalOptions.line, "v", that._horizontalGroup);
  36641. that._horizontal.labels = that._createLabels(that._axes[1], horizontalOptions, true, that._horizontalGroup)
  36642. }
  36643. that._circle = renderer.circle(canvas.left, canvas.top, 0).attr(circleOptions).append(that._crosshairGroup)
  36644. },
  36645. _createLabels: function(axes, options, isHorizontal, group) {
  36646. var that = this,
  36647. canvas = that._canvas,
  36648. renderer = that._renderer,
  36649. x,
  36650. y,
  36651. text,
  36652. labels = [],
  36653. background,
  36654. curentLabelPos,
  36655. bbox;
  36656. if (!options.label || !options.label.visible)
  36657. return;
  36658. $.each(axes, function(_, axis) {
  36659. var axisOptions = axis.getOptions(),
  36660. position = axisOptions.position;
  36661. if (axis._virtual || axisOptions.stubData)
  36662. return;
  36663. curentLabelPos = axis.getCurrentLabelPos();
  36664. if (isHorizontal) {
  36665. y = canvas.top;
  36666. x = curentLabelPos
  36667. }
  36668. else {
  36669. x = canvas.left;
  36670. y = curentLabelPos
  36671. }
  36672. text = renderer.text("0", x, y).css(DX.viz.core.utils.patchFontOptions(options.label.font)).attr({align: position === TOP || position === BOTTOM ? CENTER : position === RIGHT ? LEFT : RIGHT}).append(group);
  36673. bbox = text.getBBox();
  36674. text.attr({y: isHorizontal ? 2 * y - bbox.y - bbox.height / 2 : position === BOTTOM ? 2 * y - bbox.y : 2 * y - (bbox.y + bbox.height)});
  36675. background = renderer.rect(0, 0, 0, 0).attr({fill: options.label.backgroundColor || options.line.stroke}).append(group).toBackground();
  36676. labels.push({
  36677. text: text,
  36678. background: background,
  36679. axis: axis,
  36680. pos: {
  36681. coord: curentLabelPos,
  36682. side: position
  36683. }
  36684. })
  36685. });
  36686. return labels
  36687. },
  36688. _updateText: function(coord, labels) {
  36689. var that = this,
  36690. bbox,
  36691. text,
  36692. textElement,
  36693. backgroundElement;
  36694. if (!labels)
  36695. return;
  36696. $.each(labels, function(i, label) {
  36697. textElement = label.text;
  36698. backgroundElement = label.background;
  36699. if (!textElement)
  36700. return;
  36701. text = label.axis.getUntranslatedValue(coord);
  36702. if (_isDefined(text)) {
  36703. textElement.attr({text: text});
  36704. bbox = textElement.getBBox();
  36705. that._updateLinesCanvas(label.pos.side, label.pos.coord);
  36706. backgroundElement.attr({
  36707. x: bbox.x - LABEL_BACKGROUND_PADDING_X,
  36708. y: bbox.y - LABEL_BACKGROUND_PADDING_Y,
  36709. width: bbox.width + LABEL_BACKGROUND_PADDING_X * 2,
  36710. height: bbox.height + LABEL_BACKGROUND_PADDING_Y * 2
  36711. })
  36712. }
  36713. else {
  36714. textElement.attr({text: ""});
  36715. backgroundElement.attr({
  36716. x: 0,
  36717. y: 0,
  36718. width: 0,
  36719. height: 0
  36720. })
  36721. }
  36722. })
  36723. },
  36724. show: function() {
  36725. this._crosshairGroup.attr({visibility: "visible"})
  36726. },
  36727. hide: function() {
  36728. this._crosshairGroup.attr({visibility: "hidden"})
  36729. },
  36730. _updateLinesCanvas: function(position, labelPosition) {
  36731. var coords = this._linesCanvas,
  36732. canvas = this._canvas;
  36733. coords[position] = coords[position] !== canvas[position] && mathAbs(coords[position] - canvas[position]) < mathAbs(labelPosition - canvas[position]) ? coords[position] : labelPosition
  36734. },
  36735. _updateLines: function(lines, x, y, r, isHorizontal) {
  36736. var coords = this._linesCanvas,
  36737. canvas = this._canvas,
  36738. points = isHorizontal ? [[mathMin(x - r, coords.left), canvas.top, x - r, canvas.top], [x + r, canvas.top, mathMax(coords.right, x + r), canvas.top]] : [[canvas.left, mathMin(coords.top, y - r), canvas.left, y - r], [canvas.left, y + r, canvas.left, mathMax(coords.bottom, y + r)]];
  36739. for (var i = 0; i < 2; i++)
  36740. lines[i].attr({points: points[i]})
  36741. },
  36742. _resetLinesCanvas: function() {
  36743. var canvas = this._canvas;
  36744. this._linesCanvas = {
  36745. left: canvas.left,
  36746. right: canvas.right,
  36747. top: canvas.top,
  36748. bottom: canvas.bottom
  36749. }
  36750. },
  36751. _getClipRectForPane: function(x, y) {
  36752. var panes = this._panes,
  36753. i,
  36754. coords;
  36755. for (i = 0; i < panes.length; i++) {
  36756. coords = panes[i].coords;
  36757. if (coords.left <= x && coords.right >= x && coords.top <= y && coords.bottom >= y)
  36758. return panes[i].clipRect
  36759. }
  36760. return {id: null}
  36761. },
  36762. shift: function(x, y, r) {
  36763. var that = this,
  36764. horizontal = that._horizontal,
  36765. vertical = that._vertical,
  36766. clipRect,
  36767. rad = !r ? 0 : r + 3,
  36768. canvas = that._canvas;
  36769. x = _round(x);
  36770. y = _round(y);
  36771. if (x >= canvas.left && x <= canvas.right && y >= canvas.top && y <= canvas.bottom) {
  36772. that.show();
  36773. that._resetLinesCanvas();
  36774. clipRect = that._getClipRectForPane(x, y);
  36775. that._circle.attr({
  36776. cx: x,
  36777. cy: y,
  36778. r: rad,
  36779. clipId: clipRect.id
  36780. });
  36781. if (horizontal.lines) {
  36782. that._updateText(y, horizontal.labels);
  36783. that._updateLines(horizontal.lines, x, y, rad, true);
  36784. that._horizontalGroup.attr({translateY: y - canvas.top})
  36785. }
  36786. if (vertical.lines) {
  36787. that._updateText(x, vertical.labels);
  36788. that._updateLines(vertical.lines, x, y, rad, false);
  36789. that._verticalGroup.attr({translateX: x - canvas.left})
  36790. }
  36791. }
  36792. else
  36793. that.hide()
  36794. }
  36795. }
  36796. })(jQuery, DevExpress);
  36797. DevExpress.MOD_VIZ_CHARTS = true
  36798. }
  36799. if (!DevExpress.MOD_VIZ_GAUGES) {
  36800. if (!DevExpress.MOD_VIZ_CORE)
  36801. throw Error('Required module is not referenced: viz-core');
  36802. /*! Module viz-gauges, file namespaces.js */
  36803. (function(DX) {
  36804. DX.viz.gauges = {__internals: {
  36805. circularNeedles: {},
  36806. circularMarkers: {},
  36807. linearNeedles: {},
  36808. linearMarkers: {}
  36809. }};
  36810. DX.viz.gauges.__tests = {}
  36811. })(DevExpress);
  36812. /*! Module viz-gauges, file factory.js */
  36813. (function(DX, $, undefined) {
  36814. var internals = DX.viz.gauges.__internals,
  36815. circularNeedles = internals.circularNeedles,
  36816. circularMarkers = internals.circularMarkers,
  36817. linearNeedles = internals.linearNeedles,
  36818. linearMarkers = internals.linearMarkers,
  36819. _String = String;
  36820. DX.viz.gauges.__factory = {
  36821. createCircularIndicator: function(parameters, type, _strict) {
  36822. var indicatorType;
  36823. switch (_String(type).toLowerCase()) {
  36824. case'rectangleneedle':
  36825. indicatorType = circularNeedles.RectangleNeedle;
  36826. break;
  36827. case'triangleneedle':
  36828. indicatorType = circularNeedles.TriangleNeedle;
  36829. break;
  36830. case'twocolorneedle':
  36831. indicatorType = circularNeedles.TwoColorRectangleNeedle;
  36832. break;
  36833. case'rangebar':
  36834. indicatorType = internals.CircularRangeBar;
  36835. break;
  36836. case'trianglemarker':
  36837. indicatorType = circularMarkers.TriangleMarker;
  36838. break;
  36839. case'textcloud':
  36840. indicatorType = circularMarkers.TextCloudMarker;
  36841. break;
  36842. default:
  36843. indicatorType = _strict ? null : circularNeedles.RectangleNeedle;
  36844. break
  36845. }
  36846. return indicatorType ? new indicatorType(parameters) : null
  36847. },
  36848. createLinearIndicator: function(parameters, type, _strict) {
  36849. var indicatorType = internals.LinearRangeBar;
  36850. switch (_String(type).toLowerCase()) {
  36851. case'rectangle':
  36852. indicatorType = linearNeedles.RectangleNeedle;
  36853. break;
  36854. case'rhombus':
  36855. indicatorType = linearNeedles.RhombusNeedle;
  36856. break;
  36857. case'circle':
  36858. indicatorType = linearNeedles.CircleNeedle;
  36859. break;
  36860. case'rangebar':
  36861. indicatorType = internals.LinearRangeBar;
  36862. break;
  36863. case'trianglemarker':
  36864. indicatorType = linearMarkers.TriangleMarker;
  36865. break;
  36866. case'textcloud':
  36867. indicatorType = linearMarkers.TextCloudMarker;
  36868. break;
  36869. default:
  36870. indicatorType = _strict ? null : internals.LinearRangeBar;
  36871. break
  36872. }
  36873. return indicatorType ? new indicatorType(parameters) : null
  36874. },
  36875. createCircularScale: function(parameters) {
  36876. return new internals.CircularScale(parameters)
  36877. },
  36878. createLinearScale: function(parameters) {
  36879. return new internals.LinearScale(parameters)
  36880. },
  36881. createCircularRangeContainer: function(parameters) {
  36882. return new internals.CircularRangeContainer(parameters)
  36883. },
  36884. createLinearRangeContainer: function(parameters) {
  36885. return new internals.LinearRangeContainer(parameters)
  36886. },
  36887. createTitle: function(parameters) {
  36888. return new internals.Title(parameters)
  36889. },
  36890. createIndicator: function() {
  36891. return internals.Indicator && new internals.Indicator || null
  36892. },
  36893. createLayoutManager: function() {
  36894. return new internals.LayoutManager
  36895. },
  36896. createThemeManager: function(options) {
  36897. return new internals.ThemeManager(options)
  36898. },
  36899. createTracker: function(parameters) {
  36900. return new internals.Tracker(parameters)
  36901. }
  36902. };
  36903. var _isFunction = DX.utils.isFunction,
  36904. _extend = $.extend;
  36905. var _formatHelper = DX.formatHelper;
  36906. internals.formatValue = function(value, options, extra) {
  36907. options = options || {};
  36908. var text = _formatHelper.format(value, options.format, options.precision),
  36909. context;
  36910. if (_isFunction(options.customizeText)) {
  36911. context = _extend({
  36912. value: value,
  36913. valueText: text
  36914. }, extra);
  36915. return _String(options.customizeText.call(context, context))
  36916. }
  36917. return text
  36918. };
  36919. internals.getSampleText = function(translator, options) {
  36920. var text1 = internals.formatValue(translator.getDomainStart(), options),
  36921. text2 = internals.formatValue(translator.getDomainEnd(), options);
  36922. return text1.length >= text2.length ? text1 : text2
  36923. }
  36924. })(DevExpress, jQuery);
  36925. /*! Module viz-gauges, file baseIndicator.js */
  36926. (function(DX, $, undefined) {
  36927. var _isFinite = isFinite,
  36928. _Number = Number;
  36929. DX.viz.gauges.__internals.BaseElement = DX.Class.inherit({
  36930. ctor: function(parameters) {
  36931. var that = this;
  36932. $.each(parameters, function(name, value) {
  36933. that["_" + name] = value
  36934. });
  36935. that._init()
  36936. },
  36937. dispose: function() {
  36938. var that = this;
  36939. $.each(that, function(name) {
  36940. that[name] = null
  36941. });
  36942. return that
  36943. },
  36944. getOffset: function() {
  36945. return _Number(this._options.offset) || 0
  36946. }
  36947. });
  36948. DX.viz.gauges.__internals.BaseIndicator = DX.viz.gauges.__internals.BaseElement.inherit({
  36949. _init: function() {
  36950. this._rootElement = this._createRoot();
  36951. this._trackerElement = this._createTracker()
  36952. },
  36953. _setupAnimation: function() {
  36954. var that = this;
  36955. if (that._options.animation)
  36956. that._animation = {
  36957. step: function(pos) {
  36958. that._actualValue = that._animation.start + that._animation.delta * pos;
  36959. that._actualPosition = that._translator.translate(that._actualValue);
  36960. that._move()
  36961. },
  36962. duration: that._options.animation.duration > 0 ? _Number(that._options.animation.duration) : 0,
  36963. easing: that._options.animation.easing
  36964. }
  36965. },
  36966. _runAnimation: function(value, notifyReady) {
  36967. var that = this,
  36968. animation = that._animation;
  36969. animation.start = that._actualValue;
  36970. animation.delta = value - that._actualValue;
  36971. that._rootElement.animate({_: 0}, {
  36972. step: animation.step,
  36973. duration: animation.duration,
  36974. easing: animation.easing,
  36975. complete: notifyReady
  36976. })
  36977. },
  36978. _createRoot: function() {
  36979. return this._renderer.g().attr({'class': this._className})
  36980. },
  36981. _createTracker: function() {
  36982. return this._renderer.path([], "area")
  36983. },
  36984. _getTrackerSettings: $.noop,
  36985. clean: function() {
  36986. var that = this;
  36987. that._animation && that._rootElement.stopAnimation();
  36988. that._rootElement.remove();
  36989. that._rootElement.clear();
  36990. that._clear();
  36991. that._tracker.detach(that._trackerElement);
  36992. that._options = that.enabled = that._animation = null;
  36993. return that
  36994. },
  36995. render: function(options) {
  36996. var that = this;
  36997. that.type = options.type;
  36998. that._options = options;
  36999. that._actualValue = that._currentValue = that._translator.adjust(that._options.currentValue);
  37000. that.enabled = that._isEnabled();
  37001. if (that.enabled) {
  37002. that._setupAnimation();
  37003. that._rootElement.attr({fill: that._options.color}).append(that._owner);
  37004. that._tracker.attach(that._trackerElement, that, that._trackerInfo)
  37005. }
  37006. return that
  37007. },
  37008. resize: function(layout) {
  37009. var that = this;
  37010. that._rootElement.clear();
  37011. that._clear();
  37012. that.visible = that._isVisible(layout);
  37013. if (that.visible) {
  37014. $.extend(that._options, layout);
  37015. that._actualPosition = that._translator.translate(that._actualValue);
  37016. that._render();
  37017. that._trackerElement.attr(that._getTrackerSettings());
  37018. that._move()
  37019. }
  37020. return that
  37021. },
  37022. value: function(arg, _noAnimation) {
  37023. var that = this,
  37024. immediateReady = true,
  37025. val;
  37026. if (arg !== undefined) {
  37027. val = that._translator.adjust(arg);
  37028. that._notifiers.dirty();
  37029. if (that._currentValue !== val && _isFinite(val)) {
  37030. that._currentValue = val;
  37031. if (that.visible)
  37032. if (that._animation && !_noAnimation) {
  37033. immediateReady = false;
  37034. that._runAnimation(val, that._notifiers.ready)
  37035. }
  37036. else {
  37037. that._actualValue = val;
  37038. that._actualPosition = that._translator.translate(val);
  37039. that._move()
  37040. }
  37041. }
  37042. immediateReady && that._notifiers.ready();
  37043. return that
  37044. }
  37045. return that._currentValue
  37046. },
  37047. _isEnabled: null,
  37048. _isVisible: null,
  37049. _render: null,
  37050. _clear: null,
  37051. _move: null
  37052. })
  37053. })(DevExpress, jQuery);
  37054. /*! Module viz-gauges, file baseMarker.js */
  37055. (function(DX, undefined) {
  37056. var viz = DX.viz,
  37057. core = viz.core,
  37058. _min = Math.min,
  37059. _round = Math.round,
  37060. _formatValue = viz.gauges.__internals.formatValue,
  37061. _getSampleText = viz.gauges.__internals.getSampleText,
  37062. COEFFICIENTS_MAP = {};
  37063. COEFFICIENTS_MAP['right-bottom'] = COEFFICIENTS_MAP['rb'] = [0, -1, -1, 0, 0, 1, 1, 0];
  37064. COEFFICIENTS_MAP['bottom-right'] = COEFFICIENTS_MAP['br'] = [-1, 0, 0, -1, 1, 0, 0, 1];
  37065. COEFFICIENTS_MAP['left-bottom'] = COEFFICIENTS_MAP['lb'] = [0, -1, 1, 0, 0, 1, -1, 0];
  37066. COEFFICIENTS_MAP['bottom-left'] = COEFFICIENTS_MAP['bl'] = [1, 0, 0, -1, -1, 0, 0, 1];
  37067. COEFFICIENTS_MAP['left-top'] = COEFFICIENTS_MAP['lt'] = [0, 1, 1, 0, 0, -1, -1, 0];
  37068. COEFFICIENTS_MAP['top-left'] = COEFFICIENTS_MAP['tl'] = [1, 0, 0, 1, -1, 0, 0, -1];
  37069. COEFFICIENTS_MAP['right-top'] = COEFFICIENTS_MAP['rt'] = [0, 1, -1, 0, 0, -1, 1, 0];
  37070. COEFFICIENTS_MAP['top-right'] = COEFFICIENTS_MAP['tr'] = [-1, 0, 0, 1, 1, 0, 0, -1];
  37071. function getTextCloudInfo(options) {
  37072. var x = options.x,
  37073. y = options.y,
  37074. type = COEFFICIENTS_MAP[options.type],
  37075. cloudWidth = options.textWidth + 2 * options.horMargin,
  37076. cloudHeight = options.textHeight + 2 * options.verMargin,
  37077. tailWidth,
  37078. tailHeight,
  37079. cx = x,
  37080. cy = y;
  37081. tailWidth = tailHeight = options.tailLength;
  37082. if (type[0] & 1)
  37083. tailHeight = _min(tailHeight, cloudHeight / 3);
  37084. else
  37085. tailWidth = _min(tailWidth, cloudWidth / 3);
  37086. return {
  37087. cx: _round(cx + type[0] * tailWidth + (type[0] + type[2]) * cloudWidth / 2),
  37088. cy: _round(cy + type[1] * tailHeight + (type[1] + type[3]) * cloudHeight / 2),
  37089. points: [_round(x), _round(y), _round(x += type[0] * (cloudWidth + tailWidth)), _round(y += type[1] * (cloudHeight + tailHeight)), _round(x += type[2] * cloudWidth), _round(y += type[3] * cloudHeight), _round(x += type[4] * cloudWidth), _round(y += type[5] * cloudHeight), _round(x += type[6] * (cloudWidth - tailWidth)), _round(y += type[7] * (cloudHeight - tailHeight))]
  37090. }
  37091. }
  37092. viz.gauges.__tests.getTextCloudInfo = getTextCloudInfo;
  37093. viz.gauges.__internals.BaseTextCloudMarker = viz.gauges.__internals.BaseIndicator.inherit({
  37094. _move: function() {
  37095. var that = this,
  37096. bbox,
  37097. info,
  37098. textCloudOptions = that._getTextCloudOptions();
  37099. that._text.attr({text: _formatValue(that._actualValue, that._options.text)});
  37100. bbox = that._text.getBBox();
  37101. info = getTextCloudInfo({
  37102. x: textCloudOptions.x,
  37103. y: textCloudOptions.y,
  37104. textWidth: bbox.width,
  37105. textHeight: bbox.height,
  37106. horMargin: that._options.horizontalOffset,
  37107. verMargin: that._options.verticalOffset,
  37108. tailLength: that._options.arrowLength,
  37109. type: textCloudOptions.type
  37110. });
  37111. that._text.attr({
  37112. x: info.cx,
  37113. y: info.cy + that._textVerticalOffset
  37114. });
  37115. that._cloud.attr({points: info.points});
  37116. that._trackerElement && that._trackerElement.attr({points: info.points})
  37117. },
  37118. _measureText: function() {
  37119. var that = this,
  37120. root,
  37121. text,
  37122. bbox;
  37123. if (!that._textVerticalOffset) {
  37124. root = that._createRoot().append(that._owner);
  37125. text = that._renderer.text(_getSampleText(that._translator, that._options.text), 0, 0).attr({align: "center"}).css(core.utils.patchFontOptions(that._options.text.font)).append(root);
  37126. bbox = text.getBBox();
  37127. root.remove();
  37128. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  37129. that._textWidth = bbox.width;
  37130. that._textHeight = bbox.height;
  37131. that._textFullWidth = that._textWidth + 2 * that._options.horizontalOffset;
  37132. that._textFullHeight = that._textHeight + 2 * that._options.verticalOffset
  37133. }
  37134. },
  37135. _render: function() {
  37136. var that = this;
  37137. that._measureText();
  37138. that._cloud = that._cloud || that._renderer.path([], "area").append(that._rootElement);
  37139. that._text = that._text || that._renderer.text().append(that._rootElement);
  37140. that._text.attr({align: "center"}).css(core.utils.patchFontOptions(that._options.text.font))
  37141. },
  37142. _clear: function() {
  37143. delete this._cloud;
  37144. delete this._text
  37145. },
  37146. getTooltipParameters: function() {
  37147. var position = this._getTextCloudOptions();
  37148. return {
  37149. x: position.x,
  37150. y: position.y,
  37151. value: this._currentValue,
  37152. color: this._options.color
  37153. }
  37154. }
  37155. })
  37156. })(DevExpress);
  37157. /*! Module viz-gauges, file baseRangeBar.js */
  37158. (function(DX, $, undefined) {
  37159. var viz = DX.viz,
  37160. core = viz.core,
  37161. $extend = $.extend,
  37162. formatValue = viz.gauges.__internals.formatValue,
  37163. getSampleText = viz.gauges.__internals.getSampleText;
  37164. viz.gauges.__internals.BaseRangeBar = viz.gauges.__internals.BaseIndicator.inherit({
  37165. _measureText: function() {
  37166. var that = this,
  37167. root,
  37168. text,
  37169. bbox;
  37170. that._hasText = that._isTextVisible();
  37171. if (that._hasText && !that._textVerticalOffset) {
  37172. root = that._createRoot().append(that._owner);
  37173. text = that._renderer.text(getSampleText(that._translator, that._options.text), 0, 0).attr({
  37174. 'class': 'dxg-text',
  37175. align: 'center'
  37176. }).css(core.utils.patchFontOptions(that._options.text.font)).append(root);
  37177. bbox = text.getBBox();
  37178. root.remove();
  37179. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  37180. that._textWidth = bbox.width;
  37181. that._textHeight = bbox.height
  37182. }
  37183. },
  37184. _move: function() {
  37185. var that = this;
  37186. that._updateBarItemsPositions();
  37187. if (that._hasText) {
  37188. that._text.attr({text: formatValue(that._actualValue, that._options.text)});
  37189. that._updateTextPosition();
  37190. that._updateLinePosition()
  37191. }
  37192. },
  37193. _updateBarItems: function() {
  37194. var that = this,
  37195. options = that._options,
  37196. backgroundColor,
  37197. spaceColor,
  37198. translator = that._translator;
  37199. that._setBarSides();
  37200. that._startPosition = translator.translate(translator.getDomainStart());
  37201. that._endPosition = translator.translate(translator.getDomainEnd());
  37202. that._basePosition = translator.translate(options.baseValue);
  37203. that._space = that._getSpace();
  37204. backgroundColor = options.backgroundColor || 'none';
  37205. if (backgroundColor !== 'none' && that._space > 0)
  37206. spaceColor = options.containerBackgroundColor || 'none';
  37207. else {
  37208. that._space = 0;
  37209. spaceColor = 'none'
  37210. }
  37211. that._backItem1.attr({fill: backgroundColor});
  37212. that._backItem2.attr({fill: backgroundColor});
  37213. that._spaceItem1.attr({fill: spaceColor});
  37214. that._spaceItem2.attr({fill: spaceColor})
  37215. },
  37216. _getSpace: function() {
  37217. return 0
  37218. },
  37219. _updateTextItems: function() {
  37220. var that = this;
  37221. if (that._hasText) {
  37222. that._line = that._line || that._renderer.path([], "line").attr({
  37223. 'class': 'dxg-main-bar',
  37224. "stroke-linecap": "square"
  37225. }).append(that._rootElement);
  37226. that._text = that._text || that._renderer.text('', 0, 0).attr({'class': 'dxg-text'}).append(that._rootElement);
  37227. that._text.attr({align: that._getTextAlign()}).css(that._getFontOptions());
  37228. that._setTextItemsSides()
  37229. }
  37230. else {
  37231. if (that._line) {
  37232. that._line.remove();
  37233. delete that._line
  37234. }
  37235. if (that._text) {
  37236. that._text.remove();
  37237. delete that._text
  37238. }
  37239. }
  37240. },
  37241. _isTextVisible: function() {
  37242. return false
  37243. },
  37244. _getTextAlign: function() {
  37245. return 'center'
  37246. },
  37247. _getFontOptions: function() {
  37248. var options = this._options,
  37249. font = options.text.font;
  37250. if (!font || !font.color)
  37251. font = $extend({}, font, {color: options.color});
  37252. return core.utils.patchFontOptions(font)
  37253. },
  37254. _updateBarItemsPositions: function() {
  37255. var that = this,
  37256. positions = that._getPositions();
  37257. that._backItem1.attr(that._buildItemSettings(positions.start, positions.back1));
  37258. that._backItem2.attr(that._buildItemSettings(positions.back2, positions.end));
  37259. that._spaceItem1.attr(that._buildItemSettings(positions.back1, positions.main1));
  37260. that._spaceItem2.attr(that._buildItemSettings(positions.main2, positions.back2));
  37261. that._mainItem.attr(that._buildItemSettings(positions.main1, positions.main2));
  37262. that._trackerElement && that._trackerElement.attr(that._buildItemSettings(positions.main1, positions.main2))
  37263. },
  37264. _render: function() {
  37265. var that = this;
  37266. that._measureText();
  37267. if (!that._backItem1) {
  37268. that._backItem1 = that._createBarItem();
  37269. that._backItem1.attr({'class': 'dxg-back-bar'})
  37270. }
  37271. if (!that._backItem2) {
  37272. that._backItem2 = that._createBarItem();
  37273. that._backItem2.attr({'class': 'dxg-back-bar'})
  37274. }
  37275. if (!that._spaceItem1) {
  37276. that._spaceItem1 = that._createBarItem();
  37277. that._spaceItem1.attr({'class': 'dxg-space-bar'})
  37278. }
  37279. if (!that._spaceItem2) {
  37280. that._spaceItem2 = that._createBarItem();
  37281. that._spaceItem2.attr({'class': 'dxg-space-bar'})
  37282. }
  37283. if (!that._mainItem) {
  37284. that._mainItem = that._createBarItem();
  37285. that._mainItem.attr({'class': 'dxg-main-bar'})
  37286. }
  37287. that._updateBarItems();
  37288. that._updateTextItems()
  37289. },
  37290. _clear: function() {
  37291. var that = this;
  37292. delete that._backItem1;
  37293. delete that._backItem2;
  37294. delete that._spaceItem1;
  37295. delete that._spaceItem2;
  37296. delete that._mainItem;
  37297. delete that._hasText;
  37298. delete that._line;
  37299. delete that._text
  37300. },
  37301. getTooltipParameters: function() {
  37302. var position = this._getTooltipPosition();
  37303. return {
  37304. x: position.x,
  37305. y: position.y,
  37306. value: this._currentValue,
  37307. color: this._options.color,
  37308. offset: 0
  37309. }
  37310. }
  37311. })
  37312. })(DevExpress, jQuery);
  37313. /*! Module viz-gauges, file circularNeedle.js */
  37314. (function(DX, undefined) {
  37315. var circularNeedles = DX.viz.gauges.__internals.circularNeedles,
  37316. _Number = Number;
  37317. circularNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
  37318. _move: function() {
  37319. var that = this,
  37320. options = that._options,
  37321. angle = DX.utils.convertAngleToRendererSpace(that._actualPosition);
  37322. that._rootElement.rotate(angle, options.x, options.y);
  37323. that._trackerElement && that._trackerElement.rotate(angle, options.x, options.y)
  37324. },
  37325. _isEnabled: function() {
  37326. return this._options.width > 0
  37327. },
  37328. _isVisible: function(layout) {
  37329. return layout.radius - _Number(this._options.indentFromCenter) > 0
  37330. },
  37331. _getTrackerSettings: function() {
  37332. var options = this._options,
  37333. x = options.x,
  37334. y = options.y - (options.radius + _Number(options.indentFromCenter)) / 2,
  37335. width = options.width / 2,
  37336. length = (options.radius - _Number(options.indentFromCenter)) / 2;
  37337. width > 10 || (width = 10);
  37338. length > 10 || (length = 10);
  37339. return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
  37340. },
  37341. _renderSpindle: function() {
  37342. var that = this,
  37343. options = that._options,
  37344. gapSize;
  37345. if (options.spindleSize > 0) {
  37346. gapSize = _Number(options.spindleGapSize) || 0;
  37347. if (gapSize > 0)
  37348. gapSize = gapSize <= options.spindleSize ? gapSize : _Number(options.spindleSize);
  37349. that._spindleOuter = that._spindleOuter || that._renderer.circle().append(that._rootElement);
  37350. that._spindleInner = that._spindleInner || that._renderer.circle().append(that._rootElement);
  37351. that._spindleOuter.attr({
  37352. 'class': 'dxg-spindle-border',
  37353. cx: options.x,
  37354. cy: options.y,
  37355. r: options.spindleSize / 2
  37356. });
  37357. that._spindleInner.attr({
  37358. 'class': 'dxg-spindle-hole',
  37359. cx: options.x,
  37360. cy: options.y,
  37361. r: gapSize / 2,
  37362. fill: options.containerBackgroundColor
  37363. })
  37364. }
  37365. },
  37366. _render: function() {
  37367. var that = this;
  37368. that._renderPointer();
  37369. that._renderSpindle()
  37370. },
  37371. _clearSpindle: function() {
  37372. delete this._spindleOuter;
  37373. delete this._spindleInner
  37374. },
  37375. _clearPointer: function() {
  37376. delete this._element
  37377. },
  37378. _clear: function() {
  37379. this._clearPointer();
  37380. this._clearSpindle()
  37381. },
  37382. measure: function(layout) {
  37383. var result = {max: layout.radius};
  37384. if (this._options.indentFromCenter < 0)
  37385. result.inverseHorizontalOffset = result.inverseVerticalOffset = -_Number(this._options.indentFromCenter);
  37386. return result
  37387. },
  37388. getTooltipParameters: function() {
  37389. var options = this._options,
  37390. cossin = DX.utils.getCosAndSin(this._actualPosition),
  37391. r = (options.radius + _Number(options.indentFromCenter)) / 2;
  37392. return {
  37393. x: options.x + cossin.cos * r,
  37394. y: options.y - cossin.sin * r,
  37395. value: this._currentValue,
  37396. color: options.color,
  37397. offset: options.width / 2
  37398. }
  37399. }
  37400. });
  37401. circularNeedles.RectangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
  37402. var that = this,
  37403. options = that._options,
  37404. y2 = options.y - options.radius,
  37405. y1 = options.y - _Number(options.indentFromCenter),
  37406. x1 = options.x - options.width / 2,
  37407. x2 = x1 + _Number(options.width);
  37408. that._element = that._element || that._renderer.path([], "area").append(that._rootElement);
  37409. that._element.attr({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
  37410. }});
  37411. circularNeedles.TriangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
  37412. var that = this,
  37413. options = that._options,
  37414. y2 = options.y - options.radius,
  37415. y1 = options.y - _Number(options.indentFromCenter),
  37416. x1 = options.x - options.width / 2,
  37417. x2 = options.x + options.width / 2;
  37418. that._element = that._element || that._renderer.path([], "area").append(that._rootElement);
  37419. that._element.attr({points: [x1, y1, options.x, y2, x2, y1]})
  37420. }});
  37421. circularNeedles.TwoColorRectangleNeedle = circularNeedles.SimpleIndicator.inherit({
  37422. _renderPointer: function() {
  37423. var that = this,
  37424. options = that._options,
  37425. x1 = options.x - options.width / 2,
  37426. x2 = options.x + options.width / 2,
  37427. y4 = options.y - options.radius,
  37428. y1 = options.y - _Number(options.indentFromCenter),
  37429. fraction = _Number(options.secondFraction) || 0,
  37430. y2,
  37431. y3;
  37432. if (fraction >= 1)
  37433. y2 = y3 = y1;
  37434. else if (fraction <= 0)
  37435. y2 = y3 = y4;
  37436. else {
  37437. y3 = y4 + (y1 - y4) * fraction;
  37438. y2 = y3 + _Number(options.space)
  37439. }
  37440. that._firstElement = that._firstElement || that._renderer.path([], "area").append(that._rootElement);
  37441. that._spaceElement = that._spaceElement || that._renderer.path([], "area").append(that._rootElement);
  37442. that._secondElement = that._secondElement || that._renderer.path([], "area").append(that._rootElement);
  37443. that._firstElement.attr({points: [x1, y1, x1, y2, x2, y2, x2, y1]});
  37444. that._spaceElement.attr({
  37445. points: [x1, y2, x1, y3, x2, y3, x2, y2],
  37446. 'class': 'dxg-hole',
  37447. fill: options.containerBackgroundColor
  37448. });
  37449. that._secondElement.attr({
  37450. points: [x1, y3, x1, y4, x2, y4, x2, y3],
  37451. 'class': 'dxg-part',
  37452. fill: options.secondColor
  37453. })
  37454. },
  37455. _clearPointer: function() {
  37456. delete this._firstElement;
  37457. delete this._secondElement;
  37458. delete this._spaceElement
  37459. }
  37460. })
  37461. })(DevExpress);
  37462. /*! Module viz-gauges, file linearNeedle.js */
  37463. (function(DX, undefined) {
  37464. var linearNeedles = DX.viz.gauges.__internals.linearNeedles;
  37465. linearNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
  37466. _move: function() {
  37467. var that = this,
  37468. delta = that._actualPosition - that._zeroPosition;
  37469. that._rootElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0);
  37470. that._trackerElement && that._trackerElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0)
  37471. },
  37472. _isEnabled: function() {
  37473. this.vertical = this._options.vertical;
  37474. return this._options.length > 0 && this._options.width > 0
  37475. },
  37476. _isVisible: function() {
  37477. return true
  37478. },
  37479. _getTrackerSettings: function() {
  37480. var options = this._options,
  37481. x1,
  37482. x2,
  37483. y1,
  37484. y2,
  37485. width = options.width / 2,
  37486. length = options.length / 2,
  37487. p = this._zeroPosition;
  37488. width > 10 || (width = 10);
  37489. length > 10 || (length = 10);
  37490. if (this.vertical) {
  37491. x1 = options.x - length;
  37492. x2 = options.x + length;
  37493. y1 = p + width;
  37494. y2 = p - width
  37495. }
  37496. else {
  37497. x1 = p - width;
  37498. x2 = p + width;
  37499. y1 = options.y + length;
  37500. y2 = options.y - length
  37501. }
  37502. return {points: [x1, y1, x1, y2, x2, y2, x2, y1]}
  37503. },
  37504. _render: function() {
  37505. var that = this;
  37506. that._zeroPosition = that._translator.getCodomainStart()
  37507. },
  37508. _clear: function() {
  37509. delete this._element
  37510. },
  37511. measure: function(layout) {
  37512. var p = this.vertical ? layout.x : layout.y;
  37513. return {
  37514. min: p - this._options.length / 2,
  37515. max: p + this._options.length / 2
  37516. }
  37517. },
  37518. getTooltipParameters: function() {
  37519. var that = this,
  37520. options = that._options,
  37521. p = that._actualPosition,
  37522. parameters = {
  37523. x: p,
  37524. y: p,
  37525. value: that._currentValue,
  37526. color: options.color,
  37527. offset: options.width / 2
  37528. };
  37529. that.vertical ? parameters.x = options.x : parameters.y = options.y;
  37530. return parameters
  37531. }
  37532. });
  37533. linearNeedles.RectangleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  37534. var that = this,
  37535. options = that._options,
  37536. p,
  37537. x1,
  37538. x2,
  37539. y1,
  37540. y2;
  37541. that.callBase();
  37542. p = that._zeroPosition;
  37543. if (that.vertical) {
  37544. x1 = options.x - options.length / 2;
  37545. x2 = options.x + options.length / 2;
  37546. y1 = p + options.width / 2;
  37547. y2 = p - options.width / 2
  37548. }
  37549. else {
  37550. x1 = p - options.width / 2;
  37551. x2 = p + options.width / 2;
  37552. y1 = options.y + options.length / 2;
  37553. y2 = options.y - options.length / 2
  37554. }
  37555. that._element = that._element || that._renderer.path([], "area").append(that._rootElement);
  37556. that._element.attr({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
  37557. }});
  37558. linearNeedles.RhombusNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  37559. var that = this,
  37560. options = that._options,
  37561. x,
  37562. y,
  37563. dx,
  37564. dy;
  37565. that.callBase();
  37566. if (that.vertical) {
  37567. x = options.x;
  37568. y = that._zeroPosition;
  37569. dx = options.length / 2 || 0;
  37570. dy = options.width / 2 || 0
  37571. }
  37572. else {
  37573. x = that._zeroPosition;
  37574. y = options.y;
  37575. dx = options.width / 2 || 0;
  37576. dy = options.length / 2 || 0
  37577. }
  37578. that._element = that._element || that._renderer.path([], "area").append(that._rootElement);
  37579. that._element.attr({points: [x - dx, y, x, y - dy, x + dx, y, x, y + dy]})
  37580. }});
  37581. linearNeedles.CircleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  37582. var that = this,
  37583. options = that._options,
  37584. x,
  37585. y,
  37586. r;
  37587. that.callBase();
  37588. if (that.vertical) {
  37589. x = options.x;
  37590. y = that._zeroPosition
  37591. }
  37592. else {
  37593. x = that._zeroPosition;
  37594. y = options.y
  37595. }
  37596. r = options.length / 2 || 0;
  37597. that._element = that._element || that._renderer.circle().append(that._rootElement);
  37598. that._element.attr({
  37599. cx: x,
  37600. cy: y,
  37601. r: r
  37602. })
  37603. }})
  37604. })(DevExpress);
  37605. /*! Module viz-gauges, file circularMarker.js */
  37606. (function(DX, undefined) {
  37607. var circularMarkers = DX.viz.gauges.__internals.circularMarkers,
  37608. _Number = Number;
  37609. circularMarkers.TriangleMarker = DX.viz.gauges.__internals.circularNeedles.SimpleIndicator.inherit({
  37610. _isEnabled: function() {
  37611. return this._options.length > 0 && this._options.width > 0
  37612. },
  37613. _isVisible: function(layout) {
  37614. return layout.radius > 0
  37615. },
  37616. _render: function() {
  37617. var that = this,
  37618. options = that._options,
  37619. x = options.x,
  37620. y1 = options.y - options.radius,
  37621. dx = options.width / 2 || 0,
  37622. y2 = y1 - _Number(options.length),
  37623. settings;
  37624. that._element = that._element || that._renderer.path([], "area").append(that._rootElement);
  37625. settings = {
  37626. points: [x, y1, x - dx, y2, x + dx, y2],
  37627. stroke: "none",
  37628. "stroke-width": 0,
  37629. "stroke-linecap": "square"
  37630. };
  37631. if (options.space > 0) {
  37632. settings["stroke-width"] = Math.min(options.space, options.width / 4) || 0;
  37633. settings.stroke = settings["stroke-width"] > 0 ? options.containerBackgroundColor || "none" : "none"
  37634. }
  37635. that._element.attr(settings).sharp()
  37636. },
  37637. _clear: function() {
  37638. delete this._element
  37639. },
  37640. _getTrackerSettings: function() {
  37641. var options = this._options,
  37642. x = options.x,
  37643. y = options.y - options.radius - options.length / 2,
  37644. width = options.width / 2,
  37645. length = options.length / 2;
  37646. width > 10 || (width = 10);
  37647. length > 10 || (length = 10);
  37648. return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
  37649. },
  37650. measure: function(layout) {
  37651. return {
  37652. min: layout.radius,
  37653. max: layout.radius + _Number(this._options.length)
  37654. }
  37655. },
  37656. getTooltipParameters: function() {
  37657. var options = this._options,
  37658. cossin = DX.utils.getCosAndSin(this._actualPosition),
  37659. r = options.radius + options.length / 2,
  37660. parameters = this.callBase();
  37661. parameters.x = options.x + cossin.cos * r;
  37662. parameters.y = options.y - cossin.sin * r;
  37663. parameters.offset = options.length / 2;
  37664. return parameters
  37665. }
  37666. });
  37667. circularMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
  37668. _isEnabled: function() {
  37669. return true
  37670. },
  37671. _isVisible: function(layout) {
  37672. return layout.radius > 0
  37673. },
  37674. _getTextCloudOptions: function() {
  37675. var that = this,
  37676. cossin = DX.utils.getCosAndSin(that._actualPosition),
  37677. nangle = DX.utils.normalizeAngle(that._actualPosition);
  37678. return {
  37679. x: that._options.x + cossin.cos * that._options.radius,
  37680. y: that._options.y - cossin.sin * that._options.radius,
  37681. type: nangle > 270 ? "left-top" : nangle > 180 ? "top-right" : nangle > 90 ? "right-bottom" : "bottom-left"
  37682. }
  37683. },
  37684. measure: function(layout) {
  37685. var that = this,
  37686. arrowLength = _Number(that._options.arrowLength) || 0,
  37687. verticalOffset,
  37688. horizontalOffset;
  37689. that._measureText();
  37690. verticalOffset = that._textFullHeight + arrowLength;
  37691. horizontalOffset = that._textFullWidth + arrowLength;
  37692. return {
  37693. min: layout.radius,
  37694. max: layout.radius,
  37695. horizontalOffset: horizontalOffset,
  37696. verticalOffset: verticalOffset,
  37697. inverseHorizontalOffset: horizontalOffset,
  37698. inverseVerticalOffset: verticalOffset
  37699. }
  37700. }
  37701. })
  37702. })(DevExpress);
  37703. /*! Module viz-gauges, file linearMarker.js */
  37704. (function(DX, undefined) {
  37705. var linearMarkers = DX.viz.gauges.__internals.linearMarkers,
  37706. _Number = Number,
  37707. _String = String;
  37708. linearMarkers.TriangleMarker = DX.viz.gauges.__internals.linearNeedles.SimpleIndicator.inherit({
  37709. _isEnabled: function() {
  37710. var that = this;
  37711. that.vertical = that._options.vertical;
  37712. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  37713. return that._options.length > 0 && that._options.width > 0
  37714. },
  37715. _isVisible: function() {
  37716. return true
  37717. },
  37718. _render: function() {
  37719. var that = this,
  37720. options = that._options,
  37721. x1,
  37722. x2,
  37723. y1,
  37724. y2,
  37725. settings = {
  37726. stroke: 'none',
  37727. "stroke-width": 0,
  37728. "stroke-linecap": "square"
  37729. };
  37730. that.callBase();
  37731. if (that.vertical) {
  37732. x1 = options.x;
  37733. y1 = that._zeroPosition;
  37734. x2 = x1 + _Number(that._inverted ? options.length : -options.length);
  37735. settings.points = [x1, y1, x2, y1 - options.width / 2, x2, y1 + options.width / 2]
  37736. }
  37737. else {
  37738. y1 = options.y;
  37739. x1 = that._zeroPosition;
  37740. y2 = y1 + _Number(that._inverted ? options.length : -options.length);
  37741. settings.points = [x1, y1, x1 - options.width / 2, y2, x1 + options.width / 2, y2]
  37742. }
  37743. if (options.space > 0) {
  37744. settings["stroke-width"] = Math.min(options.space, options.width / 4) || 0;
  37745. settings.stroke = settings["stroke-width"] > 0 ? options.containerBackgroundColor || 'none' : 'none'
  37746. }
  37747. that._element = that._element || that._renderer.path([], "area").append(that._rootElement);
  37748. that._element.attr(settings).sharp()
  37749. },
  37750. _getTrackerSettings: function() {
  37751. var that = this,
  37752. options = that._options,
  37753. width = options.width / 2,
  37754. length = _Number(options.length),
  37755. x1,
  37756. x2,
  37757. y1,
  37758. y2,
  37759. result;
  37760. width > 10 || (width = 10);
  37761. length > 20 || (length = 20);
  37762. if (that.vertical) {
  37763. x1 = x2 = options.x;
  37764. x2 = x1 + (that._inverted ? length : -length);
  37765. y1 = that._zeroPosition + width;
  37766. y2 = that._zeroPosition - width;
  37767. result = [x1, y1, x2, y1, x2, y2, x1, y2]
  37768. }
  37769. else {
  37770. y1 = options.y;
  37771. y2 = y1 + (that._inverted ? length : -length);
  37772. x1 = that._zeroPosition - width;
  37773. x2 = that._zeroPosition + width;
  37774. result = [x1, y1, x1, y2, x2, y2, x2, y1]
  37775. }
  37776. return {points: result}
  37777. },
  37778. measure: function(layout) {
  37779. var that = this,
  37780. length = _Number(that._options.length),
  37781. minbound,
  37782. maxbound;
  37783. if (that.vertical) {
  37784. minbound = maxbound = layout.x;
  37785. if (that._inverted)
  37786. maxbound = minbound + length;
  37787. else
  37788. minbound = maxbound - length
  37789. }
  37790. else {
  37791. minbound = maxbound = layout.y;
  37792. if (that._inverted)
  37793. maxbound = minbound + length;
  37794. else
  37795. minbound = maxbound - length
  37796. }
  37797. return {
  37798. min: minbound,
  37799. max: maxbound,
  37800. indent: that._options.width / 2
  37801. }
  37802. },
  37803. getTooltipParameters: function() {
  37804. var that = this,
  37805. options = that._options,
  37806. s = (that._inverted ? options.length : -options.length) / 2,
  37807. parameters = that.callBase();
  37808. that.vertical ? parameters.x += s : parameters.y += s;
  37809. parameters.offset = options.length / 2;
  37810. return parameters
  37811. }
  37812. });
  37813. linearMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
  37814. _isEnabled: function() {
  37815. var that = this;
  37816. that.vertical = that._options.vertical;
  37817. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  37818. return true
  37819. },
  37820. _isVisible: function() {
  37821. return true
  37822. },
  37823. _getTextCloudOptions: function() {
  37824. var that = this,
  37825. x = that._actualPosition,
  37826. y = that._actualPosition,
  37827. type;
  37828. if (that.vertical) {
  37829. x = that._options.x;
  37830. type = that._inverted ? 'top-left' : 'top-right'
  37831. }
  37832. else {
  37833. y = that._options.y;
  37834. type = that._inverted ? 'right-top' : 'right-bottom'
  37835. }
  37836. return {
  37837. x: x,
  37838. y: y,
  37839. type: type
  37840. }
  37841. },
  37842. measure: function(layout) {
  37843. var that = this,
  37844. minbound,
  37845. maxbound,
  37846. arrowLength = _Number(that._options.arrowLength) || 0,
  37847. indent;
  37848. that._measureText();
  37849. if (that.vertical) {
  37850. indent = that._textFullHeight;
  37851. if (that._inverted) {
  37852. minbound = layout.x;
  37853. maxbound = layout.x + arrowLength + that._textFullWidth
  37854. }
  37855. else {
  37856. minbound = layout.x - arrowLength - that._textFullWidth;
  37857. maxbound = layout.x
  37858. }
  37859. }
  37860. else {
  37861. indent = that._textFullWidth;
  37862. if (that._inverted) {
  37863. minbound = layout.y;
  37864. maxbound = layout.y + arrowLength + that._textFullHeight
  37865. }
  37866. else {
  37867. minbound = layout.y - arrowLength - that._textFullHeight;
  37868. maxbound = layout.y
  37869. }
  37870. }
  37871. return {
  37872. min: minbound,
  37873. max: maxbound,
  37874. indent: indent
  37875. }
  37876. }
  37877. })
  37878. })(DevExpress);
  37879. /*! Module viz-gauges, file circularRangeBar.js */
  37880. (function(DX, undefined) {
  37881. var _Number = Number,
  37882. getCosAndSin = DX.utils.getCosAndSin,
  37883. convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  37884. max = Math.max,
  37885. min = Math.min;
  37886. DX.viz.gauges.__internals.CircularRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
  37887. _isEnabled: function() {
  37888. return this._options.size > 0
  37889. },
  37890. _isVisible: function(layout) {
  37891. return layout.radius - _Number(this._options.size) > 0
  37892. },
  37893. _createBarItem: function() {
  37894. return this._renderer.arc().attr({"stroke-linejoin": "round"}).append(this._rootElement)
  37895. },
  37896. _createTracker: function() {
  37897. return this._renderer.arc().attr({"stroke-linejoin": "round"})
  37898. },
  37899. _setBarSides: function() {
  37900. var that = this;
  37901. that._maxSide = that._options.radius;
  37902. that._minSide = that._maxSide - _Number(that._options.size)
  37903. },
  37904. _getSpace: function() {
  37905. var options = this._options;
  37906. return options.space > 0 ? options.space * 180 / options.radius / Math.PI : 0
  37907. },
  37908. _isTextVisible: function() {
  37909. var options = this._options.text || {};
  37910. return options.indent > 0
  37911. },
  37912. _setTextItemsSides: function() {
  37913. var that = this,
  37914. options = that._options,
  37915. indent = _Number(options.text.indent);
  37916. that._lineFrom = options.y - options.radius;
  37917. that._lineTo = that._lineFrom - indent;
  37918. that._textRadius = options.radius + indent
  37919. },
  37920. _getPositions: function() {
  37921. var that = this,
  37922. basePosition = that._basePosition,
  37923. actualPosition = that._actualPosition,
  37924. mainPosition1,
  37925. mainPosition2;
  37926. if (basePosition >= actualPosition) {
  37927. mainPosition1 = basePosition;
  37928. mainPosition2 = actualPosition
  37929. }
  37930. else {
  37931. mainPosition1 = actualPosition;
  37932. mainPosition2 = basePosition
  37933. }
  37934. return {
  37935. start: that._startPosition,
  37936. end: that._endPosition,
  37937. main1: mainPosition1,
  37938. main2: mainPosition2,
  37939. back1: min(mainPosition1 + that._space, that._startPosition),
  37940. back2: max(mainPosition2 - that._space, that._endPosition)
  37941. }
  37942. },
  37943. _buildItemSettings: function(from, to) {
  37944. var that = this;
  37945. return {
  37946. x: that._options.x,
  37947. y: that._options.y,
  37948. innerRadius: that._minSide,
  37949. outerRadius: that._maxSide,
  37950. startAngle: to,
  37951. endAngle: from
  37952. }
  37953. },
  37954. _updateTextPosition: function() {
  37955. var that = this,
  37956. cossin = getCosAndSin(that._actualPosition),
  37957. x = that._options.x + that._textRadius * cossin.cos,
  37958. y = that._options.y - that._textRadius * cossin.sin;
  37959. x += cossin.cos * that._textWidth * 0.6;
  37960. y -= cossin.sin * that._textHeight * 0.6;
  37961. that._text.attr({
  37962. x: x,
  37963. y: y + that._textVerticalOffset
  37964. })
  37965. },
  37966. _updateLinePosition: function() {
  37967. var that = this,
  37968. x = that._options.x,
  37969. x1,
  37970. x2;
  37971. if (that._basePosition > that._actualPosition) {
  37972. x1 = x - 2;
  37973. x2 = x
  37974. }
  37975. else if (that._basePosition < that._actualPosition) {
  37976. x1 = x;
  37977. x2 = x + 2
  37978. }
  37979. else {
  37980. x1 = x - 1;
  37981. x2 = x + 1
  37982. }
  37983. that._line.attr({points: [x1, that._lineFrom, x1, that._lineTo, x2, that._lineTo, x2, that._lineFrom]}).rotate(convertAngleToRendererSpace(that._actualPosition), x, that._options.y).sharp()
  37984. },
  37985. _getTooltipPosition: function() {
  37986. var that = this,
  37987. cossin = getCosAndSin((that._basePosition + that._actualPosition) / 2),
  37988. r = (that._minSide + that._maxSide) / 2;
  37989. return {
  37990. x: that._options.x + cossin.cos * r,
  37991. y: that._options.y - cossin.sin * r
  37992. }
  37993. },
  37994. measure: function(layout) {
  37995. var that = this,
  37996. result = {
  37997. min: layout.radius - _Number(that._options.size),
  37998. max: layout.radius
  37999. };
  38000. that._measureText();
  38001. if (that._hasText) {
  38002. result.max += _Number(that._options.text.indent);
  38003. result.horizontalOffset = that._textWidth;
  38004. result.verticalOffset = that._textHeight
  38005. }
  38006. return result
  38007. }
  38008. })
  38009. })(DevExpress);
  38010. /*! Module viz-gauges, file linearRangeBar.js */
  38011. (function(DX, undefined) {
  38012. var _Number = Number,
  38013. _String = String;
  38014. DX.viz.gauges.__internals.LinearRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
  38015. _isEnabled: function() {
  38016. var that = this;
  38017. that.vertical = that._options.vertical;
  38018. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  38019. return that._options.size > 0
  38020. },
  38021. _isVisible: function() {
  38022. return true
  38023. },
  38024. _createBarItem: function() {
  38025. return this._renderer.path([], "area").append(this._rootElement)
  38026. },
  38027. _createTracker: function() {
  38028. return this._renderer.path([], "area")
  38029. },
  38030. _setBarSides: function() {
  38031. var that = this,
  38032. options = that._options,
  38033. size = _Number(options.size),
  38034. minSide,
  38035. maxSide;
  38036. if (that.vertical)
  38037. if (that._inverted) {
  38038. minSide = options.x;
  38039. maxSide = options.x + size
  38040. }
  38041. else {
  38042. minSide = options.x - size;
  38043. maxSide = options.x
  38044. }
  38045. else if (that._inverted) {
  38046. minSide = options.y;
  38047. maxSide = options.y + size
  38048. }
  38049. else {
  38050. minSide = options.y - size;
  38051. maxSide = options.y
  38052. }
  38053. that._minSide = minSide;
  38054. that._maxSide = maxSide;
  38055. that._minBound = minSide;
  38056. that._maxBound = maxSide
  38057. },
  38058. _getSpace: function() {
  38059. var options = this._options;
  38060. return options.space > 0 ? _Number(options.space) : 0
  38061. },
  38062. _isTextVisible: function() {
  38063. var textOptions = this._options.text || {};
  38064. return textOptions.indent > 0 || textOptions.indent < 0
  38065. },
  38066. _getTextAlign: function() {
  38067. return this.vertical ? this._options.text.indent > 0 ? 'left' : 'right' : 'center'
  38068. },
  38069. _setTextItemsSides: function() {
  38070. var that = this,
  38071. indent = _Number(that._options.text.indent);
  38072. if (indent > 0) {
  38073. that._lineStart = that._maxSide;
  38074. that._lineEnd = that._maxSide + indent;
  38075. that._textPosition = that._lineEnd + (that.vertical ? 2 : that._textHeight / 2);
  38076. that._maxBound = that._textPosition + (that.vertical ? that._textWidth : that._textHeight / 2)
  38077. }
  38078. else if (indent < 0) {
  38079. that._lineStart = that._minSide;
  38080. that._lineEnd = that._minSide + indent;
  38081. that._textPosition = that._lineEnd - (that.vertical ? 2 : that._textHeight / 2);
  38082. that._minBound = that._textPosition - (that.vertical ? that._textWidth : that._textHeight / 2)
  38083. }
  38084. },
  38085. _getPositions: function() {
  38086. var that = this,
  38087. startPosition = that._startPosition,
  38088. endPosition = that._endPosition,
  38089. space = that._space,
  38090. basePosition = that._basePosition,
  38091. actualPosition = that._actualPosition,
  38092. mainPosition1,
  38093. mainPosition2,
  38094. backPosition1,
  38095. backPosition2;
  38096. if (startPosition < endPosition) {
  38097. if (basePosition < actualPosition) {
  38098. mainPosition1 = basePosition;
  38099. mainPosition2 = actualPosition
  38100. }
  38101. else {
  38102. mainPosition1 = actualPosition;
  38103. mainPosition2 = basePosition
  38104. }
  38105. backPosition1 = mainPosition1 - space;
  38106. backPosition2 = mainPosition2 + space
  38107. }
  38108. else {
  38109. if (basePosition > actualPosition) {
  38110. mainPosition1 = basePosition;
  38111. mainPosition2 = actualPosition
  38112. }
  38113. else {
  38114. mainPosition1 = actualPosition;
  38115. mainPosition2 = basePosition
  38116. }
  38117. backPosition1 = mainPosition1 + space;
  38118. backPosition2 = mainPosition2 - space
  38119. }
  38120. return {
  38121. start: startPosition,
  38122. end: endPosition,
  38123. main1: mainPosition1,
  38124. main2: mainPosition2,
  38125. back1: backPosition1,
  38126. back2: backPosition2
  38127. }
  38128. },
  38129. _buildItemSettings: function(from, to) {
  38130. var that = this,
  38131. side1 = that._minSide,
  38132. side2 = that._maxSide,
  38133. points = that.vertical ? [side1, from, side1, to, side2, to, side2, from] : [from, side1, from, side2, to, side2, to, side1];
  38134. return {points: points}
  38135. },
  38136. _updateTextPosition: function() {
  38137. var that = this;
  38138. that._text.attr(that.vertical ? {
  38139. x: that._textPosition,
  38140. y: that._actualPosition + that._textVerticalOffset
  38141. } : {
  38142. x: that._actualPosition,
  38143. y: that._textPosition + that._textVerticalOffset
  38144. })
  38145. },
  38146. _updateLinePosition: function() {
  38147. var that = this,
  38148. actualPosition = that._actualPosition,
  38149. side1,
  38150. side2,
  38151. points;
  38152. if (that.vertical) {
  38153. if (that._basePosition >= actualPosition) {
  38154. side1 = actualPosition;
  38155. side2 = actualPosition + 2
  38156. }
  38157. else {
  38158. side1 = actualPosition - 2;
  38159. side2 = actualPosition
  38160. }
  38161. points = [that._lineStart, side1, that._lineStart, side2, that._lineEnd, side2, that._lineEnd, side1]
  38162. }
  38163. else {
  38164. if (that._basePosition <= actualPosition) {
  38165. side1 = actualPosition - 2;
  38166. side2 = actualPosition
  38167. }
  38168. else {
  38169. side1 = actualPosition;
  38170. side2 = actualPosition + 2
  38171. }
  38172. points = [side1, that._lineStart, side1, that._lineEnd, side2, that._lineEnd, side2, that._lineStart]
  38173. }
  38174. that._line.attr({points: points}).sharp()
  38175. },
  38176. _getTooltipPosition: function() {
  38177. var that = this,
  38178. crossCenter = (that._minSide + that._maxSide) / 2,
  38179. alongCenter = (that._basePosition + that._actualPosition) / 2;
  38180. return that.vertical ? {
  38181. x: crossCenter,
  38182. y: alongCenter
  38183. } : {
  38184. x: alongCenter,
  38185. y: crossCenter
  38186. }
  38187. },
  38188. measure: function(layout) {
  38189. var that = this,
  38190. size = _Number(that._options.size),
  38191. textIndent = _Number(that._options.text.indent),
  38192. minbound,
  38193. maxbound,
  38194. indent;
  38195. that._measureText();
  38196. if (that.vertical) {
  38197. minbound = maxbound = layout.x;
  38198. if (that._inverted)
  38199. maxbound = maxbound + size;
  38200. else
  38201. minbound = minbound - size;
  38202. if (that._hasText) {
  38203. indent = that._textHeight / 2;
  38204. if (textIndent > 0)
  38205. maxbound += textIndent + that._textWidth;
  38206. if (textIndent < 0)
  38207. minbound += textIndent - that._textWidth
  38208. }
  38209. }
  38210. else {
  38211. minbound = maxbound = layout.y;
  38212. if (that._inverted)
  38213. maxbound = maxbound + size;
  38214. else
  38215. minbound = minbound - size;
  38216. if (that._hasText) {
  38217. indent = that._textWidth / 2;
  38218. if (textIndent > 0)
  38219. maxbound += textIndent + that._textHeight;
  38220. if (textIndent < 0)
  38221. minbound += textIndent - that._textHeight
  38222. }
  38223. }
  38224. return {
  38225. min: minbound,
  38226. max: maxbound,
  38227. indent: indent
  38228. }
  38229. }
  38230. })
  38231. })(DevExpress);
  38232. /*! Module viz-gauges, file scale.js */
  38233. (function(DX, $, undefined) {
  38234. var viz = DX.viz,
  38235. core = viz.core,
  38236. _Number = Number,
  38237. _String = String,
  38238. _isFinite = isFinite,
  38239. _math = Math,
  38240. _min = _math.min,
  38241. _max = _math.max,
  38242. _abs = _math.abs,
  38243. PI_DIV_180 = _math.PI / 180,
  38244. utils = DX.utils,
  38245. _isFunction = utils.isFunction,
  38246. _isArray = utils.isArray,
  38247. _getCosAndSin = utils.getCosAndSin,
  38248. _convertAngleToRendererSpace = utils.convertAngleToRendererSpace,
  38249. _map = $.map,
  38250. _formatHelper = DX.formatHelper,
  38251. _createTickManager = core.CoreFactory.createTickManager;
  38252. function binarySearch(x, list) {
  38253. var a = 0,
  38254. b = list.length - 1,
  38255. flag = list[a] - list[b] < 0,
  38256. c,
  38257. k = -1;
  38258. if (list[a] === x)
  38259. k = a;
  38260. if (list[b] === x)
  38261. k = b;
  38262. while (k < 0 && a <= b) {
  38263. c = ~~((a + b) / 2);
  38264. if (list[c] === x)
  38265. k = c;
  38266. else if (list[c] - x < 0 === flag)
  38267. a = c + 1;
  38268. else
  38269. b = c - 1
  38270. }
  38271. return k
  38272. }
  38273. function sortAsc(x, y) {
  38274. return x - y
  38275. }
  38276. viz.gauges.__internals.BaseScale = viz.gauges.__internals.BaseElement.inherit({
  38277. _init: function() {
  38278. var that = this;
  38279. that._root = that._renderer.g().attr({'class': 'dxg-scale'});
  38280. that._majorTicks = that._renderer.g().attr({'class': 'dxg-major-ticks'});
  38281. that._minorTicks = that._renderer.g().attr({'class': 'dxg-minor-ticks'});
  38282. that._labels = that._renderer.g().attr({'class': 'dxg-labels'})
  38283. },
  38284. clean: function() {
  38285. var that = this;
  38286. that._root.remove();
  38287. that._majorTicks.remove().clear();
  38288. that._minorTicks.remove().clear();
  38289. that._labels.remove().clear();
  38290. that._majorTicksEnabled = that._minorTicksEnabled = that._labelsEnabled = that._options = that.enabled = null;
  38291. return that
  38292. },
  38293. render: function(options) {
  38294. var that = this;
  38295. that._options = options;
  38296. that._processOptions(options);
  38297. if (that._majorTicksEnabled || that._minorTicksEnabled || that._labelsEnabled) {
  38298. that.enabled = true;
  38299. that._root.append(that._container);
  38300. if (that._majorTicksEnabled)
  38301. that._majorTicks.append(that._root);
  38302. if (that._minorTicksEnabled)
  38303. that._minorTicks.append(that._root);
  38304. if (that._labelsEnabled) {
  38305. that._labels.append(that._root);
  38306. that._measureText()
  38307. }
  38308. }
  38309. return that
  38310. },
  38311. _processOptions: function(options) {
  38312. var that = this;
  38313. that._majorTicksEnabled = options.majorTick.visible && options.majorTick.length > 0 && options.majorTick.width > 0;
  38314. that._minorTicksEnabled = options.minorTick.visible && options.minorTick.length > 0 && options.minorTick.width > 0;
  38315. that._labelsEnabled = options.label.visible && _Number(options.label.indentFromTick) !== 0;
  38316. that._setupOrientation()
  38317. },
  38318. _measureText: function() {
  38319. var that = this,
  38320. domain = that._translator.getDomain(),
  38321. options = that._options,
  38322. tickManager = _createTickManager({}, {
  38323. min: domain[0],
  38324. max: domain[1],
  38325. screenDelta: options.approximateScreenDelta
  38326. }, {
  38327. tickInterval: options.majorTick.tickInterval > 0 ? _Number(options.majorTick.tickInterval) : undefined,
  38328. stick: true,
  38329. textFontStyles: core.utils.patchFontOptions(options.label.font),
  38330. gridSpacingFactor: that._getGridSpacingFactor().majorTicks,
  38331. renderText: function(text, x, y, options) {
  38332. return that._renderer.text(text, x, y, options).append(that._renderer.root)
  38333. },
  38334. getText: function(value) {
  38335. return that._formatValue(value)
  38336. },
  38337. overlappingBehaviorType: that._overlappingBehaviorType
  38338. }),
  38339. maxTextParams = tickManager.getMaxLabelParams();
  38340. that._textVerticalOffset = -maxTextParams.y - maxTextParams.height / 2;
  38341. that._textWidth = maxTextParams.width;
  38342. that._textHeight = maxTextParams.height;
  38343. that._textLength = maxTextParams.length
  38344. },
  38345. _formatValue: function(value) {
  38346. var options = this._options.label,
  38347. text = _formatHelper.format(value, options.format, options.precision);
  38348. if (_isFunction(options.customizeText)) {
  38349. text = {
  38350. value: value,
  38351. valueText: text
  38352. };
  38353. text = _String(options.customizeText.call(text, text))
  38354. }
  38355. return text
  38356. },
  38357. _setupOrientation: null,
  38358. _getCustomValues: function(values, compare) {
  38359. var translator = this._translator,
  38360. result = [];
  38361. if (_isArray(values)) {
  38362. result = _map(values, function(x) {
  38363. return _isFinite(translator.translate(x)) ? _Number(x) : null
  38364. }).sort(compare);
  38365. result = _map(result, function(x, i) {
  38366. return x !== result[i - 1] ? x : null
  38367. })
  38368. }
  38369. return result
  38370. },
  38371. _getLabelPosition: function(layout) {
  38372. return this._getAxisLabelPosition(_Number(this._options.majorTick.length), _Number(this._options.label.indentFromTick), layout)
  38373. },
  38374. _generateTicks: function(layout) {
  38375. var that = this,
  38376. scaleOptions = that._options,
  38377. translatorDomains = that._translator.getDomain(),
  38378. data = {
  38379. min: translatorDomains[0],
  38380. max: translatorDomains[1],
  38381. screenDelta: that._getScreenDelta(layout)
  38382. },
  38383. gridSpacingFactors = that._getGridSpacingFactor(),
  38384. options = {
  38385. tickInterval: scaleOptions.majorTick.tickInterval > 0 ? _Number(scaleOptions.majorTick.tickInterval) : undefined,
  38386. minorTickInterval: scaleOptions.minorTick.tickInterval > 0 ? _Number(scaleOptions.minorTick.tickInterval) : undefined,
  38387. gridSpacingFactor: gridSpacingFactors.majorTicks,
  38388. minorGridSpacingFactor: gridSpacingFactors.minorTicks,
  38389. numberMultipliers: [1, 2, 5],
  38390. textFontStyles: core.utils.patchFontOptions(scaleOptions.label.font),
  38391. labelOptions: scaleOptions.label,
  38392. getText: function(value) {
  38393. return that._formatValue(value)
  38394. },
  38395. isHorizontal: !that.vertical,
  38396. stick: true,
  38397. showMinorTicks: true
  38398. },
  38399. tickManager;
  38400. if (scaleOptions.majorTick.useTicksAutoArrangement) {
  38401. options.useTicksAutoArrangement = true;
  38402. options.renderText = function(text, x, y, options) {
  38403. return that._renderer.text(text, x, y, options).append(that._renderer.root)
  38404. };
  38405. options.translate = that._getTranslateFunction(layout);
  38406. that._applyOverlappingOptions(options, layout)
  38407. }
  38408. tickManager = _createTickManager({}, data, options);
  38409. return {
  38410. majorTicks: tickManager.getTicks(true),
  38411. minorTicks: tickManager.getMinorTicks()
  38412. }
  38413. },
  38414. _getTicks: function(layout) {
  38415. var that = this,
  38416. options = that._options,
  38417. info = that._generateTicks(layout),
  38418. majorValues = options.majorTick.showCalculatedTicks ? info.majorTicks : [],
  38419. customMajorValues = _map(that._getCustomValues(options.majorTick.customTickValues, sortAsc), function(value) {
  38420. return binarySearch(value, majorValues) === -1 ? value : null
  38421. }),
  38422. minorValues = _map(options.minorTick.showCalculatedTicks ? info.minorTicks : [], function(value) {
  38423. return binarySearch(value, customMajorValues) === -1 ? value : null
  38424. }),
  38425. customMinorValues = that._getCustomValues(options.minorTick.customTickValues, sortAsc),
  38426. list = majorValues.concat(minorValues, customMajorValues).sort(sortAsc);
  38427. customMinorValues = _map(customMinorValues, function(value) {
  38428. return binarySearch(value, list) === -1 ? value : null
  38429. });
  38430. return {
  38431. major: _map(majorValues.concat(customMajorValues), function(value) {
  38432. return {
  38433. value: value,
  38434. position: that._translator.translate(value)
  38435. }
  38436. }),
  38437. minor: _map(minorValues.concat(customMinorValues), function(value) {
  38438. return {
  38439. value: value,
  38440. position: that._translator.translate(value)
  38441. }
  38442. })
  38443. }
  38444. },
  38445. _createMajorTicks: function(ticks, layout) {
  38446. var that = this,
  38447. points,
  38448. i = 0,
  38449. ii = ticks.length,
  38450. element;
  38451. that._majorTicks.clear().attr({fill: that._options.majorTick.color});
  38452. points = that._getTickPoints(_Number(that._options.majorTick.length), _Number(that._options.majorTick.width), layout);
  38453. if (points) {
  38454. that._options.hideFirstTick && ++i;
  38455. that._options.hideLastTick && --ii;
  38456. for (; i < ii; ++i) {
  38457. element = that._renderer.path(points, "area");
  38458. that._moveTick(element, ticks[i], layout);
  38459. element.append(that._majorTicks)
  38460. }
  38461. }
  38462. },
  38463. _createMinorTicks: function(ticks, layout) {
  38464. var that = this,
  38465. points,
  38466. i = 0,
  38467. ii = ticks.length,
  38468. element;
  38469. that._minorTicks.clear().attr({fill: that._options.minorTick.color});
  38470. points = that._getTickPoints(_Number(that._options.minorTick.length), _Number(that._options.minorTick.width), layout);
  38471. if (points)
  38472. for (; i < ii; ++i) {
  38473. element = that._renderer.path(points, "area");
  38474. that._moveTick(element, ticks[i], layout);
  38475. element.append(that._minorTicks)
  38476. }
  38477. },
  38478. _createLabels: function(ticks, layout) {
  38479. var that = this,
  38480. indentFromTick = _Number(that._options.label.indentFromTick),
  38481. textPosition,
  38482. i = 0,
  38483. ii = ticks.length,
  38484. points,
  38485. text,
  38486. fontStyles = {},
  38487. rangeContainer;
  38488. that._labels.clear().attr({align: that._getLabelAlign(indentFromTick)}).css(core.utils.patchFontOptions(that._options.label.font));
  38489. textPosition = that._getLabelPosition(layout);
  38490. if (textPosition) {
  38491. rangeContainer = that._options.label.useRangeColors ? that._options.rangeContainer : null;
  38492. that._options.hideFirstLabel && ++i;
  38493. that._options.hideLastLabel && --ii;
  38494. for (; i < ii; ++i) {
  38495. text = that._formatValue(ticks[i].value);
  38496. fontStyles.fill = rangeContainer ? rangeContainer.getColorForValue(ticks[i].value) : null;
  38497. points = that._getLabelOptions(text, textPosition, indentFromTick, ticks[i], layout);
  38498. that._renderer.text(text, points.x, points.y + that._textVerticalOffset).css(fontStyles).append(that._labels)
  38499. }
  38500. }
  38501. },
  38502. resize: function(layout) {
  38503. var that = this,
  38504. ticks = that._getTicks(layout);
  38505. if (that._majorTicksEnabled)
  38506. that._createMajorTicks(ticks.major, layout);
  38507. if (that._minorTicksEnabled)
  38508. that._createMinorTicks(ticks.minor, layout);
  38509. if (that._labelsEnabled)
  38510. that._createLabels(ticks.major, layout);
  38511. return that
  38512. }
  38513. });
  38514. viz.gauges.__internals.CircularScale = viz.gauges.__internals.BaseScale.inherit({
  38515. _getGridSpacingFactor: function() {
  38516. return {
  38517. majorTicks: 17,
  38518. minorTicks: 5
  38519. }
  38520. },
  38521. _getTranslateFunction: function(layout) {
  38522. var that = this,
  38523. indent = _Number(that._options.label.indentFromTick),
  38524. translator = this._translator;
  38525. layout = layout || {
  38526. x: 0,
  38527. y: 0,
  38528. radius: 0
  38529. };
  38530. return function(value) {
  38531. var position = that._getLabelPosition(layout),
  38532. text = that._formatValue(value);
  38533. return that._getLabelOptions(text, position, indent, {position: translator.translate(value)}, layout)
  38534. }
  38535. },
  38536. _overlappingBehaviorType: "circular",
  38537. _getScreenDelta: function(layout) {
  38538. return (this._translator.getCodomainStart() - this._translator.getCodomainEnd()) * layout.radius * PI_DIV_180
  38539. },
  38540. _setupOrientation: function() {
  38541. var that = this;
  38542. that._inner = that._outer = 0;
  38543. switch (that._options.orientation) {
  38544. case'inside':
  38545. that._inner = 1;
  38546. break;
  38547. case'center':
  38548. that._inner = that._outer = 0.5;
  38549. break;
  38550. default:
  38551. that._outer = 1;
  38552. break
  38553. }
  38554. },
  38555. _getTickPoints: function(length, width, layout) {
  38556. var x1 = layout.x - width / 2,
  38557. x2 = layout.x + width / 2,
  38558. y1 = layout.y - layout.radius - length * this._outer,
  38559. y2 = layout.y - layout.radius + length * this._inner;
  38560. return y1 > 0 && y2 > 0 ? [x1, y1, x2, y1, x2, y2, x1, y2] : null
  38561. },
  38562. _moveTick: function(element, tick, layout) {
  38563. element.rotate(_convertAngleToRendererSpace(tick.position), layout.x, layout.y)
  38564. },
  38565. _getAxisLabelPosition: function(tickLength, textIndent, layout) {
  38566. var position = layout.radius + tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
  38567. return position > 0 ? position : null
  38568. },
  38569. _getLabelAlign: function() {
  38570. return 'center'
  38571. },
  38572. _applyOverlappingOptions: function(options, layout) {
  38573. options.circularRadius = this._getLabelPosition(layout);
  38574. options.circularStartAngle = this._translator.getCodomainStart();
  38575. options.circularEndAngle = this._translator.getCodomainEnd();
  38576. options.overlappingBehaviorType = "circular"
  38577. },
  38578. _getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {
  38579. var cossin = _getCosAndSin(tick.position),
  38580. x = layout.x + cossin.cos * textPosition,
  38581. y = layout.y - cossin.sin * textPosition,
  38582. dx = cossin.cos * (textValue.length / this._textLength) * this._textWidth / 2,
  38583. dy = cossin.sin * this._textHeight / 2;
  38584. if (textIndent > 0) {
  38585. x += dx;
  38586. y -= dy
  38587. }
  38588. else {
  38589. x -= dx;
  38590. y += dy
  38591. }
  38592. return {
  38593. x: x,
  38594. y: y
  38595. }
  38596. },
  38597. measure: function(layout) {
  38598. var that = this,
  38599. result = {
  38600. min: layout.radius,
  38601. max: layout.radius
  38602. };
  38603. if (that._majorTicksEnabled) {
  38604. result.min = _min(result.min, layout.radius - that._inner * that._options.majorTick.length);
  38605. result.max = _max(result.max, layout.radius + that._outer * that._options.majorTick.length)
  38606. }
  38607. if (that._minorTicksEnabled) {
  38608. result.min = _min(result.min, layout.radius - that._inner * that._options.minorTick.length);
  38609. result.max = _max(result.max, layout.radius + that._outer * that._options.minorTick.length)
  38610. }
  38611. if (that._labelsEnabled) {
  38612. if (that._options.label.indentFromTick > 0) {
  38613. result.horizontalOffset = _Number(that._options.label.indentFromTick) + that._textWidth;
  38614. result.verticalOffset = _Number(that._options.label.indentFromTick) + that._textHeight
  38615. }
  38616. else {
  38617. result.horizontalOffset = result.verticalOffset = 0;
  38618. result.min -= -_Number(that._options.label.indentFromTick) + _max(that._textWidth, that._textHeight)
  38619. }
  38620. result.inverseHorizontalOffset = that._textWidth / 2;
  38621. result.inverseVerticalOffset = that._textHeight / 2
  38622. }
  38623. return result
  38624. }
  38625. });
  38626. viz.gauges.__internals.LinearScale = viz.gauges.__internals.BaseScale.inherit({
  38627. _getGridSpacingFactor: function() {
  38628. return {
  38629. majorTicks: 25,
  38630. minorTicks: 5
  38631. }
  38632. },
  38633. _getTranslateFunction: function() {
  38634. var tr = this._translator;
  38635. return function(value) {
  38636. return tr.translate(value)
  38637. }
  38638. },
  38639. _overlappingBehaviorType: "linear",
  38640. _getScreenDelta: function() {
  38641. return _abs(this._translator.getCodomainEnd() - this._translator.getCodomainStart())
  38642. },
  38643. _setupOrientation: function() {
  38644. var that = this;
  38645. that.vertical = that._options.vertical;
  38646. that._inner = that._outer = 0;
  38647. if (that.vertical)
  38648. switch (that._options.horizontalOrientation) {
  38649. case'left':
  38650. that._inner = 1;
  38651. break;
  38652. case'center':
  38653. that._inner = that._outer = 0.5;
  38654. break;
  38655. default:
  38656. that._outer = 1;
  38657. break
  38658. }
  38659. else
  38660. switch (that._options.verticalOrientation) {
  38661. case'top':
  38662. that._inner = 1;
  38663. break;
  38664. case'middle':
  38665. that._inner = that._outer = 0.5;
  38666. break;
  38667. default:
  38668. that._outer = 1;
  38669. break
  38670. }
  38671. },
  38672. _getTickPoints: function(length, width, layout) {
  38673. var that = this,
  38674. x1,
  38675. x2,
  38676. y1,
  38677. y2;
  38678. if (that.vertical) {
  38679. x1 = layout.x - length * that._inner;
  38680. x2 = layout.x + length * that._outer;
  38681. y1 = -width / 2;
  38682. y2 = +width / 2
  38683. }
  38684. else {
  38685. x1 = -width / 2;
  38686. x2 = +width / 2;
  38687. y1 = layout.y - length * that._inner;
  38688. y2 = layout.y + length * that._outer
  38689. }
  38690. return [x1, y1, x2, y1, x2, y2, x1, y2]
  38691. },
  38692. _moveTick: function(element, tick) {
  38693. var x = 0,
  38694. y = 0;
  38695. if (this.vertical)
  38696. y = tick.position;
  38697. else
  38698. x = tick.position;
  38699. element.move(x, y)
  38700. },
  38701. _getAxisLabelPosition: function(tickLength, textIndent, layout) {
  38702. var position = tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
  38703. if (this.vertical)
  38704. position += layout.x;
  38705. else
  38706. position += layout.y + (textIndent >= 0 ? 1 : -1) * (this._textVerticalOffset || 0);
  38707. return position
  38708. },
  38709. _getLabelAlign: function(textIndent) {
  38710. return this.vertical ? textIndent > 0 ? 'left' : 'right' : 'center'
  38711. },
  38712. _applyOverlappingOptions: function(options) {
  38713. options.overlappingBehaviorType = "linear"
  38714. },
  38715. _getLabelOptions: function(textValue, textPosition, textIndent, tick) {
  38716. var x,
  38717. y;
  38718. if (this.vertical) {
  38719. x = textPosition;
  38720. y = tick.position
  38721. }
  38722. else {
  38723. x = tick.position;
  38724. y = textPosition
  38725. }
  38726. return {
  38727. x: x,
  38728. y: y
  38729. }
  38730. },
  38731. measure: function(layout) {
  38732. var that = this,
  38733. p = layout[that.vertical ? 'x' : 'y'],
  38734. result = {
  38735. min: p,
  38736. max: p
  38737. };
  38738. if (that._majorTicksEnabled) {
  38739. result.min = _min(result.min, p - that._inner * that._options.majorTick.length);
  38740. result.max = _max(result.max, p + that._outer * that._options.majorTick.length)
  38741. }
  38742. if (that._minorTicksEnabled) {
  38743. result.min = _min(result.min, p - that._inner * that._options.minorTick.length);
  38744. result.max = _max(result.max, p + that._outer * that._options.minorTick.length)
  38745. }
  38746. if (that._labelsEnabled) {
  38747. if (that._options.label.indentFromTick > 0)
  38748. result.max += +_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
  38749. else
  38750. result.min -= -_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
  38751. result.indent = that[that.vertical ? '_textHeight' : '_textWidth'] / 2
  38752. }
  38753. return result
  38754. }
  38755. })
  38756. })(DevExpress, jQuery);
  38757. /*! Module viz-gauges, file rangeContainer.js */
  38758. (function(DX, $, undefined) {
  38759. var _Number = Number,
  38760. _String = String,
  38761. _max = Math.max,
  38762. _abs = Math.abs,
  38763. _isString = DX.utils.isString,
  38764. _isArray = DX.utils.isArray,
  38765. _isFinite = isFinite,
  38766. _each = $.each,
  38767. _map = $.map,
  38768. _Palette = DX.viz.core.Palette;
  38769. DX.viz.gauges.__internals.BaseRangeContainer = DX.viz.gauges.__internals.BaseElement.inherit({
  38770. _init: function() {
  38771. this._root = this._renderer.g().attr({'class': 'dxg-range-container'})
  38772. },
  38773. clean: function() {
  38774. this._root.remove().clear();
  38775. this._options = this.enabled = null;
  38776. return this
  38777. },
  38778. _getRanges: function() {
  38779. var that = this,
  38780. options = that._options,
  38781. translator = that._translator,
  38782. totalStart = translator.getDomain()[0],
  38783. totalEnd = translator.getDomain()[1],
  38784. totalDelta = totalEnd - totalStart,
  38785. isNotEmptySegment = totalDelta >= 0 ? isNotEmptySegmentAsc : isNotEmptySegmentDes,
  38786. subtractSegment = totalDelta >= 0 ? subtractSegmentAsc : subtractSegmentDes,
  38787. list = [],
  38788. ranges = [],
  38789. backgroundRanges = [{
  38790. start: totalStart,
  38791. end: totalEnd
  38792. }],
  38793. threshold = _abs(totalDelta) / 1E4,
  38794. palette = new _Palette(options.palette, {
  38795. type: 'indicatingSet',
  38796. theme: options.themeName
  38797. }),
  38798. backgroundColor = _isString(options.backgroundColor) ? options.backgroundColor : 'none',
  38799. width = options.width || {},
  38800. startWidth = _Number(width > 0 ? width : width.start),
  38801. endWidth = _Number(width > 0 ? width : width.end),
  38802. deltaWidth = endWidth - startWidth;
  38803. if (options.ranges !== undefined && !_isArray(options.ranges))
  38804. return null;
  38805. if (!(startWidth >= 0 && endWidth >= 0 && startWidth + endWidth > 0))
  38806. return null;
  38807. list = _map(_isArray(options.ranges) ? options.ranges : [], function(rangeOptions, i) {
  38808. rangeOptions = rangeOptions || {};
  38809. var start = translator.adjust(rangeOptions.startValue),
  38810. end = translator.adjust(rangeOptions.endValue);
  38811. return _isFinite(start) && _isFinite(end) && isNotEmptySegment(start, end, threshold) ? {
  38812. start: start,
  38813. end: end,
  38814. color: rangeOptions.color,
  38815. classIndex: i
  38816. } : null
  38817. });
  38818. _each(list, function(i, item) {
  38819. var paletteColor = palette.getNextColor();
  38820. item.color = _isString(item.color) && item.color || paletteColor || 'none';
  38821. item.className = 'dxg-range dxg-range-' + item.classIndex;
  38822. delete item.classIndex
  38823. });
  38824. _each(list, function(_, item) {
  38825. var i,
  38826. ii,
  38827. sub,
  38828. subs,
  38829. range,
  38830. newRanges = [],
  38831. newBackgroundRanges = [];
  38832. for (i = 0, ii = ranges.length; i < ii; ++i) {
  38833. range = ranges[i];
  38834. subs = subtractSegment(range.start, range.end, item.start, item.end);
  38835. (sub = subs[0]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub);
  38836. (sub = subs[1]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub)
  38837. }
  38838. newRanges.push(item);
  38839. ranges = newRanges;
  38840. for (i = 0, ii = backgroundRanges.length; i < ii; ++i) {
  38841. range = backgroundRanges[i];
  38842. subs = subtractSegment(range.start, range.end, item.start, item.end);
  38843. (sub = subs[0]) && newBackgroundRanges.push(sub);
  38844. (sub = subs[1]) && newBackgroundRanges.push(sub)
  38845. }
  38846. backgroundRanges = newBackgroundRanges
  38847. });
  38848. _each(backgroundRanges, function(_, range) {
  38849. range.color = backgroundColor;
  38850. range.className = 'dxg-range dxg-background-range';
  38851. ranges.push(range)
  38852. });
  38853. _each(ranges, function(_, range) {
  38854. range.startWidth = (range.start - totalStart) / totalDelta * deltaWidth + startWidth;
  38855. range.endWidth = (range.end - totalStart) / totalDelta * deltaWidth + startWidth
  38856. });
  38857. return ranges
  38858. },
  38859. render: function(options) {
  38860. var that = this;
  38861. that._options = options;
  38862. that._processOptions();
  38863. that._ranges = that._getRanges();
  38864. if (that._ranges) {
  38865. that.enabled = true;
  38866. that._root.append(that._container)
  38867. }
  38868. return that
  38869. },
  38870. resize: function(layout) {
  38871. var that = this;
  38872. that._root.clear();
  38873. if (that._isVisible(layout))
  38874. _each(that._ranges, function(_, range) {
  38875. that._createRange(range, layout).attr({
  38876. fill: range.color,
  38877. 'class': range.className
  38878. }).append(that._root)
  38879. });
  38880. return that
  38881. },
  38882. _processOptions: null,
  38883. _isVisible: null,
  38884. _createRange: null,
  38885. getColorForValue: function(value) {
  38886. var color = null;
  38887. _each(this._ranges, function(_, range) {
  38888. if (range.start <= value && value <= range.end || range.start >= value && value >= range.end) {
  38889. color = range.color;
  38890. return false
  38891. }
  38892. });
  38893. return color
  38894. }
  38895. });
  38896. function subtractSegmentAsc(segmentStart, segmentEnd, otherStart, otherEnd) {
  38897. var result;
  38898. if (otherStart > segmentStart && otherEnd < segmentEnd)
  38899. result = [{
  38900. start: segmentStart,
  38901. end: otherStart
  38902. }, {
  38903. start: otherEnd,
  38904. end: segmentEnd
  38905. }];
  38906. else if (otherStart >= segmentEnd || otherEnd <= segmentStart)
  38907. result = [{
  38908. start: segmentStart,
  38909. end: segmentEnd
  38910. }];
  38911. else if (otherStart <= segmentStart && otherEnd >= segmentEnd)
  38912. result = [];
  38913. else if (otherStart > segmentStart)
  38914. result = [{
  38915. start: segmentStart,
  38916. end: otherStart
  38917. }];
  38918. else if (otherEnd < segmentEnd)
  38919. result = [{
  38920. start: otherEnd,
  38921. end: segmentEnd
  38922. }];
  38923. return result
  38924. }
  38925. function subtractSegmentDes(segmentStart, segmentEnd, otherStart, otherEnd) {
  38926. var result;
  38927. if (otherStart < segmentStart && otherEnd > segmentEnd)
  38928. result = [{
  38929. start: segmentStart,
  38930. end: otherStart
  38931. }, {
  38932. start: otherEnd,
  38933. end: segmentEnd
  38934. }];
  38935. else if (otherStart <= segmentEnd || otherEnd >= segmentStart)
  38936. result = [{
  38937. start: segmentStart,
  38938. end: segmentEnd
  38939. }];
  38940. else if (otherStart >= segmentStart && otherEnd <= segmentEnd)
  38941. result = [];
  38942. else if (otherStart < segmentStart)
  38943. result = [{
  38944. start: segmentStart,
  38945. end: otherStart
  38946. }];
  38947. else if (otherEnd > segmentEnd)
  38948. result = [{
  38949. start: otherEnd,
  38950. end: segmentEnd
  38951. }];
  38952. return result
  38953. }
  38954. function isNotEmptySegmentAsc(start, end, threshold) {
  38955. return end - start >= threshold
  38956. }
  38957. function isNotEmptySegmentDes(start, end, threshold) {
  38958. return start - end >= threshold
  38959. }
  38960. DX.viz.gauges.__internals.CircularRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
  38961. _processOptions: function() {
  38962. var that = this;
  38963. that._inner = that._outer = 0;
  38964. switch (_String(that._options.orientation).toLowerCase()) {
  38965. case'inside':
  38966. that._inner = 1;
  38967. break;
  38968. case'center':
  38969. that._inner = that._outer = 0.5;
  38970. break;
  38971. default:
  38972. that._outer = 1;
  38973. break
  38974. }
  38975. },
  38976. _isVisible: function(layout) {
  38977. var width = this._options.width;
  38978. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  38979. return layout.radius - this._inner * width > 0
  38980. },
  38981. _createRange: function(range, layout) {
  38982. var that = this,
  38983. width = (range.startWidth + range.endWidth) / 2;
  38984. return that._renderer.arc(layout.x, layout.y, layout.radius - that._inner * width, layout.radius + that._outer * width, that._translator.translate(range.end), that._translator.translate(range.start)).attr({"stroke-linejoin": "round"})
  38985. },
  38986. measure: function(layout) {
  38987. var width = this._options.width;
  38988. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  38989. return {
  38990. min: layout.radius - this._inner * width,
  38991. max: layout.radius + this._outer * width
  38992. }
  38993. }
  38994. });
  38995. DX.viz.gauges.__internals.LinearRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
  38996. _processOptions: function() {
  38997. var that = this;
  38998. that.vertical = that._options.vertical;
  38999. that._inner = that._outer = 0;
  39000. if (that.vertical)
  39001. switch (_String(that._options.horizontalOrientation).toLowerCase()) {
  39002. case'left':
  39003. that._inner = 1;
  39004. break;
  39005. case'center':
  39006. that._inner = that._outer = 0.5;
  39007. break;
  39008. default:
  39009. that._outer = 1;
  39010. break
  39011. }
  39012. else
  39013. switch (_String(that._options.verticalOrientation).toLowerCase()) {
  39014. case'top':
  39015. that._inner = 1;
  39016. break;
  39017. case'middle':
  39018. that._inner = that._outer = 0.5;
  39019. break;
  39020. default:
  39021. that._outer = 1;
  39022. break
  39023. }
  39024. },
  39025. _isVisible: function() {
  39026. return true
  39027. },
  39028. _createRange: function(range, layout) {
  39029. var that = this,
  39030. inner = that._inner,
  39031. outer = that._outer,
  39032. startPosition = that._translator.translate(range.start),
  39033. endPosition = that._translator.translate(range.end),
  39034. points,
  39035. x = layout.x,
  39036. y = layout.y,
  39037. startWidth = range.startWidth,
  39038. endWidth = range.endWidth;
  39039. if (that.vertical)
  39040. points = [x - startWidth * inner, startPosition, x - endWidth * inner, endPosition, x + endWidth * outer, endPosition, x + startWidth * outer, startPosition];
  39041. else
  39042. points = [startPosition, y + startWidth * outer, startPosition, y - startWidth * inner, endPosition, y - endWidth * inner, endPosition, y + endWidth * outer];
  39043. return that._renderer.path(points, "area")
  39044. },
  39045. measure: function(layout) {
  39046. var result = {},
  39047. width;
  39048. result.min = result.max = layout[this.vertical ? 'x' : 'y'];
  39049. width = this._options.width;
  39050. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  39051. result.min -= this._inner * width;
  39052. result.max += this._outer * width;
  39053. return result
  39054. }
  39055. })
  39056. })(DevExpress, jQuery);
  39057. /*! Module viz-gauges, file title.js */
  39058. (function(DX, $, undefined) {
  39059. var viz = DX.viz,
  39060. core = viz.core,
  39061. _isString = DX.utils.isString,
  39062. _max = Math.max,
  39063. _extend = $.extend;
  39064. viz.gauges.__internals.Title = DX.Class.inherit({
  39065. ctor: function(parameters) {
  39066. this._renderer = parameters.renderer;
  39067. this._container = parameters.container
  39068. },
  39069. dispose: function() {
  39070. this._renderer = this._container = null;
  39071. return this
  39072. },
  39073. clean: function() {
  39074. var that = this;
  39075. if (that._root) {
  39076. that._root.remove().clear();
  39077. that._root = that._layout = null
  39078. }
  39079. return that
  39080. },
  39081. render: function(titleOptions, subtitleOptions) {
  39082. var that = this,
  39083. hasTitle = _isString(titleOptions.text) && titleOptions.text.length > 0,
  39084. hasSubtitle = _isString(subtitleOptions.text) && subtitleOptions.text.length > 0,
  39085. element,
  39086. bbox,
  39087. totalWidth = 0,
  39088. totalHeight = 0,
  39089. y = 0;
  39090. if (!hasTitle && !hasSubtitle)
  39091. return that;
  39092. that._root = that._renderer.g().attr({'class': 'dxg-title'}).append(that._container);
  39093. if (hasTitle) {
  39094. element = that._renderer.text(titleOptions.text, 0, 0).attr({align: 'center'}).css(core.utils.patchFontOptions(titleOptions.font)).append(that._root);
  39095. bbox = element.getBBox();
  39096. y += -bbox.y;
  39097. element.attr({y: y});
  39098. y += bbox.height + bbox.y;
  39099. totalWidth = _max(totalWidth, bbox.width);
  39100. totalHeight += bbox.height
  39101. }
  39102. if (hasSubtitle) {
  39103. element = that._renderer.text(subtitleOptions.text, 0, 0).attr({align: 'center'}).css(core.utils.patchFontOptions(subtitleOptions.font)).append(that._root);
  39104. bbox = element.getBBox();
  39105. y += -bbox.y;
  39106. element.attr({y: y});
  39107. totalWidth = _max(totalWidth, bbox.width);
  39108. totalHeight += bbox.height
  39109. }
  39110. that._layout = _extend({
  39111. position: titleOptions.position,
  39112. width: totalWidth,
  39113. height: totalHeight
  39114. }, titleOptions.layout);
  39115. return that
  39116. },
  39117. getLayoutOptions: function() {
  39118. return this._layout
  39119. },
  39120. locate: function(left, top) {
  39121. this._root.attr({
  39122. translateX: left + this._layout.width / 2,
  39123. translateY: top
  39124. });
  39125. return this
  39126. }
  39127. })
  39128. })(DevExpress, jQuery);
  39129. /*! Module viz-gauges, file layoutManager.js */
  39130. (function(DX, $, undefined) {
  39131. var _Number = Number,
  39132. _String = String,
  39133. _max = Math.max,
  39134. _each = $.each;
  39135. function patchLayoutOptions(options) {
  39136. if (options.position) {
  39137. var position = _String(options.position).toLowerCase().split('-');
  39138. options.verticalAlignment = position[0];
  39139. options.horizontalAlignment = position[1]
  39140. }
  39141. }
  39142. DX.viz.gauges.__internals.LayoutManager = DX.Class.inherit({
  39143. setRect: function(rect) {
  39144. this._currentRect = rect.clone();
  39145. return this
  39146. },
  39147. getRect: function() {
  39148. return this._currentRect.clone()
  39149. },
  39150. beginLayout: function(rect) {
  39151. this._rootRect = rect.clone();
  39152. this._currentRect = rect.clone();
  39153. this._cache = [];
  39154. return this
  39155. },
  39156. applyLayout: function(target) {
  39157. var options = target.getLayoutOptions(),
  39158. currentRect,
  39159. verticalOverlay;
  39160. if (!options)
  39161. return this;
  39162. currentRect = this._currentRect;
  39163. verticalOverlay = _Number(options.overlay) || 0;
  39164. patchLayoutOptions(options);
  39165. switch (_String(options.verticalAlignment).toLowerCase()) {
  39166. case'bottom':
  39167. currentRect.bottom -= _max(options.height - verticalOverlay, 0);
  39168. break;
  39169. default:
  39170. currentRect.top += _max(options.height - verticalOverlay, 0);
  39171. break
  39172. }
  39173. this._cache.push({
  39174. target: target,
  39175. options: options
  39176. });
  39177. return this
  39178. },
  39179. endLayout: function() {
  39180. var that = this,
  39181. rootRect = that._rootRect,
  39182. currentRect = that._currentRect;
  39183. _each(that._cache, function(_, cacheItem) {
  39184. var options = cacheItem.options,
  39185. left,
  39186. top,
  39187. verticalOverlay = _Number(options.overlay) || 0;
  39188. switch (_String(options.verticalAlignment).toLowerCase()) {
  39189. case'bottom':
  39190. top = currentRect.bottom - verticalOverlay;
  39191. currentRect.bottom += _max(options.height - verticalOverlay, 0);
  39192. break;
  39193. default:
  39194. top = currentRect.top - options.height + verticalOverlay;
  39195. currentRect.top -= _max(options.height - verticalOverlay, 0);
  39196. break
  39197. }
  39198. switch (_String(options.horizontalAlignment).toLowerCase()) {
  39199. case'left':
  39200. left = rootRect.left;
  39201. break;
  39202. case'right':
  39203. left = rootRect.right - options.width;
  39204. break;
  39205. default:
  39206. left = rootRect.horizontalMiddle() - options.width / 2;
  39207. break
  39208. }
  39209. cacheItem.target.locate(left, top)
  39210. });
  39211. that._cache = null;
  39212. return that
  39213. },
  39214. selectRectByAspectRatio: function(aspectRatio, margins) {
  39215. var rect = this._currentRect.clone(),
  39216. selfAspectRatio,
  39217. width = 0,
  39218. height = 0;
  39219. margins = margins || {};
  39220. if (aspectRatio > 0) {
  39221. rect.left += margins.left || 0;
  39222. rect.right -= margins.right || 0;
  39223. rect.top += margins.top || 0;
  39224. rect.bottom -= margins.bottom || 0;
  39225. if (rect.width() > 0 && rect.height() > 0) {
  39226. selfAspectRatio = rect.height() / rect.width();
  39227. if (selfAspectRatio > 1)
  39228. aspectRatio < selfAspectRatio ? width = rect.width() : height = rect.height();
  39229. else
  39230. aspectRatio > selfAspectRatio ? height = rect.height() : width = rect.width();
  39231. width > 0 || (width = height / aspectRatio);
  39232. height > 0 || (height = width * aspectRatio);
  39233. width = (rect.width() - width) / 2;
  39234. height = (rect.height() - height) / 2;
  39235. rect.left += width;
  39236. rect.right -= width;
  39237. rect.top += height;
  39238. rect.bottom -= height
  39239. }
  39240. else {
  39241. rect.left = rect.right = rect.horizontalMiddle();
  39242. rect.top = rect.bottom = rect.verticalMiddle()
  39243. }
  39244. }
  39245. return rect
  39246. },
  39247. selectRectBySizes: function(sizes, margins) {
  39248. var rect = this._currentRect.clone(),
  39249. step;
  39250. margins = margins || {};
  39251. if (sizes) {
  39252. rect.left += margins.left || 0;
  39253. rect.right -= margins.right || 0;
  39254. rect.top += margins.top || 0;
  39255. rect.bottom -= margins.bottom || 0;
  39256. if (sizes.width > 0) {
  39257. step = (rect.width() - sizes.width) / 2;
  39258. if (step > 0) {
  39259. rect.left += step;
  39260. rect.right -= step
  39261. }
  39262. }
  39263. if (sizes.height > 0) {
  39264. step = (rect.height() - sizes.height) / 2;
  39265. if (step > 0) {
  39266. rect.top += step;
  39267. rect.bottom -= step
  39268. }
  39269. }
  39270. }
  39271. return rect
  39272. }
  39273. })
  39274. })(DevExpress, jQuery);
  39275. /*! Module viz-gauges, file themeManager.js */
  39276. (function(DX, $, undefined) {
  39277. var _extend = $.extend;
  39278. DX.viz.gauges.__internals.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  39279. _themeSection: 'gauge',
  39280. _fontFields: ['scale.label.font', 'valueIndicators.rangebar.text.font', 'valueIndicators.textcloud.text.font', 'title.font', 'subtitle.font', 'tooltip.font', 'indicator.text.font', 'loadingIndicator.font'],
  39281. _initializeTheme: function() {
  39282. var that = this,
  39283. subTheme;
  39284. if (that._subTheme) {
  39285. subTheme = _extend(true, {}, that._theme[that._subTheme], that._theme);
  39286. _extend(true, that._theme, subTheme)
  39287. }
  39288. that.callBase.apply(that, arguments)
  39289. }
  39290. })
  39291. })(DevExpress, jQuery);
  39292. /*! Module viz-gauges, file baseGauge.js */
  39293. (function(DX, $, undefined) {
  39294. var _Number = Number,
  39295. _isString = DX.utils.isString,
  39296. _getAppropriateFormat = DX.utils.getAppropriateFormat,
  39297. _extend = $.extend,
  39298. _each = $.each;
  39299. DX.viz.gauges.dxBaseGauge = DX.viz.core.BaseWidget.inherit({
  39300. _rootClassPrefix: "dxg",
  39301. _createThemeManager: function() {
  39302. return this._factory.createThemeManager()
  39303. },
  39304. _initCore: function() {
  39305. var that = this;
  39306. that._root = that._renderer.root;
  39307. that._translator = that._factory.createTranslator();
  39308. that._initNotifiers();
  39309. that._tracker = that._factory.createTracker({
  39310. renderer: that._renderer,
  39311. container: that._root
  39312. });
  39313. that._layoutManager = that._factory.createLayoutManager();
  39314. that._title = that._factory.createTitle({
  39315. renderer: that._renderer,
  39316. container: that._root
  39317. });
  39318. that._deltaIndicator = that._factory.createDeltaIndicator({
  39319. renderer: that._renderer,
  39320. container: that._root
  39321. });
  39322. that._setupDomain();
  39323. that._setTrackerCallbacks()
  39324. },
  39325. _setTrackerCallbacks: function() {
  39326. var that = this,
  39327. renderer = that._renderer,
  39328. tooltip = that._tooltip;
  39329. that._tracker.setCallbacks({
  39330. 'tooltip-show': function(target, info) {
  39331. var tooltipParameters = target.getTooltipParameters(),
  39332. offset = renderer.getRootOffset(),
  39333. formatObject = _extend({
  39334. value: tooltipParameters.value,
  39335. valueText: tooltip.formatValue(tooltipParameters.value),
  39336. color: tooltipParameters.color
  39337. }, info);
  39338. return tooltip.show(formatObject, {
  39339. x: tooltipParameters.x + offset.left,
  39340. y: tooltipParameters.y + offset.top,
  39341. offset: tooltipParameters.offset
  39342. }, {target: info})
  39343. },
  39344. 'tooltip-hide': function() {
  39345. return tooltip.hide()
  39346. }
  39347. });
  39348. that._resetTrackerCallbacks = function() {
  39349. that._resetTrackerCallbacks = that = renderer = tooltip = null
  39350. }
  39351. },
  39352. _initNotifiers: function() {
  39353. var that = this,
  39354. counter = 0;
  39355. that._notifiers = {
  39356. dirty: function() {
  39357. that._resetIsReady();
  39358. ++counter
  39359. },
  39360. ready: function() {
  39361. if (--counter === 0)
  39362. that._drawn()
  39363. }
  39364. }
  39365. },
  39366. _disposeCore: function() {
  39367. var that = this;
  39368. that._themeManager.dispose();
  39369. that._tracker.dispose();
  39370. that._title.dispose();
  39371. that._deltaIndicator && that._deltaIndicator.dispose();
  39372. that._root = that._translator = that._notifiers = that._tracker = that._layoutManager = that._title = null
  39373. },
  39374. _refresh: function() {
  39375. var that = this,
  39376. callBase = that.callBase;
  39377. that._endLoading(function() {
  39378. callBase.call(that)
  39379. })
  39380. },
  39381. _clean: function() {
  39382. this._cleanCore()
  39383. },
  39384. _render: function() {
  39385. var that = this;
  39386. that._setupCodomain();
  39387. that._setupAnimationSettings();
  39388. that._setupDefaultFormat();
  39389. that._renderCore()
  39390. },
  39391. _cleanCore: function() {
  39392. var that = this;
  39393. that._title.clean();
  39394. that._deltaIndicator && that._deltaIndicator.clean();
  39395. that._tracker.deactivate();
  39396. that._cleanContent()
  39397. },
  39398. _renderCore: function() {
  39399. var that = this;
  39400. if (!that._isValidDomain)
  39401. return;
  39402. var theme = that._themeManager.theme(),
  39403. titleTheme = _extend(true, {}, theme.title, processTitleOptions(that.option("title"))),
  39404. subTitleTheme = _extend(true, {}, theme.subtitle, processTitleOptions(that.option("subtitle")));
  39405. that._title.render(titleTheme, subTitleTheme);
  39406. that._deltaIndicator && that._deltaIndicator.render(_extend(true, {}, theme.indicator, that.option("indicator")));
  39407. that._layoutManager.beginLayout(that._rootRect);
  39408. _each([that._deltaIndicator, that._title], function(_, item) {
  39409. item && that._layoutManager.applyLayout(item)
  39410. });
  39411. that._mainRect = that._layoutManager.getRect();
  39412. that._renderContent();
  39413. that._layoutManager.endLayout();
  39414. that._tracker.setTooltipState(that._tooltip.isEnabled());
  39415. that._tracker.activate();
  39416. that._noAnimation = null;
  39417. that.option("debugMode") === true && that._renderDebugInfo();
  39418. that._debug_rendered && that._debug_rendered()
  39419. },
  39420. _setTooltipOptions: function() {
  39421. var that = this;
  39422. that.callBase();
  39423. that._tracker && that._tracker.setTooltipState(that._tooltip.isEnabled())
  39424. },
  39425. _renderDebugInfo: function() {
  39426. var that = this,
  39427. group = that._debugGroup || that._renderer.g().attr({"class": "debug-info"}).append(that._renderer.root),
  39428. rect;
  39429. group.clear();
  39430. rect = that._rootRect;
  39431. that._renderer.rect(rect.left, rect.top, rect.width(), rect.height()).attr({
  39432. stroke: "#000000",
  39433. "stroke-width": 1,
  39434. fill: "none"
  39435. }).append(group);
  39436. rect = that._mainRect;
  39437. that._renderer.rect(rect.left, rect.top, rect.width(), rect.height()).attr({
  39438. stroke: "#0000FF",
  39439. "stroke-width": 1,
  39440. fill: "none"
  39441. }).append(group);
  39442. rect = that._layoutManager.getRect();
  39443. rect && that._renderer.rect(rect.left, rect.top, rect.width(), rect.height()).attr({
  39444. stroke: "#FF0000",
  39445. "stroke-width": 1,
  39446. fill: "none"
  39447. }).append(group);
  39448. rect = that._title.getLayoutOptions() ? that._title._root.getBBox() : null;
  39449. rect && that._renderer.rect(rect.x, rect.y, rect.width, rect.height).attr({
  39450. stroke: "#00FF00",
  39451. "stroke-width": 1,
  39452. fill: "none"
  39453. }).append(group);
  39454. rect = that._deltaIndicator && that._deltaIndicator.getLayoutOptions() ? that._deltaIndicator._root.getBBox() : null;
  39455. rect && that._renderer.rect(rect.x, rect.y, rect.width, rect.height).attr({
  39456. stroke: "#00FF00",
  39457. "stroke-width": 1,
  39458. fill: "none"
  39459. }).append(group)
  39460. },
  39461. _applySize: function() {
  39462. var canvas = this._canvas;
  39463. this._rootRect = new DX.viz.core.Rectangle({
  39464. left: canvas.left,
  39465. top: canvas.top,
  39466. right: canvas.width - canvas.right,
  39467. bottom: canvas.height - canvas.bottom
  39468. });
  39469. this._width = canvas.width;
  39470. this._height = canvas.height
  39471. },
  39472. _resize: function() {
  39473. var that = this;
  39474. that._resizing = that._noAnimation = true;
  39475. that._cleanCore();
  39476. that._renderCore();
  39477. that._resizing = null
  39478. },
  39479. _optionChanged: function(args) {
  39480. var that = this;
  39481. switch (args.name) {
  39482. case"startValue":
  39483. case"endValue":
  39484. that._setupDomain();
  39485. that._invalidate();
  39486. break;
  39487. default:
  39488. that.callBase(args);
  39489. break
  39490. }
  39491. },
  39492. _setupDomain: function() {
  39493. var that = this;
  39494. that._setupDomainCore();
  39495. that._isValidDomain = isFinite(1 / (that._translator.getDomain()[1] - that._translator.getDomain()[0]));
  39496. if (!that._isValidDomain)
  39497. that._incidentOccured("W2301")
  39498. },
  39499. _setupAnimationSettings: function() {
  39500. var that = this,
  39501. option = that.option("animation");
  39502. that._animationSettings = null;
  39503. if (option === undefined || option) {
  39504. option = _extend({
  39505. enabled: true,
  39506. duration: 1000,
  39507. easing: "easeOutCubic"
  39508. }, option);
  39509. if (option.enabled && option.duration > 0)
  39510. that._animationSettings = {
  39511. duration: _Number(option.duration),
  39512. easing: option.easing
  39513. }
  39514. }
  39515. that._containerBackgroundColor = that.option("containerBackgroundColor") || that._themeManager.theme().containerBackgroundColor
  39516. },
  39517. _setupDefaultFormat: function() {
  39518. var domain = this._translator.getDomain();
  39519. this._defaultFormatOptions = _getAppropriateFormat(domain[0], domain[1], this._getApproximateScreenRange())
  39520. },
  39521. _setupDomainCore: null,
  39522. _calculateSize: null,
  39523. _cleanContent: null,
  39524. _renderContent: null,
  39525. _setupCodomain: null,
  39526. _getApproximateScreenRange: null,
  39527. _factory: {
  39528. createTranslator: function() {
  39529. return new DX.viz.core.Translator1D
  39530. },
  39531. createTracker: function(parameters) {
  39532. return new DX.viz.gauges.__internals.Tracker(parameters)
  39533. },
  39534. createLayoutManager: function() {
  39535. return new DX.viz.gauges.__internals.LayoutManager
  39536. },
  39537. createTitle: function(parameters) {
  39538. return new DX.viz.gauges.__internals.Title(parameters)
  39539. },
  39540. createDeltaIndicator: function(parameters) {
  39541. return DX.viz.gauges.__internals.DeltaIndicator ? new DX.viz.gauges.__internals.DeltaIndicator(parameters) : null
  39542. }
  39543. }
  39544. });
  39545. function processTitleOptions(options) {
  39546. return _isString(options) ? {text: options} : options || {}
  39547. }
  39548. })(DevExpress, jQuery);
  39549. /*! Module viz-gauges, file gauge.js */
  39550. (function(DX, $, undefined) {
  39551. var _isDefined = DX.utils.isDefined,
  39552. _isArray = DX.utils.isArray,
  39553. _isNumber = DX.utils.isNumber,
  39554. _isFinite = isFinite,
  39555. _Number = Number,
  39556. _String = String,
  39557. _abs = Math.abs,
  39558. _extend = $.extend,
  39559. _each = $.each,
  39560. _map = $.map,
  39561. _noop = $.noop,
  39562. _factory = DX.viz.gauges.__factory,
  39563. OPTION_VALUE = 'value',
  39564. OPTION_SUBVALUES = 'subvalues';
  39565. function processValue(value, fallbackValue) {
  39566. return _isFinite(value) ? _Number(value) : fallbackValue
  39567. }
  39568. function parseArrayOfNumbers(arg) {
  39569. return _isArray(arg) ? arg : _isNumber(arg) ? [arg] : null
  39570. }
  39571. DX.viz.gauges.dxGauge = DX.viz.gauges.dxBaseGauge.inherit({
  39572. _initCore: function() {
  39573. var that = this;
  39574. that._setupValue(that.option(OPTION_VALUE));
  39575. that.__subvalues = parseArrayOfNumbers(that.option(OPTION_SUBVALUES));
  39576. that._setupSubvalues(that.__subvalues);
  39577. selectMode(that);
  39578. that.callBase.apply(that, arguments);
  39579. that._scale = that._createScale({
  39580. renderer: that._renderer,
  39581. container: that._root,
  39582. translator: that._translator
  39583. });
  39584. that._rangeContainer = that._createRangeContainer({
  39585. renderer: that._renderer,
  39586. container: that._root,
  39587. translator: that._translator
  39588. })
  39589. },
  39590. _disposeCore: function() {
  39591. var that = this;
  39592. that.callBase.apply(that, arguments);
  39593. that._scale.dispose();
  39594. that._rangeContainer.dispose();
  39595. that._disposeValueIndicators();
  39596. that._scale = that._rangeContainer = null
  39597. },
  39598. _disposeValueIndicators: function() {
  39599. var that = this;
  39600. that._valueIndicator && that._valueIndicator.dispose();
  39601. that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.dispose();
  39602. that._valueIndicator = that._subvalueIndicatorsSet = null
  39603. },
  39604. _setupDomainCore: function() {
  39605. var that = this,
  39606. scaleOption = that.option('scale') || {},
  39607. startValue = that.option('startValue'),
  39608. endValue = that.option('endValue');
  39609. startValue = _isNumber(startValue) ? _Number(startValue) : _isNumber(scaleOption.startValue) ? _Number(scaleOption.startValue) : 0;
  39610. endValue = _isNumber(endValue) ? _Number(endValue) : _isNumber(scaleOption.endValue) ? _Number(scaleOption.endValue) : 100;
  39611. that._baseValue = startValue < endValue ? startValue : endValue;
  39612. that._translator.setDomain(startValue, endValue)
  39613. },
  39614. _cleanContent: function() {
  39615. var that = this;
  39616. that._rangeContainer.clean();
  39617. that._scale.clean();
  39618. that._cleanValueIndicators()
  39619. },
  39620. _renderContent: function() {
  39621. var that = this,
  39622. elements;
  39623. that._rangeContainer.render(_extend(that._getOption("rangeContainer"), {
  39624. themeName: that._themeManager.themeName(),
  39625. vertical: that._area.vertical
  39626. }));
  39627. that._scale.render(_extend(that._getOption("scale"), {
  39628. rangeContainer: that._rangeContainer.enabled ? that._rangeContainer : null,
  39629. approximateScreenDelta: that._getApproximateScreenRange(),
  39630. offset: 0,
  39631. vertical: that._area.vertical
  39632. }));
  39633. elements = _map([that._scale, that._rangeContainer].concat(that._prepareValueIndicators()), function(element) {
  39634. return element && element.enabled ? element : null
  39635. });
  39636. that._applyMainLayout(elements);
  39637. _each(elements, function(_, element) {
  39638. element.resize(that._getElementLayout(element.getOffset()))
  39639. });
  39640. that._updateActiveElements()
  39641. },
  39642. _updateIndicatorSettings: function(settings) {
  39643. var that = this;
  39644. settings.currentValue = settings.baseValue = _isFinite(that._translator.translate(settings.baseValue)) ? _Number(settings.baseValue) : that._baseValue;
  39645. settings.vertical = that._area.vertical;
  39646. if (settings.text && !settings.text.format && !settings.text.precision) {
  39647. settings.text.format = that._defaultFormatOptions.format;
  39648. settings.text.precision = that._defaultFormatOptions.precision
  39649. }
  39650. },
  39651. _prepareIndicatorSettings: function(options, defaultTypeField) {
  39652. var that = this,
  39653. theme = that._themeManager.theme("valueIndicators"),
  39654. type = _String(options.type || that._themeManager.theme(defaultTypeField)).toLowerCase(),
  39655. settings = _extend(true, {}, theme._default, theme[type], options);
  39656. settings.type = type;
  39657. settings.animation = that._animationSettings;
  39658. settings.containerBackgroundColor = that._containerBackgroundColor;
  39659. that._updateIndicatorSettings(settings);
  39660. return settings
  39661. },
  39662. _cleanValueIndicators: function() {
  39663. this._valueIndicator && this._valueIndicator.clean();
  39664. this._subvalueIndicatorsSet && this._subvalueIndicatorsSet.clean()
  39665. },
  39666. _prepareValueIndicators: function() {
  39667. var that = this;
  39668. that._prepareValueIndicator();
  39669. that.__subvalues !== null && that._prepareSubvalueIndicators();
  39670. return [that._valueIndicator, that._subvalueIndicatorsSet]
  39671. },
  39672. _updateActiveElements: function() {
  39673. this._updateValueIndicator();
  39674. this._updateSubvalueIndicators()
  39675. },
  39676. _prepareValueIndicator: function() {
  39677. var that = this,
  39678. target = that._valueIndicator,
  39679. settings = that._prepareIndicatorSettings(that.option("valueIndicator") || {}, 'valueIndicatorType');
  39680. if (target && target.type !== settings.type) {
  39681. target.dispose();
  39682. target = null
  39683. }
  39684. if (!target)
  39685. target = that._valueIndicator = that._createIndicator(settings.type, that._root, 'dxg-value-indicator', 'value-indicator');
  39686. target.render(settings)
  39687. },
  39688. _createSubvalueIndicatorsSet: function() {
  39689. var that = this,
  39690. owner = that._renderer.g().attr({'class': 'dxg-subvalue-indicators'});
  39691. return new ValueIndicatorsSet({
  39692. root: owner,
  39693. container: that._root,
  39694. createIndicator: function(type, i) {
  39695. return that._createIndicator(type, owner, 'dxg-subvalue-indicator', 'subvalue-indicator', i)
  39696. }
  39697. })
  39698. },
  39699. _prepareSubvalueIndicators: function() {
  39700. var that = this,
  39701. target = that._subvalueIndicatorsSet,
  39702. settings = that._prepareIndicatorSettings(that.option("subvalueIndicator") || {}, 'subvalueIndicatorType'),
  39703. isRecreate;
  39704. if (!target)
  39705. target = that._subvalueIndicatorsSet = that._createSubvalueIndicatorsSet();
  39706. isRecreate = settings.type !== target.type;
  39707. target.type = settings.type;
  39708. if (that._createIndicator(settings.type))
  39709. target.render(settings, isRecreate)
  39710. },
  39711. _setupValue: function(value) {
  39712. this.__value = processValue(value, this.__value)
  39713. },
  39714. _setupSubvalues: function(subvalues) {
  39715. var vals = subvalues === undefined ? this.__subvalues : parseArrayOfNumbers(subvalues),
  39716. i,
  39717. ii,
  39718. list;
  39719. if (vals === null)
  39720. return;
  39721. for (i = 0, ii = vals.length, list = []; i < ii; ++i)
  39722. list.push(processValue(vals[i], this.__subvalues[i]));
  39723. this.__subvalues = list
  39724. },
  39725. _updateValueIndicator: function() {
  39726. var that = this;
  39727. that._valueIndicator && that._valueIndicator.value(that.__value, that._noAnimation);
  39728. that._resizing || that.hideLoadingIndicator()
  39729. },
  39730. _updateSubvalueIndicators: function() {
  39731. var that = this;
  39732. that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.values(that.__subvalues, that._noAnimation);
  39733. that._resizing || that.hideLoadingIndicator()
  39734. },
  39735. value: function(arg) {
  39736. var that = this;
  39737. if (arg !== undefined) {
  39738. that._setupValue(arg);
  39739. that._updateValueIndicator();
  39740. that.option(OPTION_VALUE, that.__value);
  39741. return that
  39742. }
  39743. return that.__value
  39744. },
  39745. subvalues: function(arg) {
  39746. var that = this;
  39747. if (arg !== undefined) {
  39748. if (that.__subvalues !== null) {
  39749. that._setupSubvalues(arg);
  39750. that._updateSubvalueIndicators();
  39751. that.option(OPTION_SUBVALUES, that.__subvalues)
  39752. }
  39753. return that
  39754. }
  39755. return that.__subvalues !== null ? that.__subvalues.slice() : undefined
  39756. },
  39757. _valueChangedHandler: function(name, val) {
  39758. var that = this;
  39759. switch (name) {
  39760. case OPTION_VALUE:
  39761. that._setupValue(val);
  39762. that._updateValueIndicator();
  39763. that.option(OPTION_VALUE, that.__value);
  39764. return true;
  39765. case OPTION_SUBVALUES:
  39766. if (that.__subvalues !== null) {
  39767. that._setupSubvalues(val);
  39768. that._updateSubvalueIndicators();
  39769. that.option(OPTION_SUBVALUES, that.__subvalues);
  39770. return true
  39771. }
  39772. return false;
  39773. default:
  39774. return false
  39775. }
  39776. },
  39777. _optionChanged: function(args) {
  39778. var that = this;
  39779. if (that._valueChangedHandler(args.name, args.value, args.previousValue))
  39780. return;
  39781. if (args.name === "scale") {
  39782. that._setupDomain();
  39783. that._invalidate()
  39784. }
  39785. else
  39786. that.callBase.apply(that, arguments)
  39787. },
  39788. _optionValuesEqual: function(name, oldValue, newValue) {
  39789. var result;
  39790. switch (name) {
  39791. case OPTION_VALUE:
  39792. result = oldValue === newValue;
  39793. break;
  39794. case OPTION_SUBVALUES:
  39795. result = compareArrays(oldValue, newValue);
  39796. break;
  39797. default:
  39798. result = this.callBase.apply(this, arguments);
  39799. break
  39800. }
  39801. return result
  39802. },
  39803. _applyMainLayout: null,
  39804. _getElementLayout: null,
  39805. _createScale: function(parameters) {
  39806. return _factory[this._factoryMethods.scale](parameters)
  39807. },
  39808. _createRangeContainer: function(parameters) {
  39809. return _factory[this._factoryMethods.rangeContainer](parameters)
  39810. },
  39811. _createIndicator: function(type, owner, className, trackerType, trackerIndex, _strict) {
  39812. var that = this,
  39813. indicator = _factory[that._factoryMethods.indicator]({
  39814. renderer: that._renderer,
  39815. translator: that._translator,
  39816. notifiers: that._notifiers,
  39817. owner: owner,
  39818. tracker: that._tracker,
  39819. className: className
  39820. }, type, _strict);
  39821. if (indicator) {
  39822. indicator.type = type;
  39823. indicator._trackerInfo = {
  39824. type: trackerType,
  39825. index: trackerIndex
  39826. }
  39827. }
  39828. return indicator
  39829. },
  39830. _getApproximateScreenRange: null
  39831. });
  39832. DX.viz.gauges.dxGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);
  39833. DX.viz.gauges.dxGauge.prototype._factory.createThemeManager = function() {
  39834. return new DX.viz.gauges.__internals.ThemeManager
  39835. };
  39836. function valueGetter(arg) {
  39837. return arg ? arg.value : NaN
  39838. }
  39839. function setupValues(that, fieldName, optionItems) {
  39840. var currentValues = that[fieldName],
  39841. newValues = _isArray(optionItems) ? _map(optionItems, valueGetter) : [],
  39842. i = 0,
  39843. ii = newValues.length,
  39844. list = [];
  39845. for (; i < ii; ++i)
  39846. list.push(processValue(newValues[i], currentValues[i]));
  39847. that[fieldName] = list
  39848. }
  39849. function selectMode(gauge) {
  39850. if (gauge.option(OPTION_VALUE) === undefined && gauge.option(OPTION_SUBVALUES) === undefined)
  39851. if (gauge.option('valueIndicators') !== undefined) {
  39852. disableDefaultMode(gauge);
  39853. selectHardMode(gauge)
  39854. }
  39855. }
  39856. function disableDefaultMode(that) {
  39857. that.value = that.subvalues = _noop;
  39858. that._setupValue = that._setupSubvalues = that._updateValueIndicator = that._updateSubvalueIndicators = null
  39859. }
  39860. function selectHardMode(that) {
  39861. that._indicatorValues = [];
  39862. setupValues(that, '_indicatorValues', that.option('valueIndicators'));
  39863. that._valueIndicators = [];
  39864. that._valueChangedHandler = valueChangedHandler_hardMode;
  39865. that._updateActiveElements = updateActiveElements_hardMode;
  39866. that._prepareValueIndicators = prepareValueIndicators_hardMode;
  39867. that._disposeValueIndicators = disposeValueIndicators_hardMode;
  39868. that._cleanValueIndicators = cleanValueIndicators_hardMode;
  39869. that.indicatorValue = indicatorValue_hardMode
  39870. }
  39871. function valueChangedHandler_hardMode(name, val) {
  39872. if (name === 'valueIndicators') {
  39873. setupValues(this, '_indicatorValues', val);
  39874. this._invalidate();
  39875. return true
  39876. }
  39877. return false
  39878. }
  39879. function updateActiveElements_hardMode() {
  39880. var that = this;
  39881. _each(that._valueIndicators, function(_, valueIndicator) {
  39882. valueIndicator.value(that._indicatorValues[valueIndicator.index], that._noAnimation)
  39883. });
  39884. that._resizing || that.hideLoadingIndicator()
  39885. }
  39886. function prepareValueIndicators_hardMode() {
  39887. var that = this,
  39888. valueIndicators = that._valueIndicators || [],
  39889. userOptions = that.option('valueIndicators'),
  39890. optionList = [],
  39891. i = 0,
  39892. ii;
  39893. for (ii = _isArray(userOptions) ? userOptions.length : 0; i < ii; ++i)
  39894. optionList.push(userOptions[i]);
  39895. for (ii = valueIndicators.length; i < ii; ++i)
  39896. optionList.push(null);
  39897. var newValueIndicators = [];
  39898. _each(optionList, function(i, userSettings) {
  39899. var valueIndicator = valueIndicators[i];
  39900. if (!userSettings) {
  39901. valueIndicator && valueIndicator.dispose();
  39902. return
  39903. }
  39904. var settings = that._prepareIndicatorSettings(userSettings, "valueIndicatorType");
  39905. if (valueIndicator && valueIndicator.type !== settings.type) {
  39906. valueIndicator.dispose();
  39907. valueIndicator = null
  39908. }
  39909. if (!valueIndicator)
  39910. valueIndicator = that._createIndicator(settings.type, that._root, 'dxg-value-indicator', 'value-indicator', i, true);
  39911. if (valueIndicator) {
  39912. valueIndicator.index = i;
  39913. valueIndicator.render(settings);
  39914. newValueIndicators.push(valueIndicator)
  39915. }
  39916. });
  39917. that._valueIndicators = newValueIndicators;
  39918. return that._valueIndicators
  39919. }
  39920. function disposeValueIndicators_hardMode() {
  39921. _each(this._valueIndicators, function(_, valueIndicator) {
  39922. valueIndicator.dispose()
  39923. });
  39924. this._valueIndicators = null
  39925. }
  39926. function cleanValueIndicators_hardMode() {
  39927. _each(this._valueIndicators, function(_, valueIndicator) {
  39928. valueIndicator.clean()
  39929. })
  39930. }
  39931. function indicatorValue_hardMode(index, value) {
  39932. return accessPointerValue(this, this._valueIndicators, this._indicatorValues, index, value)
  39933. }
  39934. function accessPointerValue(that, pointers, values, index, value) {
  39935. if (value !== undefined) {
  39936. if (values[index] !== undefined) {
  39937. values[index] = processValue(value, values[index]);
  39938. pointers[index] && pointers[index].value(values[index]);
  39939. that._resizing || that.hideLoadingIndicator()
  39940. }
  39941. return that
  39942. }
  39943. else
  39944. return values[index]
  39945. }
  39946. function compareArrays(array1, array2) {
  39947. var i,
  39948. ii;
  39949. if (array1 === array2)
  39950. return true;
  39951. if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
  39952. for (i = 0, ii = array1.length; i < ii; ++i)
  39953. if (_abs(array1[i] - array2[i]) > 1E-8)
  39954. return false;
  39955. return true
  39956. }
  39957. return false
  39958. }
  39959. function ValueIndicatorsSet(parameters) {
  39960. this._parameters = parameters;
  39961. this._indicators = []
  39962. }
  39963. ValueIndicatorsSet.prototype = {
  39964. costructor: ValueIndicatorsSet,
  39965. dispose: function() {
  39966. var that = this;
  39967. _each(that._indicators, function(_, indicator) {
  39968. indicator.dispose()
  39969. });
  39970. that._parameters = that._options = that._indicators = that._colorPalette = that._palette = null;
  39971. return that
  39972. },
  39973. clean: function() {
  39974. var that = this;
  39975. that._parameters.root.remove();
  39976. that._sample && that._sample.clean().dispose();
  39977. _each(that._indicators, function(_, indicator) {
  39978. indicator.clean()
  39979. });
  39980. that._sample = that._options = that._palette = null;
  39981. return that
  39982. },
  39983. render: function(options, isRecreate) {
  39984. var that = this;
  39985. that._options = options;
  39986. that._sample = that._parameters.createIndicator(that.type);
  39987. that._sample.render(options);
  39988. that.enabled = that._sample.enabled;
  39989. that._palette = _isDefined(options.palette) ? new DX.viz.core.Palette(options.palette) : null;
  39990. if (that.enabled) {
  39991. that._parameters.root.append(that._parameters.container);
  39992. that._generatePalette(that._indicators.length);
  39993. that._indicators = _map(that._indicators, function(indicator, i) {
  39994. if (isRecreate) {
  39995. indicator.dispose();
  39996. indicator = that._parameters.createIndicator(that.type, i)
  39997. }
  39998. indicator.render(that._getIndicatorOptions(i));
  39999. return indicator
  40000. })
  40001. }
  40002. return that
  40003. },
  40004. getOffset: function() {
  40005. return _Number(this._options.offset) || 0
  40006. },
  40007. resize: function(layout) {
  40008. var that = this;
  40009. that._layout = layout;
  40010. _each(that._indicators, function(_, indicator) {
  40011. indicator.resize(layout)
  40012. });
  40013. return that
  40014. },
  40015. measure: function(layout) {
  40016. return this._sample.measure(layout)
  40017. },
  40018. _getIndicatorOptions: function(index) {
  40019. var result = this._options;
  40020. if (this._colorPalette)
  40021. result = _extend({}, result, {color: this._colorPalette[index]});
  40022. return result
  40023. },
  40024. _generatePalette: function(count) {
  40025. var that = this,
  40026. colors = null;
  40027. if (that._palette) {
  40028. colors = [];
  40029. that._palette.reset();
  40030. var i = 0;
  40031. for (; i < count; ++i)
  40032. colors.push(that._palette.getNextColor())
  40033. }
  40034. that._colorPalette = colors
  40035. },
  40036. _adjustIndicatorsCount: function(count) {
  40037. var that = this,
  40038. indicators = that._indicators,
  40039. i,
  40040. ii,
  40041. indicator,
  40042. indicatorsLen = indicators.length;
  40043. if (indicatorsLen > count) {
  40044. for (i = count, ii = indicatorsLen; i < ii; ++i)
  40045. indicators[i].clean().dispose();
  40046. that._indicators = indicators.slice(0, count);
  40047. that._generatePalette(indicators.length)
  40048. }
  40049. else if (indicatorsLen < count) {
  40050. that._generatePalette(count);
  40051. for (i = indicatorsLen, ii = count; i < ii; ++i) {
  40052. indicator = that._parameters.createIndicator(that.type, i);
  40053. indicator.render(that._getIndicatorOptions(i)).resize(that._layout);
  40054. indicators.push(indicator)
  40055. }
  40056. }
  40057. },
  40058. values: function(arg, _noAnimation) {
  40059. var that = this;
  40060. if (!that.enabled)
  40061. return;
  40062. if (arg !== undefined) {
  40063. if (!_isArray(arg))
  40064. arg = _isFinite(arg) ? [Number(arg)] : null;
  40065. if (arg) {
  40066. that._adjustIndicatorsCount(arg.length);
  40067. _each(that._indicators, function(i, indicator) {
  40068. indicator.value(arg[i], _noAnimation)
  40069. })
  40070. }
  40071. return that
  40072. }
  40073. return _map(that._indicators, function(indicator) {
  40074. return indicator.value()
  40075. })
  40076. }
  40077. }
  40078. })(DevExpress, jQuery);
  40079. /*! Module viz-gauges, file circularGauge.js */
  40080. (function(DX, $, undefined) {
  40081. var _isFinite = isFinite,
  40082. _Number = Number,
  40083. _normalizeAngle = DX.utils.normalizeAngle,
  40084. _getCosAndSin = DX.utils.getCosAndSin,
  40085. _abs = Math.abs,
  40086. _max = Math.max,
  40087. _min = Math.min,
  40088. _round = Math.round,
  40089. _each = $.each,
  40090. PI = Math.PI;
  40091. function getSides(startAngle, endAngle) {
  40092. var startCosSin = _getCosAndSin(startAngle),
  40093. endCosSin = _getCosAndSin(endAngle),
  40094. startCos = startCosSin.cos,
  40095. startSin = startCosSin.sin,
  40096. endCos = endCosSin.cos,
  40097. endSin = endCosSin.sin;
  40098. return {
  40099. left: startSin <= 0 && endSin >= 0 || startSin <= 0 && endSin <= 0 && startCos <= endCos || startSin >= 0 && endSin >= 0 && startCos >= endCos ? -1 : _min(startCos, endCos, 0),
  40100. right: startSin >= 0 && endSin <= 0 || startSin >= 0 && endSin >= 0 && startCos >= endCos || startSin <= 0 && endSin <= 0 && startCos <= endCos ? 1 : _max(startCos, endCos, 0),
  40101. up: startCos <= 0 && endCos >= 0 || startCos <= 0 && endCos <= 0 && startSin >= endSin || startCos >= 0 && endCos >= 0 && startSin <= endSin ? -1 : -_max(startSin, endSin, 0),
  40102. down: startCos >= 0 && endCos <= 0 || startCos >= 0 && endCos >= 0 && startSin <= endSin || startCos <= 0 && endCos <= 0 && startSin >= endSin ? 1 : -_min(startSin, endSin, 0)
  40103. }
  40104. }
  40105. DX.registerComponent("dxCircularGauge", DX.viz.gauges, DX.viz.gauges.dxGauge.inherit({
  40106. _rootClass: "dxg-circular-gauge",
  40107. _factoryMethods: {
  40108. scale: 'createCircularScale',
  40109. rangeContainer: 'createCircularRangeContainer',
  40110. indicator: 'createCircularIndicator'
  40111. },
  40112. _setupCodomain: function() {
  40113. var that = this,
  40114. geometry = that.option("geometry") || {},
  40115. startAngle = geometry.startAngle,
  40116. endAngle = geometry.endAngle,
  40117. sides;
  40118. startAngle = _isFinite(startAngle) ? _normalizeAngle(startAngle) : 225;
  40119. endAngle = _isFinite(endAngle) ? _normalizeAngle(endAngle) : -45;
  40120. if (_abs(startAngle - endAngle) < 1) {
  40121. endAngle -= 360;
  40122. sides = {
  40123. left: -1,
  40124. up: -1,
  40125. right: 1,
  40126. down: 1
  40127. }
  40128. }
  40129. else {
  40130. startAngle < endAngle && (endAngle -= 360);
  40131. sides = getSides(startAngle, endAngle)
  40132. }
  40133. that._area = {
  40134. x: 0,
  40135. y: 0,
  40136. radius: 100,
  40137. startCoord: startAngle,
  40138. endCoord: endAngle,
  40139. scaleRadius: geometry.scaleRadius > 0 ? _Number(geometry.scaleRadius) : undefined,
  40140. sides: sides
  40141. };
  40142. that._translator.setCodomain(startAngle, endAngle)
  40143. },
  40144. _measureMainElements: function(elements) {
  40145. var that = this,
  40146. radius = that._area.radius,
  40147. maxRadius = 0,
  40148. minRadius = Infinity,
  40149. maxHorizontalOffset = 0,
  40150. maxVerticalOffset = 0,
  40151. maxInverseHorizontalOffset = 0,
  40152. maxInverseVerticalOffset = 0;
  40153. _each(elements, function(_, element) {
  40154. var bounds = element.measure({radius: radius - element.getOffset()});
  40155. bounds.min > 0 && (minRadius = _min(minRadius, bounds.min));
  40156. bounds.max > 0 && (maxRadius = _max(maxRadius, bounds.max));
  40157. bounds.horizontalOffset > 0 && (maxHorizontalOffset = _max(maxHorizontalOffset, bounds.max + bounds.horizontalOffset));
  40158. bounds.verticalOffset > 0 && (maxVerticalOffset = _max(maxVerticalOffset, bounds.max + bounds.verticalOffset));
  40159. bounds.inverseHorizontalOffset > 0 && (maxInverseHorizontalOffset = _max(maxInverseHorizontalOffset, bounds.inverseHorizontalOffset));
  40160. bounds.inverseVerticalOffset > 0 && (maxInverseVerticalOffset = _max(maxInverseVerticalOffset, bounds.inverseVerticalOffset))
  40161. });
  40162. maxHorizontalOffset = _max(maxHorizontalOffset - maxRadius, 0);
  40163. maxVerticalOffset = _max(maxVerticalOffset - maxRadius, 0);
  40164. return {
  40165. minRadius: minRadius,
  40166. maxRadius: maxRadius,
  40167. horizontalMargin: maxHorizontalOffset,
  40168. verticalMargin: maxVerticalOffset,
  40169. inverseHorizontalMargin: maxInverseHorizontalOffset,
  40170. inverseVerticalMargin: maxInverseVerticalOffset
  40171. }
  40172. },
  40173. _applyMainLayout: function(elements) {
  40174. var that = this,
  40175. measurements = that._measureMainElements(elements),
  40176. area = that._area,
  40177. sides = area.sides,
  40178. margins = {
  40179. left: (sides.left < -0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
  40180. right: (sides.right > 0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
  40181. top: (sides.up < -0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0,
  40182. bottom: (sides.down > 0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0
  40183. },
  40184. rect = that._layoutManager.selectRectByAspectRatio((sides.down - sides.up) / (sides.right - sides.left), margins),
  40185. radius = _min(rect.width() / (sides.right - sides.left), rect.height() / (sides.down - sides.up)),
  40186. x,
  40187. y,
  40188. scaler = (measurements.maxRadius - area.radius + area.scaleRadius) / radius;
  40189. if (0 < scaler && scaler < 1) {
  40190. rect = rect.scale(scaler);
  40191. radius *= scaler
  40192. }
  40193. radius = radius - measurements.maxRadius + area.radius;
  40194. x = rect.left - rect.width() * sides.left / (sides.right - sides.left);
  40195. y = rect.top - rect.height() * sides.up / (sides.down - sides.up);
  40196. area.x = _round(x);
  40197. area.y = _round(y);
  40198. area.radius = radius;
  40199. rect.left -= margins.left;
  40200. rect.right += margins.right;
  40201. rect.top -= margins.top;
  40202. rect.bottom += margins.bottom;
  40203. that._layoutManager.setRect(rect)
  40204. },
  40205. _getElementLayout: function(offset) {
  40206. return {
  40207. x: this._area.x,
  40208. y: this._area.y,
  40209. radius: _round(this._area.radius - offset)
  40210. }
  40211. },
  40212. _getApproximateScreenRange: function() {
  40213. var that = this,
  40214. area = that._area,
  40215. r = _min(that._canvas.width / (area.sides.right - area.sides.left), that._canvas.height / (area.sides.down - area.sides.up));
  40216. r > area.totalRadius && (r = area.totalRadius);
  40217. r = 0.8 * r;
  40218. return -that._translator.getCodomainRange() * r * PI / 180
  40219. },
  40220. _getDefaultSize: function() {
  40221. return {
  40222. width: 300,
  40223. height: 300
  40224. }
  40225. }
  40226. }));
  40227. DX.viz.gauges.dxCircularGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);
  40228. DX.viz.gauges.dxCircularGauge.prototype._factory.createThemeManager = function() {
  40229. var themeManager = new DX.viz.gauges.__internals.ThemeManager;
  40230. themeManager._subTheme = "_circular";
  40231. return themeManager
  40232. }
  40233. })(DevExpress, jQuery);
  40234. /*! Module viz-gauges, file linearGauge.js */
  40235. (function(DX, $, undefined) {
  40236. var _String = String,
  40237. _Number = Number,
  40238. _max = Math.max,
  40239. _min = Math.min,
  40240. _round = Math.round,
  40241. _each = $.each;
  40242. DX.registerComponent("dxLinearGauge", DX.viz.gauges, DX.viz.gauges.dxGauge.inherit({
  40243. _rootClass: 'dxg-linear-gauge',
  40244. _factoryMethods: {
  40245. scale: 'createLinearScale',
  40246. rangeContainer: 'createLinearRangeContainer',
  40247. indicator: 'createLinearIndicator'
  40248. },
  40249. _setupCodomain: function() {
  40250. var that = this,
  40251. geometry = that.option('geometry') || {},
  40252. vertical = _String(geometry.orientation).toLowerCase() === 'vertical';
  40253. that._area = {
  40254. vertical: vertical,
  40255. x: 0,
  40256. y: 0,
  40257. startCoord: -100,
  40258. endCoord: 100,
  40259. scaleSize: geometry.scaleSize > 0 ? _Number(geometry.scaleSize) : undefined
  40260. };
  40261. that._scale.vertical = vertical;
  40262. that._rangeContainer.vertical = vertical
  40263. },
  40264. _measureMainElements: function(elements) {
  40265. var that = this,
  40266. x = that._area.x,
  40267. y = that._area.y,
  40268. minBound = 1000,
  40269. maxBound = 0,
  40270. indent = 0;
  40271. _each(elements, function(_, element) {
  40272. var bounds = element.measure({
  40273. x: x + element.getOffset(),
  40274. y: y + element.getOffset()
  40275. });
  40276. maxBound = _max(maxBound, bounds.max);
  40277. minBound = _min(minBound, bounds.min);
  40278. bounds.indent > 0 && (indent = _max(indent, bounds.indent))
  40279. });
  40280. return {
  40281. minBound: minBound,
  40282. maxBound: maxBound,
  40283. indent: indent
  40284. }
  40285. },
  40286. _applyMainLayout: function(elements) {
  40287. var that = this,
  40288. measurements = that._measureMainElements(elements),
  40289. area = that._area,
  40290. rect,
  40291. offset,
  40292. counterSize = area.scaleSize + 2 * measurements.indent;
  40293. if (area.vertical) {
  40294. rect = that._layoutManager.selectRectBySizes({
  40295. width: measurements.maxBound - measurements.minBound,
  40296. height: counterSize
  40297. });
  40298. offset = rect.horizontalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
  40299. area.startCoord = rect.bottom - measurements.indent;
  40300. area.endCoord = rect.top + measurements.indent;
  40301. area.x = _round(area.x + offset)
  40302. }
  40303. else {
  40304. rect = that._layoutManager.selectRectBySizes({
  40305. height: measurements.maxBound - measurements.minBound,
  40306. width: counterSize
  40307. });
  40308. offset = rect.verticalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
  40309. area.startCoord = rect.left + measurements.indent;
  40310. area.endCoord = rect.right - measurements.indent;
  40311. area.y = _round(area.y + offset)
  40312. }
  40313. that._translator.setCodomain(area.startCoord, area.endCoord);
  40314. that._layoutManager.setRect(rect)
  40315. },
  40316. _getElementLayout: function(offset) {
  40317. return {
  40318. x: _round(this._area.x + offset),
  40319. y: _round(this._area.y + offset)
  40320. }
  40321. },
  40322. _getApproximateScreenRange: function() {
  40323. var that = this,
  40324. area = that._area,
  40325. s = area.vertical ? that._canvas.height : that._canvas.width;
  40326. s > area.totalSize && (s = area.totalSize);
  40327. s = s * 0.8;
  40328. return s
  40329. },
  40330. _getDefaultSize: function() {
  40331. var geometry = this.option('geometry') || {};
  40332. if (geometry.orientation === 'vertical')
  40333. return {
  40334. width: 100,
  40335. height: 300
  40336. };
  40337. else
  40338. return {
  40339. width: 300,
  40340. height: 100
  40341. }
  40342. }
  40343. }));
  40344. DX.viz.gauges.dxLinearGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);
  40345. DX.viz.gauges.dxLinearGauge.prototype._factory.createThemeManager = function() {
  40346. var themeManager = new DX.viz.gauges.__internals.ThemeManager;
  40347. themeManager._subTheme = '_linear';
  40348. return themeManager
  40349. }
  40350. })(DevExpress, jQuery);
  40351. /*! Module viz-gauges, file barGauge.js */
  40352. (function(DX, $, undefined) {
  40353. var PI_DIV_180 = Math.PI / 180,
  40354. _abs = Math.abs,
  40355. _round = Math.round,
  40356. _floor = Math.floor,
  40357. _min = Math.min,
  40358. _max = Math.max,
  40359. _isArray = DX.utils.isArray,
  40360. _convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  40361. _getCosAndSin = DX.utils.getCosAndSin,
  40362. _patchFontOptions = DX.viz.core.utils.patchFontOptions,
  40363. _Number = Number,
  40364. _isFinite = isFinite,
  40365. _noop = $.noop,
  40366. _extend = $.extend,
  40367. _getSampleText = DX.viz.gauges.__internals.getSampleText,
  40368. _formatValue = DX.viz.gauges.__internals.formatValue,
  40369. _Palette = DX.viz.core.Palette,
  40370. OPTION_VALUES = "values";
  40371. var dxBarGauge = DX.viz.gauges.dxBaseGauge.inherit({
  40372. _rootClass: "dxbg-bar-gauge",
  40373. _initCore: function() {
  40374. var that = this;
  40375. that.callBase.apply(that, arguments);
  40376. that._barsGroup = that._renderer.g().attr({"class": "dxbg-bars"});
  40377. that._values = [];
  40378. that._context = {
  40379. renderer: that._renderer,
  40380. translator: that._translator,
  40381. tracker: that._tracker,
  40382. group: that._barsGroup
  40383. };
  40384. that._animateStep = function(pos) {
  40385. var bars = that._bars,
  40386. i,
  40387. ii;
  40388. for (i = 0, ii = bars.length; i < ii; ++i)
  40389. bars[i].animate(pos)
  40390. };
  40391. that._animateComplete = function() {
  40392. var bars = that._bars,
  40393. i,
  40394. ii;
  40395. for (i = 0, ii = bars.length; i < ii; ++i)
  40396. bars[i].endAnimation();
  40397. that._notifiers.ready()
  40398. }
  40399. },
  40400. _disposeCore: function() {
  40401. var that = this;
  40402. that._barsGroup = that._values = that._context = that._animateStep = that._animateComplete = null;
  40403. that.callBase.apply(that, arguments)
  40404. },
  40405. _setupDomainCore: function() {
  40406. var that = this,
  40407. startValue = that.option("startValue"),
  40408. endValue = that.option("endValue");
  40409. _isFinite(startValue) || (startValue = 0);
  40410. _isFinite(endValue) || (endValue = 100);
  40411. that._translator.setDomain(startValue, endValue);
  40412. that._baseValue = that._translator.adjust(that.option("baseValue"));
  40413. _isFinite(that._baseValue) || (that._baseValue = startValue < endValue ? startValue : endValue)
  40414. },
  40415. _getDefaultSize: function() {
  40416. return {
  40417. width: 300,
  40418. height: 300
  40419. }
  40420. },
  40421. _setupCodomain: DX.viz.gauges.dxCircularGauge.prototype._setupCodomain,
  40422. _getApproximateScreenRange: function() {
  40423. var that = this,
  40424. sides = that._area.sides,
  40425. width = that._canvas.width / (sides.right - sides.left),
  40426. height = that._canvas.height / (sides.down - sides.up),
  40427. r = width < height ? width : height;
  40428. return -that._translator.getCodomainRange() * r * PI_DIV_180
  40429. },
  40430. _setupAnimationSettings: function() {
  40431. var that = this;
  40432. that.callBase.apply(that, arguments);
  40433. if (that._animationSettings) {
  40434. that._animationSettings.step = that._animateStep;
  40435. that._animationSettings.complete = that._animateComplete
  40436. }
  40437. },
  40438. _cleanContent: function() {
  40439. var that = this,
  40440. i,
  40441. ii;
  40442. that._barsGroup.remove();
  40443. that._animationSettings && that._barsGroup.stopAnimation();
  40444. for (i = 0, ii = that._bars ? that._bars.length : 0; i < ii; ++i)
  40445. that._bars[i].dispose();
  40446. that._palette = that._bars = null
  40447. },
  40448. _renderContent: function() {
  40449. var that = this,
  40450. labelOptions = that.option("label"),
  40451. text,
  40452. bbox,
  40453. context = that._context;
  40454. that._barsGroup.append(that._root);
  40455. context.textEnabled = labelOptions === undefined || labelOptions && (!("visible" in labelOptions) || labelOptions.visible);
  40456. if (context.textEnabled) {
  40457. context.textColor = labelOptions && labelOptions.font && labelOptions.font.color || null;
  40458. labelOptions = _extend(true, {}, that._themeManager.theme().label, labelOptions);
  40459. context.formatOptions = {
  40460. format: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.format : that._defaultFormatOptions.format,
  40461. precision: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.precision : that._defaultFormatOptions.precision,
  40462. customizeText: labelOptions.customizeText
  40463. };
  40464. context.textOptions = {align: "center"};
  40465. context.fontStyles = _patchFontOptions(_extend({}, that._themeManager.theme().label.font, labelOptions.font, {color: null}));
  40466. that._textIndent = labelOptions.indent > 0 ? _Number(labelOptions.indent) : 0;
  40467. context.lineWidth = labelOptions.connectorWidth > 0 ? _Number(labelOptions.connectorWidth) : 0;
  40468. context.lineColor = labelOptions.connectorColor || null;
  40469. text = that._renderer.text(_getSampleText(that._translator, context.formatOptions), 0, 0).attr(context.textOptions).css(context.fontStyles).append(that._barsGroup);
  40470. bbox = text.getBBox();
  40471. text.remove();
  40472. context.textVerticalOffset = -bbox.y - bbox.height / 2;
  40473. context.textWidth = bbox.width;
  40474. context.textHeight = bbox.height
  40475. }
  40476. DX.viz.gauges.dxCircularGauge.prototype._applyMainLayout.call(that);
  40477. that._renderBars()
  40478. },
  40479. _measureMainElements: function() {
  40480. var result = {maxRadius: this._area.radius};
  40481. if (this._context.textEnabled) {
  40482. result.horizontalMargin = this._context.textWidth;
  40483. result.verticalMargin = this._context.textHeight
  40484. }
  40485. return result
  40486. },
  40487. _renderBars: function() {
  40488. var that = this,
  40489. options = _extend({}, that._themeManager.theme(), that.option()),
  40490. relativeInnerRadius,
  40491. radius,
  40492. area = that._area;
  40493. that._palette = new _Palette(options.palette, {
  40494. stepHighlight: 50,
  40495. theme: that._themeManager.themeName()
  40496. });
  40497. relativeInnerRadius = options.relativeInnerRadius > 0 && options.relativeInnerRadius < 1 ? _Number(options.relativeInnerRadius) : 0.1;
  40498. radius = area.radius;
  40499. if (that._context.textEnabled) {
  40500. that._textIndent = _round(_min(that._textIndent, radius / 2));
  40501. radius -= that._textIndent
  40502. }
  40503. that._outerRadius = _floor(radius);
  40504. that._innerRadius = _floor(radius * relativeInnerRadius);
  40505. that._barSpacing = options.barSpacing > 0 ? _Number(options.barSpacing) : 0;
  40506. _extend(that._context, {
  40507. backgroundColor: options.backgroundColor,
  40508. x: area.x,
  40509. y: area.y,
  40510. startAngle: area.startCoord,
  40511. endAngle: area.endCoord,
  40512. baseAngle: that._translator.translate(that._baseValue)
  40513. });
  40514. that._bars = [];
  40515. that._updateValues(that.option(OPTION_VALUES))
  40516. },
  40517. _arrangeBars: function(count) {
  40518. var that = this,
  40519. radius = that._outerRadius - that._innerRadius,
  40520. context = that._context,
  40521. spacing,
  40522. _count,
  40523. unitOffset,
  40524. i;
  40525. context.barSize = count > 0 ? _max((radius - (count - 1) * that._barSpacing) / count, 1) : 0;
  40526. spacing = count > 1 ? _max(_min((radius - count * context.barSize) / (count - 1), that._barSpacing), 0) : 0;
  40527. _count = _min(_floor((radius + spacing) / context.barSize), count);
  40528. that._setBarsCount(_count);
  40529. radius = that._outerRadius;
  40530. context.textRadius = radius + that._textIndent;
  40531. that._palette.reset();
  40532. unitOffset = context.barSize + spacing;
  40533. for (i = 0; i < _count; ++i, radius -= unitOffset)
  40534. that._bars[i].arrange({
  40535. radius: radius,
  40536. color: that._palette.getNextColor()
  40537. })
  40538. },
  40539. _setBarsCount: function(count) {
  40540. var that = this,
  40541. i,
  40542. ii;
  40543. if (that._bars.length > count) {
  40544. for (i = count, ii = that._bars.length; i < ii; ++i)
  40545. that._bars[i].dispose();
  40546. that._bars.splice(count, ii - count)
  40547. }
  40548. else if (that._bars.length < count)
  40549. for (i = that._bars.length, ii = count; i < ii; ++i)
  40550. that._bars.push(new BarWrapper(i, that._context));
  40551. if (that._bars.length > 0) {
  40552. if (that._dummyBackground) {
  40553. that._dummyBackground.dispose();
  40554. that._dummyBackground = null
  40555. }
  40556. }
  40557. else {
  40558. if (!that._dummyBackground)
  40559. that._dummyBackground = that._renderer.arc().attr({"stroke-linejoin": "round"}).append(that._barsGroup);
  40560. that._dummyBackground.attr({
  40561. x: that._context.x,
  40562. y: that._context.y,
  40563. outerRadius: that._outerRadius,
  40564. innerRadius: that._innerRadius,
  40565. startAngle: that._context.endAngle,
  40566. endAngle: that._context.startAngle,
  40567. fill: that._context.backgroundColor
  40568. })
  40569. }
  40570. },
  40571. _updateBars: function(values) {
  40572. var that = this,
  40573. i,
  40574. ii;
  40575. for (i = 0, ii = that._bars.length; i < ii; ++i)
  40576. that._bars[i].setValue(values[i])
  40577. },
  40578. _animateBars: function(values) {
  40579. var that = this,
  40580. i,
  40581. ii = that._bars.length;
  40582. if (ii > 0) {
  40583. for (i = 0; i < ii; ++i)
  40584. that._bars[i].beginAnimation(values[i]);
  40585. that._barsGroup.animate({_: 0}, that._animationSettings)
  40586. }
  40587. },
  40588. _updateValues: function(values) {
  40589. var that = this,
  40590. list = _isArray(values) && values || _isFinite(values) && [values] || [],
  40591. i,
  40592. ii = list.length,
  40593. value,
  40594. barValues = [],
  40595. immediateReady = true;
  40596. that._values.length = ii;
  40597. for (i = 0; i < ii; ++i) {
  40598. value = list[i];
  40599. that._values[i] = value = _Number(_isFinite(value) ? value : that._values[i]);
  40600. if (_isFinite(value))
  40601. barValues.push(value)
  40602. }
  40603. that._notifiers.dirty();
  40604. that._animationSettings && that._barsGroup.stopAnimation();
  40605. if (that._bars) {
  40606. that._arrangeBars(barValues.length);
  40607. if (that._animationSettings && !that._noAnimation) {
  40608. immediateReady = false;
  40609. that._animateBars(barValues)
  40610. }
  40611. else
  40612. that._updateBars(barValues)
  40613. }
  40614. immediateReady && that._notifiers.ready();
  40615. if (!that._resizing) {
  40616. that.option(OPTION_VALUES, that._values);
  40617. that.hideLoadingIndicator()
  40618. }
  40619. },
  40620. values: function(arg) {
  40621. if (arg !== undefined) {
  40622. this._updateValues(arg);
  40623. return this
  40624. }
  40625. else
  40626. return this._values.slice(0)
  40627. },
  40628. _optionChanged: function(args) {
  40629. if (args.name === OPTION_VALUES)
  40630. this._updateValues(args.value);
  40631. else
  40632. this.callBase.apply(this, arguments)
  40633. },
  40634. _optionValuesEqual: function(name, oldValue, newValue) {
  40635. if (name === OPTION_VALUES)
  40636. return compareArrays(oldValue, newValue);
  40637. else
  40638. return this.callBase.apply(this, arguments)
  40639. }
  40640. });
  40641. DX.registerComponent("dxBarGauge", DX.viz.gauges, dxBarGauge);
  40642. var ThemeManager = DX.viz.gauges.__internals.ThemeManager.inherit({
  40643. _themeSection: "barGauge",
  40644. _fontFields: ["label.font", "title.font", "tooltip.font", "loadingIndicator.font"]
  40645. });
  40646. dxBarGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.dxBaseGauge.prototype._factory);
  40647. dxBarGauge.prototype._factory.createThemeManager = function() {
  40648. return new ThemeManager
  40649. };
  40650. var BarWrapper = function(index, context) {
  40651. var that = this;
  40652. that._context = context;
  40653. that._background = context.renderer.arc().attr({
  40654. "stroke-linejoin": "round",
  40655. fill: context.backgroundColor
  40656. }).append(context.group);
  40657. that._bar = context.renderer.arc().attr({"stroke-linejoin": "round"}).append(context.group);
  40658. if (context.textEnabled) {
  40659. that._line = context.renderer.path([], "line").attr({"stroke-width": context.lineWidth}).append(context.group);
  40660. that._text = context.renderer.text("", 0, 0).css(context.fontStyles).attr(context.textOptions).append(context.group)
  40661. }
  40662. that._tracker = context.renderer.arc().attr({"stroke-linejoin": "round"});
  40663. context.tracker.attach(that._tracker, that, {index: index});
  40664. that._index = index;
  40665. that._angle = context.baseAngle;
  40666. that._settings = {
  40667. x: context.x,
  40668. y: context.y,
  40669. startAngle: context.baseAngle,
  40670. endAngle: context.baseAngle
  40671. }
  40672. };
  40673. _extend(BarWrapper.prototype, {
  40674. dispose: function() {
  40675. var that = this;
  40676. that._background.dispose();
  40677. that._bar.dispose();
  40678. if (that._context.textEnabled) {
  40679. that._line.dispose();
  40680. that._text.dispose()
  40681. }
  40682. that._context.tracker.detach(that._tracker);
  40683. that._context = that._settings = that._background = that._bar = that._line = that._text = that._tracker = null;
  40684. return that
  40685. },
  40686. arrange: function(options) {
  40687. var that = this,
  40688. context = that._context;
  40689. that._settings.outerRadius = options.radius;
  40690. that._settings.innerRadius = options.radius - context.barSize;
  40691. that._background.attr(_extend({}, that._settings, {
  40692. startAngle: context.endAngle,
  40693. endAngle: context.startAngle
  40694. }));
  40695. that._bar.attr(that._settings);
  40696. that._tracker.attr(that._settings);
  40697. that._color = options.color;
  40698. that._bar.attr({fill: options.color});
  40699. if (context.textEnabled) {
  40700. that._line.attr({
  40701. points: [context.x, context.y - that._settings.innerRadius, context.x, context.y - context.textRadius],
  40702. stroke: context.lineColor || options.color
  40703. }).sharp();
  40704. that._text.css({fill: context.textColor || options.color})
  40705. }
  40706. return that
  40707. },
  40708. getTooltipParameters: function() {
  40709. var that = this,
  40710. cossin = _getCosAndSin((that._angle + that._context.baseAngle) / 2);
  40711. return {
  40712. x: _round(that._context.x + (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.cos),
  40713. y: _round(that._context.y - (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.sin),
  40714. offset: 0,
  40715. color: that._color,
  40716. value: that._value
  40717. }
  40718. },
  40719. setAngle: function(angle) {
  40720. var that = this,
  40721. cossin;
  40722. that._angle = angle;
  40723. setAngles(that._settings, that._context.baseAngle, that._angle);
  40724. that._bar.attr(that._settings);
  40725. that._tracker.attr(that._settings);
  40726. if (that._context.textEnabled) {
  40727. that._line.rotate(_convertAngleToRendererSpace(that._angle), that._context.x, that._context.y);
  40728. cossin = _getCosAndSin(that._angle);
  40729. that._text.attr({
  40730. text: _formatValue(that._value, that._context.formatOptions, {index: that._index}),
  40731. x: that._context.x + (that._context.textRadius + that._context.textWidth * 0.6) * cossin.cos,
  40732. y: that._context.y - (that._context.textRadius + that._context.textHeight * 0.6) * cossin.sin + that._context.textVerticalOffset
  40733. })
  40734. }
  40735. return that
  40736. },
  40737. _processValue: function(value) {
  40738. this._value = this._context.translator.adjust(value);
  40739. return this._context.translator.translate(this._value)
  40740. },
  40741. setValue: function(value) {
  40742. return this.setAngle(this._processValue(value))
  40743. },
  40744. beginAnimation: function(value) {
  40745. var that = this,
  40746. angle = this._processValue(value);
  40747. if (!compareFloats(that._angle, angle)) {
  40748. that._start = that._angle;
  40749. that._delta = angle - that._angle;
  40750. that._tracker.attr({visibility: "hidden"});
  40751. if (that._context.textEnabled) {
  40752. that._line.attr({visibility: "hidden"});
  40753. that._text.attr({visibility: "hidden"})
  40754. }
  40755. }
  40756. else {
  40757. that.animate = _noop;
  40758. that.setAngle(that._angle)
  40759. }
  40760. },
  40761. animate: function(pos) {
  40762. var that = this;
  40763. that._angle = that._start + that._delta * pos;
  40764. setAngles(that._settings, that._context.baseAngle, that._angle);
  40765. that._bar.attr(that._settings)
  40766. },
  40767. endAnimation: function() {
  40768. var that = this;
  40769. if (that._delta !== undefined) {
  40770. if (compareFloats(that._angle, that._start + that._delta)) {
  40771. that._tracker.attr({visibility: null});
  40772. if (that._context.textEnabled) {
  40773. that._line.attr({visibility: null});
  40774. that._text.attr({visibility: null})
  40775. }
  40776. that.setAngle(that._angle)
  40777. }
  40778. }
  40779. else
  40780. delete that.animate;
  40781. delete that._start;
  40782. delete that._delta
  40783. }
  40784. });
  40785. function setAngles(target, angle1, angle2) {
  40786. target.startAngle = angle1 < angle2 ? angle1 : angle2;
  40787. target.endAngle = angle1 < angle2 ? angle2 : angle1
  40788. }
  40789. function compareFloats(value1, value2) {
  40790. return _abs(value1 - value2) < 0.0001
  40791. }
  40792. function compareArrays(array1, array2) {
  40793. if (array1 === array2)
  40794. return true;
  40795. if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
  40796. for (var i = 0, ii = array1.length; i < ii; ++i)
  40797. if (!compareFloats(array1[i], array2[i]))
  40798. return false;
  40799. return true
  40800. }
  40801. return false
  40802. }
  40803. var __BarWrapper = BarWrapper;
  40804. DX.viz.gauges.__tests.BarWrapper = __BarWrapper;
  40805. DX.viz.gauges.__tests.stubBarWrapper = function(barWrapperType) {
  40806. BarWrapper = barWrapperType
  40807. };
  40808. DX.viz.gauges.__tests.restoreBarWrapper = function() {
  40809. BarWrapper = __BarWrapper
  40810. }
  40811. })(DevExpress, jQuery);
  40812. /*! Module viz-gauges, file tracker.js */
  40813. (function(DX, $, undefined) {
  40814. var _abs = Math.abs,
  40815. TOOLTIP_SHOW_DELAY = 300,
  40816. TOOLTIP_HIDE_DELAY = 300,
  40817. TOOLTIP_TOUCH_SHOW_DELAY = 400,
  40818. TOOLTIP_TOUCH_HIDE_DELAY = 300;
  40819. DX.viz.gauges.__internals.Tracker = DX.Class.inherit({
  40820. ctor: function(parameters) {
  40821. DX.utils.debug.assertParam(parameters, 'parameters');
  40822. DX.utils.debug.assertParam(parameters.renderer, 'parameters.renderer');
  40823. DX.utils.debug.assertParam(parameters.container, 'parameters.container');
  40824. var that = this;
  40825. that._container = parameters.container;
  40826. that._element = parameters.renderer.g().attr({
  40827. 'class': 'dxg-tracker',
  40828. stroke: 'none',
  40829. "stroke-width": 0,
  40830. fill: '#000000',
  40831. opacity: 0.0001
  40832. });
  40833. that._showTooltipCallback = function() {
  40834. that._showTooltipTimeout = null;
  40835. var target = that._tooltipEvent.target,
  40836. data = $(target).data();
  40837. that._targetEvent = null;
  40838. if (that._tooltipTarget !== target && that._callbacks['tooltip-show'](data.target, data.info))
  40839. that._tooltipTarget = target
  40840. };
  40841. that._hideTooltipCallback = function() {
  40842. that._hideTooltipTimeout = null;
  40843. that._targetEvent = null;
  40844. if (that._tooltipTarget) {
  40845. that._callbacks['tooltip-hide']();
  40846. that._tooltipTarget = null
  40847. }
  40848. };
  40849. that._dispose = function() {
  40850. clearTimeout(that._showTooltipTimeout);
  40851. clearTimeout(that._hideTooltipTimeout);
  40852. that._showTooltipCallback = that._hideTooltipCallback = that._dispose = null
  40853. };
  40854. that._DEBUG_showTooltipTimeoutSet = that._DEBUG_showTooltipTimeoutCleared = that._DEBUG_hideTooltipTimeoutSet = that._DEBUG_hideTooltipTimeoutCleared = 0;
  40855. that.TOOLTIP_SHOW_DELAY = TOOLTIP_SHOW_DELAY;
  40856. that.TOOLTIP_HIDE_DELAY = TOOLTIP_HIDE_DELAY;
  40857. that.TOOLTIP_TOUCH_SHOW_DELAY = TOOLTIP_TOUCH_SHOW_DELAY;
  40858. that.TOOLTIP_TOUCH_HIDE_DELAY = TOOLTIP_TOUCH_HIDE_DELAY
  40859. },
  40860. dispose: function() {
  40861. var that = this;
  40862. that._dispose();
  40863. that.deactivate();
  40864. that._element.remove();
  40865. that._container = that._element = that._context = that._callbacks = null;
  40866. return that
  40867. },
  40868. activate: function() {
  40869. this._element.append(this._container);
  40870. return this
  40871. },
  40872. deactivate: function() {
  40873. this._element.remove().clear();
  40874. return this
  40875. },
  40876. attach: function(element, target, info) {
  40877. element.data({
  40878. target: target,
  40879. info: info
  40880. }).append(this._element);
  40881. return this
  40882. },
  40883. detach: function(element) {
  40884. element.remove();
  40885. return this
  40886. },
  40887. setTooltipState: function(state) {
  40888. var that = this,
  40889. data;
  40890. that._element.off(tooltipMouseEvents).off(tooltipTouchEvents).off(tooltipMouseWheelEvents);
  40891. if (state) {
  40892. data = {tracker: that};
  40893. that._element.on(tooltipMouseEvents, data).on(tooltipTouchEvents, data).on(tooltipMouseWheelEvents, data)
  40894. }
  40895. return that
  40896. },
  40897. setCallbacks: function(callbacks) {
  40898. this._callbacks = callbacks;
  40899. return this
  40900. },
  40901. _showTooltip: function(event, delay) {
  40902. var that = this;
  40903. that._hideTooltipTimeout && ++that._DEBUG_hideTooltipTimeoutCleared;
  40904. clearTimeout(that._hideTooltipTimeout);
  40905. that._hideTooltipTimeout = null;
  40906. if (that._tooltipTarget === event.target)
  40907. return;
  40908. clearTimeout(that._showTooltipTimeout);
  40909. that._tooltipEvent = event;
  40910. ++that._DEBUG_showTooltipTimeoutSet;
  40911. that._showTooltipTimeout = setTimeout(that._showTooltipCallback, delay)
  40912. },
  40913. _hideTooltip: function(delay) {
  40914. var that = this;
  40915. that._showTooltipTimeout && ++that._DEBUG_showTooltipTimeoutCleared;
  40916. clearTimeout(that._showTooltipTimeout);
  40917. that._showTooltipTimeout = null;
  40918. clearTimeout(that._hideTooltipTimeout);
  40919. if (delay) {
  40920. ++that._DEBUG_hideTooltipTimeoutSet;
  40921. that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)
  40922. }
  40923. else
  40924. that._hideTooltipCallback()
  40925. }
  40926. });
  40927. var tooltipMouseEvents = {
  40928. 'mouseover.gauge-tooltip': handleTooltipMouseOver,
  40929. 'mouseout.gauge-tooltip': handleTooltipMouseOut
  40930. };
  40931. var tooltipMouseMoveEvents = {'mousemove.gauge-tooltip': handleTooltipMouseMove};
  40932. var tooltipMouseWheelEvents = {'dxmousewheel.gauge-tooltip': handleTooltipMouseWheel};
  40933. var tooltipTouchEvents = {'touchstart.gauge-tooltip': handleTooltipTouchStart};
  40934. function handleTooltipMouseOver(event) {
  40935. var tracker = event.data.tracker;
  40936. tracker._x = event.pageX;
  40937. tracker._y = event.pageY;
  40938. tracker._element.off(tooltipMouseMoveEvents).on(tooltipMouseMoveEvents, event.data);
  40939. tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
  40940. }
  40941. function handleTooltipMouseMove(event) {
  40942. var tracker = event.data.tracker;
  40943. if (tracker._showTooltipTimeout && _abs(event.pageX - tracker._x) > 4 || _abs(event.pageY - tracker._y) > 4) {
  40944. tracker._x = event.pageX;
  40945. tracker._y = event.pageY;
  40946. tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
  40947. }
  40948. }
  40949. function handleTooltipMouseOut(event) {
  40950. var tracker = event.data.tracker;
  40951. tracker._element.off(tooltipMouseMoveEvents);
  40952. tracker._hideTooltip(TOOLTIP_HIDE_DELAY)
  40953. }
  40954. function handleTooltipMouseWheel(event) {
  40955. event.data.tracker._hideTooltip()
  40956. }
  40957. var active_touch_tooltip_tracker = null;
  40958. DX.viz.gauges.__internals.Tracker._DEBUG_reset = function() {
  40959. active_touch_tooltip_tracker = null
  40960. };
  40961. function handleTooltipTouchStart(event) {
  40962. event.preventDefault();
  40963. var tracker = active_touch_tooltip_tracker;
  40964. if (tracker && tracker !== event.data.tracker)
  40965. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  40966. tracker = active_touch_tooltip_tracker = event.data.tracker;
  40967. tracker._showTooltip(event, TOOLTIP_TOUCH_SHOW_DELAY);
  40968. tracker._touch = true
  40969. }
  40970. function handleTooltipDocumentTouchStart() {
  40971. var tracker = active_touch_tooltip_tracker;
  40972. if (tracker) {
  40973. if (!tracker._touch) {
  40974. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  40975. active_touch_tooltip_tracker = null
  40976. }
  40977. tracker._touch = null
  40978. }
  40979. }
  40980. function handleTooltipDocumentTouchEnd() {
  40981. var tracker = active_touch_tooltip_tracker;
  40982. if (tracker)
  40983. if (tracker._showTooltipTimeout) {
  40984. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  40985. active_touch_tooltip_tracker = null
  40986. }
  40987. }
  40988. $(window.document).on({
  40989. 'touchstart.gauge-tooltip': handleTooltipDocumentTouchStart,
  40990. 'touchend.gauge-tooltip': handleTooltipDocumentTouchEnd
  40991. })
  40992. })(DevExpress, jQuery);
  40993. DevExpress.MOD_VIZ_GAUGES = true
  40994. }
  40995. if (!DevExpress.MOD_VIZ_RANGESELECTOR) {
  40996. if (!DevExpress.MOD_VIZ_CORE)
  40997. throw Error('Required module is not referenced: viz-core');
  40998. /*! Module viz-rangeselector, file namespaces.js */
  40999. (function(DevExpress) {
  41000. DevExpress.viz.rangeSelector = {}
  41001. })(DevExpress);
  41002. /*! Module viz-rangeselector, file utils.js */
  41003. (function($, DX, undefined) {
  41004. var dxUtils = DX.utils;
  41005. var findLessOrEqualValueIndex = function(values, value) {
  41006. if (!values || values.length === 0)
  41007. return -1;
  41008. var minIndex = 0,
  41009. maxIndex = values.length - 1;
  41010. while (maxIndex - minIndex > 1) {
  41011. var index = minIndex + maxIndex >> 1;
  41012. if (values[index] > value)
  41013. maxIndex = index;
  41014. else
  41015. minIndex = index
  41016. }
  41017. return values[maxIndex] <= value ? maxIndex : minIndex
  41018. };
  41019. var findLessOrEqualValue = function(values, value) {
  41020. var index = findLessOrEqualValueIndex(values, value);
  41021. if (values && index >= 0 && index < values.length)
  41022. return values[index];
  41023. return value
  41024. };
  41025. var findNearValue = function(values, value) {
  41026. var index = findLessOrEqualValueIndex(values, value);
  41027. if (values && index >= 0 && index < values.length) {
  41028. if (index + 1 < values.length)
  41029. if (dxUtils.isDate(value)) {
  41030. if (values[index + 1].getTime() - value.getTime() < value.getTime() - values[index].getTime())
  41031. index++
  41032. }
  41033. else if (values[index + 1] - value < value - values[index])
  41034. index++;
  41035. return values[index]
  41036. }
  41037. return value
  41038. };
  41039. var findGreaterOrEqualValue = function(values, value) {
  41040. var index = findLessOrEqualValueIndex(values, value);
  41041. if (values && index >= 0 && index < values.length) {
  41042. if (values[index] < value && index + 1 < values.length)
  41043. index++;
  41044. return values[index]
  41045. }
  41046. return value
  41047. };
  41048. var getEventPageX = function(eventArgs) {
  41049. var result = 0;
  41050. if (eventArgs.pageX)
  41051. result = eventArgs.pageX;
  41052. else if (eventArgs.originalEvent && eventArgs.originalEvent.pageX)
  41053. result = eventArgs.originalEvent.pageX;
  41054. if (eventArgs.originalEvent && eventArgs.originalEvent.touches)
  41055. if (eventArgs.originalEvent.touches.length > 0)
  41056. result = eventArgs.originalEvent.touches[0].pageX;
  41057. else if (eventArgs.originalEvent.changedTouches.length > 0)
  41058. result = eventArgs.originalEvent.changedTouches[0].pageX;
  41059. return result
  41060. };
  41061. var truncateSelectedRange = function(value, scaleOptions) {
  41062. var isDiscrete = scaleOptions.type === 'discrete',
  41063. categories = isDiscrete ? scaleOptions._categoriesInfo.categories : undefined,
  41064. startValue = scaleOptions.startValue,
  41065. endValue = scaleOptions.endValue,
  41066. min,
  41067. max,
  41068. valueIndex;
  41069. if (isDiscrete) {
  41070. valueIndex = $.inArray(value, categories);
  41071. return valueIndex < 0 ? startValue : value
  41072. }
  41073. else
  41074. min = startValue > endValue ? endValue : startValue,
  41075. max = startValue > endValue ? startValue : endValue;
  41076. if (value < min)
  41077. value = min;
  41078. if (value > max)
  41079. value = max;
  41080. return value
  41081. };
  41082. DX.viz.rangeSelector.utils = {
  41083. findLessOrEqualValue: findLessOrEqualValue,
  41084. findNearValue: findNearValue,
  41085. findGreaterOrEqualValue: findGreaterOrEqualValue,
  41086. getEventPageX: getEventPageX,
  41087. truncateSelectedRange: truncateSelectedRange,
  41088. trackerSettings: {
  41089. fill: 'grey',
  41090. stroke: 'grey',
  41091. opacity: 0.0001
  41092. },
  41093. animationSettings: {duration: 250}
  41094. }
  41095. })(jQuery, DevExpress);
  41096. /*! Module viz-rangeselector, file baseVisualElementMethods.js */
  41097. (function(DX) {
  41098. DX.viz.rangeSelector.baseVisualElementMethods = {
  41099. init: function(renderer) {
  41100. this._renderer = renderer;
  41101. this._isDrawn = false
  41102. },
  41103. applyOptions: function(options) {
  41104. this._options = options || {};
  41105. this._applyOptions(this._options)
  41106. },
  41107. _applyOptions: function(){},
  41108. redraw: function(group) {
  41109. var that = this;
  41110. if (!that._isDrawn) {
  41111. that._isDrawn = that._draw(group || that._group) !== false;
  41112. if (group)
  41113. that._group = group
  41114. }
  41115. else
  41116. that._update(group || that._group)
  41117. },
  41118. isDrawn: function() {
  41119. return !!this._isDrawn
  41120. },
  41121. isInitialized: function() {
  41122. return !!this._options
  41123. },
  41124. _draw: function(){},
  41125. _update: function(group) {
  41126. group.clear();
  41127. this._draw(group)
  41128. }
  41129. }
  41130. })(DevExpress);
  41131. /*! Module viz-rangeselector, file rangeSelector.js */
  41132. (function($, DX, undefined) {
  41133. var rangeSelector = DX.viz.rangeSelector,
  41134. utils = DX.utils,
  41135. core = DX.viz.core,
  41136. patchFontOptions = core.utils.patchFontOptions,
  41137. ParseUtils = core.ParseUtils,
  41138. formatHelper = DX.formatHelper,
  41139. SCALE_TEXT_SPACING = 5,
  41140. HEIGHT_COMPACT_MODE = 24,
  41141. POINTER_SIZE = 4,
  41142. EMPTY_SLIDER_MARKER_TEXT = '. . .',
  41143. _isDefined = utils.isDefined,
  41144. _isNumber = utils.isNumber,
  41145. _isDate = utils.isDate,
  41146. _max = Math.max,
  41147. _ceil = Math.ceil,
  41148. START_VALUE = 'startValue',
  41149. END_VALUE = 'endValue',
  41150. DATETIME = 'datetime',
  41151. SELECTED_RANGE = 'selectedRange',
  41152. DISCRETE = 'discrete',
  41153. STRING = 'string',
  41154. SELECTED_RANGE_CHANGED = SELECTED_RANGE + 'Changed',
  41155. CONTAINER_BACKGROUND_COLOR = "containerBackgroundColor",
  41156. SLIDER_MARKER = "sliderMarker",
  41157. BACKGROUND = "background",
  41158. LOGARITHMIC = "logarithmic",
  41159. INVISIBLE_POS = -1000,
  41160. logarithmBase = 10;
  41161. rangeSelector.consts = {
  41162. emptySliderMarkerText: EMPTY_SLIDER_MARKER_TEXT,
  41163. pointerSize: POINTER_SIZE
  41164. };
  41165. rangeSelector.HEIGHT_COMPACT_MODE = HEIGHT_COMPACT_MODE;
  41166. rangeSelector.__getTextBBox = getTextBBox;
  41167. function cloneSelectedRange(arg) {
  41168. return {
  41169. startValue: arg.startValue,
  41170. endValue: arg.endValue
  41171. }
  41172. }
  41173. var formatValue = rangeSelector.formatValue = function(value, formatOptions) {
  41174. var formatObject = {
  41175. value: value,
  41176. valueText: formatHelper.format(value, formatOptions.format, formatOptions.precision)
  41177. };
  41178. return String(utils.isFunction(formatOptions.customizeText) ? formatOptions.customizeText.call(formatObject, formatObject) : formatObject.valueText)
  41179. };
  41180. var createRangeContainer = function(rangeContainerOptions) {
  41181. return rangeSelector.rangeSelectorFactory.createRangeContainer(rangeContainerOptions)
  41182. };
  41183. var createTranslator = function(range, canvas) {
  41184. return {
  41185. x: core.CoreFactory.createTranslator2D(range.arg, canvas, {direction: "horizontal"}),
  41186. y: core.CoreFactory.createTranslator2D(range.val, canvas)
  41187. }
  41188. };
  41189. var createTranslatorCanvas = function(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight) {
  41190. return {
  41191. left: rangeContainerCanvas.left,
  41192. top: rangeContainerCanvas.top,
  41193. right: sizeOptions.width - rangeContainerCanvas.width - rangeContainerCanvas.left,
  41194. bottom: sizeOptions.height - rangeContainerCanvas.height - rangeContainerCanvas.top + scaleLabelsAreaHeight,
  41195. width: sizeOptions.width,
  41196. height: sizeOptions.height
  41197. }
  41198. };
  41199. var calculateMarkerHeight = function(renderer, value, sliderMarkerOptions) {
  41200. var formattedText = value === undefined ? EMPTY_SLIDER_MARKER_TEXT : formatValue(value, sliderMarkerOptions),
  41201. textBBox = getTextBBox(renderer, formattedText, sliderMarkerOptions.font);
  41202. return _ceil(textBBox.height) + 2 * sliderMarkerOptions.paddingTopBottom + POINTER_SIZE
  41203. };
  41204. var calculateScaleLabelHalfWidth = function(renderer, value, scaleOptions) {
  41205. var formattedText = formatValue(value, scaleOptions.label),
  41206. textBBox = getTextBBox(renderer, formattedText, scaleOptions.label.font);
  41207. return _ceil(textBBox.width / 2)
  41208. };
  41209. var calculateRangeContainerCanvas = function(size, indents, scaleLabelsAreaHeight, isCompactMode) {
  41210. var canvas = {
  41211. left: size.left + indents.left,
  41212. top: size.top + indents.top,
  41213. width: size.width - size.left - size.right - indents.left - indents.right,
  41214. height: !isCompactMode ? size.height - size.top - size.bottom - indents.top : HEIGHT_COMPACT_MODE + scaleLabelsAreaHeight
  41215. };
  41216. if (canvas.width <= 0)
  41217. canvas.width = 1;
  41218. return canvas
  41219. };
  41220. var parseSliderMarkersPlaceholderSize = function(placeholderSize) {
  41221. var placeholderWidthLeft,
  41222. placeholderWidthRight,
  41223. placeholderHeight;
  41224. if (_isNumber(placeholderSize))
  41225. placeholderWidthLeft = placeholderWidthRight = placeholderHeight = placeholderSize;
  41226. else if (placeholderSize) {
  41227. if (_isNumber(placeholderSize.height))
  41228. placeholderHeight = placeholderSize.height;
  41229. if (_isNumber(placeholderSize.width))
  41230. placeholderWidthLeft = placeholderWidthRight = placeholderSize.width;
  41231. else if (placeholderSize.width) {
  41232. if (_isNumber(placeholderSize.width.left))
  41233. placeholderWidthLeft = placeholderSize.width.left;
  41234. if (_isNumber(placeholderSize.width.right))
  41235. placeholderWidthRight = placeholderSize.width.right
  41236. }
  41237. }
  41238. else
  41239. return null;
  41240. return {
  41241. widthLeft: placeholderWidthLeft,
  41242. widthRight: placeholderWidthRight,
  41243. height: placeholderHeight
  41244. }
  41245. };
  41246. var calculateIndents = function(renderer, size, scale, sliderMarkerOptions, indentOptions) {
  41247. var leftMarkerHeight,
  41248. leftScaleLabelWidth = 0,
  41249. rightScaleLabelWidth = 0,
  41250. rightMarkerHeight,
  41251. placeholderWidthLeft = 0,
  41252. placeholderWidthRight = 0,
  41253. placeholderHeight,
  41254. parsedPlaceholderSize;
  41255. indentOptions = indentOptions || {};
  41256. parsedPlaceholderSize = parseSliderMarkersPlaceholderSize(sliderMarkerOptions.placeholderSize);
  41257. if (parsedPlaceholderSize && indentOptions.left === undefined && indentOptions.right === undefined) {
  41258. placeholderWidthLeft = parsedPlaceholderSize.widthLeft;
  41259. placeholderWidthRight = parsedPlaceholderSize.widthRight
  41260. }
  41261. else {
  41262. placeholderWidthLeft = indentOptions.left;
  41263. placeholderWidthRight = indentOptions.right
  41264. }
  41265. if (parsedPlaceholderSize && sliderMarkerOptions.placeholderHeight === undefined)
  41266. placeholderHeight = parsedPlaceholderSize.height;
  41267. else
  41268. placeholderHeight = sliderMarkerOptions.placeholderHeight;
  41269. if (sliderMarkerOptions.visible) {
  41270. leftMarkerHeight = calculateMarkerHeight(renderer, scale.startValue, sliderMarkerOptions);
  41271. rightMarkerHeight = calculateMarkerHeight(renderer, scale.endValue, sliderMarkerOptions);
  41272. if (placeholderHeight === undefined)
  41273. placeholderHeight = _max(leftMarkerHeight, rightMarkerHeight)
  41274. }
  41275. if (scale.label.visible) {
  41276. leftScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.startValue, scale);
  41277. rightScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.endValue, scale)
  41278. }
  41279. placeholderWidthLeft = placeholderWidthLeft !== undefined ? placeholderWidthLeft : leftScaleLabelWidth;
  41280. placeholderWidthRight = (placeholderWidthRight !== undefined ? placeholderWidthRight : rightScaleLabelWidth) || 1;
  41281. return {
  41282. left: placeholderWidthLeft,
  41283. right: placeholderWidthRight,
  41284. top: placeholderHeight || 0,
  41285. bottom: 0
  41286. }
  41287. };
  41288. var calculateValueType = function(firstValue, secondValue) {
  41289. var typeFirstValue = $.type(firstValue),
  41290. typeSecondValue = $.type(secondValue),
  41291. validType = function(type) {
  41292. return typeFirstValue === type || typeSecondValue === type
  41293. };
  41294. return validType('date') ? DATETIME : validType('number') ? 'numeric' : validType(STRING) ? STRING : ''
  41295. };
  41296. var showScaleMarkers = function(scaleOptions) {
  41297. return scaleOptions.valueType === DATETIME && scaleOptions.marker.visible
  41298. };
  41299. var updateTranslatorRangeInterval = function(translatorRange, scaleOptions) {
  41300. var intervalX = scaleOptions.minorTickInterval || scaleOptions.majorTickInterval;
  41301. if (scaleOptions.valueType === "datetime")
  41302. intervalX = utils.dateToMilliseconds(intervalX);
  41303. translatorRange = translatorRange.arg.addRange({interval: intervalX})
  41304. };
  41305. var createRange = function(options) {
  41306. return new core.Range(options)
  41307. };
  41308. var checkLogarithmicOptions = function(options, defaultLogarithmBase, incidentOccured) {
  41309. var logarithmBase;
  41310. if (!options)
  41311. return;
  41312. logarithmBase = options.logarithmBase;
  41313. if (options.type === LOGARITHMIC && logarithmBase <= 0 || logarithmBase && !_isNumber(logarithmBase)) {
  41314. options.logarithmBase = defaultLogarithmBase;
  41315. incidentOccured('E2104')
  41316. }
  41317. else if (options.type !== LOGARITHMIC)
  41318. options.logarithmBase = undefined
  41319. };
  41320. var calculateScaleAreaHeight = function(renderer, scaleOptions, visibleMarkers) {
  41321. var textBBox,
  41322. value = "0",
  41323. formatObject = {
  41324. value: 0,
  41325. valueText: value
  41326. },
  41327. labelScaleOptions = scaleOptions.label,
  41328. markerScaleOPtions = scaleOptions.marker,
  41329. customizeText = labelScaleOptions.customizeText,
  41330. placeholderHeight = scaleOptions.placeholderHeight,
  41331. text = utils.isFunction(customizeText) ? customizeText.call(formatObject, formatObject) : value,
  41332. visibleLabels = labelScaleOptions.visible;
  41333. if (placeholderHeight)
  41334. return placeholderHeight;
  41335. else {
  41336. textBBox = getTextBBox(renderer, text, labelScaleOptions.font);
  41337. return (visibleLabels ? labelScaleOptions.topIndent + textBBox.height : 0) + (visibleMarkers ? markerScaleOPtions.topIndent + markerScaleOPtions.separatorHeight : 0)
  41338. }
  41339. };
  41340. var updateTickIntervals = function(scaleOptions, screenDelta, incidentOccured, stick, min, max) {
  41341. var categoriesInfo = scaleOptions._categoriesInfo,
  41342. tickManager = core.CoreFactory.createTickManager({
  41343. axisType: scaleOptions.type,
  41344. dataType: scaleOptions.valueType
  41345. }, {
  41346. min: min,
  41347. max: max,
  41348. screenDelta: screenDelta,
  41349. customTicks: categoriesInfo && categoriesInfo.categories
  41350. }, {
  41351. labelOptions: {},
  41352. boundCoef: 1,
  41353. minorTickInterval: scaleOptions.minorTickInterval,
  41354. tickInterval: scaleOptions.majorTickInterval,
  41355. incidentOccured: incidentOccured,
  41356. base: scaleOptions.logarithmBase,
  41357. showMinorTicks: true,
  41358. withMinorCorrection: true,
  41359. stick: stick !== false
  41360. });
  41361. tickManager.getTicks(true);
  41362. return {
  41363. majorTickInterval: tickManager.getTickInterval(),
  41364. minorTickInterval: tickManager.getMinorTickInterval(),
  41365. bounds: tickManager.getTickBounds()
  41366. }
  41367. };
  41368. var calculateTranslatorRange = function(seriesDataSource, scaleOptions) {
  41369. var minValue,
  41370. maxValue,
  41371. inverted = false,
  41372. isEqualDates,
  41373. startValue = scaleOptions.startValue,
  41374. endValue = scaleOptions.endValue,
  41375. categories,
  41376. categoriesInfo,
  41377. translatorRange = seriesDataSource ? seriesDataSource.getBoundRange() : {
  41378. arg: createRange(),
  41379. val: createRange({isValueRange: true})
  41380. },
  41381. rangeForCategories;
  41382. if (scaleOptions.type === DISCRETE) {
  41383. rangeForCategories = createRange({
  41384. categories: scaleOptions.categories || (!seriesDataSource && startValue && endValue ? [startValue, endValue] : undefined),
  41385. minVisible: startValue,
  41386. maxVisible: endValue
  41387. });
  41388. rangeForCategories.addRange(translatorRange.arg);
  41389. translatorRange.arg = rangeForCategories;
  41390. categories = rangeForCategories.categories || [];
  41391. scaleOptions._categoriesInfo = categoriesInfo = utils.getCategoriesInfo(categories, startValue || categories[0], endValue || categories[categories.length - 1])
  41392. }
  41393. if (_isDefined(startValue) && _isDefined(endValue)) {
  41394. inverted = scaleOptions.inverted = categoriesInfo ? categoriesInfo.inverted : startValue > endValue;
  41395. minValue = categoriesInfo ? categoriesInfo.start : inverted ? endValue : startValue;
  41396. maxValue = categoriesInfo ? categoriesInfo.end : inverted ? startValue : endValue
  41397. }
  41398. else if (_isDefined(startValue) || _isDefined(endValue)) {
  41399. minValue = startValue;
  41400. maxValue = endValue
  41401. }
  41402. else if (categoriesInfo) {
  41403. minValue = categoriesInfo.start;
  41404. maxValue = categoriesInfo.end
  41405. }
  41406. isEqualDates = _isDate(minValue) && _isDate(maxValue) && minValue.getTime() === maxValue.getTime();
  41407. if (minValue !== maxValue && !isEqualDates)
  41408. translatorRange.arg.addRange({
  41409. invert: inverted,
  41410. min: minValue,
  41411. max: maxValue,
  41412. minVisible: minValue,
  41413. maxVisible: maxValue,
  41414. dataType: scaleOptions.valueType
  41415. });
  41416. translatorRange.arg.addRange({
  41417. base: scaleOptions.logarithmBase,
  41418. axisType: scaleOptions.type
  41419. });
  41420. if (!translatorRange.arg.isDefined()) {
  41421. if (isEqualDates)
  41422. scaleOptions.valueType = 'numeric';
  41423. translatorRange.arg.setStubData(scaleOptions.valueType)
  41424. }
  41425. return translatorRange
  41426. };
  41427. var startEndNotDefined = function(start, end) {
  41428. return !_isDefined(start) || !_isDefined(end)
  41429. };
  41430. function getTextBBox(renderer, text, fontOptions) {
  41431. var textElement = renderer.text(text, INVISIBLE_POS, INVISIBLE_POS).css(patchFontOptions(fontOptions)).append(renderer.root);
  41432. var textBBox = textElement.getBBox();
  41433. textElement.remove();
  41434. return textBBox
  41435. }
  41436. function processValue(selectedRangeOptions, scaleOptions, entity, incidentOccured) {
  41437. var parsedValue,
  41438. value = selectedRangeOptions[entity],
  41439. parser = scaleOptions.parser || function() {
  41440. return null
  41441. },
  41442. resultValue = scaleOptions[entity];
  41443. if (_isDefined(value))
  41444. parsedValue = parser(value);
  41445. if (!_isDefined(parsedValue))
  41446. incidentOccured("E2203", [entity]);
  41447. else
  41448. resultValue = parsedValue;
  41449. return rangeSelector.utils.truncateSelectedRange(resultValue, scaleOptions)
  41450. }
  41451. DX.registerComponent("dxRangeSelector", rangeSelector, core.BaseWidget.inherit({
  41452. _eventsMap: $.extend({}, core.BaseWidget.prototype._eventsMap, {
  41453. onSelectedRangeChanged: {
  41454. name: SELECTED_RANGE_CHANGED,
  41455. deprecated: SELECTED_RANGE_CHANGED,
  41456. deprecatedContext: function() {
  41457. return null
  41458. },
  41459. deprecatedArgs: function(arg) {
  41460. return [cloneSelectedRange(arg)]
  41461. }
  41462. },
  41463. selectedRangeChanged: {newName: "onSelectedRangeChanged"}
  41464. }),
  41465. _setDeprecatedOptions: function() {
  41466. this.callBase();
  41467. $.extend(this._deprecatedOptions, {
  41468. selectedRangeChanged: {
  41469. since: "14.2",
  41470. message: "Use the 'onSelectedRangeChanged' option instead"
  41471. },
  41472. "sliderMarker.padding": {
  41473. since: "15.1",
  41474. message: "Use the 'paddingTopBottom' and 'paddingLeftRight' options instead"
  41475. },
  41476. "sliderMarker.placeholderSize": {
  41477. since: "15.1",
  41478. message: "Use the 'placeholderHeight' and 'indent' options instead"
  41479. }
  41480. })
  41481. },
  41482. _rootClassPrefix: "dxrs",
  41483. _rootClass: "dxrs-range-selector",
  41484. _dataSourceOptions: function() {
  41485. return {paginate: false}
  41486. },
  41487. _dataIsReady: function() {
  41488. return this._isDataSourceReady()
  41489. },
  41490. _initCore: function() {
  41491. var that = this;
  41492. that.rangeContainer = createRangeContainer(that._renderer);
  41493. that._reinitDataSource();
  41494. that._renderer.root.css({
  41495. "touch-action": "pan-y",
  41496. "-ms-touch-action": "pan-y"
  41497. })
  41498. },
  41499. _initTooltip: $.noop,
  41500. _setTooltipRendererOptions: $.noop,
  41501. _setTooltipOptions: $.noop,
  41502. _getDefaultSize: function() {
  41503. return {
  41504. width: 400,
  41505. height: 160
  41506. }
  41507. },
  41508. _handleLoadingIndicatorShown: $.noop,
  41509. _reinitDataSource: function() {
  41510. this._refreshDataSource()
  41511. },
  41512. _disposeCore: function() {
  41513. var that = this,
  41514. disposeObject = function(propName) {
  41515. that[propName] && that[propName].dispose(),
  41516. that[propName] = null
  41517. };
  41518. that.callBase();
  41519. disposeObject("renderer");
  41520. that.translators = null;
  41521. disposeObject("rangeContainer")
  41522. },
  41523. _createThemeManager: function() {
  41524. return rangeSelector.rangeSelectorFactory.createThemeManager()
  41525. },
  41526. _refresh: function() {
  41527. var that = this,
  41528. callBase = that.callBase;
  41529. that._endLoading(function() {
  41530. callBase.call(that)
  41531. })
  41532. },
  41533. _render: function(isResizing) {
  41534. var that = this,
  41535. currentAnimationEnabled,
  41536. renderer = that._renderer;
  41537. isResizing = isResizing || that.__isResizing;
  41538. that._applyOptions();
  41539. if (isResizing) {
  41540. currentAnimationEnabled = renderer.animationEnabled();
  41541. renderer.updateAnimationOptions({enabled: false});
  41542. that.rangeContainer.redraw();
  41543. renderer.updateAnimationOptions({enabled: currentAnimationEnabled})
  41544. }
  41545. else
  41546. that.rangeContainer.redraw();
  41547. !isResizing && (!that._dataSource || that._dataSource && that._dataSource.isLoaded()) && that.hideLoadingIndicator();
  41548. that._drawn();
  41549. that.__rendered && that.__rendered()
  41550. },
  41551. _optionChanged: function(args) {
  41552. var that = this,
  41553. name = args.name;
  41554. if (name === "dataSource")
  41555. that._reinitDataSource();
  41556. else if (name === SELECTED_RANGE)
  41557. that.setSelectedRange(that.option(SELECTED_RANGE));
  41558. else
  41559. that.callBase(args)
  41560. },
  41561. _applySize: $.noop,
  41562. _resize: function() {
  41563. this._render(true)
  41564. },
  41565. _dataSourceChangedHandler: function() {
  41566. var that = this;
  41567. that._endLoading(function() {
  41568. if (that._renderer.drawn)
  41569. that._render()
  41570. })
  41571. },
  41572. _applyOptions: function() {
  41573. var that = this,
  41574. rangeContainerCanvas,
  41575. seriesDataSource,
  41576. translatorRange,
  41577. scaleLabelsAreaHeight,
  41578. sizeOptions = that._canvas,
  41579. indents,
  41580. sliderMarkerOptions,
  41581. selectedRange,
  41582. chartOptions = that.option('chart'),
  41583. shutterOptions = that._getOption("shutter"),
  41584. background = that._getOption(BACKGROUND),
  41585. isCompactMode,
  41586. scaleOptions,
  41587. chartThemeManager;
  41588. that._isUpdating = true;
  41589. seriesDataSource = that._createSeriesDataSource(chartOptions);
  41590. isCompactMode = !(seriesDataSource && seriesDataSource.isShowChart() || background && background.image && background.image.url);
  41591. if (seriesDataSource) {
  41592. chartThemeManager = seriesDataSource.getThemeManager();
  41593. checkLogarithmicOptions(chartOptions && chartOptions.valueAxis, chartThemeManager.getOptions("valueAxis").logarithmBase, that._incidentOccured)
  41594. }
  41595. scaleOptions = that._scaleOptions = that._prepareScaleOptions(seriesDataSource);
  41596. translatorRange = calculateTranslatorRange(seriesDataSource, scaleOptions);
  41597. that._updateScaleOptions(seriesDataSource, translatorRange.arg, sizeOptions.width);
  41598. updateTranslatorRangeInterval(translatorRange, scaleOptions);
  41599. sliderMarkerOptions = that._prepareSliderMarkersOptions(sizeOptions.width);
  41600. selectedRange = that._initSelection();
  41601. indents = calculateIndents(that._renderer, sizeOptions, scaleOptions, sliderMarkerOptions, that.option("indent"));
  41602. scaleLabelsAreaHeight = calculateScaleAreaHeight(that._renderer, scaleOptions, showScaleMarkers(scaleOptions));
  41603. rangeContainerCanvas = calculateRangeContainerCanvas(sizeOptions, indents, scaleLabelsAreaHeight, isCompactMode);
  41604. that.translators = createTranslator(translatorRange, createTranslatorCanvas(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight));
  41605. scaleOptions.ticksInfo = that._getTicksInfo(rangeContainerCanvas.width);
  41606. that._testTicksInfo = scaleOptions.ticksInfo;
  41607. that._selectedRange = selectedRange;
  41608. if (seriesDataSource)
  41609. seriesDataSource.adjustSeriesDimensions(that.translators);
  41610. shutterOptions.color = shutterOptions.color || that._getOption(CONTAINER_BACKGROUND_COLOR, true);
  41611. that.rangeContainer.applyOptions({
  41612. canvas: rangeContainerCanvas,
  41613. isCompactMode: isCompactMode,
  41614. scaleLabelsAreaHeight: scaleLabelsAreaHeight,
  41615. indents: indents,
  41616. translators: that.translators,
  41617. selectedRange: selectedRange,
  41618. scale: scaleOptions,
  41619. behavior: that._getOption('behavior'),
  41620. background: background,
  41621. chart: chartOptions,
  41622. seriesDataSource: seriesDataSource,
  41623. sliderMarker: sliderMarkerOptions,
  41624. sliderHandle: that._getOption('sliderHandle'),
  41625. shutter: shutterOptions,
  41626. selectedRangeColor: that._getOption("selectedRangeColor", true),
  41627. selectedRangeChanged: function(selectedRange, blockSelectedRangeChanged) {
  41628. that.option(SELECTED_RANGE, selectedRange);
  41629. if (!blockSelectedRangeChanged)
  41630. that._eventTrigger(SELECTED_RANGE_CHANGED, cloneSelectedRange(selectedRange))
  41631. },
  41632. setSelectedRange: function(selectedRange) {
  41633. that.setSelectedRange(selectedRange)
  41634. }
  41635. });
  41636. that._isUpdating = false;
  41637. chartThemeManager && chartThemeManager.dispose()
  41638. },
  41639. _initSelection: function() {
  41640. var that = this,
  41641. scaleOptions = that._scaleOptions,
  41642. selectedRangeOptions = that.option(SELECTED_RANGE),
  41643. incidentOccured = that._incidentOccured;
  41644. if (!selectedRangeOptions)
  41645. return cloneSelectedRange(scaleOptions);
  41646. else
  41647. return {
  41648. startValue: processValue(selectedRangeOptions, scaleOptions, START_VALUE, incidentOccured),
  41649. endValue: processValue(selectedRangeOptions, scaleOptions, END_VALUE, incidentOccured)
  41650. }
  41651. },
  41652. _createSeriesDataSource: function(chartOptions) {
  41653. var that = this,
  41654. seriesDataSource,
  41655. dataSource = that._dataSource && that._dataSource.items(),
  41656. scaleOptions = that._getOption('scale'),
  41657. valueType = scaleOptions.valueType,
  41658. backgroundOption = that.option(BACKGROUND);
  41659. if (!valueType)
  41660. valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue);
  41661. if (dataSource || chartOptions && chartOptions.series) {
  41662. chartOptions = $.extend({}, chartOptions, {theme: that.option("theme")});
  41663. seriesDataSource = new rangeSelector.SeriesDataSource({
  41664. renderer: that._renderer,
  41665. dataSource: dataSource,
  41666. valueType: (valueType || '').toLowerCase(),
  41667. axisType: scaleOptions.type,
  41668. chart: chartOptions,
  41669. dataSourceField: that.option('dataSourceField'),
  41670. backgroundColor: backgroundOption && backgroundOption.color,
  41671. incidentOccured: that._incidentOccured,
  41672. categories: scaleOptions.categories
  41673. })
  41674. }
  41675. return seriesDataSource
  41676. },
  41677. _prepareScaleOptions: function(seriesDataSource) {
  41678. var that = this,
  41679. scaleOptions = that._getOption('scale'),
  41680. parsedValue = 0,
  41681. parseUtils = new ParseUtils,
  41682. valueType = parseUtils.correctValueType((scaleOptions.valueType || '').toLowerCase()),
  41683. parser,
  41684. validateStartEndValues = function(field, parser) {
  41685. var messageToIncidentOccured = field === START_VALUE ? 'start' : 'end';
  41686. if (_isDefined(scaleOptions[field])) {
  41687. parsedValue = parser(scaleOptions[field]);
  41688. if (_isDefined(parsedValue))
  41689. scaleOptions[field] = parsedValue;
  41690. else {
  41691. scaleOptions[field] = undefined;
  41692. that._incidentOccured("E2202", [messageToIncidentOccured])
  41693. }
  41694. }
  41695. };
  41696. if (seriesDataSource)
  41697. valueType = seriesDataSource.getCalculatedValueType() || valueType;
  41698. if (!valueType)
  41699. valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue) || 'numeric';
  41700. if (valueType === STRING || scaleOptions.categories) {
  41701. scaleOptions.type = DISCRETE;
  41702. valueType = STRING
  41703. }
  41704. scaleOptions.valueType = valueType;
  41705. parser = parseUtils.getParser(valueType, 'scale');
  41706. validateStartEndValues(START_VALUE, parser);
  41707. validateStartEndValues(END_VALUE, parser);
  41708. checkLogarithmicOptions(scaleOptions, logarithmBase, that._incidentOccured);
  41709. if (!scaleOptions.type)
  41710. scaleOptions.type = 'continuous';
  41711. scaleOptions.parser = parser;
  41712. return scaleOptions
  41713. },
  41714. _prepareSliderMarkersOptions: function(screenDelta) {
  41715. var that = this,
  41716. scaleOptions = that._scaleOptions,
  41717. minorTickInterval = scaleOptions.minorTickInterval,
  41718. majorTickInterval = scaleOptions.majorTickInterval,
  41719. endValue = scaleOptions.endValue,
  41720. startValue = scaleOptions.startValue,
  41721. sliderMarkerOptions = that._getOption(SLIDER_MARKER),
  41722. businessInterval,
  41723. sliderMarkerUserOption = that.option(SLIDER_MARKER) || {};
  41724. sliderMarkerOptions.borderColor = that._getOption(CONTAINER_BACKGROUND_COLOR, true);
  41725. if (!sliderMarkerOptions.format) {
  41726. if (!that._getOption('behavior').snapToTicks && _isNumber(scaleOptions.startValue)) {
  41727. businessInterval = Math.abs(endValue - startValue);
  41728. sliderMarkerOptions.format = 'fixedPoint';
  41729. sliderMarkerOptions.precision = utils.getSignificantDigitPosition(businessInterval / screenDelta)
  41730. }
  41731. if (scaleOptions.valueType === DATETIME)
  41732. if (!scaleOptions.marker.visible) {
  41733. if (_isDefined(startValue) && _isDefined(endValue))
  41734. sliderMarkerOptions.format = formatHelper.getDateFormatByTickInterval(startValue, endValue, minorTickInterval !== 0 ? minorTickInterval : majorTickInterval)
  41735. }
  41736. else
  41737. sliderMarkerOptions.format = utils.getDateUnitInterval(_isDefined(minorTickInterval) && minorTickInterval !== 0 ? minorTickInterval : majorTickInterval)
  41738. }
  41739. if (sliderMarkerUserOption.padding !== undefined && sliderMarkerUserOption.paddingLeftRight === undefined && sliderMarkerUserOption.paddingTopBottom === undefined)
  41740. sliderMarkerOptions.paddingLeftRight = sliderMarkerOptions.paddingTopBottom = sliderMarkerUserOption.padding;
  41741. return sliderMarkerOptions
  41742. },
  41743. _updateScaleOptions: function(seriesDataSource, translatorRange, screenDelta) {
  41744. var scaleOptions = this._scaleOptions,
  41745. min = _isDefined(translatorRange.minVisible) ? translatorRange.minVisible : translatorRange.min,
  41746. max = _isDefined(translatorRange.maxVisible) ? translatorRange.maxVisible : translatorRange.max,
  41747. tickIntervalsInfo = updateTickIntervals(scaleOptions, screenDelta, this._incidentOccured, translatorRange.stick, min, max),
  41748. bounds,
  41749. isEmptyInterval,
  41750. categoriesInfo = scaleOptions._categoriesInfo;
  41751. if (seriesDataSource && !seriesDataSource.isEmpty() && !translatorRange.stubData) {
  41752. bounds = tickIntervalsInfo.bounds;
  41753. translatorRange.addRange(bounds);
  41754. scaleOptions.startValue = scaleOptions.inverted ? bounds.maxVisible : bounds.minVisible;
  41755. scaleOptions.endValue = scaleOptions.inverted ? bounds.minVisible : bounds.maxVisible
  41756. }
  41757. if (categoriesInfo) {
  41758. scaleOptions.startValue = categoriesInfo.start;
  41759. scaleOptions.endValue = categoriesInfo.end
  41760. }
  41761. isEmptyInterval = _isDate(scaleOptions.startValue) && _isDate(scaleOptions.endValue) && scaleOptions.startValue.getTime() === scaleOptions.endValue.getTime() || scaleOptions.startValue === scaleOptions.endValue;
  41762. scaleOptions.isEmpty = startEndNotDefined(scaleOptions.startValue, scaleOptions.endValue) || isEmptyInterval;
  41763. if (scaleOptions.isEmpty)
  41764. scaleOptions.startValue = scaleOptions.endValue = undefined;
  41765. else {
  41766. scaleOptions.minorTickInterval = tickIntervalsInfo.minorTickInterval;
  41767. scaleOptions.majorTickInterval = tickIntervalsInfo.majorTickInterval;
  41768. if (scaleOptions.valueType === DATETIME && !_isDefined(scaleOptions.label.format))
  41769. if (!scaleOptions.marker.visible)
  41770. scaleOptions.label.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.majorTickInterval);
  41771. else
  41772. scaleOptions.label.format = utils.getDateUnitInterval(scaleOptions.majorTickInterval)
  41773. }
  41774. },
  41775. _getStubTicks: function(scaleOptions) {
  41776. scaleOptions.isEmpty = true;
  41777. return ["canvas_position_left", "canvas_position_center", "canvas_position_right"]
  41778. },
  41779. _getTickManagerOptions: function(scaleOptions, isEmpty, startValue, endValue) {
  41780. var that = this;
  41781. return {
  41782. labelOptions: {},
  41783. minorTickInterval: isEmpty ? 0 : that._getOption('scale').minorTickInterval,
  41784. tickInterval: scaleOptions.majorTickInterval,
  41785. addMinMax: scaleOptions.showCustomBoundaryTicks ? {
  41786. min: true,
  41787. max: true
  41788. } : undefined,
  41789. minorTickCount: scaleOptions.minorTickCount,
  41790. textOptions: {
  41791. align: 'center',
  41792. font: scaleOptions.label.font
  41793. },
  41794. textFontStyles: patchFontOptions(scaleOptions.label.font),
  41795. incidentOccured: that._incidentOccured,
  41796. isHorizontal: true,
  41797. renderText: function(text, x, y, options) {
  41798. return that._renderer.text(text, x, y, options).append(that._renderer.root)
  41799. },
  41800. getText: startEndNotDefined(startValue, endValue) ? function(value) {
  41801. return value
  41802. } : function(value) {
  41803. return formatValue(value, scaleOptions.label)
  41804. },
  41805. translate: function(value) {
  41806. return that.translators.x.translate(value)
  41807. },
  41808. textSpacing: SCALE_TEXT_SPACING,
  41809. setTicksAtUnitBeginning: scaleOptions.setTicksAtUnitBeginning,
  41810. useTicksAutoArrangement: scaleOptions.useTicksAutoArrangement,
  41811. base: scaleOptions.logarithmBase,
  41812. stick: true,
  41813. showMinorTicks: true,
  41814. withMinorCorrection: true
  41815. }
  41816. },
  41817. _getTicksInfo: function(screenDelta) {
  41818. var that = this,
  41819. scaleOptions = that._scaleOptions,
  41820. translators = that.translators,
  41821. isEmpty = scaleOptions.isEmpty,
  41822. businessRange = translators.x.getBusinessRange(),
  41823. categoriesInfo = scaleOptions._categoriesInfo,
  41824. tickManagerTypes = {
  41825. axisType: scaleOptions.type,
  41826. dataType: scaleOptions.valueType
  41827. },
  41828. tickManagerData,
  41829. startValue = scaleOptions.startValue,
  41830. endValue = scaleOptions.endValue,
  41831. tickManagerOptions = that._getTickManagerOptions(scaleOptions, isEmpty, startValue, endValue),
  41832. majorTicks,
  41833. customBoundaryTicks,
  41834. tickManager,
  41835. fullTicks,
  41836. noInfoFromMinMax;
  41837. tickManagerData = {
  41838. min: isEmpty ? businessRange.min : startValue,
  41839. max: isEmpty ? businessRange.max : endValue,
  41840. screenDelta: screenDelta,
  41841. customTicks: categoriesInfo && categoriesInfo.categories
  41842. };
  41843. tickManager = core.CoreFactory.createTickManager(tickManagerTypes, tickManagerData, tickManagerOptions);
  41844. if (scaleOptions.type === DISCRETE)
  41845. noInfoFromMinMax = !_isDefined(tickManagerData.min) || !_isDefined(tickManagerData.max);
  41846. else
  41847. noInfoFromMinMax = !_isDefined(tickManagerData.min) && !_isDefined(tickManagerData.max);
  41848. majorTicks = noInfoFromMinMax && !_isDefined(tickManagerData.customTicks) ? that._getStubTicks(scaleOptions) : tickManager.getTicks(true);
  41849. customBoundaryTicks = tickManager.getBoundaryTicks();
  41850. fullTicks = tickManager.getFullTicks();
  41851. if (customBoundaryTicks.length) {
  41852. if (majorTicks[0].valueOf() === customBoundaryTicks[0].valueOf())
  41853. majorTicks.splice(0, 1);
  41854. if (majorTicks[majorTicks.length - 1].valueOf() === customBoundaryTicks[customBoundaryTicks.length - 1].valueOf())
  41855. majorTicks.pop()
  41856. }
  41857. return {
  41858. majorTicks: majorTicks,
  41859. minorTicks: tickManager.getMinorTicks(),
  41860. majorTickInterval: tickManager.getTickInterval(),
  41861. fullTicks: fullTicks,
  41862. customBoundaryTicks: customBoundaryTicks
  41863. }
  41864. },
  41865. getSelectedRange: function() {
  41866. return cloneSelectedRange(this.rangeContainer.slidersContainer.getSelectedRange())
  41867. },
  41868. setSelectedRange: function(selectedRange) {
  41869. var that = this;
  41870. if (that._isUpdating || !selectedRange)
  41871. return;
  41872. var oldSelectedRange = that.rangeContainer.slidersContainer.getSelectedRange();
  41873. if (oldSelectedRange && oldSelectedRange.startValue === selectedRange.startValue && oldSelectedRange.endValue === selectedRange.endValue)
  41874. return;
  41875. that.rangeContainer.slidersContainer.setSelectedRange(selectedRange)
  41876. },
  41877. resetSelectedRange: function(blockSelectedRangeChanged) {
  41878. var data = cloneSelectedRange(this._scaleOptions);
  41879. data.blockSelectedRangeChanged = blockSelectedRangeChanged;
  41880. this.setSelectedRange(data)
  41881. },
  41882. render: function(isResizing) {
  41883. var that = this;
  41884. that.__isResizing = isResizing;
  41885. that.callBase.apply(that, arguments);
  41886. that.__isResizing = null;
  41887. return that
  41888. }
  41889. }).include(DX.ui.DataHelperMixin))
  41890. })(jQuery, DevExpress);
  41891. /*! Module viz-rangeselector, file rangeContainer.js */
  41892. (function($, DX, undefined) {
  41893. var rangeSelector = DX.viz.rangeSelector,
  41894. baseVisualElementMethods = rangeSelector.baseVisualElementMethods,
  41895. RangeContainer;
  41896. var createSlidersContainer = function(options) {
  41897. return rangeSelector.rangeSelectorFactory.createSlidersContainer(options)
  41898. };
  41899. var createScale = function(options) {
  41900. return rangeSelector.rangeSelectorFactory.createScale(options)
  41901. };
  41902. var createRangeView = function(options) {
  41903. return rangeSelector.rangeSelectorFactory.createRangeView(options)
  41904. };
  41905. var _createClipRectCanvas = function(canvas, indents) {
  41906. return {
  41907. left: canvas.left - indents.left,
  41908. top: canvas.top - indents.top,
  41909. width: canvas.width + indents.right + indents.left,
  41910. height: canvas.height + indents.bottom + indents.top
  41911. }
  41912. };
  41913. function canvasOptionsToRenderOptions(canvasOptions) {
  41914. return {
  41915. x: canvasOptions.left,
  41916. y: canvasOptions.top,
  41917. width: canvasOptions.width,
  41918. height: canvasOptions.height
  41919. }
  41920. }
  41921. RangeContainer = function(renderer) {
  41922. baseVisualElementMethods.init.apply(this, arguments);
  41923. this.slidersContainer = createSlidersContainer(renderer);
  41924. this.rangeView = createRangeView(renderer);
  41925. this.scale = createScale(renderer)
  41926. };
  41927. RangeContainer.prototype = $.extend({}, baseVisualElementMethods, {
  41928. constructor: RangeContainer,
  41929. dispose: function() {
  41930. this.slidersContainer.dispose();
  41931. this.slidersContainer = null
  41932. },
  41933. _applyOptions: function(options) {
  41934. var that = this,
  41935. scaleLabelsAreaHeight = options.scaleLabelsAreaHeight,
  41936. canvas = options.canvas,
  41937. isCompactMode = options.isCompactMode,
  41938. viewCanvas = {
  41939. left: canvas.left,
  41940. top: canvas.top,
  41941. width: canvas.width,
  41942. height: canvas.height >= scaleLabelsAreaHeight ? canvas.height - scaleLabelsAreaHeight : 0
  41943. };
  41944. that._viewCanvas = viewCanvas;
  41945. that.slidersContainer.applyOptions({
  41946. isCompactMode: isCompactMode,
  41947. canvas: viewCanvas,
  41948. selectedRangeColor: options.selectedRangeColor,
  41949. translator: options.translators.x,
  41950. scale: options.scale,
  41951. selectedRange: options.selectedRange,
  41952. sliderMarker: options.sliderMarker,
  41953. sliderHandle: options.sliderHandle,
  41954. shutter: options.shutter,
  41955. behavior: options.behavior,
  41956. selectedRangeChanged: options.selectedRangeChanged
  41957. });
  41958. that.rangeView.applyOptions({
  41959. isCompactMode: isCompactMode,
  41960. canvas: viewCanvas,
  41961. translators: options.translators,
  41962. background: options.background,
  41963. chart: options.chart,
  41964. seriesDataSource: options.seriesDataSource,
  41965. behavior: options.behavior,
  41966. isEmpty: options.scale.isEmpty
  41967. });
  41968. that.scale.applyOptions({
  41969. isCompactMode: isCompactMode,
  41970. canvas: canvas,
  41971. translator: options.translators.x,
  41972. scale: options.scale,
  41973. scaleLabelsAreaHeight: scaleLabelsAreaHeight,
  41974. setSelectedRange: options.setSelectedRange
  41975. })
  41976. },
  41977. _draw: function() {
  41978. var that = this,
  41979. containerGroup,
  41980. rangeViewGroup,
  41981. slidersContainerGroup,
  41982. scaleGroup,
  41983. trackersGroup,
  41984. options = that._options,
  41985. clipRectCanvas = _createClipRectCanvas(options.canvas, options.indents),
  41986. viewCanvas = that._viewCanvas,
  41987. renderer = that._renderer,
  41988. slidersContainer = that.slidersContainer;
  41989. that._clipRect = renderer.clipRect(clipRectCanvas.left, clipRectCanvas.top, clipRectCanvas.width, clipRectCanvas.height);
  41990. that._viewClipRect = renderer.clipRect(viewCanvas.left, viewCanvas.top, viewCanvas.width, viewCanvas.height);
  41991. containerGroup = renderer.g().attr({
  41992. 'class': 'rangeContainer',
  41993. clipId: that._clipRect.id
  41994. }).append(renderer.root);
  41995. rangeViewGroup = renderer.g().attr({
  41996. 'class': 'view',
  41997. clipId: that._viewClipRect.id
  41998. });
  41999. that._slidersGroup = slidersContainerGroup = renderer.g().attr({'class': 'slidersContainer'});
  42000. scaleGroup = renderer.g().attr({'class': 'scale'});
  42001. trackersGroup = renderer.g().attr({'class': 'trackers'});
  42002. rangeViewGroup.append(containerGroup);
  42003. if (!options.isCompactMode) {
  42004. slidersContainerGroup.append(containerGroup);
  42005. scaleGroup.append(containerGroup)
  42006. }
  42007. else {
  42008. scaleGroup.append(containerGroup);
  42009. slidersContainerGroup.append(containerGroup)
  42010. }
  42011. trackersGroup.append(containerGroup);
  42012. that.rangeView.redraw(rangeViewGroup);
  42013. slidersContainer.redraw(slidersContainerGroup);
  42014. that.scale.redraw(scaleGroup);
  42015. that._trackersGroup = trackersGroup;
  42016. slidersContainer.appendTrackers(trackersGroup)
  42017. },
  42018. _update: function() {
  42019. var that = this,
  42020. options = that._options,
  42021. slidersContainer = that.slidersContainer;
  42022. that._clipRect.attr(canvasOptionsToRenderOptions(_createClipRectCanvas(options.canvas, options.indents)));
  42023. that._viewClipRect.attr(canvasOptionsToRenderOptions(that._viewCanvas));
  42024. that.rangeView.redraw();
  42025. slidersContainer.redraw(that._slidersGroup);
  42026. slidersContainer.appendTrackers(that._trackersGroup);
  42027. that.scale.redraw()
  42028. },
  42029. createSlidersContainer: createSlidersContainer,
  42030. createScale: createScale
  42031. });
  42032. rangeSelector.RangeContainer = RangeContainer
  42033. })(jQuery, DevExpress);
  42034. /*! Module viz-rangeselector, file scale.js */
  42035. (function($, DX, undefined) {
  42036. var viz = DX.viz,
  42037. rangeSelector = viz.rangeSelector,
  42038. formatHelper = DX.formatHelper,
  42039. rangeSelectorUtils = rangeSelector.utils,
  42040. utils = DX.utils,
  42041. _isDefined = utils.isDefined,
  42042. HALF_TICK_LENGTH = 6,
  42043. MINOR_TICK_OPACITY_COEF = 0.6,
  42044. Scale,
  42045. baseVisualElementMethods = rangeSelector.baseVisualElementMethods,
  42046. _extend = $.extend;
  42047. function calculateRangeByMarkerPosition(posX, markerDatePositions, scaleOptions) {
  42048. var selectedRange = {},
  42049. position,
  42050. i;
  42051. for (i = 0; i < markerDatePositions.length; i++) {
  42052. position = markerDatePositions[i];
  42053. if (!scaleOptions.inverted) {
  42054. if (posX >= position.posX)
  42055. selectedRange.startValue = position.date;
  42056. else if (!selectedRange.endValue)
  42057. selectedRange.endValue = position.date
  42058. }
  42059. else if (posX < position.posX)
  42060. selectedRange.endValue = position.date;
  42061. else if (!selectedRange.startValue)
  42062. selectedRange.startValue = position.date
  42063. }
  42064. selectedRange.startValue = selectedRange.startValue || scaleOptions.startValue;
  42065. selectedRange.endValue = selectedRange.endValue || scaleOptions.endValue;
  42066. return selectedRange
  42067. }
  42068. var dateSetters = {};
  42069. dateSetters.millisecond = function(date) {
  42070. date.setMilliseconds(0)
  42071. };
  42072. dateSetters.second = function(date) {
  42073. date.setSeconds(0, 0)
  42074. };
  42075. dateSetters.minute = function(date) {
  42076. date.setMinutes(0, 0, 0)
  42077. };
  42078. dateSetters.hour = function(date) {
  42079. date.setHours(0, 0, 0, 0)
  42080. };
  42081. dateSetters.week = dateSetters.day = function(date) {
  42082. date.setDate(1);
  42083. dateSetters.hour(date)
  42084. };
  42085. dateSetters.month = function(date) {
  42086. date.setMonth(0);
  42087. dateSetters.day(date)
  42088. };
  42089. dateSetters.quarter = function(date) {
  42090. date.setMonth(formatHelper.getFirstQuarterMonth(date.getMonth()));
  42091. dateSetters.day(date)
  42092. };
  42093. function getMarkerDate(date, tickInterval) {
  42094. var markerDate = new Date(date.getTime()),
  42095. setter = dateSetters[tickInterval];
  42096. setter && setter(markerDate);
  42097. return markerDate
  42098. }
  42099. function prepareDatesDifferences(datesDifferences, tickInterval) {
  42100. var deleteDifferent = tickInterval,
  42101. dateUnitInterval,
  42102. i;
  42103. if (deleteDifferent === 'week')
  42104. deleteDifferent = 'day';
  42105. if (deleteDifferent === 'quarter')
  42106. deleteDifferent = 'month';
  42107. if (datesDifferences[deleteDifferent])
  42108. for (i = 0; i < utils.dateUnitIntervals.length; i++) {
  42109. dateUnitInterval = utils.dateUnitIntervals[i];
  42110. if (datesDifferences[dateUnitInterval]) {
  42111. datesDifferences[dateUnitInterval] = false;
  42112. datesDifferences.count--
  42113. }
  42114. if (dateUnitInterval === deleteDifferent)
  42115. break
  42116. }
  42117. }
  42118. function getLabel(value, options) {
  42119. var formatObject = {
  42120. value: value,
  42121. valueText: formatHelper.format(value, options.format, options.precision)
  42122. };
  42123. return String(utils.isFunction(options.customizeText) ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText)
  42124. }
  42125. Scale = function() {
  42126. baseVisualElementMethods.init.apply(this, arguments)
  42127. };
  42128. Scale.prototype = _extend({}, baseVisualElementMethods, {
  42129. constructor: Scale,
  42130. _setupDateUnitInterval: function(scaleOptions) {
  42131. var key,
  42132. millisecTickInterval,
  42133. majorTickInterval = scaleOptions.ticksInfo.majorTickInterval,
  42134. majorTicks = scaleOptions.ticksInfo.majorTicks;
  42135. if (scaleOptions.valueType === 'datetime') {
  42136. if (majorTicks && majorTicks.autoArrangementStep > 1) {
  42137. if (utils.isString(majorTickInterval))
  42138. majorTickInterval = utils.getDateIntervalByString(majorTickInterval);
  42139. for (key in majorTickInterval)
  42140. if (majorTickInterval.hasOwnProperty(key)) {
  42141. majorTickInterval[key] *= majorTicks.autoArrangementStep;
  42142. millisecTickInterval = utils.dateToMilliseconds(majorTickInterval)
  42143. }
  42144. majorTickInterval = utils.convertMillisecondsToDateUnits(millisecTickInterval)
  42145. }
  42146. this.dateUnitInterval = utils.getDateUnitInterval(majorTickInterval)
  42147. }
  42148. },
  42149. _getDrawnDateMarker: function(date, options) {
  42150. var that = this,
  42151. labelPosX,
  42152. labelPosY,
  42153. scaleOptions = that._options.scale,
  42154. textElement,
  42155. textElementWidth,
  42156. textIndent,
  42157. pathElement;
  42158. if (options.x === null)
  42159. return;
  42160. that.textOptions.align = "left";
  42161. pathElement = that._renderer.path([options.x, options.y, options.x, options.y + scaleOptions.marker.separatorHeight], "line").attr(that._majorTickStyle).append(options.group);
  42162. textElement = that._renderer.text(getLabel(date, options.label), 0, 0).attr(that.textOptions).css(that.fontOptions).append(options.group);
  42163. textElementWidth = textElement.getBBox().width;
  42164. textIndent = scaleOptions.tick.width + scaleOptions.marker.textLeftIndent;
  42165. labelPosX = scaleOptions.inverted ? options.x - textIndent - textElementWidth : options.x + textIndent;
  42166. labelPosY = options.y + scaleOptions.marker.textTopIndent + that.fontOptions["font-size"];
  42167. textElement.move(labelPosX, labelPosY);
  42168. return {
  42169. x1: labelPosX,
  42170. x2: labelPosX + textElementWidth,
  42171. path: pathElement,
  42172. text: textElement
  42173. }
  42174. },
  42175. _deleteDrawnDateMarker: function(marker) {
  42176. marker.path.dispose();
  42177. marker.path = null;
  42178. marker.text.dispose();
  42179. marker.text = null
  42180. },
  42181. _drawDateMarkers: function(dates, group) {
  42182. var that = this,
  42183. i,
  42184. options = that._options,
  42185. datesLength = dates.length,
  42186. datesDifferences,
  42187. markerDate,
  42188. posX,
  42189. markerDatePositions = [],
  42190. prevDateMarker,
  42191. dateMarker;
  42192. if (options.scale.valueType !== 'datetime' || !that.visibleMarkers)
  42193. return;
  42194. if (dates.length > 1) {
  42195. for (i = 1; i < datesLength; i++) {
  42196. datesDifferences = utils.getDatesDifferences(dates[i - 1], dates[i]);
  42197. prepareDatesDifferences(datesDifferences, that.dateUnitInterval);
  42198. if (datesDifferences.count > 0) {
  42199. markerDate = getMarkerDate(dates[i], that.dateUnitInterval);
  42200. that.markerDates = that.markerDates || [];
  42201. that.markerDates.push(markerDate);
  42202. posX = that.translator.translate(markerDate);
  42203. dateMarker = that._getDrawnDateMarker(markerDate, {
  42204. group: group,
  42205. y: options.canvas.top + options.canvas.height - that.markersAreaHeight + options.scale.marker.topIndent,
  42206. x: posX,
  42207. label: that._getLabelFormatOptions(formatHelper.getDateFormatByDifferences(datesDifferences))
  42208. });
  42209. if (prevDateMarker === undefined || dateMarker.x1 > prevDateMarker.x2 || dateMarker.x2 < prevDateMarker.x1) {
  42210. posX !== null && markerDatePositions.push({
  42211. date: markerDate,
  42212. posX: posX
  42213. });
  42214. prevDateMarker = dateMarker
  42215. }
  42216. else
  42217. that._deleteDrawnDateMarker(dateMarker)
  42218. }
  42219. }
  42220. that._initializeMarkersEvents(markerDatePositions, group)
  42221. }
  42222. },
  42223. _getLabelFormatOptions: function(formatString) {
  42224. if (!_isDefined(this._options.scale.marker.label.format))
  42225. return _extend({}, this._options.scale.marker.label, {format: formatString});
  42226. return this._options.scale.marker.label
  42227. },
  42228. _initializeMarkersEvents: function(markerDatePositions, group) {
  42229. var that = this,
  42230. options = that._options,
  42231. markersAreaTop = options.canvas.top + options.canvas.height - this.markersAreaHeight + options.scale.marker.topIndent,
  42232. markersTracker,
  42233. svgOffsetLeft,
  42234. posX,
  42235. selectedRange;
  42236. if (markerDatePositions.length > 0) {
  42237. markersTracker = that._renderer.rect(options.canvas.left, markersAreaTop, options.canvas.width, options.scale.marker.separatorHeight).attr(rangeSelectorUtils.trackerSettings).append(group);
  42238. markersTracker.on(rangeSelector.events.start, function(e) {
  42239. svgOffsetLeft = that._renderer.getRootOffset().left;
  42240. posX = rangeSelectorUtils.getEventPageX(e) - svgOffsetLeft;
  42241. selectedRange = calculateRangeByMarkerPosition(posX, markerDatePositions, options.scale);
  42242. options.setSelectedRange(selectedRange)
  42243. });
  42244. that._markersTracker = markersTracker
  42245. }
  42246. },
  42247. _drawLabel: function(text, group) {
  42248. var that = this,
  42249. options = that._options,
  42250. canvas = options.canvas,
  42251. textY = canvas.top + canvas.height - that.markersAreaHeight,
  42252. textElements = that._renderer.text(getLabel(text, options.scale.label), that.translator.translate(text), textY).attr(that.textOptions).css(that.fontOptions).append(group);
  42253. that.textElements = that.textElements || [];
  42254. that.textElements.push(textElements)
  42255. },
  42256. _drawTicks: function(ticks, group, directionOffset, coords, style, labelsGroup) {
  42257. var that = this,
  42258. i,
  42259. posX,
  42260. tickElement;
  42261. for (i = 0; i < ticks.length; i++) {
  42262. if (labelsGroup)
  42263. that._drawLabel(ticks[i], labelsGroup);
  42264. posX = that.translator.translate(ticks[i], directionOffset);
  42265. tickElement = that._createLine([posX, coords[0], posX, coords[1]], group, style);
  42266. that.tickElements = that.tickElements || [];
  42267. that.tickElements.push(tickElement)
  42268. }
  42269. },
  42270. _createLine: function(points, group, options) {
  42271. return this._renderer.path(points, "line").attr(options).append(group)
  42272. },
  42273. _redraw: function(group) {
  42274. var that = this,
  42275. options = that._options,
  42276. scaleOptions = options.scale,
  42277. renderer = that._renderer,
  42278. labelsGroup = renderer.g().append(group),
  42279. ticksGroup = renderer.g(),
  42280. ticksInfo = scaleOptions.ticksInfo,
  42281. majorTicks = ticksInfo.majorTicks,
  42282. minorTicks = ticksInfo.minorTicks,
  42283. customBoundaryTicks = ticksInfo.customBoundaryTicks,
  42284. hideLabels = scaleOptions.isEmpty || !scaleOptions.label.visible,
  42285. isDiscrete = scaleOptions.type === "discrete",
  42286. directionOffset = isDiscrete ? -1 : 0,
  42287. isCompactMode = options.isCompactMode,
  42288. canvas = options.canvas,
  42289. bottom = canvas.top + canvas.height - that.scaleLabelsAreaHeight,
  42290. center = canvas.top + (bottom - canvas.top) / 2,
  42291. coords = isCompactMode ? [center - HALF_TICK_LENGTH, center + HALF_TICK_LENGTH] : [canvas.top, bottom],
  42292. categoriesInfo = scaleOptions._categoriesInfo,
  42293. majorTickStyle = that._majorTickStyle;
  42294. that._drawTicks(majorTicks, ticksGroup, directionOffset, coords, majorTickStyle, !hideLabels && labelsGroup);
  42295. if (scaleOptions.showMinorTicks || isDiscrete)
  42296. that._drawTicks(minorTicks, ticksGroup, directionOffset, coords, that._minorTickStyle);
  42297. that._drawTicks(customBoundaryTicks, ticksGroup, 0, coords, majorTickStyle);
  42298. isDiscrete && categoriesInfo && _isDefined(categoriesInfo.end) && that._drawTicks([categoriesInfo.end], ticksGroup, 1, coords, majorTickStyle);
  42299. if (isCompactMode)
  42300. that._createLine([canvas.left, center, canvas.width + canvas.left, center], group, _extend({}, majorTickStyle, {sharp: "v"}));
  42301. ticksGroup.append(group);
  42302. that._drawDateMarkers(majorTicks, labelsGroup)
  42303. },
  42304. _applyOptions: function(options) {
  42305. var that = this,
  42306. scaleOptions = options.scale,
  42307. labelsAreaHeight,
  42308. tick = scaleOptions.tick;
  42309. that.textOptions = {align: 'center'};
  42310. that.fontOptions = viz.core.utils.patchFontOptions(scaleOptions.label.font);
  42311. that._majorTickStyle = {
  42312. "stroke-width": tick.width,
  42313. stroke: tick.color,
  42314. "stroke-opacity": tick.opacity,
  42315. sharp: "h"
  42316. };
  42317. that._minorTickStyle = _extend({}, that._majorTickStyle, {"stroke-opacity": tick.opacity * MINOR_TICK_OPACITY_COEF});
  42318. that._setupDateUnitInterval(scaleOptions);
  42319. that.visibleMarkers = scaleOptions.marker.visible === undefined ? true : scaleOptions.marker.visible;
  42320. labelsAreaHeight = scaleOptions.label.visible ? scaleOptions.label.topIndent + that.fontOptions["font-size"] : 0;
  42321. that.scaleLabelsAreaHeight = options.scaleLabelsAreaHeight;
  42322. that.markersAreaHeight = that.scaleLabelsAreaHeight - labelsAreaHeight;
  42323. that.translator = options.translator
  42324. },
  42325. _draw: function(group) {
  42326. this._redraw(group)
  42327. },
  42328. _update: function() {
  42329. if (this._markersTracker)
  42330. this._markersTracker.off(rangeSelector.events.start, '**');
  42331. baseVisualElementMethods._update.apply(this, arguments)
  42332. }
  42333. });
  42334. Scale.prototype._calculateRangeByMarkerPosition = calculateRangeByMarkerPosition;
  42335. Scale.prototype._prepareDatesDifferences = prepareDatesDifferences;
  42336. rangeSelector.Scale = Scale
  42337. })(jQuery, DevExpress);
  42338. /*! Module viz-rangeselector, file rangeFactory.js */
  42339. (function($, DX, undefined) {
  42340. var rangeSelector = DX.viz.rangeSelector;
  42341. rangeSelector.rangeSelectorFactory = function() {
  42342. return {
  42343. createRangeContainer: function(rangeContainerOptions) {
  42344. return new rangeSelector.RangeContainer(rangeContainerOptions)
  42345. },
  42346. createSlidersContainer: function(options) {
  42347. return new rangeSelector.SlidersContainer(options)
  42348. },
  42349. createScale: function(options) {
  42350. return new rangeSelector.Scale(options)
  42351. },
  42352. createSliderMarker: function(options) {
  42353. return new rangeSelector.SliderMarker(options)
  42354. },
  42355. createRangeView: function(options) {
  42356. return new rangeSelector.RangeView(options)
  42357. },
  42358. createThemeManager: function(options) {
  42359. return new rangeSelector.ThemeManager(options)
  42360. },
  42361. createSlider: function(renderer, sliderIndex) {
  42362. return new rangeSelector.Slider(renderer, sliderIndex)
  42363. },
  42364. createSlidersEventsManager: function(renderer, slidersController, processSelectionChanged) {
  42365. return new rangeSelector.SlidersEventsManager(renderer, slidersController, processSelectionChanged)
  42366. },
  42367. createSlidersController: function(sliders) {
  42368. return new rangeSelector.SlidersController(sliders)
  42369. }
  42370. }
  42371. }()
  42372. })(jQuery, DevExpress);
  42373. /*! Module viz-rangeselector, file slidersContainer.js */
  42374. (function($, DX, undefined) {
  42375. var rangeSelector = DX.viz.rangeSelector,
  42376. utils = DX.utils,
  42377. msPointerEnabled = DX.support.pointer,
  42378. isNumber = utils.isNumber,
  42379. isDate = utils.isDate,
  42380. isString = utils.isString,
  42381. rangeSelectorUtils = rangeSelector.utils,
  42382. baseVisualElementMethods = rangeSelector.baseVisualElementMethods,
  42383. rangeSelectorFactory = rangeSelector.rangeSelectorFactory,
  42384. trackerAttributes = rangeSelectorUtils.trackerSettings;
  42385. function SlidersContainer() {
  42386. var that = this;
  42387. baseVisualElementMethods.init.apply(that, arguments);
  42388. that._controller = rangeSelectorFactory.createSlidersController(that._renderer);
  42389. that._eventsManager = rangeSelectorFactory.createSlidersEventsManager(that._renderer, that._controller, function(moving) {
  42390. that._processSelectionChanged(moving)
  42391. });
  42392. that._lastSelectedRange = {}
  42393. }
  42394. SlidersContainer.prototype = $.extend({}, baseVisualElementMethods, {
  42395. constructor: SlidersContainer,
  42396. _drawAreaTracker: function(group) {
  42397. var that = this,
  42398. areaTracker,
  42399. selectedAreaTracker,
  42400. canvas = that._options.canvas,
  42401. renderer = that._renderer;
  42402. areaTracker = renderer.rect(canvas.left, canvas.top, canvas.width, canvas.height).attr(trackerAttributes).append(group);
  42403. selectedAreaTracker = renderer.rect(canvas.left, canvas.top, canvas.width, canvas.height).attr(trackerAttributes).css({cursor: 'pointer'}).append(group);
  42404. that._controller.setAreaTrackers(areaTracker, selectedAreaTracker)
  42405. },
  42406. dispose: function() {
  42407. this._eventsManager.dispose();
  42408. this._controller.dispose();
  42409. this._eventManager = null
  42410. },
  42411. _processSelectionChanged: function(moving, blockSelectedRangeChanged) {
  42412. var that = this,
  42413. equalLastSelectedRange = function(selectedRange) {
  42414. return selectedRange && that._lastSelectedRange.startValue === selectedRange.startValue && that._lastSelectedRange.endValue === selectedRange.endValue
  42415. },
  42416. selectedRange = that.getSelectedRange();
  42417. if ((!moving || (that._options.behavior.callSelectedRangeChanged || '').toLowerCase() === "onmoving") && that._options.selectedRangeChanged && !equalLastSelectedRange(selectedRange)) {
  42418. that._updateLastSelectedRange(selectedRange);
  42419. if (utils.isFunction(that._options.selectedRangeChanged))
  42420. that._options.selectedRangeChanged.call(null, selectedRange, blockSelectedRangeChanged);
  42421. if (!moving && !equalLastSelectedRange(selectedRange))
  42422. that.setSelectedRange(selectedRange)
  42423. }
  42424. },
  42425. _updateLastSelectedRange: function(selectedRange) {
  42426. selectedRange = selectedRange || this._options.selectedRange;
  42427. this._lastSelectedRange = {
  42428. startValue: selectedRange.startValue,
  42429. endValue: selectedRange.endValue
  42430. }
  42431. },
  42432. getSelectedRange: function() {
  42433. return this._controller.getSelectedRange()
  42434. },
  42435. setSelectedRange: function(selectedRange) {
  42436. var that = this,
  42437. scale = that._options.scale,
  42438. startValue,
  42439. endValue,
  42440. currentSelectedRange = that._options.selectedRange,
  42441. checkTypes = function(valueName, value) {
  42442. var valueFromScale = scale[valueName];
  42443. if (isNumber(valueFromScale) && isNumber(value) || isDate(valueFromScale) && isDate(value) || isString(valueFromScale) && isString(value))
  42444. currentSelectedRange[valueName] = value
  42445. };
  42446. if (selectedRange) {
  42447. startValue = selectedRange.startValue;
  42448. endValue = selectedRange.endValue
  42449. }
  42450. checkTypes('startValue', startValue);
  42451. checkTypes('endValue', endValue);
  42452. currentSelectedRange.startValue = rangeSelectorUtils.truncateSelectedRange(currentSelectedRange.startValue, scale);
  42453. currentSelectedRange.endValue = rangeSelectorUtils.truncateSelectedRange(currentSelectedRange.endValue, scale);
  42454. that._controller.applySelectedRange(currentSelectedRange);
  42455. that._controller.applyPosition();
  42456. that._processSelectionChanged(false, selectedRange && selectedRange.blockSelectedRangeChanged)
  42457. },
  42458. appendTrackers: function(group) {
  42459. this._controller.appendTrackers(group)
  42460. },
  42461. _applyOptions: function(options) {
  42462. var that = this;
  42463. that._controller.applyOptions({
  42464. isCompactMode: options.isCompactMode,
  42465. translator: options.translator,
  42466. canvas: options.canvas,
  42467. sliderMarker: options.sliderMarker,
  42468. sliderHandle: options.sliderHandle,
  42469. shutter: options.shutter,
  42470. scale: options.scale,
  42471. behavior: options.behavior
  42472. });
  42473. that._eventsManager.applyOptions({behavior: options.behavior})
  42474. },
  42475. _draw: function(group) {
  42476. var that = this,
  42477. rootElement;
  42478. if (msPointerEnabled) {
  42479. rootElement = that._renderer.root;
  42480. rootElement && rootElement.css({msTouchAction: "pinch-zoom"})
  42481. }
  42482. that._controller.redraw(group);
  42483. that._drawAreaTracker(group);
  42484. that._eventsManager.initialize();
  42485. that._update(group)
  42486. },
  42487. _updateSelectedView: function(group) {
  42488. var that = this,
  42489. options = that._options,
  42490. canvas = options.canvas,
  42491. lineOptions = {
  42492. "stroke-width": 3,
  42493. stroke: options.selectedRangeColor,
  42494. sharp: "v"
  42495. },
  42496. center = canvas.top + canvas.height / 2,
  42497. selectedView = that._selectedView,
  42498. selectedViewAppended = that._selectedViewAppended,
  42499. controller = that._controller;
  42500. if (!options.isCompactMode) {
  42501. if (selectedView && selectedViewAppended) {
  42502. selectedView.remove();
  42503. that._selectedViewAppended = false
  42504. }
  42505. controller.createShutters()
  42506. }
  42507. else {
  42508. if (!selectedView) {
  42509. that._selectedView = selectedView = that._renderer.path([canvas.left, center, canvas.left, center], "line").attr(lineOptions);
  42510. controller.setSelectedView(selectedView)
  42511. }
  42512. else
  42513. selectedView.attr(lineOptions);
  42514. if (!selectedViewAppended) {
  42515. selectedView.append(group);
  42516. controller.removeShutters();
  42517. that._selectedViewAppended = true
  42518. }
  42519. }
  42520. },
  42521. _update: function(group) {
  42522. var that = this,
  42523. isEmpty = that._options.scale.isEmpty,
  42524. controller = that._controller;
  42525. that._eventsManager.setEnabled(!isEmpty);
  42526. !isEmpty && that._updateSelectedView(group);
  42527. controller.applySelectedRange(isEmpty ? {} : that._options.selectedRange);
  42528. controller.applyPosition(that.isDrawn());
  42529. that._updateLastSelectedRange();
  42530. controller.redraw()
  42531. },
  42532. getController: function() {
  42533. return this._controller
  42534. }
  42535. });
  42536. rangeSelector.SlidersContainer = SlidersContainer
  42537. })(jQuery, DevExpress);
  42538. /*! Module viz-rangeselector, file slidersController.js */
  42539. (function($, DX, undefined) {
  42540. var rangeSelector = DX.viz.rangeSelector,
  42541. createSlider = rangeSelector.rangeSelectorFactory.createSlider,
  42542. utils = DX.utils,
  42543. rangeSelectorUtils = rangeSelector.utils,
  42544. _SliderController,
  42545. START_VALUE_INDEX = 0,
  42546. END_VALUE_INDEX = 1,
  42547. DISCRETE = 'discrete';
  42548. _SliderController = rangeSelector.SlidersController = function(renderer) {
  42549. var sliders = [createSlider(renderer, START_VALUE_INDEX), createSlider(renderer, END_VALUE_INDEX)];
  42550. sliders[START_VALUE_INDEX].setAnotherSlider(sliders[END_VALUE_INDEX]);
  42551. sliders[END_VALUE_INDEX].setAnotherSlider(sliders[START_VALUE_INDEX]);
  42552. this._sliders = sliders
  42553. };
  42554. _SliderController.prototype = {
  42555. constructor: _SliderController,
  42556. setAreaTrackers: function(areaTracker, selectedAreaTracker) {
  42557. this._areaTracker = areaTracker;
  42558. this._selectedAreaTracker = selectedAreaTracker
  42559. },
  42560. applyOptions: function(options) {
  42561. var that = this,
  42562. values = null,
  42563. startSlider = that.getSlider(START_VALUE_INDEX),
  42564. endSlider = that.getSlider(END_VALUE_INDEX),
  42565. scaleOptions = options.scale;
  42566. that._options = options;
  42567. startSlider.applyOptions(options);
  42568. endSlider.applyOptions(options);
  42569. if (options.behavior.snapToTicks && scaleOptions.type !== DISCRETE) {
  42570. values = scaleOptions.ticksInfo.fullTicks;
  42571. if (values.length > 1 && values[0] > values[values.length - 1])
  42572. values = values.reverse()
  42573. }
  42574. startSlider.setAvailableValues(values);
  42575. endSlider.setAvailableValues(values)
  42576. },
  42577. processDocking: function(sliderIndex) {
  42578. var that = this;
  42579. if (sliderIndex !== undefined)
  42580. that.getSlider(sliderIndex).processDocking();
  42581. else {
  42582. that.getSlider(START_VALUE_INDEX).processDocking();
  42583. that.getSlider(END_VALUE_INDEX).processDocking()
  42584. }
  42585. that.setTrackersCursorStyle('default');
  42586. that.applyAreaTrackersPosition();
  42587. that._applySelectedRangePosition()
  42588. },
  42589. _applySelectedRangePosition: function(disableAnimation) {
  42590. var that = this,
  42591. options = that._options,
  42592. canvas = options.canvas,
  42593. center = canvas.top + canvas.height / 2,
  42594. isAnimation = options.behavior.animationEnabled && !disableAnimation,
  42595. startSliderPos = that.getSlider(START_VALUE_INDEX).getPosition(),
  42596. interval = that.getSelectedRangeInterval(),
  42597. points = [startSliderPos, center, startSliderPos + interval, center],
  42598. selectedView = that._selectedView;
  42599. if (!selectedView || !options.isCompactMode)
  42600. return;
  42601. if (isAnimation)
  42602. selectedView.animate({points: points}, rangeSelectorUtils.animationSettings);
  42603. else
  42604. selectedView.stopAnimation().attr({points: points})
  42605. },
  42606. setSelectedView: function(selectedView) {
  42607. this._selectedView = selectedView
  42608. },
  42609. getSelectedRangeInterval: function() {
  42610. var that = this;
  42611. return that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition()
  42612. },
  42613. moveSliders: function(postitionDelta, selectedRangeInterval) {
  42614. var startSlider = this.getSlider(START_VALUE_INDEX);
  42615. startSlider.setPosition(startSlider.getPosition() + postitionDelta, false, selectedRangeInterval);
  42616. this.applyPosition(true)
  42617. },
  42618. moveSlider: function(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, startOffsetPositionChangedCallback) {
  42619. var that = this,
  42620. slider = that.getSlider(sliderIndex),
  42621. anotherSlider = slider.getAnotherSlider(),
  42622. anotherSliderPosition = anotherSlider.getPosition(),
  42623. doSwap;
  42624. if (slider.canSwap())
  42625. if (sliderIndex === START_VALUE_INDEX ? position > anotherSliderPosition : position < anotherSliderPosition) {
  42626. doSwap = fastSwap;
  42627. if (!fastSwap)
  42628. if (Math.abs(offsetPosition) >= Math.abs(startOffsetPosition)) {
  42629. doSwap = true;
  42630. if (offsetPosition * startOffsetPosition < 0) {
  42631. position += 2 * startOffsetPosition;
  42632. startOffsetPositionChangedCallback(-startOffsetPosition)
  42633. }
  42634. else {
  42635. position -= 2 * startOffsetPosition;
  42636. startOffsetPositionChangedCallback(startOffsetPosition)
  42637. }
  42638. }
  42639. if (doSwap) {
  42640. that.swapSliders();
  42641. anotherSlider.applyPosition(true)
  42642. }
  42643. }
  42644. slider.setPosition(position, true);
  42645. slider.applyPosition(true);
  42646. that.applyAreaTrackersPosition();
  42647. that._applySelectedRangePosition(true);
  42648. that.setTrackersCursorStyle('w-resize')
  42649. },
  42650. applySelectedAreaCenterPosition: function(pos) {
  42651. var that = this,
  42652. startSlider = that.getSlider(START_VALUE_INDEX),
  42653. slidersContainerHalfWidth = (that.getSlider(END_VALUE_INDEX).getPosition() - startSlider.getPosition()) / 2,
  42654. selectedRangeInterval = that.getSelectedRangeInterval();
  42655. startSlider.setPosition(pos - slidersContainerHalfWidth, false, selectedRangeInterval);
  42656. that.applyPosition();
  42657. that.processDocking()
  42658. },
  42659. endSelection: function() {
  42660. var startSlider = this.getSlider(START_VALUE_INDEX),
  42661. endSlider = this.getSlider(END_VALUE_INDEX),
  42662. cloudSpacing = startSlider.getCloudBorder() - endSlider.getCloudBorder(),
  42663. overlappedState;
  42664. if (cloudSpacing > 0)
  42665. overlappedState = true;
  42666. else
  42667. overlappedState = false;
  42668. startSlider.setOverlapped(overlappedState);
  42669. endSlider.setOverlapped(overlappedState)
  42670. },
  42671. processManualSelection: function(startPosition, endPosition, eventArgs) {
  42672. var that = this,
  42673. animateSliderIndex,
  42674. movingSliderIndex,
  42675. positionRange = [Math.min(startPosition, endPosition), Math.max(startPosition, endPosition)],
  42676. movingSlider,
  42677. animatedSlider;
  42678. animateSliderIndex = startPosition < endPosition ? START_VALUE_INDEX : END_VALUE_INDEX;
  42679. movingSliderIndex = startPosition < endPosition ? END_VALUE_INDEX : START_VALUE_INDEX;
  42680. movingSlider = that.getSlider(movingSliderIndex);
  42681. animatedSlider = that.getSlider(animateSliderIndex);
  42682. movingSlider.setPosition(positionRange[movingSliderIndex]);
  42683. animatedSlider.setPosition(positionRange[animateSliderIndex]);
  42684. movingSlider.setPosition(positionRange[movingSliderIndex], true);
  42685. movingSlider.startEventHandler(eventArgs);
  42686. animatedSlider.processDocking();
  42687. movingSlider.applyPosition(true)
  42688. },
  42689. applySelectedRange: function(selectedRange) {
  42690. utils.debug.assertParam(selectedRange, 'selectedRange not passed');
  42691. var that = this,
  42692. scaleoptions = that._options.scale,
  42693. inverted = scaleoptions.inverted,
  42694. startSlider = that.getSlider(START_VALUE_INDEX),
  42695. endSlider = that.getSlider(END_VALUE_INDEX),
  42696. startValue = selectedRange.startValue,
  42697. endValue = selectedRange.endValue,
  42698. categoriesInfo,
  42699. setValues = function(startValue, endValue, isInverted) {
  42700. (isInverted ? endSlider : startSlider).setValue(startValue);
  42701. (isInverted ? startSlider : endSlider).setValue(endValue)
  42702. };
  42703. if (scaleoptions.type !== DISCRETE)
  42704. if (!inverted && startValue > endValue || inverted && startValue < endValue)
  42705. setValues(startValue, endValue, true);
  42706. else
  42707. setValues(startValue, endValue);
  42708. else {
  42709. categoriesInfo = utils.getCategoriesInfo(scaleoptions._categoriesInfo.categories, startValue, endValue);
  42710. setValues(categoriesInfo.start, categoriesInfo.end, categoriesInfo.inverted ^ scaleoptions.inverted)
  42711. }
  42712. },
  42713. getSelectedRange: function() {
  42714. return {
  42715. startValue: this.getSlider(START_VALUE_INDEX).getValue(),
  42716. endValue: this.getSlider(END_VALUE_INDEX).getValue()
  42717. }
  42718. },
  42719. swapSliders: function() {
  42720. var that = this;
  42721. that._sliders.reverse();
  42722. that.getSlider(START_VALUE_INDEX).changeLocation();
  42723. that.getSlider(END_VALUE_INDEX).changeLocation()
  42724. },
  42725. applyAreaTrackersPosition: function() {
  42726. var that = this,
  42727. selectedRange = that.getSelectedRange(),
  42728. canvas = that._options.canvas,
  42729. scaleOptions = that._options.scale,
  42730. startSlider = that.getSlider(START_VALUE_INDEX),
  42731. width = that.getSlider(END_VALUE_INDEX).getPosition() - startSlider.getPosition(),
  42732. options = {
  42733. x: startSlider.getPosition(),
  42734. width: width < 0 ? 0 : width,
  42735. y: canvas.top,
  42736. height: canvas.height
  42737. },
  42738. style = {cursor: scaleOptions.endValue - scaleOptions.startValue === selectedRange.endValue - selectedRange.startValue ? 'default' : 'pointer'};
  42739. that._selectedAreaTracker.attr(options).css(style);
  42740. that._areaTracker.attr({
  42741. x: canvas.left,
  42742. width: canvas.width,
  42743. y: canvas.top,
  42744. height: canvas.height
  42745. })
  42746. },
  42747. applyPosition: function(disableAnimation) {
  42748. var that = this;
  42749. that.getSlider(START_VALUE_INDEX).applyPosition(disableAnimation);
  42750. that.getSlider(END_VALUE_INDEX).applyPosition(disableAnimation);
  42751. that.applyAreaTrackersPosition();
  42752. that._applySelectedRangePosition(disableAnimation)
  42753. },
  42754. redraw: function(group) {
  42755. var that = this;
  42756. that.getSlider(START_VALUE_INDEX).redraw(group);
  42757. that.getSlider(END_VALUE_INDEX).redraw(group);
  42758. that._foregroundSliderIndex = END_VALUE_INDEX
  42759. },
  42760. toForeground: function(slider) {
  42761. var that = this,
  42762. sliderIndex = slider.getIndex();
  42763. if (that._foregroundSliderIndex !== sliderIndex) {
  42764. slider.toForeground();
  42765. that._foregroundSliderIndex = sliderIndex
  42766. }
  42767. },
  42768. appendTrackers: function(group) {
  42769. var that = this;
  42770. if (that._areaTracker && that._selectedAreaTracker) {
  42771. that._areaTracker.append(group);
  42772. that._selectedAreaTracker.append(group)
  42773. }
  42774. that.getSlider(START_VALUE_INDEX).appendTrackers(group);
  42775. that.getSlider(END_VALUE_INDEX).appendTrackers(group)
  42776. },
  42777. getSlider: function(sliderIndex) {
  42778. return this._sliders[sliderIndex]
  42779. },
  42780. getAreaTracker: function() {
  42781. return this._areaTracker
  42782. },
  42783. getSelectedAreaTracker: function() {
  42784. return this._selectedAreaTracker
  42785. },
  42786. setTrackersCursorStyle: function(style) {
  42787. var that = this;
  42788. that._selectedAreaTracker.css({cursor: style});
  42789. that._areaTracker.css({cursor: style})
  42790. },
  42791. createShutters: function() {
  42792. var sliders = this._sliders;
  42793. sliders[0].createShutter();
  42794. sliders[1].createShutter()
  42795. },
  42796. removeShutters: function() {
  42797. var sliders = this._sliders;
  42798. sliders[0].removeShutter();
  42799. sliders[1].removeShutter()
  42800. },
  42801. dispose: function() {
  42802. var sliders = this._sliders;
  42803. sliders[0].dispose();
  42804. sliders[1].dispose()
  42805. }
  42806. }
  42807. })(jQuery, DevExpress);
  42808. /*! Module viz-rangeselector, file slidersEventsManager.js */
  42809. (function($, DX, undefined) {
  42810. var rangeSelector = DX.viz.rangeSelector,
  42811. MIN_MANUAL_SELECTING_WIDTH = 10,
  42812. START_VALUE_INDEX = 0,
  42813. END_VALUE_INDEX = 1,
  42814. addNamespace = DX.ui.events.addNamespace,
  42815. _SlidersEventManager,
  42816. rangeSelectorUtils = rangeSelector.utils,
  42817. getEventPageX = rangeSelectorUtils.getEventPageX,
  42818. rangeSelectorCount = 0;
  42819. rangeSelector.events = {
  42820. start: "dxpointerdown",
  42821. move: "dxpointermove",
  42822. end: "dxpointerup"
  42823. };
  42824. var isLeftButtonPressed = function(event) {
  42825. var e = event || window.event,
  42826. originalEvent = e.originalEvent,
  42827. touches = e.touches,
  42828. pointerType = originalEvent ? originalEvent.pointerType : false,
  42829. eventTouches = originalEvent ? originalEvent.touches : false,
  42830. isIE8LeftClick = e.which === undefined && e.button === 1,
  42831. isMSPointerLeftClick = originalEvent && pointerType !== undefined && (pointerType === (originalEvent.MSPOINTER_TYPE_TOUCH || 'touch') || pointerType === (originalEvent.MSPOINTER_TYPE_MOUSE || 'mouse') && originalEvent.buttons === 1),
  42832. isLeftClick = isIE8LeftClick || e.which === 1,
  42833. isTouches = touches && touches.length > 0 || eventTouches && eventTouches.length > 0;
  42834. return isLeftClick || isMSPointerLeftClick || isTouches
  42835. };
  42836. var isMultiTouches = function(event) {
  42837. var originalEvent = event.originalEvent,
  42838. touches = event.touches,
  42839. eventTouches = originalEvent ? originalEvent.touches : false;
  42840. return touches && touches.length > 1 || eventTouches && eventTouches.length > 1 || null
  42841. };
  42842. var isTouchEventArgs = function(e) {
  42843. return e && e.type && e.type.indexOf('touch') === 0
  42844. };
  42845. _SlidersEventManager = rangeSelector.SlidersEventsManager = function(renderer, slidersController, processSelectionChanged) {
  42846. var that = this,
  42847. uniqueNS = that._uniqueNS = 'dx-range-selector_' + rangeSelectorCount++,
  42848. rangeSelectorEvents = rangeSelector.events;
  42849. that._renderer = renderer;
  42850. that._slidersController = slidersController;
  42851. that._processSelectionChanged = processSelectionChanged;
  42852. that._enabled = true;
  42853. that._eventsNames = {
  42854. start: addNamespace(rangeSelectorEvents.start, uniqueNS),
  42855. move: addNamespace(rangeSelectorEvents.move, uniqueNS),
  42856. end: addNamespace(rangeSelectorEvents.end, uniqueNS)
  42857. }
  42858. };
  42859. _SlidersEventManager.prototype = {
  42860. constructor: _SlidersEventManager,
  42861. _initializeSliderEvents: function(sliderIndex) {
  42862. var that = this,
  42863. isTouchEvent,
  42864. slidersController = that._slidersController,
  42865. processSelectionChanged = that._processSelectionChanged,
  42866. slider = slidersController.getSlider(sliderIndex),
  42867. fastSwap,
  42868. startOffsetPosition,
  42869. splitterMoving,
  42870. sliderEndHandler = function() {
  42871. if (splitterMoving) {
  42872. splitterMoving = false;
  42873. slidersController.endSelection();
  42874. slidersController.processDocking();
  42875. processSelectionChanged(false)
  42876. }
  42877. },
  42878. sliderMoveHandler = function(e) {
  42879. var pageX,
  42880. offsetPosition,
  42881. svgOffsetLeft = that._renderer.getRootOffset().left,
  42882. position,
  42883. sliderIndex = slider.getIndex();
  42884. if (isTouchEvent !== isTouchEventArgs(e))
  42885. return;
  42886. if (!isLeftButtonPressed(e, true) && splitterMoving) {
  42887. splitterMoving = false;
  42888. slidersController.processDocking();
  42889. processSelectionChanged(false)
  42890. }
  42891. else if (splitterMoving) {
  42892. if (!isMultiTouches(e)) {
  42893. this.preventedDefault = true;
  42894. e.preventDefault()
  42895. }
  42896. pageX = getEventPageX(e);
  42897. position = pageX - startOffsetPosition - svgOffsetLeft;
  42898. offsetPosition = pageX - slider.getPosition() - svgOffsetLeft;
  42899. slidersController.moveSlider(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, function(newStartOffsetPosition) {
  42900. startOffsetPosition = newStartOffsetPosition
  42901. });
  42902. processSelectionChanged(true)
  42903. }
  42904. slidersController.endSelection()
  42905. },
  42906. eventsNames = that._eventsNames;
  42907. slider.startEventHandler = function(e) {
  42908. if (!that._enabled || !isLeftButtonPressed(e) || splitterMoving)
  42909. return;
  42910. fastSwap = this === slider.getSliderTracker().element;
  42911. splitterMoving = true;
  42912. isTouchEvent = isTouchEventArgs(e);
  42913. startOffsetPosition = getEventPageX(e) - slider.getPosition() - that._renderer.getRootOffset().left;
  42914. if (!isMultiTouches(e)) {
  42915. this.preventedDefault = true;
  42916. e.stopPropagation();
  42917. e.preventDefault()
  42918. }
  42919. };
  42920. slider.on(eventsNames.move, function() {
  42921. slidersController.toForeground(slider)
  42922. });
  42923. slider.on(eventsNames.start, slider.startEventHandler);
  42924. $(document).on(eventsNames.end, sliderEndHandler).on(eventsNames.move, sliderMoveHandler);
  42925. slider.__moveEventHandler = sliderMoveHandler
  42926. },
  42927. _initializeAreaEvents: function() {
  42928. var that = this,
  42929. isTouchEvent,
  42930. slidersController = that._slidersController,
  42931. processSelectionChanged = that._processSelectionChanged,
  42932. areaTracker = slidersController.getAreaTracker(),
  42933. unselectedAreaProcessing = false,
  42934. startPageX,
  42935. areaEndHandler = function(e) {
  42936. var pageX;
  42937. if (unselectedAreaProcessing) {
  42938. pageX = getEventPageX(e);
  42939. if (that._options.behavior.moveSelectedRangeByClick && Math.abs(startPageX - pageX) < MIN_MANUAL_SELECTING_WIDTH)
  42940. slidersController.applySelectedAreaCenterPosition(pageX - that._renderer.getRootOffset().left);
  42941. unselectedAreaProcessing = false;
  42942. slidersController.endSelection();
  42943. processSelectionChanged(false)
  42944. }
  42945. },
  42946. areaMoveHandler = function(e) {
  42947. var pageX,
  42948. startPosition,
  42949. endPosition,
  42950. svgOffsetLeft = that._renderer.getRootOffset().left;
  42951. if (isTouchEvent !== isTouchEventArgs(e))
  42952. return;
  42953. if (unselectedAreaProcessing && !isLeftButtonPressed(e)) {
  42954. unselectedAreaProcessing = false;
  42955. processSelectionChanged(false)
  42956. }
  42957. if (unselectedAreaProcessing) {
  42958. pageX = getEventPageX(e);
  42959. if (that._options.behavior.manualRangeSelectionEnabled && Math.abs(startPageX - pageX) >= MIN_MANUAL_SELECTING_WIDTH) {
  42960. startPosition = startPageX - svgOffsetLeft;
  42961. endPosition = pageX - svgOffsetLeft;
  42962. slidersController.processManualSelection(startPosition, endPosition, e);
  42963. unselectedAreaProcessing = false;
  42964. processSelectionChanged(true)
  42965. }
  42966. }
  42967. },
  42968. eventsNames = that._eventsNames;
  42969. areaTracker.on(eventsNames.start, function(e) {
  42970. if (!that._enabled || !isLeftButtonPressed(e) || unselectedAreaProcessing)
  42971. return;
  42972. unselectedAreaProcessing = true;
  42973. isTouchEvent = isTouchEventArgs(e);
  42974. startPageX = getEventPageX(e)
  42975. });
  42976. $(document).on(eventsNames.end, areaEndHandler).on(eventsNames.move, areaMoveHandler);
  42977. that.__areaMoveEventHandler = areaMoveHandler
  42978. },
  42979. _initializeSelectedAreaEvents: function() {
  42980. var that = this,
  42981. isTouchEvent,
  42982. slidersController = that._slidersController,
  42983. processSelectionChanged = that._processSelectionChanged,
  42984. selectedAreaTracker = slidersController.getSelectedAreaTracker(),
  42985. selectedAreaMoving = false,
  42986. offsetStartPosition,
  42987. selectedRangeInterval,
  42988. selectedAreaEndHandler = function() {
  42989. if (selectedAreaMoving) {
  42990. selectedAreaMoving = false;
  42991. slidersController.processDocking();
  42992. processSelectionChanged(false)
  42993. }
  42994. },
  42995. selectedAreaMoveHandler = function(e) {
  42996. var positionDelta,
  42997. pageX;
  42998. if (isTouchEvent !== isTouchEventArgs(e))
  42999. return;
  43000. if (selectedAreaMoving && !isLeftButtonPressed(e)) {
  43001. selectedAreaMoving = false;
  43002. slidersController.processDocking();
  43003. processSelectionChanged(false)
  43004. }
  43005. if (selectedAreaMoving) {
  43006. if (!isMultiTouches(e)) {
  43007. this.preventedDefault = true;
  43008. e.preventDefault()
  43009. }
  43010. pageX = getEventPageX(e);
  43011. positionDelta = pageX - slidersController.getSlider(START_VALUE_INDEX).getPosition() - offsetStartPosition;
  43012. slidersController.moveSliders(positionDelta, selectedRangeInterval);
  43013. processSelectionChanged(true)
  43014. }
  43015. slidersController.endSelection()
  43016. },
  43017. eventsNames = that._eventsNames;
  43018. selectedAreaTracker.on(eventsNames.start, function(e) {
  43019. if (!that._enabled || !isLeftButtonPressed(e) || selectedAreaMoving)
  43020. return;
  43021. selectedAreaMoving = true;
  43022. isTouchEvent = isTouchEventArgs(e);
  43023. offsetStartPosition = getEventPageX(e) - slidersController.getSlider(START_VALUE_INDEX).getPosition();
  43024. selectedRangeInterval = slidersController.getSelectedRangeInterval();
  43025. if (!isMultiTouches(e)) {
  43026. this.preventedDefault = true;
  43027. e.stopPropagation();
  43028. e.preventDefault()
  43029. }
  43030. });
  43031. $(document).on(eventsNames.end, selectedAreaEndHandler).on(eventsNames.move, selectedAreaMoveHandler);
  43032. that.__selectedAreaMoveEventHandler = selectedAreaMoveHandler
  43033. },
  43034. applyOptions: function(options) {
  43035. this._options = options
  43036. },
  43037. dispose: function() {
  43038. $(document).off('.' + this._uniqueNS)
  43039. },
  43040. initialize: function() {
  43041. var that = this;
  43042. that._initializeSelectedAreaEvents(that);
  43043. that._initializeAreaEvents();
  43044. that._initializeSliderEvents(START_VALUE_INDEX);
  43045. that._initializeSliderEvents(END_VALUE_INDEX)
  43046. },
  43047. setEnabled: function(enabled) {
  43048. this._enabled = enabled
  43049. }
  43050. }
  43051. })(jQuery, DevExpress);
  43052. /*! Module viz-rangeselector, file slider.js */
  43053. (function($, DX, undefined) {
  43054. var rangeSelector = DX.viz.rangeSelector,
  43055. utils = DX.utils,
  43056. rangeSelectorUtils = rangeSelector.utils,
  43057. _inArray = $.inArray,
  43058. dxSupport = DX.support,
  43059. touchSupport = dxSupport.touchEvents,
  43060. msPointerEnabled = dxSupport.pointer,
  43061. SPLITTER_WIDTH = 8,
  43062. TOUCH_SPLITTER_WIDTH = 20,
  43063. START_VALUE_INDEX = 0,
  43064. END_VALUE_INDEX = 1,
  43065. DISCRETE = 'discrete',
  43066. baseVisualElementMethods = rangeSelector.baseVisualElementMethods;
  43067. function checkItemsSpacing(firstSliderPosition, secondSliderPosition, distance) {
  43068. return Math.abs(secondSliderPosition - firstSliderPosition) < distance
  43069. }
  43070. function getValidCategories(categories, curValue, anotherSliderValue, offset) {
  43071. var curValueindex = _inArray(curValue, categories);
  43072. if (curValueindex === 0 || curValueindex === categories.length - 1)
  43073. return anotherSliderValue;
  43074. return categories[curValueindex - offset]
  43075. }
  43076. function Slider(renderer, index) {
  43077. baseVisualElementMethods.init.apply(this, arguments);
  43078. this._index = index
  43079. }
  43080. Slider.prototype = $.extend({}, baseVisualElementMethods, {
  43081. getText: function() {
  43082. if (this._marker)
  43083. return this._marker.getText()
  43084. },
  43085. getAvailableValues: function() {
  43086. return this._values
  43087. },
  43088. getShutter: function() {
  43089. return this._shutter
  43090. },
  43091. getMarker: function() {
  43092. return this._marker
  43093. },
  43094. constructor: Slider,
  43095. _createSlider: function(group) {
  43096. var that = this,
  43097. sliderHandle,
  43098. sliderGroup,
  43099. sliderHandleOptions = that._options.sliderHandle,
  43100. canvas = that._options.canvas,
  43101. renderer = that._renderer;
  43102. sliderGroup = renderer.g().attr({
  43103. 'class': 'slider',
  43104. translateX: canvas.left,
  43105. translateY: canvas.top
  43106. }).append(group);
  43107. sliderHandle = renderer.path([0, 0, 0, canvas.height], "line").attr({
  43108. "stroke-width": sliderHandleOptions.width,
  43109. stroke: sliderHandleOptions.color,
  43110. "stroke-opacity": sliderHandleOptions.opacity,
  43111. sharp: "h"
  43112. }).append(sliderGroup);
  43113. sliderGroup.setValid = function(correct) {
  43114. sliderHandle.attr({stroke: correct ? that._options.sliderHandle.color : that._options.sliderMarker.invalidRangeColor})
  43115. };
  43116. sliderGroup.updateHeight = function() {
  43117. sliderHandle.attr({points: [0, 0, 0, that._options.canvas.height]})
  43118. };
  43119. sliderGroup.applyOptions = function(options) {
  43120. sliderHandle.attr(options)
  43121. };
  43122. sliderGroup.__line = sliderHandle;
  43123. return sliderGroup
  43124. },
  43125. _createSliderTracker: function(group) {
  43126. var that = this,
  43127. sliderHandleWidth = that._options.sliderHandle.width,
  43128. splitterWidth = SPLITTER_WIDTH < sliderHandleWidth ? sliderHandleWidth : SPLITTER_WIDTH,
  43129. sliderWidth = touchSupport || msPointerEnabled ? TOUCH_SPLITTER_WIDTH : splitterWidth,
  43130. sliderTracker,
  43131. canvas = that._options.canvas,
  43132. renderer = that._renderer,
  43133. sliderTrackerGroup = renderer.g().attr({
  43134. 'class': 'sliderTracker',
  43135. translateX: 0,
  43136. translateY: canvas.top
  43137. }).append(group);
  43138. sliderTracker = renderer.rect(-sliderWidth / 2, 0, sliderWidth, canvas.height).attr(rangeSelectorUtils.trackerSettings).css({cursor: 'w-resize'}).append(sliderTrackerGroup);
  43139. sliderTrackerGroup.updateHeight = function() {
  43140. sliderTracker.attr({height: that._options.canvas.height})
  43141. };
  43142. sliderTrackerGroup.__rect = sliderTracker;
  43143. return sliderTrackerGroup
  43144. },
  43145. _setPosition: function(position, correctByMinMaxRange) {
  43146. var that = this,
  43147. correctedPosition = that._correctPosition(position),
  43148. value = that._options.translator.untranslate(correctedPosition, that._getValueDirection());
  43149. that.setValue(value, correctByMinMaxRange, false);
  43150. that._position = correctedPosition
  43151. },
  43152. _getValueDirection: function() {
  43153. return this._options.scale.type === DISCRETE ? this.getIndex() === START_VALUE_INDEX ? -1 : 1 : 0
  43154. },
  43155. _setPositionForBothSliders: function(startPosition, interval) {
  43156. var that = this,
  43157. anotherSlider = that.getAnotherSlider(),
  43158. startValue,
  43159. endValue,
  43160. endPosition,
  43161. options = that._options,
  43162. scale = options.scale,
  43163. canvas = options.canvas,
  43164. rightBorderCoords = canvas.left + canvas.width,
  43165. translator = options.translator,
  43166. valueDirection = that._getValueDirection(),
  43167. valueDirectionAnotherSlider = anotherSlider._getValueDirection(),
  43168. getNextValue = function(value, isNegative, reverseValueDirection) {
  43169. var curValueDirection = !reverseValueDirection ? valueDirection : valueDirectionAnotherSlider,
  43170. curAnotherValueDirection = reverseValueDirection ? valueDirection : valueDirectionAnotherSlider;
  43171. return translator.untranslate(that._correctBounds(utils.addInterval(translator.translate(value, curValueDirection), interval, isNegative)), curAnotherValueDirection)
  43172. };
  43173. startPosition = that._correctBounds(startPosition);
  43174. startValue = translator.untranslate(startPosition, valueDirection);
  43175. endValue = getNextValue(startValue);
  43176. endPosition = startPosition + interval;
  43177. if (endPosition > rightBorderCoords) {
  43178. endValue = scale.endValue;
  43179. endPosition = rightBorderCoords;
  43180. startValue = getNextValue(endValue, true, true);
  43181. startPosition = that._correctBounds(endPosition - interval)
  43182. }
  43183. else
  43184. endPosition = that._correctBounds(endPosition);
  43185. if (that._values)
  43186. if (!scale.inverted ? startValue < that._values[0] : startValue > that._values[that._values.length - 1]) {
  43187. startValue = that._correctByAvailableValues(startValue, false);
  43188. endValue = getNextValue(startValue)
  43189. }
  43190. else {
  43191. endValue = that._correctByAvailableValues(endValue, false);
  43192. startValue = getNextValue(endValue, true)
  43193. }
  43194. anotherSlider.setValue(endValue, undefined, false);
  43195. that.setValue(startValue, undefined, false);
  43196. that._position = startPosition;
  43197. anotherSlider._position = endPosition
  43198. },
  43199. _correctPosition: function(position) {
  43200. return this._correctBounds(this._correctInversion(position))
  43201. },
  43202. _correctInversion: function(position) {
  43203. var that = this,
  43204. correctedPosition = position,
  43205. anotherSliderPosition = that.getAnotherSlider().getPosition(),
  43206. slidersInverted = that.getIndex() === START_VALUE_INDEX ? position > anotherSliderPosition : position < anotherSliderPosition;
  43207. if (slidersInverted)
  43208. correctedPosition = anotherSliderPosition;
  43209. return correctedPosition
  43210. },
  43211. _correctBounds: function(position) {
  43212. var that = this,
  43213. correctedPosition = position,
  43214. canvas = that._options.canvas;
  43215. if (position < canvas.left)
  43216. correctedPosition = canvas.left;
  43217. if (position > canvas.left + canvas.width)
  43218. correctedPosition = canvas.left + canvas.width;
  43219. return correctedPosition
  43220. },
  43221. _correctValue: function(businessValue, correctByMinMaxRange, skipCorrection) {
  43222. var that = this,
  43223. result = that._correctByAvailableValues(businessValue, skipCorrection);
  43224. if (correctByMinMaxRange)
  43225. result = that._correctByMinMaxRange(result);
  43226. if (that._options.scale.type !== DISCRETE)
  43227. result = that.correctByMinRange(result);
  43228. return result
  43229. },
  43230. _correctByAvailableValues: function(businessValue, skipCorrection) {
  43231. var values = this._values;
  43232. if (!skipCorrection && values)
  43233. return rangeSelectorUtils.findNearValue(values, businessValue);
  43234. return businessValue
  43235. },
  43236. _correctByMinMaxRange: function(businessValue) {
  43237. var that = this,
  43238. result = businessValue,
  43239. scale = that._options.scale,
  43240. values = that._values,
  43241. sliderIndex = that.getIndex(),
  43242. anotherSlider = that.getAnotherSlider(),
  43243. anotherBusinessValue = anotherSlider.getValue(),
  43244. isValid = true,
  43245. minValue,
  43246. maxValue,
  43247. maxRange = scale.maxRange,
  43248. minRange = scale.minRange,
  43249. categoriesInfo;
  43250. if (scale.type === DISCRETE) {
  43251. categoriesInfo = scale._categoriesInfo;
  43252. if (checkItemsSpacing(that.getPosition(), anotherSlider.getPosition(), that._options.translator.getInterval() / 2)) {
  43253. isValid = false;
  43254. result = getValidCategories(categoriesInfo.categories, businessValue, anotherSlider.getValue(), sliderIndex === START_VALUE_INDEX ? 1 : -1)
  43255. }
  43256. }
  43257. else {
  43258. if (!scale.inverted && sliderIndex === START_VALUE_INDEX || scale.inverted && sliderIndex === END_VALUE_INDEX) {
  43259. if (maxRange)
  43260. minValue = that._addInterval(anotherBusinessValue, maxRange, true);
  43261. if (minRange)
  43262. maxValue = that._addInterval(anotherBusinessValue, minRange, true)
  43263. }
  43264. else {
  43265. if (maxRange)
  43266. maxValue = that._addInterval(anotherBusinessValue, maxRange);
  43267. if (minRange)
  43268. minValue = that._addInterval(anotherBusinessValue, minRange)
  43269. }
  43270. if (maxValue !== undefined && result > maxValue) {
  43271. result = values ? rangeSelectorUtils.findLessOrEqualValue(values, maxValue) : maxValue;
  43272. isValid = false
  43273. }
  43274. else if (minValue !== undefined && result < minValue) {
  43275. result = values ? rangeSelectorUtils.findGreaterOrEqualValue(values, minValue) : minValue;
  43276. isValid = false
  43277. }
  43278. }
  43279. that._setValid(isValid);
  43280. return result
  43281. },
  43282. _addInterval: function(value, interval, isNegative) {
  43283. var result,
  43284. type = this._options.scale.type,
  43285. base = type === "logarithmic" && this._options.scale.logarithmBase,
  43286. power;
  43287. if (base) {
  43288. power = utils.addInterval(utils.getLog(value, base), interval, isNegative);
  43289. result = Math.pow(base, power)
  43290. }
  43291. else
  43292. result = utils.addInterval(value, interval, isNegative);
  43293. return result
  43294. },
  43295. correctByMinRange: function(businessValue) {
  43296. var that = this,
  43297. startValue,
  43298. endValue,
  43299. scale = that._options.scale,
  43300. result = businessValue;
  43301. if (scale.minRange)
  43302. if (that.getIndex() === END_VALUE_INDEX) {
  43303. startValue = that._addInterval(scale.startValue, scale.minRange, scale.inverted);
  43304. if (!scale.inverted && result < startValue || scale.inverted && result > startValue)
  43305. result = startValue
  43306. }
  43307. else if (that.getIndex() === START_VALUE_INDEX) {
  43308. endValue = that._addInterval(scale.endValue, scale.minRange, !scale.inverted);
  43309. if (!scale.inverted && result > endValue || scale.inverted && result < endValue)
  43310. result = endValue
  43311. }
  43312. return result
  43313. },
  43314. _applySliderPosition: function(position, disableAnimation) {
  43315. var that = this,
  43316. options = that._options,
  43317. isAnimation = options.behavior.animationEnabled && !disableAnimation,
  43318. slider = that._slider,
  43319. sliderTracker = that._sliderTracker,
  43320. attrs = {
  43321. translateX: position,
  43322. translateY: options.canvas.top
  43323. },
  43324. animationSettings = rangeSelectorUtils.animationSettings;
  43325. that._marker && that._marker.setPosition(position);
  43326. if (isAnimation) {
  43327. slider.animate(attrs, animationSettings);
  43328. sliderTracker.animate(attrs, animationSettings)
  43329. }
  43330. else {
  43331. slider.stopAnimation().attr(attrs);
  43332. sliderTracker.stopAnimation().attr(attrs)
  43333. }
  43334. sliderTracker.updateHeight();
  43335. slider.updateHeight()
  43336. },
  43337. _applyShutterPosition: function(position, disableAnimation) {
  43338. var that = this,
  43339. shutterSettings,
  43340. options = that._options,
  43341. shutter = that._shutter,
  43342. isAnimation = options.behavior.animationEnabled && !disableAnimation,
  43343. sliderIndex = that.getIndex(),
  43344. canvas = options.canvas,
  43345. halfSliderHandleWidth = options.sliderHandle.width / 2,
  43346. width;
  43347. if (!shutter)
  43348. return;
  43349. if (sliderIndex === START_VALUE_INDEX) {
  43350. width = position - canvas.left - Math.floor(halfSliderHandleWidth);
  43351. if (width < 0)
  43352. width = 0;
  43353. shutterSettings = {
  43354. x: canvas.left,
  43355. y: canvas.top,
  43356. width: width,
  43357. height: canvas.height
  43358. }
  43359. }
  43360. else if (sliderIndex === END_VALUE_INDEX)
  43361. shutterSettings = {
  43362. x: position + Math.ceil(halfSliderHandleWidth),
  43363. y: canvas.top,
  43364. width: canvas.left + canvas.width - position,
  43365. height: canvas.height
  43366. };
  43367. if (isAnimation)
  43368. shutter.animate(shutterSettings, rangeSelectorUtils.animationSettings);
  43369. else
  43370. shutter.stopAnimation().attr(shutterSettings)
  43371. },
  43372. _setValid: function(isValid) {
  43373. this._marker && this._marker.setValid(isValid);
  43374. this._slider.setValid(isValid)
  43375. },
  43376. _setText: function(text) {
  43377. this._marker && this._marker.setText(text)
  43378. },
  43379. _update: function() {
  43380. var that = this,
  43381. options = that._options,
  43382. shutterOptions = options.shutter,
  43383. sliderHandleOptions = options.sliderHandle,
  43384. marker = that._marker;
  43385. if (marker) {
  43386. marker.applyOptions(options.sliderMarker);
  43387. marker.setCanvas(that._options.canvas)
  43388. }
  43389. that._shutter && that._shutter.attr({
  43390. fill: shutterOptions.color,
  43391. "fill-opacity": shutterOptions.opacity
  43392. });
  43393. that._slider && that._slider.applyOptions({
  43394. "stroke-width": sliderHandleOptions.width,
  43395. stroke: sliderHandleOptions.color,
  43396. "stroke-opacity": sliderHandleOptions.opacity
  43397. })
  43398. },
  43399. _draw: function(group) {
  43400. var that = this,
  43401. slider,
  43402. marker,
  43403. sliderAreaGroup,
  43404. options = that._options,
  43405. renderer = that._renderer;
  43406. that._container = sliderAreaGroup = renderer.g().attr({'class': 'sliderArea'}).append(group);
  43407. slider = that._createSlider(sliderAreaGroup);
  43408. if (options.sliderMarker.visible) {
  43409. marker = rangeSelector.rangeSelectorFactory.createSliderMarker({
  43410. renderer: renderer,
  43411. isLeftPointer: that.getIndex() === END_VALUE_INDEX,
  43412. sliderMarkerOptions: options.sliderMarker
  43413. });
  43414. marker.setCanvas(options.canvas);
  43415. marker.draw(slider)
  43416. }
  43417. that._slider = slider;
  43418. that._marker = marker;
  43419. that._sliderTracker = that._createSliderTracker(group)
  43420. },
  43421. toForeground: function() {
  43422. this._container.toForeground()
  43423. },
  43424. _applyOptions: function() {
  43425. this._lastPosition = null
  43426. },
  43427. getIndex: function() {
  43428. return this._index
  43429. },
  43430. setAvailableValues: function(values) {
  43431. this._values = values
  43432. },
  43433. setAnotherSlider: function(slider) {
  43434. this._anotherSlider = slider
  43435. },
  43436. getAnotherSlider: function() {
  43437. return this._anotherSlider
  43438. },
  43439. appendTrackers: function(group) {
  43440. this._sliderTracker && this._sliderTracker.append(group)
  43441. },
  43442. getSliderTracker: function() {
  43443. return this._sliderTracker
  43444. },
  43445. changeLocation: function() {
  43446. var that = this;
  43447. that._marker && that._marker.changeLocation();
  43448. that._index = that._index === START_VALUE_INDEX ? END_VALUE_INDEX : START_VALUE_INDEX;
  43449. if (that._options.scale.type === DISCRETE)
  43450. that.setPosition(that._position);
  43451. that._lastPosition = null
  43452. },
  43453. setPosition: function(position, correctByMinMaxRange, selectedRangeInterval) {
  43454. var that = this,
  43455. slider;
  43456. if (selectedRangeInterval !== undefined) {
  43457. slider = that.getIndex() === START_VALUE_INDEX ? that : that.getAnotherSlider();
  43458. slider._setPositionForBothSliders(position, selectedRangeInterval)
  43459. }
  43460. else
  43461. that._setPosition(position, correctByMinMaxRange)
  43462. },
  43463. getPosition: function() {
  43464. return this._position
  43465. },
  43466. setValue: function(value, correctByMinMaxRange, skipCorrection) {
  43467. var that = this,
  43468. options = that._options,
  43469. canvas = options.canvas,
  43470. position,
  43471. text;
  43472. if (value === undefined) {
  43473. that._value = undefined;
  43474. position = that.getIndex() === START_VALUE_INDEX ? canvas.left : canvas.left + canvas.width;
  43475. text = rangeSelector.consts.emptySliderMarkerText
  43476. }
  43477. else {
  43478. that._value = that._correctValue(value, correctByMinMaxRange, utils.isDefined(skipCorrection) ? !!skipCorrection : true);
  43479. position = options.translator.translate(that._value, that._getValueDirection());
  43480. text = rangeSelector.formatValue(that._value, options.sliderMarker)
  43481. }
  43482. that._setText(text);
  43483. that._valuePosition = that._position = position
  43484. },
  43485. setOverlapped: function(isOverlapped) {
  43486. this._marker && this._marker.setOverlapped(isOverlapped)
  43487. },
  43488. getValue: function() {
  43489. return this._value
  43490. },
  43491. canSwap: function() {
  43492. var that = this,
  43493. scale = that._options.scale,
  43494. startValue,
  43495. endValue,
  43496. anotherSliderValue;
  43497. if (that._options.behavior.allowSlidersSwap) {
  43498. if (scale.minRange) {
  43499. anotherSliderValue = that.getAnotherSlider().getValue();
  43500. if (that.getIndex() === START_VALUE_INDEX) {
  43501. endValue = that._addInterval(scale.endValue, scale.minRange, !scale.inverted);
  43502. if (!scale.inverted && anotherSliderValue > endValue || scale.inverted && anotherSliderValue < endValue)
  43503. return false
  43504. }
  43505. else {
  43506. startValue = that._addInterval(scale.startValue, scale.minRange, scale.inverted);
  43507. if (!scale.inverted && anotherSliderValue < startValue || scale.inverted && anotherSliderValue > startValue)
  43508. return false
  43509. }
  43510. }
  43511. return true
  43512. }
  43513. return false
  43514. },
  43515. processDocking: function() {
  43516. var that = this;
  43517. that._position = that._valuePosition;
  43518. that.applyPosition(false);
  43519. that._setValid(true)
  43520. },
  43521. applyPosition: function(disableAnimation) {
  43522. var that = this,
  43523. position = that.getPosition();
  43524. if (that._lastPosition !== position) {
  43525. that._applySliderPosition(position, disableAnimation);
  43526. that._applyShutterPosition(position, disableAnimation);
  43527. that._lastPosition = position
  43528. }
  43529. },
  43530. on: function(event, handler) {
  43531. var that = this,
  43532. marker = that._marker,
  43533. tracker = marker && marker.getTracker(),
  43534. sliderTracker = that._sliderTracker;
  43535. sliderTracker && sliderTracker.on(event, handler);
  43536. tracker && tracker.on(event, handler)
  43537. },
  43538. createShutter: function() {
  43539. var that = this,
  43540. index = that.getIndex(),
  43541. canvas = that._options.canvas,
  43542. renderer = that._renderer,
  43543. shutter = that._shutter;
  43544. if (!shutter) {
  43545. if (index === START_VALUE_INDEX)
  43546. shutter = renderer.rect(canvas.left, canvas.top, 0, canvas.height);
  43547. else if (index === END_VALUE_INDEX)
  43548. shutter = renderer.rect(canvas.left, canvas.top, canvas.width, canvas.height);
  43549. that._shutter = shutter
  43550. }
  43551. shutter.append(that._container)
  43552. },
  43553. removeShutter: function() {
  43554. var shutter = this._shutter;
  43555. shutter && shutter.remove()
  43556. },
  43557. getCloudBorder: function() {
  43558. return this._marker ? this._marker.getBorderPosition() : 0
  43559. },
  43560. dispose: function() {
  43561. var marker = this._marker;
  43562. marker && marker.dispose()
  43563. }
  43564. });
  43565. rangeSelector.Slider = Slider
  43566. })(jQuery, DevExpress);
  43567. /*! Module viz-rangeselector, file sliderMarker.js */
  43568. (function($, DX, undefined) {
  43569. var viz = DX.viz,
  43570. core = viz.core,
  43571. rangeSelector = viz.rangeSelector,
  43572. SliderMarker,
  43573. SLIDER_MARKER_UPDATE_DELAY = 75,
  43574. POINTER_SIZE = rangeSelector.consts.pointerSize;
  43575. var getRectSize = function(that, textSize) {
  43576. var options = that._options;
  43577. return {
  43578. width: Math.round(2 * options.paddingLeftRight + textSize.width),
  43579. height: Math.round(2 * options.paddingTopBottom + textSize.height)
  43580. }
  43581. };
  43582. var getAreaPointsInfo = function(that, textSize) {
  43583. var rectSize = getRectSize(that, textSize),
  43584. rectWidth = rectSize.width,
  43585. rectHeight = rectSize.height,
  43586. rectLeftBorder = -rectWidth,
  43587. rectRightBorder = 0,
  43588. pointerRightPoint = POINTER_SIZE,
  43589. pointerCenterPoint = 0,
  43590. pointerLeftPoint = -POINTER_SIZE,
  43591. position = that._position,
  43592. canvas = that._canvas,
  43593. isLeft = that._isLeftPointer,
  43594. correctCloudBorders = function() {
  43595. rectLeftBorder++;
  43596. rectRightBorder++;
  43597. pointerRightPoint++;
  43598. pointerCenterPoint++;
  43599. pointerLeftPoint++
  43600. },
  43601. checkPointerBorders = function() {
  43602. if (pointerRightPoint > rectRightBorder)
  43603. pointerRightPoint = rectRightBorder;
  43604. else if (pointerLeftPoint < rectLeftBorder)
  43605. pointerLeftPoint = rectLeftBorder;
  43606. isLeft && correctCloudBorders()
  43607. },
  43608. borderPosition = position;
  43609. if (isLeft)
  43610. if (position > canvas.left + canvas.width - rectWidth) {
  43611. rectRightBorder = -position + (canvas.left + canvas.width);
  43612. rectLeftBorder = rectRightBorder - rectWidth;
  43613. checkPointerBorders();
  43614. borderPosition += rectLeftBorder
  43615. }
  43616. else {
  43617. rectLeftBorder = pointerLeftPoint = 0;
  43618. rectRightBorder = rectWidth
  43619. }
  43620. else if (position - canvas.left < rectWidth) {
  43621. rectLeftBorder = -(position - canvas.left);
  43622. rectRightBorder = rectLeftBorder + rectWidth;
  43623. checkPointerBorders();
  43624. borderPosition += rectRightBorder
  43625. }
  43626. else {
  43627. pointerRightPoint = 0;
  43628. correctCloudBorders()
  43629. }
  43630. that._borderPosition = borderPosition;
  43631. return {
  43632. offset: rectLeftBorder,
  43633. isCutted: (!isLeft || pointerCenterPoint !== pointerLeftPoint) && (isLeft || pointerCenterPoint !== pointerRightPoint),
  43634. points: [rectLeftBorder, 0, rectRightBorder, 0, rectRightBorder, rectHeight, pointerRightPoint, rectHeight, pointerCenterPoint, rectHeight + POINTER_SIZE, pointerLeftPoint, rectHeight, rectLeftBorder, rectHeight]
  43635. }
  43636. };
  43637. var getTextSize = function(that) {
  43638. var textSize = that._label.getBBox();
  43639. if (!that._textHeight && isFinite(textSize.height))
  43640. that._textHeight = textSize.height;
  43641. return {
  43642. width: textSize.width,
  43643. height: that._textHeight,
  43644. y: textSize.y
  43645. }
  43646. };
  43647. SliderMarker = rangeSelector.SliderMarker = function(options) {
  43648. var that = this;
  43649. that._renderer = options.renderer;
  43650. that._text = options.text;
  43651. that._isLeftPointer = options.isLeftPointer;
  43652. that._options = $.extend(true, {}, options.sliderMarkerOptions);
  43653. that._options.textFontStyles = core.utils.patchFontOptions(that._options.font);
  43654. that._isValid = true;
  43655. that._isOverlapped = false
  43656. };
  43657. SliderMarker.prototype = {
  43658. constructor: SliderMarker,
  43659. draw: function(group) {
  43660. var that = this,
  43661. options = that._options,
  43662. sliderMarkerGroup = that._sliderMarkerGroup = that._renderer.g().attr({'class': 'sliderMarker'}).append(group);
  43663. that._area = that._renderer.path([], "area").attr({fill: options.color}).append(sliderMarkerGroup);
  43664. that._label = that._renderer.text(that._text, 0, 0).attr({align: 'left'}).css(options.textFontStyles).append(sliderMarkerGroup);
  43665. that._tracker = that._renderer.rect(0, 0, 2 * options.paddingLeftRight, 2 * options.paddingTopBottom + POINTER_SIZE).attr(rangeSelector.utils.trackerSettings).css({cursor: 'pointer'}).append(sliderMarkerGroup);
  43666. that._border = that._renderer.rect(0, 0, 1, 0).attr({fill: options.borderColor});
  43667. that._drawn = true;
  43668. that._update()
  43669. },
  43670. _update: function() {
  43671. var that = this,
  43672. textSize,
  43673. options = that._options,
  43674. currentTextSize,
  43675. rectSize;
  43676. clearTimeout(that._timeout);
  43677. if (!that._drawn)
  43678. return;
  43679. that._label.attr({text: that._text || ""});
  43680. currentTextSize = getTextSize(that);
  43681. rectSize = getRectSize(that, currentTextSize);
  43682. textSize = that._textSize || currentTextSize;
  43683. textSize = that._textSize = currentTextSize.width > textSize.width || currentTextSize.height > textSize.height ? currentTextSize : textSize;
  43684. that._timeout = setTimeout(function() {
  43685. updateSliderMarker(currentTextSize, rectSize);
  43686. that._textSize = currentTextSize
  43687. }, SLIDER_MARKER_UPDATE_DELAY);
  43688. function updateSliderMarker(size, rectSize) {
  43689. var points,
  43690. pointsData,
  43691. offset;
  43692. rectSize = rectSize || getRectSize(that, size);
  43693. that._sliderMarkerGroup.attr({translateY: -(rectSize.height + POINTER_SIZE)});
  43694. pointsData = getAreaPointsInfo(that, size);
  43695. points = pointsData.points;
  43696. offset = pointsData.offset;
  43697. that._area.attr({points: points});
  43698. that._border.attr({
  43699. x: that._isLeftPointer ? points[0] - 1 : points[2],
  43700. height: pointsData.isCutted ? rectSize.height : rectSize.height + POINTER_SIZE
  43701. });
  43702. that._tracker.attr({
  43703. translateX: offset,
  43704. width: rectSize.width,
  43705. height: rectSize.height + POINTER_SIZE
  43706. });
  43707. that._label.attr({
  43708. translateX: options.paddingLeftRight + offset,
  43709. translateY: rectSize.height / 2 - (size.y + size.height / 2)
  43710. })
  43711. }
  43712. updateSliderMarker(textSize)
  43713. },
  43714. setText: function(value) {
  43715. var that = this;
  43716. if (that._text !== value)
  43717. that._text = value
  43718. },
  43719. setPosition: function(position) {
  43720. this._position = position;
  43721. this._update()
  43722. },
  43723. changeLocation: function() {
  43724. var that = this;
  43725. that._isLeftPointer = !that._isLeftPointer;
  43726. that._update()
  43727. },
  43728. applyOptions: function(options) {
  43729. var that = this,
  43730. fontSyles,
  43731. opt = that._options = $.extend(true, {}, options);
  43732. fontSyles = opt.textFontStyles = core.utils.patchFontOptions(opt.font);
  43733. that._textHeight = null;
  43734. that._area.attr({fill: options.color});
  43735. that._border.attr({fill: options.borderColor});
  43736. that._label.css(fontSyles);
  43737. that._update()
  43738. },
  43739. getTracker: function() {
  43740. return this._tracker
  43741. },
  43742. setValid: function(isValid) {
  43743. var that = this,
  43744. options = that._options;
  43745. if (that._isValid !== isValid) {
  43746. that._isValid = isValid;
  43747. that._area.attr({fill: isValid ? options.color : options.invalidRangeColor})
  43748. }
  43749. },
  43750. dispose: function() {
  43751. clearTimeout(this._timeout)
  43752. },
  43753. setOverlapped: function(isOverlapped) {
  43754. var border = this._border,
  43755. currentOverlappedState = this._isOverlapped;
  43756. if (currentOverlappedState === isOverlapped)
  43757. return;
  43758. if (isOverlapped)
  43759. border.append(this._sliderMarkerGroup);
  43760. else
  43761. this._isOverlapped && border.remove();
  43762. this._isOverlapped = isOverlapped
  43763. },
  43764. getBorderPosition: function() {
  43765. return this._borderPosition
  43766. },
  43767. setCanvas: function(canvas) {
  43768. this._canvas = canvas
  43769. }
  43770. };
  43771. SliderMarker.prototype.updateDelay = SLIDER_MARKER_UPDATE_DELAY;
  43772. SliderMarker.prototype.getText = function() {
  43773. return this._text
  43774. }
  43775. })(jQuery, DevExpress);
  43776. /*! Module viz-rangeselector, file rangeView.js */
  43777. (function($, DX, undefined) {
  43778. var rangeSelector = DX.viz.rangeSelector,
  43779. RangeView,
  43780. baseVisualElementMethods = rangeSelector.baseVisualElementMethods;
  43781. RangeView = function() {
  43782. baseVisualElementMethods.init.apply(this, arguments)
  43783. };
  43784. RangeView.prototype = $.extend({}, baseVisualElementMethods, {
  43785. constructor: RangeView,
  43786. _draw: function(group) {
  43787. var that = this,
  43788. series,
  43789. i,
  43790. options = that._options,
  43791. isCompactMode = options.isCompactMode,
  43792. canvas = options.canvas,
  43793. isEmpty = options.isEmpty,
  43794. renderer = that._renderer,
  43795. seriesDataSource = options.seriesDataSource,
  43796. showChart = seriesDataSource && seriesDataSource.isShowChart() && !isEmpty,
  43797. background = options.background,
  43798. backgroundColor = showChart ? seriesDataSource.getBackgroundColor() : background.color,
  43799. backgroundImage = background.image,
  43800. backgroundIsVisible = background.visible;
  43801. if (isCompactMode)
  43802. return;
  43803. if (backgroundIsVisible && !isEmpty && backgroundColor)
  43804. renderer.rect(canvas.left, canvas.top, canvas.width + 1, canvas.height).attr({
  43805. fill: backgroundColor,
  43806. 'class': 'dx-range-selector-background'
  43807. }).append(group);
  43808. if (backgroundIsVisible && backgroundImage && backgroundImage.url)
  43809. renderer.image(canvas.left, canvas.top, canvas.width + 1, canvas.height, backgroundImage.url, backgroundImage.location).append(group);
  43810. if (showChart) {
  43811. series = seriesDataSource.getSeries();
  43812. seriesDataSource.adjustSeriesDimensions(options.translators, options.chart.useAggregation);
  43813. for (i = 0; i < series.length; i++) {
  43814. series[i]._extGroups.seriesGroup = group;
  43815. series[i]._extGroups.labelsGroup = group;
  43816. series[i].draw(options.translators, options.behavior && options.behavior.animationEnabled && renderer.animationEnabled())
  43817. }
  43818. }
  43819. }
  43820. });
  43821. rangeSelector.RangeView = RangeView
  43822. })(jQuery, DevExpress);
  43823. /*! Module viz-rangeselector, file seriesDataSource.js */
  43824. (function($, DX, undefined) {
  43825. var rangeSelector = DX.viz.rangeSelector,
  43826. charts = DX.viz.charts,
  43827. core = DX.viz.core,
  43828. coreFactory = core.CoreFactory,
  43829. utils = DX.utils,
  43830. _SeriesDatasource;
  43831. var createThemeManager = function(chartOptions) {
  43832. return charts.factory.createThemeManager(chartOptions, 'rangeSelector.chart')
  43833. };
  43834. var isArrayOfSimpleTypes = function(data) {
  43835. return $.isArray(data) && data.length > 0 && (utils.isNumber(data[0]) || utils.isDate(data[0]))
  43836. };
  43837. var convertToArrayOfObjects = function(data) {
  43838. return $.map(data, function(item, i) {
  43839. return {
  43840. arg: item,
  43841. val: i
  43842. }
  43843. })
  43844. };
  43845. var processSeriesFamilies = function(series, equalBarWidth, minBubbleSize, maxBubbleSize) {
  43846. var families = [],
  43847. types = [];
  43848. $.each(series, function(i, item) {
  43849. if ($.inArray(item.type, types) === -1)
  43850. types.push(item.type)
  43851. });
  43852. $.each(types, function(_, type) {
  43853. var family = new coreFactory.createSeriesFamily({
  43854. type: type,
  43855. equalBarWidth: equalBarWidth,
  43856. minBubbleSize: minBubbleSize,
  43857. maxBubbleSize: maxBubbleSize
  43858. });
  43859. family.add(series);
  43860. family.adjustSeriesValues();
  43861. families.push(family)
  43862. });
  43863. return families
  43864. };
  43865. var isStickType = function(type) {
  43866. var nonStickTypes = ["bar", "candlestick", "stock", "bubble"],
  43867. stickType = true;
  43868. type = type.toLowerCase();
  43869. $.each(nonStickTypes, function(_, item) {
  43870. if (type.indexOf(item) !== -1) {
  43871. stickType = false;
  43872. return false
  43873. }
  43874. });
  43875. return stickType
  43876. };
  43877. function setTemplateFields(data, templateData, series) {
  43878. $.each(data, function(_, data) {
  43879. $.each(series.getTeamplatedFields(), function(_, field) {
  43880. data[field.teamplateField] = data[field.originalField]
  43881. });
  43882. templateData.push(data)
  43883. });
  43884. series.updateTeamplateFieldNames()
  43885. }
  43886. _SeriesDatasource = rangeSelector.SeriesDataSource = function(options) {
  43887. var that = this,
  43888. templatedSeries,
  43889. seriesTemplate,
  43890. themeManager = that._themeManager = createThemeManager(options.chart),
  43891. topIndent,
  43892. bottomIndent;
  43893. themeManager._fontFields = ["commonSeriesSettings.label.font"];
  43894. themeManager.setTheme(options.chart.theme);
  43895. topIndent = themeManager.getOptions('topIndent');
  43896. bottomIndent = themeManager.getOptions('bottomIndent');
  43897. that._indent = {
  43898. top: topIndent >= 0 && topIndent < 1 ? topIndent : 0,
  43899. bottom: bottomIndent >= 0 && bottomIndent < 1 ? bottomIndent : 0
  43900. };
  43901. that._valueAxis = themeManager.getOptions('valueAxisRangeSelector') || {};
  43902. that._hideChart = false;
  43903. seriesTemplate = themeManager.getOptions('seriesTemplate');
  43904. if (options.dataSource && seriesTemplate)
  43905. templatedSeries = utils.processSeriesTemplate(seriesTemplate, options.dataSource);
  43906. that._series = that._calculateSeries(options, templatedSeries);
  43907. that._seriesFamilies = processSeriesFamilies(that._series, themeManager.getOptions('equalBarWidth'), themeManager.getOptions('minBubbleSize'), themeManager.getOptions('maxBubbleSize'))
  43908. };
  43909. _SeriesDatasource.prototype = {
  43910. constructor: _SeriesDatasource,
  43911. _calculateSeries: function(options, templatedSeries) {
  43912. var that = this,
  43913. series = [],
  43914. particularSeriesOptions,
  43915. seriesTheme,
  43916. data,
  43917. groupSeries,
  43918. parsedData,
  43919. chartThemeManager = that._themeManager,
  43920. hasSeriesTemplate = !!chartThemeManager.getOptions('seriesTemplate'),
  43921. allSeriesOptions = hasSeriesTemplate ? templatedSeries : options.chart.series,
  43922. seriesValueType = options.chart.valueAxis && options.chart.valueAxis.valueType,
  43923. dataSourceField,
  43924. i,
  43925. newSeries,
  43926. particularSeries;
  43927. that.teamplateData = [];
  43928. if (options.dataSource && !allSeriesOptions) {
  43929. if (isArrayOfSimpleTypes(options.dataSource))
  43930. options.dataSource = convertToArrayOfObjects(options.dataSource);
  43931. dataSourceField = options.dataSourceField || 'arg';
  43932. allSeriesOptions = {
  43933. argumentField: dataSourceField,
  43934. valueField: dataSourceField
  43935. };
  43936. that._hideChart = true
  43937. }
  43938. allSeriesOptions = $.isArray(allSeriesOptions) ? allSeriesOptions : allSeriesOptions ? [allSeriesOptions] : [];
  43939. that._backgroundColor = options.backgroundColor;
  43940. for (i = 0; i < allSeriesOptions.length; i++) {
  43941. particularSeriesOptions = $.extend(true, {incidentOccured: options.incidentOccured}, allSeriesOptions[i]);
  43942. particularSeriesOptions.rotated = false;
  43943. data = particularSeriesOptions.data || options.dataSource;
  43944. seriesTheme = chartThemeManager.getOptions("series", particularSeriesOptions);
  43945. seriesTheme.argumentField = seriesTheme.argumentField || options.dataSourceField;
  43946. if (data && data.length > 0) {
  43947. newSeries = coreFactory.createSeries({renderer: options.renderer}, seriesTheme);
  43948. series.push(newSeries)
  43949. }
  43950. if (hasSeriesTemplate)
  43951. setTemplateFields(data, that.teamplateData, newSeries)
  43952. }
  43953. data = hasSeriesTemplate ? that.teamplateData : data;
  43954. groupSeries = [series];
  43955. groupSeries.argumentOptions = {
  43956. categories: options.categories,
  43957. argumentType: options.valueType,
  43958. type: options.axisType
  43959. };
  43960. groupSeries[0].valueOptions = {valueType: dataSourceField ? options.valueType : seriesValueType};
  43961. that._dataValidator = core.CoreFactory.createDataValidator(data, groupSeries, options.incidentOccured, chartThemeManager.getOptions("dataPrepareSettings"));
  43962. parsedData = that._dataValidator.validate();
  43963. for (i = 0; i < series.length; i++) {
  43964. particularSeries = series[i];
  43965. particularSeries.updateData(parsedData)
  43966. }
  43967. return series
  43968. },
  43969. adjustSeriesDimensions: function(translators, useAggregation) {
  43970. var that = this;
  43971. if (useAggregation)
  43972. $.each(that._series || [], function(_, s) {
  43973. s.resamplePoints(translators.x)
  43974. });
  43975. $.each(that._seriesFamilies, function(_, family) {
  43976. family.adjustSeriesDimensions({
  43977. arg: translators.x,
  43978. val: translators.y
  43979. })
  43980. })
  43981. },
  43982. getBoundRange: function() {
  43983. var that = this,
  43984. rangeData,
  43985. valueAxisMin = that._valueAxis.min,
  43986. valueAxisMax = that._valueAxis.max,
  43987. valRange = new core.Range({
  43988. isValueRange: true,
  43989. min: valueAxisMin,
  43990. minVisible: valueAxisMin,
  43991. max: valueAxisMax,
  43992. maxVisible: valueAxisMax,
  43993. axisType: that._valueAxis.type,
  43994. base: that._valueAxis.logarithmBase
  43995. }),
  43996. argRange = new core.Range({}),
  43997. rangeYSize,
  43998. rangeVisibleSizeY,
  43999. minIndent,
  44000. maxIndent;
  44001. $.each(that._series, function(_, series) {
  44002. rangeData = series.getRangeData();
  44003. valRange.addRange(rangeData.val);
  44004. argRange.addRange(rangeData.arg);
  44005. if (!isStickType(series.type))
  44006. argRange.addRange({stick: false})
  44007. });
  44008. if (valRange.isDefined() && argRange.isDefined()) {
  44009. minIndent = that._valueAxis.inverted ? that._indent.top : that._indent.bottom;
  44010. maxIndent = that._valueAxis.inverted ? that._indent.bottom : that._indent.top;
  44011. rangeYSize = valRange.max - valRange.min;
  44012. rangeVisibleSizeY = ($.isNumeric(valRange.maxVisible) ? valRange.maxVisible : valRange.max) - ($.isNumeric(valRange.minVisible) ? valRange.minVisible : valRange.min);
  44013. if (utils.isDate(valRange.min))
  44014. valRange.min = new Date(valRange.min.valueOf() - rangeYSize * minIndent);
  44015. else
  44016. valRange.min -= rangeYSize * minIndent;
  44017. if (utils.isDate(valRange.max))
  44018. valRange.max = new Date(valRange.max.valueOf() + rangeYSize * maxIndent);
  44019. else
  44020. valRange.max += rangeYSize * maxIndent;
  44021. if ($.isNumeric(rangeVisibleSizeY)) {
  44022. valRange.maxVisible = valRange.maxVisible ? valRange.maxVisible + rangeVisibleSizeY * maxIndent : undefined;
  44023. valRange.minVisible = valRange.minVisible ? valRange.minVisible - rangeVisibleSizeY * minIndent : undefined
  44024. }
  44025. valRange.invert = that._valueAxis.inverted
  44026. }
  44027. return {
  44028. arg: argRange,
  44029. val: valRange
  44030. }
  44031. },
  44032. getSeries: function() {
  44033. var that = this;
  44034. return that._series
  44035. },
  44036. getBackgroundColor: function() {
  44037. return this._backgroundColor
  44038. },
  44039. isEmpty: function() {
  44040. var that = this;
  44041. return that.getSeries().length === 0
  44042. },
  44043. isShowChart: function() {
  44044. var that = this;
  44045. return !that.isEmpty() && !that._hideChart
  44046. },
  44047. getCalculatedValueType: function() {
  44048. var that = this,
  44049. result;
  44050. if (that._series.length)
  44051. result = that._series[0].argumentType;
  44052. return result
  44053. },
  44054. getThemeManager: function() {
  44055. return this._themeManager
  44056. }
  44057. }
  44058. })(jQuery, DevExpress);
  44059. /*! Module viz-rangeselector, file themeManager.js */
  44060. (function($, DX, undefined) {
  44061. DX.viz.rangeSelector.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  44062. _themeSection: 'rangeSelector',
  44063. _fontFields: ['scale.label.font', 'sliderMarker.font', 'loadingIndicator.font']
  44064. })
  44065. })(jQuery, DevExpress);
  44066. DevExpress.MOD_VIZ_RANGESELECTOR = true
  44067. }
  44068. if (!DevExpress.MOD_VIZ_VECTORMAP) {
  44069. if (!DevExpress.MOD_VIZ_CORE)
  44070. throw Error('Required module is not referenced: viz-core');
  44071. /*! Module viz-vectormap, file map.js */
  44072. (function(DX, $, undefined) {
  44073. DX.viz.map = {};
  44074. var _parseScalar = DX.viz.core.utils.parseScalar,
  44075. DEFAULT_WIDTH = 800,
  44076. DEFAULT_HEIGHT = 400,
  44077. TOOLTIP_OFFSET = 12,
  44078. _extend = $.extend,
  44079. nextDataKey = 1;
  44080. function generateDataKey() {
  44081. return "vectormap-data-" + nextDataKey++
  44082. }
  44083. var Map = DX.viz.core.BaseWidget.inherit({
  44084. _eventsMap: _extend({}, DX.viz.core.BaseWidget.prototype._eventsMap, {
  44085. onClick: {
  44086. name: "click",
  44087. deprecated: "click",
  44088. deprecatedContext: function(arg) {
  44089. return arg.component
  44090. },
  44091. deprecatedArgs: function(arg) {
  44092. return [arg.jQueryEvent]
  44093. }
  44094. },
  44095. click: {newName: "onClick"},
  44096. onCenterChanged: {
  44097. name: "centerChanged",
  44098. deprecated: "centerChanged",
  44099. deprecatedContext: function(arg) {
  44100. return arg.component
  44101. },
  44102. deprecatedArgs: function(arg) {
  44103. return [arg.center]
  44104. }
  44105. },
  44106. centerChanged: {newName: "onCenterChanged"},
  44107. onZoomFactorChanged: {
  44108. name: "zoomFactorChanged",
  44109. deprecated: "zoomFactorChanged",
  44110. deprecatedContext: function(arg) {
  44111. return arg.component
  44112. },
  44113. deprecatedArgs: function(arg) {
  44114. return [arg.zoomFactor]
  44115. }
  44116. },
  44117. zoomFactorChanged: {newName: "onZoomFactorChanged"},
  44118. onAreaClick: {
  44119. name: "areaClick",
  44120. deprecated: "areaSettings.click",
  44121. deprecatedContext: function(arg) {
  44122. return arg.target
  44123. },
  44124. deprecatedArgs: function(arg) {
  44125. return [arg.target, arg.jQueryEvent]
  44126. }
  44127. },
  44128. onAreaHoverChanged: {name: "areaHoverChanged"},
  44129. onAreaSelectionChanged: {
  44130. name: "areaSelectionChanged",
  44131. deprecated: "areaSettings.selectionChanged",
  44132. deprecatedContext: function(arg) {
  44133. return arg.target
  44134. },
  44135. deprecatedArgs: function(arg) {
  44136. return [arg.target]
  44137. }
  44138. },
  44139. onMarkerClick: {
  44140. name: "markerClick",
  44141. deprecated: "markerSettings.click",
  44142. deprecatedContext: function(arg) {
  44143. return arg.target
  44144. },
  44145. deprecatedArgs: function(arg) {
  44146. return [arg.target, arg.jQueryEvent]
  44147. }
  44148. },
  44149. onMarkerHoverChanged: {name: "markerHoverChanged"},
  44150. onMarkerSelectionChanged: {
  44151. name: "markerSelectionChanged",
  44152. deprecated: "markerSettings.selectionChanged",
  44153. deprecatedContext: function(arg) {
  44154. return arg.target
  44155. },
  44156. deprecatedArgs: function(arg) {
  44157. return [arg.target]
  44158. }
  44159. }
  44160. }),
  44161. _setDeprecatedOptions: function() {
  44162. this.callBase();
  44163. $.extend(this._deprecatedOptions, {
  44164. click: {
  44165. since: "14.2",
  44166. message: 'Use the "onClick" option instead'
  44167. },
  44168. centerChanged: {
  44169. since: "14.2",
  44170. message: 'Use the "onCenterChanged" option instead'
  44171. },
  44172. zoomFactorChanged: {
  44173. since: "14.2",
  44174. message: 'Use the "onZoomFactorChanged" option instead'
  44175. },
  44176. "areaSettings.click": {
  44177. since: "14.2",
  44178. message: 'Use the "onAreaClick" option instead'
  44179. },
  44180. "areaSettings.selectionChanged": {
  44181. since: "14.2",
  44182. message: 'Use the "onAreaSelectionChanged" option instead'
  44183. },
  44184. "markerSettings.click": {
  44185. since: "14.2",
  44186. message: 'Use the "onMarkerClick" option instead'
  44187. },
  44188. "markerSettings.selectionChanged": {
  44189. since: "14.2",
  44190. message: 'Use the "onMarkerSelectionChanged" option instead'
  44191. },
  44192. "markerSettings.font": {
  44193. since: "14.2",
  44194. message: 'Use the "label.font" option instead'
  44195. }
  44196. })
  44197. },
  44198. _rootClassPrefix: "dxm",
  44199. _rootClass: "dxm-vector-map",
  44200. _createThemeManager: function() {
  44201. return this._factory.createThemeManager()
  44202. },
  44203. _initBackground: function(dataKey) {
  44204. this._background = this._renderer.rect(0, 0, 0, 0).attr({"class": "dxm-background"}).data(dataKey, {type: "background"})
  44205. },
  44206. _initAreasManager: function(dataKey, notifyDirty, notifyReady) {
  44207. var that = this;
  44208. that._areasManager = that._factory.createAreasManager({
  44209. container: that._root,
  44210. renderer: that._renderer,
  44211. projection: that._projection,
  44212. themeManager: that._themeManager,
  44213. tracker: that._tracker,
  44214. dataKey: dataKey,
  44215. eventTrigger: that._eventTrigger,
  44216. dataExchanger: that._dataExchanger,
  44217. notifyDirty: notifyDirty,
  44218. notifyReady: notifyReady
  44219. })
  44220. },
  44221. _initMarkersManager: function(dataKey, notifyDirty, notifyReady) {
  44222. var that = this;
  44223. that._markersManager = that._factory.createMarkersManager({
  44224. container: that._root,
  44225. renderer: that._renderer,
  44226. projection: that._projection,
  44227. themeManager: that._themeManager,
  44228. tracker: that._tracker,
  44229. eventTrigger: that._eventTrigger,
  44230. dataExchanger: that._dataExchanger,
  44231. dataKey: dataKey,
  44232. notifyDirty: notifyDirty,
  44233. notifyReady: notifyReady
  44234. })
  44235. },
  44236. _initLegendsControl: function() {
  44237. var that = this;
  44238. that._legendsControl = that._factory.createLegendsControl({
  44239. container: that._root,
  44240. renderer: that._renderer,
  44241. layoutControl: that._layoutControl,
  44242. dataExchanger: that._dataExchanger
  44243. })
  44244. },
  44245. _initControlBar: function(dataKey) {
  44246. var that = this;
  44247. that._controlBar = that._factory.createControlBar({
  44248. container: that._root,
  44249. renderer: that._renderer,
  44250. layoutControl: that._layoutControl,
  44251. projection: that._projection,
  44252. dataKey: dataKey
  44253. })
  44254. },
  44255. _initElements: function() {
  44256. var that = this,
  44257. dataKey = generateDataKey(),
  44258. notifyCounter = 0;
  44259. that._dataExchanger = new DataExchanger;
  44260. that._initCenterHandler();
  44261. that._projection = that._factory.createProjection();
  44262. that._tracker = that._factory.createTracker({
  44263. root: that._root,
  44264. projection: that._projection,
  44265. dataKey: dataKey
  44266. });
  44267. that._layoutControl = that._factory.createLayoutControl();
  44268. that._initBackground(dataKey);
  44269. that._initAreasManager(dataKey, notifyDirty, notifyReady);
  44270. that._initMarkersManager(dataKey, notifyDirty, notifyReady);
  44271. that._initLegendsControl();
  44272. that._initControlBar(dataKey);
  44273. function notifyDirty() {
  44274. that._resetIsReady();
  44275. ++notifyCounter
  44276. }
  44277. function notifyReady() {
  44278. if (--notifyCounter === 0) {
  44279. that._drawn();
  44280. that.hideLoadingIndicator()
  44281. }
  44282. }
  44283. },
  44284. _initCore: function() {
  44285. var that = this;
  44286. that._root = that._renderer.root;
  44287. that._root.attr({
  44288. align: 'center',
  44289. cursor: 'default'
  44290. });
  44291. that._initElements();
  44292. that._projection.setBounds(that.option("bounds")).setMaxZoom(that.option("maxZoomFactor")).setZoom(that.option("zoomFactor"), true).setCenter(that.option("center"), true);
  44293. that._setTrackerCallbacks();
  44294. that._setControlBarCallbacks();
  44295. that._setProjectionCallbacks()
  44296. },
  44297. _init: function() {
  44298. var that = this;
  44299. that.callBase.apply(that, arguments);
  44300. that._areasManager.setData(that.option("mapData"));
  44301. that._markersManager.setData(that.option("markers"))
  44302. },
  44303. _disposeCore: function() {
  44304. var that = this;
  44305. that._resetProjectionCallbacks();
  44306. that._resetTrackerCallbacks();
  44307. that._resetControlBarCallbacks();
  44308. that._tracker.dispose();
  44309. that._legendsControl.dispose();
  44310. that._areasManager.dispose();
  44311. that._markersManager.dispose();
  44312. that._controlBar.dispose();
  44313. that._layoutControl.dispose();
  44314. that._disposeCenterHandler();
  44315. that._dataExchanger.dispose();
  44316. that._projection.dispose();
  44317. that._dataExchanger = that._projection = that._tracker = that._layoutControl = that._root = that._background = that._areasManager = that._markersManager = that._controlBar = that._legendsControl = null
  44318. },
  44319. _initCenterHandler: function() {
  44320. var that = this,
  44321. xdrag,
  44322. ydrag,
  44323. isCursorChanged = false;
  44324. that._centerHandler = {
  44325. processStart: function(arg) {
  44326. if (that._centeringEnabled) {
  44327. xdrag = arg.x;
  44328. ydrag = arg.y;
  44329. that._noCenterChanged = true
  44330. }
  44331. },
  44332. processMove: function(arg) {
  44333. if (that._centeringEnabled) {
  44334. if (!isCursorChanged) {
  44335. that._root.attr({cursor: "move"});
  44336. isCursorChanged = true
  44337. }
  44338. that._projection.moveCenter(xdrag - arg.x, ydrag - arg.y);
  44339. xdrag = arg.x;
  44340. ydrag = arg.y
  44341. }
  44342. },
  44343. processEnd: function() {
  44344. if (that._centeringEnabled) {
  44345. that._root.attr({cursor: "default"});
  44346. that._noCenterChanged = null;
  44347. isCursorChanged && that._raiseCenterChanged();
  44348. isCursorChanged = false
  44349. }
  44350. }
  44351. }
  44352. },
  44353. _disposeCenterHandler: function() {
  44354. this._centerHandler = null
  44355. },
  44356. _setProjectionCallbacks: function() {
  44357. var that = this;
  44358. that._projection.on({
  44359. center: function() {
  44360. that._raiseCenterChanged()
  44361. },
  44362. zoom: function() {
  44363. that._raiseZoomFactorChanged()
  44364. }
  44365. });
  44366. that._resetProjectionCallbacks = function() {
  44367. that._resetProjectionCallbacks = that = null
  44368. }
  44369. },
  44370. _setTrackerCallbacks: function() {
  44371. var that = this,
  44372. centerHandler = that._centerHandler,
  44373. renderer = that._renderer,
  44374. managers = {
  44375. area: that._areasManager,
  44376. marker: that._markersManager
  44377. },
  44378. controlBar = that._controlBar,
  44379. tooltip = that._tooltip,
  44380. isControlDrag = false;
  44381. that._tracker.setCallbacks({
  44382. click: function(arg) {
  44383. var offset = renderer.getRootOffset(),
  44384. manager;
  44385. arg.$event.x = arg.x - offset.left;
  44386. arg.$event.y = arg.y - offset.top;
  44387. manager = managers[arg.data.type];
  44388. if (manager)
  44389. manager.raiseClick(arg.data.index, arg.$event);
  44390. if (manager || arg.data.type === "background")
  44391. that._eventTrigger("click", {jQueryEvent: arg.$event})
  44392. },
  44393. start: function(arg) {
  44394. isControlDrag = arg.data.type === "control-bar";
  44395. if (isControlDrag) {
  44396. arg.data = arg.data.index;
  44397. controlBar.processStart(arg)
  44398. }
  44399. else
  44400. centerHandler.processStart(arg)
  44401. },
  44402. move: function(arg) {
  44403. if (isControlDrag) {
  44404. arg.data = arg.data.index;
  44405. controlBar.processMove(arg)
  44406. }
  44407. else
  44408. centerHandler.processMove(arg)
  44409. },
  44410. end: function(arg) {
  44411. if (isControlDrag) {
  44412. arg.data = arg.data.index;
  44413. controlBar.processEnd(arg);
  44414. isControlDrag = false
  44415. }
  44416. else
  44417. centerHandler.processEnd()
  44418. },
  44419. zoom: function(arg) {
  44420. controlBar.processZoom(arg)
  44421. },
  44422. "hover-on": function(arg) {
  44423. var manager = managers[arg.data.type];
  44424. if (manager)
  44425. manager.hoverItem(arg.data.index, true)
  44426. },
  44427. "hover-off": function(arg) {
  44428. var manager = managers[arg.data.type];
  44429. if (manager)
  44430. manager.hoverItem(arg.data.index, false)
  44431. },
  44432. "focus-on": function(arg, done) {
  44433. var result = false,
  44434. proxy;
  44435. if (tooltip.isEnabled()) {
  44436. proxy = managers[arg.data.type] ? managers[arg.data.type].getProxyItem(arg.data.index) : null;
  44437. if (proxy && tooltip.show(proxy, {
  44438. x: 0,
  44439. y: 0,
  44440. offset: 0
  44441. }, {target: proxy})) {
  44442. tooltip.move(arg.x, arg.y, TOOLTIP_OFFSET);
  44443. result = true
  44444. }
  44445. }
  44446. done(result)
  44447. },
  44448. "focus-move": function(arg) {
  44449. tooltip.move(arg.x, arg.y, TOOLTIP_OFFSET)
  44450. },
  44451. "focus-off": function() {
  44452. tooltip.hide()
  44453. }
  44454. });
  44455. that._resetTrackerCallbacks = function() {
  44456. that._resetTrackerCallbacks = that = centerHandler = renderer = managers = controlBar = tooltip = null
  44457. }
  44458. },
  44459. _setControlBarCallbacks: function() {
  44460. var that = this,
  44461. projection = that._projection,
  44462. isZoomChanged;
  44463. that._projection.on({zoom: function() {
  44464. isZoomChanged = true
  44465. }});
  44466. that._controlBar.setCallbacks({
  44467. reset: function(isCenter, isZoom) {
  44468. if (isCenter)
  44469. projection.setCenter(null);
  44470. if (isZoom)
  44471. projection.setZoom(null)
  44472. },
  44473. beginMove: function() {
  44474. that._noCenterChanged = true
  44475. },
  44476. endMove: function() {
  44477. that._noCenterChanged = null;
  44478. that._raiseCenterChanged()
  44479. },
  44480. move: function(dx, dy) {
  44481. projection.moveCenter(dx, dy)
  44482. },
  44483. zoom: function(zoom, center) {
  44484. var coords,
  44485. screenPosition;
  44486. if (center) {
  44487. screenPosition = that._renderer.getRootOffset();
  44488. screenPosition = [center[0] - screenPosition.left, center[1] - screenPosition.top];
  44489. coords = projection.fromScreenPoint(screenPosition[0], screenPosition[1])
  44490. }
  44491. isZoomChanged = false;
  44492. projection.setScaledZoom(zoom);
  44493. if (isZoomChanged && center)
  44494. projection.setCenterByPoint(coords, screenPosition)
  44495. }
  44496. });
  44497. that._resetControlBarCallbacks = function() {
  44498. that._resetControlBarCallbacks = that = projection = null
  44499. }
  44500. },
  44501. _setupInteraction: function() {
  44502. var that = this;
  44503. that._centerHandler.processEnd();
  44504. that._centeringEnabled = !!_parseScalar(this._getOption("panningEnabled", true), true);
  44505. that._zoomingEnabled = !!_parseScalar(this._getOption("zoomingEnabled", true), true);
  44506. that._controlBar.setInteraction({
  44507. centeringEnabled: that._centeringEnabled,
  44508. zoomingEnabled: that._zoomingEnabled
  44509. })
  44510. },
  44511. _getDefaultSize: function() {
  44512. return {
  44513. width: DEFAULT_WIDTH,
  44514. height: DEFAULT_HEIGHT
  44515. }
  44516. },
  44517. _applySize: function() {
  44518. var that = this,
  44519. width = that._canvas.width,
  44520. height = that._canvas.height;
  44521. that._projection.setSize(width, height);
  44522. that._layoutControl.setSize(width, height);
  44523. that._background.attr({
  44524. x: 0,
  44525. y: 0,
  44526. width: width,
  44527. height: height
  44528. })
  44529. },
  44530. _resize: $.noop,
  44531. _clean: function() {
  44532. var that = this;
  44533. that._tracker.reset();
  44534. that._layoutControl.stop();
  44535. that._background.remove();
  44536. that._areasManager.clean();
  44537. that._markersManager.clean();
  44538. that._controlBar.clean();
  44539. that._legendsControl.clean()
  44540. },
  44541. _render: function() {
  44542. var that = this;
  44543. that._background.append(that._root);
  44544. that._areasManager.render();
  44545. that._markersManager.render();
  44546. that._controlBar.render();
  44547. that._legendsControl.render();
  44548. that._layoutControl.start()
  44549. },
  44550. _optionChanged: function(args) {
  44551. var that = this,
  44552. value = args.value;
  44553. switch (args.name) {
  44554. case"mapData":
  44555. that._areasManager.setData(value);
  44556. break;
  44557. case"markers":
  44558. that._markersManager.setData(value);
  44559. break;
  44560. case"bounds":
  44561. that._projection.setBounds(value);
  44562. break;
  44563. case"maxZoomFactor":
  44564. that._projection.setMaxZoom(value);
  44565. break;
  44566. case"zoomFactor":
  44567. that._projection.setZoom(value);
  44568. break;
  44569. case"center":
  44570. that._projection.setCenter(value);
  44571. break;
  44572. case"background":
  44573. that._setBackgroundOptions();
  44574. break;
  44575. case"areaSettings":
  44576. that._setAreasManagerOptions();
  44577. break;
  44578. case"markerSettings":
  44579. that._setMarkersManagerOptions();
  44580. break;
  44581. case"controlBar":
  44582. that._setControlBarOptions();
  44583. break;
  44584. case"legends":
  44585. that._setLegendsOptions();
  44586. break;
  44587. case"touchEnabled":
  44588. case"wheelEnabled":
  44589. that._setTrackerOptions();
  44590. break;
  44591. case"panningEnabled":
  44592. case"zoomingEnabled":
  44593. that._setupInteraction();
  44594. break;
  44595. default:
  44596. that.callBase.apply(that, arguments);
  44597. break
  44598. }
  44599. },
  44600. _handleThemeOptionsCore: function() {
  44601. var that = this;
  44602. that._setBackgroundOptions();
  44603. that._setAreasManagerOptions();
  44604. that._setMarkersManagerOptions();
  44605. that._setControlBarOptions();
  44606. that._setLegendsOptions();
  44607. that._setTrackerOptions();
  44608. that._setupInteraction()
  44609. },
  44610. _setBackgroundOptions: function() {
  44611. var settings = this._getOption("background");
  44612. this._background.attr({
  44613. "stroke-width": settings.borderWidth,
  44614. stroke: settings.borderColor,
  44615. fill: settings.color
  44616. })
  44617. },
  44618. _setAreasManagerOptions: function() {
  44619. this._areasManager.setOptions(this.option("areaSettings"));
  44620. this._eventTrigger.update("onAreaClick");
  44621. this._eventTrigger.update("onAreaSelectionChanged")
  44622. },
  44623. _setMarkersManagerOptions: function() {
  44624. this._markersManager.setOptions(this.option("markerSettings"));
  44625. this._eventTrigger.update("onMarkerClick");
  44626. this._eventTrigger.update("onMarkerSelectionChanged")
  44627. },
  44628. _setControlBarOptions: function() {
  44629. this._controlBar.setOptions(this._getOption("controlBar"))
  44630. },
  44631. _setLegendsOptions: function() {
  44632. this._legendsControl.setOptions(this.option("legends"), this._themeManager.theme("legend"))
  44633. },
  44634. _setTrackerOptions: function() {
  44635. this._tracker.setOptions({
  44636. touchEnabled: this._getOption("touchEnabled", true),
  44637. wheelEnabled: this._getOption("wheelEnabled", true)
  44638. })
  44639. },
  44640. _raiseCenterChanged: function() {
  44641. !this._noCenterChanged && this._eventTrigger("centerChanged", {center: this._projection.getCenter()})
  44642. },
  44643. _raiseZoomFactorChanged: function() {
  44644. !this._noZoomFactorChanged && this._eventTrigger("zoomFactorChanged", {zoomFactor: this._projection.getZoom()})
  44645. },
  44646. _refresh: function() {
  44647. var that = this,
  44648. callBase = that.callBase;
  44649. that._endLoading(function() {
  44650. callBase.call(that)
  44651. })
  44652. },
  44653. getAreas: function() {
  44654. return this._areasManager.getProxyItems()
  44655. },
  44656. getMarkers: function() {
  44657. return this._markersManager.getProxyItems()
  44658. },
  44659. clearAreaSelection: function(_noEvent) {
  44660. this._areasManager.clearSelection(_noEvent);
  44661. return this
  44662. },
  44663. clearMarkerSelection: function(_noEvent) {
  44664. this._markersManager.clearSelection(_noEvent);
  44665. return this
  44666. },
  44667. clearSelection: function(_noEvent) {
  44668. return this.clearAreaSelection(_noEvent).clearMarkerSelection(_noEvent)
  44669. },
  44670. center: function(value, _noEvent) {
  44671. var that = this;
  44672. if (value === undefined)
  44673. return that._projection.getCenter();
  44674. else {
  44675. that._noCenterChanged = _noEvent;
  44676. that._projection.setCenter(value);
  44677. that._noCenterChanged = null;
  44678. return that
  44679. }
  44680. },
  44681. zoomFactor: function(value, _noEvent) {
  44682. var that = this;
  44683. if (value === undefined)
  44684. return that._projection.getZoom();
  44685. else {
  44686. that._noZoomFactorChanged = _noEvent;
  44687. that._projection.setZoom(value);
  44688. that._noZoomFactorChanged = null;
  44689. return that
  44690. }
  44691. },
  44692. viewport: function(value, _noEvent) {
  44693. var that = this;
  44694. if (value === undefined)
  44695. return that._projection.getViewport();
  44696. else {
  44697. that._noCenterChanged = that._noZoomFactorChanged = _noEvent;
  44698. that._projection.setViewport(value);
  44699. that._noCenterChanged = that._noZoomFactorChanged = null;
  44700. return that
  44701. }
  44702. },
  44703. convertCoordinates: function(x, y) {
  44704. return this._projection.fromScreenPoint(x, y)
  44705. },
  44706. _factory: {}
  44707. });
  44708. var DataExchanger = function() {
  44709. this._store = {}
  44710. };
  44711. DataExchanger.prototype = {
  44712. constructor: DataExchanger,
  44713. dispose: function() {
  44714. this._store = null;
  44715. return this
  44716. },
  44717. _get: function(category, name) {
  44718. var store = this._store[category] || (this._store[category] = {});
  44719. return store[name] || (store[name] = {})
  44720. },
  44721. set: function(category, name, data) {
  44722. var item = this._get(category, name);
  44723. item.data = data;
  44724. item.callback && item.callback(data);
  44725. return this
  44726. },
  44727. bind: function(category, name, callback) {
  44728. var item = this._get(category, name);
  44729. item.callback = callback;
  44730. item.data && callback(item.data);
  44731. return this
  44732. },
  44733. unbind: function(category, name) {
  44734. var item = this._get(category, name);
  44735. item.data = item.callback = null;
  44736. return this
  44737. }
  44738. };
  44739. DX.registerComponent("dxVectorMap", DX.viz.map, Map);
  44740. DX.viz.map._internal = {};
  44741. DX.viz.map.sources = {};
  44742. DX.viz.map._tests = {};
  44743. DX.viz.map._tests.DataExchanger = DataExchanger;
  44744. DX.viz.map._tests.stubDataExchanger = function(stub) {
  44745. DataExchanger = stub
  44746. }
  44747. })(DevExpress, jQuery);
  44748. /*! Module viz-vectormap, file projection.js */
  44749. (function(DX, $, undefined) {
  44750. var _Number = Number,
  44751. _isArray = DX.utils.isArray,
  44752. _math = Math,
  44753. _min = _math.min,
  44754. _max = _math.max,
  44755. _abs = _math.abs,
  44756. _tan = _math.tan,
  44757. _atan = _math.atan,
  44758. _exp = _math.exp,
  44759. _round = _math.round,
  44760. _ln = _math.log,
  44761. _pow = _math.pow,
  44762. PI = _math.PI,
  44763. QUARTER_PI = PI / 4,
  44764. PI_TO_360 = PI / 360,
  44765. TWO_TO_LN2 = 2 / _math.LN2,
  44766. MIN_BOUNDS_RANGE = 1 / 3600 / 180 / 10,
  44767. DEFAULT_MIN_ZOOM = 1,
  44768. DEFAULT_MAX_ZOOM = 1 << 8,
  44769. MERCATOR_MIN_LON = -180,
  44770. MERCATOR_MAX_LON = 180,
  44771. MERCATOR_MIN_LAT = -85.0511,
  44772. MERCATOR_MAX_LAT = 85.0511;
  44773. var mercator = {
  44774. aspectRatio: 1,
  44775. project: function(coordinates) {
  44776. var lon = coordinates[0],
  44777. lat = coordinates[1];
  44778. return [lon <= MERCATOR_MIN_LON ? -1 : lon >= MERCATOR_MAX_LON ? +1 : lon / 180, lat <= MERCATOR_MIN_LAT ? +1 : lat >= MERCATOR_MAX_LAT ? -1 : -_ln(_tan(QUARTER_PI + lat * PI_TO_360)) / PI]
  44779. },
  44780. unproject: function(coordinates) {
  44781. var x = coordinates[0],
  44782. y = coordinates[1];
  44783. return [x <= -1 ? MERCATOR_MIN_LON : x >= +1 ? MERCATOR_MAX_LON : 180 * x, y <= -1 ? MERCATOR_MAX_LAT : y >= +1 ? MERCATOR_MIN_LAT : (_atan(_exp(-PI * coordinates[1])) - QUARTER_PI) / PI_TO_360]
  44784. }
  44785. };
  44786. function createProjectUnprojectMethods(p1, p2, delta) {
  44787. var x0 = (p1[0] + p2[0]) / 2 - delta / 2,
  44788. y0 = (p1[1] + p2[1]) / 2 - delta / 2,
  44789. k = 2 / delta;
  44790. return {
  44791. project: function(coordinates) {
  44792. var p = mercator.project(coordinates);
  44793. return [-1 + (p[0] - x0) * k, -1 + (p[1] - y0) * k]
  44794. },
  44795. unproject: function(coordinates) {
  44796. var p = [x0 + (coordinates[0] + 1) / k, y0 + (coordinates[1] + 1) / k];
  44797. return mercator.unproject(p)
  44798. }
  44799. }
  44800. }
  44801. function floatsEqual(f1, f2) {
  44802. return _abs(f1 - f2) < 1E-8
  44803. }
  44804. function truncate(value, min, max, fallback) {
  44805. var _value = _Number(value);
  44806. if (_value < min)
  44807. _value = min;
  44808. else if (_value > max)
  44809. _value = max;
  44810. else if (!(min <= _value && _value <= max))
  44811. _value = fallback;
  44812. return _value
  44813. }
  44814. function truncateQuad(quad, min, max) {
  44815. return {
  44816. lt: [truncate(quad[0], min[0], max[0], min[0]), truncate(quad[1], min[1], max[1], min[1])],
  44817. rb: [truncate(quad[2], min[0], max[0], max[0]), truncate(quad[3], min[1], max[1], max[1])]
  44818. }
  44819. }
  44820. function parseBounds(bounds) {
  44821. var p1 = mercator.unproject([-1, -1]),
  44822. p2 = mercator.unproject([+1, +1]),
  44823. min = [_min(p1[0], p2[0]), _min(p1[1], p2[1])],
  44824. max = [_max(p1[0], p2[0]), _max(p1[1], p2[1])],
  44825. quad = bounds;
  44826. if (quad)
  44827. quad = truncateQuad(quad, min, max);
  44828. return {
  44829. min: quad ? [_min(quad.lt[0], quad.rb[0]), _min(quad.lt[1], quad.rb[1])] : min,
  44830. max: quad ? [_max(quad.lt[0], quad.rb[0]), _max(quad.lt[1], quad.rb[1])] : max
  44831. }
  44832. }
  44833. function selectCenterValue(value1, value2, center1, center2) {
  44834. var result;
  44835. if (value1 > -1 && value2 >= +1)
  44836. result = center1;
  44837. else if (value1 <= -1 && value2 < +1)
  44838. result = center2;
  44839. else
  44840. result = (center1 + center2) / 2;
  44841. return result
  44842. }
  44843. function Projection() {
  44844. this._events = {
  44845. project: $.Callbacks(),
  44846. transform: $.Callbacks(),
  44847. center: $.Callbacks(),
  44848. zoom: $.Callbacks(),
  44849. "max-zoom": $.Callbacks()
  44850. };
  44851. this.setBounds(null)
  44852. }
  44853. Projection.prototype = {
  44854. constructor: Projection,
  44855. _minZoom: DEFAULT_MIN_ZOOM,
  44856. _maxZoom: DEFAULT_MAX_ZOOM,
  44857. _zoom: DEFAULT_MIN_ZOOM,
  44858. _center: [NaN, NaN],
  44859. dispose: function() {
  44860. this._events = null;
  44861. return this
  44862. },
  44863. setSize: function(width, height) {
  44864. var that = this;
  44865. that._x0 = width / 2;
  44866. that._y0 = height / 2;
  44867. if (width / height <= mercator.aspectRatio) {
  44868. that._xradius = width / 2;
  44869. that._yradius = width / 2 / mercator.aspectRatio
  44870. }
  44871. else {
  44872. that._xradius = height / 2 * mercator.aspectRatio;
  44873. that._yradius = height / 2
  44874. }
  44875. that._events["transform"].fire(that.getTransform());
  44876. return that
  44877. },
  44878. setBounds: function(bounds) {
  44879. var that = this,
  44880. _bounds = parseBounds(bounds),
  44881. p1,
  44882. p2,
  44883. delta,
  44884. methods;
  44885. that._minBound = _bounds.min;
  44886. that._maxBound = _bounds.max;
  44887. p1 = mercator.project(_bounds.min);
  44888. p2 = mercator.project(_bounds.max);
  44889. delta = [_abs(p2[0] - p1[0]), _abs(p2[1] - p1[1])];
  44890. delta = _min(delta[0] > MIN_BOUNDS_RANGE ? delta[0] : 2, delta[1] > MIN_BOUNDS_RANGE ? delta[1] : 2);
  44891. methods = delta < 2 ? createProjectUnprojectMethods(p1, p2, delta) : mercator;
  44892. that._project = methods.project;
  44893. that._unproject = methods.unproject;
  44894. that._defaultCenter = that._unproject([0, 0]);
  44895. that.setCenter(that._defaultCenter);
  44896. that._events.project.fire();
  44897. return that
  44898. },
  44899. _toScreen: function(coordinates) {
  44900. return [this._x0 + this._xradius * coordinates[0], this._y0 + this._yradius * coordinates[1]]
  44901. },
  44902. _fromScreen: function(coordinates) {
  44903. return [(coordinates[0] - this._x0) / this._xradius, (coordinates[1] - this._y0) / this._yradius]
  44904. },
  44905. _toTransformed: function(coordinates) {
  44906. return [coordinates[0] * this._zoom + this._dxcenter, coordinates[1] * this._zoom + this._dycenter]
  44907. },
  44908. _toTransformedFast: function(coordinates) {
  44909. return [coordinates[0] * this._zoom, coordinates[1] * this._zoom]
  44910. },
  44911. _fromTransformed: function(coordinates) {
  44912. return [(coordinates[0] - this._dxcenter) / this._zoom, (coordinates[1] - this._dycenter) / this._zoom]
  44913. },
  44914. _adjustCenter: function() {
  44915. var that = this,
  44916. center = that._project(that._center);
  44917. that._dxcenter = -center[0] * that._zoom;
  44918. that._dycenter = -center[1] * that._zoom
  44919. },
  44920. projectArea: function(coordinates) {
  44921. var i = 0,
  44922. ii = _isArray(coordinates) ? coordinates.length : 0,
  44923. subcoords,
  44924. j,
  44925. jj,
  44926. subresult,
  44927. result = [];
  44928. for (; i < ii; ++i) {
  44929. subcoords = coordinates[i];
  44930. subresult = [];
  44931. for (j = 0, jj = _isArray(subcoords) ? subcoords.length : 0; j < jj; ++j)
  44932. subresult.push(this._project(subcoords[j]));
  44933. result.push(subresult)
  44934. }
  44935. return result
  44936. },
  44937. projectPoint: function(coordinates) {
  44938. return coordinates ? this._project(coordinates) : []
  44939. },
  44940. getAreaCoordinates: function(data) {
  44941. var k = 0,
  44942. kk = data.length,
  44943. partialData,
  44944. i,
  44945. ii,
  44946. list = [],
  44947. partialPath,
  44948. point;
  44949. for (; k < kk; ++k) {
  44950. partialData = data[k];
  44951. partialPath = [];
  44952. for (i = 0, ii = partialData.length; i < ii; ++i) {
  44953. point = this._toScreen(this._toTransformedFast(partialData[i]));
  44954. partialPath.push(point[0], point[1])
  44955. }
  44956. list.push(partialPath)
  44957. }
  44958. return list
  44959. },
  44960. getPointCoordinates: function(data) {
  44961. var point = this._toScreen(this._toTransformedFast(data));
  44962. return {
  44963. x: _round(point[0]),
  44964. y: _round(point[1])
  44965. }
  44966. },
  44967. getSquareSize: function(size) {
  44968. return [size[0] * this._zoom * this._xradius, size[1] * this._zoom * this._yradius]
  44969. },
  44970. getZoom: function() {
  44971. return this._zoom
  44972. },
  44973. setZoom: function(zoom, _forceEvent) {
  44974. var that = this,
  44975. zoom__ = that._zoom;
  44976. that._zoom = truncate(zoom, that._minZoom, that._maxZoom, that._minZoom);
  44977. that._adjustCenter();
  44978. if (!floatsEqual(zoom__, that._zoom) || _forceEvent)
  44979. that._events.zoom.fire(that.getZoom(), that.getTransform());
  44980. return that
  44981. },
  44982. getScaledZoom: function() {
  44983. return _round((this._scale.length - 1) * _ln(this._zoom) / _ln(this._maxZoom))
  44984. },
  44985. setScaledZoom: function(scaledZoom) {
  44986. return this.setZoom(this._scale[_round(scaledZoom)])
  44987. },
  44988. getZoomScalePartition: function() {
  44989. return this._scale.length - 1
  44990. },
  44991. _setupScaling: function() {
  44992. var that = this,
  44993. k = _round(TWO_TO_LN2 * _ln(that._maxZoom)),
  44994. step,
  44995. zoom,
  44996. i = 1;
  44997. k = k > 4 ? k : 4;
  44998. step = _pow(that._maxZoom, 1 / k);
  44999. zoom = that._minZoom;
  45000. that._scale = [zoom];
  45001. for (; i <= k; ++i)
  45002. that._scale.push(zoom *= step)
  45003. },
  45004. setMaxZoom: function(maxZoom) {
  45005. var that = this;
  45006. that._minZoom = DEFAULT_MIN_ZOOM;
  45007. that._maxZoom = truncate(maxZoom, that._minZoom, _Number.MAX_VALUE, DEFAULT_MAX_ZOOM);
  45008. that._setupScaling();
  45009. if (that._zoom > that._maxZoom)
  45010. that.setZoom(that._maxZoom);
  45011. that._events["max-zoom"].fire(that._maxZoom);
  45012. return that
  45013. },
  45014. getMinZoom: function() {
  45015. return this._minZoom
  45016. },
  45017. getMaxZoom: function() {
  45018. return this._maxZoom
  45019. },
  45020. getCenter: function() {
  45021. return [this._center[0], this._center[1]]
  45022. },
  45023. setCenter: function(center, _forceEvent) {
  45024. var that = this,
  45025. _center = _isArray(center) ? center : [],
  45026. center__ = that._center;
  45027. that._center = [truncate(_center[0], that._minBound[0], that._maxBound[0], that._defaultCenter[0]), truncate(_center[1], that._minBound[1], that._maxBound[1], that._defaultCenter[1])];
  45028. that._adjustCenter();
  45029. if (!floatsEqual(center__[0], that._center[0]) || !floatsEqual(center__[1], that._center[1]) || _forceEvent)
  45030. that._events.center.fire(that.getCenter(), that.getTransform());
  45031. return that
  45032. },
  45033. setCenterByPoint: function(coordinates, screenPosition) {
  45034. var that = this,
  45035. p = that._project(coordinates),
  45036. q = that._fromScreen(screenPosition);
  45037. return that.setCenter(that._unproject([-q[0] / that._zoom + p[0], -q[1] / that._zoom + p[1]]))
  45038. },
  45039. moveCenter: function(screenDx, screenDy) {
  45040. var that = this,
  45041. current = that._toScreen(that._toTransformed(that._project(that._center))),
  45042. center = that._unproject(that._fromTransformed(that._fromScreen([current[0] + screenDx, current[1] + screenDy])));
  45043. return that.setCenter(center)
  45044. },
  45045. getViewport: function() {
  45046. var p1 = this._unproject(this._fromTransformed([-1, -1])),
  45047. p2 = this._unproject(this._fromTransformed([+1, +1]));
  45048. return [p1[0], p1[1], p2[0], p2[1]]
  45049. },
  45050. setViewport: function(viewport) {
  45051. var that = this;
  45052. if (!_isArray(viewport))
  45053. return that.setZoom(that._minZoom).setCenter(that._defaultCenter);
  45054. var _viewport = truncateQuad(viewport, that._minBound, that._maxBound),
  45055. lt = that._project(_viewport.lt),
  45056. rb = that._project(_viewport.rb),
  45057. l = _min(lt[0], rb[0]),
  45058. t = _min(lt[1], rb[1]),
  45059. r = _max(lt[0], rb[0]),
  45060. b = _max(lt[1], rb[1]),
  45061. zoom = 2 / _max(r - l, b - t),
  45062. xc = selectCenterValue(l, r, -1 - zoom * l, +1 - zoom * r),
  45063. yc = selectCenterValue(t, b, -1 - zoom * t, +1 - zoom * b);
  45064. return that.setZoom(zoom).setCenter(that._unproject([-xc / zoom, -yc / zoom]))
  45065. },
  45066. getTransform: function() {
  45067. return {
  45068. translateX: this._dxcenter * this._xradius,
  45069. translateY: this._dycenter * this._yradius
  45070. }
  45071. },
  45072. fromScreenPoint: function(x, y) {
  45073. return this._unproject(this._fromTransformed(this._fromScreen([x, y])))
  45074. },
  45075. on: function(obj) {
  45076. $.each(this._events, function(name, list) {
  45077. obj[name] && list.add(obj[name])
  45078. });
  45079. return this
  45080. }
  45081. };
  45082. DX.viz.map._tests.Projection = Projection;
  45083. DX.viz.map._tests.mercator = mercator;
  45084. DX.viz.map._tests._DEBUG_stubMercator = function(stub) {
  45085. mercator = stub
  45086. };
  45087. DX.viz.map._tests._DEBUG_restoreMercator = function() {
  45088. mercator = DX.viz.map._tests.mercator
  45089. };
  45090. DX.viz.map.dxVectorMap.prototype._factory.createProjection = function() {
  45091. return new Projection
  45092. }
  45093. })(DevExpress, jQuery);
  45094. /*! Module viz-vectormap, file controlBar.js */
  45095. (function(DX, undefined) {
  45096. var _Number = Number,
  45097. _math = Math,
  45098. _round = _math.round,
  45099. _floor = _math.floor,
  45100. _pow = _math.pow,
  45101. _ln = _math.log,
  45102. _LN2 = _math.LN2,
  45103. utils = DX.viz.core.utils,
  45104. _parseScalar = utils.parseScalar,
  45105. parseHorizontalAlignment = utils.enumParser(["left", "center", "right"]),
  45106. parseVerticalAlignment = utils.enumParser(["top", "bottom"]),
  45107. COMMAND_RESET = "command-reset",
  45108. COMMAND_MOVE_UP = "command-move-up",
  45109. COMMAND_MOVE_RIGHT = "command-move-right",
  45110. COMMAND_MOVE_DOWN = "command-move-down",
  45111. COMMAND_MOVE_LEFT = "command-move-left",
  45112. COMMAND_ZOOM_IN = "command-zoom-in",
  45113. COMMAND_ZOOM_OUT = "command-zoom-out",
  45114. COMMAND_ZOOM_DRAG_LINE = "command-zoom-drag-line",
  45115. COMMAND_ZOOM_DRAG = "command-zoom-drag",
  45116. EVENT_TARGET_TYPE = "control-bar",
  45117. FLAG_CENTERING = 1,
  45118. FLAG_ZOOMING = 2,
  45119. SIZE_OPTIONS = {
  45120. bigCircleSize: 58,
  45121. smallCircleSize: 28,
  45122. buttonSize: 10,
  45123. arrowButtonOffset: 20,
  45124. incdecButtonSize: 11,
  45125. incButtonOffset: 66,
  45126. decButtonOffset: 227,
  45127. sliderLineStartOffset: 88.5,
  45128. sliderLineEndOffset: 205.5,
  45129. sliderLength: 20,
  45130. sliderWidth: 8,
  45131. trackerGap: 4
  45132. },
  45133. OFFSET_X = 30.5,
  45134. OFFSET_Y = 30.5,
  45135. TOTAL_WIDTH = 61,
  45136. TOTAL_HEIGHT = 274,
  45137. COMMAND_TO_TYPE_MAP = {};
  45138. COMMAND_TO_TYPE_MAP[COMMAND_RESET] = ResetCommand;
  45139. COMMAND_TO_TYPE_MAP[COMMAND_MOVE_UP] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_RIGHT] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_DOWN] = COMMAND_TO_TYPE_MAP[COMMAND_MOVE_LEFT] = MoveCommand;
  45140. COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_IN] = COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_OUT] = ZoomCommand;
  45141. COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_DRAG] = ZoomDragCommand;
  45142. var ControlBar = DX.Class.inherit({
  45143. _flags: 0,
  45144. ctor: function(parameters) {
  45145. var that = this;
  45146. that._params = parameters;
  45147. that._createElements(parameters.renderer, parameters.dataKey);
  45148. parameters.layoutControl.addItem(that);
  45149. that._subscribeToProjection(parameters.projection);
  45150. that._setVisibility(false)
  45151. },
  45152. setCallbacks: function(callbacks) {
  45153. this._callbacks = callbacks;
  45154. return this
  45155. },
  45156. _createElements: function(renderer, dataKey) {
  45157. var that = this,
  45158. buttonsGroups,
  45159. trackersGroup;
  45160. that._root = renderer.g().attr({"class": "dxm-control-bar"});
  45161. buttonsGroups = that._buttonsGroup = renderer.g().attr({"class": "dxm-control-buttons"}).append(that._root);
  45162. trackersGroup = renderer.g().attr({
  45163. stroke: "none",
  45164. "stroke-width": 0,
  45165. fill: "#000000",
  45166. opacity: 0.0001
  45167. }).css({cursor: "pointer"}).append(that._root);
  45168. that._createButtons(renderer, dataKey, buttonsGroups);
  45169. that._createTrackers(renderer, dataKey, trackersGroup)
  45170. },
  45171. _createButtons: function(renderer, dataKey, group) {
  45172. var that = this,
  45173. options = SIZE_OPTIONS,
  45174. size = options.buttonSize / 2,
  45175. offset1 = options.arrowButtonOffset - size,
  45176. offset2 = options.arrowButtonOffset,
  45177. incdecButtonSize = options.incdecButtonSize / 2,
  45178. directionOptions = {
  45179. "stroke-linecap": "square",
  45180. fill: "none"
  45181. },
  45182. line = "line";
  45183. renderer.circle(0, 0, options.bigCircleSize / 2).append(group);
  45184. renderer.circle(0, 0, size).attr({fill: "none"}).append(group);
  45185. renderer.path([-size, -offset1, 0, -offset2, size, -offset1], line).attr(directionOptions).append(group);
  45186. renderer.path([offset1, -size, offset2, 0, offset1, size], line).attr(directionOptions).append(group);
  45187. renderer.path([size, offset1, 0, offset2, -size, offset1], line).attr(directionOptions).append(group);
  45188. renderer.path([-offset1, size, -offset2, 0, -offset1, -size], line).attr(directionOptions).append(group);
  45189. renderer.circle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group);
  45190. renderer.path([[-incdecButtonSize, options.incButtonOffset, incdecButtonSize, options.incButtonOffset], [0, options.incButtonOffset - incdecButtonSize, 0, options.incButtonOffset + incdecButtonSize]], "area").append(group);
  45191. renderer.circle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group);
  45192. renderer.path([-incdecButtonSize, options.decButtonOffset, incdecButtonSize, options.decButtonOffset], "area").append(group);
  45193. that._progressBar = renderer.path([], "area").append(group);
  45194. that._zoomDrag = renderer.rect(_floor(-options.sliderLength / 2), _floor(options.sliderLineEndOffset - options.sliderWidth / 2), options.sliderLength, options.sliderWidth).append(group);
  45195. that._sliderLineLength = options.sliderLineEndOffset - options.sliderLineStartOffset
  45196. },
  45197. _createTrackers: function(renderer, dataKey, group) {
  45198. var options = SIZE_OPTIONS,
  45199. size = _round((options.arrowButtonOffset - options.trackerGap) / 2),
  45200. offset1 = options.arrowButtonOffset - size,
  45201. offset2 = _round(_pow(options.bigCircleSize * options.bigCircleSize / 4 - size * size, 0.5)),
  45202. size2 = offset2 - offset1;
  45203. renderer.rect(-size, -size, size * 2, size * 2).data(dataKey, {
  45204. index: COMMAND_RESET,
  45205. type: EVENT_TARGET_TYPE
  45206. }).append(group);
  45207. renderer.rect(-size, -offset2, size * 2, size2).data(dataKey, {
  45208. index: COMMAND_MOVE_UP,
  45209. type: EVENT_TARGET_TYPE
  45210. }).append(group);
  45211. renderer.rect(offset1, -size, size2, size * 2).data(dataKey, {
  45212. index: COMMAND_MOVE_RIGHT,
  45213. type: EVENT_TARGET_TYPE
  45214. }).append(group);
  45215. renderer.rect(-size, offset1, size * 2, size2).data(dataKey, {
  45216. index: COMMAND_MOVE_DOWN,
  45217. type: EVENT_TARGET_TYPE
  45218. }).append(group);
  45219. renderer.rect(-offset2, -size, size2, size * 2).data(dataKey, {
  45220. index: COMMAND_MOVE_LEFT,
  45221. type: EVENT_TARGET_TYPE
  45222. }).append(group);
  45223. renderer.circle(0, options.incButtonOffset, options.smallCircleSize / 2).data(dataKey, {
  45224. index: COMMAND_ZOOM_IN,
  45225. type: EVENT_TARGET_TYPE
  45226. }).append(group);
  45227. renderer.circle(0, options.decButtonOffset, options.smallCircleSize / 2).data(dataKey, {
  45228. index: COMMAND_ZOOM_OUT,
  45229. type: EVENT_TARGET_TYPE
  45230. }).append(group);
  45231. renderer.rect(-2, options.sliderLineStartOffset - 2, 4, options.sliderLineEndOffset - options.sliderLineStartOffset + 4).css({cursor: "default"}).data(dataKey, {
  45232. index: COMMAND_ZOOM_DRAG_LINE,
  45233. type: EVENT_TARGET_TYPE
  45234. }).append(group);
  45235. this._zoomDragCover = renderer.rect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).data(dataKey, {
  45236. index: COMMAND_ZOOM_DRAG,
  45237. type: EVENT_TARGET_TYPE
  45238. }).append(group)
  45239. },
  45240. _subscribeToProjection: function(projection) {
  45241. var that = this;
  45242. projection.on({
  45243. zoom: function() {
  45244. that._adjustZoom(projection.getScaledZoom())
  45245. },
  45246. "max-zoom": function() {
  45247. that._zoomPartition = projection.getZoomScalePartition();
  45248. that._sliderUnitLength = that._sliderLineLength / that._zoomPartition;
  45249. that._adjustZoom(projection.getScaledZoom())
  45250. }
  45251. })
  45252. },
  45253. dispose: function() {
  45254. var that = this;
  45255. that._params.layoutControl.removeItem(that);
  45256. that._root.clear();
  45257. that._params = that._callbacks = that._root = that._buttonsGroup = that._zoomDrag = that._zoomDragCover = that._progressBar = null;
  45258. return that
  45259. },
  45260. resize: function(size) {
  45261. this._setVisibility(size !== null && this._options.enabled && this._flags);
  45262. return this
  45263. },
  45264. _setVisibility: function(state) {
  45265. this._root.attr({visibility: state ? null : "hidden"})
  45266. },
  45267. getLayoutOptions: function() {
  45268. var options = this._options;
  45269. return this._rendered && options.enabled && this._flags ? {
  45270. width: 2 * options.margin + TOTAL_WIDTH,
  45271. height: 2 * options.margin + TOTAL_HEIGHT,
  45272. horizontalAlignment: options.horizontalAlignment,
  45273. verticalAlignment: options.verticalAlignment
  45274. } : null
  45275. },
  45276. locate: function(x, y) {
  45277. this._root.attr({
  45278. translateX: x + this._options.margin + OFFSET_X,
  45279. translateY: y + this._options.margin + OFFSET_Y
  45280. });
  45281. return this
  45282. },
  45283. setInteraction: function(interaction) {
  45284. var that = this;
  45285. that.processEnd();
  45286. if (_parseScalar(interaction.centeringEnabled, true))
  45287. that._flags |= FLAG_CENTERING;
  45288. else
  45289. that._flags &= ~FLAG_CENTERING;
  45290. if (_parseScalar(interaction.zoomingEnabled, true))
  45291. that._flags |= FLAG_ZOOMING;
  45292. else
  45293. that._flags &= ~FLAG_ZOOMING;
  45294. if (that._rendered)
  45295. that._refresh();
  45296. return that
  45297. },
  45298. setOptions: function(options) {
  45299. var that = this;
  45300. that.processEnd();
  45301. that._buttonsGroup.attr({
  45302. "stroke-width": options.borderWidth,
  45303. stroke: options.borderColor,
  45304. fill: options.color,
  45305. "fill-opacity": options.opacity
  45306. });
  45307. that._options = {
  45308. enabled: !!_parseScalar(options.enabled, true),
  45309. margin: options.margin > 0 ? _Number(options.margin) : 0,
  45310. horizontalAlignment: parseHorizontalAlignment(options.horizontalAlignment, "left"),
  45311. verticalAlignment: parseVerticalAlignment(options.verticalAlignment, "top")
  45312. };
  45313. that._rendered && that._refresh();
  45314. return that
  45315. },
  45316. _refresh: function() {
  45317. var isVisible = this._flags && this._options.enabled;
  45318. this._setVisibility(isVisible);
  45319. if (isVisible)
  45320. this.updateLayout()
  45321. },
  45322. clean: function() {
  45323. var that = this;
  45324. that._rendered = null;
  45325. that._root.remove();
  45326. return that
  45327. },
  45328. render: function() {
  45329. var that = this;
  45330. that._rendered = true;
  45331. that._root.append(that._params.container);
  45332. that._refresh();
  45333. return that
  45334. },
  45335. _adjustZoom: function(zoom) {
  45336. var that = this,
  45337. transform,
  45338. y,
  45339. start = SIZE_OPTIONS.sliderLineStartOffset,
  45340. end = SIZE_OPTIONS.sliderLineEndOffset,
  45341. h = SIZE_OPTIONS.sliderWidth;
  45342. that._zoomFactor = _round(zoom);
  45343. that._zoomFactor >= 0 || (that._zoomFactor = 0);
  45344. that._zoomFactor <= that._zoomPartition || (that._zoomFactor = that._zoomPartition);
  45345. transform = {translateY: -that._zoomFactor * that._sliderUnitLength};
  45346. y = end - h / 2 + transform.translateY;
  45347. that._progressBar.attr({points: [[0, start, 0, _math.max(start, y)], [0, _math.min(end, y + h), 0, end]]});
  45348. that._zoomDrag.attr(transform);
  45349. that._zoomDragCover.attr(transform)
  45350. },
  45351. _applyZoom: function(center) {
  45352. this._callbacks.zoom(this._zoomFactor, this._flags & FLAG_CENTERING ? center : undefined)
  45353. },
  45354. processStart: function(arg) {
  45355. var commandType = COMMAND_TO_TYPE_MAP[arg.data];
  45356. this._command = commandType && this._options.enabled && commandType.flags & this._flags ? new commandType(this, arg) : null;
  45357. return this
  45358. },
  45359. processMove: function(arg) {
  45360. this._command && this._command.update(arg);
  45361. return this
  45362. },
  45363. processEnd: function() {
  45364. this._command && this._command.finish();
  45365. this._command = null;
  45366. return this
  45367. },
  45368. processZoom: function(arg) {
  45369. var that = this,
  45370. zoomFactor;
  45371. if (that._flags & FLAG_ZOOMING) {
  45372. if (arg.delta)
  45373. zoomFactor = arg.delta;
  45374. else if (arg.ratio)
  45375. zoomFactor = _ln(arg.ratio) / _LN2;
  45376. that._adjustZoom(that._zoomFactor + zoomFactor);
  45377. that._applyZoom([arg.x, arg.y])
  45378. }
  45379. return that
  45380. }
  45381. });
  45382. function disposeCommand(command) {
  45383. delete command._owner;
  45384. command.update = function(){};
  45385. command.finish = function(){}
  45386. }
  45387. function ResetCommand(owner, arg) {
  45388. this._owner = owner;
  45389. this._command = arg.data
  45390. }
  45391. ResetCommand.flags = FLAG_CENTERING | FLAG_ZOOMING;
  45392. ResetCommand.prototype.update = function(arg) {
  45393. arg.data !== this._command && disposeCommand(this)
  45394. };
  45395. ResetCommand.prototype.finish = function() {
  45396. var flags = this._owner._flags;
  45397. this._owner._callbacks.reset(!!(flags & FLAG_CENTERING), !!(flags & FLAG_ZOOMING));
  45398. if (flags & FLAG_ZOOMING)
  45399. this._owner._adjustZoom(0);
  45400. disposeCommand(this)
  45401. };
  45402. function MoveCommand(owner, arg) {
  45403. this._command = arg.data;
  45404. var timeout = null,
  45405. interval = 100,
  45406. dx = 0,
  45407. dy = 0;
  45408. switch (this._command) {
  45409. case COMMAND_MOVE_UP:
  45410. dy = -10;
  45411. break;
  45412. case COMMAND_MOVE_RIGHT:
  45413. dx = 10;
  45414. break;
  45415. case COMMAND_MOVE_DOWN:
  45416. dy = 10;
  45417. break;
  45418. case COMMAND_MOVE_LEFT:
  45419. dx = -10;
  45420. break
  45421. }
  45422. function callback() {
  45423. owner._callbacks.move(dx, dy);
  45424. timeout = setTimeout(callback, interval)
  45425. }
  45426. this._stop = function() {
  45427. clearTimeout(timeout);
  45428. owner._callbacks.endMove();
  45429. this._stop = owner = null;
  45430. return this
  45431. };
  45432. arg = null;
  45433. owner._callbacks.beginMove();
  45434. callback()
  45435. }
  45436. MoveCommand.flags = FLAG_CENTERING;
  45437. MoveCommand.prototype.update = function(arg) {
  45438. this._command !== arg.data && this.finish()
  45439. };
  45440. MoveCommand.prototype.finish = function() {
  45441. disposeCommand(this._stop())
  45442. };
  45443. function ZoomCommand(owner, arg) {
  45444. this._owner = owner;
  45445. this._command = arg.data;
  45446. var timeout = null,
  45447. interval = 150,
  45448. dzoom = this._command === COMMAND_ZOOM_IN ? 1 : -1;
  45449. function callback() {
  45450. owner._adjustZoom(owner._zoomFactor + dzoom);
  45451. timeout = setTimeout(callback, interval)
  45452. }
  45453. this._stop = function() {
  45454. clearTimeout(timeout);
  45455. this._stop = owner = null;
  45456. return this
  45457. };
  45458. arg = null;
  45459. callback()
  45460. }
  45461. ZoomCommand.flags = FLAG_ZOOMING;
  45462. ZoomCommand.prototype.update = function(arg) {
  45463. this._command !== arg.data && this.finish()
  45464. };
  45465. ZoomCommand.prototype.finish = function() {
  45466. this._owner._applyZoom();
  45467. disposeCommand(this._stop())
  45468. };
  45469. function ZoomDragCommand(owner, arg) {
  45470. this._owner = owner;
  45471. this._zoomFactor = owner._zoomFactor;
  45472. this._pos = arg.y
  45473. }
  45474. ZoomDragCommand.flags = FLAG_ZOOMING;
  45475. ZoomDragCommand.prototype.update = function(arg) {
  45476. var owner = this._owner;
  45477. owner._adjustZoom(this._zoomFactor + owner._zoomPartition * (this._pos - arg.y) / owner._sliderLineLength)
  45478. };
  45479. ZoomDragCommand.prototype.finish = function() {
  45480. this._owner._applyZoom();
  45481. disposeCommand(this)
  45482. };
  45483. DX.viz.map._tests.ControlBar = ControlBar;
  45484. var COMMAND_TO_TYPE_MAP__ORIGINAL = COMMAND_TO_TYPE_MAP;
  45485. DX.viz.map._tests.stubCommandToTypeMap = function(map) {
  45486. COMMAND_TO_TYPE_MAP = map
  45487. };
  45488. DX.viz.map._tests.restoreCommandToTypeMap = function() {
  45489. COMMAND_TO_TYPE_MAP = COMMAND_TO_TYPE_MAP__ORIGINAL
  45490. };
  45491. DX.viz.map.dxVectorMap.prototype._factory.createControlBar = function(parameters) {
  45492. return new ControlBar(parameters)
  45493. }
  45494. })(DevExpress);
  45495. /*! Module viz-vectormap, file tracker.js */
  45496. (function(DX, $, undefined) {
  45497. var _math = Math,
  45498. _abs = _math.abs,
  45499. _sqrt = _math.sqrt,
  45500. _round = _math.round,
  45501. _addNamespace = DX.ui.events.addNamespace,
  45502. _parseScalar = DX.viz.core.utils.parseScalar,
  45503. _now = $.now,
  45504. _NAME = DX.viz.map.dxVectorMap.prototype.NAME,
  45505. EVENTS = {};
  45506. setupEvents();
  45507. var EVENT_START = "start",
  45508. EVENT_MOVE = "move",
  45509. EVENT_END = "end",
  45510. EVENT_ZOOM = "zoom",
  45511. EVENT_HOVER_ON = "hover-on",
  45512. EVENT_HOVER_OFF = "hover-off",
  45513. EVENT_CLICK = "click",
  45514. EVENT_FOCUS_ON = "focus-on",
  45515. EVENT_FOCUS_MOVE = "focus-move",
  45516. EVENT_FOCUS_OFF = "focus-off",
  45517. CLICK_TIME_THRESHOLD = 500,
  45518. CLICK_COORD_THRESHOLD_MOUSE = 5,
  45519. CLICK_COORD_THRESHOLD_TOUCH = 20,
  45520. DRAG_COORD_THRESHOLD_MOUSE = 5,
  45521. DRAG_COORD_THRESHOLD_TOUCH = 10,
  45522. FOCUS_ON_DELAY_MOUSE = 300,
  45523. FOCUS_OFF_DELAY_MOUSE = 300,
  45524. FOCUS_ON_DELAY_TOUCH = 300,
  45525. FOCUS_OFF_DELAY_TOUCH = 400,
  45526. FOCUS_COORD_THRESHOLD_MOUSE = 5,
  45527. WHEEL_COOLDOWN = 50,
  45528. WHEEL_DIRECTION_COOLDOWN = 300;
  45529. function Tracker(parameters) {
  45530. var that = this;
  45531. that._root = parameters.root;
  45532. that._callbacks = {};
  45533. that._createEventHandlers(parameters.dataKey);
  45534. that._createProjectionHandlers(parameters.projection);
  45535. that._focus = new Focus(that._callbacks);
  45536. that._attachHandlers()
  45537. }
  45538. Tracker.prototype = {
  45539. constructor: Tracker,
  45540. dispose: function() {
  45541. var that = this;
  45542. that._detachHandlers();
  45543. that._focus.dispose();
  45544. that._root = that._callbacks = that._focus = that._docHandlers = that._rootHandlers = null;
  45545. return that
  45546. },
  45547. _startClick: function(event, data) {
  45548. if (!data)
  45549. return;
  45550. var coords = getEventCoords(event);
  45551. this._clickState = {
  45552. x: coords.x,
  45553. y: coords.y,
  45554. threshold: isTouchEvent(event) ? CLICK_COORD_THRESHOLD_TOUCH : CLICK_COORD_THRESHOLD_MOUSE,
  45555. time: _now()
  45556. }
  45557. },
  45558. _endClick: function(event, data) {
  45559. var state = this._clickState,
  45560. threshold,
  45561. coords;
  45562. if (!state)
  45563. return;
  45564. if (_now() - state.time <= CLICK_TIME_THRESHOLD) {
  45565. threshold = state.threshold;
  45566. coords = getEventCoords(event);
  45567. if (_abs(coords.x - state.x) <= threshold && _abs(coords.y - state.y) <= threshold)
  45568. this._callbacks[EVENT_CLICK]({
  45569. data: data,
  45570. x: coords.x,
  45571. y: coords.y,
  45572. $event: event
  45573. })
  45574. }
  45575. this._clickState = null
  45576. },
  45577. _startDrag: function(event, data) {
  45578. if (!data)
  45579. return;
  45580. var coords = getEventCoords(event),
  45581. state = this._dragState = {
  45582. x: coords.x,
  45583. y: coords.y,
  45584. data: data
  45585. };
  45586. this._callbacks[EVENT_START]({
  45587. x: state.x,
  45588. y: state.y,
  45589. data: state.data
  45590. })
  45591. },
  45592. _moveDrag: function(event, data) {
  45593. var state = this._dragState,
  45594. coords,
  45595. threshold;
  45596. if (!state)
  45597. return;
  45598. coords = getEventCoords(event);
  45599. threshold = isTouchEvent(event) ? DRAG_COORD_THRESHOLD_TOUCH : DRAG_COORD_THRESHOLD_MOUSE;
  45600. if (state.active || _abs(coords.x - state.x) > threshold || _abs(coords.y - state.y) > threshold) {
  45601. state.x = coords.x;
  45602. state.y = coords.y;
  45603. state.active = true;
  45604. state.data = data || {};
  45605. this._callbacks[EVENT_MOVE]({
  45606. x: state.x,
  45607. y: state.y,
  45608. data: state.data
  45609. })
  45610. }
  45611. },
  45612. _endDrag: function() {
  45613. var state = this._dragState;
  45614. if (!state)
  45615. return;
  45616. this._dragState = null;
  45617. this._callbacks[EVENT_END]({
  45618. x: state.x,
  45619. y: state.y,
  45620. data: state.data
  45621. })
  45622. },
  45623. _wheelZoom: function(event, data) {
  45624. if (!data)
  45625. return;
  45626. var that = this,
  45627. lock = that._wheelLock,
  45628. time = _now(),
  45629. delta,
  45630. coords;
  45631. if (time - lock.time <= WHEEL_COOLDOWN)
  45632. return;
  45633. if (time - lock.dirTime > WHEEL_DIRECTION_COOLDOWN)
  45634. lock.dir = 0;
  45635. delta = adjustWheelDelta(event.originalEvent.wheelDelta / 120 || event.originalEvent.detail / -3 || 0, lock);
  45636. if (delta === 0)
  45637. return;
  45638. coords = getEventCoords(event);
  45639. that._callbacks[EVENT_ZOOM]({
  45640. delta: delta,
  45641. x: coords.x,
  45642. y: coords.y
  45643. });
  45644. lock.time = lock.dirTime = time
  45645. },
  45646. _startZoom: function(event, data) {
  45647. if (!isTouchEvent(event) || !data)
  45648. return;
  45649. var state = this._zoomState = this._zoomState || {},
  45650. coords,
  45651. pointer2;
  45652. if (state.pointer1 && state.pointer2)
  45653. return;
  45654. if (state.pointer1 === undefined) {
  45655. state.pointer1 = getPointerId(event) || 0;
  45656. coords = getMultitouchEventCoords(event, state.pointer1);
  45657. state.x1 = state.x1_0 = coords.x;
  45658. state.y1 = state.y1_0 = coords.y
  45659. }
  45660. if (state.pointer2 === undefined) {
  45661. pointer2 = getPointerId(event) || 1;
  45662. if (pointer2 !== state.pointer1) {
  45663. coords = getMultitouchEventCoords(event, pointer2);
  45664. if (coords) {
  45665. state.x2 = state.x2_0 = coords.x;
  45666. state.y2 = state.y2_0 = coords.y;
  45667. state.pointer2 = pointer2;
  45668. state.ready = true;
  45669. this._endDrag()
  45670. }
  45671. }
  45672. }
  45673. },
  45674. _moveZoom: function(event) {
  45675. var state = this._zoomState,
  45676. coords;
  45677. if (!state || !isTouchEvent(event))
  45678. return;
  45679. if (state.pointer1 !== undefined) {
  45680. coords = getMultitouchEventCoords(event, state.pointer1);
  45681. if (coords) {
  45682. state.x1 = coords.x;
  45683. state.y1 = coords.y
  45684. }
  45685. }
  45686. if (state.pointer2 !== undefined) {
  45687. coords = getMultitouchEventCoords(event, state.pointer2);
  45688. if (coords) {
  45689. state.x2 = coords.x;
  45690. state.y2 = coords.y
  45691. }
  45692. }
  45693. },
  45694. _endZoom: function(event) {
  45695. var state = this._zoomState,
  45696. startDistance,
  45697. currentDistance;
  45698. if (!state || !isTouchEvent(event))
  45699. return;
  45700. if (state.ready) {
  45701. startDistance = getDistance(state.x1_0, state.y1_0, state.x2_0, state.y2_0);
  45702. currentDistance = getDistance(state.x1, state.y1, state.x2, state.y2);
  45703. this._callbacks[EVENT_ZOOM]({
  45704. ratio: currentDistance / startDistance,
  45705. x: (state.x1_0 + state.x2_0) / 2,
  45706. y: (state.y1_0 + state.y2_0) / 2
  45707. })
  45708. }
  45709. this._zoomState = null
  45710. },
  45711. _startHover: function(event, data) {
  45712. this._doHover(event, data, true)
  45713. },
  45714. _moveHover: function(event, data) {
  45715. this._doHover(event, data, false)
  45716. },
  45717. _doHover: function(event, data, isTouch) {
  45718. var that = this;
  45719. if (that._dragState && that._dragState.active || that._zoomState && that._zoomState.ready) {
  45720. that._cancelHover();
  45721. return
  45722. }
  45723. if (isTouchEvent(event) !== isTouch || that._hoverTarget === event.target || that._hoverState && that._hoverState.data === data)
  45724. return;
  45725. that._cancelHover();
  45726. if (data) {
  45727. that._hoverState = {data: data};
  45728. that._callbacks[EVENT_HOVER_ON]({data: data})
  45729. }
  45730. that._hoverTarget = event.target
  45731. },
  45732. _cancelHover: function() {
  45733. var state = this._hoverState;
  45734. this._hoverState = this._hoverTarget = null;
  45735. if (state)
  45736. this._callbacks[EVENT_HOVER_OFF]({data: state.data})
  45737. },
  45738. _startFocus: function(event, data) {
  45739. this._doFocus(event, data, true)
  45740. },
  45741. _moveFocus: function(event, data) {
  45742. this._doFocus(event, data, false)
  45743. },
  45744. _doFocus: function(event, data, isTouch) {
  45745. var that = this;
  45746. if (that._dragState && that._dragState.active || that._zoomState && that._zoomState.ready) {
  45747. that._cancelFocus();
  45748. return
  45749. }
  45750. if (isTouchEvent(event) !== isTouch)
  45751. return;
  45752. that._focus.turnOff(isTouch ? FOCUS_OFF_DELAY_TOUCH : FOCUS_OFF_DELAY_MOUSE);
  45753. data && that._focus.turnOn(data, getEventCoords(event), isTouch ? FOCUS_ON_DELAY_TOUCH : FOCUS_ON_DELAY_MOUSE, isTouch)
  45754. },
  45755. _endFocus: function(event) {
  45756. if (!isTouchEvent(event))
  45757. return;
  45758. this._focus.cancelOn()
  45759. },
  45760. _cancelFocus: function() {
  45761. this._focus.cancel()
  45762. },
  45763. _createEventHandlers: function(DATA_KEY) {
  45764. var that = this;
  45765. that._docHandlers = {};
  45766. that._rootHandlers = {};
  45767. that._docHandlers[EVENTS.start] = function(event) {
  45768. var isTouch = isTouchEvent(event),
  45769. data = $(event.target).data(DATA_KEY);
  45770. if (isTouch && !that._isTouchEnabled)
  45771. return;
  45772. data && event.preventDefault();
  45773. that._startClick(event, data);
  45774. that._startDrag(event, data);
  45775. that._startZoom(event, data);
  45776. that._startHover(event, data);
  45777. that._startFocus(event, data)
  45778. };
  45779. that._docHandlers[EVENTS.move] = function(event) {
  45780. var isTouch = isTouchEvent(event),
  45781. data = $(event.target).data(DATA_KEY);
  45782. if (isTouch && !that._isTouchEnabled)
  45783. return;
  45784. that._moveDrag(event, data);
  45785. that._moveZoom(event, data);
  45786. that._moveHover(event, data);
  45787. that._moveFocus(event, data)
  45788. };
  45789. that._docHandlers[EVENTS.end] = function(event) {
  45790. var isTouch = isTouchEvent(event),
  45791. data = $(event.target).data(DATA_KEY);
  45792. if (isTouch && !that._isTouchEnabled)
  45793. return;
  45794. that._endClick(event, data);
  45795. that._endDrag(event, data);
  45796. that._endZoom(event, data);
  45797. that._endFocus(event, data)
  45798. };
  45799. that._rootHandlers[EVENTS.wheel] = function(event) {
  45800. that._cancelFocus();
  45801. if (!that._isWheelEnabled)
  45802. return;
  45803. var data = $(event.target).data(DATA_KEY);
  45804. if (data) {
  45805. event.preventDefault();
  45806. event.stopPropagation();
  45807. that._wheelZoom(event, data)
  45808. }
  45809. };
  45810. that._wheelLock = {dir: 0}
  45811. },
  45812. _createProjectionHandlers: function(projection) {
  45813. var that = this;
  45814. projection.on({
  45815. center: handler,
  45816. zoom: handler
  45817. });
  45818. function handler() {
  45819. that._cancelFocus()
  45820. }
  45821. },
  45822. reset: function() {
  45823. var that = this;
  45824. that._clickState = null;
  45825. that._endDrag();
  45826. that._cancelHover();
  45827. that._cancelFocus();
  45828. return that
  45829. },
  45830. setCallbacks: function(callbacks) {
  45831. $.extend(this._callbacks, callbacks);
  45832. return this
  45833. },
  45834. setOptions: function(options) {
  45835. var that = this;
  45836. that.reset();
  45837. that._detachHandlers();
  45838. that._isTouchEnabled = !!_parseScalar(options.touchEnabled, true);
  45839. that._isWheelEnabled = !!_parseScalar(options.wheelEnabled, true);
  45840. that._attachHandlers();
  45841. return that
  45842. },
  45843. _detachHandlers: function() {
  45844. var that = this;
  45845. if (that._isTouchEnabled)
  45846. that._root.css({
  45847. "touch-action": "",
  45848. "-ms-touch-action": "",
  45849. "-webkit-user-select": ""
  45850. }).off(_addNamespace("MSHoldVisual", _NAME)).off(_addNamespace("contextmenu", _NAME));
  45851. $(document).off(that._docHandlers);
  45852. that._root.off(that._rootHandlers)
  45853. },
  45854. _attachHandlers: function() {
  45855. var that = this;
  45856. if (that._isTouchEnabled)
  45857. that._root.css({
  45858. "touch-action": "none",
  45859. "-ms-touch-action": "none",
  45860. "-webkit-user-select": "none"
  45861. }).on(_addNamespace("MSHoldVisual", _NAME), function(event) {
  45862. event.preventDefault()
  45863. }).on(_addNamespace("contextmenu", _NAME), function(event) {
  45864. isTouchEvent(event) && event.preventDefault()
  45865. });
  45866. $(document).on(that._docHandlers);
  45867. that._root.on(that._rootHandlers)
  45868. }
  45869. };
  45870. var Focus = function(callbacks) {
  45871. var that = this,
  45872. _activeData = null,
  45873. _data = null,
  45874. _disabled = false,
  45875. _onTimer = null,
  45876. _offTimer = null,
  45877. _x,
  45878. _y;
  45879. that.dispose = function() {
  45880. clearTimeout(_onTimer);
  45881. clearTimeout(_offTimer);
  45882. that.turnOn = that.turnOff = that.cancel = that.cancelOn = that.dispose = that = callbacks = _activeData = _data = _onTimer = _offTimer = null
  45883. };
  45884. that.turnOn = function(data, coords, timeout, forceTimeout) {
  45885. if (data === _data && _disabled)
  45886. return;
  45887. _disabled = false;
  45888. _data = data;
  45889. if (_activeData) {
  45890. _x = coords.x;
  45891. _y = coords.y;
  45892. clearTimeout(_onTimer);
  45893. _onTimer = setTimeout(function() {
  45894. _onTimer = null;
  45895. if (_data === _activeData) {
  45896. callbacks[EVENT_FOCUS_MOVE]({
  45897. data: _data,
  45898. x: _x,
  45899. y: _y
  45900. });
  45901. onCheck(true)
  45902. }
  45903. else
  45904. callbacks[EVENT_FOCUS_ON]({
  45905. data: _data,
  45906. x: _x,
  45907. y: _y
  45908. }, onCheck)
  45909. }, forceTimeout ? timeout : 0)
  45910. }
  45911. else if (!_onTimer || _abs(coords.x - _x) > FOCUS_COORD_THRESHOLD_MOUSE || _abs(coords.y - _y) > FOCUS_COORD_THRESHOLD_MOUSE || forceTimeout) {
  45912. _x = coords.x;
  45913. _y = coords.y;
  45914. clearTimeout(_onTimer);
  45915. _onTimer = setTimeout(function() {
  45916. _onTimer = null;
  45917. callbacks[EVENT_FOCUS_ON]({
  45918. data: _data,
  45919. x: _x,
  45920. y: _y
  45921. }, onCheck)
  45922. }, timeout)
  45923. }
  45924. function onCheck(result) {
  45925. _disabled = !result;
  45926. if (result) {
  45927. _activeData = _data;
  45928. clearTimeout(_offTimer);
  45929. _offTimer = null
  45930. }
  45931. }
  45932. };
  45933. that.turnOff = function(timeout) {
  45934. clearTimeout(_onTimer);
  45935. _onTimer = null;
  45936. _data = null;
  45937. if (_activeData && !_disabled)
  45938. _offTimer = _offTimer || setTimeout(function() {
  45939. _offTimer = null;
  45940. callbacks[EVENT_FOCUS_OFF]({data: _activeData});
  45941. _activeData = null
  45942. }, timeout)
  45943. };
  45944. that.cancel = function() {
  45945. clearTimeout(_onTimer);
  45946. clearTimeout(_offTimer);
  45947. if (_activeData)
  45948. callbacks[EVENT_FOCUS_OFF]({data: _activeData});
  45949. _activeData = _data = _onTimer = _offTimer = null
  45950. };
  45951. that.cancelOn = function() {
  45952. clearTimeout(_onTimer);
  45953. _onTimer = null
  45954. }
  45955. };
  45956. DX.viz.map._tests.Tracker = Tracker;
  45957. DX.viz.map._tests._DEBUG_forceEventMode = function(mode) {
  45958. setupEvents(mode)
  45959. };
  45960. DX.viz.map._tests.Focus = Focus;
  45961. DX.viz.map._tests._DEBUG_stubFocusType = function(focusType) {
  45962. Focus = focusType
  45963. };
  45964. DX.viz.map._tests._DEBUG_restoreFocusType = function() {
  45965. Focus = DX.viz.map._tests.Focus
  45966. };
  45967. DX.viz.map.dxVectorMap.prototype._factory.createTracker = function(parameters) {
  45968. return new Tracker(parameters)
  45969. };
  45970. function getDistance(x1, y1, x2, y2) {
  45971. return _sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
  45972. }
  45973. function isTouchEvent(event) {
  45974. var type = event.originalEvent.type,
  45975. pointerType = event.originalEvent.pointerType;
  45976. return /^touch/.test(type) || /^MSPointer/.test(type) && pointerType !== 4 || /^pointer/.test(type) && pointerType !== "mouse"
  45977. }
  45978. function selectItem(flags, items) {
  45979. var i = 0,
  45980. ii = flags.length,
  45981. item;
  45982. for (; i < ii; ++i)
  45983. if (flags[i]) {
  45984. item = items[i];
  45985. break
  45986. }
  45987. return _addNamespace(item || items[i], _NAME)
  45988. }
  45989. function setupEvents() {
  45990. var flags = [navigator.pointerEnabled, navigator.msPointerEnabled, "ontouchstart" in window];
  45991. if (arguments.length)
  45992. flags = [arguments[0] === "pointer", arguments[0] === "MSPointer", arguments[0] === "touch"];
  45993. EVENTS = {
  45994. start: selectItem(flags, ["pointerdown", "MSPointerDown", "touchstart mousedown", "mousedown"]),
  45995. move: selectItem(flags, ["pointermove", "MSPointerMove", "touchmove mousemove", "mousemove"]),
  45996. end: selectItem(flags, ["pointerup", "MSPointerUp", "touchend mouseup", "mouseup"]),
  45997. wheel: selectItem([], ["mousewheel DOMMouseScroll"])
  45998. }
  45999. }
  46000. function getEventCoords(event) {
  46001. var originalEvent = event.originalEvent,
  46002. touch = originalEvent.touches && originalEvent.touches[0] || {};
  46003. return {
  46004. x: touch.pageX || originalEvent.pageX || event.pageX,
  46005. y: touch.pageY || originalEvent.pageY || event.pageY
  46006. }
  46007. }
  46008. function getPointerId(event) {
  46009. return event.originalEvent.pointerId
  46010. }
  46011. function getMultitouchEventCoords(event, pointerId) {
  46012. var originalEvent = event.originalEvent;
  46013. if (originalEvent.pointerId !== undefined)
  46014. originalEvent = originalEvent.pointerId === pointerId ? originalEvent : null;
  46015. else
  46016. originalEvent = originalEvent.touches[pointerId];
  46017. return originalEvent ? {
  46018. x: originalEvent.pageX || event.pageX,
  46019. y: originalEvent.pageY || event.pageY
  46020. } : null
  46021. }
  46022. function adjustWheelDelta(delta, lock) {
  46023. if (delta === 0)
  46024. return 0;
  46025. var _delta = _abs(delta),
  46026. sign = _round(delta / _delta);
  46027. if (lock.dir && sign !== lock.dir)
  46028. return 0;
  46029. lock.dir = sign;
  46030. if (_delta < 0.1)
  46031. _delta = 0;
  46032. else if (_delta < 1)
  46033. _delta = 1;
  46034. else if (_delta > 4)
  46035. _delta = 4;
  46036. else
  46037. _delta = _round(_delta);
  46038. return sign * _delta
  46039. }
  46040. })(DevExpress, jQuery);
  46041. /*! Module viz-vectormap, file themeManager.js */
  46042. (function(DX, $, undefined) {
  46043. var _Number = Number,
  46044. _extend = $.extend,
  46045. _each = $.each;
  46046. var ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  46047. _themeSection: "map",
  46048. _fontFields: ["areaSettings.label.font", "markerSettings.label.font", "tooltip.font", "legend.font", "loadingIndicator.font"],
  46049. getCommonAreaSettings: function(options) {
  46050. var settings = _extend(true, {}, this._theme.areaSettings, options),
  46051. palette,
  46052. i,
  46053. colors;
  46054. if (settings.paletteSize > 0) {
  46055. palette = new DX.viz.core.GradientPalette(settings.palette, settings.paletteSize);
  46056. for (i = 0, colors = []; i < settings.paletteSize; ++i)
  46057. colors.push(palette.getColor(i));
  46058. settings._colors = colors
  46059. }
  46060. return settings
  46061. },
  46062. getAreaSettings: function(commonSettings, options) {
  46063. var settings = _extend(true, {}, commonSettings, options);
  46064. settings.borderWidth = _Number(settings.borderWidth) || 0;
  46065. settings.borderColor = settings.borderColor || null;
  46066. if (options.color === undefined && options.paletteIndex >= 0)
  46067. settings.color = commonSettings._colors[options.paletteIndex];
  46068. settings.color = settings.color || null;
  46069. settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
  46070. settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
  46071. settings.hoveredColor = settings.hoveredColor || settings.color;
  46072. settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
  46073. settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
  46074. settings.selectedColor = settings.selectedColor || settings.color;
  46075. return settings
  46076. },
  46077. getCommonMarkerSettings: function(options) {
  46078. options && !options.label && options.font && (options.label = {font: options.font}) && (options.font = undefined);
  46079. var theme = _extend({}, this._theme.markerSettings),
  46080. _options = _extend({}, options),
  46081. themeParts = {},
  46082. optionsParts = {},
  46083. settings;
  46084. _each(theme, function(name, themePart) {
  46085. if (name[0] === "_") {
  46086. themeParts[name] = themePart;
  46087. optionsParts[name] = _options[name];
  46088. theme[name] = _options[name] = undefined
  46089. }
  46090. });
  46091. settings = _extend(true, {}, theme, _options);
  46092. _each(themeParts, function(name, themePart) {
  46093. settings[name] = _extend(true, {}, theme, themePart, _options, optionsParts[name])
  46094. });
  46095. return settings
  46096. },
  46097. getMarkerSettings: function(commonSettings, options, type) {
  46098. var settings = _extend(true, {}, commonSettings["_" + type], options);
  46099. settings.borderWidth = _Number(settings.borderWidth) || 0;
  46100. settings.borderColor = settings.borderColor || null;
  46101. settings.color = settings.color || null;
  46102. settings.opacity = settings.opacity || null;
  46103. settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
  46104. settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
  46105. settings.hoveredColor = settings.hoveredColor || settings.color;
  46106. settings.hoveredOpacity = settings.hoveredOpacity || settings.opacity;
  46107. settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
  46108. settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
  46109. settings.selectedColor = settings.selectedColor || settings.color;
  46110. settings.selectedOpacity = settings.selectedOpacity || settings.opacity;
  46111. return settings
  46112. },
  46113. getPieColors: function(commonSettings, count) {
  46114. var colors = commonSettings._pie._colors || [],
  46115. palette,
  46116. i,
  46117. _count = count > 8 ? count : 8;
  46118. if (colors.length < _count) {
  46119. palette = new DX.viz.core.Palette(commonSettings._pie.palette, {
  46120. stepHighlight: 50,
  46121. theme: this.themeName()
  46122. });
  46123. for (i = 0, colors = []; i < _count; ++i)
  46124. colors.push(palette.getNextColor());
  46125. commonSettings._pie._colors = colors
  46126. }
  46127. return colors
  46128. }
  46129. });
  46130. DX.viz.map._tests.ThemeManager = ThemeManager;
  46131. DX.viz.map.dxVectorMap.prototype._factory.createThemeManager = function() {
  46132. return new ThemeManager
  46133. }
  46134. })(DevExpress, jQuery);
  46135. /*! Module viz-vectormap, file legend.js */
  46136. (function(DX, $, undefined) {
  46137. var _String = String,
  46138. _isArray = DX.utils.isArray,
  46139. _extend = $.extend,
  46140. _each = $.each,
  46141. _BaseLegend = DX.viz.core.Legend;
  46142. function Legend(parameters) {
  46143. var that = this;
  46144. that._params = parameters;
  46145. that._root = parameters.renderer.g().attr({"class": "dxm-legend"});
  46146. parameters.layoutControl.addItem(that);
  46147. _BaseLegend.apply(that, [{
  46148. renderer: parameters.renderer,
  46149. group: that._root,
  46150. backgroundClass: null,
  46151. itemsGroupClass: null,
  46152. textField: "text",
  46153. getFormatObject: function(data) {
  46154. return data
  46155. }
  46156. }]);
  46157. that._onDataChanged = function(items) {
  46158. var itemsForUpdate = $.map(items, function(item) {
  46159. return _extend(true, {states: {normal: {fill: item.color}}}, item)
  46160. });
  46161. that.update(itemsForUpdate, that._options);
  46162. that._refresh()
  46163. }
  46164. }
  46165. var legendPrototype = Legend.prototype = DX.utils.clone(_BaseLegend.prototype);
  46166. legendPrototype.constructor = Legend;
  46167. legendPrototype.dispose = function() {
  46168. var that = this;
  46169. that._params.layoutControl.removeItem(that);
  46170. that._unbindData();
  46171. that._params = that._root = that._onDataChanged = null;
  46172. return _BaseLegend.prototype.dispose.apply(that, arguments)
  46173. };
  46174. legendPrototype.clean = function() {
  46175. this._rendered = false;
  46176. this._root.remove();
  46177. return this
  46178. };
  46179. legendPrototype.render = function() {
  46180. var that = this;
  46181. that._root.append(that._params.container);
  46182. that._rendered = true;
  46183. that._refresh();
  46184. return that
  46185. };
  46186. legendPrototype.resize = function(size) {
  46187. if (size === null)
  46188. this.erase();
  46189. else
  46190. this.setSize(size).draw();
  46191. return this
  46192. };
  46193. legendPrototype.locate = _BaseLegend.prototype.shift;
  46194. legendPrototype._unbindData = function() {
  46195. if (this._dataCategory)
  46196. this._params.dataExchanger.unbind(this._dataCategory, this._dataName)
  46197. };
  46198. legendPrototype._bindData = function(info) {
  46199. this._params.dataExchanger.bind(this._dataCategory = info.category, this._dataName = info.name, this._onDataChanged)
  46200. };
  46201. var sourceMap = {
  46202. areacolorgroups: {
  46203. category: "areas",
  46204. name: "color"
  46205. },
  46206. markercolorgroups: {
  46207. category: "markers",
  46208. name: "color"
  46209. },
  46210. markersizegroups: {
  46211. category: "markers",
  46212. name: "size"
  46213. }
  46214. };
  46215. var unknownSource = {
  46216. category: "UNKNOWN",
  46217. name: "UNKNOWN"
  46218. };
  46219. legendPrototype.setOptions = function(options) {
  46220. var that = this;
  46221. that.update(that._data, options);
  46222. that._unbindData();
  46223. that._bindData(sourceMap[_String(options.source).toLowerCase()] || unknownSource);
  46224. that._refresh();
  46225. return that
  46226. };
  46227. legendPrototype._refresh = function() {
  46228. if (this._rendered)
  46229. this.updateLayout()
  46230. };
  46231. function LegendsControl(parameters) {
  46232. this._parameters = parameters;
  46233. this._items = []
  46234. }
  46235. LegendsControl.prototype = {
  46236. constructor: LegendsControl,
  46237. dispose: function() {
  46238. _each(this._items, function(_, item) {
  46239. item.dispose()
  46240. });
  46241. this._parameters = this._items = null;
  46242. return this
  46243. },
  46244. setOptions: function(options, theme) {
  46245. var optionList = _isArray(options) ? options : [],
  46246. i = 0,
  46247. ii = optionList.length,
  46248. item,
  46249. newItems = [],
  46250. items = this._items;
  46251. for (; i < ii; ++i) {
  46252. item = (items[i] || new Legend(this._parameters)).setOptions(_extend(true, {}, theme, optionList[i]));
  46253. newItems.push(item)
  46254. }
  46255. for (ii = items.length; i < ii; ++i)
  46256. items[i].clean().dispose();
  46257. this._items = newItems
  46258. },
  46259. clean: function() {
  46260. _each(this._items, function(_, item) {
  46261. item.clean()
  46262. });
  46263. return this
  46264. },
  46265. render: function() {
  46266. _each(this._items, function(_, item) {
  46267. item.render()
  46268. });
  46269. return this
  46270. }
  46271. };
  46272. DX.viz.map.dxVectorMap.prototype._factory.createLegendsControl = function(parameters) {
  46273. return new LegendsControl(parameters)
  46274. };
  46275. DX.viz.map._tests.Legend = Legend;
  46276. DX.viz.map._tests.LegendsControl = LegendsControl;
  46277. DX.viz.map._tests.stubLegendType = function(stub) {
  46278. Legend = stub
  46279. };
  46280. DX.viz.map._tests.restoreLegendType = function() {
  46281. Legend = DX.viz.map._tests.Legend
  46282. };
  46283. DX.viz.map._tests.extendLegendSourceMap = function(name, value) {
  46284. sourceMap[name] = value
  46285. }
  46286. })(DevExpress, jQuery);
  46287. /*! Module viz-vectormap, file layout.js */
  46288. (function(DX, $, undefined) {
  46289. var _round = Math.round,
  46290. _min = Math.min,
  46291. _max = Math.max,
  46292. _each = $.each,
  46293. _inArray = $.inArray,
  46294. horizontalAlignmentMap = {
  46295. left: 0,
  46296. center: 1,
  46297. right: 2
  46298. },
  46299. verticalAlignmentMap = {
  46300. top: 0,
  46301. bottom: 1
  46302. };
  46303. function getCellIndex(options) {
  46304. return verticalAlignmentMap[options.verticalAlignment] * 3 + horizontalAlignmentMap[options.horizontalAlignment]
  46305. }
  46306. function createCells(canvas, items) {
  46307. var hstep = (canvas.right - canvas.left) / 3,
  46308. vstep = (canvas.bottom - canvas.top) / 2,
  46309. h1 = canvas.left,
  46310. h2 = _round(h1 + hstep),
  46311. h3 = _round(h1 + hstep + hstep),
  46312. h4 = canvas.right,
  46313. v1 = canvas.top,
  46314. v2 = _round(v1 + vstep),
  46315. v3 = canvas.bottom,
  46316. cells = [{rect: [h1, v1, h2, v2]}, {
  46317. rect: [h2, v1, h3, v2],
  46318. center: true
  46319. }, {
  46320. rect: [h3, v1, h4, v2],
  46321. horInv: true
  46322. }, {
  46323. rect: [h1, v2, h2, v3],
  46324. verInv: true
  46325. }, {
  46326. rect: [h2, v2, h3, v3],
  46327. center: true,
  46328. verInv: true
  46329. }, {
  46330. rect: [h3, v2, h4, v3],
  46331. horInv: true,
  46332. verInv: true
  46333. }],
  46334. itemsList = [[], [], [], [], [], []];
  46335. _each(items, function(_, item) {
  46336. var options = item.getLayoutOptions();
  46337. if (options)
  46338. itemsList[getCellIndex(options)].push({
  46339. item: item,
  46340. width: options.width,
  46341. height: options.height
  46342. })
  46343. });
  46344. _each(cells, function(i, cell) {
  46345. if (itemsList[i].length)
  46346. cell.items = itemsList[i];
  46347. else {
  46348. if (cell.center)
  46349. cell.rect[0] = cell.rect[2] = (cell.rect[0] + cell.rect[2]) / 2;
  46350. else
  46351. cell.rect[cell.horInv ? 0 : 2] = cell.rect[cell.horInv ? 2 : 0];
  46352. cell.rect[cell.verInv ? 1 : 3] = cell.rect[cell.verInv ? 3 : 1]
  46353. }
  46354. });
  46355. return cells
  46356. }
  46357. function adjustCellSizes(cells) {
  46358. _each([0, 1, 2, 3, 4, 5], function(_, index) {
  46359. var cell = cells[index],
  46360. otherCell = cells[(index + 3) % 6];
  46361. if (cell.items)
  46362. if (!otherCell.items) {
  46363. cell.rect[1] = _min(cell.rect[1], otherCell.rect[3]);
  46364. cell.rect[3] = _max(cell.rect[3], otherCell.rect[1])
  46365. }
  46366. });
  46367. _each([1, 4], function(_, index) {
  46368. var cell = cells[index],
  46369. otherCell1 = cells[index - 1],
  46370. otherCell2 = cells[index + 1],
  46371. size1,
  46372. size2;
  46373. if (cell.items) {
  46374. if (!otherCell1.items && !otherCell2.items) {
  46375. size1 = cell.rect[0] - otherCell1.rect[2];
  46376. size2 = otherCell2.rect[0] - cell.rect[2];
  46377. if (size1 > size2)
  46378. if (size1 / size2 >= 2) {
  46379. cell.rect[0] -= size1;
  46380. cell.right = true
  46381. }
  46382. else {
  46383. cell.rect[0] -= size2;
  46384. cell.rect[2] += size2
  46385. }
  46386. else if (size2 / size1 >= 2) {
  46387. cell.rect[2] += size2;
  46388. cell.center = null
  46389. }
  46390. else {
  46391. cell.rect[0] -= size1;
  46392. cell.rect[2] += size1
  46393. }
  46394. }
  46395. }
  46396. else {
  46397. if (otherCell1.items)
  46398. otherCell1.rect[2] = (cell.rect[0] + cell.rect[2]) / 2;
  46399. if (otherCell2.items)
  46400. otherCell2.rect[0] = (cell.rect[0] + cell.rect[2]) / 2
  46401. }
  46402. })
  46403. }
  46404. function adjustCellsAndApplyLayout(cells, forceMode) {
  46405. var hasHiddenItems = false;
  46406. adjustCellSizes(cells);
  46407. _each(cells, function(_, cell) {
  46408. if (cell.items)
  46409. hasHiddenItems = applyCellLayout(cell, forceMode) || hasHiddenItems
  46410. });
  46411. return hasHiddenItems
  46412. }
  46413. function applyCellLayout(cell, forceMode) {
  46414. var cellRect = cell.rect,
  46415. cellWidth = cellRect[2] - cellRect[0],
  46416. cellHeight = cellRect[3] - cellRect[1],
  46417. xoffset = 0,
  46418. yoffset = 0,
  46419. currentHeight = 0,
  46420. totalL = cellRect[2],
  46421. totalT = cellRect[3],
  46422. totalR = cellRect[0],
  46423. totalB = cellRect[1],
  46424. moves = [],
  46425. hasHiddenItems = false;
  46426. _each(cell.items, function(_, item) {
  46427. if (item.width > cellWidth || item.height > cellHeight) {
  46428. moves.push(null);
  46429. hasHiddenItems = true;
  46430. return forceMode || false
  46431. }
  46432. if (xoffset + item.width > cellWidth) {
  46433. yoffset += currentHeight;
  46434. xoffset = currentHeight = 0
  46435. }
  46436. if (yoffset + item.height > cellHeight) {
  46437. moves.push(null);
  46438. hasHiddenItems = true;
  46439. return forceMode || false
  46440. }
  46441. currentHeight = _max(currentHeight, item.height);
  46442. var dx = cell.horInv ? cellRect[2] - item.width - xoffset : cellRect[0] + xoffset,
  46443. dy = cell.verInv ? cellRect[3] - item.height - yoffset : cellRect[1] + yoffset;
  46444. xoffset += item.width;
  46445. totalL = _min(totalL, dx);
  46446. totalT = _min(totalT, dy);
  46447. totalR = _max(totalR, dx + item.width);
  46448. totalB = _max(totalB, dy + item.height);
  46449. moves.push([dx, dy])
  46450. });
  46451. if (forceMode || !hasHiddenItems) {
  46452. xoffset = 0;
  46453. if (cell.right)
  46454. xoffset = cellRect[2] - cellRect[0] - totalR + totalL;
  46455. else if (cell.center)
  46456. xoffset = _round((cellRect[2] - cellRect[0] - totalR + totalL) / 2);
  46457. _each(cell.items, function(i, item) {
  46458. var move = moves[i];
  46459. if (move)
  46460. item.item.locate(move[0] + xoffset, move[1]);
  46461. else
  46462. item.item.resize(null)
  46463. });
  46464. cell.rect = [totalL, totalT, totalR, totalB];
  46465. cell.items = null
  46466. }
  46467. return hasHiddenItems
  46468. }
  46469. function applyLayout(canvas, items) {
  46470. var cells = createCells(canvas, items);
  46471. if (adjustCellsAndApplyLayout(cells))
  46472. adjustCellsAndApplyLayout(cells, true)
  46473. }
  46474. function LayoutControl() {
  46475. var that = this;
  46476. that._items = [];
  46477. that._suspended = true;
  46478. that._updateLayout = function() {
  46479. that._update()
  46480. }
  46481. }
  46482. LayoutControl.prototype = {
  46483. constructor: LayoutControl,
  46484. dispose: function() {
  46485. this._items = this._updateLayout = null;
  46486. return this
  46487. },
  46488. setSize: function(width, height) {
  46489. this._size = {
  46490. width: width,
  46491. height: height
  46492. };
  46493. this._update();
  46494. return this
  46495. },
  46496. stop: function() {
  46497. this._suspended = true;
  46498. return this
  46499. },
  46500. start: function() {
  46501. this._suspended = null;
  46502. this._update();
  46503. return this
  46504. },
  46505. addItem: function(item) {
  46506. this._items.push(item);
  46507. item.updateLayout = this._updateLayout;
  46508. return this
  46509. },
  46510. removeItem: function(item) {
  46511. this._items.splice(_inArray(item, this._items), 1);
  46512. item.updateLayout = null;
  46513. return this
  46514. },
  46515. _update: function() {
  46516. if (this._suspended)
  46517. return;
  46518. var size = this._size;
  46519. _each(this._items, function(_, item) {
  46520. item.resize(size)
  46521. });
  46522. applyLayout({
  46523. left: 0,
  46524. top: 0,
  46525. right: size.width,
  46526. bottom: size.height
  46527. }, this._items)
  46528. }
  46529. };
  46530. DX.viz.map.dxVectorMap.prototype._factory.createLayoutControl = function() {
  46531. return new LayoutControl
  46532. };
  46533. DX.viz.map._tests.LayoutControl = LayoutControl
  46534. })(DevExpress, jQuery);
  46535. /*! Module viz-vectormap, file mapItemsManager.js */
  46536. (function(DX, $, undefined) {
  46537. var _isFinite = isFinite,
  46538. _utils = DX.utils,
  46539. _coreUtils = DX.viz.core.utils,
  46540. _isString = _utils.isString,
  46541. _isArray = _utils.isArray,
  46542. _isFunction = _utils.isFunction,
  46543. _patchFontOptions = _coreUtils.patchFontOptions,
  46544. _parseScalar = _coreUtils.parseScalar,
  46545. _extend = $.extend,
  46546. _each = $.each,
  46547. _map = $.map;
  46548. var SELECTIONS = {
  46549. none: null,
  46550. single: -1,
  46551. multiple: NaN
  46552. };
  46553. function getSelection(selectionMode) {
  46554. var selection = String(selectionMode).toLowerCase();
  46555. selection = selection in SELECTIONS ? SELECTIONS[selection] : SELECTIONS.single;
  46556. if (selection !== null)
  46557. selection = {
  46558. state: {},
  46559. single: selection || null
  46560. };
  46561. return selection
  46562. }
  46563. function createEventTriggers(context, trigger, names) {
  46564. context.raiseHoverChanged = function(handle, state) {
  46565. trigger(names.hoverChanged, {
  46566. target: handle.proxy,
  46567. state: state
  46568. })
  46569. };
  46570. context.raiseSelectionChanged = function(handle) {
  46571. trigger(names.selectionChanged, {target: handle.proxy})
  46572. }
  46573. }
  46574. var MapItemsManager = DX.Class.inherit({
  46575. _rootClass: null,
  46576. ctor: function(parameters) {
  46577. var that = this;
  46578. that._params = parameters;
  46579. that._init();
  46580. parameters.projection.on({
  46581. project: function() {
  46582. that._reproject()
  46583. },
  46584. transform: function(transform) {
  46585. that._transform(transform);
  46586. that._relocate()
  46587. },
  46588. center: function(_, transform) {
  46589. that._transform(transform)
  46590. },
  46591. zoom: function(_, transform) {
  46592. that._transform(transform);
  46593. that._relocate()
  46594. }
  46595. })
  46596. },
  46597. _init: function() {
  46598. var that = this;
  46599. that._context = {
  46600. renderer: that._params.renderer,
  46601. projection: that._params.projection,
  46602. dataKey: that._params.dataKey,
  46603. selection: null,
  46604. getItemSettings: that._createItemSettingsBuilder()
  46605. };
  46606. that._initRoot();
  46607. createEventTriggers(that._context, that._params.eventTrigger, that._eventNames)
  46608. },
  46609. _createItemSettingsBuilder: function() {
  46610. var that = this;
  46611. return function(proxy, settings) {
  46612. var result = {};
  46613. _each(that._grouping, function(settingField, grouping) {
  46614. var value,
  46615. index;
  46616. if (_isFinite(value = grouping.callback(proxy)) && (index = findGroupPosition(value, grouping.groups)) >= 0)
  46617. result[settingField] = grouping.groups[index][settingField]
  46618. });
  46619. return that._getItemSettings(proxy, _extend({}, settings, result))
  46620. }
  46621. },
  46622. _initRoot: function() {
  46623. this._context.root = this._root = this._params.renderer.g().attr({"class": this._rootClass})
  46624. },
  46625. dispose: function() {
  46626. var that = this;
  46627. that._destroyHandles();
  46628. that._params = that._context = that._grouping = null;
  46629. that._disposeRoot();
  46630. return that
  46631. },
  46632. _disposeRoot: function() {
  46633. this._root = null
  46634. },
  46635. clean: function() {
  46636. var that = this;
  46637. that._destroyItems();
  46638. that._removeRoot();
  46639. that._rendered = false;
  46640. return that
  46641. },
  46642. _removeRoot: function() {
  46643. this._root.remove()
  46644. },
  46645. setOptions: function(options) {
  46646. var that = this;
  46647. that._processOptions(options || {});
  46648. that._params.notifyDirty();
  46649. that._destroyItems();
  46650. that._createItems(that._params.notifyReady);
  46651. return that
  46652. },
  46653. render: function() {
  46654. var that = this;
  46655. that._rendered = true;
  46656. that._params.notifyDirty();
  46657. that._appendRoot();
  46658. that._createItems(that._params.notifyReady, true);
  46659. return that
  46660. },
  46661. _processOptions: function(options) {
  46662. var that = this,
  46663. settings = that._commonSettings = that._getCommonSettings(options),
  46664. context = that._context;
  46665. that._customizeCallback = _isFunction(settings.customize) ? settings.customize : $.noop;
  46666. context.hover = !!_parseScalar(settings.hoverEnabled, true);
  46667. if (context.selection)
  46668. _each(context.selection.state, function(_, handle) {
  46669. handle && handle.resetSelected()
  46670. });
  46671. context.selection = getSelection(settings.selectionMode);
  46672. that._grouping = {};
  46673. that._updateGrouping()
  46674. },
  46675. _appendRoot: function() {
  46676. this._root.append(this._params.container)
  46677. },
  46678. _destroyItems: function() {
  46679. var that = this;
  46680. that._clearRoot();
  46681. clearTimeout(that._labelsTimeout);
  46682. that._rendered && that._handles && _each(that._handles, function(_, handle) {
  46683. if (handle.item) {
  46684. handle.item.dispose();
  46685. handle.item = null
  46686. }
  46687. })
  46688. },
  46689. _clearRoot: function() {
  46690. this._root.clear()
  46691. },
  46692. _destroyHandles: function() {
  46693. this._handles && _each(this._handles, function(_, handle) {
  46694. handle.dispose()
  46695. });
  46696. this._handles = null
  46697. },
  46698. _createHandles: function(source) {
  46699. var that = this;
  46700. if (_isArray(source))
  46701. that._handles = _map(source, function(dataItem, i) {
  46702. dataItem = dataItem || {};
  46703. var handle = new MapItemHandle(that._context, that._getItemCoordinates(dataItem), that._getItemAttributes(dataItem), i, that._itemType),
  46704. proxy = handle.proxy;
  46705. that._initProxy(proxy, dataItem);
  46706. handle.settings = that._customizeCallback.call(proxy, proxy) || {};
  46707. if (handle.settings.isSelected)
  46708. proxy.selected(true);
  46709. return handle
  46710. })
  46711. },
  46712. _createItems: function(notifyReady) {
  46713. var that = this,
  46714. selectedItems = [],
  46715. immediateReady = true;
  46716. if (that._rendered && that._handles) {
  46717. _each(that._handles, function(_, handle) {
  46718. handle.item = that._createItem(handle.proxy).init(that._context, handle.proxy).project().update(handle.settings).locate();
  46719. if (handle.proxy.selected())
  46720. selectedItems.push(handle.item)
  46721. });
  46722. _each(selectedItems, function(_, item) {
  46723. item.setSelectedState()
  46724. });
  46725. that._arrangeItems();
  46726. if (that._commonSettings.label.enabled) {
  46727. immediateReady = false;
  46728. clearTimeout(that._labelsTimeout);
  46729. that._labelsTimeout = setTimeout(function() {
  46730. _each(that._handles, function(_, handle) {
  46731. handle.item.createLabel()
  46732. });
  46733. notifyReady()
  46734. })
  46735. }
  46736. }
  46737. immediateReady && notifyReady()
  46738. },
  46739. _processSource: null,
  46740. setData: function(data) {
  46741. var that = this;
  46742. that._params.notifyDirty();
  46743. if (_isString(data))
  46744. $.getJSON(data).done(updateSource).fail(function() {
  46745. updateSource(null)
  46746. });
  46747. else
  46748. updateSource(data);
  46749. return that;
  46750. function updateSource(source) {
  46751. if (that._rendered)
  46752. that._params.tracker.reset();
  46753. that._destroyItems();
  46754. that._destroyHandles();
  46755. that._createHandles(that._processSource(source));
  46756. that._createItems(that._params.notifyReady)
  46757. }
  46758. },
  46759. _transform: function(transform) {
  46760. this._root.attr(transform)
  46761. },
  46762. _reproject: function() {
  46763. this._rendered && this._handles && _each(this._handles, function(_, handle) {
  46764. handle.item.project().locate()
  46765. })
  46766. },
  46767. _relocate: function() {
  46768. this._rendered && this._handles && _each(this._handles, function(_, handle) {
  46769. handle.item.locate()
  46770. })
  46771. },
  46772. hoverItem: function(index, state) {
  46773. this._handles[index].setHovered(state);
  46774. return this
  46775. },
  46776. selectItem: function(index, state, noCallback) {
  46777. this._handles[index].setSelected(state, noCallback);
  46778. return this
  46779. },
  46780. clearSelection: function() {
  46781. var selection = this._context.selection;
  46782. if (selection)
  46783. _each(selection.state, function(_, handle) {
  46784. handle && handle.setSelected(false)
  46785. });
  46786. return this
  46787. },
  46788. raiseClick: function(index, $event) {
  46789. this._params.eventTrigger(this._eventNames.click, {
  46790. target: this._handles[index].proxy,
  46791. jQueryEvent: $event
  46792. });
  46793. return this
  46794. },
  46795. getProxyItems: function() {
  46796. return _map(this._handles, function(handle) {
  46797. return handle.proxy
  46798. })
  46799. },
  46800. getProxyItem: function(index) {
  46801. return this._handles[index].proxy
  46802. },
  46803. _performGrouping: function(partition, settingField, valueCallback, valuesCallback) {
  46804. var groups = createGroups(partition),
  46805. values;
  46806. if (groups) {
  46807. values = valuesCallback(groups.length);
  46808. _each(groups, function(i, group) {
  46809. group.index = i;
  46810. group[settingField] = values[i]
  46811. });
  46812. this._grouping[settingField] = {
  46813. callback: valueCallback,
  46814. groups: groups
  46815. }
  46816. }
  46817. else {
  46818. delete this._grouping[settingField];
  46819. groups = []
  46820. }
  46821. this._params.dataExchanger.set(this._dataCategory, settingField, groups)
  46822. },
  46823. _groupByColor: function(colorGroups, palette, valueCallback) {
  46824. this._performGrouping(colorGroups, "color", valueCallback, function(count) {
  46825. var _palette = new DX.viz.core.GradientPalette(palette, count),
  46826. i = 0,
  46827. list = [];
  46828. for (; i < count; ++i)
  46829. list.push(_palette.getColor(i));
  46830. return list
  46831. })
  46832. }
  46833. });
  46834. MapItemsManager.prototype.TEST_getContext = function() {
  46835. return this._context
  46836. };
  46837. MapItemsManager.prototype.TEST_performGrouping = MapItemsManager.prototype._performGrouping;
  46838. MapItemsManager.prototype.TEST_groupByColor = MapItemsManager.prototype._groupByColor;
  46839. DX.viz.map._internal.mapItemBehavior = {
  46840. init: function(ctx, proxy) {
  46841. var that = this;
  46842. that._ctx = ctx;
  46843. that._data = {
  46844. index: proxy.index,
  46845. type: proxy.type
  46846. };
  46847. that._proxy = proxy;
  46848. that._root = that._createRoot().append(that._ctx.root);
  46849. return that
  46850. },
  46851. dispose: function() {
  46852. disposeItem(this);
  46853. return this
  46854. },
  46855. project: function() {
  46856. var that = this;
  46857. that._coords = that._project(that._ctx.projection, that._proxy.coordinates());
  46858. return this
  46859. },
  46860. locate: function() {
  46861. var that = this;
  46862. that._locate(that._transform(that._ctx.projection, that._coords));
  46863. that._label && that._label.value && that._locateLabel();
  46864. return that
  46865. },
  46866. update: function(settings) {
  46867. var that = this;
  46868. that._settings = that._ctx.getItemSettings(that._proxy, settings);
  46869. that._update(that._settings);
  46870. that._label && that._updateLabel();
  46871. return that
  46872. },
  46873. createLabel: function() {
  46874. var that = this;
  46875. that._label = {
  46876. root: that._createLabelRoot(),
  46877. text: that._ctx.renderer.text(),
  46878. tracker: that._ctx.renderer.rect().attr({
  46879. stroke: "none",
  46880. "stroke-width": 0,
  46881. fill: "#000000",
  46882. opacity: 0.0001
  46883. }).data(that._ctx.dataKey, that._data)
  46884. };
  46885. that._updateLabel();
  46886. return that
  46887. },
  46888. _updateLabel: function() {
  46889. var that = this,
  46890. settings = that._settings.label;
  46891. that._label.value = String(this._proxy.text || this._proxy.attribute(this._settings.label.dataField) || "");
  46892. if (that._label.value) {
  46893. that._label.text.attr({
  46894. text: that._label.value,
  46895. x: 0,
  46896. y: 0
  46897. }).css(_patchFontOptions(settings.font)).attr({
  46898. align: "center",
  46899. stroke: settings.stroke,
  46900. "stroke-width": settings["stroke-width"],
  46901. "stroke-opacity": settings["stroke-opacity"]
  46902. }).append(that._label.root);
  46903. that._label.tracker.append(that._label.root);
  46904. that._adjustLabel();
  46905. that._locateLabel()
  46906. }
  46907. }
  46908. };
  46909. var MapItemHandle = function(context, coordinates, attributes, index, type) {
  46910. var handle = this;
  46911. handle._ctx = context;
  46912. handle._idx = index;
  46913. handle._hovered = handle._selected = false;
  46914. attributes = _extend({}, attributes);
  46915. handle.proxy = {
  46916. index: index,
  46917. type: type,
  46918. coordinates: function() {
  46919. return coordinates
  46920. },
  46921. attribute: function(name, value) {
  46922. if (arguments.length > 1) {
  46923. attributes[name] = value;
  46924. return this
  46925. }
  46926. else
  46927. return arguments.length > 0 ? attributes[name] : attributes
  46928. },
  46929. selected: function(state, _noEvent) {
  46930. if (arguments.length > 0) {
  46931. handle.setSelected(!!state, _noEvent);
  46932. return this
  46933. }
  46934. else
  46935. return handle._selected
  46936. },
  46937. applySettings: function(settings) {
  46938. _extend(true, handle.settings, settings);
  46939. handle.item && handle.item.update(handle.settings);
  46940. return this
  46941. }
  46942. }
  46943. };
  46944. MapItemHandle.prototype = {
  46945. constructor: MapItemHandle,
  46946. dispose: function() {
  46947. disposeItem(this.proxy);
  46948. disposeItem(this);
  46949. return this
  46950. },
  46951. setHovered: function(state) {
  46952. state = !!state;
  46953. var that = this;
  46954. if (that._ctx.hover && that._hovered !== state) {
  46955. that._hovered = state;
  46956. if (that.item) {
  46957. if (that._hovered)
  46958. that.item.onHover();
  46959. if (!that._selected) {
  46960. that.item[that._hovered ? "setHoveredState" : "setDefaultState"]();
  46961. that._ctx.raiseHoverChanged(that, that._hovered)
  46962. }
  46963. }
  46964. }
  46965. return that
  46966. },
  46967. resetSelected: function() {
  46968. this._selected = false;
  46969. return this
  46970. },
  46971. setSelected: function(state, _noEvent) {
  46972. state = !!state;
  46973. var that = this,
  46974. context = that._ctx,
  46975. selection = that._ctx.selection,
  46976. tmp;
  46977. if (selection && that._selected !== state) {
  46978. that._selected = state;
  46979. tmp = selection.state[selection.single];
  46980. selection.state[selection.single] = null;
  46981. if (tmp)
  46982. tmp.setSelected(false);
  46983. selection.state[selection.single || that._idx] = state ? that : null;
  46984. if (that.item) {
  46985. that.item[state ? "setSelectedState" : that._hovered ? "setHoveredState" : "setDefaultState"]();
  46986. if (!_noEvent)
  46987. context.raiseSelectionChanged(that)
  46988. }
  46989. }
  46990. return that
  46991. }
  46992. };
  46993. function disposeItem(item) {
  46994. _each(item, function(name) {
  46995. item[name] = null
  46996. })
  46997. }
  46998. function createGroups(partition) {
  46999. var i,
  47000. ii,
  47001. groups = null;
  47002. if (_isArray(partition) && partition.length > 1) {
  47003. groups = [];
  47004. for (i = 0, ii = partition.length - 1; i < ii; ++i)
  47005. groups.push({
  47006. start: Number(partition[i]),
  47007. end: Number(partition[i + 1])
  47008. })
  47009. }
  47010. return groups
  47011. }
  47012. function findGroupPosition(value, groups) {
  47013. var i = 0,
  47014. ii = groups.length;
  47015. for (; i < ii; ++i)
  47016. if (groups[i].start <= value && value <= groups[i].end)
  47017. return i;
  47018. return -1
  47019. }
  47020. _extend(DX.viz.map._tests, {
  47021. MapItemsManager: MapItemsManager,
  47022. MapItemHandle: MapItemHandle,
  47023. stubMapItemHandle: function(mapItemHandleType) {
  47024. MapItemHandle = mapItemHandleType
  47025. },
  47026. restoreMapItemHandle: function() {
  47027. MapItemHandle = DX.viz.map._tests.MapItemHandle
  47028. }
  47029. });
  47030. DX.viz.map.dxVectorMap.prototype._factory.MapItemsManager = MapItemsManager
  47031. })(DevExpress, jQuery);
  47032. /*! Module viz-vectormap, file areasManager.js */
  47033. (function(DX, $, undefined) {
  47034. var _abs = Math.abs,
  47035. _sqrt = Math.sqrt,
  47036. _noop = $.noop,
  47037. TOLERANCE = 1;
  47038. var AreasManager = DX.viz.map.dxVectorMap.prototype._factory.MapItemsManager.inherit({
  47039. _rootClass: "dxm-areas",
  47040. _dataCategory: "areas",
  47041. _eventNames: {
  47042. click: "areaClick",
  47043. hoverChanged: "areaHoverChanged",
  47044. selectionChanged: "areaSelectionChanged"
  47045. },
  47046. _initRoot: function() {
  47047. var that = this;
  47048. that.callBase.apply(that, arguments);
  47049. that._context.labelRoot = that._labelRoot = that._params.renderer.g().attr({"class": "dxm-area-labels"})
  47050. },
  47051. _disposeRoot: function() {
  47052. this.callBase.apply(this, arguments);
  47053. this._labelRoot = null
  47054. },
  47055. _processSource: function(source) {
  47056. var isGeoJson = source && source.type === "FeatureCollection";
  47057. this._getItemCoordinates = isGeoJson ? getCoordinatesGeoJson : getCoordinatesDefault;
  47058. this._getItemAttributes = isGeoJson ? getAttributesGeoJson : getAttributesDefault;
  47059. return isGeoJson ? source.features : source
  47060. },
  47061. _getCommonSettings: function(options) {
  47062. return this._params.themeManager.getCommonAreaSettings(options)
  47063. },
  47064. _initProxy: _noop,
  47065. _itemType: "area",
  47066. _removeRoot: function() {
  47067. this.callBase.apply(this, arguments);
  47068. this._labelRoot.remove()
  47069. },
  47070. _appendRoot: function() {
  47071. var that = this;
  47072. that.callBase.apply(that, arguments);
  47073. if (that._commonSettings.label.enabled)
  47074. that._labelRoot.append(that._params.container)
  47075. },
  47076. _clearRoot: function() {
  47077. this.callBase.apply(this, arguments);
  47078. this._labelRoot.clear()
  47079. },
  47080. _getItemSettings: function(_, options) {
  47081. return this._params.themeManager.getAreaSettings(this._commonSettings, options)
  47082. },
  47083. _transform: function(transform) {
  47084. this.callBase.apply(this, arguments);
  47085. this._labelRoot.attr(transform)
  47086. },
  47087. _createItem: function() {
  47088. return new Area
  47089. },
  47090. _updateGrouping: function() {
  47091. var commonSettings = this._commonSettings,
  47092. attributeName = commonSettings.colorGroupingField;
  47093. this._groupByColor(commonSettings.colorGroups, commonSettings.palette, function(proxy) {
  47094. return proxy.attribute(attributeName)
  47095. })
  47096. },
  47097. _arrangeItems: _noop
  47098. });
  47099. function getCoordinatesDefault(dataItem) {
  47100. return dataItem.coordinates
  47101. }
  47102. function getCoordinatesGeoJson(dataItem) {
  47103. var coordinates,
  47104. type;
  47105. if (dataItem.geometry) {
  47106. type = dataItem.geometry.type;
  47107. coordinates = dataItem.geometry.coordinates;
  47108. if (coordinates && (type === "Polygon" || type === "MultiPolygon"))
  47109. type === "MultiPolygon" && (coordinates = [].concat.apply([], coordinates));
  47110. else
  47111. coordinates = undefined
  47112. }
  47113. return coordinates
  47114. }
  47115. function getAttributesDefault(dataItem) {
  47116. return dataItem.attributes
  47117. }
  47118. function getAttributesGeoJson(dataItem) {
  47119. return dataItem.properties
  47120. }
  47121. function Area(){}
  47122. $.extend(Area.prototype, DX.viz.map._internal.mapItemBehavior, {
  47123. _project: function(projection, coords) {
  47124. return projection.projectArea(coords)
  47125. },
  47126. _createRoot: function() {
  47127. return this._ctx.renderer.path([], "area").data(this._ctx.dataKey, this._data)
  47128. },
  47129. _update: function(settings) {
  47130. this._styles = {
  47131. normal: {
  47132. "class": "dxm-area",
  47133. stroke: settings.borderColor,
  47134. "stroke-width": settings.borderWidth,
  47135. fill: settings.color
  47136. },
  47137. hovered: {
  47138. "class": "dxm-area dxm-area-hovered",
  47139. stroke: settings.hoveredBorderColor,
  47140. "stroke-width": settings.hoveredBorderWidth,
  47141. fill: settings.hoveredColor
  47142. },
  47143. selected: {
  47144. "class": "dxm-area dxm-area-selected",
  47145. stroke: settings.selectedBorderColor,
  47146. "stroke-width": settings.selectedBorderWidth,
  47147. fill: settings.selectedColor
  47148. }
  47149. };
  47150. this._root.attr(this._styles.normal);
  47151. return this
  47152. },
  47153. _transform: function(projection, coords) {
  47154. return projection.getAreaCoordinates(coords)
  47155. },
  47156. _locate: function(coords) {
  47157. this._root.attr({points: coords})
  47158. },
  47159. onHover: _noop,
  47160. setDefaultState: function() {
  47161. this._root.attr(this._styles.normal).toBackground()
  47162. },
  47163. setHoveredState: function() {
  47164. this._root.attr(this._styles.hovered).toForeground()
  47165. },
  47166. setSelectedState: function() {
  47167. this._root.attr(this._styles.selected).toForeground()
  47168. },
  47169. _createLabelRoot: function() {
  47170. return this._ctx.renderer.g().attr({"class": "dxm-area-label"}).append(this._ctx.labelRoot)
  47171. },
  47172. _adjustLabel: function() {
  47173. var that = this,
  47174. centroid = calculateAreaCentroid(that._coords),
  47175. bbox = that._label.text.getBBox(),
  47176. offset = -bbox.y - bbox.height / 2;
  47177. that._centroid = centroid.coords;
  47178. that._areaSize = _sqrt(centroid.area);
  47179. that._labelSize = [bbox.width, bbox.height];
  47180. that._label.text.attr({y: offset});
  47181. that._label.tracker.attr({
  47182. x: bbox.x,
  47183. y: bbox.y + offset,
  47184. width: bbox.width,
  47185. height: bbox.height
  47186. })
  47187. },
  47188. _locateLabel: function() {
  47189. var that = this,
  47190. coords = that._ctx.projection.getPointCoordinates(that._centroid),
  47191. size = that._ctx.projection.getSquareSize([that._areaSize, that._areaSize]);
  47192. that._label.root.attr({
  47193. translateX: coords.x,
  47194. translateY: coords.y,
  47195. visibility: that._labelSize[0] / size[0] < TOLERANCE && that._labelSize[1] / size[1] < TOLERANCE ? null : "hidden"
  47196. })
  47197. }
  47198. });
  47199. function calculatePolygonCentroid(coordinates) {
  47200. var i = 0,
  47201. ii = coordinates.length,
  47202. v1,
  47203. v2 = coordinates[ii - 1],
  47204. cross,
  47205. cx = 0,
  47206. cy = 0,
  47207. area = 0;
  47208. for (; i < ii; ++i) {
  47209. v1 = v2;
  47210. v2 = coordinates[i];
  47211. cross = v1[0] * v2[1] - v2[0] * v1[1];
  47212. area += cross;
  47213. cx += (v1[0] + v2[0]) * cross;
  47214. cy += (v1[1] + v2[1]) * cross
  47215. }
  47216. area /= 2;
  47217. cx /= 6 * area;
  47218. cy /= 6 * area;
  47219. return {
  47220. coords: [cx, cy],
  47221. area: _abs(area)
  47222. }
  47223. }
  47224. function calculateAreaCentroid(coordinates) {
  47225. var i = 0,
  47226. ii = coordinates.length,
  47227. centroid,
  47228. resultCentroid,
  47229. maxArea = 0;
  47230. for (; i < ii; ++i) {
  47231. centroid = calculatePolygonCentroid(coordinates[i]);
  47232. if (centroid.area > maxArea) {
  47233. maxArea = centroid.area;
  47234. resultCentroid = centroid
  47235. }
  47236. }
  47237. return resultCentroid
  47238. }
  47239. DX.viz.map._internal.AreasManager = AreasManager;
  47240. DX.viz.map._internal.Area = Area;
  47241. DX.viz.map._tests.AreasManager = AreasManager;
  47242. DX.viz.map._tests.Area = Area;
  47243. DX.viz.map.dxVectorMap.prototype._factory.createAreasManager = function(parameters) {
  47244. return new AreasManager(parameters)
  47245. }
  47246. })(DevExpress, jQuery);
  47247. /*! Module viz-vectormap, file markersManager.js */
  47248. (function(DX, $, undefined) {
  47249. var _Number = Number,
  47250. _String = String,
  47251. _isFinite = isFinite,
  47252. _math = Math,
  47253. _round = _math.round,
  47254. _max = _math.max,
  47255. _min = _math.min,
  47256. _extend = $.extend,
  47257. _each = $.each,
  47258. _isArray = DX.utils.isArray,
  47259. CLASS_DEFAULT = "dxm-marker",
  47260. CLASS_HOVERED = "dxm-marker dxm-marker-hovered",
  47261. CLASS_SELECTED = "dxm-marker dxm-marker-selected",
  47262. DOT = "dot",
  47263. BUBBLE = "bubble",
  47264. PIE = "pie",
  47265. IMAGE = "image",
  47266. DEFAULT_MARKER_TYPE = null,
  47267. MARKER_TYPES = {};
  47268. var MarkersManager = DX.viz.map.dxVectorMap.prototype._factory.MapItemsManager.inherit({
  47269. _rootClass: "dxm-markers",
  47270. _dataCategory: "markers",
  47271. _eventNames: {
  47272. click: "markerClick",
  47273. hoverChanged: "markerHoverChanged",
  47274. selectionChanged: "markerSelectionChanged"
  47275. },
  47276. _init: function() {
  47277. var that = this;
  47278. that.callBase.apply(that, arguments);
  47279. that._context.getPieColors = function(count) {
  47280. return that._params.themeManager.getPieColors(that._commonSettings, count)
  47281. };
  47282. that._filter = that._params.renderer.shadowFilter("-40%", "-40%", "180%", "200%", 0, 1, 1, "#000000", 0.2)
  47283. },
  47284. _dispose: function() {
  47285. this.callBase.apply(this, arguments);
  47286. this._filter.dispose();
  47287. this._filter = null
  47288. },
  47289. _getItemCoordinates: function(dataItem) {
  47290. return dataItem.coordinates
  47291. },
  47292. _getItemAttributes: function(dataItem) {
  47293. return dataItem.attributes
  47294. },
  47295. _processSource: function(source) {
  47296. return source
  47297. },
  47298. _getCommonSettings: function(options) {
  47299. return this._params.themeManager.getCommonMarkerSettings(options)
  47300. },
  47301. _processOptions: function(options) {
  47302. var that = this;
  47303. that._commonType = parseMarkerType(options && options.type, DEFAULT_MARKER_TYPE);
  47304. that.callBase.apply(that, arguments);
  47305. that._commonSettings._filter = that._filter.ref
  47306. },
  47307. _arrangeBubbles: function() {
  47308. var markers = this._handles,
  47309. bubbles = [],
  47310. i,
  47311. ii = markers.length,
  47312. marker,
  47313. values = [],
  47314. minValue,
  47315. maxValue,
  47316. deltaValue;
  47317. if (this._commonSettings._bubble.sizeGroups)
  47318. return;
  47319. for (i = 0; i < ii; ++i) {
  47320. marker = markers[i];
  47321. if (marker.item.type === BUBBLE) {
  47322. bubbles.push(marker);
  47323. if (_isFinite(marker.proxy.value))
  47324. values.push(marker.proxy.value)
  47325. }
  47326. }
  47327. minValue = _min.apply(null, values);
  47328. maxValue = _max.apply(null, values);
  47329. deltaValue = maxValue - minValue || 1;
  47330. for (i = 0, ii = bubbles.length; i < ii; ++i) {
  47331. marker = bubbles[i];
  47332. marker.item.setSize(_isFinite(marker.proxy.value) ? (marker.proxy.value - minValue) / deltaValue : 0)
  47333. }
  47334. },
  47335. _itemType: "marker",
  47336. _initProxy: function(proxy, dataItem) {
  47337. _each(dataItem, function(name, value) {
  47338. if (proxy[name] === undefined)
  47339. proxy[name] = value
  47340. });
  47341. proxy._TYPE = parseMarkerType(dataItem.type, null)
  47342. },
  47343. _getItemSettings: function(proxy, options) {
  47344. var type = proxy._TYPE || this._commonType,
  47345. settings = this._params.themeManager.getMarkerSettings(this._commonSettings, _extend({}, proxy.style, options), type);
  47346. proxy.text = proxy.text || settings.text;
  47347. return settings
  47348. },
  47349. _createItem: function(proxy) {
  47350. return new MARKER_TYPES[proxy._TYPE || this._commonType]
  47351. },
  47352. _updateGrouping: function() {
  47353. var that = this,
  47354. markerType = that._commonType,
  47355. colorDataField,
  47356. sizeDataField,
  47357. commonSettings = that._commonSettings["_" + markerType];
  47358. if (markerType === DOT || markerType === BUBBLE) {
  47359. colorDataField = commonSettings.colorGroupingField;
  47360. that._groupByColor(commonSettings.colorGroups, commonSettings.palette, function(proxy) {
  47361. return !proxy._TYPE || proxy._TYPE === markerType ? proxy.attribute(colorDataField) : NaN
  47362. })
  47363. }
  47364. sizeDataField = commonSettings.sizeGroupingField;
  47365. that._performGrouping(commonSettings.sizeGroups, "size", function(proxy) {
  47366. return !proxy._TYPE || proxy._TYPE === markerType ? proxy.value || proxy.attribute(sizeDataField) : NaN
  47367. }, function(count) {
  47368. var minSize = commonSettings.minSize > 0 ? _Number(commonSettings.minSize) : 0,
  47369. maxSize = commonSettings.maxSize >= minSize ? _Number(commonSettings.maxSize) : 0,
  47370. i = 0,
  47371. sizes = [];
  47372. for (i = 0; i < count; ++i)
  47373. sizes.push((minSize * (count - i - 1) + maxSize * i) / (count - 1));
  47374. return sizes
  47375. })
  47376. },
  47377. _updateLegendForPies: function() {
  47378. var count = 0;
  47379. _each(this._handles, function(_, handle) {
  47380. var proxy = handle.proxy,
  47381. values;
  47382. if (!proxy._TYPE || proxy._TYPE === PIE) {
  47383. values = proxy.values;
  47384. if (values && values.length > count)
  47385. count = values.length
  47386. }
  47387. });
  47388. if (count > 0)
  47389. this._params.dataExchanger.set(this._dataCategory, "color", $.map(this._context.getPieColors(count).slice(0, count), function(color, i) {
  47390. return {
  47391. index: i,
  47392. color: color
  47393. }
  47394. }))
  47395. },
  47396. _arrangeItems: function() {
  47397. this._arrangeBubbles();
  47398. this._updateLegendForPies()
  47399. }
  47400. });
  47401. var baseMarkerBehavior = _extend({}, DX.viz.map._internal.mapItemBehavior, {
  47402. _project: function(projection, coords) {
  47403. return projection.projectPoint(coords)
  47404. },
  47405. _createRoot: function() {
  47406. return this._ctx.renderer.g()
  47407. },
  47408. _update: function(settings) {
  47409. var that = this;
  47410. that._root.attr({"class": CLASS_DEFAULT}).clear();
  47411. that._create(settings, that._ctx.renderer, that._root);
  47412. return that
  47413. },
  47414. _transform: function(projection, coords) {
  47415. return projection.getPointCoordinates(coords)
  47416. },
  47417. _locate: function(coords) {
  47418. this._root.attr({
  47419. translateX: coords.x,
  47420. translateY: coords.y
  47421. })
  47422. },
  47423. onHover: function() {
  47424. this._root.toForeground()
  47425. },
  47426. setDefaultState: function() {
  47427. this._root.attr({"class": CLASS_DEFAULT}).toBackground();
  47428. this._applyDefault()
  47429. },
  47430. setHoveredState: function() {
  47431. this._root.attr({"class": CLASS_HOVERED});
  47432. this._applyHovered()
  47433. },
  47434. setSelectedState: function() {
  47435. this._root.attr({"class": CLASS_SELECTED}).toForeground();
  47436. this._applySelected()
  47437. },
  47438. _createLabelRoot: function() {
  47439. return this._root
  47440. },
  47441. _adjustLabel: function() {
  47442. var bbox = this._label.text.getBBox(),
  47443. x = _round(-bbox.x + this._size / 2) + 2,
  47444. y = _round(-bbox.y - bbox.height / 2) - 1;
  47445. this._label.text.attr({
  47446. x: x,
  47447. y: y
  47448. });
  47449. this._label.tracker.attr({
  47450. x: x + bbox.x - 1,
  47451. y: y + bbox.y - 1,
  47452. width: bbox.width + 2,
  47453. height: bbox.height + 2
  47454. })
  47455. },
  47456. _locateLabel: $.noop
  47457. });
  47458. function DotMarker(){}
  47459. _extend(DotMarker.prototype, baseMarkerBehavior, {
  47460. type: DOT,
  47461. _create: function(style, renderer, root) {
  47462. var that = this,
  47463. size = that._size = style.size > 0 ? _Number(style.size) : 0,
  47464. hoveredSize = size,
  47465. selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0),
  47466. hoveredBackSize = hoveredSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
  47467. selectedBackSize = selectedSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
  47468. r = size / 2;
  47469. that._dotDefault = {
  47470. cx: 0,
  47471. cy: 0,
  47472. r: r,
  47473. stroke: style.borderColor,
  47474. "stroke-width": style.borderWidth,
  47475. fill: style.color,
  47476. filter: style.shadow ? style._filter : null
  47477. };
  47478. that._dotHovered = {
  47479. cx: 0,
  47480. cy: 0,
  47481. r: hoveredSize / 2,
  47482. stroke: style.hoveredBorderColor,
  47483. "stroke-width": style.hoveredBorderWidth,
  47484. fill: style.hoveredColor
  47485. };
  47486. that._dotSelected = {
  47487. cx: 0,
  47488. cy: 0,
  47489. r: selectedSize / 2,
  47490. stroke: style.selectedBorderColor,
  47491. "stroke-width": style.selectedBorderWidth,
  47492. fill: style.selectedColor
  47493. };
  47494. that._backDefault = {
  47495. cx: 0,
  47496. cy: 0,
  47497. r: r,
  47498. stroke: "none",
  47499. "stroke-width": 0,
  47500. fill: style.backColor,
  47501. opacity: style.backOpacity
  47502. };
  47503. that._backHovered = {
  47504. cx: 0,
  47505. cy: 0,
  47506. r: hoveredBackSize / 2,
  47507. stroke: "none",
  47508. "stroke-width": 0,
  47509. fill: style.backColor,
  47510. opacity: style.backOpacity
  47511. };
  47512. that._backSelected = {
  47513. cx: 0,
  47514. cy: 0,
  47515. r: selectedBackSize / 2,
  47516. stroke: "none",
  47517. "stroke-width": 0,
  47518. fill: style.backColor,
  47519. opacity: style.backOpacity
  47520. };
  47521. that._back = renderer.circle().sharp().attr(that._backDefault).data(that._ctx.dataKey, that._data).append(root);
  47522. that._dot = renderer.circle().sharp().attr(that._dotDefault).data(that._ctx.dataKey, that._data).append(root)
  47523. },
  47524. _destroy: function() {
  47525. this._back = this._dot = null
  47526. },
  47527. _applyDefault: function() {
  47528. this._back.attr(this._backDefault);
  47529. this._dot.attr(this._dotDefault)
  47530. },
  47531. _applyHovered: function() {
  47532. this._back.attr(this._backHovered);
  47533. this._dot.attr(this._dotHovered)
  47534. },
  47535. _applySelected: function() {
  47536. this._back.attr(this._backSelected);
  47537. this._dot.attr(this._dotSelected)
  47538. }
  47539. });
  47540. function BubbleMarker(){}
  47541. _extend(BubbleMarker.prototype, baseMarkerBehavior, {
  47542. type: BUBBLE,
  47543. _create: function(style, renderer, root) {
  47544. var that = this;
  47545. that._minSize = style.minSize > 0 ? _Number(style.minSize) : 0;
  47546. that._maxSize = style.maxSize > that._minSize ? _Number(style.maxSize) : that._minSize;
  47547. that.value = _isFinite(that._proxy.value) ? _Number(that._proxy.value) : null;
  47548. that._default = {
  47549. stroke: style.borderColor,
  47550. "stroke-width": style.borderWidth,
  47551. fill: style.color,
  47552. opacity: style.opacity
  47553. };
  47554. that._hovered = {
  47555. stroke: style.hoveredBorderColor,
  47556. "stroke-width": style.hoveredBorderWidth,
  47557. fill: style.hoveredColor,
  47558. opacity: style.hoveredOpacity
  47559. };
  47560. that._selected = {
  47561. stroke: style.selectedBorderColor,
  47562. "stroke-width": style.selectedBorderWidth,
  47563. fill: style.selectedColor,
  47564. opacity: style.selectedOpacity
  47565. };
  47566. that._bubble = renderer.circle(0, 0, 0).sharp().attr(that._default).data(that._ctx.dataKey, that._data).append(root);
  47567. that.setSize(style.size / that._maxSize || 1)
  47568. },
  47569. _applyDefault: function() {
  47570. this._bubble.attr(this._default)
  47571. },
  47572. _applyHovered: function() {
  47573. this._bubble.attr(this._hovered)
  47574. },
  47575. _applySelected: function() {
  47576. this._bubble.attr(this._selected)
  47577. },
  47578. setSize: function(ratio) {
  47579. var that = this,
  47580. r = (that._minSize + ratio * (that._maxSize - that._minSize)) / 2;
  47581. that._default.r = that._hovered.r = that._selected.r = r;
  47582. that._size = 2 * r;
  47583. that._bubble.attr({r: r});
  47584. return that
  47585. }
  47586. });
  47587. function PieMarker(){}
  47588. _extend(PieMarker.prototype, baseMarkerBehavior, {
  47589. type: PIE,
  47590. _create: function(style, renderer, root) {
  47591. var that = this,
  47592. r = (style.size > 0 ? _Number(style.size) : 0) / 2,
  47593. srcValues,
  47594. i = 0,
  47595. ii,
  47596. values,
  47597. value,
  47598. sum = 0,
  47599. translator,
  47600. startAngle,
  47601. endAngle,
  47602. colors;
  47603. that._size = 2 * r;
  47604. that._pieDefault = {opacity: style.opacity};
  47605. that._pieHovered = {opacity: style.hoveredOpacity};
  47606. that._pieSelected = {opacity: style.selectedOpacity};
  47607. that._borderDefault = {
  47608. stroke: style.borderColor,
  47609. "stroke-width": style.borderWidth
  47610. };
  47611. that._borderHovered = {
  47612. stroke: style.hoveredBorderColor,
  47613. "stroke-width": style.hoveredBorderWidth
  47614. };
  47615. that._borderSelected = {
  47616. stroke: style.selectedBorderColor,
  47617. "stroke-width": style.selectedBorderWidth
  47618. };
  47619. srcValues = that._proxy.values;
  47620. ii = _isArray(srcValues) ? srcValues.length : 0;
  47621. values = [];
  47622. for (; i < ii; ++i) {
  47623. value = _Number(srcValues[i]);
  47624. if (_isFinite(value)) {
  47625. values.push(value);
  47626. sum += value
  47627. }
  47628. }
  47629. that._pie = renderer.g().attr(that._pieDefault);
  47630. translator = new DX.viz.core.Translator1D(0, sum, 90, 450);
  47631. startAngle = translator.translate(0);
  47632. colors = that._ctx.getPieColors(values.length);
  47633. for (value = 0, i = 0, ii = values.length; i < ii; ++i) {
  47634. value += values[i];
  47635. endAngle = translator.translate(value);
  47636. renderer.arc(0, 0, 0, r, startAngle, endAngle).attr({
  47637. "stroke-linejoin": "round",
  47638. fill: colors[i]
  47639. }).data(that._ctx.dataKey, that._data).append(that._pie);
  47640. startAngle = endAngle
  47641. }
  47642. that._pie.append(root);
  47643. that._border = renderer.circle(0, 0, r).sharp().attr(that._borderDefault).data(that._ctx.dataKey, that._data).append(root)
  47644. },
  47645. _applyDefault: function() {
  47646. this._pie.attr(this._pieDefault);
  47647. this._border.attr(this._borderDefault)
  47648. },
  47649. _applyHovered: function() {
  47650. this._pie.attr(this._pieHovered);
  47651. this._border.attr(this._borderHovered)
  47652. },
  47653. _applySelected: function() {
  47654. this._pie.attr(this._pieSelected);
  47655. this._border.attr(this._borderSelected)
  47656. }
  47657. });
  47658. function ImageMarker(){}
  47659. _extend(ImageMarker.prototype, baseMarkerBehavior, {
  47660. type: IMAGE,
  47661. _create: function(style, renderer, root) {
  47662. var that = this,
  47663. size = that._size = style.size > 0 ? _Number(style.size) : 0,
  47664. hoveredSize = size + (style.hoveredStep > 0 ? _Number(style.hoveredStep) : 0),
  47665. selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0);
  47666. that._default = {
  47667. x: -size / 2,
  47668. y: -size / 2,
  47669. width: size,
  47670. height: size
  47671. };
  47672. that._hovered = {
  47673. x: -hoveredSize / 2,
  47674. y: -hoveredSize / 2,
  47675. width: hoveredSize,
  47676. height: hoveredSize
  47677. };
  47678. that._selected = {
  47679. x: -selectedSize / 2,
  47680. y: -selectedSize / 2,
  47681. width: selectedSize,
  47682. height: selectedSize
  47683. };
  47684. that._image = renderer.image().attr(that._default).attr({
  47685. href: that._proxy.url,
  47686. location: "center"
  47687. }).append(root);
  47688. that._tracker = renderer.rect().attr(that._default).attr({
  47689. stroke: "none",
  47690. "stroke-width": 0,
  47691. fill: "#000000",
  47692. opacity: 0.0001
  47693. }).data(that._ctx.dataKey, that._data).append(root)
  47694. },
  47695. _applyDefault: function() {
  47696. this._image.attr(this._default);
  47697. this._tracker.attr(this._default)
  47698. },
  47699. _applyHovered: function() {
  47700. this._image.attr(this._hovered);
  47701. this._tracker.attr(this._hovered)
  47702. },
  47703. _applySelected: function() {
  47704. this._image.attr(this._selected);
  47705. this._tracker.attr(this._selected)
  47706. }
  47707. });
  47708. _each([DotMarker, BubbleMarker, PieMarker, ImageMarker], function(_, markerType) {
  47709. DEFAULT_MARKER_TYPE = DEFAULT_MARKER_TYPE || markerType.prototype.type;
  47710. MARKER_TYPES[markerType.prototype.type] = markerType
  47711. });
  47712. function parseMarkerType(type, defaultType) {
  47713. var _type = _String(type).toLowerCase();
  47714. return MARKER_TYPES[_type] ? _type : defaultType
  47715. }
  47716. var __originalDefaultMarkerType = DEFAULT_MARKER_TYPE,
  47717. __originalMarkerTypes = _extend({}, MARKER_TYPES);
  47718. DX.viz.map._tests.stubMarkerTypes = function(markerTypes, defaultMarkerType) {
  47719. DEFAULT_MARKER_TYPE = defaultMarkerType;
  47720. MARKER_TYPES = markerTypes
  47721. };
  47722. DX.viz.map._tests.restoreMarkerTypes = function() {
  47723. DEFAULT_MARKER_TYPE = __originalDefaultMarkerType;
  47724. MARKER_TYPES = __originalMarkerTypes
  47725. };
  47726. DX.viz.map._tests.baseMarkerBehavior = baseMarkerBehavior;
  47727. DX.viz.map._tests.MarkersManager = MarkersManager;
  47728. DX.viz.map._tests.DotMarker = DotMarker;
  47729. DX.viz.map._tests.BubbleMarker = BubbleMarker;
  47730. DX.viz.map._tests.PieMarker = PieMarker;
  47731. DX.viz.map._tests.ImageMarker = ImageMarker;
  47732. DX.viz.map.dxVectorMap.prototype._factory.createMarkersManager = function(parameters) {
  47733. return new MarkersManager(parameters)
  47734. }
  47735. })(DevExpress, jQuery);
  47736. DevExpress.MOD_VIZ_VECTORMAP = true
  47737. }
  47738. if (!DevExpress.MOD_VIZ_SPARKLINES) {
  47739. if (!DevExpress.MOD_VIZ_CORE)
  47740. throw Error('Required module is not referenced: viz-core');
  47741. /*! Module viz-sparklines, file baseSparkline.js */
  47742. (function($, DX, undefined) {
  47743. var DEFAULT_LINE_SPACING = 2,
  47744. DEFAULT_EVENTS_DELAY = 200,
  47745. TOUCH_EVENTS_DELAY = 1000,
  47746. _extend = $.extend,
  47747. _abs = Math.abs,
  47748. core = DX.viz.core;
  47749. function generateDefaultCustomizeTooltipCallback(fontOptions, rtlEnabled) {
  47750. var lineSpacing = fontOptions.lineSpacing,
  47751. lineHeight = (lineSpacing !== undefined && lineSpacing !== null ? lineSpacing : DEFAULT_LINE_SPACING) + fontOptions.size;
  47752. DX.viz.sparklines.generated_customize_tooltip = function() {
  47753. return {
  47754. lineHeight: lineHeight,
  47755. rtlEnabled: rtlEnabled
  47756. }
  47757. };
  47758. return function(customizeObject) {
  47759. var html = "",
  47760. vt = customizeObject.valueText;
  47761. for (var i = 0; i < vt.length; i += 2)
  47762. html += "<tr><td>" + vt[i] + "</td><td style='width: 15px'></td><td style='text-align: " + (rtlEnabled ? "left" : "right") + "'>" + vt[i + 1] + "</td></tr>";
  47763. return {html: "<table style='border-spacing:0px; line-height: " + lineHeight + "px'>" + html + "</table>"}
  47764. }
  47765. }
  47766. DX.viz.sparklines = {};
  47767. DX.viz.sparklines.BaseSparkline = core.BaseWidget.inherit({
  47768. _setDeprecatedOptions: function() {
  47769. this.callBase();
  47770. $.extend(this._deprecatedOptions, {
  47771. "tooltip.verticalAlignment": {
  47772. since: "15.1",
  47773. message: "Now tootips are aligned automatically"
  47774. },
  47775. "tooltip.horizontalAlignment": {
  47776. since: "15.1",
  47777. message: "Now tootips are aligned automatically"
  47778. }
  47779. })
  47780. },
  47781. _clean: function() {
  47782. var that = this;
  47783. if (that._tooltipShown) {
  47784. that._tooltipShown = false;
  47785. that._tooltip.hide()
  47786. }
  47787. that._cleanWidgetElements();
  47788. that._cleanTranslators()
  47789. },
  47790. _initCore: function() {
  47791. var that = this;
  47792. that._tooltipTracker = that._renderer.root;
  47793. that._tooltipTracker.attr({"pointer-events": "visible"});
  47794. that._createHtmlElements();
  47795. that._initTooltipEvents()
  47796. },
  47797. _initTooltip: function() {
  47798. this._initTooltipBase = this.callBase;
  47799. return
  47800. },
  47801. _getDefaultSize: function() {
  47802. return this._defaultSize
  47803. },
  47804. _isContainerVisible: function() {
  47805. return true
  47806. },
  47807. _disposeCore: function() {
  47808. this._disposeWidgetElements();
  47809. this._disposeTooltipEvents();
  47810. this._ranges = null
  47811. },
  47812. _render: function() {
  47813. this._prepareOptions();
  47814. this._updateWidgetElements();
  47815. this._drawWidgetElements()
  47816. },
  47817. _updateWidgetElements: function() {
  47818. this._updateRange();
  47819. this._updateTranslator()
  47820. },
  47821. _applySize: function() {
  47822. if (this._allOptions)
  47823. this._allOptions.size = {
  47824. width: this._canvas.width,
  47825. height: this._canvas.height
  47826. }
  47827. },
  47828. _cleanTranslators: function() {
  47829. this._translatorX = null;
  47830. this._translatorY = null
  47831. },
  47832. _setupResizeHandler: $.noop,
  47833. _resize: function() {
  47834. var that = this;
  47835. that._redrawWidgetElements();
  47836. if (that._tooltipShown) {
  47837. that._tooltipShown = false;
  47838. that._tooltip.hide()
  47839. }
  47840. that._drawn()
  47841. },
  47842. _prepareOptions: function() {
  47843. return _extend(true, {}, this._themeManager.theme(), this.option())
  47844. },
  47845. _createThemeManager: function() {
  47846. var themeManager = new DX.viz.core.BaseThemeManager;
  47847. themeManager._themeSection = this._widgetType;
  47848. themeManager._fontFields = ["tooltip.font"];
  47849. return themeManager
  47850. },
  47851. _getTooltipCoords: function() {
  47852. var canvas = this._canvas,
  47853. rootOffset = this._renderer.getRootOffset();
  47854. return {
  47855. x: canvas.width / 2 + rootOffset.left,
  47856. y: canvas.height / 2 + rootOffset.top
  47857. }
  47858. },
  47859. _initTooltipEvents: function() {
  47860. var that = this,
  47861. data = {widget: that};
  47862. that._showTooltipCallback = function() {
  47863. var tooltip;
  47864. that._showTooltipTimeout = null;
  47865. if (!that._tooltipShown) {
  47866. that._tooltipShown = true;
  47867. tooltip = that._getTooltip();
  47868. tooltip.isEnabled() && that._tooltip.show(that._getTooltipData(), that._getTooltipCoords(), {})
  47869. }
  47870. that._DEBUG_showCallback && that._DEBUG_showCallback()
  47871. };
  47872. that._hideTooltipCallback = function() {
  47873. var tooltipWasShown = that._tooltipShown;
  47874. that._hideTooltipTimeout = null;
  47875. if (that._tooltipShown) {
  47876. that._tooltipShown = false;
  47877. that._tooltip.hide()
  47878. }
  47879. that._DEBUG_hideCallback && that._DEBUG_hideCallback(tooltipWasShown)
  47880. };
  47881. that._disposeCallbacks = function() {
  47882. that = that._showTooltipCallback = that._hideTooltipCallback = that._disposeCallbacks = null
  47883. };
  47884. that._tooltipTracker.on(mouseEvents, data).on(touchEvents, data).on(mouseWheelEvents, data);
  47885. that._tooltipTracker.on(menuEvents)
  47886. },
  47887. _disposeTooltipEvents: function() {
  47888. var that = this;
  47889. clearTimeout(that._showTooltipTimeout);
  47890. clearTimeout(that._hideTooltipTimeout);
  47891. that._tooltipTracker.off();
  47892. that._disposeCallbacks()
  47893. },
  47894. _updateTranslator: function() {
  47895. var that = this,
  47896. canvas = this._canvas,
  47897. ranges = this._ranges;
  47898. that._translatorX = new core.Translator2D(ranges.arg, canvas, {direction: "horizontal"});
  47899. that._translatorY = new core.Translator2D(ranges.val, canvas)
  47900. },
  47901. _getTooltip: function() {
  47902. var that = this;
  47903. if (!that._tooltip) {
  47904. that._initTooltipBase();
  47905. that._setTooltipRendererOptions(that._tooltipRendererOptions);
  47906. that._tooltipRendererOptions = null;
  47907. that._setTooltipOptions()
  47908. }
  47909. return that._tooltip
  47910. },
  47911. _setTooltipRendererOptions: function(options) {
  47912. if (this._tooltip)
  47913. this._tooltip.setRendererOptions(options);
  47914. else
  47915. this._tooltipRendererOptions = options
  47916. },
  47917. _setTooltipOptions: function() {
  47918. var tooltip = this._tooltip,
  47919. options = tooltip && this._getOption("tooltip");
  47920. tooltip && tooltip.update($.extend({}, options, {
  47921. customizeTooltip: !$.isFunction(options.customizeTooltip) ? generateDefaultCustomizeTooltipCallback(options.font, this.option("rtlEnabled")) : options.customizeTooltip,
  47922. enabled: options.enabled && this._isTooltipEnabled()
  47923. }))
  47924. },
  47925. _showTooltip: function(delay) {
  47926. var that = this;
  47927. ++that._DEBUG_clearHideTooltipTimeout;
  47928. clearTimeout(that._hideTooltipTimeout);
  47929. that._hideTooltipTimeout = null;
  47930. clearTimeout(that._showTooltipTimeout);
  47931. ++that._DEBUG_showTooltipTimeoutSet;
  47932. that._showTooltipTimeout = setTimeout(that._showTooltipCallback, delay)
  47933. },
  47934. _hideTooltip: function(delay) {
  47935. var that = this;
  47936. ++that._DEBUG_clearShowTooltipTimeout;
  47937. clearTimeout(that._showTooltipTimeout);
  47938. that._showTooltipTimeout = null;
  47939. clearTimeout(that._hideTooltipTimeout);
  47940. if (delay) {
  47941. ++that._DEBUG_hideTooltipTimeoutSet;
  47942. that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)
  47943. }
  47944. else
  47945. that._hideTooltipCallback()
  47946. },
  47947. _initLoadingIndicator: $.noop,
  47948. _disposeLoadingIndicator: $.noop,
  47949. _handleLoadingIndicatorOptionChanged: $.noop,
  47950. showLoadingIndicator: $.noop,
  47951. hideLoadingIndicator: $.noop
  47952. });
  47953. var menuEvents = {
  47954. "contextmenu.sparkline-tooltip": function(event) {
  47955. if (DX.ui.events.isTouchEvent(event) || DX.ui.events.isPointerEvent(event))
  47956. event.preventDefault()
  47957. },
  47958. "MSHoldVisual.sparkline-tooltip": function(event) {
  47959. event.preventDefault()
  47960. }
  47961. };
  47962. var mouseEvents = {
  47963. "mouseover.sparkline-tooltip": function(event) {
  47964. isPointerDownCalled = false;
  47965. var widget = event.data.widget;
  47966. widget._x = event.pageX;
  47967. widget._y = event.pageY;
  47968. widget._tooltipTracker.off(mouseMoveEvents).on(mouseMoveEvents, event.data);
  47969. widget._showTooltip(DEFAULT_EVENTS_DELAY)
  47970. },
  47971. "mouseout.sparkline-tooltip": function(event) {
  47972. if (isPointerDownCalled)
  47973. return;
  47974. var widget = event.data.widget;
  47975. widget._tooltipTracker.off(mouseMoveEvents);
  47976. widget._hideTooltip(DEFAULT_EVENTS_DELAY)
  47977. }
  47978. };
  47979. var mouseWheelEvents = {"dxmousewheel.sparkline-tooltip": function(event) {
  47980. event.data.widget._hideTooltip()
  47981. }};
  47982. var mouseMoveEvents = {"mousemove.sparkline-tooltip": function(event) {
  47983. var widget = event.data.widget;
  47984. if (widget._showTooltipTimeout && (_abs(widget._x - event.pageX) > 3 || _abs(widget._y - event.pageY) > 3)) {
  47985. widget._x = event.pageX;
  47986. widget._y = event.pageY;
  47987. widget._showTooltip(DEFAULT_EVENTS_DELAY)
  47988. }
  47989. }};
  47990. var active_touch_tooltip_widget = null,
  47991. touchstartTooltipProcessing = function(event) {
  47992. event.preventDefault();
  47993. var widget = active_touch_tooltip_widget;
  47994. if (widget && widget !== event.data.widget)
  47995. widget._hideTooltip(DEFAULT_EVENTS_DELAY);
  47996. widget = active_touch_tooltip_widget = event.data.widget;
  47997. widget._showTooltip(TOUCH_EVENTS_DELAY);
  47998. widget._touch = true
  47999. },
  48000. touchstartDocumentProcessing = function() {
  48001. var widget = active_touch_tooltip_widget;
  48002. if (widget) {
  48003. if (!widget._touch) {
  48004. widget._hideTooltip(DEFAULT_EVENTS_DELAY);
  48005. active_touch_tooltip_widget = null
  48006. }
  48007. widget._touch = null
  48008. }
  48009. },
  48010. touchendDocumentProcessing = function() {
  48011. var widget = active_touch_tooltip_widget;
  48012. if (widget)
  48013. if (widget._showTooltipTimeout) {
  48014. widget._hideTooltip(DEFAULT_EVENTS_DELAY);
  48015. active_touch_tooltip_widget = null
  48016. }
  48017. },
  48018. isPointerDownCalled = false;
  48019. var touchEvents = {
  48020. "pointerdown.sparkline-tooltip": touchstartTooltipProcessing,
  48021. "touchstart.sparkline-tooltip": touchstartTooltipProcessing
  48022. };
  48023. $(document).on({
  48024. "pointerdown.sparkline-tooltip": function() {
  48025. isPointerDownCalled = true;
  48026. touchstartDocumentProcessing()
  48027. },
  48028. "touchstart.sparkline-tooltip": touchstartDocumentProcessing,
  48029. "pointerup.sparkline-tooltip": touchendDocumentProcessing,
  48030. "touchend.sparkline-tooltip": touchendDocumentProcessing
  48031. });
  48032. DX.viz.sparklines.BaseSparkline._DEBUG_reset = function() {
  48033. active_touch_tooltip_widget = null
  48034. }
  48035. })(jQuery, DevExpress);
  48036. /*! Module viz-sparklines, file sparkline.js */
  48037. (function($, DX, undefined) {
  48038. var viz = DX.viz,
  48039. core = viz.core,
  48040. MIN_BAR_WIDTH = 1,
  48041. MAX_BAR_WIDTH = 50,
  48042. DEFAULT_BAR_INTERVAL = 4,
  48043. DEFAULT_CANVAS_WIDTH = 250,
  48044. DEFAULT_CANVAS_HEIGHT = 30,
  48045. DEFAULT_HORIZONTAL_MARGIN = 5,
  48046. DEFAULT_VERTICAL_MARGIN = 3,
  48047. ALLOWED_TYPES = {
  48048. line: true,
  48049. spline: true,
  48050. stepline: true,
  48051. area: true,
  48052. steparea: true,
  48053. splinearea: true,
  48054. bar: true,
  48055. winloss: true
  48056. },
  48057. _map = $.map,
  48058. _math = Math,
  48059. _abs = _math.abs,
  48060. _round = _math.round,
  48061. _max = _math.max,
  48062. _min = _math.min,
  48063. _isFinite = isFinite,
  48064. _isDefined = DX.utils.isDefined,
  48065. _Number = Number,
  48066. _String = String;
  48067. DX.registerComponent("dxSparkline", viz.sparklines, viz.sparklines.BaseSparkline.inherit({
  48068. _rootClassPrefix: "dxsl",
  48069. _rootClass: "dxsl-sparkline",
  48070. _widgetType: "sparkline",
  48071. _defaultSize: {
  48072. width: DEFAULT_CANVAS_WIDTH,
  48073. height: DEFAULT_CANVAS_HEIGHT,
  48074. left: DEFAULT_HORIZONTAL_MARGIN,
  48075. right: DEFAULT_HORIZONTAL_MARGIN,
  48076. top: DEFAULT_VERTICAL_MARGIN,
  48077. bottom: DEFAULT_VERTICAL_MARGIN
  48078. },
  48079. _initCore: function() {
  48080. this.callBase();
  48081. this._refreshDataSource();
  48082. this._createSeries()
  48083. },
  48084. _dataSourceChangedHandler: function() {
  48085. if (this._initialized) {
  48086. this._clean();
  48087. this._updateWidgetElements();
  48088. this._drawWidgetElements()
  48089. }
  48090. },
  48091. _updateWidgetElements: function() {
  48092. this._updateSeries();
  48093. this.callBase()
  48094. },
  48095. _dataSourceOptions: function() {
  48096. return {paginate: false}
  48097. },
  48098. _redrawWidgetElements: function() {
  48099. this._updateTranslator();
  48100. this._correctPoints();
  48101. this._series.draw({
  48102. x: this._translatorX,
  48103. y: this._translatorY
  48104. });
  48105. this._seriesGroup.append(this._renderer.root)
  48106. },
  48107. _disposeWidgetElements: function() {
  48108. var that = this;
  48109. delete that._seriesGroup;
  48110. delete that._seriesLabelGroup;
  48111. that._series && that._series.dispose();
  48112. that._series = null
  48113. },
  48114. _cleanWidgetElements: function() {
  48115. this._seriesGroup.remove();
  48116. this._seriesLabelGroup.remove();
  48117. this._seriesGroup.clear();
  48118. this._seriesLabelGroup.clear()
  48119. },
  48120. _drawWidgetElements: function() {
  48121. if (this._isDataSourceReady()) {
  48122. this._drawSeries();
  48123. this._drawn()
  48124. }
  48125. },
  48126. _prepareOptions: function() {
  48127. this._allOptions = this.callBase();
  48128. this._allOptions.type = _String(this._allOptions.type).toLowerCase();
  48129. if (!ALLOWED_TYPES[this._allOptions.type])
  48130. this._allOptions.type = "line"
  48131. },
  48132. _createHtmlElements: function() {
  48133. this._seriesGroup = this._renderer.g().attr({"class": "dxsl-series"});
  48134. this._seriesLabelGroup = this._renderer.g().attr({"class": "dxsl-series-labels"})
  48135. },
  48136. _createSeries: function() {
  48137. this._series = new core.series.Series({
  48138. renderer: this._renderer,
  48139. seriesGroup: this._seriesGroup,
  48140. labelsGroup: this._seriesLabelGroup
  48141. }, {
  48142. widgetType: "chart",
  48143. type: "line"
  48144. })
  48145. },
  48146. getSeriesOptions: function() {
  48147. return this._series.getOptions()
  48148. },
  48149. _updateSeries: function() {
  48150. var that = this,
  48151. groupSeries,
  48152. dataValidator,
  48153. seriesOptions;
  48154. that._prepareDataSource();
  48155. seriesOptions = that._prepareSeriesOptions();
  48156. that._series.updateOptions(seriesOptions);
  48157. groupSeries = [[that._series]];
  48158. groupSeries.argumentOptions = {type: seriesOptions.type === "bar" ? "discrete" : undefined};
  48159. dataValidator = new core.DataValidator(that._simpleDataSource, groupSeries, that._incidentOccured, {
  48160. checkTypeForAllData: false,
  48161. convertToAxisDataType: true,
  48162. sortingMethod: true
  48163. });
  48164. that._simpleDataSource = dataValidator.validate();
  48165. that._series.updateData(that._simpleDataSource)
  48166. },
  48167. _optionChanged: function(args) {
  48168. if (args.name === "dataSource" && this._allOptions)
  48169. this._refreshDataSource();
  48170. else
  48171. this.callBase.apply(this, arguments)
  48172. },
  48173. _parseNumericDataSource: function(data, argField, valField) {
  48174. var ignoreEmptyPoints = this.option("ignoreEmptyPoints");
  48175. return _map(data, function(dataItem, index) {
  48176. var item = null,
  48177. isDataNumber,
  48178. value;
  48179. if (dataItem !== undefined) {
  48180. item = {};
  48181. isDataNumber = _isFinite(dataItem);
  48182. item[argField] = isDataNumber ? _String(index) : dataItem[argField];
  48183. value = isDataNumber ? dataItem : dataItem[valField];
  48184. item[valField] = value === null ? ignoreEmptyPoints ? undefined : value : _Number(value);
  48185. item = item[argField] !== undefined && item[valField] !== undefined ? item : null
  48186. }
  48187. return item
  48188. })
  48189. },
  48190. _parseWinlossDataSource: function(data, argField, valField) {
  48191. var lowBarValue = -1,
  48192. zeroBarValue = 0,
  48193. highBarValue = 1,
  48194. delta = 0.0001,
  48195. target = this._allOptions.winlossThreshold;
  48196. return _map(data, function(dataItem) {
  48197. var item = {};
  48198. item[argField] = dataItem[argField];
  48199. if (_abs(dataItem[valField] - target) < delta)
  48200. item[valField] = zeroBarValue;
  48201. else if (dataItem[valField] > target)
  48202. item[valField] = highBarValue;
  48203. else
  48204. item[valField] = lowBarValue;
  48205. return item
  48206. })
  48207. },
  48208. _prepareDataSource: function() {
  48209. var that = this,
  48210. options = that._allOptions,
  48211. argField = options.argumentField,
  48212. valField = options.valueField,
  48213. dataSource = that._dataSource ? that._dataSource.items() : [],
  48214. data = that._parseNumericDataSource(dataSource, argField, valField);
  48215. if (options.type === "winloss") {
  48216. that._winlossDataSource = data;
  48217. that._simpleDataSource = that._parseWinlossDataSource(data, argField, valField)
  48218. }
  48219. else
  48220. that._simpleDataSource = data
  48221. },
  48222. _prepareSeriesOptions: function() {
  48223. var that = this,
  48224. options = that._allOptions,
  48225. type = options.type === "winloss" ? "bar" : options.type;
  48226. return {
  48227. visible: true,
  48228. argumentField: options.argumentField,
  48229. valueField: options.valueField,
  48230. color: options.lineColor,
  48231. width: options.lineWidth,
  48232. widgetType: "chart",
  48233. type: type,
  48234. opacity: type.indexOf("area") !== -1 ? that._allOptions.areaOpacity : undefined,
  48235. customizePoint: that._getCustomizeFunction(),
  48236. point: {
  48237. size: options.pointSize,
  48238. symbol: options.pointSymbol,
  48239. border: {
  48240. visible: true,
  48241. width: 2
  48242. },
  48243. color: options.pointColor,
  48244. visible: false,
  48245. hoverStyle: {border: {}},
  48246. selectionStyle: {border: {}}
  48247. },
  48248. border: {
  48249. color: options.lineColor,
  48250. width: options.lineWidth,
  48251. visible: type !== "bar"
  48252. }
  48253. }
  48254. },
  48255. _createBarCustomizeFunction: function(pointIndexes) {
  48256. var that = this,
  48257. options = that._allOptions,
  48258. winlossData = that._winlossDataSource;
  48259. return function() {
  48260. var index = this.index,
  48261. isWinloss = options.type === "winloss",
  48262. target = isWinloss ? options.winlossThreshold : 0,
  48263. value = isWinloss ? winlossData[index][options.valueField] : this.value,
  48264. positiveColor = isWinloss ? options.winColor : options.barPositiveColor,
  48265. negativeColor = isWinloss ? options.lossColor : options.barNegativeColor,
  48266. color;
  48267. if (value >= target)
  48268. color = positiveColor;
  48269. else
  48270. color = negativeColor;
  48271. if (index === pointIndexes.first || index === pointIndexes.last)
  48272. color = options.firstLastColor;
  48273. if (index === pointIndexes.min)
  48274. color = options.minColor;
  48275. if (index === pointIndexes.max)
  48276. color = options.maxColor;
  48277. return {color: color}
  48278. }
  48279. },
  48280. _createLineCustomizeFunction: function(pointIndexes) {
  48281. var that = this,
  48282. options = that._allOptions;
  48283. return function() {
  48284. var color,
  48285. index = this.index;
  48286. if (index === pointIndexes.first || index === pointIndexes.last)
  48287. color = options.firstLastColor;
  48288. if (index === pointIndexes.min)
  48289. color = options.minColor;
  48290. if (index === pointIndexes.max)
  48291. color = options.maxColor;
  48292. return color ? {
  48293. visible: true,
  48294. border: {color: color}
  48295. } : {}
  48296. }
  48297. },
  48298. _getCustomizeFunction: function() {
  48299. var that = this,
  48300. options = that._allOptions,
  48301. dataSource = that._winlossDataSource || that._simpleDataSource,
  48302. drawnPointIndexes = that._getExtremumPointsIndexes(dataSource),
  48303. customizeFunction;
  48304. if (options.type === "winloss" || options.type === "bar")
  48305. customizeFunction = that._createBarCustomizeFunction(drawnPointIndexes);
  48306. else
  48307. customizeFunction = that._createLineCustomizeFunction(drawnPointIndexes);
  48308. return customizeFunction
  48309. },
  48310. _getExtremumPointsIndexes: function(data) {
  48311. var that = this,
  48312. options = that._allOptions,
  48313. lastIndex = data.length - 1,
  48314. indexes = {};
  48315. that._minMaxIndexes = that._findMinMax(data);
  48316. if (options.showFirstLast) {
  48317. indexes.first = 0;
  48318. indexes.last = lastIndex
  48319. }
  48320. if (options.showMinMax) {
  48321. indexes.min = that._minMaxIndexes.minIndex;
  48322. indexes.max = that._minMaxIndexes.maxIndex
  48323. }
  48324. return indexes
  48325. },
  48326. _findMinMax: function(data) {
  48327. var that = this,
  48328. valField = that._allOptions.valueField,
  48329. firstItem = data[0] || {},
  48330. firstValue = firstItem[valField] || 0,
  48331. min = firstValue,
  48332. max = firstValue,
  48333. minIndex = 0,
  48334. maxIndex = 0,
  48335. dataLength = data.length,
  48336. value,
  48337. i;
  48338. for (i = 1; i < dataLength; i++) {
  48339. value = data[i][valField];
  48340. if (value < min) {
  48341. min = value;
  48342. minIndex = i
  48343. }
  48344. if (value > max) {
  48345. max = value;
  48346. maxIndex = i
  48347. }
  48348. }
  48349. return {
  48350. minIndex: minIndex,
  48351. maxIndex: maxIndex
  48352. }
  48353. },
  48354. _updateRange: function() {
  48355. var that = this,
  48356. series = that._series,
  48357. type = series.type,
  48358. isBarType = type === "bar",
  48359. isWinlossType = type === "winloss",
  48360. DEFAULT_VALUE_RANGE_MARGIN = 0.15,
  48361. DEFAULT_ARGUMENT_RANGE_MARGIN = 0.1,
  48362. WINLOSS_MAX_RANGE = 1,
  48363. WINLOSS_MIN_RANGE = -1,
  48364. rangeData = series.getRangeData(),
  48365. minValue = that._allOptions.minValue,
  48366. hasMinY = _isDefined(minValue) && _isFinite(minValue),
  48367. maxValue = that._allOptions.maxValue,
  48368. hasMaxY = _isDefined(maxValue) && _isFinite(maxValue),
  48369. valCoef,
  48370. argCoef;
  48371. valCoef = (rangeData.val.max - rangeData.val.min) * DEFAULT_VALUE_RANGE_MARGIN;
  48372. if (isBarType || isWinlossType || type === "area") {
  48373. if (rangeData.val.min !== 0)
  48374. rangeData.val.min -= valCoef;
  48375. if (rangeData.val.max !== 0)
  48376. rangeData.val.max += valCoef
  48377. }
  48378. else {
  48379. rangeData.val.min -= valCoef;
  48380. rangeData.val.max += valCoef
  48381. }
  48382. if (hasMinY || hasMaxY) {
  48383. if (hasMinY && hasMaxY) {
  48384. rangeData.val.minVisible = _min(minValue, maxValue);
  48385. rangeData.val.maxVisible = _max(minValue, maxValue)
  48386. }
  48387. else {
  48388. rangeData.val.minVisible = hasMinY ? _Number(minValue) : undefined;
  48389. rangeData.val.maxVisible = hasMaxY ? _Number(maxValue) : undefined
  48390. }
  48391. if (isWinlossType) {
  48392. rangeData.val.minVisible = hasMinY ? _max(rangeData.val.minVisible, WINLOSS_MIN_RANGE) : undefined;
  48393. rangeData.val.maxVisible = hasMaxY ? _min(rangeData.val.maxVisible, WINLOSS_MAX_RANGE) : undefined
  48394. }
  48395. }
  48396. if (series.getPoints().length > 1)
  48397. if (isBarType) {
  48398. argCoef = (rangeData.arg.max - rangeData.arg.min) * DEFAULT_ARGUMENT_RANGE_MARGIN;
  48399. rangeData.arg.min = rangeData.arg.min - argCoef;
  48400. rangeData.arg.max = rangeData.arg.max + argCoef
  48401. }
  48402. else
  48403. rangeData.arg.stick = true;
  48404. that._ranges = rangeData
  48405. },
  48406. _getBarWidth: function(pointsCount) {
  48407. var that = this,
  48408. canvas = that._canvas,
  48409. intervalWidth = pointsCount * DEFAULT_BAR_INTERVAL,
  48410. rangeWidth = canvas.width - canvas.left - canvas.right - intervalWidth,
  48411. width = _round(rangeWidth / pointsCount);
  48412. if (width < MIN_BAR_WIDTH)
  48413. width = MIN_BAR_WIDTH;
  48414. if (width > MAX_BAR_WIDTH)
  48415. width = MAX_BAR_WIDTH;
  48416. return width
  48417. },
  48418. _correctPoints: function() {
  48419. var that = this,
  48420. seriesType = that._allOptions.type,
  48421. seriesPoints = that._series.getPoints(),
  48422. pointsLength = seriesPoints.length,
  48423. barWidth,
  48424. i;
  48425. if (seriesType === "bar" || seriesType === "winloss") {
  48426. barWidth = that._getBarWidth(pointsLength);
  48427. for (i = 0; i < pointsLength; i++)
  48428. seriesPoints[i].correctCoordinates({
  48429. width: barWidth,
  48430. offset: 0
  48431. })
  48432. }
  48433. },
  48434. _drawSeries: function() {
  48435. var that = this;
  48436. if (that._simpleDataSource.length > 0) {
  48437. that._correctPoints();
  48438. that._series.draw({
  48439. x: that._translatorX,
  48440. y: that._translatorY
  48441. });
  48442. that._seriesGroup.append(that._renderer.root)
  48443. }
  48444. },
  48445. _isTooltipEnabled: function() {
  48446. return !!this._simpleDataSource.length
  48447. },
  48448. _getTooltipData: function() {
  48449. var that = this,
  48450. options = that._allOptions,
  48451. dataSource = that._winlossDataSource || that._simpleDataSource,
  48452. tooltip = that._tooltip;
  48453. if (dataSource.length === 0)
  48454. return {};
  48455. var minMax = that._minMaxIndexes,
  48456. valueField = options.valueField,
  48457. first = dataSource[0][valueField],
  48458. last = dataSource[dataSource.length - 1][valueField],
  48459. min = dataSource[minMax.minIndex][valueField],
  48460. max = dataSource[minMax.maxIndex][valueField],
  48461. formattedFirst = tooltip.formatValue(first),
  48462. formattedLast = tooltip.formatValue(last),
  48463. formattedMin = tooltip.formatValue(min),
  48464. formattedMax = tooltip.formatValue(max),
  48465. customizeObject = {
  48466. firstValue: formattedFirst,
  48467. lastValue: formattedLast,
  48468. minValue: formattedMin,
  48469. maxValue: formattedMax,
  48470. originalFirstValue: first,
  48471. originalLastValue: last,
  48472. originalMinValue: min,
  48473. originalMaxValue: max,
  48474. valueText: ["Start:", formattedFirst, "End:", formattedLast, "Min:", formattedMin, "Max:", formattedMax]
  48475. };
  48476. if (options.type === "winloss") {
  48477. customizeObject.originalThresholdValue = options.winlossThreshold;
  48478. customizeObject.thresholdValue = tooltip.formatValue(options.winlossThreshold)
  48479. }
  48480. return customizeObject
  48481. }
  48482. }).include(DX.ui.DataHelperMixin))
  48483. })(jQuery, DevExpress);
  48484. /*! Module viz-sparklines, file bullet.js */
  48485. (function($, DX, undefined) {
  48486. var TARGET_MIN_Y = 0.02,
  48487. TARGET_MAX_Y = 0.98,
  48488. BAR_VALUE_MIN_Y = 0.1,
  48489. BAR_VALUE_MAX_Y = 0.9,
  48490. DEFAULT_CANVAS_WIDTH = 300,
  48491. DEFAULT_CANVAS_HEIGHT = 30,
  48492. DEFAULT_HORIZONTAL_MARGIN = 1,
  48493. DEFAULT_VERTICAL_MARGIN = 2,
  48494. _Number = Number,
  48495. _isFinite = isFinite;
  48496. DX.registerComponent("dxBullet", DX.viz.sparklines, DX.viz.sparklines.BaseSparkline.inherit({
  48497. _rootClassPrefix: "dxb",
  48498. _rootClass: "dxb-bullet",
  48499. _widgetType: "bullet",
  48500. _defaultSize: {
  48501. width: DEFAULT_CANVAS_WIDTH,
  48502. height: DEFAULT_CANVAS_HEIGHT,
  48503. left: DEFAULT_HORIZONTAL_MARGIN,
  48504. right: DEFAULT_HORIZONTAL_MARGIN,
  48505. top: DEFAULT_VERTICAL_MARGIN,
  48506. bottom: DEFAULT_VERTICAL_MARGIN
  48507. },
  48508. _disposeWidgetElements: function() {
  48509. delete this._zeroLevelPath;
  48510. delete this._targetPath;
  48511. delete this._barValuePath
  48512. },
  48513. _redrawWidgetElements: function() {
  48514. this._updateTranslator();
  48515. this._drawBarValue();
  48516. this._drawTarget();
  48517. this._drawZeroLevel()
  48518. },
  48519. _cleanWidgetElements: function() {
  48520. this._zeroLevelPath.remove();
  48521. this._targetPath.remove();
  48522. this._barValuePath.remove()
  48523. },
  48524. _drawWidgetElements: function() {
  48525. this._drawBullet();
  48526. this._drawn()
  48527. },
  48528. _createHtmlElements: function() {
  48529. var renderer = this._renderer;
  48530. this._zeroLevelPath = renderer.path(undefined, "line").attr({
  48531. "class": "dxb-zero-level",
  48532. "stroke-linecap": "square"
  48533. });
  48534. this._targetPath = renderer.path(undefined, "line").attr({
  48535. "class": "dxb-target",
  48536. "stroke-linecap": "square"
  48537. });
  48538. this._barValuePath = renderer.path(undefined, "line").attr({
  48539. "class": "dxb-bar-value",
  48540. "stroke-linecap": "square"
  48541. })
  48542. },
  48543. _prepareOptions: function() {
  48544. var that = this,
  48545. options,
  48546. startScaleValue,
  48547. endScaleValue,
  48548. level,
  48549. value,
  48550. target,
  48551. isValueUndefined,
  48552. isTargetUndefined;
  48553. that._allOptions = options = that.callBase();
  48554. isValueUndefined = that._allOptions.value === undefined;
  48555. isTargetUndefined = that._allOptions.target === undefined;
  48556. that._tooltipEnabled = !(isValueUndefined && isTargetUndefined);
  48557. if (isValueUndefined)
  48558. that._allOptions.value = 0;
  48559. if (isTargetUndefined)
  48560. that._allOptions.target = 0;
  48561. options.value = value = _Number(options.value);
  48562. options.target = target = _Number(options.target);
  48563. if (that._allOptions.startScaleValue === undefined) {
  48564. that._allOptions.startScaleValue = target < value ? target : value;
  48565. that._allOptions.startScaleValue = that._allOptions.startScaleValue < 0 ? that._allOptions.startScaleValue : 0
  48566. }
  48567. if (that._allOptions.endScaleValue === undefined)
  48568. that._allOptions.endScaleValue = target > value ? target : value;
  48569. options.startScaleValue = startScaleValue = _Number(options.startScaleValue);
  48570. options.endScaleValue = endScaleValue = _Number(options.endScaleValue);
  48571. if (endScaleValue < startScaleValue) {
  48572. level = endScaleValue;
  48573. that._allOptions.endScaleValue = startScaleValue;
  48574. that._allOptions.startScaleValue = level;
  48575. that._allOptions.inverted = true
  48576. }
  48577. },
  48578. _updateRange: function() {
  48579. var that = this,
  48580. options = that._allOptions;
  48581. that._ranges = {
  48582. arg: {
  48583. invert: options.inverted,
  48584. min: options.startScaleValue,
  48585. max: options.endScaleValue,
  48586. axisType: "continuous",
  48587. dataType: "numeric"
  48588. },
  48589. val: {
  48590. min: 0,
  48591. max: 1,
  48592. axisType: "continuous",
  48593. dataType: "numeric"
  48594. }
  48595. }
  48596. },
  48597. _drawBullet: function() {
  48598. var that = this,
  48599. options = that._allOptions,
  48600. isValidBounds = options.startScaleValue !== options.endScaleValue,
  48601. isValidMin = _isFinite(options.startScaleValue),
  48602. isValidMax = _isFinite(options.endScaleValue),
  48603. isValidValue = _isFinite(options.value),
  48604. isValidTarget = _isFinite(options.target);
  48605. if (isValidBounds && isValidMax && isValidMin && isValidTarget && isValidValue) {
  48606. this._drawBarValue();
  48607. this._drawTarget();
  48608. this._drawZeroLevel()
  48609. }
  48610. },
  48611. _getTargetParams: function() {
  48612. var that = this,
  48613. options = that._allOptions,
  48614. translatorY = that._translatorY,
  48615. x = that._translatorX.translate(options.target);
  48616. return {
  48617. points: [x, translatorY.translate(TARGET_MIN_Y), x, translatorY.translate(TARGET_MAX_Y)],
  48618. stroke: options.targetColor,
  48619. "stroke-width": options.targetWidth
  48620. }
  48621. },
  48622. _getBarValueParams: function() {
  48623. var that = this,
  48624. options = that._allOptions,
  48625. translatorX = that._translatorX,
  48626. translatorY = that._translatorY,
  48627. startLevel = options.startScaleValue,
  48628. endLevel = options.endScaleValue,
  48629. value = options.value,
  48630. y2 = translatorY.translate(BAR_VALUE_MIN_Y),
  48631. y1 = translatorY.translate(BAR_VALUE_MAX_Y),
  48632. x1,
  48633. x2;
  48634. if (value > 0) {
  48635. x1 = startLevel <= 0 ? 0 : startLevel;
  48636. x2 = value >= endLevel ? endLevel : value < x1 ? x1 : value
  48637. }
  48638. else {
  48639. x1 = endLevel >= 0 ? 0 : endLevel;
  48640. x2 = value < startLevel ? startLevel : value > x1 ? x1 : value
  48641. }
  48642. x1 = translatorX.translate(x1);
  48643. x2 = translatorX.translate(x2);
  48644. return {
  48645. points: [x1, y1, x2, y1, x2, y2, x1, y2],
  48646. fill: options.color
  48647. }
  48648. },
  48649. _getZeroLevelParams: function() {
  48650. var that = this,
  48651. translatorY = that._translatorY,
  48652. x = that._translatorX.translate(0);
  48653. return {
  48654. points: [x, translatorY.translate(TARGET_MIN_Y), x, translatorY.translate(TARGET_MAX_Y)],
  48655. stroke: that._allOptions.targetColor,
  48656. "stroke-width": 1
  48657. }
  48658. },
  48659. _drawZeroLevel: function() {
  48660. var that = this,
  48661. options = that._allOptions;
  48662. if (0 > options.endScaleValue || 0 < options.startScaleValue || !options.showZeroLevel)
  48663. return;
  48664. that._zeroLevelPath.attr(that._getZeroLevelParams()).sharp().append(that._renderer.root)
  48665. },
  48666. _drawTarget: function() {
  48667. var that = this,
  48668. options = that._allOptions,
  48669. target = options.target;
  48670. if (target > options.endScaleValue || target < options.startScaleValue || !options.showTarget)
  48671. return;
  48672. that._targetPath.attr(that._getTargetParams()).sharp().append(that._renderer.root)
  48673. },
  48674. _drawBarValue: function() {
  48675. this._barValuePath.attr(this._getBarValueParams()).append(this._renderer.root)
  48676. },
  48677. _getTooltipCoords: function() {
  48678. var canvas = this._canvas,
  48679. rootOffset = this._renderer.getRootOffset(),
  48680. bbox = this._barValuePath.getBBox();
  48681. return {
  48682. x: bbox.x + bbox.width / 2 + rootOffset.left,
  48683. y: canvas.height / 2 + rootOffset.top
  48684. }
  48685. },
  48686. _getTooltipData: function() {
  48687. var that = this,
  48688. tooltip = that._tooltip,
  48689. options = that._allOptions,
  48690. value = options.value,
  48691. target = options.target;
  48692. return {
  48693. originalValue: value,
  48694. originalTarget: target,
  48695. value: tooltip.formatValue(value),
  48696. target: tooltip.formatValue(target),
  48697. valueText: ["Actual Value:", value, "Target Value:", target]
  48698. }
  48699. },
  48700. _isTooltipEnabled: function() {
  48701. return this._tooltipEnabled
  48702. }
  48703. }))
  48704. })(jQuery, DevExpress);
  48705. DevExpress.MOD_VIZ_SPARKLINES = true
  48706. }