dx.all.debug.js.bak 3.4 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222432234322443225432264322743228432294323043231432324323343234432354323643237432384323943240432414324243243432444324543246432474324843249432504325143252432534325443255432564325743258432594326043261432624326343264432654326643267432684326943270432714327243273432744327543276432774327843279432804328143282432834328443285432864328743288432894329043291432924329343294432954329643297432984329943300433014330243303433044330543306433074330843309433104331143312433134331443315433164331743318433194332043321433224332343324433254332643327433284332943330433314333243333433344333543336433374333843339433404334143342433434334443345433464334743348433494335043351433524335343354433554335643357433584335943360433614336243363433644336543366433674336843369433704337143372433734337443375433764337743378433794338043381433824338343384433854338643387433884338943390433914339243393433944339543396433974339843399434004340143402434034340443405434064340743408434094341043411434124341343414434154341643417434184341943420434214342243423434244342543426434274342843429434304343143432434334343443435434364343743438434394344043441434424344343444434454344643447434484344943450434514345243453434544345543456434574345843459434604346143462434634346443465434664346743468434694347043471434724347343474434754347643477434784347943480434814348243483434844348543486434874348843489434904349143492434934349443495434964349743498434994350043501435024350343504435054350643507435084350943510435114351243513435144351543516435174351843519435204352143522435234352443525435264352743528435294353043531435324353343534435354353643537435384353943540435414354243543435444354543546435474354843549435504355143552435534355443555435564355743558435594356043561435624356343564435654356643567435684356943570435714357243573435744357543576435774357843579435804358143582435834358443585435864358743588435894359043591435924359343594435954359643597435984359943600436014360243603436044360543606436074360843609436104361143612436134361443615436164361743618436194362043621436224362343624436254362643627436284362943630436314363243633436344363543636436374363843639436404364143642436434364443645436464364743648436494365043651436524365343654436554365643657436584365943660436614366243663436644366543666436674366843669436704367143672436734367443675436764367743678436794368043681436824368343684436854368643687436884368943690436914369243693436944369543696436974369843699437004370143702437034370443705437064370743708437094371043711437124371343714437154371643717437184371943720437214372243723437244372543726437274372843729437304373143732437334373443735437364373743738437394374043741437424374343744437454374643747437484374943750437514375243753437544375543756437574375843759437604376143762437634376443765437664376743768437694377043771437724377343774437754377643777437784377943780437814378243783437844378543786437874378843789437904379143792437934379443795437964379743798437994380043801438024380343804438054380643807438084380943810438114381243813438144381543816438174381843819438204382143822438234382443825438264382743828438294383043831438324383343834438354383643837438384383943840438414384243843438444384543846438474384843849438504385143852438534385443855438564385743858438594386043861438624386343864438654386643867438684386943870438714387243873438744387543876438774387843879438804388143882438834388443885438864388743888438894389043891438924389343894438954389643897438984389943900439014390243903439044390543906439074390843909439104391143912439134391443915439164391743918439194392043921439224392343924439254392643927439284392943930439314393243933439344393543936439374393843939439404394143942439434394443945439464394743948439494395043951439524395343954439554395643957439584395943960439614396243963439644396543966439674396843969439704397143972439734397443975439764397743978439794398043981439824398343984439854398643987439884398943990439914399243993439944399543996439974399843999440004400144002440034400444005440064400744008440094401044011440124401344014440154401644017440184401944020440214402244023440244402544026440274402844029440304403144032440334403444035440364403744038440394404044041440424404344044440454404644047440484404944050440514405244053440544405544056440574405844059440604406144062440634406444065440664406744068440694407044071440724407344074440754407644077440784407944080440814408244083440844408544086440874408844089440904409144092440934409444095440964409744098440994410044101441024410344104441054410644107441084410944110441114411244113441144411544116441174411844119441204412144122441234412444125441264412744128441294413044131441324413344134441354413644137441384413944140441414414244143441444414544146441474414844149441504415144152441534415444155441564415744158441594416044161441624416344164441654416644167441684416944170441714417244173441744417544176441774417844179441804418144182441834418444185441864418744188441894419044191441924419344194441954419644197441984419944200442014420244203442044420544206442074420844209442104421144212442134421444215442164421744218442194422044221442224422344224442254422644227442284422944230442314423244233442344423544236442374423844239442404424144242442434424444245442464424744248442494425044251442524425344254442554425644257442584425944260442614426244263442644426544266442674426844269442704427144272442734427444275442764427744278442794428044281442824428344284442854428644287442884428944290442914429244293442944429544296442974429844299443004430144302443034430444305443064430744308443094431044311443124431344314443154431644317443184431944320443214432244323443244432544326443274432844329443304433144332443334433444335443364433744338443394434044341443424434344344443454434644347443484434944350443514435244353443544435544356443574435844359443604436144362443634436444365443664436744368443694437044371443724437344374443754437644377443784437944380443814438244383443844438544386443874438844389443904439144392443934439444395443964439744398443994440044401444024440344404444054440644407444084440944410444114441244413444144441544416444174441844419444204442144422444234442444425444264442744428444294443044431444324443344434444354443644437444384443944440444414444244443444444444544446444474444844449444504445144452444534445444455444564445744458444594446044461444624446344464444654446644467444684446944470444714447244473444744447544476444774447844479444804448144482444834448444485444864448744488444894449044491444924449344494444954449644497444984449944500445014450244503445044450544506445074450844509445104451144512445134451444515445164451744518445194452044521445224452344524445254452644527445284452944530445314453244533445344453544536445374453844539445404454144542445434454444545445464454744548445494455044551445524455344554445554455644557445584455944560445614456244563445644456544566445674456844569445704457144572445734457444575445764457744578445794458044581445824458344584445854458644587445884458944590445914459244593445944459544596445974459844599446004460144602446034460444605446064460744608446094461044611446124461344614446154461644617446184461944620446214462244623446244462544626446274462844629446304463144632446334463444635446364463744638446394464044641446424464344644446454464644647446484464944650446514465244653446544465544656446574465844659446604466144662446634466444665446664466744668446694467044671446724467344674446754467644677446784467944680446814468244683446844468544686446874468844689446904469144692446934469444695446964469744698446994470044701447024470344704447054470644707447084470944710447114471244713447144471544716447174471844719447204472144722447234472444725447264472744728447294473044731447324473344734447354473644737447384473944740447414474244743447444474544746447474474844749447504475144752447534475444755447564475744758447594476044761447624476344764447654476644767447684476944770447714477244773447744477544776447774477844779447804478144782447834478444785447864478744788447894479044791447924479344794447954479644797447984479944800448014480244803448044480544806448074480844809448104481144812448134481444815448164481744818448194482044821448224482344824448254482644827448284482944830448314483244833448344483544836448374483844839448404484144842448434484444845448464484744848448494485044851448524485344854448554485644857448584485944860448614486244863448644486544866448674486844869448704487144872448734487444875448764487744878448794488044881448824488344884448854488644887448884488944890448914489244893448944489544896448974489844899449004490144902449034490444905449064490744908449094491044911449124491344914449154491644917449184491944920449214492244923449244492544926449274492844929449304493144932449334493444935449364493744938449394494044941449424494344944449454494644947449484494944950449514495244953449544495544956449574495844959449604496144962449634496444965449664496744968449694497044971449724497344974449754497644977449784497944980449814498244983449844498544986449874498844989449904499144992449934499444995449964499744998449994500045001450024500345004450054500645007450084500945010450114501245013450144501545016450174501845019450204502145022450234502445025450264502745028450294503045031450324503345034450354503645037450384503945040450414504245043450444504545046450474504845049450504505145052450534505445055450564505745058450594506045061450624506345064450654506645067450684506945070450714507245073450744507545076450774507845079450804508145082450834508445085450864508745088450894509045091450924509345094450954509645097450984509945100451014510245103451044510545106451074510845109451104511145112451134511445115451164511745118451194512045121451224512345124451254512645127451284512945130451314513245133451344513545136451374513845139451404514145142451434514445145451464514745148451494515045151451524515345154451554515645157451584515945160451614516245163451644516545166451674516845169451704517145172451734517445175451764517745178451794518045181451824518345184451854518645187451884518945190451914519245193451944519545196451974519845199452004520145202452034520445205452064520745208452094521045211452124521345214452154521645217452184521945220452214522245223452244522545226452274522845229452304523145232452334523445235452364523745238452394524045241452424524345244452454524645247452484524945250452514525245253452544525545256452574525845259452604526145262452634526445265452664526745268452694527045271452724527345274452754527645277452784527945280452814528245283452844528545286452874528845289452904529145292452934529445295452964529745298452994530045301453024530345304453054530645307453084530945310453114531245313453144531545316453174531845319453204532145322453234532445325453264532745328453294533045331453324533345334453354533645337453384533945340453414534245343453444534545346453474534845349453504535145352453534535445355453564535745358453594536045361453624536345364453654536645367453684536945370453714537245373453744537545376453774537845379453804538145382453834538445385453864538745388453894539045391453924539345394453954539645397453984539945400454014540245403454044540545406454074540845409454104541145412454134541445415454164541745418454194542045421454224542345424454254542645427454284542945430454314543245433454344543545436454374543845439454404544145442454434544445445454464544745448454494545045451454524545345454454554545645457454584545945460454614546245463454644546545466454674546845469454704547145472454734547445475454764547745478454794548045481454824548345484454854548645487454884548945490454914549245493454944549545496454974549845499455004550145502455034550445505455064550745508455094551045511455124551345514455154551645517455184551945520455214552245523455244552545526455274552845529455304553145532455334553445535455364553745538455394554045541455424554345544455454554645547455484554945550455514555245553455544555545556455574555845559455604556145562455634556445565455664556745568455694557045571455724557345574455754557645577455784557945580455814558245583455844558545586455874558845589455904559145592455934559445595455964559745598455994560045601456024560345604456054560645607456084560945610456114561245613456144561545616456174561845619456204562145622456234562445625456264562745628456294563045631456324563345634456354563645637456384563945640456414564245643456444564545646456474564845649456504565145652456534565445655456564565745658456594566045661456624566345664456654566645667456684566945670456714567245673456744567545676456774567845679456804568145682456834568445685456864568745688456894569045691456924569345694456954569645697456984569945700457014570245703457044570545706457074570845709457104571145712457134571445715457164571745718457194572045721457224572345724457254572645727457284572945730457314573245733457344573545736457374573845739457404574145742457434574445745457464574745748457494575045751457524575345754457554575645757457584575945760457614576245763457644576545766457674576845769457704577145772457734577445775457764577745778457794578045781457824578345784457854578645787457884578945790457914579245793457944579545796457974579845799458004580145802458034580445805458064580745808458094581045811458124581345814458154581645817458184581945820458214582245823458244582545826458274582845829458304583145832458334583445835458364583745838458394584045841458424584345844458454584645847458484584945850458514585245853458544585545856458574585845859458604586145862458634586445865458664586745868458694587045871458724587345874458754587645877458784587945880458814588245883458844588545886458874588845889458904589145892458934589445895458964589745898458994590045901459024590345904459054590645907459084590945910459114591245913459144591545916459174591845919459204592145922459234592445925459264592745928459294593045931459324593345934459354593645937459384593945940459414594245943459444594545946459474594845949459504595145952459534595445955459564595745958459594596045961459624596345964459654596645967459684596945970459714597245973459744597545976459774597845979459804598145982459834598445985459864598745988459894599045991459924599345994459954599645997459984599946000460014600246003460044600546006460074600846009460104601146012460134601446015460164601746018460194602046021460224602346024460254602646027460284602946030460314603246033460344603546036460374603846039460404604146042460434604446045460464604746048460494605046051460524605346054460554605646057460584605946060460614606246063460644606546066460674606846069460704607146072460734607446075460764607746078460794608046081460824608346084460854608646087460884608946090460914609246093460944609546096460974609846099461004610146102461034610446105461064610746108461094611046111461124611346114461154611646117461184611946120461214612246123461244612546126461274612846129461304613146132461334613446135461364613746138461394614046141461424614346144461454614646147461484614946150461514615246153461544615546156461574615846159461604616146162461634616446165461664616746168461694617046171461724617346174461754617646177461784617946180461814618246183461844618546186461874618846189461904619146192461934619446195461964619746198461994620046201462024620346204462054620646207462084620946210462114621246213462144621546216462174621846219462204622146222462234622446225462264622746228462294623046231462324623346234462354623646237462384623946240462414624246243462444624546246462474624846249462504625146252462534625446255462564625746258462594626046261462624626346264462654626646267462684626946270462714627246273462744627546276462774627846279462804628146282462834628446285462864628746288462894629046291462924629346294462954629646297462984629946300463014630246303463044630546306463074630846309463104631146312463134631446315463164631746318463194632046321463224632346324463254632646327463284632946330463314633246333463344633546336463374633846339463404634146342463434634446345463464634746348463494635046351463524635346354463554635646357463584635946360463614636246363463644636546366463674636846369463704637146372463734637446375463764637746378463794638046381463824638346384463854638646387463884638946390463914639246393463944639546396463974639846399464004640146402464034640446405464064640746408464094641046411464124641346414464154641646417464184641946420464214642246423464244642546426464274642846429464304643146432464334643446435464364643746438464394644046441464424644346444464454644646447464484644946450464514645246453464544645546456464574645846459464604646146462464634646446465464664646746468464694647046471464724647346474464754647646477464784647946480464814648246483464844648546486464874648846489464904649146492464934649446495464964649746498464994650046501465024650346504465054650646507465084650946510465114651246513465144651546516465174651846519465204652146522465234652446525465264652746528465294653046531465324653346534465354653646537465384653946540465414654246543465444654546546465474654846549465504655146552465534655446555465564655746558465594656046561465624656346564465654656646567465684656946570465714657246573465744657546576465774657846579465804658146582465834658446585465864658746588465894659046591465924659346594465954659646597465984659946600466014660246603466044660546606466074660846609466104661146612466134661446615466164661746618466194662046621466224662346624466254662646627466284662946630466314663246633466344663546636466374663846639466404664146642466434664446645466464664746648466494665046651466524665346654466554665646657466584665946660466614666246663466644666546666466674666846669466704667146672466734667446675466764667746678466794668046681466824668346684466854668646687466884668946690466914669246693466944669546696466974669846699467004670146702467034670446705467064670746708467094671046711467124671346714467154671646717467184671946720467214672246723467244672546726467274672846729467304673146732467334673446735467364673746738467394674046741467424674346744467454674646747467484674946750467514675246753467544675546756467574675846759467604676146762467634676446765467664676746768467694677046771467724677346774467754677646777467784677946780467814678246783467844678546786467874678846789467904679146792467934679446795467964679746798467994680046801468024680346804468054680646807468084680946810468114681246813468144681546816468174681846819468204682146822468234682446825468264682746828468294683046831468324683346834468354683646837468384683946840468414684246843468444684546846468474684846849468504685146852468534685446855468564685746858468594686046861468624686346864468654686646867468684686946870468714687246873468744687546876468774687846879468804688146882468834688446885468864688746888468894689046891468924689346894468954689646897468984689946900469014690246903469044690546906469074690846909469104691146912469134691446915469164691746918469194692046921469224692346924469254692646927469284692946930469314693246933469344693546936469374693846939469404694146942469434694446945469464694746948469494695046951469524695346954469554695646957469584695946960469614696246963469644696546966469674696846969469704697146972469734697446975469764697746978469794698046981469824698346984469854698646987469884698946990469914699246993469944699546996469974699846999470004700147002470034700447005470064700747008470094701047011470124701347014470154701647017470184701947020470214702247023470244702547026470274702847029470304703147032470334703447035470364703747038470394704047041470424704347044470454704647047470484704947050470514705247053470544705547056470574705847059470604706147062470634706447065470664706747068470694707047071470724707347074470754707647077470784707947080470814708247083470844708547086470874708847089470904709147092470934709447095470964709747098470994710047101471024710347104471054710647107471084710947110471114711247113471144711547116471174711847119471204712147122471234712447125471264712747128471294713047131471324713347134471354713647137471384713947140471414714247143471444714547146471474714847149471504715147152471534715447155471564715747158471594716047161471624716347164471654716647167471684716947170471714717247173471744717547176471774717847179471804718147182471834718447185471864718747188471894719047191471924719347194471954719647197471984719947200472014720247203472044720547206472074720847209472104721147212472134721447215472164721747218472194722047221472224722347224472254722647227472284722947230472314723247233472344723547236472374723847239472404724147242472434724447245472464724747248472494725047251472524725347254472554725647257472584725947260472614726247263472644726547266472674726847269472704727147272472734727447275472764727747278472794728047281472824728347284472854728647287472884728947290472914729247293472944729547296472974729847299473004730147302473034730447305473064730747308473094731047311473124731347314473154731647317473184731947320473214732247323473244732547326473274732847329473304733147332473334733447335473364733747338473394734047341473424734347344473454734647347473484734947350473514735247353473544735547356473574735847359473604736147362473634736447365473664736747368473694737047371473724737347374473754737647377473784737947380473814738247383473844738547386473874738847389473904739147392473934739447395473964739747398473994740047401474024740347404474054740647407474084740947410474114741247413474144741547416474174741847419474204742147422474234742447425474264742747428474294743047431474324743347434474354743647437474384743947440474414744247443474444744547446474474744847449474504745147452474534745447455474564745747458474594746047461474624746347464474654746647467474684746947470474714747247473474744747547476474774747847479474804748147482474834748447485474864748747488474894749047491474924749347494474954749647497474984749947500475014750247503475044750547506475074750847509475104751147512475134751447515475164751747518475194752047521475224752347524475254752647527475284752947530475314753247533475344753547536475374753847539475404754147542475434754447545475464754747548475494755047551475524755347554475554755647557475584755947560475614756247563475644756547566475674756847569475704757147572475734757447575475764757747578475794758047581475824758347584475854758647587475884758947590475914759247593475944759547596475974759847599476004760147602476034760447605476064760747608476094761047611476124761347614476154761647617476184761947620476214762247623476244762547626476274762847629476304763147632476334763447635476364763747638476394764047641476424764347644476454764647647476484764947650476514765247653476544765547656476574765847659476604766147662476634766447665476664766747668476694767047671476724767347674476754767647677476784767947680476814768247683476844768547686476874768847689476904769147692476934769447695476964769747698476994770047701477024770347704477054770647707477084770947710477114771247713477144771547716477174771847719477204772147722477234772447725477264772747728477294773047731477324773347734477354773647737477384773947740477414774247743477444774547746477474774847749477504775147752477534775447755477564775747758477594776047761477624776347764477654776647767477684776947770477714777247773477744777547776477774777847779477804778147782477834778447785477864778747788477894779047791477924779347794477954779647797477984779947800478014780247803478044780547806478074780847809478104781147812478134781447815478164781747818478194782047821478224782347824478254782647827478284782947830478314783247833478344783547836478374783847839478404784147842478434784447845478464784747848478494785047851478524785347854478554785647857478584785947860478614786247863478644786547866478674786847869478704787147872478734787447875478764787747878478794788047881478824788347884478854788647887478884788947890478914789247893478944789547896478974789847899479004790147902479034790447905479064790747908479094791047911479124791347914479154791647917479184791947920479214792247923479244792547926479274792847929479304793147932479334793447935479364793747938479394794047941479424794347944479454794647947479484794947950479514795247953479544795547956479574795847959479604796147962479634796447965479664796747968479694797047971479724797347974479754797647977479784797947980479814798247983479844798547986479874798847989479904799147992479934799447995479964799747998479994800048001480024800348004480054800648007480084800948010480114801248013480144801548016480174801848019480204802148022480234802448025480264802748028480294803048031480324803348034480354803648037480384803948040480414804248043480444804548046480474804848049480504805148052480534805448055480564805748058480594806048061480624806348064480654806648067480684806948070480714807248073480744807548076480774807848079480804808148082480834808448085480864808748088480894809048091480924809348094480954809648097480984809948100481014810248103481044810548106481074810848109481104811148112481134811448115481164811748118481194812048121481224812348124481254812648127481284812948130481314813248133481344813548136481374813848139481404814148142481434814448145481464814748148481494815048151481524815348154481554815648157481584815948160481614816248163481644816548166481674816848169481704817148172481734817448175481764817748178481794818048181481824818348184481854818648187481884818948190481914819248193481944819548196481974819848199482004820148202482034820448205482064820748208482094821048211482124821348214482154821648217482184821948220482214822248223482244822548226482274822848229482304823148232482334823448235482364823748238482394824048241482424824348244482454824648247482484824948250482514825248253482544825548256482574825848259482604826148262482634826448265482664826748268482694827048271482724827348274482754827648277482784827948280482814828248283482844828548286482874828848289482904829148292482934829448295482964829748298482994830048301483024830348304483054830648307483084830948310483114831248313483144831548316483174831848319483204832148322483234832448325483264832748328483294833048331483324833348334483354833648337483384833948340483414834248343483444834548346483474834848349483504835148352483534835448355483564835748358483594836048361483624836348364483654836648367483684836948370483714837248373483744837548376483774837848379483804838148382483834838448385483864838748388483894839048391483924839348394483954839648397483984839948400484014840248403484044840548406484074840848409484104841148412484134841448415484164841748418484194842048421484224842348424484254842648427484284842948430484314843248433484344843548436484374843848439484404844148442484434844448445484464844748448484494845048451484524845348454484554845648457484584845948460484614846248463484644846548466484674846848469484704847148472484734847448475484764847748478484794848048481484824848348484484854848648487484884848948490484914849248493484944849548496484974849848499485004850148502485034850448505485064850748508485094851048511485124851348514485154851648517485184851948520485214852248523485244852548526485274852848529485304853148532485334853448535485364853748538485394854048541485424854348544485454854648547485484854948550485514855248553485544855548556485574855848559485604856148562485634856448565485664856748568485694857048571485724857348574485754857648577485784857948580485814858248583485844858548586485874858848589485904859148592485934859448595485964859748598485994860048601486024860348604486054860648607486084860948610486114861248613486144861548616486174861848619486204862148622486234862448625486264862748628486294863048631486324863348634486354863648637486384863948640486414864248643486444864548646486474864848649486504865148652486534865448655486564865748658486594866048661486624866348664486654866648667486684866948670486714867248673486744867548676486774867848679486804868148682486834868448685486864868748688486894869048691486924869348694486954869648697486984869948700487014870248703487044870548706487074870848709487104871148712487134871448715487164871748718487194872048721487224872348724487254872648727487284872948730487314873248733487344873548736487374873848739487404874148742487434874448745487464874748748487494875048751487524875348754487554875648757487584875948760487614876248763487644876548766487674876848769487704877148772487734877448775487764877748778487794878048781487824878348784487854878648787487884878948790487914879248793487944879548796487974879848799488004880148802488034880448805488064880748808488094881048811488124881348814488154881648817488184881948820488214882248823488244882548826488274882848829488304883148832488334883448835488364883748838488394884048841488424884348844488454884648847488484884948850488514885248853488544885548856488574885848859488604886148862488634886448865488664886748868488694887048871488724887348874488754887648877488784887948880488814888248883488844888548886488874888848889488904889148892488934889448895488964889748898488994890048901489024890348904489054890648907489084890948910489114891248913489144891548916489174891848919489204892148922489234892448925489264892748928489294893048931489324893348934489354893648937489384893948940489414894248943489444894548946489474894848949489504895148952489534895448955489564895748958489594896048961489624896348964489654896648967489684896948970489714897248973489744897548976489774897848979489804898148982489834898448985489864898748988489894899048991489924899348994489954899648997489984899949000490014900249003490044900549006490074900849009490104901149012490134901449015490164901749018490194902049021490224902349024490254902649027490284902949030490314903249033490344903549036490374903849039490404904149042490434904449045490464904749048490494905049051490524905349054490554905649057490584905949060490614906249063490644906549066490674906849069490704907149072490734907449075490764907749078490794908049081490824908349084490854908649087490884908949090490914909249093490944909549096490974909849099491004910149102491034910449105491064910749108491094911049111491124911349114491154911649117491184911949120491214912249123491244912549126491274912849129491304913149132491334913449135491364913749138491394914049141491424914349144491454914649147491484914949150491514915249153491544915549156491574915849159491604916149162491634916449165491664916749168491694917049171491724917349174491754917649177491784917949180491814918249183491844918549186491874918849189491904919149192491934919449195491964919749198491994920049201492024920349204492054920649207492084920949210492114921249213492144921549216492174921849219492204922149222492234922449225492264922749228492294923049231492324923349234492354923649237492384923949240492414924249243492444924549246492474924849249492504925149252492534925449255492564925749258492594926049261492624926349264492654926649267492684926949270492714927249273492744927549276492774927849279492804928149282492834928449285492864928749288492894929049291492924929349294492954929649297492984929949300493014930249303493044930549306493074930849309493104931149312493134931449315493164931749318493194932049321493224932349324493254932649327493284932949330493314933249333493344933549336493374933849339493404934149342493434934449345493464934749348493494935049351493524935349354493554935649357493584935949360493614936249363493644936549366493674936849369493704937149372493734937449375493764937749378493794938049381493824938349384493854938649387493884938949390493914939249393493944939549396493974939849399494004940149402494034940449405494064940749408494094941049411494124941349414494154941649417494184941949420494214942249423494244942549426494274942849429494304943149432494334943449435494364943749438494394944049441494424944349444494454944649447494484944949450494514945249453494544945549456494574945849459494604946149462494634946449465494664946749468494694947049471494724947349474494754947649477494784947949480494814948249483494844948549486494874948849489494904949149492494934949449495494964949749498494994950049501495024950349504495054950649507495084950949510495114951249513495144951549516495174951849519495204952149522495234952449525495264952749528495294953049531495324953349534495354953649537495384953949540495414954249543495444954549546495474954849549495504955149552495534955449555495564955749558495594956049561495624956349564495654956649567495684956949570495714957249573495744957549576495774957849579495804958149582495834958449585495864958749588495894959049591495924959349594495954959649597495984959949600496014960249603496044960549606496074960849609496104961149612496134961449615496164961749618496194962049621496224962349624496254962649627496284962949630496314963249633496344963549636496374963849639496404964149642496434964449645496464964749648496494965049651496524965349654496554965649657496584965949660496614966249663496644966549666496674966849669496704967149672496734967449675496764967749678496794968049681496824968349684496854968649687496884968949690496914969249693496944969549696496974969849699497004970149702497034970449705497064970749708497094971049711497124971349714497154971649717497184971949720497214972249723497244972549726497274972849729497304973149732497334973449735497364973749738497394974049741497424974349744497454974649747497484974949750497514975249753497544975549756497574975849759497604976149762497634976449765497664976749768497694977049771497724977349774497754977649777497784977949780497814978249783497844978549786497874978849789497904979149792497934979449795497964979749798497994980049801498024980349804498054980649807498084980949810498114981249813498144981549816498174981849819498204982149822498234982449825498264982749828498294983049831498324983349834498354983649837498384983949840498414984249843498444984549846498474984849849498504985149852498534985449855498564985749858498594986049861498624986349864498654986649867498684986949870498714987249873498744987549876498774987849879498804988149882498834988449885498864988749888498894989049891498924989349894498954989649897498984989949900499014990249903499044990549906499074990849909499104991149912499134991449915499164991749918499194992049921499224992349924499254992649927499284992949930499314993249933499344993549936499374993849939499404994149942499434994449945499464994749948499494995049951499524995349954499554995649957499584995949960499614996249963499644996549966499674996849969499704997149972499734997449975499764997749978499794998049981499824998349984499854998649987499884998949990499914999249993499944999549996499974999849999500005000150002500035000450005500065000750008500095001050011500125001350014500155001650017500185001950020500215002250023500245002550026500275002850029500305003150032500335003450035500365003750038500395004050041500425004350044500455004650047500485004950050500515005250053500545005550056500575005850059500605006150062500635006450065500665006750068500695007050071500725007350074500755007650077500785007950080500815008250083500845008550086500875008850089500905009150092500935009450095500965009750098500995010050101501025010350104501055010650107501085010950110501115011250113501145011550116501175011850119501205012150122501235012450125501265012750128501295013050131501325013350134501355013650137501385013950140501415014250143501445014550146501475014850149501505015150152501535015450155501565015750158501595016050161501625016350164501655016650167501685016950170501715017250173501745017550176501775017850179501805018150182501835018450185501865018750188501895019050191501925019350194501955019650197501985019950200502015020250203502045020550206502075020850209502105021150212502135021450215502165021750218502195022050221502225022350224502255022650227502285022950230502315023250233502345023550236502375023850239502405024150242502435024450245502465024750248502495025050251502525025350254502555025650257502585025950260502615026250263502645026550266502675026850269502705027150272502735027450275502765027750278502795028050281502825028350284502855028650287502885028950290502915029250293502945029550296502975029850299503005030150302503035030450305503065030750308503095031050311503125031350314503155031650317503185031950320503215032250323503245032550326503275032850329503305033150332503335033450335503365033750338503395034050341503425034350344503455034650347503485034950350503515035250353503545035550356503575035850359503605036150362503635036450365503665036750368503695037050371503725037350374503755037650377503785037950380503815038250383503845038550386503875038850389503905039150392503935039450395503965039750398503995040050401504025040350404504055040650407504085040950410504115041250413504145041550416504175041850419504205042150422504235042450425504265042750428504295043050431504325043350434504355043650437504385043950440504415044250443504445044550446504475044850449504505045150452504535045450455504565045750458504595046050461504625046350464504655046650467504685046950470504715047250473504745047550476504775047850479504805048150482504835048450485504865048750488504895049050491504925049350494504955049650497504985049950500505015050250503505045050550506505075050850509505105051150512505135051450515505165051750518505195052050521505225052350524505255052650527505285052950530505315053250533505345053550536505375053850539505405054150542505435054450545505465054750548505495055050551505525055350554505555055650557505585055950560505615056250563505645056550566505675056850569505705057150572505735057450575505765057750578505795058050581505825058350584505855058650587505885058950590505915059250593505945059550596505975059850599506005060150602506035060450605506065060750608506095061050611506125061350614506155061650617506185061950620506215062250623506245062550626506275062850629506305063150632506335063450635506365063750638506395064050641506425064350644506455064650647506485064950650506515065250653506545065550656506575065850659506605066150662506635066450665506665066750668506695067050671506725067350674506755067650677506785067950680506815068250683506845068550686506875068850689506905069150692506935069450695506965069750698506995070050701507025070350704507055070650707507085070950710507115071250713507145071550716507175071850719507205072150722507235072450725507265072750728507295073050731507325073350734507355073650737507385073950740507415074250743507445074550746507475074850749507505075150752507535075450755507565075750758507595076050761507625076350764507655076650767507685076950770507715077250773507745077550776507775077850779507805078150782507835078450785507865078750788507895079050791507925079350794507955079650797507985079950800508015080250803508045080550806508075080850809508105081150812508135081450815508165081750818508195082050821508225082350824508255082650827508285082950830508315083250833508345083550836508375083850839508405084150842508435084450845508465084750848508495085050851508525085350854508555085650857508585085950860508615086250863508645086550866508675086850869508705087150872508735087450875508765087750878508795088050881508825088350884508855088650887508885088950890508915089250893508945089550896508975089850899509005090150902509035090450905509065090750908509095091050911509125091350914509155091650917509185091950920509215092250923509245092550926509275092850929509305093150932509335093450935509365093750938509395094050941509425094350944509455094650947509485094950950509515095250953509545095550956509575095850959509605096150962509635096450965509665096750968509695097050971509725097350974509755097650977509785097950980509815098250983509845098550986509875098850989509905099150992509935099450995509965099750998509995100051001510025100351004510055100651007510085100951010510115101251013510145101551016510175101851019510205102151022510235102451025510265102751028510295103051031510325103351034510355103651037510385103951040510415104251043510445104551046510475104851049510505105151052510535105451055510565105751058510595106051061510625106351064510655106651067510685106951070510715107251073510745107551076510775107851079510805108151082510835108451085510865108751088510895109051091510925109351094510955109651097510985109951100511015110251103511045110551106511075110851109511105111151112511135111451115511165111751118511195112051121511225112351124511255112651127511285112951130511315113251133511345113551136511375113851139511405114151142511435114451145511465114751148511495115051151511525115351154511555115651157511585115951160511615116251163511645116551166511675116851169511705117151172511735117451175511765117751178511795118051181511825118351184511855118651187511885118951190511915119251193511945119551196511975119851199512005120151202512035120451205512065120751208512095121051211512125121351214512155121651217512185121951220512215122251223512245122551226512275122851229512305123151232512335123451235512365123751238512395124051241512425124351244512455124651247512485124951250512515125251253512545125551256512575125851259512605126151262512635126451265512665126751268512695127051271512725127351274512755127651277512785127951280512815128251283512845128551286512875128851289512905129151292512935129451295512965129751298512995130051301513025130351304513055130651307513085130951310513115131251313513145131551316513175131851319513205132151322513235132451325513265132751328513295133051331513325133351334513355133651337513385133951340513415134251343513445134551346513475134851349513505135151352513535135451355513565135751358513595136051361513625136351364513655136651367513685136951370513715137251373513745137551376513775137851379513805138151382513835138451385513865138751388513895139051391513925139351394513955139651397513985139951400514015140251403514045140551406514075140851409514105141151412514135141451415514165141751418514195142051421514225142351424514255142651427514285142951430514315143251433514345143551436514375143851439514405144151442514435144451445514465144751448514495145051451514525145351454514555145651457514585145951460514615146251463514645146551466514675146851469514705147151472514735147451475514765147751478514795148051481514825148351484514855148651487514885148951490514915149251493514945149551496514975149851499515005150151502515035150451505515065150751508515095151051511515125151351514515155151651517515185151951520515215152251523515245152551526515275152851529515305153151532515335153451535515365153751538515395154051541515425154351544515455154651547515485154951550515515155251553515545155551556515575155851559515605156151562515635156451565515665156751568515695157051571515725157351574515755157651577515785157951580515815158251583515845158551586515875158851589515905159151592515935159451595515965159751598515995160051601516025160351604516055160651607516085160951610516115161251613516145161551616516175161851619516205162151622516235162451625516265162751628516295163051631516325163351634516355163651637516385163951640516415164251643516445164551646516475164851649516505165151652516535165451655516565165751658516595166051661516625166351664516655166651667516685166951670516715167251673516745167551676516775167851679516805168151682516835168451685516865168751688516895169051691516925169351694516955169651697516985169951700517015170251703517045170551706517075170851709517105171151712517135171451715517165171751718517195172051721517225172351724517255172651727517285172951730517315173251733517345173551736517375173851739517405174151742517435174451745517465174751748517495175051751517525175351754517555175651757517585175951760517615176251763517645176551766517675176851769517705177151772517735177451775517765177751778517795178051781517825178351784517855178651787517885178951790517915179251793517945179551796517975179851799518005180151802518035180451805518065180751808518095181051811518125181351814518155181651817518185181951820518215182251823518245182551826518275182851829518305183151832518335183451835518365183751838518395184051841518425184351844518455184651847518485184951850518515185251853518545185551856518575185851859518605186151862518635186451865518665186751868518695187051871518725187351874518755187651877518785187951880518815188251883518845188551886518875188851889518905189151892518935189451895518965189751898518995190051901519025190351904519055190651907519085190951910519115191251913519145191551916519175191851919519205192151922519235192451925519265192751928519295193051931519325193351934519355193651937519385193951940519415194251943519445194551946519475194851949519505195151952519535195451955519565195751958519595196051961519625196351964519655196651967519685196951970519715197251973519745197551976519775197851979519805198151982519835198451985519865198751988519895199051991519925199351994519955199651997519985199952000520015200252003520045200552006520075200852009520105201152012520135201452015520165201752018520195202052021520225202352024520255202652027520285202952030520315203252033520345203552036520375203852039520405204152042520435204452045520465204752048520495205052051520525205352054520555205652057520585205952060520615206252063520645206552066520675206852069520705207152072520735207452075520765207752078520795208052081520825208352084520855208652087520885208952090520915209252093520945209552096520975209852099521005210152102521035210452105521065210752108521095211052111521125211352114521155211652117521185211952120521215212252123521245212552126521275212852129521305213152132521335213452135521365213752138521395214052141521425214352144521455214652147521485214952150521515215252153521545215552156521575215852159521605216152162521635216452165521665216752168521695217052171521725217352174521755217652177521785217952180521815218252183521845218552186521875218852189521905219152192521935219452195521965219752198521995220052201522025220352204522055220652207522085220952210522115221252213522145221552216522175221852219522205222152222522235222452225522265222752228522295223052231522325223352234522355223652237522385223952240522415224252243522445224552246522475224852249522505225152252522535225452255522565225752258522595226052261522625226352264522655226652267522685226952270522715227252273522745227552276522775227852279522805228152282522835228452285522865228752288522895229052291522925229352294522955229652297522985229952300523015230252303523045230552306523075230852309523105231152312523135231452315523165231752318523195232052321523225232352324523255232652327523285232952330523315233252333523345233552336523375233852339523405234152342523435234452345523465234752348523495235052351523525235352354523555235652357523585235952360523615236252363523645236552366523675236852369523705237152372523735237452375523765237752378523795238052381523825238352384523855238652387523885238952390523915239252393523945239552396523975239852399524005240152402524035240452405524065240752408524095241052411524125241352414524155241652417524185241952420524215242252423524245242552426524275242852429524305243152432524335243452435524365243752438524395244052441524425244352444524455244652447524485244952450524515245252453524545245552456524575245852459524605246152462524635246452465524665246752468524695247052471524725247352474524755247652477524785247952480524815248252483524845248552486524875248852489524905249152492524935249452495524965249752498524995250052501525025250352504525055250652507525085250952510525115251252513525145251552516525175251852519525205252152522525235252452525525265252752528525295253052531525325253352534525355253652537525385253952540525415254252543525445254552546525475254852549525505255152552525535255452555525565255752558525595256052561525625256352564525655256652567525685256952570525715257252573525745257552576525775257852579525805258152582525835258452585525865258752588525895259052591525925259352594525955259652597525985259952600526015260252603526045260552606526075260852609526105261152612526135261452615526165261752618526195262052621526225262352624526255262652627526285262952630526315263252633526345263552636526375263852639526405264152642526435264452645526465264752648526495265052651526525265352654526555265652657526585265952660526615266252663526645266552666526675266852669526705267152672526735267452675526765267752678526795268052681526825268352684526855268652687526885268952690526915269252693526945269552696526975269852699527005270152702527035270452705527065270752708527095271052711527125271352714527155271652717527185271952720527215272252723527245272552726527275272852729527305273152732527335273452735527365273752738527395274052741527425274352744527455274652747527485274952750527515275252753527545275552756527575275852759527605276152762527635276452765527665276752768527695277052771527725277352774527755277652777527785277952780527815278252783527845278552786527875278852789527905279152792527935279452795527965279752798527995280052801528025280352804528055280652807528085280952810528115281252813528145281552816528175281852819528205282152822528235282452825528265282752828528295283052831528325283352834528355283652837528385283952840528415284252843528445284552846528475284852849528505285152852528535285452855528565285752858528595286052861528625286352864528655286652867528685286952870528715287252873528745287552876528775287852879528805288152882528835288452885528865288752888528895289052891528925289352894528955289652897528985289952900529015290252903529045290552906529075290852909529105291152912529135291452915529165291752918529195292052921529225292352924529255292652927529285292952930529315293252933529345293552936529375293852939529405294152942529435294452945529465294752948529495295052951529525295352954529555295652957529585295952960529615296252963529645296552966529675296852969529705297152972529735297452975529765297752978529795298052981529825298352984529855298652987529885298952990529915299252993529945299552996529975299852999530005300153002530035300453005530065300753008530095301053011530125301353014530155301653017530185301953020530215302253023530245302553026530275302853029530305303153032530335303453035530365303753038530395304053041530425304353044530455304653047530485304953050530515305253053530545305553056530575305853059530605306153062530635306453065530665306753068530695307053071530725307353074530755307653077530785307953080530815308253083530845308553086530875308853089530905309153092530935309453095530965309753098530995310053101531025310353104531055310653107531085310953110531115311253113531145311553116531175311853119531205312153122531235312453125531265312753128531295313053131531325313353134531355313653137531385313953140531415314253143531445314553146531475314853149531505315153152531535315453155531565315753158531595316053161531625316353164531655316653167531685316953170531715317253173531745317553176531775317853179531805318153182531835318453185531865318753188531895319053191531925319353194531955319653197531985319953200532015320253203532045320553206532075320853209532105321153212532135321453215532165321753218532195322053221532225322353224532255322653227532285322953230532315323253233532345323553236532375323853239532405324153242532435324453245532465324753248532495325053251532525325353254532555325653257532585325953260532615326253263532645326553266532675326853269532705327153272532735327453275532765327753278532795328053281532825328353284532855328653287532885328953290532915329253293532945329553296532975329853299533005330153302533035330453305533065330753308533095331053311533125331353314533155331653317533185331953320533215332253323533245332553326533275332853329533305333153332533335333453335533365333753338533395334053341533425334353344533455334653347533485334953350533515335253353533545335553356533575335853359533605336153362533635336453365533665336753368533695337053371533725337353374533755337653377533785337953380533815338253383533845338553386533875338853389533905339153392533935339453395533965339753398533995340053401534025340353404534055340653407534085340953410534115341253413534145341553416534175341853419534205342153422534235342453425534265342753428534295343053431534325343353434534355343653437534385343953440534415344253443534445344553446534475344853449534505345153452534535345453455534565345753458534595346053461534625346353464534655346653467534685346953470534715347253473534745347553476534775347853479534805348153482534835348453485534865348753488534895349053491534925349353494534955349653497534985349953500535015350253503535045350553506535075350853509535105351153512535135351453515535165351753518535195352053521535225352353524535255352653527535285352953530535315353253533535345353553536535375353853539535405354153542535435354453545535465354753548535495355053551535525355353554535555355653557535585355953560535615356253563535645356553566535675356853569535705357153572535735357453575535765357753578535795358053581535825358353584535855358653587535885358953590535915359253593535945359553596535975359853599536005360153602536035360453605536065360753608536095361053611536125361353614536155361653617536185361953620536215362253623536245362553626536275362853629536305363153632536335363453635536365363753638536395364053641536425364353644536455364653647536485364953650536515365253653536545365553656536575365853659536605366153662536635366453665536665366753668536695367053671536725367353674536755367653677536785367953680536815368253683536845368553686536875368853689536905369153692536935369453695536965369753698536995370053701537025370353704537055370653707537085370953710537115371253713537145371553716537175371853719537205372153722537235372453725537265372753728537295373053731537325373353734537355373653737537385373953740537415374253743537445374553746537475374853749537505375153752537535375453755537565375753758537595376053761537625376353764537655376653767537685376953770537715377253773537745377553776537775377853779537805378153782537835378453785537865378753788537895379053791537925379353794537955379653797537985379953800538015380253803538045380553806538075380853809538105381153812538135381453815538165381753818538195382053821538225382353824538255382653827538285382953830538315383253833538345383553836538375383853839538405384153842538435384453845538465384753848538495385053851538525385353854538555385653857538585385953860538615386253863538645386553866538675386853869538705387153872538735387453875538765387753878538795388053881538825388353884538855388653887538885388953890538915389253893538945389553896538975389853899539005390153902539035390453905539065390753908539095391053911539125391353914539155391653917539185391953920539215392253923539245392553926539275392853929539305393153932539335393453935539365393753938539395394053941539425394353944539455394653947539485394953950539515395253953539545395553956539575395853959539605396153962539635396453965539665396753968539695397053971539725397353974539755397653977539785397953980539815398253983539845398553986539875398853989539905399153992539935399453995539965399753998539995400054001540025400354004540055400654007540085400954010540115401254013540145401554016540175401854019540205402154022540235402454025540265402754028540295403054031540325403354034540355403654037540385403954040540415404254043540445404554046540475404854049540505405154052540535405454055540565405754058540595406054061540625406354064540655406654067540685406954070540715407254073540745407554076540775407854079540805408154082540835408454085540865408754088540895409054091540925409354094540955409654097540985409954100541015410254103541045410554106541075410854109541105411154112541135411454115541165411754118541195412054121541225412354124541255412654127541285412954130541315413254133541345413554136541375413854139541405414154142541435414454145541465414754148541495415054151541525415354154541555415654157541585415954160541615416254163541645416554166541675416854169541705417154172541735417454175541765417754178541795418054181541825418354184541855418654187541885418954190541915419254193541945419554196541975419854199542005420154202542035420454205542065420754208542095421054211542125421354214542155421654217542185421954220542215422254223542245422554226542275422854229542305423154232542335423454235542365423754238542395424054241542425424354244542455424654247542485424954250542515425254253542545425554256542575425854259542605426154262542635426454265542665426754268542695427054271542725427354274542755427654277542785427954280542815428254283542845428554286542875428854289542905429154292542935429454295542965429754298542995430054301543025430354304543055430654307543085430954310543115431254313543145431554316543175431854319543205432154322543235432454325543265432754328543295433054331543325433354334543355433654337543385433954340543415434254343543445434554346543475434854349543505435154352543535435454355543565435754358543595436054361543625436354364543655436654367543685436954370543715437254373543745437554376543775437854379543805438154382543835438454385543865438754388543895439054391543925439354394543955439654397543985439954400544015440254403544045440554406544075440854409544105441154412544135441454415544165441754418544195442054421544225442354424544255442654427544285442954430544315443254433544345443554436544375443854439544405444154442544435444454445544465444754448544495445054451544525445354454544555445654457544585445954460544615446254463544645446554466544675446854469544705447154472544735447454475544765447754478544795448054481544825448354484544855448654487544885448954490544915449254493544945449554496544975449854499545005450154502545035450454505545065450754508545095451054511545125451354514545155451654517545185451954520545215452254523545245452554526545275452854529545305453154532545335453454535545365453754538545395454054541545425454354544545455454654547545485454954550545515455254553545545455554556545575455854559545605456154562545635456454565545665456754568545695457054571545725457354574545755457654577545785457954580545815458254583545845458554586545875458854589545905459154592545935459454595545965459754598545995460054601546025460354604546055460654607546085460954610546115461254613546145461554616546175461854619546205462154622546235462454625546265462754628546295463054631546325463354634546355463654637546385463954640546415464254643546445464554646546475464854649546505465154652546535465454655546565465754658546595466054661546625466354664546655466654667546685466954670546715467254673546745467554676546775467854679546805468154682546835468454685546865468754688546895469054691546925469354694546955469654697546985469954700547015470254703547045470554706547075470854709547105471154712547135471454715547165471754718547195472054721547225472354724547255472654727547285472954730547315473254733547345473554736547375473854739547405474154742547435474454745547465474754748547495475054751547525475354754547555475654757547585475954760547615476254763547645476554766547675476854769547705477154772547735477454775547765477754778547795478054781547825478354784547855478654787547885478954790547915479254793547945479554796547975479854799548005480154802548035480454805548065480754808548095481054811548125481354814548155481654817548185481954820548215482254823548245482554826548275482854829548305483154832548335483454835548365483754838548395484054841548425484354844548455484654847548485484954850548515485254853548545485554856548575485854859548605486154862548635486454865548665486754868548695487054871548725487354874548755487654877548785487954880548815488254883548845488554886548875488854889548905489154892548935489454895548965489754898548995490054901549025490354904549055490654907549085490954910549115491254913549145491554916549175491854919549205492154922549235492454925549265492754928549295493054931549325493354934549355493654937549385493954940549415494254943549445494554946549475494854949549505495154952549535495454955549565495754958549595496054961549625496354964549655496654967549685496954970549715497254973549745497554976549775497854979549805498154982549835498454985549865498754988549895499054991549925499354994549955499654997549985499955000550015500255003550045500555006550075500855009550105501155012550135501455015550165501755018550195502055021550225502355024550255502655027550285502955030550315503255033550345503555036550375503855039550405504155042550435504455045550465504755048550495505055051550525505355054550555505655057550585505955060550615506255063550645506555066550675506855069550705507155072550735507455075550765507755078550795508055081550825508355084550855508655087550885508955090550915509255093550945509555096550975509855099551005510155102551035510455105551065510755108551095511055111551125511355114551155511655117551185511955120551215512255123551245512555126551275512855129551305513155132551335513455135551365513755138551395514055141551425514355144551455514655147551485514955150551515515255153551545515555156551575515855159551605516155162551635516455165551665516755168551695517055171551725517355174551755517655177551785517955180551815518255183551845518555186551875518855189551905519155192551935519455195551965519755198551995520055201552025520355204552055520655207552085520955210552115521255213552145521555216552175521855219552205522155222552235522455225552265522755228552295523055231552325523355234552355523655237552385523955240552415524255243552445524555246552475524855249552505525155252552535525455255552565525755258552595526055261552625526355264552655526655267552685526955270552715527255273552745527555276552775527855279552805528155282552835528455285552865528755288552895529055291552925529355294552955529655297552985529955300553015530255303553045530555306553075530855309553105531155312553135531455315553165531755318553195532055321553225532355324553255532655327553285532955330553315533255333553345533555336553375533855339553405534155342553435534455345553465534755348553495535055351553525535355354553555535655357553585535955360553615536255363553645536555366553675536855369553705537155372553735537455375553765537755378553795538055381553825538355384553855538655387553885538955390553915539255393553945539555396553975539855399554005540155402554035540455405554065540755408554095541055411554125541355414554155541655417554185541955420554215542255423554245542555426554275542855429554305543155432554335543455435554365543755438554395544055441554425544355444554455544655447554485544955450554515545255453554545545555456554575545855459554605546155462554635546455465554665546755468554695547055471554725547355474554755547655477554785547955480554815548255483554845548555486554875548855489554905549155492554935549455495554965549755498554995550055501555025550355504555055550655507555085550955510555115551255513555145551555516555175551855519555205552155522555235552455525555265552755528555295553055531555325553355534555355553655537555385553955540555415554255543555445554555546555475554855549555505555155552555535555455555555565555755558555595556055561555625556355564555655556655567555685556955570555715557255573555745557555576555775557855579555805558155582555835558455585555865558755588555895559055591555925559355594555955559655597555985559955600556015560255603556045560555606556075560855609556105561155612556135561455615556165561755618556195562055621556225562355624556255562655627556285562955630556315563255633556345563555636556375563855639556405564155642556435564455645556465564755648556495565055651556525565355654556555565655657556585565955660556615566255663556645566555666556675566855669556705567155672556735567455675556765567755678556795568055681556825568355684556855568655687556885568955690556915569255693556945569555696556975569855699557005570155702557035570455705557065570755708557095571055711557125571355714557155571655717557185571955720557215572255723557245572555726557275572855729557305573155732557335573455735557365573755738557395574055741557425574355744557455574655747557485574955750557515575255753557545575555756557575575855759557605576155762557635576455765557665576755768557695577055771557725577355774557755577655777557785577955780557815578255783557845578555786557875578855789557905579155792557935579455795557965579755798557995580055801558025580355804558055580655807558085580955810558115581255813558145581555816558175581855819558205582155822558235582455825558265582755828558295583055831558325583355834558355583655837558385583955840558415584255843558445584555846558475584855849558505585155852558535585455855558565585755858558595586055861558625586355864558655586655867558685586955870558715587255873558745587555876558775587855879558805588155882558835588455885558865588755888558895589055891558925589355894558955589655897558985589955900559015590255903559045590555906559075590855909559105591155912559135591455915559165591755918559195592055921559225592355924559255592655927559285592955930559315593255933559345593555936559375593855939559405594155942559435594455945559465594755948559495595055951559525595355954559555595655957559585595955960559615596255963559645596555966559675596855969559705597155972559735597455975559765597755978559795598055981559825598355984559855598655987559885598955990559915599255993559945599555996559975599855999560005600156002560035600456005560065600756008560095601056011560125601356014560155601656017560185601956020560215602256023560245602556026560275602856029560305603156032560335603456035560365603756038560395604056041560425604356044560455604656047560485604956050560515605256053560545605556056560575605856059560605606156062560635606456065560665606756068560695607056071560725607356074560755607656077560785607956080560815608256083560845608556086560875608856089560905609156092560935609456095560965609756098560995610056101561025610356104561055610656107561085610956110561115611256113561145611556116561175611856119561205612156122561235612456125561265612756128561295613056131561325613356134561355613656137561385613956140561415614256143561445614556146561475614856149561505615156152561535615456155561565615756158561595616056161561625616356164561655616656167561685616956170561715617256173561745617556176561775617856179561805618156182561835618456185561865618756188561895619056191561925619356194561955619656197561985619956200562015620256203562045620556206562075620856209562105621156212562135621456215562165621756218562195622056221562225622356224562255622656227562285622956230562315623256233562345623556236562375623856239562405624156242562435624456245562465624756248562495625056251562525625356254562555625656257562585625956260562615626256263562645626556266562675626856269562705627156272562735627456275562765627756278562795628056281562825628356284562855628656287562885628956290562915629256293562945629556296562975629856299563005630156302563035630456305563065630756308563095631056311563125631356314563155631656317563185631956320563215632256323563245632556326563275632856329563305633156332563335633456335563365633756338563395634056341563425634356344563455634656347563485634956350563515635256353563545635556356563575635856359563605636156362563635636456365563665636756368563695637056371563725637356374563755637656377563785637956380563815638256383563845638556386563875638856389563905639156392563935639456395563965639756398563995640056401564025640356404564055640656407564085640956410564115641256413564145641556416564175641856419564205642156422564235642456425564265642756428564295643056431564325643356434564355643656437564385643956440564415644256443564445644556446564475644856449564505645156452564535645456455564565645756458564595646056461564625646356464564655646656467564685646956470564715647256473564745647556476564775647856479564805648156482564835648456485564865648756488564895649056491564925649356494564955649656497564985649956500565015650256503565045650556506565075650856509565105651156512565135651456515565165651756518565195652056521565225652356524565255652656527565285652956530565315653256533565345653556536565375653856539565405654156542565435654456545565465654756548565495655056551565525655356554565555655656557565585655956560565615656256563565645656556566565675656856569565705657156572565735657456575565765657756578565795658056581565825658356584565855658656587565885658956590565915659256593565945659556596565975659856599566005660156602566035660456605566065660756608566095661056611566125661356614566155661656617566185661956620566215662256623566245662556626566275662856629566305663156632566335663456635566365663756638566395664056641566425664356644566455664656647566485664956650566515665256653566545665556656566575665856659566605666156662566635666456665566665666756668566695667056671566725667356674566755667656677566785667956680566815668256683566845668556686566875668856689566905669156692566935669456695566965669756698566995670056701567025670356704567055670656707567085670956710567115671256713567145671556716567175671856719567205672156722567235672456725567265672756728567295673056731567325673356734567355673656737567385673956740567415674256743567445674556746567475674856749567505675156752567535675456755567565675756758567595676056761567625676356764567655676656767567685676956770567715677256773567745677556776567775677856779567805678156782567835678456785567865678756788567895679056791567925679356794567955679656797567985679956800568015680256803568045680556806568075680856809568105681156812568135681456815568165681756818568195682056821568225682356824568255682656827568285682956830568315683256833568345683556836568375683856839568405684156842568435684456845568465684756848568495685056851568525685356854568555685656857568585685956860568615686256863568645686556866568675686856869568705687156872568735687456875568765687756878568795688056881568825688356884568855688656887568885688956890568915689256893568945689556896568975689856899569005690156902569035690456905569065690756908569095691056911569125691356914569155691656917569185691956920569215692256923569245692556926569275692856929569305693156932569335693456935569365693756938569395694056941569425694356944569455694656947569485694956950569515695256953569545695556956569575695856959569605696156962569635696456965569665696756968569695697056971569725697356974569755697656977569785697956980569815698256983569845698556986569875698856989569905699156992569935699456995569965699756998569995700057001570025700357004570055700657007570085700957010570115701257013570145701557016570175701857019570205702157022570235702457025570265702757028570295703057031570325703357034570355703657037570385703957040570415704257043570445704557046570475704857049570505705157052570535705457055570565705757058570595706057061570625706357064570655706657067570685706957070570715707257073570745707557076570775707857079570805708157082570835708457085570865708757088570895709057091570925709357094570955709657097570985709957100571015710257103571045710557106571075710857109571105711157112571135711457115571165711757118571195712057121571225712357124571255712657127571285712957130571315713257133571345713557136571375713857139571405714157142571435714457145571465714757148571495715057151571525715357154571555715657157571585715957160571615716257163571645716557166571675716857169571705717157172571735717457175571765717757178571795718057181571825718357184571855718657187571885718957190571915719257193571945719557196571975719857199572005720157202572035720457205572065720757208572095721057211572125721357214572155721657217572185721957220572215722257223572245722557226572275722857229572305723157232572335723457235572365723757238572395724057241572425724357244572455724657247572485724957250572515725257253572545725557256572575725857259572605726157262572635726457265572665726757268572695727057271572725727357274572755727657277572785727957280572815728257283572845728557286572875728857289572905729157292572935729457295572965729757298572995730057301573025730357304573055730657307573085730957310573115731257313573145731557316573175731857319573205732157322573235732457325573265732757328573295733057331573325733357334573355733657337573385733957340573415734257343573445734557346573475734857349573505735157352573535735457355573565735757358573595736057361573625736357364573655736657367573685736957370573715737257373573745737557376573775737857379573805738157382573835738457385573865738757388573895739057391573925739357394573955739657397573985739957400574015740257403574045740557406574075740857409574105741157412574135741457415574165741757418574195742057421574225742357424574255742657427574285742957430574315743257433574345743557436574375743857439574405744157442574435744457445574465744757448574495745057451574525745357454574555745657457574585745957460574615746257463574645746557466574675746857469574705747157472574735747457475574765747757478574795748057481574825748357484574855748657487574885748957490574915749257493574945749557496574975749857499575005750157502575035750457505575065750757508575095751057511575125751357514575155751657517575185751957520575215752257523575245752557526575275752857529575305753157532575335753457535575365753757538575395754057541575425754357544575455754657547575485754957550575515755257553575545755557556575575755857559575605756157562575635756457565575665756757568575695757057571575725757357574575755757657577575785757957580575815758257583575845758557586575875758857589575905759157592575935759457595575965759757598575995760057601576025760357604576055760657607576085760957610576115761257613576145761557616576175761857619576205762157622576235762457625576265762757628576295763057631576325763357634576355763657637576385763957640576415764257643576445764557646576475764857649576505765157652576535765457655576565765757658576595766057661576625766357664576655766657667576685766957670576715767257673576745767557676576775767857679576805768157682576835768457685576865768757688576895769057691576925769357694576955769657697576985769957700577015770257703577045770557706577075770857709577105771157712577135771457715577165771757718577195772057721577225772357724577255772657727577285772957730577315773257733577345773557736577375773857739577405774157742577435774457745577465774757748577495775057751577525775357754577555775657757577585775957760577615776257763577645776557766577675776857769577705777157772577735777457775577765777757778577795778057781577825778357784577855778657787577885778957790577915779257793577945779557796577975779857799578005780157802578035780457805578065780757808578095781057811578125781357814578155781657817578185781957820578215782257823578245782557826578275782857829578305783157832578335783457835578365783757838578395784057841578425784357844578455784657847578485784957850578515785257853578545785557856578575785857859578605786157862578635786457865578665786757868578695787057871578725787357874578755787657877578785787957880578815788257883578845788557886578875788857889578905789157892578935789457895578965789757898578995790057901579025790357904579055790657907579085790957910579115791257913579145791557916579175791857919579205792157922579235792457925579265792757928579295793057931579325793357934579355793657937579385793957940579415794257943579445794557946579475794857949579505795157952579535795457955579565795757958579595796057961579625796357964579655796657967579685796957970579715797257973579745797557976579775797857979579805798157982579835798457985579865798757988579895799057991579925799357994579955799657997579985799958000580015800258003580045800558006580075800858009580105801158012580135801458015580165801758018580195802058021580225802358024580255802658027580285802958030580315803258033580345803558036580375803858039580405804158042580435804458045580465804758048580495805058051580525805358054580555805658057580585805958060580615806258063580645806558066580675806858069580705807158072580735807458075580765807758078580795808058081580825808358084580855808658087580885808958090580915809258093580945809558096580975809858099581005810158102581035810458105581065810758108581095811058111581125811358114581155811658117581185811958120581215812258123581245812558126581275812858129581305813158132581335813458135581365813758138581395814058141581425814358144581455814658147581485814958150581515815258153581545815558156581575815858159581605816158162581635816458165581665816758168581695817058171581725817358174581755817658177581785817958180581815818258183581845818558186581875818858189581905819158192581935819458195581965819758198581995820058201582025820358204582055820658207582085820958210582115821258213582145821558216582175821858219582205822158222582235822458225582265822758228582295823058231582325823358234582355823658237582385823958240582415824258243582445824558246582475824858249582505825158252582535825458255582565825758258582595826058261582625826358264582655826658267582685826958270582715827258273582745827558276582775827858279582805828158282582835828458285582865828758288582895829058291582925829358294582955829658297582985829958300583015830258303583045830558306583075830858309583105831158312583135831458315583165831758318583195832058321583225832358324583255832658327583285832958330583315833258333583345833558336583375833858339583405834158342583435834458345583465834758348583495835058351583525835358354583555835658357583585835958360583615836258363583645836558366583675836858369583705837158372583735837458375583765837758378583795838058381583825838358384583855838658387583885838958390583915839258393583945839558396583975839858399584005840158402584035840458405584065840758408584095841058411584125841358414584155841658417584185841958420584215842258423584245842558426584275842858429584305843158432584335843458435584365843758438584395844058441584425844358444584455844658447584485844958450584515845258453584545845558456584575845858459584605846158462584635846458465584665846758468584695847058471584725847358474584755847658477584785847958480584815848258483584845848558486584875848858489584905849158492584935849458495584965849758498584995850058501585025850358504585055850658507585085850958510585115851258513585145851558516585175851858519585205852158522585235852458525585265852758528585295853058531585325853358534585355853658537585385853958540585415854258543585445854558546585475854858549585505855158552585535855458555585565855758558585595856058561585625856358564585655856658567585685856958570585715857258573585745857558576585775857858579585805858158582585835858458585585865858758588585895859058591585925859358594585955859658597585985859958600586015860258603586045860558606586075860858609586105861158612586135861458615586165861758618586195862058621586225862358624586255862658627586285862958630586315863258633586345863558636586375863858639586405864158642586435864458645586465864758648586495865058651586525865358654586555865658657586585865958660586615866258663586645866558666586675866858669586705867158672586735867458675586765867758678586795868058681586825868358684586855868658687586885868958690586915869258693586945869558696586975869858699587005870158702587035870458705587065870758708587095871058711587125871358714587155871658717587185871958720587215872258723587245872558726587275872858729587305873158732587335873458735587365873758738587395874058741587425874358744587455874658747587485874958750587515875258753587545875558756587575875858759587605876158762587635876458765587665876758768587695877058771587725877358774587755877658777587785877958780587815878258783587845878558786587875878858789587905879158792587935879458795587965879758798587995880058801588025880358804588055880658807588085880958810588115881258813588145881558816588175881858819588205882158822588235882458825588265882758828588295883058831588325883358834588355883658837588385883958840588415884258843588445884558846588475884858849588505885158852588535885458855588565885758858588595886058861588625886358864588655886658867588685886958870588715887258873588745887558876588775887858879588805888158882588835888458885588865888758888588895889058891588925889358894588955889658897588985889958900589015890258903589045890558906589075890858909589105891158912589135891458915589165891758918589195892058921589225892358924589255892658927589285892958930589315893258933589345893558936589375893858939589405894158942589435894458945589465894758948589495895058951589525895358954589555895658957589585895958960589615896258963589645896558966589675896858969589705897158972589735897458975589765897758978589795898058981589825898358984589855898658987589885898958990589915899258993589945899558996589975899858999590005900159002590035900459005590065900759008590095901059011590125901359014590155901659017590185901959020590215902259023590245902559026590275902859029590305903159032590335903459035590365903759038590395904059041590425904359044590455904659047590485904959050590515905259053590545905559056590575905859059590605906159062590635906459065590665906759068590695907059071590725907359074590755907659077590785907959080590815908259083590845908559086590875908859089590905909159092590935909459095590965909759098590995910059101591025910359104591055910659107591085910959110591115911259113591145911559116591175911859119591205912159122591235912459125591265912759128591295913059131591325913359134591355913659137591385913959140591415914259143591445914559146591475914859149591505915159152591535915459155591565915759158591595916059161591625916359164591655916659167591685916959170591715917259173591745917559176591775917859179591805918159182591835918459185591865918759188591895919059191591925919359194591955919659197591985919959200592015920259203592045920559206592075920859209592105921159212592135921459215592165921759218592195922059221592225922359224592255922659227592285922959230592315923259233592345923559236592375923859239592405924159242592435924459245592465924759248592495925059251592525925359254592555925659257592585925959260592615926259263592645926559266592675926859269592705927159272592735927459275592765927759278592795928059281592825928359284592855928659287592885928959290592915929259293592945929559296592975929859299593005930159302593035930459305593065930759308593095931059311593125931359314593155931659317593185931959320593215932259323593245932559326593275932859329593305933159332593335933459335593365933759338593395934059341593425934359344593455934659347593485934959350593515935259353593545935559356593575935859359593605936159362593635936459365593665936759368593695937059371593725937359374593755937659377593785937959380593815938259383593845938559386593875938859389593905939159392593935939459395593965939759398593995940059401594025940359404594055940659407594085940959410594115941259413594145941559416594175941859419594205942159422594235942459425594265942759428594295943059431594325943359434594355943659437594385943959440594415944259443594445944559446594475944859449594505945159452594535945459455594565945759458594595946059461594625946359464594655946659467594685946959470594715947259473594745947559476594775947859479594805948159482594835948459485594865948759488594895949059491594925949359494594955949659497594985949959500595015950259503595045950559506595075950859509595105951159512595135951459515595165951759518595195952059521595225952359524595255952659527595285952959530595315953259533595345953559536595375953859539595405954159542595435954459545595465954759548595495955059551595525955359554595555955659557595585955959560595615956259563595645956559566595675956859569595705957159572595735957459575595765957759578595795958059581595825958359584595855958659587595885958959590595915959259593595945959559596595975959859599596005960159602596035960459605596065960759608596095961059611596125961359614596155961659617596185961959620596215962259623596245962559626596275962859629596305963159632596335963459635596365963759638596395964059641596425964359644596455964659647596485964959650596515965259653596545965559656596575965859659596605966159662596635966459665596665966759668596695967059671596725967359674596755967659677596785967959680596815968259683596845968559686596875968859689596905969159692596935969459695596965969759698596995970059701597025970359704597055970659707597085970959710597115971259713597145971559716597175971859719597205972159722597235972459725597265972759728597295973059731597325973359734597355973659737597385973959740597415974259743597445974559746597475974859749597505975159752597535975459755597565975759758597595976059761597625976359764597655976659767597685976959770597715977259773597745977559776597775977859779597805978159782597835978459785597865978759788597895979059791597925979359794597955979659797597985979959800598015980259803598045980559806598075980859809598105981159812598135981459815598165981759818598195982059821598225982359824598255982659827598285982959830598315983259833598345983559836598375983859839598405984159842598435984459845598465984759848598495985059851598525985359854598555985659857598585985959860598615986259863598645986559866598675986859869598705987159872598735987459875598765987759878598795988059881598825988359884598855988659887598885988959890598915989259893598945989559896598975989859899599005990159902599035990459905599065990759908599095991059911599125991359914599155991659917599185991959920599215992259923599245992559926599275992859929599305993159932599335993459935599365993759938599395994059941599425994359944599455994659947599485994959950599515995259953599545995559956599575995859959599605996159962599635996459965599665996759968599695997059971599725997359974599755997659977599785997959980599815998259983599845998559986599875998859989599905999159992599935999459995599965999759998599996000060001600026000360004600056000660007600086000960010600116001260013600146001560016600176001860019600206002160022600236002460025600266002760028600296003060031600326003360034600356003660037600386003960040600416004260043600446004560046600476004860049600506005160052600536005460055600566005760058600596006060061600626006360064600656006660067600686006960070600716007260073600746007560076600776007860079600806008160082600836008460085600866008760088600896009060091600926009360094600956009660097600986009960100601016010260103601046010560106601076010860109601106011160112601136011460115601166011760118601196012060121601226012360124601256012660127601286012960130601316013260133601346013560136601376013860139601406014160142601436014460145601466014760148601496015060151601526015360154601556015660157601586015960160601616016260163601646016560166601676016860169601706017160172601736017460175601766017760178601796018060181601826018360184601856018660187601886018960190601916019260193601946019560196601976019860199602006020160202602036020460205602066020760208602096021060211602126021360214602156021660217602186021960220602216022260223602246022560226602276022860229602306023160232602336023460235602366023760238602396024060241602426024360244602456024660247602486024960250602516025260253602546025560256602576025860259602606026160262602636026460265602666026760268602696027060271602726027360274602756027660277602786027960280602816028260283602846028560286602876028860289602906029160292602936029460295602966029760298602996030060301603026030360304603056030660307603086030960310603116031260313603146031560316603176031860319603206032160322603236032460325603266032760328603296033060331603326033360334603356033660337603386033960340603416034260343603446034560346603476034860349603506035160352603536035460355603566035760358603596036060361603626036360364603656036660367603686036960370603716037260373603746037560376603776037860379603806038160382603836038460385603866038760388603896039060391603926039360394603956039660397603986039960400604016040260403604046040560406604076040860409604106041160412604136041460415604166041760418604196042060421604226042360424604256042660427604286042960430604316043260433604346043560436604376043860439604406044160442604436044460445604466044760448604496045060451604526045360454604556045660457604586045960460604616046260463604646046560466604676046860469604706047160472604736047460475604766047760478604796048060481604826048360484604856048660487604886048960490604916049260493604946049560496604976049860499605006050160502605036050460505605066050760508605096051060511605126051360514605156051660517605186051960520605216052260523605246052560526605276052860529605306053160532605336053460535605366053760538605396054060541605426054360544605456054660547605486054960550605516055260553605546055560556605576055860559605606056160562605636056460565605666056760568605696057060571605726057360574605756057660577605786057960580605816058260583605846058560586605876058860589605906059160592605936059460595605966059760598605996060060601606026060360604606056060660607606086060960610606116061260613606146061560616606176061860619606206062160622606236062460625606266062760628606296063060631606326063360634606356063660637606386063960640606416064260643606446064560646606476064860649606506065160652606536065460655606566065760658606596066060661606626066360664606656066660667606686066960670606716067260673606746067560676606776067860679606806068160682606836068460685606866068760688606896069060691606926069360694606956069660697606986069960700607016070260703607046070560706607076070860709607106071160712607136071460715607166071760718607196072060721607226072360724607256072660727607286072960730607316073260733607346073560736607376073860739607406074160742607436074460745607466074760748607496075060751607526075360754607556075660757607586075960760607616076260763607646076560766607676076860769607706077160772607736077460775607766077760778607796078060781607826078360784607856078660787607886078960790607916079260793607946079560796607976079860799608006080160802608036080460805608066080760808608096081060811608126081360814608156081660817608186081960820608216082260823608246082560826608276082860829608306083160832608336083460835608366083760838608396084060841608426084360844608456084660847608486084960850608516085260853608546085560856608576085860859608606086160862608636086460865608666086760868608696087060871608726087360874608756087660877608786087960880608816088260883608846088560886608876088860889608906089160892608936089460895608966089760898608996090060901609026090360904609056090660907609086090960910609116091260913609146091560916609176091860919609206092160922609236092460925609266092760928609296093060931609326093360934609356093660937609386093960940609416094260943609446094560946609476094860949609506095160952609536095460955609566095760958609596096060961609626096360964609656096660967609686096960970609716097260973609746097560976609776097860979609806098160982609836098460985609866098760988609896099060991609926099360994609956099660997609986099961000610016100261003610046100561006610076100861009610106101161012610136101461015610166101761018610196102061021610226102361024610256102661027610286102961030610316103261033610346103561036610376103861039610406104161042610436104461045610466104761048610496105061051610526105361054610556105661057610586105961060610616106261063610646106561066610676106861069610706107161072610736107461075610766107761078610796108061081610826108361084610856108661087610886108961090610916109261093610946109561096610976109861099611006110161102611036110461105611066110761108611096111061111611126111361114611156111661117611186111961120611216112261123611246112561126611276112861129611306113161132611336113461135611366113761138611396114061141611426114361144611456114661147611486114961150611516115261153611546115561156611576115861159611606116161162611636116461165611666116761168611696117061171611726117361174611756117661177611786117961180611816118261183611846118561186611876118861189611906119161192611936119461195611966119761198611996120061201612026120361204612056120661207612086120961210612116121261213612146121561216612176121861219612206122161222612236122461225612266122761228612296123061231612326123361234612356123661237612386123961240612416124261243612446124561246612476124861249612506125161252612536125461255612566125761258612596126061261612626126361264612656126661267612686126961270612716127261273612746127561276612776127861279612806128161282612836128461285612866128761288612896129061291612926129361294612956129661297612986129961300613016130261303613046130561306613076130861309613106131161312613136131461315613166131761318613196132061321613226132361324613256132661327613286132961330613316133261333613346133561336613376133861339613406134161342613436134461345613466134761348613496135061351613526135361354613556135661357613586135961360613616136261363613646136561366613676136861369613706137161372613736137461375613766137761378613796138061381613826138361384613856138661387613886138961390613916139261393613946139561396613976139861399614006140161402614036140461405614066140761408614096141061411614126141361414614156141661417614186141961420614216142261423614246142561426614276142861429614306143161432614336143461435614366143761438614396144061441614426144361444614456144661447614486144961450614516145261453614546145561456614576145861459614606146161462614636146461465614666146761468614696147061471614726147361474614756147661477614786147961480614816148261483614846148561486614876148861489614906149161492614936149461495614966149761498614996150061501615026150361504615056150661507615086150961510615116151261513615146151561516615176151861519615206152161522615236152461525615266152761528615296153061531615326153361534615356153661537615386153961540615416154261543615446154561546615476154861549615506155161552615536155461555615566155761558615596156061561615626156361564615656156661567615686156961570615716157261573615746157561576615776157861579615806158161582615836158461585615866158761588615896159061591615926159361594615956159661597615986159961600616016160261603616046160561606616076160861609616106161161612616136161461615616166161761618616196162061621616226162361624616256162661627616286162961630616316163261633616346163561636616376163861639616406164161642616436164461645616466164761648616496165061651616526165361654616556165661657616586165961660616616166261663616646166561666616676166861669616706167161672616736167461675616766167761678616796168061681616826168361684616856168661687616886168961690616916169261693616946169561696616976169861699617006170161702617036170461705617066170761708617096171061711617126171361714617156171661717617186171961720617216172261723617246172561726617276172861729617306173161732617336173461735617366173761738617396174061741617426174361744617456174661747617486174961750617516175261753617546175561756617576175861759617606176161762617636176461765617666176761768617696177061771617726177361774617756177661777617786177961780617816178261783617846178561786617876178861789617906179161792617936179461795617966179761798617996180061801618026180361804618056180661807618086180961810618116181261813618146181561816618176181861819618206182161822618236182461825618266182761828618296183061831618326183361834618356183661837618386183961840618416184261843618446184561846618476184861849618506185161852618536185461855618566185761858618596186061861618626186361864618656186661867618686186961870618716187261873618746187561876618776187861879618806188161882618836188461885618866188761888618896189061891618926189361894618956189661897618986189961900619016190261903619046190561906619076190861909619106191161912619136191461915619166191761918619196192061921619226192361924619256192661927619286192961930619316193261933619346193561936619376193861939619406194161942619436194461945619466194761948619496195061951619526195361954619556195661957619586195961960619616196261963619646196561966619676196861969619706197161972619736197461975619766197761978619796198061981619826198361984619856198661987619886198961990619916199261993619946199561996619976199861999620006200162002620036200462005620066200762008620096201062011620126201362014620156201662017620186201962020620216202262023620246202562026620276202862029620306203162032620336203462035620366203762038620396204062041620426204362044620456204662047620486204962050620516205262053620546205562056620576205862059620606206162062620636206462065620666206762068620696207062071620726207362074620756207662077620786207962080620816208262083620846208562086620876208862089620906209162092620936209462095620966209762098620996210062101621026210362104621056210662107621086210962110621116211262113621146211562116621176211862119621206212162122621236212462125621266212762128621296213062131621326213362134621356213662137621386213962140621416214262143621446214562146621476214862149621506215162152621536215462155621566215762158621596216062161621626216362164621656216662167621686216962170621716217262173621746217562176621776217862179621806218162182621836218462185621866218762188621896219062191621926219362194621956219662197621986219962200622016220262203622046220562206622076220862209622106221162212622136221462215622166221762218622196222062221622226222362224622256222662227622286222962230622316223262233622346223562236622376223862239622406224162242622436224462245622466224762248622496225062251622526225362254622556225662257622586225962260622616226262263622646226562266622676226862269622706227162272622736227462275622766227762278622796228062281622826228362284622856228662287622886228962290622916229262293622946229562296622976229862299623006230162302623036230462305623066230762308623096231062311623126231362314623156231662317623186231962320623216232262323623246232562326623276232862329623306233162332623336233462335623366233762338623396234062341623426234362344623456234662347623486234962350623516235262353623546235562356623576235862359623606236162362623636236462365623666236762368623696237062371623726237362374623756237662377623786237962380623816238262383623846238562386623876238862389623906239162392623936239462395623966239762398623996240062401624026240362404624056240662407624086240962410624116241262413624146241562416624176241862419624206242162422624236242462425624266242762428624296243062431624326243362434624356243662437624386243962440624416244262443624446244562446624476244862449624506245162452624536245462455624566245762458624596246062461624626246362464624656246662467624686246962470624716247262473624746247562476624776247862479624806248162482624836248462485624866248762488624896249062491624926249362494624956249662497624986249962500625016250262503625046250562506625076250862509625106251162512625136251462515625166251762518625196252062521625226252362524625256252662527625286252962530625316253262533625346253562536625376253862539625406254162542625436254462545625466254762548625496255062551625526255362554625556255662557625586255962560625616256262563625646256562566625676256862569625706257162572625736257462575625766257762578625796258062581625826258362584625856258662587625886258962590625916259262593625946259562596625976259862599626006260162602626036260462605626066260762608626096261062611626126261362614626156261662617626186261962620626216262262623626246262562626626276262862629626306263162632626336263462635626366263762638626396264062641626426264362644626456264662647626486264962650626516265262653626546265562656626576265862659626606266162662626636266462665626666266762668626696267062671626726267362674626756267662677626786267962680626816268262683626846268562686626876268862689626906269162692626936269462695626966269762698626996270062701627026270362704627056270662707627086270962710627116271262713627146271562716627176271862719627206272162722627236272462725627266272762728627296273062731627326273362734627356273662737627386273962740627416274262743627446274562746627476274862749627506275162752627536275462755627566275762758627596276062761627626276362764627656276662767627686276962770627716277262773627746277562776627776277862779627806278162782627836278462785627866278762788627896279062791627926279362794627956279662797627986279962800628016280262803628046280562806628076280862809628106281162812628136281462815628166281762818628196282062821628226282362824628256282662827628286282962830628316283262833628346283562836628376283862839628406284162842628436284462845628466284762848628496285062851628526285362854628556285662857628586285962860628616286262863628646286562866628676286862869628706287162872628736287462875628766287762878628796288062881628826288362884628856288662887628886288962890628916289262893628946289562896628976289862899629006290162902629036290462905629066290762908629096291062911629126291362914629156291662917629186291962920629216292262923629246292562926629276292862929629306293162932629336293462935629366293762938629396294062941629426294362944629456294662947629486294962950629516295262953629546295562956629576295862959629606296162962629636296462965629666296762968629696297062971629726297362974629756297662977629786297962980629816298262983629846298562986629876298862989629906299162992629936299462995629966299762998629996300063001630026300363004630056300663007630086300963010630116301263013630146301563016630176301863019630206302163022630236302463025630266302763028630296303063031630326303363034630356303663037630386303963040630416304263043630446304563046630476304863049630506305163052630536305463055630566305763058630596306063061630626306363064630656306663067630686306963070630716307263073630746307563076630776307863079630806308163082630836308463085630866308763088630896309063091630926309363094630956309663097630986309963100631016310263103631046310563106631076310863109631106311163112631136311463115631166311763118631196312063121631226312363124631256312663127631286312963130631316313263133631346313563136631376313863139631406314163142631436314463145631466314763148631496315063151631526315363154631556315663157631586315963160631616316263163631646316563166631676316863169631706317163172631736317463175631766317763178631796318063181631826318363184631856318663187631886318963190631916319263193631946319563196631976319863199632006320163202632036320463205632066320763208632096321063211632126321363214632156321663217632186321963220632216322263223632246322563226632276322863229632306323163232632336323463235632366323763238632396324063241632426324363244632456324663247632486324963250632516325263253632546325563256632576325863259632606326163262632636326463265632666326763268632696327063271632726327363274632756327663277632786327963280632816328263283632846328563286632876328863289632906329163292632936329463295632966329763298632996330063301633026330363304633056330663307633086330963310633116331263313633146331563316633176331863319633206332163322633236332463325633266332763328633296333063331633326333363334633356333663337633386333963340633416334263343633446334563346633476334863349633506335163352633536335463355633566335763358633596336063361633626336363364633656336663367633686336963370633716337263373633746337563376633776337863379633806338163382633836338463385633866338763388633896339063391633926339363394633956339663397633986339963400634016340263403634046340563406634076340863409634106341163412634136341463415634166341763418634196342063421634226342363424634256342663427634286342963430634316343263433634346343563436634376343863439634406344163442634436344463445634466344763448634496345063451634526345363454634556345663457634586345963460634616346263463634646346563466634676346863469634706347163472634736347463475634766347763478634796348063481634826348363484634856348663487634886348963490634916349263493634946349563496634976349863499635006350163502635036350463505635066350763508635096351063511635126351363514635156351663517635186351963520635216352263523635246352563526635276352863529635306353163532635336353463535635366353763538635396354063541635426354363544635456354663547635486354963550635516355263553635546355563556635576355863559635606356163562635636356463565635666356763568635696357063571635726357363574635756357663577635786357963580635816358263583635846358563586635876358863589635906359163592635936359463595635966359763598635996360063601636026360363604636056360663607636086360963610636116361263613636146361563616636176361863619636206362163622636236362463625636266362763628636296363063631636326363363634636356363663637636386363963640636416364263643636446364563646636476364863649636506365163652636536365463655636566365763658636596366063661636626366363664636656366663667636686366963670636716367263673636746367563676636776367863679636806368163682636836368463685636866368763688636896369063691636926369363694636956369663697636986369963700637016370263703637046370563706637076370863709637106371163712637136371463715637166371763718637196372063721637226372363724637256372663727637286372963730637316373263733637346373563736637376373863739637406374163742637436374463745637466374763748637496375063751637526375363754637556375663757637586375963760637616376263763637646376563766637676376863769637706377163772637736377463775637766377763778637796378063781637826378363784637856378663787637886378963790637916379263793637946379563796637976379863799638006380163802638036380463805638066380763808638096381063811638126381363814638156381663817638186381963820638216382263823638246382563826638276382863829638306383163832638336383463835638366383763838638396384063841638426384363844638456384663847638486384963850638516385263853638546385563856638576385863859638606386163862638636386463865638666386763868638696387063871638726387363874638756387663877638786387963880638816388263883638846388563886638876388863889638906389163892638936389463895638966389763898638996390063901639026390363904639056390663907639086390963910639116391263913639146391563916639176391863919639206392163922639236392463925639266392763928639296393063931639326393363934639356393663937639386393963940639416394263943639446394563946639476394863949639506395163952639536395463955639566395763958639596396063961639626396363964639656396663967639686396963970639716397263973639746397563976639776397863979639806398163982639836398463985639866398763988639896399063991639926399363994639956399663997639986399964000640016400264003640046400564006640076400864009640106401164012640136401464015640166401764018640196402064021640226402364024640256402664027640286402964030640316403264033640346403564036640376403864039640406404164042640436404464045640466404764048640496405064051640526405364054640556405664057640586405964060640616406264063640646406564066640676406864069640706407164072640736407464075640766407764078640796408064081640826408364084640856408664087640886408964090640916409264093640946409564096640976409864099641006410164102641036410464105641066410764108641096411064111641126411364114641156411664117641186411964120641216412264123641246412564126641276412864129641306413164132641336413464135641366413764138641396414064141641426414364144641456414664147641486414964150641516415264153641546415564156641576415864159641606416164162641636416464165641666416764168641696417064171641726417364174641756417664177641786417964180641816418264183641846418564186641876418864189641906419164192641936419464195641966419764198641996420064201642026420364204642056420664207642086420964210642116421264213642146421564216642176421864219642206422164222642236422464225642266422764228642296423064231642326423364234642356423664237642386423964240642416424264243642446424564246642476424864249642506425164252642536425464255642566425764258642596426064261642626426364264642656426664267642686426964270642716427264273642746427564276642776427864279642806428164282642836428464285642866428764288642896429064291642926429364294642956429664297642986429964300643016430264303643046430564306643076430864309643106431164312643136431464315643166431764318643196432064321643226432364324643256432664327643286432964330643316433264333643346433564336643376433864339643406434164342643436434464345643466434764348643496435064351643526435364354643556435664357643586435964360643616436264363643646436564366643676436864369643706437164372643736437464375643766437764378643796438064381643826438364384643856438664387643886438964390643916439264393643946439564396643976439864399644006440164402644036440464405644066440764408644096441064411644126441364414644156441664417644186441964420644216442264423644246442564426644276442864429644306443164432644336443464435644366443764438644396444064441644426444364444644456444664447644486444964450644516445264453644546445564456644576445864459644606446164462644636446464465644666446764468644696447064471644726447364474644756447664477644786447964480644816448264483644846448564486644876448864489644906449164492644936449464495644966449764498644996450064501645026450364504645056450664507645086450964510645116451264513645146451564516645176451864519645206452164522645236452464525645266452764528645296453064531645326453364534645356453664537645386453964540645416454264543645446454564546645476454864549645506455164552645536455464555645566455764558645596456064561645626456364564645656456664567645686456964570645716457264573645746457564576645776457864579645806458164582645836458464585645866458764588645896459064591645926459364594645956459664597645986459964600646016460264603646046460564606646076460864609646106461164612646136461464615646166461764618646196462064621646226462364624646256462664627646286462964630646316463264633646346463564636646376463864639646406464164642646436464464645646466464764648646496465064651646526465364654646556465664657646586465964660646616466264663646646466564666646676466864669646706467164672646736467464675646766467764678646796468064681646826468364684646856468664687646886468964690646916469264693646946469564696646976469864699647006470164702647036470464705647066470764708647096471064711647126471364714647156471664717647186471964720647216472264723647246472564726647276472864729647306473164732647336473464735647366473764738647396474064741647426474364744647456474664747647486474964750647516475264753647546475564756647576475864759647606476164762647636476464765647666476764768647696477064771647726477364774647756477664777647786477964780647816478264783647846478564786647876478864789647906479164792647936479464795647966479764798647996480064801648026480364804648056480664807648086480964810648116481264813648146481564816648176481864819648206482164822648236482464825648266482764828648296483064831648326483364834648356483664837648386483964840648416484264843648446484564846648476484864849648506485164852648536485464855648566485764858648596486064861648626486364864648656486664867648686486964870648716487264873648746487564876648776487864879648806488164882648836488464885648866488764888648896489064891648926489364894648956489664897648986489964900649016490264903649046490564906649076490864909649106491164912649136491464915649166491764918649196492064921649226492364924649256492664927649286492964930649316493264933649346493564936649376493864939649406494164942649436494464945649466494764948649496495064951649526495364954649556495664957649586495964960649616496264963649646496564966649676496864969649706497164972649736497464975649766497764978649796498064981649826498364984649856498664987649886498964990649916499264993649946499564996649976499864999650006500165002650036500465005650066500765008650096501065011650126501365014650156501665017650186501965020650216502265023650246502565026650276502865029650306503165032650336503465035650366503765038650396504065041650426504365044650456504665047650486504965050650516505265053650546505565056650576505865059650606506165062650636506465065650666506765068650696507065071650726507365074650756507665077650786507965080650816508265083650846508565086650876508865089650906509165092650936509465095650966509765098650996510065101651026510365104651056510665107651086510965110651116511265113651146511565116651176511865119651206512165122651236512465125651266512765128651296513065131651326513365134651356513665137651386513965140651416514265143651446514565146651476514865149651506515165152651536515465155651566515765158651596516065161651626516365164651656516665167651686516965170651716517265173651746517565176651776517865179651806518165182651836518465185651866518765188651896519065191651926519365194651956519665197651986519965200652016520265203652046520565206652076520865209652106521165212652136521465215652166521765218652196522065221652226522365224652256522665227652286522965230652316523265233652346523565236652376523865239652406524165242652436524465245652466524765248652496525065251652526525365254652556525665257652586525965260652616526265263652646526565266652676526865269652706527165272652736527465275652766527765278652796528065281652826528365284652856528665287652886528965290652916529265293652946529565296652976529865299653006530165302653036530465305653066530765308653096531065311653126531365314653156531665317653186531965320653216532265323653246532565326653276532865329653306533165332653336533465335653366533765338653396534065341653426534365344653456534665347653486534965350653516535265353653546535565356653576535865359653606536165362653636536465365653666536765368653696537065371653726537365374653756537665377653786537965380653816538265383653846538565386653876538865389653906539165392653936539465395653966539765398653996540065401654026540365404654056540665407654086540965410654116541265413654146541565416654176541865419654206542165422654236542465425654266542765428654296543065431654326543365434654356543665437654386543965440654416544265443654446544565446654476544865449654506545165452654536545465455654566545765458654596546065461654626546365464654656546665467654686546965470654716547265473654746547565476654776547865479654806548165482654836548465485654866548765488654896549065491654926549365494654956549665497654986549965500655016550265503655046550565506655076550865509655106551165512655136551465515655166551765518655196552065521655226552365524655256552665527655286552965530655316553265533655346553565536655376553865539655406554165542655436554465545655466554765548655496555065551655526555365554655556555665557655586555965560655616556265563655646556565566655676556865569655706557165572655736557465575655766557765578655796558065581655826558365584655856558665587655886558965590655916559265593655946559565596655976559865599656006560165602656036560465605656066560765608656096561065611656126561365614656156561665617656186561965620656216562265623656246562565626656276562865629656306563165632656336563465635656366563765638656396564065641656426564365644656456564665647656486564965650656516565265653656546565565656656576565865659656606566165662656636566465665656666566765668656696567065671656726567365674656756567665677656786567965680656816568265683656846568565686656876568865689656906569165692656936569465695656966569765698656996570065701657026570365704657056570665707657086570965710657116571265713657146571565716657176571865719657206572165722657236572465725657266572765728657296573065731657326573365734657356573665737657386573965740657416574265743657446574565746657476574865749657506575165752657536575465755657566575765758657596576065761657626576365764657656576665767657686576965770657716577265773657746577565776657776577865779657806578165782657836578465785657866578765788657896579065791657926579365794657956579665797657986579965800658016580265803658046580565806658076580865809658106581165812658136581465815658166581765818658196582065821658226582365824658256582665827658286582965830658316583265833658346583565836658376583865839658406584165842658436584465845658466584765848658496585065851658526585365854658556585665857658586585965860658616586265863658646586565866658676586865869658706587165872658736587465875658766587765878658796588065881658826588365884658856588665887658886588965890658916589265893658946589565896658976589865899659006590165902659036590465905659066590765908659096591065911659126591365914659156591665917659186591965920659216592265923659246592565926659276592865929659306593165932659336593465935659366593765938659396594065941659426594365944659456594665947659486594965950659516595265953659546595565956659576595865959659606596165962659636596465965659666596765968659696597065971659726597365974659756597665977659786597965980659816598265983659846598565986659876598865989659906599165992659936599465995659966599765998659996600066001660026600366004660056600666007660086600966010660116601266013660146601566016660176601866019660206602166022660236602466025660266602766028660296603066031660326603366034660356603666037660386603966040660416604266043660446604566046660476604866049660506605166052660536605466055660566605766058660596606066061660626606366064660656606666067660686606966070660716607266073660746607566076660776607866079660806608166082660836608466085660866608766088660896609066091660926609366094660956609666097660986609966100661016610266103661046610566106661076610866109661106611166112661136611466115661166611766118661196612066121661226612366124661256612666127661286612966130661316613266133661346613566136661376613866139661406614166142661436614466145661466614766148661496615066151661526615366154661556615666157661586615966160661616616266163661646616566166661676616866169661706617166172661736617466175661766617766178661796618066181661826618366184661856618666187661886618966190661916619266193661946619566196661976619866199662006620166202662036620466205662066620766208662096621066211662126621366214662156621666217662186621966220662216622266223662246622566226662276622866229662306623166232662336623466235662366623766238662396624066241662426624366244662456624666247662486624966250662516625266253662546625566256662576625866259662606626166262662636626466265662666626766268662696627066271662726627366274662756627666277662786627966280662816628266283662846628566286662876628866289662906629166292662936629466295662966629766298662996630066301663026630366304663056630666307663086630966310663116631266313663146631566316663176631866319663206632166322663236632466325663266632766328663296633066331663326633366334663356633666337663386633966340663416634266343663446634566346663476634866349663506635166352663536635466355663566635766358663596636066361663626636366364663656636666367663686636966370663716637266373663746637566376663776637866379663806638166382663836638466385663866638766388663896639066391663926639366394663956639666397663986639966400664016640266403664046640566406664076640866409664106641166412664136641466415664166641766418664196642066421664226642366424664256642666427664286642966430664316643266433664346643566436664376643866439664406644166442664436644466445664466644766448664496645066451664526645366454664556645666457664586645966460664616646266463664646646566466664676646866469664706647166472664736647466475664766647766478664796648066481664826648366484664856648666487664886648966490664916649266493664946649566496664976649866499665006650166502665036650466505665066650766508665096651066511665126651366514665156651666517665186651966520665216652266523665246652566526665276652866529665306653166532665336653466535665366653766538665396654066541665426654366544665456654666547665486654966550665516655266553665546655566556665576655866559665606656166562665636656466565665666656766568665696657066571665726657366574665756657666577665786657966580665816658266583665846658566586665876658866589665906659166592665936659466595665966659766598665996660066601666026660366604666056660666607666086660966610666116661266613666146661566616666176661866619666206662166622666236662466625666266662766628666296663066631666326663366634666356663666637666386663966640666416664266643666446664566646666476664866649666506665166652666536665466655666566665766658666596666066661666626666366664666656666666667666686666966670666716667266673666746667566676666776667866679666806668166682666836668466685666866668766688666896669066691666926669366694666956669666697666986669966700667016670266703667046670566706667076670866709667106671166712667136671466715667166671766718667196672066721667226672366724667256672666727667286672966730667316673266733667346673566736667376673866739667406674166742667436674466745667466674766748667496675066751667526675366754667556675666757667586675966760667616676266763667646676566766667676676866769667706677166772667736677466775667766677766778667796678066781667826678366784667856678666787667886678966790667916679266793667946679566796667976679866799668006680166802668036680466805668066680766808668096681066811668126681366814668156681666817668186681966820668216682266823668246682566826668276682866829668306683166832668336683466835668366683766838668396684066841668426684366844668456684666847668486684966850668516685266853668546685566856668576685866859668606686166862668636686466865668666686766868668696687066871668726687366874668756687666877668786687966880668816688266883668846688566886668876688866889668906689166892668936689466895668966689766898668996690066901669026690366904669056690666907669086690966910669116691266913669146691566916669176691866919669206692166922669236692466925669266692766928669296693066931669326693366934669356693666937669386693966940669416694266943669446694566946669476694866949669506695166952669536695466955669566695766958669596696066961669626696366964669656696666967669686696966970669716697266973669746697566976669776697866979669806698166982669836698466985669866698766988669896699066991669926699366994669956699666997669986699967000670016700267003670046700567006670076700867009670106701167012670136701467015670166701767018670196702067021670226702367024670256702667027670286702967030670316703267033670346703567036670376703867039670406704167042670436704467045670466704767048670496705067051670526705367054670556705667057670586705967060670616706267063670646706567066670676706867069670706707167072670736707467075670766707767078670796708067081670826708367084670856708667087670886708967090670916709267093670946709567096670976709867099671006710167102671036710467105671066710767108671096711067111671126711367114671156711667117671186711967120671216712267123671246712567126671276712867129671306713167132671336713467135671366713767138671396714067141671426714367144671456714667147671486714967150671516715267153671546715567156671576715867159671606716167162671636716467165671666716767168671696717067171671726717367174671756717667177671786717967180671816718267183671846718567186671876718867189671906719167192671936719467195671966719767198671996720067201672026720367204672056720667207672086720967210672116721267213672146721567216672176721867219672206722167222672236722467225672266722767228672296723067231672326723367234672356723667237672386723967240672416724267243672446724567246672476724867249672506725167252672536725467255672566725767258672596726067261672626726367264672656726667267672686726967270672716727267273672746727567276672776727867279672806728167282672836728467285672866728767288672896729067291672926729367294672956729667297672986729967300673016730267303673046730567306673076730867309673106731167312673136731467315673166731767318673196732067321673226732367324673256732667327673286732967330673316733267333673346733567336673376733867339673406734167342673436734467345673466734767348673496735067351673526735367354673556735667357673586735967360673616736267363673646736567366673676736867369673706737167372673736737467375673766737767378673796738067381673826738367384673856738667387673886738967390673916739267393673946739567396673976739867399674006740167402674036740467405674066740767408674096741067411674126741367414674156741667417674186741967420674216742267423674246742567426674276742867429674306743167432674336743467435674366743767438674396744067441674426744367444674456744667447674486744967450674516745267453674546745567456674576745867459674606746167462674636746467465674666746767468674696747067471674726747367474674756747667477674786747967480674816748267483674846748567486674876748867489674906749167492674936749467495674966749767498674996750067501675026750367504675056750667507675086750967510675116751267513675146751567516675176751867519675206752167522675236752467525675266752767528675296753067531675326753367534675356753667537675386753967540675416754267543675446754567546675476754867549675506755167552675536755467555675566755767558675596756067561675626756367564675656756667567675686756967570675716757267573675746757567576675776757867579675806758167582675836758467585675866758767588675896759067591675926759367594675956759667597675986759967600676016760267603676046760567606676076760867609676106761167612676136761467615676166761767618676196762067621676226762367624676256762667627676286762967630676316763267633676346763567636676376763867639676406764167642676436764467645676466764767648676496765067651676526765367654676556765667657676586765967660676616766267663676646766567666676676766867669676706767167672676736767467675676766767767678676796768067681676826768367684676856768667687676886768967690676916769267693676946769567696676976769867699677006770167702677036770467705677066770767708677096771067711677126771367714677156771667717677186771967720677216772267723677246772567726677276772867729677306773167732677336773467735677366773767738677396774067741677426774367744677456774667747677486774967750677516775267753677546775567756677576775867759677606776167762677636776467765677666776767768677696777067771677726777367774677756777667777677786777967780677816778267783677846778567786677876778867789677906779167792677936779467795677966779767798677996780067801678026780367804678056780667807678086780967810678116781267813678146781567816678176781867819678206782167822678236782467825678266782767828678296783067831678326783367834678356783667837678386783967840678416784267843678446784567846678476784867849678506785167852678536785467855678566785767858678596786067861678626786367864678656786667867678686786967870678716787267873678746787567876678776787867879678806788167882678836788467885678866788767888678896789067891678926789367894678956789667897678986789967900679016790267903679046790567906679076790867909679106791167912679136791467915679166791767918679196792067921679226792367924679256792667927679286792967930679316793267933679346793567936679376793867939679406794167942679436794467945679466794767948679496795067951679526795367954679556795667957679586795967960679616796267963679646796567966679676796867969679706797167972679736797467975679766797767978679796798067981679826798367984679856798667987679886798967990679916799267993679946799567996679976799867999680006800168002680036800468005680066800768008680096801068011680126801368014680156801668017680186801968020680216802268023680246802568026680276802868029680306803168032680336803468035680366803768038680396804068041680426804368044680456804668047680486804968050680516805268053680546805568056680576805868059680606806168062680636806468065680666806768068680696807068071680726807368074680756807668077680786807968080680816808268083680846808568086680876808868089680906809168092680936809468095680966809768098680996810068101681026810368104681056810668107681086810968110681116811268113681146811568116681176811868119681206812168122681236812468125681266812768128681296813068131681326813368134681356813668137681386813968140681416814268143681446814568146681476814868149681506815168152681536815468155681566815768158681596816068161681626816368164681656816668167681686816968170681716817268173681746817568176681776817868179681806818168182681836818468185681866818768188681896819068191681926819368194681956819668197681986819968200682016820268203682046820568206682076820868209682106821168212682136821468215682166821768218682196822068221682226822368224682256822668227682286822968230682316823268233682346823568236682376823868239682406824168242682436824468245682466824768248682496825068251682526825368254682556825668257682586825968260682616826268263682646826568266682676826868269682706827168272682736827468275682766827768278682796828068281682826828368284682856828668287682886828968290682916829268293682946829568296682976829868299683006830168302683036830468305683066830768308683096831068311683126831368314683156831668317683186831968320683216832268323683246832568326683276832868329683306833168332683336833468335683366833768338683396834068341683426834368344683456834668347683486834968350683516835268353683546835568356683576835868359683606836168362683636836468365683666836768368683696837068371683726837368374683756837668377683786837968380683816838268383683846838568386683876838868389683906839168392683936839468395683966839768398683996840068401684026840368404684056840668407684086840968410684116841268413684146841568416684176841868419684206842168422684236842468425684266842768428684296843068431684326843368434684356843668437684386843968440684416844268443684446844568446684476844868449684506845168452684536845468455684566845768458684596846068461684626846368464684656846668467684686846968470684716847268473684746847568476684776847868479684806848168482684836848468485684866848768488684896849068491684926849368494684956849668497684986849968500685016850268503685046850568506685076850868509685106851168512685136851468515685166851768518685196852068521685226852368524685256852668527685286852968530685316853268533685346853568536685376853868539685406854168542685436854468545685466854768548685496855068551685526855368554685556855668557685586855968560685616856268563685646856568566685676856868569685706857168572685736857468575685766857768578685796858068581685826858368584685856858668587685886858968590685916859268593685946859568596685976859868599686006860168602686036860468605686066860768608686096861068611686126861368614686156861668617686186861968620686216862268623686246862568626686276862868629686306863168632686336863468635686366863768638686396864068641686426864368644686456864668647686486864968650686516865268653686546865568656686576865868659686606866168662686636866468665686666866768668686696867068671686726867368674686756867668677686786867968680686816868268683686846868568686686876868868689686906869168692686936869468695686966869768698686996870068701687026870368704687056870668707687086870968710687116871268713687146871568716687176871868719687206872168722687236872468725687266872768728687296873068731687326873368734687356873668737687386873968740687416874268743687446874568746687476874868749687506875168752687536875468755687566875768758687596876068761687626876368764687656876668767687686876968770687716877268773687746877568776687776877868779687806878168782687836878468785687866878768788687896879068791687926879368794687956879668797687986879968800688016880268803688046880568806688076880868809688106881168812688136881468815688166881768818688196882068821688226882368824688256882668827688286882968830688316883268833688346883568836688376883868839688406884168842688436884468845688466884768848688496885068851688526885368854688556885668857688586885968860688616886268863688646886568866688676886868869688706887168872688736887468875688766887768878688796888068881688826888368884688856888668887688886888968890688916889268893688946889568896688976889868899689006890168902689036890468905689066890768908689096891068911689126891368914689156891668917689186891968920689216892268923689246892568926689276892868929689306893168932689336893468935689366893768938689396894068941689426894368944689456894668947689486894968950689516895268953689546895568956689576895868959689606896168962689636896468965689666896768968689696897068971689726897368974689756897668977689786897968980689816898268983689846898568986689876898868989689906899168992689936899468995689966899768998689996900069001690026900369004690056900669007690086900969010690116901269013690146901569016690176901869019690206902169022690236902469025690266902769028690296903069031690326903369034690356903669037690386903969040690416904269043690446904569046690476904869049690506905169052690536905469055690566905769058690596906069061690626906369064690656906669067690686906969070690716907269073690746907569076690776907869079690806908169082690836908469085690866908769088690896909069091690926909369094690956909669097690986909969100691016910269103691046910569106691076910869109691106911169112691136911469115691166911769118691196912069121691226912369124691256912669127691286912969130691316913269133691346913569136691376913869139691406914169142691436914469145691466914769148691496915069151691526915369154691556915669157691586915969160691616916269163691646916569166691676916869169691706917169172691736917469175691766917769178691796918069181691826918369184691856918669187691886918969190691916919269193691946919569196691976919869199692006920169202692036920469205692066920769208692096921069211692126921369214692156921669217692186921969220692216922269223692246922569226692276922869229692306923169232692336923469235692366923769238692396924069241692426924369244692456924669247692486924969250692516925269253692546925569256692576925869259692606926169262692636926469265692666926769268692696927069271692726927369274692756927669277692786927969280692816928269283692846928569286692876928869289692906929169292692936929469295692966929769298692996930069301693026930369304693056930669307693086930969310693116931269313693146931569316693176931869319693206932169322693236932469325693266932769328693296933069331693326933369334693356933669337693386933969340693416934269343693446934569346693476934869349693506935169352693536935469355693566935769358693596936069361693626936369364693656936669367693686936969370693716937269373693746937569376693776937869379693806938169382693836938469385693866938769388693896939069391693926939369394693956939669397693986939969400694016940269403694046940569406694076940869409694106941169412694136941469415694166941769418694196942069421694226942369424694256942669427694286942969430694316943269433694346943569436694376943869439694406944169442694436944469445694466944769448694496945069451694526945369454694556945669457694586945969460694616946269463694646946569466694676946869469694706947169472694736947469475694766947769478694796948069481694826948369484694856948669487694886948969490694916949269493694946949569496694976949869499695006950169502695036950469505695066950769508695096951069511695126951369514695156951669517695186951969520695216952269523695246952569526695276952869529695306953169532695336953469535695366953769538695396954069541695426954369544695456954669547695486954969550695516955269553695546955569556695576955869559695606956169562695636956469565695666956769568695696957069571695726957369574695756957669577695786957969580695816958269583695846958569586695876958869589695906959169592695936959469595695966959769598695996960069601696026960369604696056960669607696086960969610696116961269613696146961569616696176961869619696206962169622696236962469625696266962769628696296963069631696326963369634696356963669637696386963969640696416964269643696446964569646696476964869649696506965169652696536965469655696566965769658696596966069661696626966369664696656966669667696686966969670696716967269673696746967569676696776967869679696806968169682696836968469685696866968769688696896969069691696926969369694696956969669697696986969969700697016970269703697046970569706697076970869709697106971169712697136971469715697166971769718697196972069721697226972369724697256972669727697286972969730697316973269733697346973569736697376973869739697406974169742697436974469745697466974769748697496975069751697526975369754697556975669757697586975969760697616976269763697646976569766697676976869769697706977169772697736977469775697766977769778697796978069781697826978369784697856978669787697886978969790697916979269793697946979569796697976979869799698006980169802698036980469805698066980769808698096981069811698126981369814698156981669817698186981969820698216982269823698246982569826698276982869829698306983169832698336983469835698366983769838698396984069841698426984369844698456984669847698486984969850698516985269853698546985569856698576985869859698606986169862698636986469865698666986769868698696987069871698726987369874698756987669877698786987969880698816988269883698846988569886698876988869889698906989169892698936989469895698966989769898698996990069901699026990369904699056990669907699086990969910699116991269913699146991569916699176991869919699206992169922699236992469925699266992769928699296993069931699326993369934699356993669937699386993969940699416994269943699446994569946699476994869949699506995169952699536995469955699566995769958699596996069961699626996369964699656996669967699686996969970699716997269973699746997569976699776997869979699806998169982699836998469985699866998769988699896999069991699926999369994699956999669997699986999970000700017000270003700047000570006700077000870009700107001170012700137001470015700167001770018700197002070021700227002370024700257002670027700287002970030700317003270033700347003570036700377003870039700407004170042700437004470045700467004770048700497005070051700527005370054700557005670057700587005970060700617006270063700647006570066700677006870069700707007170072700737007470075700767007770078700797008070081700827008370084700857008670087700887008970090700917009270093700947009570096700977009870099701007010170102701037010470105701067010770108701097011070111701127011370114701157011670117701187011970120701217012270123701247012570126701277012870129701307013170132701337013470135701367013770138701397014070141701427014370144701457014670147701487014970150701517015270153701547015570156701577015870159701607016170162701637016470165701667016770168701697017070171701727017370174701757017670177701787017970180701817018270183701847018570186701877018870189701907019170192701937019470195701967019770198701997020070201702027020370204702057020670207702087020970210702117021270213702147021570216702177021870219702207022170222702237022470225702267022770228702297023070231702327023370234702357023670237702387023970240702417024270243702447024570246702477024870249702507025170252702537025470255702567025770258702597026070261702627026370264702657026670267702687026970270702717027270273702747027570276702777027870279702807028170282702837028470285702867028770288702897029070291702927029370294702957029670297702987029970300703017030270303703047030570306703077030870309703107031170312703137031470315703167031770318703197032070321703227032370324703257032670327703287032970330703317033270333703347033570336703377033870339703407034170342703437034470345703467034770348703497035070351703527035370354703557035670357703587035970360703617036270363703647036570366703677036870369703707037170372703737037470375703767037770378703797038070381703827038370384703857038670387703887038970390703917039270393703947039570396703977039870399704007040170402704037040470405704067040770408704097041070411704127041370414704157041670417704187041970420704217042270423704247042570426704277042870429704307043170432704337043470435704367043770438704397044070441704427044370444704457044670447704487044970450704517045270453704547045570456704577045870459704607046170462704637046470465704667046770468704697047070471704727047370474704757047670477704787047970480704817048270483704847048570486704877048870489704907049170492704937049470495704967049770498704997050070501705027050370504705057050670507705087050970510705117051270513705147051570516705177051870519705207052170522705237052470525705267052770528705297053070531705327053370534705357053670537705387053970540705417054270543705447054570546705477054870549705507055170552705537055470555705567055770558705597056070561705627056370564705657056670567705687056970570705717057270573705747057570576705777057870579705807058170582705837058470585705867058770588705897059070591705927059370594705957059670597705987059970600706017060270603706047060570606706077060870609706107061170612706137061470615706167061770618706197062070621706227062370624706257062670627706287062970630706317063270633706347063570636706377063870639706407064170642706437064470645706467064770648706497065070651706527065370654706557065670657706587065970660706617066270663706647066570666706677066870669706707067170672706737067470675706767067770678706797068070681706827068370684706857068670687706887068970690706917069270693706947069570696706977069870699707007070170702707037070470705707067070770708707097071070711707127071370714707157071670717707187071970720707217072270723707247072570726707277072870729707307073170732707337073470735707367073770738707397074070741707427074370744707457074670747707487074970750707517075270753707547075570756707577075870759707607076170762707637076470765707667076770768707697077070771707727077370774707757077670777707787077970780707817078270783707847078570786707877078870789707907079170792707937079470795707967079770798707997080070801708027080370804708057080670807708087080970810708117081270813708147081570816708177081870819708207082170822708237082470825708267082770828708297083070831708327083370834708357083670837708387083970840708417084270843708447084570846708477084870849708507085170852708537085470855708567085770858708597086070861708627086370864708657086670867708687086970870708717087270873708747087570876708777087870879708807088170882708837088470885708867088770888708897089070891708927089370894708957089670897708987089970900709017090270903709047090570906709077090870909709107091170912709137091470915709167091770918709197092070921709227092370924709257092670927709287092970930709317093270933709347093570936709377093870939709407094170942709437094470945709467094770948709497095070951709527095370954709557095670957709587095970960709617096270963709647096570966709677096870969709707097170972709737097470975709767097770978709797098070981709827098370984709857098670987709887098970990709917099270993709947099570996709977099870999710007100171002710037100471005710067100771008710097101071011710127101371014710157101671017710187101971020710217102271023710247102571026710277102871029710307103171032710337103471035710367103771038710397104071041710427104371044710457104671047710487104971050710517105271053710547105571056710577105871059710607106171062710637106471065710667106771068710697107071071710727107371074710757107671077710787107971080710817108271083710847108571086710877108871089710907109171092710937109471095710967109771098710997110071101711027110371104711057110671107711087110971110711117111271113711147111571116711177111871119711207112171122711237112471125711267112771128711297113071131711327113371134711357113671137711387113971140711417114271143711447114571146711477114871149711507115171152711537115471155711567115771158711597116071161711627116371164711657116671167711687116971170711717117271173711747117571176711777117871179711807118171182711837118471185711867118771188711897119071191711927119371194711957119671197711987119971200712017120271203712047120571206712077120871209712107121171212712137121471215712167121771218712197122071221712227122371224712257122671227712287122971230712317123271233712347123571236712377123871239712407124171242712437124471245712467124771248712497125071251712527125371254712557125671257712587125971260712617126271263712647126571266712677126871269712707127171272712737127471275712767127771278712797128071281712827128371284712857128671287712887128971290712917129271293712947129571296712977129871299713007130171302713037130471305713067130771308713097131071311713127131371314713157131671317713187131971320713217132271323713247132571326713277132871329713307133171332713337133471335713367133771338713397134071341713427134371344713457134671347713487134971350713517135271353713547135571356713577135871359713607136171362713637136471365713667136771368713697137071371713727137371374713757137671377713787137971380713817138271383713847138571386713877138871389713907139171392713937139471395713967139771398713997140071401714027140371404714057140671407714087140971410714117141271413714147141571416714177141871419714207142171422714237142471425714267142771428714297143071431714327143371434714357143671437714387143971440714417144271443714447144571446714477144871449714507145171452714537145471455714567145771458714597146071461714627146371464714657146671467714687146971470714717147271473714747147571476714777147871479714807148171482714837148471485714867148771488714897149071491714927149371494714957149671497714987149971500715017150271503715047150571506715077150871509715107151171512715137151471515715167151771518715197152071521715227152371524715257152671527715287152971530715317153271533715347153571536715377153871539715407154171542715437154471545715467154771548715497155071551715527155371554715557155671557715587155971560715617156271563715647156571566715677156871569715707157171572715737157471575715767157771578715797158071581715827158371584715857158671587715887158971590715917159271593715947159571596715977159871599716007160171602716037160471605716067160771608716097161071611716127161371614716157161671617716187161971620716217162271623716247162571626716277162871629716307163171632716337163471635716367163771638716397164071641716427164371644716457164671647716487164971650716517165271653716547165571656716577165871659716607166171662716637166471665716667166771668716697167071671716727167371674716757167671677716787167971680716817168271683716847168571686716877168871689716907169171692716937169471695716967169771698716997170071701717027170371704717057170671707717087170971710717117171271713717147171571716717177171871719717207172171722717237172471725717267172771728717297173071731717327173371734717357173671737717387173971740717417174271743717447174571746717477174871749717507175171752717537175471755717567175771758717597176071761717627176371764717657176671767717687176971770717717177271773717747177571776717777177871779717807178171782717837178471785717867178771788717897179071791717927179371794717957179671797717987179971800718017180271803718047180571806718077180871809718107181171812718137181471815718167181771818718197182071821718227182371824718257182671827718287182971830718317183271833718347183571836718377183871839718407184171842718437184471845718467184771848718497185071851718527185371854718557185671857718587185971860718617186271863718647186571866718677186871869718707187171872718737187471875718767187771878718797188071881718827188371884718857188671887718887188971890718917189271893718947189571896718977189871899719007190171902719037190471905719067190771908719097191071911719127191371914719157191671917719187191971920719217192271923719247192571926719277192871929719307193171932719337193471935719367193771938719397194071941719427194371944719457194671947719487194971950719517195271953719547195571956719577195871959719607196171962719637196471965719667196771968719697197071971719727197371974719757197671977719787197971980719817198271983719847198571986719877198871989719907199171992719937199471995719967199771998719997200072001720027200372004720057200672007720087200972010720117201272013720147201572016720177201872019720207202172022720237202472025720267202772028720297203072031720327203372034720357203672037720387203972040720417204272043720447204572046720477204872049720507205172052720537205472055720567205772058720597206072061720627206372064720657206672067720687206972070720717207272073720747207572076720777207872079720807208172082720837208472085720867208772088720897209072091720927209372094720957209672097720987209972100721017210272103721047210572106721077210872109721107211172112721137211472115721167211772118721197212072121721227212372124721257212672127721287212972130721317213272133721347213572136721377213872139721407214172142721437214472145721467214772148721497215072151721527215372154721557215672157721587215972160721617216272163721647216572166721677216872169721707217172172721737217472175721767217772178721797218072181721827218372184
  1. /*!
  2. * DevExtreme
  3. * Version: 14.1.9-pre
  4. * Build date: Nov 7, 2014
  5. *
  6. * Copyright (c) 2012 - 2014 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. (function checkjQueryVersion(version) {
  14. version = version.split(".");
  15. if (version[0] < 1 || version[0] == 1 && version[1] < 10)
  16. throw Error("Your version of jQuery is too old. Please upgrade jQuery to 1.10.0 or later.");
  17. })($.fn.jquery);
  18. var Class = function() {
  19. var wrapOverridden = function(baseProto, methodName, method) {
  20. return function() {
  21. var prevCallBase = this.callBase;
  22. this.callBase = baseProto[methodName];
  23. try {
  24. return method.apply(this, arguments)
  25. }
  26. finally {
  27. this.callBase = prevCallBase
  28. }
  29. }
  30. };
  31. var clonePrototype = function(obj) {
  32. var func = function(){};
  33. func.prototype = obj.prototype;
  34. return new func
  35. };
  36. var classImpl = function(){};
  37. var redefine = function(members) {
  38. var that = this;
  39. if (!members)
  40. return that;
  41. var memberNames = $.map(members, function(_, k) {
  42. return k
  43. });
  44. $.each(["toString", "toLocaleString", "valueOf"], function() {
  45. if (members[this])
  46. memberNames.push(this)
  47. });
  48. $.each(memberNames, function() {
  49. var overridden = $.isFunction(that.prototype[this]) && $.isFunction(members[this]);
  50. that.prototype[this] = overridden ? wrapOverridden(that.parent.prototype, this, members[this]) : members[this]
  51. });
  52. return that
  53. };
  54. var include = function() {
  55. var classObj = this;
  56. $.each(arguments, function() {
  57. if (this.ctor)
  58. classObj._includedCtors.push(this.ctor);
  59. for (var name in this) {
  60. if (name === "ctor")
  61. continue;
  62. if (name in classObj.prototype)
  63. throw Error("Member name collision: " + name);
  64. classObj.prototype[name] = this[name]
  65. }
  66. });
  67. return classObj
  68. };
  69. var subclassOf = function(parentClass) {
  70. if (this.parent === parentClass)
  71. return true;
  72. if (!this.parent || !this.parent.subclassOf)
  73. return false;
  74. return this.parent.subclassOf(parentClass)
  75. };
  76. classImpl.inherit = function(members) {
  77. var inheritor = function() {
  78. if (!this || this === global || typeof this.constructor !== "function")
  79. throw Error("A class must be instantiated using the 'new' keyword");
  80. var instance = this,
  81. ctor = instance.ctor;
  82. if (ctor)
  83. ctor.apply(instance, arguments);
  84. $.each(instance.constructor._includedCtors, function() {
  85. this.call(instance)
  86. })
  87. };
  88. inheritor.prototype = clonePrototype(this);
  89. inheritor.inherit = this.inherit;
  90. inheritor.redefine = redefine;
  91. inheritor.include = include;
  92. inheritor.subclassOf = subclassOf;
  93. inheritor.parent = this;
  94. inheritor._includedCtors = this._includedCtors ? this._includedCtors.slice(0) : [];
  95. inheritor.prototype.constructor = inheritor;
  96. inheritor.redefine(members);
  97. return inheritor
  98. };
  99. return classImpl
  100. }();
  101. function createQueue(discardPendingTasks) {
  102. var _tasks = [],
  103. _busy = false;
  104. function exec() {
  105. while (_tasks.length) {
  106. _busy = true;
  107. var task = _tasks.shift(),
  108. result = task();
  109. if (result === undefined)
  110. continue;
  111. if (result.then) {
  112. $.when(result).always(exec);
  113. return
  114. }
  115. throw Error("Queued task returned unexpected result");
  116. }
  117. _busy = false
  118. }
  119. function add(task, removeTaskCallback) {
  120. if (!discardPendingTasks)
  121. _tasks.push(task);
  122. else {
  123. if (_tasks[0] && removeTaskCallback)
  124. removeTaskCallback(_tasks[0]);
  125. _tasks = [task]
  126. }
  127. if (!_busy)
  128. exec()
  129. }
  130. function busy() {
  131. return _busy
  132. }
  133. return {
  134. add: add,
  135. busy: busy
  136. }
  137. }
  138. var parseUrl = function() {
  139. var a = document.createElement("a"),
  140. props = ["protocol", "hostname", "port", "pathname", "search", "hash"];
  141. var normalizePath = function(value) {
  142. if (value.charAt(0) !== "/")
  143. value = "/" + value;
  144. return value
  145. };
  146. return function(url) {
  147. a.href = url;
  148. var result = {};
  149. $.each(props, function() {
  150. result[this] = a[this]
  151. });
  152. result.pathname = normalizePath(result.pathname);
  153. return result
  154. }
  155. }();
  156. global.DevExpress = global.DevExpress || {};
  157. var enqueueAsync = function(task) {
  158. var deferred = $.Deferred();
  159. setTimeout(function() {
  160. deferred.resolve(task())
  161. }, 60);
  162. return deferred
  163. };
  164. var hideTopOverlayCallback = function() {
  165. var callbacks = [];
  166. return {
  167. add: function(callback) {
  168. var indexOfCallback = $.inArray(callback, callbacks);
  169. if (indexOfCallback === -1)
  170. callbacks.push(callback)
  171. },
  172. remove: function(callback) {
  173. var indexOfCallback = $.inArray(callback, callbacks);
  174. if (indexOfCallback !== -1)
  175. callbacks.splice(indexOfCallback, 1)
  176. },
  177. fire: function() {
  178. var callback = callbacks.pop(),
  179. result = !!callback;
  180. if (result)
  181. callback();
  182. return result
  183. },
  184. hasCallback: function() {
  185. return callbacks.length > 0
  186. },
  187. reset: function() {
  188. callbacks = []
  189. }
  190. }
  191. }();
  192. var overlayTargetContainer = function() {
  193. var defaultTargetContainer = "body";
  194. return function(targetContainer) {
  195. if (arguments.length)
  196. defaultTargetContainer = targetContainer;
  197. return defaultTargetContainer
  198. }
  199. }();
  200. $.extend(global.DevExpress, {
  201. VERSION: "14.1.8",
  202. abstract: function() {
  203. throw Error("Not implemented");
  204. },
  205. Class: Class,
  206. createQueue: createQueue,
  207. enqueue: createQueue().add,
  208. enqueueAsync: enqueueAsync,
  209. parseUrl: parseUrl,
  210. hideTopOverlayCallback: hideTopOverlayCallback,
  211. hardwareBackButton: $.Callbacks(),
  212. overlayTargetContainer: overlayTargetContainer,
  213. rtlEnabled: false
  214. })
  215. })(jQuery, this);
  216. /*! Module core, file inflector.js */
  217. (function($, DX, undefined) {
  218. var _normalize = function(text) {
  219. if (text === undefined || text === null)
  220. return "";
  221. return String(text)
  222. };
  223. var _ucfirst = function(text) {
  224. return _normalize(text).charAt(0).toUpperCase() + text.substr(1)
  225. };
  226. var _chop = function(text) {
  227. return _normalize(text).replace(/([a-z\d])([A-Z])/g, "$1 $2").split(/[\s_-]+/)
  228. };
  229. var dasherize = function(text) {
  230. return $.map(_chop(text), function(p) {
  231. return p.toLowerCase()
  232. }).join("-")
  233. };
  234. var underscore = function(text) {
  235. return dasherize(text).replace(/-/g, "_")
  236. };
  237. var camelize = function(text, upperFirst) {
  238. return $.map(_chop(text), function(p, i) {
  239. p = p.toLowerCase();
  240. if (upperFirst || i > 0)
  241. p = _ucfirst(p);
  242. return p
  243. }).join("")
  244. };
  245. var humanize = function(text) {
  246. return _ucfirst(dasherize(text).replace(/-/g, " "))
  247. };
  248. var titleize = function(text) {
  249. return $.map(_chop(text), function(p) {
  250. return _ucfirst(p.toLowerCase())
  251. }).join(" ")
  252. };
  253. DX.inflector = {
  254. dasherize: dasherize,
  255. camelize: camelize,
  256. humanize: humanize,
  257. titleize: titleize,
  258. underscore: underscore
  259. }
  260. })(jQuery, DevExpress);
  261. /*! Module core, file utils.common.js */
  262. (function($, DX, undefined) {
  263. var isDefined = function(object) {
  264. return object !== null && object !== undefined
  265. };
  266. var isString = function(object) {
  267. return $.type(object) === 'string'
  268. };
  269. var isNumber = function(object) {
  270. return typeof object === "number" && isFinite(object) || $.isNumeric(object)
  271. };
  272. var isObject = function(object) {
  273. return $.type(object) === 'object'
  274. };
  275. var isArray = function(object) {
  276. return $.type(object) === 'array'
  277. };
  278. var isDate = function(object) {
  279. return $.type(object) === 'date'
  280. };
  281. var isFunction = function(object) {
  282. return $.type(object) === 'function'
  283. };
  284. var isExponential = function(value) {
  285. return isNumber(value) && value.toString().indexOf('e') !== -1
  286. };
  287. var extendFromObject = function(target, source, overrideExistingValues) {
  288. target = target || {};
  289. for (var prop in source)
  290. if (source.hasOwnProperty(prop)) {
  291. var value = source[prop];
  292. if (!(prop in target) || overrideExistingValues)
  293. target[prop] = value
  294. }
  295. return target
  296. };
  297. var clone = function() {
  298. function Clone(){}
  299. return function(obj) {
  300. Clone.prototype = obj;
  301. return new Clone
  302. }
  303. }();
  304. var executeAsync = function(action, context) {
  305. var deferred = $.Deferred(),
  306. normalizedContext = context || this;
  307. setTimeout(function() {
  308. var result = action.call(normalizedContext);
  309. if (result && result.done && $.isFunction(result.done))
  310. result.done(function() {
  311. deferred.resolveWith(normalizedContext)
  312. });
  313. else
  314. deferred.resolveWith(normalizedContext)
  315. }, 0);
  316. return deferred.promise()
  317. };
  318. var stringFormat = function() {
  319. var s = arguments[0];
  320. for (var i = 0; i < arguments.length - 1; i++) {
  321. var reg = new RegExp("\\{" + i + "\\}", "gm");
  322. s = s.replace(reg, arguments[i + 1])
  323. }
  324. return s
  325. };
  326. var findBestMatches = function(targetFilter, items, mapFn) {
  327. var bestMatches = [],
  328. maxMatchCount = 0;
  329. $.each(items, function(index, itemSrc) {
  330. var matchCount = 0,
  331. item = mapFn ? mapFn(itemSrc) : itemSrc;
  332. $.each(targetFilter, function(paramName) {
  333. var value = item[paramName];
  334. if (value === undefined)
  335. return;
  336. if (value === targetFilter[paramName]) {
  337. matchCount++;
  338. return
  339. }
  340. matchCount = -1;
  341. return false
  342. });
  343. if (matchCount < maxMatchCount)
  344. return;
  345. if (matchCount > maxMatchCount) {
  346. bestMatches.length = 0;
  347. maxMatchCount = matchCount
  348. }
  349. bestMatches.push(itemSrc)
  350. });
  351. return bestMatches
  352. };
  353. var preg_quote = function(str) {
  354. return (str + "").replace(/([\+\*\?\\\.\[\^\]\$\(\)\{\}\>\<\|\=\!\:])/g, "\\$1")
  355. };
  356. var replaceAll = function(text, searchToken, replacementToken) {
  357. return text.replace(new RegExp("(" + preg_quote(searchToken) + ")", "gi"), replacementToken)
  358. };
  359. var splitPair = function(raw) {
  360. switch (typeof raw) {
  361. case"string":
  362. return raw.split(/\s+/, 2);
  363. case"object":
  364. return [raw.x || raw.h, raw.y || raw.v];
  365. case"number":
  366. return [raw];
  367. default:
  368. return raw
  369. }
  370. };
  371. var stringPairToObject = function(raw) {
  372. var pair = splitPair(raw),
  373. x = parseInt(pair && pair[0], 10),
  374. y = parseInt(pair && pair[1], 10);
  375. if (!isFinite(x))
  376. x = 0;
  377. if (!isFinite(y))
  378. y = x;
  379. return {
  380. x: x,
  381. y: y
  382. }
  383. };
  384. function icontains(elem, text) {
  385. var result = false;
  386. $.each($(elem).contents(), function(index, content) {
  387. if (content.nodeType === 3 && (content.textContent || content.nodeValue || "").toLowerCase().indexOf((text || "").toLowerCase()) > -1) {
  388. result = true;
  389. return false
  390. }
  391. });
  392. return result
  393. }
  394. $.expr[":"].dxicontains = $.expr.createPseudo(function(text) {
  395. return function(elem) {
  396. return icontains(elem, text)
  397. }
  398. });
  399. function deepExtendArraySafe(target, changes) {
  400. var prevValue,
  401. newValue;
  402. for (var name in changes) {
  403. prevValue = target[name];
  404. newValue = changes[name];
  405. if (target === newValue)
  406. continue;
  407. if ($.isPlainObject(newValue) && !(newValue instanceof $.Event))
  408. target[name] = deepExtendArraySafe($.isPlainObject(prevValue) ? prevValue : {}, newValue);
  409. else if (newValue !== undefined)
  410. target[name] = newValue
  411. }
  412. return target
  413. }
  414. function unwrapObservable(value) {
  415. if (DX.support.hasKo)
  416. return ko.utils.unwrapObservable(value);
  417. return value
  418. }
  419. DX.utils = {
  420. isDefined: isDefined,
  421. isString: isString,
  422. isNumber: isNumber,
  423. isObject: isObject,
  424. isArray: isArray,
  425. isDate: isDate,
  426. isFunction: isFunction,
  427. isExponential: isExponential,
  428. extendFromObject: extendFromObject,
  429. clone: clone,
  430. executeAsync: executeAsync,
  431. stringFormat: stringFormat,
  432. findBestMatches: findBestMatches,
  433. replaceAll: replaceAll,
  434. deepExtendArraySafe: deepExtendArraySafe,
  435. splitPair: splitPair,
  436. stringPairToObject: stringPairToObject,
  437. unwrapObservable: unwrapObservable
  438. }
  439. })(jQuery, DevExpress);
  440. /*! Module core, file utils.console.js */
  441. (function($, DX, undefined) {
  442. var logger = function() {
  443. var console = window.console;
  444. function info(text) {
  445. if (!console || !$.isFunction(console.info))
  446. return;
  447. console.info(text)
  448. }
  449. function warn(text) {
  450. if (!console || !$.isFunction(console.warn))
  451. return;
  452. console.warn(text)
  453. }
  454. function error(text) {
  455. if (!console || !$.isFunction(console.error))
  456. return;
  457. console.error(text)
  458. }
  459. return {
  460. info: info,
  461. warn: warn,
  462. error: error
  463. }
  464. }();
  465. var debug = function() {
  466. function assert(condition, message) {
  467. if (!condition)
  468. throw new Error(message);
  469. }
  470. function assertParam(parameter, message) {
  471. assert(parameter !== null && parameter !== undefined, message)
  472. }
  473. return {
  474. assert: assert,
  475. assertParam: assertParam
  476. }
  477. }();
  478. $.extend(DX.utils, {
  479. logger: logger,
  480. debug: debug
  481. })
  482. })(jQuery, DevExpress);
  483. /*! Module core, file utils.math.js */
  484. (function($, DX, undefined) {
  485. var PI = Math.PI,
  486. LN10 = Math.LN10;
  487. var cos = Math.cos,
  488. sin = Math.sin,
  489. abs = Math.abs,
  490. log = Math.log,
  491. floor = Math.floor,
  492. ceil = Math.ceil,
  493. max = Math.max,
  494. min = Math.min,
  495. isNaN = window.isNaN,
  496. Number = window.Number,
  497. NaN = window.NaN;
  498. var isNumber = DX.utils.isNumber,
  499. isExponential = DX.utils.isExponential;
  500. var getPrecision = function(value) {
  501. var stringFraction,
  502. stringValue = value.toString(),
  503. pointIndex = stringValue.indexOf('.'),
  504. startIndex,
  505. precision;
  506. if (isExponential(value)) {
  507. precision = getDecimalOrder(value);
  508. if (precision < 0)
  509. return Math.abs(precision);
  510. else
  511. return 0
  512. }
  513. if (pointIndex !== -1) {
  514. startIndex = pointIndex + 1;
  515. stringFraction = stringValue.substring(startIndex, startIndex + 20);
  516. return stringFraction.length
  517. }
  518. return 0
  519. };
  520. var getLog = function(value, base) {
  521. if (!value)
  522. return 0;
  523. return Math.log(value) / Math.log(base)
  524. };
  525. var raiseTo = function(power, base) {
  526. return Math.pow(base, power)
  527. };
  528. var sign = function(value) {
  529. if (value === 0)
  530. return 0;
  531. return value / abs(value)
  532. };
  533. var normalizeAngle = function(angle) {
  534. return (angle % 360 + 360) % 360
  535. };
  536. var convertAngleToRendererSpace = function(angle) {
  537. return 90 - angle
  538. };
  539. var degreesToRadians = function(value) {
  540. return PI * value / 180
  541. };
  542. var getCosAndSin = function(angle) {
  543. var angleInRadians = degreesToRadians(angle);
  544. return {
  545. cos: cos(angleInRadians),
  546. sin: sin(angleInRadians)
  547. }
  548. };
  549. var DECIMAL_ORDER_THRESHOLD = 1E-14;
  550. var getDecimalOrder = function(number) {
  551. var n = abs(number),
  552. cn;
  553. if (!isNaN(n)) {
  554. if (n > 0) {
  555. n = log(n) / LN10;
  556. cn = ceil(n);
  557. return cn - n < DECIMAL_ORDER_THRESHOLD ? cn : floor(n)
  558. }
  559. return 0
  560. }
  561. return NaN
  562. };
  563. var getAppropriateFormat = function(start, end, count) {
  564. var order = max(getDecimalOrder(start), getDecimalOrder(end)),
  565. precision = -getDecimalOrder(abs(end - start) / count),
  566. format;
  567. if (!isNaN(order) && !isNaN(precision)) {
  568. if (abs(order) <= 4) {
  569. format = 'fixedPoint';
  570. precision < 0 && (precision = 0);
  571. precision > 4 && (precision = 4)
  572. }
  573. else {
  574. format = 'exponential';
  575. precision += order - 1;
  576. precision > 3 && (precision = 3)
  577. }
  578. return {
  579. format: format,
  580. precision: precision
  581. }
  582. }
  583. return null
  584. };
  585. var getFraction = function(value) {
  586. var valueString,
  587. dotIndex;
  588. if (isNumber(value)) {
  589. valueString = value.toString();
  590. dotIndex = valueString.indexOf('.');
  591. if (dotIndex >= 0)
  592. if (isExponential(value))
  593. return valueString.substr(dotIndex + 1, valueString.indexOf('e') - dotIndex - 1);
  594. else {
  595. valueString = value.toFixed(20);
  596. return valueString.substr(dotIndex + 1, valueString.length - dotIndex + 1)
  597. }
  598. }
  599. return ''
  600. };
  601. var getSignificantDigitPosition = function(value) {
  602. var fraction = getFraction(value),
  603. i;
  604. if (fraction)
  605. for (i = 0; i < fraction.length; i++)
  606. if (fraction.charAt(i) !== '0')
  607. return i + 1;
  608. return 0
  609. };
  610. var adjustValue = function(value) {
  611. var fraction = getFraction(value),
  612. nextValue,
  613. i;
  614. if (fraction)
  615. for (i = 1; i <= fraction.length; i++) {
  616. nextValue = roundValue(value, i);
  617. if (nextValue !== 0 && fraction[i - 2] && fraction[i - 1] && fraction[i - 2] === fraction[i - 1])
  618. return nextValue
  619. }
  620. return value
  621. };
  622. var roundValue = function(value, precision) {
  623. if (precision > 20)
  624. precision = 20;
  625. if (isNumber(value))
  626. if (isExponential(value))
  627. return Number(value.toExponential(precision));
  628. else
  629. return Number(value.toFixed(precision))
  630. };
  631. var applyPrecisionByMinDelta = function(min, delta, value) {
  632. var minPrecision = getPrecision(min),
  633. deltaPrecision = getPrecision(delta);
  634. return roundValue(value, minPrecision < deltaPrecision ? deltaPrecision : minPrecision)
  635. };
  636. $.extend(DX.utils, {
  637. getLog: getLog,
  638. raiseTo: raiseTo,
  639. sign: sign,
  640. normalizeAngle: normalizeAngle,
  641. convertAngleToRendererSpace: convertAngleToRendererSpace,
  642. degreesToRadians: degreesToRadians,
  643. getCosAndSin: getCosAndSin,
  644. getDecimalOrder: getDecimalOrder,
  645. getAppropriateFormat: getAppropriateFormat,
  646. getFraction: getFraction,
  647. adjustValue: adjustValue,
  648. roundValue: roundValue,
  649. applyPrecisionByMinDelta: applyPrecisionByMinDelta,
  650. getSignificantDigitPosition: getSignificantDigitPosition
  651. });
  652. DX.utils.getPrecision = getPrecision
  653. })(jQuery, DevExpress);
  654. /*! Module core, file utils.date.js */
  655. (function($, DX, undefined) {
  656. var isObject = DX.utils.isObject,
  657. isString = DX.utils.isString,
  658. isDate = DX.utils.isDate,
  659. isDefined = DX.utils.isDefined;
  660. var dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'week', 'month', 'quarter', 'year'];
  661. var addSubValues = function(value1, value2, isSub) {
  662. return value1 + (isSub ? -1 : 1) * value2
  663. };
  664. var toMilliseconds = function(value) {
  665. switch (value) {
  666. case'millisecond':
  667. return 1;
  668. case'second':
  669. return toMilliseconds('millisecond') * 1000;
  670. case'minute':
  671. return toMilliseconds('second') * 60;
  672. case'hour':
  673. return toMilliseconds('minute') * 60;
  674. case'day':
  675. return toMilliseconds('hour') * 24;
  676. case'week':
  677. return toMilliseconds('day') * 7;
  678. case'month':
  679. return toMilliseconds('day') * 30;
  680. case'quarter':
  681. return toMilliseconds('month') * 3;
  682. case'year':
  683. return toMilliseconds('day') * 365;
  684. default:
  685. return 0
  686. }
  687. };
  688. function parseISO8601(isoString) {
  689. var result = new Date(0);
  690. var chunks = isoString.replace("Z", "").split("T"),
  691. date = String(chunks[0]).split("-"),
  692. time = String(chunks[1]).split(":");
  693. var year,
  694. month,
  695. day,
  696. hours,
  697. minutes,
  698. seconds,
  699. milliseconds;
  700. year = Number(date[0]);
  701. month = Number(date[1]) - 1;
  702. day = Number(date[2]);
  703. result.setDate(day);
  704. result.setMonth(month);
  705. result.setFullYear(year);
  706. if (time.length) {
  707. hours = Number(time[0]);
  708. minutes = Number(time[1]);
  709. seconds = Number(String(time[2]).split(".")[0]);
  710. milliseconds = Number(String(time[2]).split(".")[1]) || 0;
  711. result.setHours(hours);
  712. result.setMinutes(minutes);
  713. result.setSeconds(seconds);
  714. result.setMilliseconds(milliseconds)
  715. }
  716. return result
  717. }
  718. function formatISO8601(date) {
  719. function pad(n) {
  720. if (n < 10)
  721. return "0".concat(n);
  722. return String(n)
  723. }
  724. return [date.getFullYear(), "-", pad(date.getMonth() + 1), "-", pad(date.getDate()), "T", pad(date.getHours()), ":", pad(date.getMinutes()), ":", pad(date.getSeconds()), "Z"].join("")
  725. }
  726. var convertMillisecondsToDateUnits = function(value) {
  727. var i,
  728. dateUnitCount,
  729. dateUnitInterval,
  730. dateUnitIntervals = ['millisecond', 'second', 'minute', 'hour', 'day', 'month', 'year'],
  731. result = {};
  732. for (i = dateUnitIntervals.length - 1; i >= 0; i--) {
  733. dateUnitInterval = dateUnitIntervals[i];
  734. dateUnitCount = Math.floor(value / toMilliseconds(dateUnitInterval));
  735. if (dateUnitCount > 0) {
  736. result[dateUnitInterval + 's'] = dateUnitCount;
  737. value -= convertDateUnitToMilliseconds(dateUnitInterval, dateUnitCount)
  738. }
  739. }
  740. return result
  741. };
  742. var convertDateTickIntervalToMilliseconds = function(tickInterval) {
  743. var milliseconds = 0;
  744. if (isObject(tickInterval))
  745. $.each(tickInterval, function(key, value) {
  746. milliseconds += convertDateUnitToMilliseconds(key.substr(0, key.length - 1), value)
  747. });
  748. if (isString(tickInterval))
  749. milliseconds = convertDateUnitToMilliseconds(tickInterval, 1);
  750. return milliseconds
  751. };
  752. var convertDateUnitToMilliseconds = function(dateUnit, count) {
  753. return toMilliseconds(dateUnit) * count
  754. };
  755. var getDateUnitInterval = function(tickInterval) {
  756. var maxInterval = -1,
  757. i;
  758. if (isString(tickInterval))
  759. return tickInterval;
  760. if (isObject(tickInterval)) {
  761. $.each(tickInterval, function(key, value) {
  762. for (i = 0; i < dateUnitIntervals.length; i++)
  763. if (value && (key === dateUnitIntervals[i] + 's' || key === dateUnitIntervals[i]) && maxInterval < i)
  764. maxInterval = i
  765. });
  766. return dateUnitIntervals[maxInterval]
  767. }
  768. return ''
  769. };
  770. var correctDateWithUnitBeginning = function(date, dateInterval) {
  771. var dayMonth,
  772. firstQuarterMonth,
  773. dateUnitInterval = getDateUnitInterval(dateInterval);
  774. switch (dateUnitInterval) {
  775. case'second':
  776. date.setMilliseconds(0);
  777. break;
  778. case'minute':
  779. date.setSeconds(0, 0);
  780. break;
  781. case'hour':
  782. date.setMinutes(0, 0, 0);
  783. break;
  784. case'year':
  785. date.setMonth(0);
  786. case'month':
  787. date.setDate(1);
  788. case'day':
  789. date.setHours(0, 0, 0, 0);
  790. break;
  791. case'week':
  792. dayMonth = date.getDate();
  793. if (date.getDay() !== 0)
  794. dayMonth += 7 - date.getDay();
  795. date.setDate(dayMonth);
  796. date.setHours(0, 0, 0, 0);
  797. break;
  798. case'quarter':
  799. firstQuarterMonth = DX.formatHelper.getFirstQuarterMonth(date.getMonth());
  800. if (date.getMonth() !== firstQuarterMonth)
  801. date.setMonth(firstQuarterMonth);
  802. date.setDate(1);
  803. date.setHours(0, 0, 0, 0);
  804. break
  805. }
  806. };
  807. var getDatesDifferences = function(date1, date2) {
  808. var differences,
  809. counter = 0;
  810. differences = {
  811. year: date1.getFullYear() !== date2.getFullYear(),
  812. month: date1.getMonth() !== date2.getMonth(),
  813. day: date1.getDate() !== date2.getDate(),
  814. hour: date1.getHours() !== date2.getHours(),
  815. minute: date1.getMinutes() !== date2.getMinutes(),
  816. second: date1.getSeconds() !== date2.getSeconds()
  817. };
  818. $.each(differences, function(key, value) {
  819. if (value)
  820. counter++
  821. });
  822. differences.count = counter;
  823. return differences
  824. };
  825. var addInterval = function(value, interval, isNegative) {
  826. var result = null,
  827. intervalObject;
  828. if (isDate(value)) {
  829. intervalObject = isString(interval) ? getDateIntervalByString(interval.toLowerCase()) : interval;
  830. result = new Date(value.getTime());
  831. if (intervalObject.years)
  832. result.setFullYear(addSubValues(result.getFullYear(), intervalObject.years, isNegative));
  833. if (intervalObject.quarters)
  834. result.setMonth(addSubValues(result.getMonth(), 3 * intervalObject.quarters, isNegative));
  835. if (intervalObject.months)
  836. result.setMonth(addSubValues(result.getMonth(), intervalObject.months, isNegative));
  837. if (intervalObject.weeks)
  838. result.setDate(addSubValues(result.getDate(), 7 * intervalObject.weeks, isNegative));
  839. if (intervalObject.days)
  840. result.setDate(addSubValues(result.getDate(), intervalObject.days, isNegative));
  841. if (intervalObject.hours)
  842. result.setHours(addSubValues(result.getHours(), intervalObject.hours, isNegative));
  843. if (intervalObject.minutes)
  844. result.setMinutes(addSubValues(result.getMinutes(), intervalObject.minutes, isNegative));
  845. if (intervalObject.seconds)
  846. result.setSeconds(addSubValues(result.getSeconds(), intervalObject.seconds, isNegative));
  847. if (intervalObject.milliseconds)
  848. result.setMilliseconds(addSubValues(value.getMilliseconds(), intervalObject.milliseconds, isNegative))
  849. }
  850. else
  851. result = addSubValues(value, interval, isNegative);
  852. return result
  853. };
  854. var getDateIntervalByString = function(intervalString) {
  855. var result = {};
  856. switch (intervalString) {
  857. case'year':
  858. result.years = 1;
  859. break;
  860. case'month':
  861. result.months = 1;
  862. break;
  863. case'quarter':
  864. result.months = 3;
  865. break;
  866. case'week':
  867. result.days = 7;
  868. break;
  869. case'day':
  870. result.days = 1;
  871. break;
  872. case'hour':
  873. result.hours = 1;
  874. break;
  875. case'minute':
  876. result.minutes = 1;
  877. break;
  878. case'second':
  879. result.seconds = 1;
  880. break;
  881. case'millisecond':
  882. result.milliseconds = 1;
  883. break
  884. }
  885. return result
  886. };
  887. var sameMonthAndYear = function(date1, date2) {
  888. return date1 && date2 && date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth()
  889. };
  890. var getFirstMonthDate = function(date) {
  891. return new Date(date.getFullYear(), date.getMonth(), 1)
  892. };
  893. var dateInRange = function(date, min, max) {
  894. return normalizeDate(date, min, max) === date
  895. };
  896. var normalizeDate = function(date, min, max) {
  897. var normalizedDate = date;
  898. if (isDefined(min) && date < min)
  899. normalizedDate = min;
  900. if (isDefined(max) && date > max)
  901. normalizedDate = max;
  902. return normalizedDate
  903. };
  904. var getPower = function(value) {
  905. return value.toExponential().split("e")[1]
  906. };
  907. $.extend(DX.utils, {
  908. dateUnitIntervals: dateUnitIntervals,
  909. parseIso8601Date: parseISO8601,
  910. formatIso8601Date: formatISO8601,
  911. convertMillisecondsToDateUnits: convertMillisecondsToDateUnits,
  912. convertDateTickIntervalToMilliseconds: convertDateTickIntervalToMilliseconds,
  913. convertDateUnitToMilliseconds: convertDateUnitToMilliseconds,
  914. getDateUnitInterval: getDateUnitInterval,
  915. getDatesDifferences: getDatesDifferences,
  916. correctDateWithUnitBeginning: correctDateWithUnitBeginning,
  917. addInterval: addInterval,
  918. getDateIntervalByString: getDateIntervalByString,
  919. sameMonthAndYear: sameMonthAndYear,
  920. getFirstMonthDate: getFirstMonthDate,
  921. dateInRange: dateInRange,
  922. normalizeDate: normalizeDate,
  923. getPower: getPower
  924. })
  925. })(jQuery, DevExpress);
  926. /*! Module core, file utils.dom.js */
  927. (function($, DX, undefined) {
  928. var IOS_APP_BAR_HEIGHT = "20px";
  929. var timeRedrawOnResize = 100;
  930. var createResizeHandler = function(callback) {
  931. var $window = $(window),
  932. timeout;
  933. var debug_callback = arguments[1];
  934. var handler = function() {
  935. var width = $window.width(),
  936. height = $window.height();
  937. clearTimeout(timeout);
  938. timeout = setTimeout(function() {
  939. $window.width() === width && $window.height() === height && callback();
  940. debug_callback && debug_callback()
  941. }, timeRedrawOnResize)
  942. };
  943. handler.stop = function() {
  944. clearTimeout(timeout);
  945. return this
  946. };
  947. return handler
  948. };
  949. var windowResizeCallbacks = function() {
  950. var prevSize,
  951. callbacks = $.Callbacks(),
  952. jqWindow = $(window),
  953. resizeEventHandlerAttached = false,
  954. originalCallbacksAdd = callbacks.add,
  955. originalCallbacksRemove = callbacks.remove;
  956. var formatSize = function() {
  957. return [jqWindow.width(), jqWindow.height()].join()
  958. };
  959. var handleResize = function() {
  960. var now = formatSize();
  961. if (now === prevSize)
  962. return;
  963. prevSize = now;
  964. setTimeout(callbacks.fire)
  965. };
  966. prevSize = formatSize();
  967. callbacks.add = function() {
  968. var result = originalCallbacksAdd.apply(callbacks, arguments);
  969. if (!resizeEventHandlerAttached && callbacks.has()) {
  970. jqWindow.on("resize", handleResize);
  971. resizeEventHandlerAttached = true
  972. }
  973. return result
  974. };
  975. callbacks.remove = function() {
  976. var result = originalCallbacksRemove.apply(callbacks, arguments);
  977. if (!callbacks.has() && resizeEventHandlerAttached) {
  978. jqWindow.off("resize", handleResize);
  979. resizeEventHandlerAttached = false
  980. }
  981. return result
  982. };
  983. return callbacks
  984. }();
  985. var resetActiveElement = function() {
  986. var activeElement = document.activeElement;
  987. if (activeElement && activeElement !== document.body && activeElement.blur)
  988. activeElement.blur()
  989. };
  990. var createMarkupFromString = function(str) {
  991. var tempElement = $("<div />");
  992. if (window.WinJS)
  993. WinJS.Utilities.setInnerHTMLUnsafe(tempElement.get(0), str);
  994. else
  995. tempElement.append(str);
  996. return tempElement.contents()
  997. };
  998. var initMobileViewport = function(options) {
  999. options = $.extend({}, options);
  1000. var device = DX.devices.current();
  1001. var realDevice = DX.devices.real();
  1002. var allowZoom = options.allowZoom,
  1003. allowPan = options.allowPan,
  1004. allowSelection = "allowSelection" in options ? options.allowSelection : device.platform == "desktop";
  1005. DX.overlayTargetContainer(".dx-viewport");
  1006. var metaSelector = "meta[name=viewport]";
  1007. if (!$(metaSelector).length)
  1008. $("<meta />").attr("name", "viewport").appendTo("head");
  1009. var metaVerbs = ["width=device-width"],
  1010. msTouchVerbs = [];
  1011. if (allowZoom)
  1012. msTouchVerbs.push("pinch-zoom");
  1013. else
  1014. metaVerbs.push("initial-scale=1.0", "maximum-scale=1.0, user-scalable=no");
  1015. if (allowPan)
  1016. msTouchVerbs.push("pan-x", "pan-y");
  1017. if (!allowPan && !allowZoom)
  1018. $("html, body").css({
  1019. "-ms-content-zooming": "none",
  1020. "-ms-user-select": "none",
  1021. overflow: "hidden"
  1022. });
  1023. else
  1024. $("html").css("-ms-overflow-style", "-ms-autohiding-scrollbar");
  1025. if (!allowSelection) {
  1026. if (realDevice.ios)
  1027. $(document).on("selectstart", function() {
  1028. return false
  1029. });
  1030. $(".dx-viewport").css("user-select", "none")
  1031. }
  1032. $(metaSelector).attr("content", metaVerbs.join());
  1033. $("html").css("-ms-touch-action", msTouchVerbs.join(" ") || "none");
  1034. if (DX.support.touch)
  1035. $(document).off(".dxInitMobileViewport").on("touchmove.dxInitMobileViewport", function(e) {
  1036. var count = e.originalEvent.touches.length,
  1037. zoomDisabled = !allowZoom && count > 1,
  1038. panDisabled = !allowPan && count === 1 && !e.isScrollingEvent;
  1039. if (zoomDisabled || panDisabled)
  1040. e.preventDefault()
  1041. });
  1042. realDevice = DX.devices.real();
  1043. if (realDevice.ios) {
  1044. var isPhoneGap = document.location.protocol === "file:";
  1045. if (!isPhoneGap)
  1046. windowResizeCallbacks.add(function() {
  1047. var windowWidth = $(window).width();
  1048. $("body").width(windowWidth)
  1049. });
  1050. else if (realDevice.version[0] > 6) {
  1051. $(".dx-viewport").css("position", "relative");
  1052. $("body").css({"box-sizing": "border-box"});
  1053. $("body").css("padding-top", IOS_APP_BAR_HEIGHT);
  1054. if (realDevice.version[0] === 7 && realDevice.version[1] < 1) {
  1055. var setDeviceHeight = function() {
  1056. var deviceHeight = "height=device-" + (Math.abs(window.orientation) === 90 ? "width" : "height");
  1057. $(metaSelector).attr("content", metaVerbs.join() + "," + deviceHeight)
  1058. };
  1059. $(window).on("orientationchange", setDeviceHeight);
  1060. setDeviceHeight()
  1061. }
  1062. }
  1063. }
  1064. };
  1065. var triggerVisibilityChangeEvent = function(event) {
  1066. return function(element) {
  1067. $(element || "body").find(".dx-visibility-change-handler").each(function() {
  1068. $(this).triggerHandler(event)
  1069. })
  1070. }
  1071. };
  1072. $.extend(DX.utils, {
  1073. createResizeHandler: createResizeHandler,
  1074. windowResizeCallbacks: windowResizeCallbacks,
  1075. resetActiveElement: resetActiveElement,
  1076. createMarkupFromString: createMarkupFromString,
  1077. triggerShownEvent: triggerVisibilityChangeEvent("dxshown"),
  1078. triggerHidingEvent: triggerVisibilityChangeEvent("dxhiding"),
  1079. initMobileViewport: initMobileViewport
  1080. });
  1081. DX.utils.__timeRedrawOnResize = timeRedrawOnResize
  1082. })(jQuery, DevExpress);
  1083. /*! Module core, file utils.graphics.js */
  1084. (function($, DX, undefined) {
  1085. var isFunction = DX.utils.isFunction,
  1086. iDevice = /iphone|ipad/.test(navigator.userAgent.toLowerCase());
  1087. var processSeriesTemplate = function(seriesTemplate, items) {
  1088. var customizeSeries = isFunction(seriesTemplate.customizeSeries) ? seriesTemplate.customizeSeries : $.noop,
  1089. nameField = seriesTemplate.nameField || 'series',
  1090. generatedSeries = {},
  1091. seriesOrder = [],
  1092. series;
  1093. for (var i = 0, length = items.length; i < length; i++) {
  1094. var data = items[i];
  1095. if (nameField in data) {
  1096. series = generatedSeries[data[nameField]];
  1097. if (!series) {
  1098. series = generatedSeries[data[nameField]] = {
  1099. name: data[nameField],
  1100. data: []
  1101. };
  1102. seriesOrder.push(series.name)
  1103. }
  1104. series.data.push(data)
  1105. }
  1106. }
  1107. return $.map(seriesOrder, function(orderedName) {
  1108. var group = generatedSeries[orderedName],
  1109. seriesOptions = customizeSeries.call(null, group.name);
  1110. return $.extend(group, seriesOptions)
  1111. })
  1112. };
  1113. var getNextDefsSvgId = function() {
  1114. var numDefsSvgElements = 1;
  1115. return function() {
  1116. return 'DevExpress_' + numDefsSvgElements++
  1117. }
  1118. }();
  1119. var getRootOffset = function(renderer) {
  1120. var node,
  1121. result = {
  1122. left: 0,
  1123. top: 0
  1124. },
  1125. pointTransform,
  1126. root = renderer.getRoot();
  1127. if (root) {
  1128. node = root.element;
  1129. if (node.getScreenCTM && !iDevice) {
  1130. var ctm = node.getScreenCTM();
  1131. if (ctm) {
  1132. pointTransform = node.createSVGPoint().matrixTransform(ctm);
  1133. result.left = pointTransform.x + (document.body.scrollLeft || document.documentElement.scrollLeft);
  1134. result.top = pointTransform.y + (document.body.scrollTop || document.documentElement.scrollTop)
  1135. }
  1136. else {
  1137. result.left = document.body.scrollLeft || document.documentElement.scrollLeft;
  1138. result.top = document.body.scrollTop || document.documentElement.scrollTop
  1139. }
  1140. }
  1141. else
  1142. result = $(node).offset()
  1143. }
  1144. return result
  1145. };
  1146. $.extend(DX.utils, {
  1147. processSeriesTemplate: processSeriesTemplate,
  1148. getNextDefsSvgId: getNextDefsSvgId,
  1149. getRootOffset: getRootOffset
  1150. })
  1151. })(jQuery, DevExpress);
  1152. /*! Module core, file utils.arrays.js */
  1153. (function($, DX, undefined) {
  1154. var wrapToArray = function(entity) {
  1155. return $.isArray(entity) ? entity : [entity]
  1156. };
  1157. var removeDublicates = function(from, what) {
  1158. if (!$.isArray(from) || from.length === 0)
  1159. return [];
  1160. if (!$.isArray(what) || what.length === 0)
  1161. return from.slice();
  1162. var result = [];
  1163. $.each(from, function(_, value) {
  1164. var bIndex = $.inArray(value, what);
  1165. if (bIndex === -1)
  1166. result.push(value)
  1167. });
  1168. return result
  1169. };
  1170. $.extend(DX.utils, {
  1171. wrapToArray: wrapToArray,
  1172. removeDublicates: removeDublicates
  1173. })
  1174. })(jQuery, DevExpress);
  1175. /*! Module core, file devices.js */
  1176. (function($, DX, undefined) {
  1177. var KNOWN_UA_TABLE = {
  1178. iPhone: "iPhone",
  1179. iPhone5: "iPhone 5",
  1180. iPad: "iPad",
  1181. iPadMini: "iPad Mini",
  1182. androidPhone: "Android Mobile",
  1183. androidTablet: "Android",
  1184. win8: "MSAppHost",
  1185. win8Phone: "Windows Phone 8",
  1186. msSurface: "MSIE ARM Tablet PC",
  1187. desktop: "desktop",
  1188. tizen: "Tizen Mobile"
  1189. };
  1190. var DEFAULT_DEVICE = {
  1191. deviceType: "",
  1192. platform: "",
  1193. version: [],
  1194. phone: false,
  1195. tablet: false,
  1196. android: false,
  1197. ios: false,
  1198. win8: false,
  1199. tizen: false,
  1200. generic: false
  1201. };
  1202. var GENERIC_DEVICE = $.extend(DEFAULT_DEVICE, {
  1203. platform: "generic",
  1204. deviceType: "desktop",
  1205. generic: true
  1206. });
  1207. var uaParsers = {
  1208. win8: function(userAgent) {
  1209. var isPhone = /windows phone/i.test(userAgent),
  1210. isTablet = !isPhone && /arm(.*)trident/i.test(userAgent),
  1211. isDesktop = !isPhone && !isTablet && /msapphost/i.test(userAgent);
  1212. if (!(isPhone || isTablet || isDesktop))
  1213. return;
  1214. var matches = userAgent.match(/windows phone (\d+).(\d+)/i) || userAgent.match(/windows nt (\d+).(\d+)/i),
  1215. version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10)] : [];
  1216. return {
  1217. deviceType: isPhone ? "phone" : isTablet ? "tablet" : "desktop",
  1218. platform: "win8",
  1219. version: version
  1220. }
  1221. },
  1222. ios: function(userAgent) {
  1223. if (!/ip(hone|od|ad)/i.test(userAgent))
  1224. return;
  1225. var isPhone = /ip(hone|od)/i.test(userAgent);
  1226. var matches = userAgent.match(/os (\d+)_(\d+)_?(\d+)?/i);
  1227. var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [];
  1228. return {
  1229. deviceType: isPhone ? "phone" : "tablet",
  1230. platform: "ios",
  1231. version: version
  1232. }
  1233. },
  1234. android: function(userAgent) {
  1235. if (!/android|htc_|silk/i.test(userAgent))
  1236. return;
  1237. var isPhone = /mobile/i.test(userAgent);
  1238. var matches = userAgent.match(/android (\d+)\.(\d+)\.?(\d+)?/i);
  1239. var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10), parseInt(matches[3] || 0, 10)] : [];
  1240. return {
  1241. deviceType: isPhone ? "phone" : "tablet",
  1242. platform: "android",
  1243. version: version
  1244. }
  1245. },
  1246. tizen: function(userAgent) {
  1247. if (!/tizen/i.test(userAgent))
  1248. return;
  1249. var isPhone = /mobile/i.test(userAgent);
  1250. var matches = userAgent.match(/tizen (\d+)\.(\d+)/i);
  1251. var version = matches ? [parseInt(matches[1], 10), parseInt(matches[2], 10)] : [];
  1252. return {
  1253. deviceType: isPhone ? "phone" : "tablet",
  1254. platform: "tizen",
  1255. version: version
  1256. }
  1257. }
  1258. };
  1259. DX.Devices = DX.Class.inherit({
  1260. ctor: function(options) {
  1261. this._window = options && options.window || window;
  1262. this._realDevice = this._getDevice();
  1263. this._currentDevice = undefined;
  1264. this._currentOrientation = undefined;
  1265. this.orientationChanged = $.Callbacks();
  1266. this._recalculateOrientation();
  1267. DX.utils.windowResizeCallbacks.add($.proxy(this._recalculateOrientation, this))
  1268. },
  1269. current: function(deviceOrName) {
  1270. if (deviceOrName) {
  1271. this._currentDevice = this._getDevice(deviceOrName);
  1272. DX.ui.themes.init({_autoInit: true})
  1273. }
  1274. else {
  1275. if (!this._currentDevice) {
  1276. deviceOrName = undefined;
  1277. try {
  1278. deviceOrName = this._getDeviceOrNameFromWindowScope()
  1279. }
  1280. catch(e) {
  1281. deviceOrName = this._getDeviceNameFromSessionStorage()
  1282. }
  1283. finally {
  1284. if (!deviceOrName)
  1285. deviceOrName = this._getDeviceNameFromSessionStorage()
  1286. }
  1287. this._currentDevice = this._getDevice(deviceOrName)
  1288. }
  1289. return this._currentDevice
  1290. }
  1291. },
  1292. real: function() {
  1293. var forceDevice = arguments[0];
  1294. if ($.isPlainObject(forceDevice)) {
  1295. $.extend(this._realDevice, forceDevice);
  1296. return
  1297. }
  1298. return $.extend({}, this._realDevice)
  1299. },
  1300. orientation: function() {
  1301. return this._currentOrientation
  1302. },
  1303. isRippleEmulator: function() {
  1304. return !!this._window.tinyHippos
  1305. },
  1306. attachCssClasses: function(element, device) {
  1307. var realDevice = this._realDevice,
  1308. $element = $(element);
  1309. device = device || this.current();
  1310. if (device.deviceType)
  1311. $element.addClass("dx-device-" + device.deviceType);
  1312. $element.addClass("dx-device-" + realDevice.platform);
  1313. if (realDevice.version && realDevice.version.length)
  1314. $element.addClass("dx-device-" + realDevice.platform + "-" + realDevice.version[0]);
  1315. if (DX.devices.isSimulator())
  1316. $element.addClass("dx-simulator");
  1317. if (DX.rtlEnabled)
  1318. $element.addClass("dx-rtl")
  1319. },
  1320. isSimulator: function() {
  1321. try {
  1322. return this._isSimulator || this._window.top !== this._window.self && this._window.top["dx-force-device"] || this.isRippleEmulator()
  1323. }
  1324. catch(e) {
  1325. return false
  1326. }
  1327. },
  1328. forceSimulator: function() {
  1329. this._isSimulator = true
  1330. },
  1331. _getDevice: function(deviceName) {
  1332. if (deviceName === "genericPhone")
  1333. deviceName = {
  1334. deviceType: "phone",
  1335. platform: "generic",
  1336. generic: true
  1337. };
  1338. if ($.isPlainObject(deviceName))
  1339. return this._fromConfig(deviceName);
  1340. else {
  1341. var ua;
  1342. if (deviceName) {
  1343. ua = KNOWN_UA_TABLE[deviceName];
  1344. if (!ua)
  1345. throw Error("Unknown device");
  1346. }
  1347. else
  1348. ua = navigator.userAgent;
  1349. return this._fromUA(ua)
  1350. }
  1351. },
  1352. _getDeviceOrNameFromWindowScope: function() {
  1353. var result;
  1354. if (this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"])
  1355. result = this._window.top["dx-force-device-object"] || this._window.top["dx-force-device"];
  1356. return result
  1357. },
  1358. _getDeviceNameFromSessionStorage: function() {
  1359. return this._window.sessionStorage && (sessionStorage.getItem("dx-force-device") || sessionStorage.getItem("dx-simulator-device"))
  1360. },
  1361. _fromConfig: function(config) {
  1362. var shortcuts = {
  1363. phone: config.deviceType === "phone",
  1364. tablet: config.deviceType === "tablet",
  1365. android: config.platform === "android",
  1366. ios: config.platform === "ios",
  1367. win8: config.platform === "win8",
  1368. tizen: config.platform === "tizen",
  1369. generic: config.platform === "generic"
  1370. };
  1371. return $.extend({}, DEFAULT_DEVICE, this._currentDevice, shortcuts, config)
  1372. },
  1373. _fromUA: function(ua) {
  1374. var config;
  1375. $.each(uaParsers, function(platform, parser) {
  1376. config = parser(ua);
  1377. return !config
  1378. });
  1379. if (config)
  1380. return this._fromConfig(config);
  1381. return GENERIC_DEVICE
  1382. },
  1383. _changeOrientation: function() {
  1384. var $window = $(this._window),
  1385. orientation = $window.height() > $window.width() ? "portrait" : "landscape";
  1386. if (this._currentOrientation === orientation)
  1387. return;
  1388. this._currentOrientation = orientation;
  1389. this.orientationChanged.fire({orientation: orientation})
  1390. },
  1391. _recalculateOrientation: function() {
  1392. var windowWidth = $(this._window).width();
  1393. if (this._currentWidth === windowWidth)
  1394. return;
  1395. this._currentWidth = windowWidth;
  1396. this._changeOrientation()
  1397. }
  1398. });
  1399. DX.devices = new DX.Devices
  1400. })(jQuery, DevExpress);
  1401. /*! Module core, file browser.js */
  1402. (function($, DX, global, undefined) {
  1403. var webkitRegExp = /(webkit)[ \/]([\w.]+)/,
  1404. operaRegExp = /(opera)(?:.*version)?[ \/]([\w.]+)/,
  1405. ieRegExp = /(msie) (\d{1,2}\.\d)/,
  1406. ie11RegExp = /(trident).*rv:(\d{1,2}\.\d)/,
  1407. mozillaRegExp = /(mozilla)(?:.*? rv:([\w.]+))?/;
  1408. var ua = navigator.userAgent.toLowerCase();
  1409. var browser = function() {
  1410. var result = {},
  1411. matches = webkitRegExp.exec(ua) || operaRegExp.exec(ua) || ieRegExp.exec(ua) || ie11RegExp.exec(ua) || ua.indexOf("compatible") < 0 && mozillaRegExp.exec(ua) || [],
  1412. browserName = matches[1],
  1413. browserVersion = matches[2];
  1414. if (browserName === "trident")
  1415. browserName = "msie";
  1416. if (browserName) {
  1417. result[browserName] = true;
  1418. result.version = browserVersion
  1419. }
  1420. return result
  1421. }();
  1422. DX.browser = browser
  1423. })(jQuery, DevExpress, this);
  1424. /*! Module core, file support.js */
  1425. (function($, DX, window) {
  1426. var cssPrefixes = ["", "Webkit", "Moz", "O", "ms"],
  1427. styles = document.createElement("dx").style;
  1428. var transitionEndEventNames = {
  1429. WebkitTransition: 'webkitTransitionEnd',
  1430. MozTransition: 'transitionend',
  1431. OTransition: 'oTransitionEnd',
  1432. msTransition: 'MsTransitionEnd',
  1433. transition: 'transitionend'
  1434. };
  1435. var styleProp = function(prop) {
  1436. prop = DX.inflector.camelize(prop, true);
  1437. for (var i = 0, cssPrefixesCount = cssPrefixes.length; i < cssPrefixesCount; i++) {
  1438. var specific = cssPrefixes[i] + prop;
  1439. if (specific in styles)
  1440. return specific
  1441. }
  1442. };
  1443. var supportProp = function(prop) {
  1444. return !!styleProp(prop)
  1445. };
  1446. var isNativeScrollingSupported = function(device) {
  1447. var realDevice = DX.devices.real(),
  1448. realPlatform = realDevice.platform,
  1449. realVersion = realDevice.version,
  1450. isObsoleteAndroid = realVersion && realVersion[0] < 4 && realPlatform === "android",
  1451. isNativeScrollDevice = !isObsoleteAndroid && $.inArray(realPlatform, ["ios", "android", "win8"]) > -1;
  1452. return isNativeScrollDevice
  1453. };
  1454. DX.support = {
  1455. touch: "ontouchstart" in window || !!window.navigator.msMaxTouchPoints,
  1456. pointer: window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
  1457. transform3d: supportProp("transform"),
  1458. transition: supportProp("transition"),
  1459. transitionEndEventName: transitionEndEventNames[styleProp("transition")],
  1460. animation: supportProp("animation"),
  1461. nativeScrolling: isNativeScrollingSupported(),
  1462. winJS: "WinJS" in window,
  1463. styleProp: styleProp,
  1464. supportProp: supportProp,
  1465. hasKo: !!window.ko,
  1466. hasNg: !window.ko && !!window.angular,
  1467. inputType: function(type) {
  1468. if (type === "text")
  1469. return true;
  1470. var input = document.createElement("input");
  1471. try {
  1472. input.setAttribute("type", type);
  1473. input.value = "wrongValue";
  1474. return !input.value
  1475. }
  1476. catch(e) {
  1477. return false
  1478. }
  1479. }
  1480. }
  1481. })(jQuery, DevExpress, this);
  1482. /*! Module core, file position.js */
  1483. (function($, DX, undefined) {
  1484. var horzRe = /left|right/,
  1485. vertRe = /top|bottom/,
  1486. collisionRe = /fit|flip|none/;
  1487. var normalizeAlign = function(raw) {
  1488. var result = {
  1489. h: "center",
  1490. v: "center"
  1491. };
  1492. var pair = DX.utils.splitPair(raw);
  1493. if (pair)
  1494. $.each(pair, function() {
  1495. var w = String(this).toLowerCase();
  1496. if (horzRe.test(w))
  1497. result.h = w;
  1498. else if (vertRe.test(w))
  1499. result.v = w
  1500. });
  1501. return result
  1502. };
  1503. var normalizeOffset = function(raw) {
  1504. var values = DX.utils.stringPairToObject(raw);
  1505. return {
  1506. h: values.x,
  1507. v: values.y
  1508. }
  1509. };
  1510. var normalizeCollision = function(raw) {
  1511. var pair = DX.utils.splitPair(raw),
  1512. h = String(pair && pair[0]).toLowerCase(),
  1513. v = String(pair && pair[1]).toLowerCase();
  1514. if (!collisionRe.test(h))
  1515. h = "none";
  1516. if (!collisionRe.test(v))
  1517. v = h;
  1518. return {
  1519. h: h,
  1520. v: v
  1521. }
  1522. };
  1523. var getAlignFactor = function(align) {
  1524. switch (align) {
  1525. case"center":
  1526. return 0.5;
  1527. case"right":
  1528. case"bottom":
  1529. return 1;
  1530. default:
  1531. return 0
  1532. }
  1533. };
  1534. var inverseAlign = function(align) {
  1535. switch (align) {
  1536. case"left":
  1537. return "right";
  1538. case"right":
  1539. return "left";
  1540. case"top":
  1541. return "bottom";
  1542. case"bottom":
  1543. return "top";
  1544. default:
  1545. return align
  1546. }
  1547. };
  1548. var calculateOversize = function(data, bounds) {
  1549. var oversize = 0;
  1550. if (data.myLocation < bounds.min)
  1551. oversize += bounds.min - data.myLocation;
  1552. if (data.myLocation > bounds.max)
  1553. oversize += data.myLocation - bounds.max;
  1554. return oversize
  1555. };
  1556. var initMyLocation = function(data) {
  1557. data.myLocation = data.atLocation + getAlignFactor(data.atAlign) * data.atSize - getAlignFactor(data.myAlign) * data.mySize + data.offset
  1558. };
  1559. var decolliders = {
  1560. fit: function(data, bounds) {
  1561. var result = false;
  1562. if (data.myLocation > bounds.max) {
  1563. data.myLocation = bounds.max;
  1564. result = true
  1565. }
  1566. if (data.myLocation < bounds.min) {
  1567. data.myLocation = bounds.min;
  1568. result = true
  1569. }
  1570. return result
  1571. },
  1572. flip: function(data, bounds) {
  1573. if (data.myAlign === "center" && data.atAlign === "center")
  1574. return false;
  1575. if (data.myLocation < bounds.min || data.myLocation > bounds.max) {
  1576. var inverseData = $.extend({}, data, {
  1577. myAlign: inverseAlign(data.myAlign),
  1578. atAlign: inverseAlign(data.atAlign),
  1579. offset: -data.offset
  1580. });
  1581. initMyLocation(inverseData);
  1582. inverseData.oversize = calculateOversize(inverseData, bounds);
  1583. if (inverseData.myLocation >= bounds.min && inverseData.myLocation <= bounds.max || inverseData.myLocation > data.myLocation || inverseData.oversize < data.oversize) {
  1584. data.myLocation = inverseData.myLocation;
  1585. data.oversize = inverseData.oversize;
  1586. return true
  1587. }
  1588. }
  1589. return false
  1590. }
  1591. };
  1592. var scrollbarWidth;
  1593. var defaultPositionResult = {
  1594. h: {
  1595. location: 0,
  1596. flip: false,
  1597. fit: false,
  1598. oversize: 0
  1599. },
  1600. v: {
  1601. location: 0,
  1602. flip: false,
  1603. fit: false,
  1604. oversize: 0
  1605. }
  1606. };
  1607. var calculatePosition = function(what, options) {
  1608. var $what = $(what),
  1609. currentOffset = $what.offset(),
  1610. result = $.extend(true, {}, defaultPositionResult, {
  1611. h: {location: currentOffset.left},
  1612. v: {location: currentOffset.top}
  1613. });
  1614. if (!options)
  1615. return result;
  1616. var my = normalizeAlign(options.my),
  1617. at = normalizeAlign(options.at),
  1618. of = options.of || window,
  1619. offset = normalizeOffset(options.offset),
  1620. collision = normalizeCollision(options.collision),
  1621. boundaryOffset = normalizeOffset(options.boundaryOffset);
  1622. var h = {
  1623. mySize: $what.outerWidth(),
  1624. myAlign: my.h,
  1625. atAlign: at.h,
  1626. offset: offset.h,
  1627. collision: collision.h,
  1628. boundaryOffset: boundaryOffset.h
  1629. };
  1630. var v = {
  1631. mySize: $what.outerHeight(),
  1632. myAlign: my.v,
  1633. atAlign: at.v,
  1634. offset: offset.v,
  1635. collision: collision.v,
  1636. boundaryOffset: boundaryOffset.v
  1637. };
  1638. if (of.preventDefault) {
  1639. h.atLocation = of.pageX;
  1640. v.atLocation = of.pageY;
  1641. h.atSize = 0;
  1642. v.atSize = 0
  1643. }
  1644. else {
  1645. of = $(of);
  1646. if ($.isWindow(of[0])) {
  1647. h.atLocation = of.scrollLeft();
  1648. v.atLocation = of.scrollTop();
  1649. h.atSize = of.width();
  1650. v.atSize = of.height()
  1651. }
  1652. else if (of[0].nodeType === 9) {
  1653. h.atLocation = 0;
  1654. v.atLocation = 0;
  1655. h.atSize = of.width();
  1656. v.atSize = of.height()
  1657. }
  1658. else {
  1659. var o = of.offset();
  1660. h.atLocation = o.left;
  1661. v.atLocation = o.top;
  1662. h.atSize = of.outerWidth();
  1663. v.atSize = of.outerHeight()
  1664. }
  1665. }
  1666. initMyLocation(h);
  1667. initMyLocation(v);
  1668. var bounds = function() {
  1669. var win = $(window),
  1670. windowWidth = win.width(),
  1671. windowHeight = win.height(),
  1672. left = win.scrollLeft(),
  1673. top = win.scrollTop(),
  1674. hScrollbar = document.width > document.documentElement.clientWidth,
  1675. vScrollbar = document.height > document.documentElement.clientHeight,
  1676. hZoomLevel = DX.support.touch ? document.documentElement.clientWidth / (vScrollbar ? windowWidth - scrollbarWidth : windowWidth) : 1,
  1677. vZoomLevel = DX.support.touch ? document.documentElement.clientHeight / (hScrollbar ? windowHeight - scrollbarWidth : windowHeight) : 1;
  1678. if (scrollbarWidth === undefined)
  1679. scrollbarWidth = calculateScrollbarWidth();
  1680. return {
  1681. h: {
  1682. min: left + h.boundaryOffset,
  1683. max: left + windowWidth / hZoomLevel - h.mySize - h.boundaryOffset
  1684. },
  1685. v: {
  1686. min: top + v.boundaryOffset,
  1687. max: top + windowHeight / vZoomLevel - v.mySize - v.boundaryOffset
  1688. }
  1689. }
  1690. }();
  1691. h.oversize = calculateOversize(h, bounds.h);
  1692. v.oversize = calculateOversize(v, bounds.v);
  1693. if (decolliders[h.collision])
  1694. result.h[h.collision] = decolliders[h.collision](h, bounds.h);
  1695. if (decolliders[v.collision])
  1696. result.v[v.collision] = decolliders[v.collision](v, bounds.v);
  1697. $.extend(true, result, {
  1698. h: {
  1699. location: Math.round(h.myLocation),
  1700. oversize: Math.round(h.oversize)
  1701. },
  1702. v: {
  1703. location: Math.round(v.myLocation),
  1704. oversize: Math.round(v.oversize)
  1705. }
  1706. });
  1707. return result
  1708. };
  1709. var position = function(what, options) {
  1710. var $what = $(what);
  1711. if (!options)
  1712. return $what.offset();
  1713. DX.translator.resetPosition($what);
  1714. var offset = $what.offset(),
  1715. targetPosition = options.h && options.v ? options : calculatePosition($what, options);
  1716. DX.translator.move($what, {
  1717. left: Math.round(targetPosition.h.location - offset.left),
  1718. top: Math.round(targetPosition.v.location - offset.top)
  1719. });
  1720. return targetPosition
  1721. };
  1722. $.extend(DX, {
  1723. calculatePosition: calculatePosition,
  1724. position: position,
  1725. inverseAlign: inverseAlign
  1726. });
  1727. var calculateScrollbarWidth = function() {
  1728. var $scrollDiv = $("<div>").css({
  1729. width: 100,
  1730. height: 100,
  1731. overflow: "scroll",
  1732. position: "absolute",
  1733. top: -9999
  1734. }).appendTo($("body")),
  1735. result = $scrollDiv.get(0).offsetWidth - $scrollDiv.get(0).clientWidth;
  1736. $scrollDiv.remove();
  1737. return result
  1738. }
  1739. })(jQuery, DevExpress);
  1740. /*! Module core, file action.js */
  1741. (function($, DX, undefined) {
  1742. var actionExecutors = {};
  1743. var registerExecutor = function(name, executor) {
  1744. if ($.isPlainObject(name)) {
  1745. $.each(name, registerExecutor);
  1746. return
  1747. }
  1748. actionExecutors[name] = executor
  1749. };
  1750. var unregisterExecutor = function(name) {
  1751. var args = $.makeArray(arguments);
  1752. $.each(args, function() {
  1753. delete actionExecutors[this]
  1754. })
  1755. };
  1756. registerExecutor({
  1757. func: {execute: function(e) {
  1758. if ($.isFunction(e.action)) {
  1759. e.result = e.action.apply(e.context, e.args);
  1760. e.handled = true
  1761. }
  1762. }},
  1763. url: {execute: function(e) {
  1764. if (typeof e.action === "string" && e.action.charAt(0) !== "#")
  1765. document.location = e.action
  1766. }},
  1767. hash: {execute: function(e) {
  1768. if (typeof e.action === "string" && e.action.charAt(0) === "#")
  1769. document.location.hash = e.action
  1770. }}
  1771. });
  1772. var Action = DX.Class.inherit({
  1773. ctor: function(action, config) {
  1774. config = config || {};
  1775. this._action = action || $.noop;
  1776. this._context = config.context || window;
  1777. this._beforeExecute = config.beforeExecute || $.noop;
  1778. this._afterExecute = config.afterExecute || $.noop;
  1779. this._component = config.component;
  1780. this._excludeValidators = config.excludeValidators;
  1781. this._validatingTargetName = config.validatingTargetName
  1782. },
  1783. execute: function() {
  1784. var e = {
  1785. action: this._action,
  1786. args: Array.prototype.slice.call(arguments),
  1787. context: this._context,
  1788. component: this._component,
  1789. validatingTargetName: this._validatingTargetName,
  1790. cancel: false,
  1791. handled: false
  1792. };
  1793. if (!this._validateAction(e))
  1794. return;
  1795. this._beforeExecute.call(this._context, e);
  1796. if (e.cancel)
  1797. return;
  1798. var result = this._executeAction(e);
  1799. this._afterExecute.call(this._context, e);
  1800. return result
  1801. },
  1802. _validateAction: function(e) {
  1803. var excludeValidators = this._excludeValidators;
  1804. $.each(actionExecutors, function(name, executor) {
  1805. if (excludeValidators && $.inArray(name, excludeValidators) > -1)
  1806. return;
  1807. if (executor.validate)
  1808. executor.validate(e);
  1809. if (e.cancel)
  1810. return false
  1811. });
  1812. return !e.cancel
  1813. },
  1814. _executeAction: function(e) {
  1815. var result;
  1816. $.each(actionExecutors, function(index, executor) {
  1817. if (executor.execute)
  1818. executor.execute(e);
  1819. if (e.handled) {
  1820. result = e.result;
  1821. return false
  1822. }
  1823. });
  1824. return result
  1825. }
  1826. });
  1827. $.extend(DX, {
  1828. registerActionExecutor: registerExecutor,
  1829. unregisterActionExecutor: unregisterExecutor,
  1830. Action: Action
  1831. });
  1832. DX.__internals = {actionExecutors: actionExecutors}
  1833. })(jQuery, DevExpress);
  1834. /*! Module core, file translator.js */
  1835. (function($, DX, undefined) {
  1836. var support = DX.support,
  1837. TRANSLATOR_DATA_KEY = "dxTranslator",
  1838. TRANSFORM_MATRIX_REGEX = /matrix(3d)?\((.+?)\)/,
  1839. TRANSLATE_REGEX = /translate(?:3d)?\((.+?)\)/;
  1840. var locate = function($element) {
  1841. var result,
  1842. position,
  1843. finalPosition;
  1844. if (support.transform3d) {
  1845. var translate = getTranslate($element);
  1846. result = {
  1847. left: translate.x,
  1848. top: translate.y
  1849. }
  1850. }
  1851. else {
  1852. var originalTop = $element.css("top"),
  1853. originalLeft = $element.css("left");
  1854. position = $element.position();
  1855. $element.css({
  1856. transform: "none",
  1857. top: 0,
  1858. left: 0
  1859. });
  1860. clearCache($element);
  1861. finalPosition = $element.position();
  1862. result = {
  1863. left: position.left - finalPosition.left || parseInt(originalLeft) || 0,
  1864. top: position.top - finalPosition.top || parseInt(originalTop) || 0
  1865. };
  1866. $element.css({
  1867. top: originalTop,
  1868. left: originalLeft
  1869. })
  1870. }
  1871. return result
  1872. };
  1873. var move = function($element, position) {
  1874. if (!support.transform3d) {
  1875. $element.css(position);
  1876. return
  1877. }
  1878. var translate = getTranslate($element),
  1879. left = position.left,
  1880. top = position.top;
  1881. if (left !== undefined)
  1882. translate.x = left || 0;
  1883. if (top !== undefined)
  1884. translate.y = top || 0;
  1885. $element.css({transform: getTranslateCss(translate)});
  1886. if (isPersentValue(left) || isPersentValue(top))
  1887. clearCache($element)
  1888. };
  1889. var isPersentValue = function(value) {
  1890. return $.type(value) === "string" && value[value.length - 1] === "%"
  1891. };
  1892. var getTranslate = function($element) {
  1893. var result = $element.data(TRANSLATOR_DATA_KEY);
  1894. if (!result) {
  1895. var transformValue = $element.css("transform") || getTranslateCss({
  1896. x: 0,
  1897. y: 0
  1898. }),
  1899. matrix = transformValue.match(TRANSFORM_MATRIX_REGEX),
  1900. is3D = matrix && matrix[1];
  1901. if (matrix) {
  1902. matrix = matrix[2].split(",");
  1903. if (is3D === "3d")
  1904. matrix = matrix.slice(12, 15);
  1905. else {
  1906. matrix.push(0);
  1907. matrix = matrix.slice(4, 7)
  1908. }
  1909. }
  1910. else
  1911. matrix = [0, 0, 0];
  1912. result = {
  1913. x: parseFloat(matrix[0]),
  1914. y: parseFloat(matrix[1]),
  1915. z: parseFloat(matrix[2])
  1916. };
  1917. cacheTranslate($element, result)
  1918. }
  1919. return result
  1920. };
  1921. var cacheTranslate = function($element, translate) {
  1922. $element.data(TRANSLATOR_DATA_KEY, translate)
  1923. };
  1924. var clearCache = function($element) {
  1925. $element.removeData(TRANSLATOR_DATA_KEY)
  1926. };
  1927. var resetPosition = function($element) {
  1928. $element.css({
  1929. left: 0,
  1930. top: 0,
  1931. transform: "none"
  1932. });
  1933. clearCache($element)
  1934. };
  1935. var parseTranslate = function(translateString) {
  1936. var result = translateString.match(TRANSLATE_REGEX);
  1937. if (!result || !result[1])
  1938. return;
  1939. result = result[1].split(",");
  1940. result = {
  1941. x: parseFloat(result[0]),
  1942. y: parseFloat(result[1]),
  1943. z: parseFloat(result[2])
  1944. };
  1945. return result
  1946. };
  1947. var getTranslateCss = function(translate) {
  1948. translate.x = translate.x || 0;
  1949. translate.y = translate.y || 0;
  1950. var xValueString = isPersentValue(translate.x) ? translate.x : translate.x + "px";
  1951. var yValueString = isPersentValue(translate.y) ? translate.y : translate.y + "px";
  1952. return "translate(" + xValueString + ", " + yValueString + ")"
  1953. };
  1954. DX.translator = {
  1955. move: move,
  1956. locate: locate,
  1957. clearCache: clearCache,
  1958. parseTranslate: parseTranslate,
  1959. getTranslate: getTranslate,
  1960. getTranslateCss: getTranslateCss,
  1961. resetPosition: resetPosition
  1962. }
  1963. })(jQuery, DevExpress);
  1964. /*! Module core, file animationFrame.js */
  1965. (function($, DX, undefined) {
  1966. var FRAME_ANIMATION_STEP_TIME = 1000 / 60,
  1967. requestAnimationFrame = function(callback, element) {
  1968. return this.setTimeout(callback, FRAME_ANIMATION_STEP_TIME)
  1969. },
  1970. cancelAnimationFrame = function(requestID) {
  1971. return this.clearTimeout(requestID)
  1972. },
  1973. nativeRequestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame,
  1974. nativeCancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.oCancelAnimationFrame || window.msCancelAnimationFrame;
  1975. if (nativeRequestAnimationFrame && nativeCancelAnimationFrame) {
  1976. requestAnimationFrame = nativeRequestAnimationFrame;
  1977. cancelAnimationFrame = nativeCancelAnimationFrame
  1978. }
  1979. if (nativeRequestAnimationFrame && !nativeCancelAnimationFrame) {
  1980. var cancelledRequests = {};
  1981. requestAnimationFrame = function(callback) {
  1982. var requestId = nativeRequestAnimationFrame.call(window, function() {
  1983. try {
  1984. if (requestId in cancelledRequests)
  1985. return;
  1986. callback.apply(this, arguments)
  1987. }
  1988. finally {
  1989. delete cancelledRequests[requestId]
  1990. }
  1991. });
  1992. return requestId
  1993. };
  1994. cancelAnimationFrame = function(requestId) {
  1995. cancelledRequests[requestId] = true
  1996. }
  1997. }
  1998. requestAnimationFrame = $.proxy(requestAnimationFrame, window);
  1999. cancelAnimationFrame = $.proxy(cancelAnimationFrame, window);
  2000. $.extend(DX, {
  2001. requestAnimationFrame: requestAnimationFrame,
  2002. cancelAnimationFrame: cancelAnimationFrame
  2003. })
  2004. })(jQuery, DevExpress);
  2005. /*! Module core, file animator.js */
  2006. (function($, DX, undefined) {
  2007. DX.Animator = DX.Class.inherit({
  2008. ctor: function() {
  2009. this._finished = true;
  2010. this._stopped = false
  2011. },
  2012. start: function() {
  2013. this._stopped = false;
  2014. this._finished = false;
  2015. this._stepCore()
  2016. },
  2017. stop: function() {
  2018. this._stopped = true
  2019. },
  2020. _stepCore: function() {
  2021. if (this._isStopped()) {
  2022. this._stop();
  2023. return
  2024. }
  2025. if (this._isFinished()) {
  2026. this._finished = true;
  2027. this._complete();
  2028. return
  2029. }
  2030. this._step();
  2031. DX.requestAnimationFrame.call(window, $.proxy(this._stepCore, this))
  2032. },
  2033. _step: DX.abstract,
  2034. _isFinished: $.noop,
  2035. _stop: $.noop,
  2036. _complete: $.noop,
  2037. _isStopped: function() {
  2038. return this._stopped
  2039. },
  2040. inProgress: function() {
  2041. return !(this._stopped || this._finished)
  2042. }
  2043. })
  2044. })(jQuery, DevExpress);
  2045. /*! Module core, file fx.js */
  2046. (function($, DX, undefined) {
  2047. var translator = DX.translator,
  2048. support = DX.support,
  2049. transitionEndEventName = support.transitionEndEventName + ".dxFX";
  2050. var CSS_TRANSITION_EASING_REGEX = /cubic-bezier\((\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\)/,
  2051. RELATIVE_VALUE_REGEX = /^([+-])=(.*)/i,
  2052. ANIM_DATA_KEY = "dxAnimData",
  2053. ANIM_QUEUE_KEY = "dxAnimQueue",
  2054. TRANSFORM_PROP = "transform";
  2055. var TransitionAnimationStrategy = {
  2056. animate: function($element, config) {
  2057. var that = this,
  2058. deferred = $.Deferred();
  2059. config.transitionAnimation = {finish: function() {
  2060. that._cleanup($element, config);
  2061. deferred.resolveWith($element, [config, $element])
  2062. }};
  2063. this._startAnimation($element, config);
  2064. this._completeAnimationCallback($element, config).done(function() {
  2065. config.transitionAnimation.finish()
  2066. });
  2067. if (!config.duration)
  2068. config.transitionAnimation.finish();
  2069. return deferred.promise()
  2070. },
  2071. _completeAnimationCallback: function($element, config) {
  2072. var startTime = $.now() + config.delay,
  2073. deferred = $.Deferred(),
  2074. transitionEndFired = $.Deferred(),
  2075. simulatedTransitionEndFired = $.Deferred();
  2076. $element.one(transitionEndEventName, function(e) {
  2077. if ($.now() - startTime >= config.duration)
  2078. transitionEndFired.reject()
  2079. });
  2080. config.transitionAnimation.simulatedEndEventTimer = setTimeout(function() {
  2081. simulatedTransitionEndFired.reject()
  2082. }, config.duration + config.delay);
  2083. $.when(transitionEndFired, simulatedTransitionEndFired).fail($.proxy(function() {
  2084. deferred.resolve()
  2085. }, this));
  2086. return deferred.promise()
  2087. },
  2088. _startAnimation: function($element, config) {
  2089. $element.css("transform");
  2090. $element.css({
  2091. transitionProperty: "all",
  2092. transitionDelay: config.delay + "ms",
  2093. transitionDuration: config.duration + "ms",
  2094. transitionTimingFunction: config.easing
  2095. });
  2096. setProps($element, config.to)
  2097. },
  2098. _cleanup: function($element, config) {
  2099. $element.css("transition", "none").off(transitionEndEventName);
  2100. clearTimeout(config.transitionAnimation.simulatedEndEventTimer)
  2101. },
  2102. stop: function($element, config, jumpToEnd) {
  2103. if (!config)
  2104. return;
  2105. if (jumpToEnd)
  2106. config.transitionAnimation.finish();
  2107. else {
  2108. $.each(config.to, function(key) {
  2109. $element.css(key, $element.css(key))
  2110. });
  2111. this._cleanup($element, config)
  2112. }
  2113. }
  2114. };
  2115. var FrameAnimationStrategy = {
  2116. animate: function($element, config) {
  2117. var deferred = $.Deferred(),
  2118. that = this;
  2119. if (!config)
  2120. return deferred.reject().promise();
  2121. $.each(config.to, function(prop) {
  2122. if (config.from[prop] === undefined)
  2123. config.from[prop] = that._normalizeValue($element.css(prop))
  2124. });
  2125. if (config.to[TRANSFORM_PROP]) {
  2126. config.from[TRANSFORM_PROP] = that._parseTransform(config.from[TRANSFORM_PROP]);
  2127. config.to[TRANSFORM_PROP] = that._parseTransform(config.to[TRANSFORM_PROP])
  2128. }
  2129. config.frameAnimation = {
  2130. to: config.to,
  2131. from: config.from,
  2132. currentValue: config.from,
  2133. easing: convertTransitionTimingFuncToJQueryEasing(config.easing),
  2134. duration: config.duration,
  2135. startTime: (new Date).valueOf(),
  2136. finish: function() {
  2137. this.currentValue = this.to;
  2138. this.draw();
  2139. deferred.resolve()
  2140. },
  2141. draw: function() {
  2142. var currentValue = $.extend({}, this.currentValue);
  2143. if (currentValue[TRANSFORM_PROP])
  2144. currentValue[TRANSFORM_PROP] = $.map(currentValue[TRANSFORM_PROP], function(value, prop) {
  2145. if (prop === "translate")
  2146. return translator.getTranslateCss(value);
  2147. else if (prop === "scale")
  2148. return "scale(" + value + ")";
  2149. else if (prop.substr(0, prop.length - 1) === "rotate")
  2150. return prop + "(" + value + "deg)"
  2151. }).join(" ");
  2152. $element.css(currentValue)
  2153. }
  2154. };
  2155. if (config.delay) {
  2156. config.frameAnimation.startTime += config.delay;
  2157. config.frameAnimation.delayTimeout = setTimeout(function() {
  2158. that._animationStep($element, config)
  2159. }, config.delay)
  2160. }
  2161. else
  2162. that._animationStep($element, config);
  2163. return deferred.promise()
  2164. },
  2165. _parseTransform: function(transformString) {
  2166. var result = {};
  2167. $.each(transformString.match(/(\w|\d)+\([^\)]*\)\s*/g), function(i, part) {
  2168. var translateData = translator.parseTranslate(part),
  2169. scaleData = part.match(/scale\((.+?)\)/),
  2170. rotateData = part.match(/(rotate.)\((.+)deg\)/);
  2171. if (translateData)
  2172. result.translate = translateData;
  2173. if (scaleData && scaleData[1])
  2174. result.scale = parseFloat(scaleData[1]);
  2175. if (rotateData && rotateData[1])
  2176. result[rotateData[1]] = parseFloat(rotateData[2])
  2177. });
  2178. return result
  2179. },
  2180. stop: function($element, config, jumpToEnd) {
  2181. var frameAnimation = config && config.frameAnimation;
  2182. if (!frameAnimation)
  2183. return;
  2184. clearTimeout(frameAnimation.delayTimeout);
  2185. if (jumpToEnd)
  2186. frameAnimation.finish();
  2187. delete config.frameAnimation
  2188. },
  2189. _animationStep: function($element, config) {
  2190. var frameAnimation = config && config.frameAnimation;
  2191. if (!frameAnimation)
  2192. return;
  2193. var now = (new Date).valueOf();
  2194. if (now >= frameAnimation.startTime + frameAnimation.duration) {
  2195. frameAnimation.finish();
  2196. return
  2197. }
  2198. frameAnimation.currentValue = this._calcStepValue(frameAnimation, now - frameAnimation.startTime);
  2199. frameAnimation.draw();
  2200. DX.requestAnimationFrame($.proxy(function() {
  2201. this._animationStep($element, config)
  2202. }, this))
  2203. },
  2204. _calcStepValue: function(frameAnimation, currentDuration) {
  2205. var calcValueRecursively = function(from, to) {
  2206. var result = $.isArray(to) ? [] : {};
  2207. var calcEasedValue = function(propName) {
  2208. var x = currentDuration / frameAnimation.duration,
  2209. t = currentDuration,
  2210. b = 1 * from[propName],
  2211. c = to[propName] - from[propName],
  2212. d = frameAnimation.duration;
  2213. return $.easing[frameAnimation.easing](x, t, b, c, d)
  2214. };
  2215. $.each(to, function(propName, endPropValue) {
  2216. if (typeof endPropValue === "string" && parseFloat(endPropValue, 10) === false)
  2217. return true;
  2218. result[propName] = typeof endPropValue === "object" ? calcValueRecursively(from[propName], endPropValue) : calcEasedValue(propName)
  2219. });
  2220. return result
  2221. };
  2222. return calcValueRecursively(frameAnimation.from, frameAnimation.to)
  2223. },
  2224. _normalizeValue: function(value) {
  2225. var numericValue = parseFloat(value, 10);
  2226. if (numericValue === false)
  2227. return value;
  2228. return numericValue
  2229. }
  2230. };
  2231. var animationStrategies = {
  2232. transition: support.transition ? TransitionAnimationStrategy : FrameAnimationStrategy,
  2233. frame: FrameAnimationStrategy
  2234. };
  2235. var getAnimationStrategy = function(config) {
  2236. return animationStrategies[config && config.strategy || "transition"]
  2237. };
  2238. var TransitionTimingFuncMap = {
  2239. linear: "cubic-bezier(0, 0, 1, 1)",
  2240. ease: "cubic-bezier(0.25, 0.1, 0.25, 1)",
  2241. "ease-in": "cubic-bezier(0.42, 0, 1, 1)",
  2242. "ease-out": "cubic-bezier(0, 0, 0.58, 1)",
  2243. "ease-in-out": "cubic-bezier(0.42, 0, 0.58, 1)"
  2244. };
  2245. var convertTransitionTimingFuncToJQueryEasing = function(cssTransitionEasing) {
  2246. cssTransitionEasing = TransitionTimingFuncMap[cssTransitionEasing] || cssTransitionEasing;
  2247. var bezCoeffs = cssTransitionEasing.match(CSS_TRANSITION_EASING_REGEX);
  2248. if (!bezCoeffs)
  2249. return "linear";
  2250. bezCoeffs = bezCoeffs.slice(1, 5);
  2251. $.each(bezCoeffs, function(index, value) {
  2252. bezCoeffs[index] = parseFloat(value)
  2253. });
  2254. var easingName = "cubicbezier_" + bezCoeffs.join("_").replace(/\./g, "p");
  2255. if (!$.isFunction($.easing[easingName])) {
  2256. var polynomBezier = function(x1, y1, x2, y2) {
  2257. var Cx = 3 * x1,
  2258. Bx = 3 * (x2 - x1) - Cx,
  2259. Ax = 1 - Cx - Bx,
  2260. Cy = 3 * y1,
  2261. By = 3 * (y2 - y1) - Cy,
  2262. Ay = 1 - Cy - By;
  2263. var bezierX = function(t) {
  2264. return t * (Cx + t * (Bx + t * Ax))
  2265. };
  2266. var bezierY = function(t) {
  2267. return t * (Cy + t * (By + t * Ay))
  2268. };
  2269. var findXfor = function(t) {
  2270. var x = t,
  2271. i = 0,
  2272. z;
  2273. while (i < 14) {
  2274. z = bezierX(x) - t;
  2275. if (Math.abs(z) < 1e-3)
  2276. break;
  2277. x = x - z / derivativeX(x);
  2278. i++
  2279. }
  2280. return x
  2281. };
  2282. var derivativeX = function(t) {
  2283. return Cx + t * (2 * Bx + t * 3 * Ax)
  2284. };
  2285. return function(t) {
  2286. return bezierY(findXfor(t))
  2287. }
  2288. };
  2289. $.easing[easingName] = function(x, t, b, c, d) {
  2290. return c * polynomBezier(bezCoeffs[0], bezCoeffs[1], bezCoeffs[2], bezCoeffs[3])(t / d) + b
  2291. }
  2292. }
  2293. return easingName
  2294. };
  2295. var baseConfigValidator = function(config, animationType) {
  2296. $.each(["from", "to"], function() {
  2297. if (!$.isPlainObject(config[this]))
  2298. throw Error("Animation with the '" + animationType + "' type requires '" + this + "' configuration as an plain object.");
  2299. })
  2300. };
  2301. var CustomAnimationConfigurator = {setup: function($element, config){}};
  2302. var SlideAnimationConfigurator = {
  2303. validateConfig: function(config) {
  2304. baseConfigValidator(config, "slide")
  2305. },
  2306. setup: function($element, config) {
  2307. var location = translator.locate($element);
  2308. this._setUpConfig(location, config.from);
  2309. this._setUpConfig(location, config.to);
  2310. translator.clearCache($element);
  2311. if (!support.transform3d && $element.css("position") === "static")
  2312. $element.css("position", "relative")
  2313. },
  2314. _setUpConfig: function(location, config) {
  2315. config.left = "left" in config ? config.left : "+=0";
  2316. config.top = "top" in config ? config.top : "+=0";
  2317. this._initNewPosition(location, config)
  2318. },
  2319. _initNewPosition: function(location, config) {
  2320. var position = {
  2321. left: config.left,
  2322. top: config.top
  2323. };
  2324. delete config.left;
  2325. delete config.top;
  2326. var relativeValue = this._getRelativeValue(position.left);
  2327. if (relativeValue !== undefined)
  2328. position.left = relativeValue + location.left;
  2329. else
  2330. config.left = 0;
  2331. relativeValue = this._getRelativeValue(position.top);
  2332. if (relativeValue !== undefined)
  2333. position.top = relativeValue + location.top;
  2334. else
  2335. config.top = 0;
  2336. var translate = {
  2337. x: 0,
  2338. y: 0
  2339. };
  2340. if (support.transform3d)
  2341. translate = {
  2342. x: position.left,
  2343. y: position.top
  2344. };
  2345. else {
  2346. config.left = position.left;
  2347. config.top = position.top
  2348. }
  2349. config[TRANSFORM_PROP] = translator.getTranslateCss(translate)
  2350. },
  2351. _getRelativeValue: function(value) {
  2352. var relativeValue;
  2353. if (typeof value === "string" && (relativeValue = RELATIVE_VALUE_REGEX.exec(value)))
  2354. return parseInt(relativeValue[1] + "1") * relativeValue[2]
  2355. }
  2356. };
  2357. var FadeAnimationConfigurator = {setup: function($element, config) {
  2358. var from = config.from,
  2359. fromOpacity = $.isPlainObject(from) ? $element.css("opacity") : String(from),
  2360. toOpacity = String(config.to);
  2361. config.from = {opacity: fromOpacity};
  2362. config.to = {opacity: toOpacity}
  2363. }};
  2364. var PopAnimationConfigurator = {
  2365. validateConfig: function(config) {
  2366. baseConfigValidator(config, "pop")
  2367. },
  2368. setup: function($element, config) {
  2369. var from = config.from,
  2370. to = config.to,
  2371. fromOpacity = "opacity" in from ? from.opacity : $element.css("opacity"),
  2372. toOpacity = "opacity" in to ? to.opacity : 1,
  2373. fromScale = "scale" in from ? from.scale : 0,
  2374. toScale = "scale" in to ? to.scale : 1;
  2375. config.from = {opacity: fromOpacity};
  2376. var translate = translator.getTranslate($element);
  2377. config.from[TRANSFORM_PROP] = this._getCssTransform(translate, fromScale);
  2378. config.to = {opacity: toOpacity};
  2379. config.to[TRANSFORM_PROP] = this._getCssTransform(translate, toScale)
  2380. },
  2381. _getCssTransform: function(translate, scale) {
  2382. return translator.getTranslateCss(translate) + "scale(" + scale + ")"
  2383. }
  2384. };
  2385. var animationConfigurators = {
  2386. custom: CustomAnimationConfigurator,
  2387. slide: SlideAnimationConfigurator,
  2388. fade: FadeAnimationConfigurator,
  2389. pop: PopAnimationConfigurator
  2390. };
  2391. var getAnimationConfigurator = function(type) {
  2392. var result = animationConfigurators[type];
  2393. if (!result)
  2394. throw Error("Unknown animation type \"" + type + "\"");
  2395. return result
  2396. };
  2397. var defaultConfig = {
  2398. type: "custom",
  2399. from: {},
  2400. to: {},
  2401. duration: 400,
  2402. start: $.noop,
  2403. complete: $.noop,
  2404. easing: "ease",
  2405. delay: 0
  2406. };
  2407. var animate = function(element, config) {
  2408. var $element = $(element);
  2409. config = $.extend(true, {}, defaultConfig, config);
  2410. if (!$element.length)
  2411. return $.Deferred().resolve().promise();
  2412. var configurator = getAnimationConfigurator(config.type);
  2413. if ($.isFunction(configurator.validateConfig))
  2414. configurator.validateConfig(config);
  2415. return pushInAnimationQueue($element, config)
  2416. };
  2417. var pushInAnimationQueue = function($element, config) {
  2418. config.deferred = config.deferred || $.Deferred();
  2419. var queueData = getAnimQueueData($element);
  2420. writeAnimQueueData($element, queueData);
  2421. queueData.push(config);
  2422. if (!isAnimating($element))
  2423. shiftFromAnimationQueue($element, queueData);
  2424. return config.deferred.promise()
  2425. };
  2426. var getAnimQueueData = function($element) {
  2427. return $element.data(ANIM_QUEUE_KEY) || []
  2428. };
  2429. var writeAnimQueueData = function($element, queueData) {
  2430. $element.data(ANIM_QUEUE_KEY, queueData)
  2431. };
  2432. var destroyAnimQueueData = function($element) {
  2433. $element.removeData(ANIM_QUEUE_KEY)
  2434. };
  2435. var isAnimating = function($element) {
  2436. return !!$element.data(ANIM_DATA_KEY)
  2437. };
  2438. var shiftFromAnimationQueue = function($element, queueData) {
  2439. var queueData = getAnimQueueData($element);
  2440. if (!queueData.length)
  2441. return;
  2442. var config = queueData.shift();
  2443. if (queueData.length === 0)
  2444. destroyAnimQueueData($element);
  2445. executeAnimation($element, config).done(function() {
  2446. shiftFromAnimationQueue($element)
  2447. })
  2448. };
  2449. var executeAnimation = function($element, config) {
  2450. setupPosition($element, config.from);
  2451. setupPosition($element, config.to);
  2452. var configurator = getAnimationConfigurator(config.type);
  2453. configurator.setup($element, config);
  2454. $element.data(ANIM_DATA_KEY, config);
  2455. if (DX.fx.off)
  2456. config.duration = 0;
  2457. setProps($element, config.from);
  2458. config.start.apply(this, [$element, config]);
  2459. return getAnimationStrategy(config).animate($element, config).done(function() {
  2460. $element.removeData(ANIM_DATA_KEY);
  2461. config.complete.apply(this, [$element, config]);
  2462. config.deferred.resolveWith(this, [$element, config])
  2463. })
  2464. };
  2465. var setupPosition = function($element, config) {
  2466. if (!config.position)
  2467. return;
  2468. var position = DX.calculatePosition($element, config.position),
  2469. offset = $element.offset(),
  2470. currentPosition = $element.position();
  2471. $.extend(config, {
  2472. left: position.h.location - offset.left + currentPosition.left,
  2473. top: position.v.location - offset.top + currentPosition.top
  2474. });
  2475. delete config.position
  2476. };
  2477. var setProps = function($element, props) {
  2478. $.each(props, function(key, value) {
  2479. $element.css(key, value)
  2480. })
  2481. };
  2482. var stop = function(element, jumpToEnd) {
  2483. var $element = $(element),
  2484. queueData = getAnimQueueData($element);
  2485. $.each(queueData, function(_, config) {
  2486. config.duration = 0
  2487. });
  2488. var config = $element.data(ANIM_DATA_KEY);
  2489. getAnimationStrategy(config).stop($element, config, jumpToEnd);
  2490. $element.removeData(ANIM_DATA_KEY);
  2491. destroyAnimQueueData($element)
  2492. };
  2493. DX.fx = {
  2494. off: false,
  2495. animationTypes: animationConfigurators,
  2496. animate: animate,
  2497. isAnimating: isAnimating,
  2498. stop: stop
  2499. };
  2500. DX.fx.__internals = {convertTransitionTimingFuncToJQueryEasing: convertTransitionTimingFuncToJQueryEasing}
  2501. })(jQuery, DevExpress);
  2502. /*! Module core, file endpointSelector.js */
  2503. (function($, DX, undefined) {
  2504. var location = window.location,
  2505. DXPROXY_HOST = "dxproxy.devexpress.com:8000",
  2506. WIN_JS = location.protocol === "ms-appx:",
  2507. IS_DXPROXY = location.host === DXPROXY_HOST,
  2508. IS_LOCAL = isLocalHostName(location.hostname);
  2509. function isLocalHostName(url) {
  2510. return /^(localhost$|127\.)/i.test(url)
  2511. }
  2512. var extractProxyAppId = function() {
  2513. return location.pathname.split("/")[1]
  2514. };
  2515. var formatProxyUrl = function(localUrl) {
  2516. var urlData = DX.parseUrl(localUrl);
  2517. if (!isLocalHostName(urlData.hostname))
  2518. return localUrl;
  2519. return "http://" + DXPROXY_HOST + "/" + extractProxyAppId() + "_" + urlData.port + urlData.pathname + urlData.search
  2520. };
  2521. var EndpointSelector = DX.EndpointSelector = function(config) {
  2522. this.config = config
  2523. };
  2524. EndpointSelector.prototype = {urlFor: function(key) {
  2525. var bag = this.config[key];
  2526. if (!bag)
  2527. throw Error("Unknown endpoint key");
  2528. if (IS_DXPROXY)
  2529. return formatProxyUrl(bag.local);
  2530. if (bag.production)
  2531. if (WIN_JS && !Debug.debuggerEnabled || !WIN_JS && !IS_LOCAL)
  2532. return bag.production;
  2533. return bag.local
  2534. }}
  2535. })(jQuery, DevExpress);
  2536. /*! Module core, file formatHelper.js */
  2537. (function($, DX, undefined) {
  2538. var utils = DX.utils;
  2539. DX.NumericFormat = {
  2540. currency: 'C',
  2541. fixedpoint: 'N',
  2542. exponential: '',
  2543. percent: 'P',
  2544. decimal: 'D'
  2545. };
  2546. DX.LargeNumberFormatPostfixes = {
  2547. 1: 'K',
  2548. 2: 'M',
  2549. 3: 'B',
  2550. 4: 'T'
  2551. };
  2552. var MAX_LARGE_NUMBER_POWER = 4,
  2553. DECIMAL_BASE = 10;
  2554. DX.LargeNumberFormatPowers = {
  2555. largenumber: 'auto',
  2556. thousands: 1,
  2557. millions: 2,
  2558. billions: 3,
  2559. trillions: 4
  2560. };
  2561. DX.DateTimeFormat = {
  2562. longdate: 'D',
  2563. longtime: 'T',
  2564. monthandday: 'M',
  2565. monthandyear: 'Y',
  2566. quarterandyear: 'qq',
  2567. shortdate: 'd',
  2568. shorttime: 't',
  2569. millisecond: 'fff',
  2570. second: 'T',
  2571. minute: 't',
  2572. hour: 't',
  2573. day: 'dd',
  2574. week: 'dd',
  2575. month: 'MMMM',
  2576. quarter: 'qq',
  2577. year: 'yyyy',
  2578. longdatelongtime: 'D',
  2579. shortdateshorttime: 'd'
  2580. };
  2581. DX.formatHelper = {
  2582. defaultQuarterFormat: 'Q{0}',
  2583. romanDigits: ['I', 'II', 'III', 'IV'],
  2584. _addFormatSeparator: function(format1, format2) {
  2585. var separator = ' ';
  2586. if (format2)
  2587. return format1 + separator + format2;
  2588. return format1
  2589. },
  2590. _getDateTimeFormatPattern: function(dateTimeFormat) {
  2591. return Globalize.findClosestCulture().calendar.patterns[DX.DateTimeFormat[dateTimeFormat.toLowerCase()]]
  2592. },
  2593. _isDateFormatContains: function(format) {
  2594. var result = false;
  2595. $.each(DX.DateTimeFormat, function(key, value) {
  2596. result = key === format.toLowerCase();
  2597. return !result
  2598. });
  2599. return result
  2600. },
  2601. getQuarter: function(month) {
  2602. return Math.floor(month / 3)
  2603. },
  2604. getFirstQuarterMonth: function(month) {
  2605. return this.getQuarter(month) * 3
  2606. },
  2607. _getQuarterString: function(date, format) {
  2608. var quarter = this.getQuarter(date.getMonth());
  2609. switch (format) {
  2610. case'q':
  2611. return this.romanDigits[quarter];
  2612. case'qq':
  2613. return utils.stringFormat(this.defaultQuarterFormat, this.romanDigits[quarter]);
  2614. case'Q':
  2615. return (quarter + 1).toString();
  2616. case'QQ':
  2617. return utils.stringFormat(this.defaultQuarterFormat, (quarter + 1).toString())
  2618. }
  2619. return ''
  2620. },
  2621. _formatCustomString: function(value, format) {
  2622. var regExp = /qq|q|QQ|Q/g,
  2623. quarterFormat,
  2624. result = '',
  2625. index = 0;
  2626. regExp.lastIndex = 0;
  2627. while (index < format.length) {
  2628. quarterFormat = regExp.exec(format);
  2629. if (!quarterFormat || quarterFormat.index > index)
  2630. result += Globalize.format(value, format.substring(index, quarterFormat ? quarterFormat.index : format.length));
  2631. if (quarterFormat) {
  2632. result += this._getQuarterString(value, quarterFormat[0]);
  2633. index = quarterFormat.index + quarterFormat[0].length
  2634. }
  2635. else
  2636. index = format.length
  2637. }
  2638. return result
  2639. },
  2640. _parseNumberFormatString: function(format) {
  2641. var formatList,
  2642. formatObject = {};
  2643. if (!format || typeof format !== 'string')
  2644. return;
  2645. formatList = format.toLowerCase().split(' ');
  2646. $.each(formatList, function(index, value) {
  2647. if (value in DX.NumericFormat)
  2648. formatObject.formatType = value;
  2649. else if (value in DX.LargeNumberFormatPowers)
  2650. formatObject.power = DX.LargeNumberFormatPowers[value]
  2651. });
  2652. if (formatObject.power && !formatObject.formatType)
  2653. formatObject.formatType = 'fixedpoint';
  2654. if (formatObject.formatType)
  2655. return formatObject
  2656. },
  2657. _calculateNumberPower: function(value, base, minPower, maxPower) {
  2658. var number = Math.abs(value);
  2659. var power = 0;
  2660. if (number > 1)
  2661. while (number && number >= base && (maxPower === undefined || power < maxPower)) {
  2662. power++;
  2663. number = number / base
  2664. }
  2665. else if (number > 0 && number < 1)
  2666. while (number < 1 && (minPower === undefined || power > minPower)) {
  2667. power--;
  2668. number = number * base
  2669. }
  2670. return power
  2671. },
  2672. _getNumberByPower: function(number, power, base) {
  2673. var result = number;
  2674. while (power > 0) {
  2675. result = result / base;
  2676. power--
  2677. }
  2678. while (power < 0) {
  2679. result = result * base;
  2680. power++
  2681. }
  2682. return result
  2683. },
  2684. _formatNumber: function(value, formatObject, precision) {
  2685. var powerPostfix;
  2686. if (formatObject.power === 'auto')
  2687. formatObject.power = this._calculateNumberPower(value, 1000, 0, MAX_LARGE_NUMBER_POWER);
  2688. if (formatObject.power)
  2689. value = this._getNumberByPower(value, formatObject.power, 1000);
  2690. powerPostfix = DX.LargeNumberFormatPostfixes[formatObject.power] || '';
  2691. return this._formatNumberCore(value, formatObject.formatType, precision) + powerPostfix
  2692. },
  2693. _formatNumberExponential: function(value, precision) {
  2694. var power = this._calculateNumberPower(value, DECIMAL_BASE),
  2695. number = this._getNumberByPower(value, power, DECIMAL_BASE),
  2696. powString;
  2697. precision = precision === undefined ? 1 : precision;
  2698. if (number.toFixed(precision || 0) >= DECIMAL_BASE) {
  2699. power++;
  2700. number = number / DECIMAL_BASE
  2701. }
  2702. powString = (power >= 0 ? '+' : '') + power.toString();
  2703. return this._formatNumberCore(number, 'fixedpoint', precision) + 'E' + powString
  2704. },
  2705. _formatNumberCore: function(value, format, precision) {
  2706. if (format === 'exponential')
  2707. return this._formatNumberExponential(value, precision);
  2708. else
  2709. return Globalize.format(value, DX.NumericFormat[format] + (utils.isNumber(precision) ? precision : 0))
  2710. },
  2711. _formatDate: function(date, format, formatString) {
  2712. var resultFormat = DX.DateTimeFormat[format.toLowerCase()];
  2713. format = format.toLowerCase();
  2714. if (format === 'quarterandyear')
  2715. resultFormat = this._getQuarterString(date, resultFormat) + ' yyyy';
  2716. if (format === 'quarter')
  2717. return this._getQuarterString(date, resultFormat);
  2718. if (format === 'longdatelongtime')
  2719. return this._formatDate(date, 'longdate') + ' ' + this._formatDate(date, 'longtime');
  2720. if (format === 'shortdateshorttime')
  2721. return this._formatDate(date, 'shortDate') + ' ' + this._formatDate(date, 'shortTime');
  2722. return Globalize.format(date, resultFormat)
  2723. },
  2724. format: function(value, format, precision) {
  2725. if (format && format.format)
  2726. if (format.dateType)
  2727. return this._formatDateEx(value, format);
  2728. else if (utils.isNumber(value) && isFinite(value))
  2729. return this._formatNumberEx(value, format);
  2730. return this._format(value, format, precision)
  2731. },
  2732. _format: function(value, format, precision) {
  2733. var numberFormatObject;
  2734. if (!utils.isString(format) || format === '' || !utils.isNumber(value) && !utils.isDate(value))
  2735. return utils.isDefined(value) ? value.toString() : '';
  2736. numberFormatObject = this._parseNumberFormatString(format);
  2737. if (utils.isNumber(value) && numberFormatObject)
  2738. return this._formatNumber(value, numberFormatObject, precision);
  2739. if (utils.isDate(value) && this._isDateFormatContains(format))
  2740. return this._formatDate(value, format);
  2741. if (!numberFormatObject && !this._isDateFormatContains(format))
  2742. return this._formatCustomString(value, format)
  2743. },
  2744. _formatNumberEx: function(value, formatInfo) {
  2745. var that = this,
  2746. numericFormatType = DX.NumericFormat[formatInfo.format.toLowerCase()],
  2747. numberFormat = Globalize.culture().numberFormat,
  2748. currencyFormat = formatInfo.currencyCulture && Globalize.cultures[formatInfo.currencyCulture] ? Globalize.cultures[formatInfo.currencyCulture].numberFormat.currency : numberFormat.currency,
  2749. percentFormat = numberFormat.percent,
  2750. formatSettings = that._getUnitFormatSettings(value, formatInfo),
  2751. unit = formatSettings.unit,
  2752. precision = formatSettings.precision,
  2753. showTrailingZeros = formatSettings.showTrailingZeros,
  2754. includeGroupSeparator = formatSettings.includeGroupSeparator,
  2755. groupSymbol = numberFormat[","],
  2756. floatingSymbol = numberFormat["."],
  2757. number,
  2758. isNegative,
  2759. pattern,
  2760. currentFormat,
  2761. regexParts = /n|\$|-|%/g,
  2762. result = "";
  2763. if (!utils.isDefined(value))
  2764. return '';
  2765. value = that._applyUnitToValue(value, unit);
  2766. number = Math.abs(value);
  2767. isNegative = value < 0;
  2768. switch (numericFormatType) {
  2769. case DX.NumericFormat.decimal:
  2770. pattern = "n";
  2771. number = Math[isNegative ? "ceil" : "floor"](number);
  2772. if (precision > 0) {
  2773. var str = "" + number;
  2774. for (var i = str.length; i < precision; i += 1)
  2775. str = "0" + str;
  2776. number = str
  2777. }
  2778. if (isNegative)
  2779. number = "-" + number;
  2780. break;
  2781. case DX.NumericFormat.fixedpoint:
  2782. currentFormat = numberFormat;
  2783. case DX.NumericFormat.currency:
  2784. currentFormat = currentFormat || currencyFormat;
  2785. case DX.NumericFormat.percent:
  2786. currentFormat = currentFormat || percentFormat;
  2787. pattern = isNegative ? currentFormat.pattern[0] : currentFormat.pattern[1] || "n";
  2788. number = Globalize.format(number * (numericFormatType === DX.NumericFormat.percent ? 100 : 1), "N" + precision);
  2789. if (!showTrailingZeros)
  2790. number = that._excludeTrailingZeros(number, floatingSymbol);
  2791. if (!includeGroupSeparator)
  2792. number = number.replace(new RegExp('\\' + groupSymbol, 'g'), '');
  2793. break;
  2794. case DX.NumericFormat.exponential:
  2795. return that._formatNumberExponential(value, precision);
  2796. default:
  2797. throw"Illegal numeric format: '" + numericFormatType + "'";
  2798. }
  2799. for (; ; ) {
  2800. var lastIndex = regexParts.lastIndex,
  2801. matches = regexParts.exec(pattern);
  2802. result += pattern.slice(lastIndex, matches ? matches.index : pattern.length);
  2803. if (matches)
  2804. switch (matches[0]) {
  2805. case"-":
  2806. if (/[1-9]/.test(number))
  2807. result += numberFormat["-"];
  2808. break;
  2809. case"$":
  2810. result += currencyFormat.symbol;
  2811. break;
  2812. case"%":
  2813. result += percentFormat.symbol;
  2814. break;
  2815. case"n":
  2816. result += number + unit;
  2817. break
  2818. }
  2819. else
  2820. break
  2821. }
  2822. return (formatInfo.plus && value > 0 ? "+" : '') + result
  2823. },
  2824. _excludeTrailingZeros: function(strValue, floatingSymbol) {
  2825. var floatingIndex = strValue.indexOf(floatingSymbol),
  2826. stopIndex,
  2827. i;
  2828. if (floatingIndex < 0)
  2829. return strValue;
  2830. stopIndex = strValue.length;
  2831. for (i = stopIndex - 1; i >= floatingIndex && (strValue[i] === '0' || i === floatingIndex); i--)
  2832. stopIndex--;
  2833. return strValue.substring(0, stopIndex)
  2834. },
  2835. _getUnitFormatSettings: function(value, formatInfo) {
  2836. var unit = formatInfo.unit || '',
  2837. precision = formatInfo.precision || 0,
  2838. includeGroupSeparator = formatInfo.includeGroupSeparator || false,
  2839. showTrailingZeros = formatInfo.showTrailingZeros === undefined ? true : formatInfo.showTrailingZeros,
  2840. significantDigits = formatInfo.significantDigits || 1,
  2841. absValue;
  2842. if (unit.toLowerCase() === 'auto') {
  2843. showTrailingZeros = false;
  2844. absValue = Math.abs(value);
  2845. if (significantDigits < 1)
  2846. significantDigits = 1;
  2847. if (absValue >= 1000000000) {
  2848. unit = 'B';
  2849. absValue /= 1000000000
  2850. }
  2851. else if (absValue >= 1000000) {
  2852. unit = 'M';
  2853. absValue /= 1000000
  2854. }
  2855. else if (absValue >= 1000) {
  2856. unit = 'K';
  2857. absValue /= 1000
  2858. }
  2859. else
  2860. unit = '';
  2861. if (absValue == 0)
  2862. precision = 0;
  2863. else if (absValue < 1) {
  2864. precision = significantDigits;
  2865. var smallValue = Math.pow(10, -significantDigits);
  2866. while (absValue < smallValue) {
  2867. smallValue /= 10;
  2868. precision++
  2869. }
  2870. }
  2871. else if (absValue >= 100)
  2872. precision = significantDigits - 3;
  2873. else if (absValue >= 10)
  2874. precision = significantDigits - 2;
  2875. else
  2876. precision = significantDigits - 1
  2877. }
  2878. if (precision < 0)
  2879. precision = 0;
  2880. return {
  2881. unit: unit,
  2882. precision: precision,
  2883. showTrailingZeros: showTrailingZeros,
  2884. includeGroupSeparator: includeGroupSeparator
  2885. }
  2886. },
  2887. _applyUnitToValue: function(value, unit) {
  2888. if (unit == 'B')
  2889. return value.toFixed(1) / 1000000000;
  2890. if (unit == 'M')
  2891. return value / 1000000;
  2892. if (unit == 'K')
  2893. return value / 1000;
  2894. return value
  2895. },
  2896. _formatDateEx: function(value, formatInfo) {
  2897. var that = this,
  2898. format = formatInfo.format,
  2899. dateType = formatInfo.dateType,
  2900. calendar = Globalize.culture().calendars.standard,
  2901. time = undefined,
  2902. index,
  2903. dateStr;
  2904. format = format.toLowerCase();
  2905. if (!utils.isDefined(value))
  2906. return '';
  2907. if (dateType !== 'num' || format === 'dayofweek')
  2908. switch (format) {
  2909. case'monthyear':
  2910. return that._formatDate(value, 'monthandyear');
  2911. case'quarteryear':
  2912. return that._getQuarterString(value, 'QQ') + ' ' + value.getFullYear();
  2913. case'daymonthyear':
  2914. return that._formatDate(value, dateType + 'Date');
  2915. case'datehour':
  2916. time = new Date(value.getTime());
  2917. time.setMinutes(0);
  2918. dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
  2919. return dateType === 'timeOnly' ? that._formatDate(time, 'shorttime') : dateStr + ' ' + that._formatDate(time, 'shorttime');
  2920. case'datehourminute':
  2921. dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
  2922. return dateType === 'timeOnly' ? that._formatDate(value, 'shorttime') : dateStr + ' ' + that._formatDate(value, 'shorttime');
  2923. case'datehourminutesecond':
  2924. dateStr = dateType === 'timeOnly' ? '' : that._formatDate(value, dateType + 'Date');
  2925. return dateType === 'timeOnly' ? that._formatDate(value, 'longtime') : dateStr + ' ' + that._formatDate(value, 'longtime');
  2926. case'year':
  2927. dateStr = value.toString();
  2928. return dateType === 'abbr' ? dateStr.slice(2, 4) : dateStr;
  2929. case'quarter':
  2930. return utils.stringFormat(that.defaultQuarterFormat, value.toString());
  2931. case'month':
  2932. index = value - 1;
  2933. return dateType === 'abbr' ? calendar.months.namesAbbr[index] : calendar.months.names[index];
  2934. case'hour':
  2935. if (dateType === 'long') {
  2936. time = new Date;
  2937. time.setHours(value);
  2938. time.setMinutes(0);
  2939. return that._formatDate(time, 'shorttime')
  2940. }
  2941. else
  2942. return value.toString();
  2943. case'dayofweek':
  2944. index = utils.isString(value) ? $.inArray(value, ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']) : value;
  2945. if (dateType !== 'num')
  2946. return dateType === 'abbr' ? calendar.days.namesAbbr[index] : calendar.days.names[index];
  2947. else
  2948. return ((index - calendar.firstDay + 1 + 7) % 8).toString();
  2949. default:
  2950. return value.toString()
  2951. }
  2952. else
  2953. return value.toString()
  2954. },
  2955. getTimeFormat: function(showSecond) {
  2956. if (showSecond)
  2957. return this._getDateTimeFormatPattern('longtime');
  2958. return this._getDateTimeFormatPattern('shorttime')
  2959. },
  2960. getDateFormatByDifferences: function(dateDifferences) {
  2961. var resultFormat = '';
  2962. if (dateDifferences.millisecond)
  2963. resultFormat = DX.DateTimeFormat.millisecond;
  2964. if (dateDifferences.hour || dateDifferences.minute || dateDifferences.second)
  2965. resultFormat = this._addFormatSeparator(this.getTimeFormat(dateDifferences.second), resultFormat);
  2966. if (dateDifferences.year && dateDifferences.month && dateDifferences.day)
  2967. return this._addFormatSeparator(this._getDateTimeFormatPattern('shortdate'), resultFormat);
  2968. if (dateDifferences.year && dateDifferences.month)
  2969. return DX.DateTimeFormat['monthandyear'];
  2970. if (dateDifferences.year)
  2971. return DX.DateTimeFormat['year'];
  2972. if (dateDifferences.month && dateDifferences.day)
  2973. return this._addFormatSeparator(this._getDateTimeFormatPattern('monthandday'), resultFormat);
  2974. if (dateDifferences.month)
  2975. return DX.DateTimeFormat['month'];
  2976. if (dateDifferences.day)
  2977. return this._addFormatSeparator('dddd, dd', resultFormat);
  2978. return resultFormat
  2979. },
  2980. getDateFormatByTicks: function(ticks) {
  2981. var resultFormat,
  2982. maxDif,
  2983. currentDif,
  2984. i,
  2985. dateUnitInterval;
  2986. if (ticks.length > 1) {
  2987. maxDif = utils.getDatesDifferences(ticks[0], ticks[1]);
  2988. for (i = 1; i < ticks.length - 1; i++) {
  2989. currentDif = utils.getDatesDifferences(ticks[i], ticks[i + 1]);
  2990. if (maxDif.count < currentDif.count)
  2991. maxDif = currentDif
  2992. }
  2993. }
  2994. else
  2995. maxDif = {
  2996. year: true,
  2997. month: true,
  2998. day: true,
  2999. hour: ticks[0].getHours() > 0,
  3000. minute: ticks[0].getMinutes() > 0,
  3001. second: ticks[0].getSeconds() > 0
  3002. };
  3003. resultFormat = this.getDateFormatByDifferences(maxDif);
  3004. return resultFormat
  3005. },
  3006. getDateFormatByTickInterval: function(startValue, endValue, tickInterval) {
  3007. var resultFormat,
  3008. dateDifferences,
  3009. dateUnitInterval,
  3010. dateDifferencesConverter = {
  3011. quarter: 'month',
  3012. week: 'day'
  3013. },
  3014. correctDateDifferences = function(dateDifferences, tickInterval, value) {
  3015. switch (tickInterval) {
  3016. case'year':
  3017. dateDifferences.month = value;
  3018. case'quarter':
  3019. case'month':
  3020. dateDifferences.day = value;
  3021. case'week':
  3022. case'day':
  3023. dateDifferences.hour = value;
  3024. case'hour':
  3025. dateDifferences.minute = value;
  3026. case'minute':
  3027. dateDifferences.second = value;
  3028. case'second':
  3029. dateDifferences.millisecond = value
  3030. }
  3031. },
  3032. correctDifferencesByMaxDate = function(differences, minDate, maxDate) {
  3033. if (!maxDate.getMilliseconds() && maxDate.getSeconds()) {
  3034. if (maxDate.getSeconds() - minDate.getSeconds() === 1) {
  3035. differences.millisecond = true;
  3036. differences.second = false
  3037. }
  3038. }
  3039. else if (!maxDate.getSeconds() && maxDate.getMinutes()) {
  3040. if (maxDate.getMinutes() - minDate.getMinutes() === 1) {
  3041. differences.second = true;
  3042. differences.minute = false
  3043. }
  3044. }
  3045. else if (!maxDate.getMinutes() && maxDate.getHours()) {
  3046. if (maxDate.getHours() - minDate.getHours() === 1) {
  3047. differences.minute = true;
  3048. differences.hour = false
  3049. }
  3050. }
  3051. else if (!maxDate.getHours() && maxDate.getDate() > 1) {
  3052. if (maxDate.getDate() - minDate.getDate() === 1) {
  3053. differences.hour = true;
  3054. differences.day = false
  3055. }
  3056. }
  3057. else if (maxDate.getDate() === 1 && maxDate.getMonth()) {
  3058. if (maxDate.getMonth() - minDate.getMonth() === 1) {
  3059. differences.day = true;
  3060. differences.month = false
  3061. }
  3062. }
  3063. else if (!maxDate.getMonth() && maxDate.getFullYear())
  3064. if (maxDate.getFullYear() - minDate.getFullYear() === 1) {
  3065. differences.month = true;
  3066. differences.year = false
  3067. }
  3068. };
  3069. tickInterval = utils.isString(tickInterval) ? tickInterval.toLowerCase() : tickInterval;
  3070. dateDifferences = utils.getDatesDifferences(startValue, endValue);
  3071. if (startValue !== endValue)
  3072. correctDifferencesByMaxDate(dateDifferences, startValue > endValue ? endValue : startValue, startValue > endValue ? startValue : endValue);
  3073. dateUnitInterval = utils.getDateUnitInterval(dateDifferences);
  3074. correctDateDifferences(dateDifferences, dateUnitInterval, true);
  3075. dateUnitInterval = utils.getDateUnitInterval(tickInterval || 'second');
  3076. correctDateDifferences(dateDifferences, dateUnitInterval, false);
  3077. dateDifferences[dateDifferencesConverter[dateUnitInterval] || dateUnitInterval] = true;
  3078. resultFormat = this.getDateFormatByDifferences(dateDifferences);
  3079. return resultFormat
  3080. }
  3081. }
  3082. })(jQuery, DevExpress);
  3083. /*! Module core, file color.js */
  3084. (function(DX, undefined) {
  3085. var standardColorNames = {
  3086. aliceblue: 'f0f8ff',
  3087. antiquewhite: 'faebd7',
  3088. aqua: '00ffff',
  3089. aquamarine: '7fffd4',
  3090. azure: 'f0ffff',
  3091. beige: 'f5f5dc',
  3092. bisque: 'ffe4c4',
  3093. black: '000000',
  3094. blanchedalmond: 'ffebcd',
  3095. blue: '0000ff',
  3096. blueviolet: '8a2be2',
  3097. brown: 'a52a2a',
  3098. burlywood: 'deb887',
  3099. cadetblue: '5f9ea0',
  3100. chartreuse: '7fff00',
  3101. chocolate: 'd2691e',
  3102. coral: 'ff7f50',
  3103. cornflowerblue: '6495ed',
  3104. cornsilk: 'fff8dc',
  3105. crimson: 'dc143c',
  3106. cyan: '00ffff',
  3107. darkblue: '00008b',
  3108. darkcyan: '008b8b',
  3109. darkgoldenrod: 'b8860b',
  3110. darkgray: 'a9a9a9',
  3111. darkgreen: '006400',
  3112. darkkhaki: 'bdb76b',
  3113. darkmagenta: '8b008b',
  3114. darkolivegreen: '556b2f',
  3115. darkorange: 'ff8c00',
  3116. darkorchid: '9932cc',
  3117. darkred: '8b0000',
  3118. darksalmon: 'e9967a',
  3119. darkseagreen: '8fbc8f',
  3120. darkslateblue: '483d8b',
  3121. darkslategray: '2f4f4f',
  3122. darkturquoise: '00ced1',
  3123. darkviolet: '9400d3',
  3124. deeppink: 'ff1493',
  3125. deepskyblue: '00bfff',
  3126. dimgray: '696969',
  3127. dodgerblue: '1e90ff',
  3128. feldspar: 'd19275',
  3129. firebrick: 'b22222',
  3130. floralwhite: 'fffaf0',
  3131. forestgreen: '228b22',
  3132. fuchsia: 'ff00ff',
  3133. gainsboro: 'dcdcdc',
  3134. ghostwhite: 'f8f8ff',
  3135. gold: 'ffd700',
  3136. goldenrod: 'daa520',
  3137. gray: '808080',
  3138. green: '008000',
  3139. greenyellow: 'adff2f',
  3140. honeydew: 'f0fff0',
  3141. hotpink: 'ff69b4',
  3142. indianred: 'cd5c5c',
  3143. indigo: '4b0082',
  3144. ivory: 'fffff0',
  3145. khaki: 'f0e68c',
  3146. lavender: 'e6e6fa',
  3147. lavenderblush: 'fff0f5',
  3148. lawngreen: '7cfc00',
  3149. lemonchiffon: 'fffacd',
  3150. lightblue: 'add8e6',
  3151. lightcoral: 'f08080',
  3152. lightcyan: 'e0ffff',
  3153. lightgoldenrodyellow: 'fafad2',
  3154. lightgrey: 'd3d3d3',
  3155. lightgreen: '90ee90',
  3156. lightpink: 'ffb6c1',
  3157. lightsalmon: 'ffa07a',
  3158. lightseagreen: '20b2aa',
  3159. lightskyblue: '87cefa',
  3160. lightslateblue: '8470ff',
  3161. lightslategray: '778899',
  3162. lightsteelblue: 'b0c4de',
  3163. lightyellow: 'ffffe0',
  3164. lime: '00ff00',
  3165. limegreen: '32cd32',
  3166. linen: 'faf0e6',
  3167. magenta: 'ff00ff',
  3168. maroon: '800000',
  3169. mediumaquamarine: '66cdaa',
  3170. mediumblue: '0000cd',
  3171. mediumorchid: 'ba55d3',
  3172. mediumpurple: '9370d8',
  3173. mediumseagreen: '3cb371',
  3174. mediumslateblue: '7b68ee',
  3175. mediumspringgreen: '00fa9a',
  3176. mediumturquoise: '48d1cc',
  3177. mediumvioletred: 'c71585',
  3178. midnightblue: '191970',
  3179. mintcream: 'f5fffa',
  3180. mistyrose: 'ffe4e1',
  3181. moccasin: 'ffe4b5',
  3182. navajowhite: 'ffdead',
  3183. navy: '000080',
  3184. oldlace: 'fdf5e6',
  3185. olive: '808000',
  3186. olivedrab: '6b8e23',
  3187. orange: 'ffa500',
  3188. orangered: 'ff4500',
  3189. orchid: 'da70d6',
  3190. palegoldenrod: 'eee8aa',
  3191. palegreen: '98fb98',
  3192. paleturquoise: 'afeeee',
  3193. palevioletred: 'd87093',
  3194. papayawhip: 'ffefd5',
  3195. peachpuff: 'ffdab9',
  3196. peru: 'cd853f',
  3197. pink: 'ffc0cb',
  3198. plum: 'dda0dd',
  3199. powderblue: 'b0e0e6',
  3200. purple: '800080',
  3201. red: 'ff0000',
  3202. rosybrown: 'bc8f8f',
  3203. royalblue: '4169e1',
  3204. saddlebrown: '8b4513',
  3205. salmon: 'fa8072',
  3206. sandybrown: 'f4a460',
  3207. seagreen: '2e8b57',
  3208. seashell: 'fff5ee',
  3209. sienna: 'a0522d',
  3210. silver: 'c0c0c0',
  3211. skyblue: '87ceeb',
  3212. slateblue: '6a5acd',
  3213. slategray: '708090',
  3214. snow: 'fffafa',
  3215. springgreen: '00ff7f',
  3216. steelblue: '4682b4',
  3217. tan: 'd2b48c',
  3218. teal: '008080',
  3219. thistle: 'd8bfd8',
  3220. tomato: 'ff6347',
  3221. turquoise: '40e0d0',
  3222. violet: 'ee82ee',
  3223. violetred: 'd02090',
  3224. wheat: 'f5deb3',
  3225. white: 'ffffff',
  3226. whitesmoke: 'f5f5f5',
  3227. yellow: 'ffff00',
  3228. yellowgreen: '9acd32'
  3229. };
  3230. var standardColorTypes = [{
  3231. re: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
  3232. process: function(colorString) {
  3233. return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10)]
  3234. }
  3235. }, {
  3236. re: /^rgba\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3}),\s*(\d*\.*\d+)\)$/,
  3237. process: function(colorString) {
  3238. return [parseInt(colorString[1], 10), parseInt(colorString[2], 10), parseInt(colorString[3], 10), parseFloat(colorString[4])]
  3239. }
  3240. }, {
  3241. re: /^#(\w{2})(\w{2})(\w{2})$/,
  3242. process: function(colorString) {
  3243. return [parseInt(colorString[1], 16), parseInt(colorString[2], 16), parseInt(colorString[3], 16)]
  3244. }
  3245. }, {
  3246. re: /^#(\w{1})(\w{1})(\w{1})$/,
  3247. process: function(colorString) {
  3248. return [parseInt(colorString[1] + colorString[1], 16), parseInt(colorString[2] + colorString[2], 16), parseInt(colorString[3] + colorString[3], 16)]
  3249. }
  3250. }, {
  3251. re: /^hsv\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
  3252. process: function(colorString) {
  3253. var h = parseInt(colorString[1], 10),
  3254. s = parseInt(colorString[2], 10),
  3255. v = parseInt(colorString[3], 10),
  3256. rgb = hsvToRgb(h, s, v);
  3257. return [rgb[0], rgb[1], rgb[2], 1, [h, s, v]]
  3258. }
  3259. }, {
  3260. re: /^hsl\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
  3261. process: function(colorString) {
  3262. var h = parseInt(colorString[1], 10),
  3263. s = parseInt(colorString[2], 10),
  3264. l = parseInt(colorString[3], 10),
  3265. rgb = hslToRgb(h, s, l);
  3266. return [rgb[0], rgb[1], rgb[2], 1, null, [h, s, l]]
  3267. }
  3268. }];
  3269. function Color(value) {
  3270. this.baseColor = value;
  3271. var color;
  3272. if (value) {
  3273. color = String(value).toLowerCase().replace(/ /g, '');
  3274. color = standardColorNames[color] ? '#' + standardColorNames[color] : color;
  3275. color = parseColor(color)
  3276. }
  3277. if (!color)
  3278. this.colorIsInvalid = true;
  3279. color = color || {};
  3280. this.r = normalize(color[0]);
  3281. this.g = normalize(color[1]);
  3282. this.b = normalize(color[2]);
  3283. this.a = normalize(color[3], 1, 1);
  3284. if (color[4])
  3285. this.hsv = {
  3286. h: color[4][0],
  3287. s: color[4][1],
  3288. v: color[4][2]
  3289. };
  3290. else
  3291. this.hsv = toHsvFromRgb(this.r, this.g, this.b);
  3292. if (color[5])
  3293. this.hsl = {
  3294. h: color[5][0],
  3295. s: color[5][1],
  3296. l: color[5][2]
  3297. };
  3298. else
  3299. this.hsl = toHslFromRgb(this.r, this.g, this.b)
  3300. }
  3301. function parseColor(color) {
  3302. if (color === "transparent")
  3303. return [0, 0, 0, 0];
  3304. var result,
  3305. i = 0,
  3306. ii = standardColorTypes.length,
  3307. str;
  3308. for (; i < ii; ++i) {
  3309. str = standardColorTypes[i].re.exec(color);
  3310. if (str)
  3311. return standardColorTypes[i].process(str)
  3312. }
  3313. return null
  3314. }
  3315. function normalize(colorComponent, def, max) {
  3316. def = def || 0;
  3317. max = max || 255;
  3318. return colorComponent < 0 || isNaN(colorComponent) ? def : colorComponent > max ? max : colorComponent
  3319. }
  3320. function toHexFromRgb(r, g, b) {
  3321. return '#' + (0X01000000 | r << 16 | g << 8 | b).toString(16).slice(1)
  3322. }
  3323. function toHsvFromRgb(r, g, b) {
  3324. var max = Math.max(r, g, b),
  3325. min = Math.min(r, g, b),
  3326. delta = max - min,
  3327. H,
  3328. S,
  3329. V;
  3330. V = max;
  3331. S = max === 0 ? 0 : 1 - min / max;
  3332. if (max === min)
  3333. H = 0;
  3334. else
  3335. switch (max) {
  3336. case r:
  3337. H = 60 * ((g - b) / delta);
  3338. if (g < b)
  3339. H = H + 360;
  3340. break;
  3341. case g:
  3342. H = 60 * ((b - r) / delta) + 120;
  3343. break;
  3344. case b:
  3345. H = 60 * ((r - g) / delta) + 240;
  3346. break
  3347. }
  3348. S *= 100;
  3349. V *= 100 / 255;
  3350. return {
  3351. h: Math.round(H),
  3352. s: Math.round(S),
  3353. v: Math.round(V)
  3354. }
  3355. }
  3356. function hsvToRgb(h, s, v) {
  3357. var Vdec,
  3358. Vinc,
  3359. Vmin,
  3360. Hi,
  3361. a,
  3362. r,
  3363. g,
  3364. b;
  3365. Hi = Math.floor(h / 60);
  3366. Vmin = (100 - s) * v / 100;
  3367. a = (v - Vmin) * (h % 60 / 60);
  3368. Vinc = Vmin + a;
  3369. Vdec = v - a;
  3370. switch (Hi) {
  3371. case 0:
  3372. r = v;
  3373. g = Vinc;
  3374. b = Vmin;
  3375. break;
  3376. case 1:
  3377. r = Vdec;
  3378. g = v;
  3379. b = Vmin;
  3380. break;
  3381. case 2:
  3382. r = Vmin;
  3383. g = v;
  3384. b = Vinc;
  3385. break;
  3386. case 3:
  3387. r = Vmin;
  3388. g = Vdec;
  3389. b = v;
  3390. break;
  3391. case 4:
  3392. r = Vinc;
  3393. g = Vmin;
  3394. b = v;
  3395. break;
  3396. case 5:
  3397. r = v;
  3398. g = Vmin;
  3399. b = Vdec;
  3400. break
  3401. }
  3402. return [Math.round(r * 2.55), Math.round(g * 2.55), Math.round(b * 2.55)]
  3403. }
  3404. function calculateHue(r, g, b, delta) {
  3405. var max = Math.max(r, g, b);
  3406. switch (max) {
  3407. case r:
  3408. return (g - b) / delta + (g < b ? 6 : 0);
  3409. case g:
  3410. return (b - r) / delta + 2;
  3411. case b:
  3412. return (r - g) / delta + 4
  3413. }
  3414. }
  3415. function toHslFromRgb(r, g, b) {
  3416. r = convertTo01Bounds(r, 255);
  3417. g = convertTo01Bounds(g, 255);
  3418. b = convertTo01Bounds(b, 255);
  3419. var max = Math.max(r, g, b),
  3420. min = Math.min(r, g, b),
  3421. maxMinSumm = max + min,
  3422. h,
  3423. s,
  3424. l = maxMinSumm / 2;
  3425. if (max === min)
  3426. h = s = 0;
  3427. else {
  3428. var delta = max - min;
  3429. if (l > 0.5)
  3430. s = delta / (2 - maxMinSumm);
  3431. else
  3432. s = delta / maxMinSumm;
  3433. h = calculateHue(r, g, b, delta);
  3434. h /= 6
  3435. }
  3436. return {
  3437. h: _round(h * 360),
  3438. s: _round(s * 100),
  3439. l: _round(l * 100)
  3440. }
  3441. }
  3442. function makeTc(colorPart, h) {
  3443. var Tc = h;
  3444. if (colorPart === "r")
  3445. Tc = h + 1 / 3;
  3446. if (colorPart === "b")
  3447. Tc = h - 1 / 3;
  3448. return Tc
  3449. }
  3450. function modifyTc(Tc) {
  3451. if (Tc < 0)
  3452. Tc += 1;
  3453. if (Tc > 1)
  3454. Tc -= 1;
  3455. return Tc
  3456. }
  3457. function hueToRgb(p, q, Tc) {
  3458. Tc = modifyTc(Tc);
  3459. if (Tc < 1 / 6)
  3460. return p + (q - p) * 6 * Tc;
  3461. if (Tc < 1 / 2)
  3462. return q;
  3463. if (Tc < 2 / 3)
  3464. return p + (q - p) * (2 / 3 - Tc) * 6;
  3465. return p
  3466. }
  3467. function hslToRgb(h, s, l) {
  3468. var r,
  3469. g,
  3470. b,
  3471. h = convertTo01Bounds(h, 360),
  3472. s = convertTo01Bounds(s, 100),
  3473. l = convertTo01Bounds(l, 100);
  3474. if (s === 0)
  3475. r = g = b = l;
  3476. else {
  3477. var q = l < 0.5 ? l * (1 + s) : l + s - l * s,
  3478. p = 2 * l - q;
  3479. r = hueToRgb(p, q, makeTc("r", h));
  3480. g = hueToRgb(p, q, makeTc("g", h));
  3481. b = hueToRgb(p, q, makeTc("b", h))
  3482. }
  3483. return [_round(r * 255), _round(g * 255), _round(b * 255)]
  3484. }
  3485. function convertTo01Bounds(n, max) {
  3486. n = Math.min(max, Math.max(0, parseFloat(n)));
  3487. if (Math.abs(n - max) < 0.000001)
  3488. return 1;
  3489. return n % max / parseFloat(max)
  3490. }
  3491. function isIntegerBtwMinAndMax(number, min, max) {
  3492. min = min || 0;
  3493. max = max || 255;
  3494. if (number % 1 !== 0 || number < min || number > max || typeof number !== 'number' || isNaN(number))
  3495. return false;
  3496. return true
  3497. }
  3498. var _round = Math.round;
  3499. Color.prototype = {
  3500. constructor: Color,
  3501. highlight: function(step) {
  3502. step = step || 10;
  3503. return this.alter(step).toHex()
  3504. },
  3505. darken: function(step) {
  3506. step = step || 10;
  3507. return this.alter(-step).toHex()
  3508. },
  3509. alter: function(step) {
  3510. var result = new Color;
  3511. result.r = normalize(this.r + step);
  3512. result.g = normalize(this.g + step);
  3513. result.b = normalize(this.b + step);
  3514. return result
  3515. },
  3516. blend: function(blendColor, opacity) {
  3517. var other = blendColor instanceof Color ? blendColor : new Color(blendColor),
  3518. result = new Color;
  3519. result.r = normalize(_round(this.r * (1 - opacity) + other.r * opacity));
  3520. result.g = normalize(_round(this.g * (1 - opacity) + other.g * opacity));
  3521. result.b = normalize(_round(this.b * (1 - opacity) + other.b * opacity));
  3522. return result
  3523. },
  3524. toHex: function() {
  3525. return toHexFromRgb(this.r, this.g, this.b)
  3526. },
  3527. getPureColor: function() {
  3528. var rgb = hsvToRgb(this.hsv.h, 100, 100);
  3529. return new Color("rgb(" + rgb.join(",") + ")")
  3530. },
  3531. isValidHex: function(hex) {
  3532. return /(^#[0-9A-F]{6}$)|(^#[0-9A-F]{3}$)/i.test(hex)
  3533. },
  3534. isValidRGB: function(r, g, b) {
  3535. if (!isIntegerBtwMinAndMax(r) || !isIntegerBtwMinAndMax(g) || !isIntegerBtwMinAndMax(b))
  3536. return false;
  3537. return true
  3538. },
  3539. isValidAlpha: function(a) {
  3540. if (isNaN(a) || a < 0 || a > 1 || typeof a !== 'number')
  3541. return false;
  3542. return true
  3543. },
  3544. colorIsInvalid: false
  3545. };
  3546. DX.Color = Color
  3547. })(DevExpress);
  3548. /*! Module core, file localization.js */
  3549. (function($, DX, undefined) {
  3550. Globalize.localize = function(key, cultureSelector) {
  3551. var neutral = (cultureSelector || this.cultureSelector || "").substring(0, 2);
  3552. return this.findClosestCulture(cultureSelector).messages[key] || this.findClosestCulture(neutral).messages[key] || this.cultures["default"].messages[key]
  3553. };
  3554. var localization = function() {
  3555. var newMessages = {};
  3556. return {
  3557. setup: function(localizablePrefix) {
  3558. this.localizeString = function(text) {
  3559. var regex = new RegExp("(^|[^a-zA-Z_0-9" + localizablePrefix + "-]+)(" + localizablePrefix + "{1,2})([a-zA-Z_0-9-]+)", "g"),
  3560. escapeString = localizablePrefix + localizablePrefix;
  3561. return text.replace(regex, function(str, prefix, escape, localizationKey) {
  3562. var result = prefix + localizablePrefix + localizationKey;
  3563. if (escape !== escapeString)
  3564. if (Globalize.cultures["default"].messages[localizationKey])
  3565. result = prefix + Globalize.localize(localizationKey);
  3566. else
  3567. newMessages[localizationKey] = DX.inflector.humanize(localizationKey);
  3568. return result
  3569. })
  3570. }
  3571. },
  3572. localizeNode: function(node) {
  3573. var that = this;
  3574. $(node).each(function(index, nodeItem) {
  3575. if (!nodeItem.nodeType)
  3576. return;
  3577. if (nodeItem.nodeType === 3)
  3578. nodeItem.nodeValue = that.localizeString(nodeItem.nodeValue);
  3579. else {
  3580. $.each(nodeItem.attributes || [], function(index, attr) {
  3581. if (typeof attr.value === "string") {
  3582. var localizedValue = that.localizeString(attr.value);
  3583. if (attr.value !== localizedValue)
  3584. attr.value = localizedValue
  3585. }
  3586. });
  3587. $(nodeItem).contents().each(function(index, node) {
  3588. that.localizeNode(node)
  3589. })
  3590. }
  3591. })
  3592. },
  3593. getDictionary: function(onlyNew) {
  3594. if (onlyNew)
  3595. return newMessages;
  3596. return $.extend({}, newMessages, Globalize.cultures["default"].messages)
  3597. }
  3598. }
  3599. }();
  3600. localization.setup("@");
  3601. DX.localization = localization
  3602. })(jQuery, DevExpress);
  3603. /*! Module core, file localization.en.js */
  3604. Globalize.addCultureInfo("default", {messages: {
  3605. Yes: "Yes",
  3606. No: "No",
  3607. Cancel: "Cancel",
  3608. Clear: "Clear",
  3609. Done: "Done",
  3610. Loading: "Loading...",
  3611. Select: "Select...",
  3612. Search: "Search",
  3613. Back: "Back",
  3614. OK: "OK",
  3615. "dxLookup-searchPlaceholder": "Minimum character number: {0}",
  3616. "dxCollectionContainerWidget-noDataText": "No data to display",
  3617. "dxList-pullingDownText": "Pull down to refresh...",
  3618. "dxList-pulledDownText": "Release to refresh...",
  3619. "dxList-refreshingText": "Refreshing...",
  3620. "dxList-pageLoadingText": "Loading...",
  3621. "dxList-nextButtonText": "More",
  3622. "dxListEditDecorator-delete": "Delete",
  3623. "dxListEditDecorator-more": "More",
  3624. "dxScrollView-pullingDownText": "Pull down to refresh...",
  3625. "dxScrollView-pulledDownText": "Release to refresh...",
  3626. "dxScrollView-refreshingText": "Refreshing...",
  3627. "dxScrollView-reachBottomText": "Loading...",
  3628. "dxSwitch-onText": "ON",
  3629. "dxSwitch-offText": "OFF",
  3630. "dxDateBox-simulatedDataPickerTitleTime": "Select time",
  3631. "dxDateBox-simulatedDataPickerTitleDate": "Select date",
  3632. "dxDateBox-simulatedDataPickerTitleDateTime": "Select date and time",
  3633. "dxDataGrid-columnChooserTitle": "Column Chooser",
  3634. "dxDataGrid-columnChooserEmptyText": "Drag a column here to hide it",
  3635. "dxDataGrid-groupContinuesMessage": "Continues on the next page",
  3636. "dxDataGrid-groupContinuedMessage": "Continued from the previous page",
  3637. "dxDataGrid-editingEditRow": "Edit",
  3638. "dxDataGrid-editingSaveRowChanges": "Save",
  3639. "dxDataGrid-editingCancelRowChanges": "Cancel",
  3640. "dxDataGrid-editingDeleteRow": "Delete",
  3641. "dxDataGrid-editingUndeleteRow": "Undelete",
  3642. "dxDataGrid-editingConfirmDeleteMessage": "Are you sure you want to delete this record?",
  3643. "dxDataGrid-editingConfirmDeleteTitle": "",
  3644. "dxDataGrid-groupPanelEmptyText": "Drag a column header here to group by that column",
  3645. "dxDataGrid-noDataText": "No data",
  3646. "dxDataGrid-searchPanelPlaceholder": "Search...",
  3647. "dxDataGrid-filterRowShowAllText": "(All)",
  3648. "dxDataGrid-filterRowResetOperationText": "Reset",
  3649. "dxDataGrid-filterRowOperationEquals": "Equals",
  3650. "dxDataGrid-filterRowOperationNotEquals": "Does not equal",
  3651. "dxDataGrid-filterRowOperationLess": "Less than",
  3652. "dxDataGrid-filterRowOperationLessOrEquals": "Less than or equal to",
  3653. "dxDataGrid-filterRowOperationGreater": "Greater than",
  3654. "dxDataGrid-filterRowOperationGreaterOrEquals": "Greater than or equal to",
  3655. "dxDataGrid-filterRowOperationStartsWith": "Starts with",
  3656. "dxDataGrid-filterRowOperationContains": "Contains",
  3657. "dxDataGrid-filterRowOperationNotContains": "Does not contain",
  3658. "dxDataGrid-filterRowOperationEndsWith": "Ends with",
  3659. "dxDataGrid-trueText": "true",
  3660. "dxDataGrid-falseText": "false",
  3661. "dxDataGrid-sortingAscendingText": "Sort Ascending",
  3662. "dxDataGrid-sortingDescendingText": "Sort Descending",
  3663. "dxDataGrid-sortingClearText": "Clear Sorting"
  3664. }});
  3665. /*! Module core, file data.js */
  3666. (function($, DX, undefined) {
  3667. var bracketsToDots = function(expr) {
  3668. return expr.replace(/\[/g, ".").replace(/\]/g, "")
  3669. };
  3670. var unwrapObservable = DX.utils.unwrapObservable;
  3671. var isObservable = function(value) {
  3672. return DX.support.hasKo && ko.isObservable(value)
  3673. };
  3674. var readPropValue = function(obj, propName) {
  3675. if (propName === "this")
  3676. return obj;
  3677. return obj[propName]
  3678. };
  3679. var assignPropValue = function(obj, propName, value) {
  3680. if (propName === "this")
  3681. throw Error("Cannot assign to self");
  3682. var propValue = obj[propName];
  3683. if (isObservable(propValue))
  3684. propValue(value);
  3685. else
  3686. obj[propName] = value
  3687. };
  3688. var compileGetter = function(expr) {
  3689. if (arguments.length > 1)
  3690. expr = $.makeArray(arguments);
  3691. if (!expr || expr === "this")
  3692. return function(obj) {
  3693. return obj
  3694. };
  3695. if ($.isFunction(expr))
  3696. return expr;
  3697. if ($.isArray(expr))
  3698. return combineGetters(expr);
  3699. expr = bracketsToDots(expr);
  3700. var path = expr.split(".");
  3701. return function(obj, options) {
  3702. options = options || {};
  3703. var current = unwrapObservable(obj);
  3704. $.each(path, function() {
  3705. if (!current)
  3706. return false;
  3707. var next = unwrapObservable(current[this]);
  3708. if ($.isFunction(next) && !options.functionsAsIs)
  3709. next = next.call(current);
  3710. current = next
  3711. });
  3712. return current
  3713. }
  3714. };
  3715. var combineGetters = function(getters) {
  3716. var compiledGetters = {};
  3717. $.each(getters, function() {
  3718. compiledGetters[this] = compileGetter(this)
  3719. });
  3720. return function(obj, options) {
  3721. var result = {};
  3722. $.each(compiledGetters, function(name) {
  3723. var value = this(obj, options),
  3724. current,
  3725. path,
  3726. last,
  3727. i;
  3728. if (value === undefined)
  3729. return;
  3730. current = result;
  3731. path = name.split(".");
  3732. last = path.length - 1;
  3733. for (i = 0; i < last; i++)
  3734. current = current[path[i]] = {};
  3735. current[path[i]] = value
  3736. });
  3737. return result
  3738. }
  3739. };
  3740. var compileSetter = function(expr) {
  3741. expr = expr || "this";
  3742. expr = bracketsToDots(expr);
  3743. var pos = expr.lastIndexOf("."),
  3744. targetGetter = compileGetter(expr.substr(0, pos)),
  3745. targetPropName = expr.substr(1 + pos);
  3746. return function(obj, value, options) {
  3747. options = options || {};
  3748. var target = targetGetter(obj, {functionsAsIs: options.functionsAsIs}),
  3749. prevTargetValue = readPropValue(target, targetPropName);
  3750. if (!options.functionsAsIs && $.isFunction(prevTargetValue) && !isObservable(prevTargetValue))
  3751. target[targetPropName](value);
  3752. else {
  3753. prevTargetValue = unwrapObservable(prevTargetValue);
  3754. if (options.merge && $.isPlainObject(value) && (prevTargetValue === undefined || $.isPlainObject(prevTargetValue)) && !(value instanceof $.Event)) {
  3755. if (!prevTargetValue)
  3756. assignPropValue(target, targetPropName, {});
  3757. DX.utils.deepExtendArraySafe(unwrapObservable(readPropValue(target, targetPropName)), value)
  3758. }
  3759. else
  3760. assignPropValue(target, targetPropName, value)
  3761. }
  3762. }
  3763. };
  3764. var normalizeBinaryCriterion = function(crit) {
  3765. return [crit[0], crit.length < 3 ? "=" : String(crit[1]).toLowerCase(), crit.length < 2 ? true : crit[crit.length - 1]]
  3766. };
  3767. var normalizeSortingInfo = function(info) {
  3768. if (!$.isArray(info))
  3769. info = [info];
  3770. return $.map(info, function(i) {
  3771. return {
  3772. selector: $.isFunction(i) || typeof i === "string" ? i : i.getter || i.field || i.selector,
  3773. desc: !!(i.desc || String(i.dir).charAt(0).toLowerCase() === "d")
  3774. }
  3775. })
  3776. };
  3777. var Guid = DX.Class.inherit({
  3778. ctor: function(value) {
  3779. if (value)
  3780. value = String(value);
  3781. this._value = this._normalize(value || this._generate())
  3782. },
  3783. _normalize: function(value) {
  3784. value = value.replace(/[^a-f0-9]/ig, "").toLowerCase();
  3785. while (value.length < 32)
  3786. value += "0";
  3787. return [value.substr(0, 8), value.substr(8, 4), value.substr(12, 4), value.substr(16, 4), value.substr(20, 12)].join("-")
  3788. },
  3789. _generate: function() {
  3790. var value = "";
  3791. for (var i = 0; i < 32; i++)
  3792. value += Math.round(Math.random() * 15).toString(16);
  3793. return value
  3794. },
  3795. toString: function() {
  3796. return this._value
  3797. },
  3798. valueOf: function() {
  3799. return this._value
  3800. },
  3801. toJSON: function() {
  3802. return this._value
  3803. }
  3804. });
  3805. var toComparable = function(value, caseSensitive) {
  3806. if (value instanceof Date)
  3807. return value.getTime();
  3808. if (value instanceof Guid)
  3809. return value.valueOf();
  3810. if (!caseSensitive && typeof value === "string")
  3811. return value.toLowerCase();
  3812. return value
  3813. };
  3814. var keysEqual = function(keyExpr, key1, key2) {
  3815. if ($.isArray(keyExpr)) {
  3816. var names = $.map(key1, function(v, k) {
  3817. return k
  3818. }),
  3819. name;
  3820. for (var i = 0; i < names.length; i++) {
  3821. name = names[i];
  3822. if (toComparable(key1[name], true) != toComparable(key2[name], true))
  3823. return false
  3824. }
  3825. return true
  3826. }
  3827. return toComparable(key1, true) == toComparable(key2, true)
  3828. };
  3829. var BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
  3830. var base64_encode = function(input) {
  3831. if (!$.isArray(input))
  3832. input = stringToByteArray(String(input));
  3833. var result = "";
  3834. for (var i = 0; i < input.length; i += 3) {
  3835. var octet1 = input[i],
  3836. octet2 = input[i + 1],
  3837. octet3 = input[i + 2];
  3838. result += $.map([octet1 >> 2, (octet1 & 3) << 4 | octet2 >> 4, isNaN(octet2) ? 64 : (octet2 & 15) << 2 | octet3 >> 6, isNaN(octet3) ? 64 : octet3 & 63], function(item) {
  3839. return BASE64_CHARS.charAt(item)
  3840. }).join("")
  3841. }
  3842. return result
  3843. };
  3844. var stringToByteArray = function(str) {
  3845. var bytes = [],
  3846. code,
  3847. i;
  3848. for (i = 0; i < str.length; i++) {
  3849. code = str.charCodeAt(i);
  3850. if (code < 128)
  3851. bytes.push(code);
  3852. else if (code < 2048)
  3853. bytes.push(192 + (code >> 6), 128 + (code & 63));
  3854. else if (code < 65536)
  3855. bytes.push(224 + (code >> 12), 128 + (code >> 6 & 63), 128 + (code & 63));
  3856. else if (code < 2097152)
  3857. bytes.push(240 + (code >> 18), 128 + (code >> 12 & 63), 128 + (code >> 6 & 63), 128 + (code & 63))
  3858. }
  3859. return bytes
  3860. };
  3861. var errorMessageFromXhr = function() {
  3862. var textStatusMessages = {
  3863. timeout: "Network connection timeout",
  3864. error: "Unspecified network error",
  3865. parsererror: "Unexpected server response"
  3866. };
  3867. var textStatusDetails = {
  3868. 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",
  3869. 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",
  3870. parsererror: "the remote host did not respond with valid JSON data"
  3871. };
  3872. var explainTextStatus = function(textStatus) {
  3873. var result = textStatusMessages[textStatus];
  3874. if (!result)
  3875. return textStatus;
  3876. result += " (" + textStatusDetails[textStatus] + ")";
  3877. return result
  3878. };
  3879. return function(xhr, textStatus) {
  3880. if (xhr.status < 400)
  3881. return explainTextStatus(textStatus);
  3882. return xhr.statusText
  3883. }
  3884. }();
  3885. var data = DX.data = {
  3886. utils: {
  3887. compileGetter: compileGetter,
  3888. compileSetter: compileSetter,
  3889. normalizeBinaryCriterion: normalizeBinaryCriterion,
  3890. normalizeSortingInfo: normalizeSortingInfo,
  3891. toComparable: toComparable,
  3892. keysEqual: keysEqual,
  3893. errorMessageFromXhr: errorMessageFromXhr
  3894. },
  3895. Guid: Guid,
  3896. base64_encode: base64_encode,
  3897. queryImpl: {},
  3898. queryAdapters: {},
  3899. query: function() {
  3900. var impl = $.isArray(arguments[0]) ? "array" : "remote";
  3901. return data.queryImpl[impl].apply(this, arguments)
  3902. },
  3903. errorHandler: null,
  3904. _handleError: function(error) {
  3905. if (window.console)
  3906. console.warn("[DevExpress.data]: " + error);
  3907. if (data.errorHandler)
  3908. data.errorHandler(error)
  3909. }
  3910. }
  3911. })(jQuery, DevExpress);
  3912. /*! Module core, file data.query.array.js */
  3913. (function($, DX, undefined) {
  3914. var Class = DX.Class,
  3915. data = DX.data,
  3916. queryImpl = data.queryImpl,
  3917. compileGetter = data.utils.compileGetter,
  3918. toComparable = data.utils.toComparable;
  3919. var Iterator = Class.inherit({
  3920. toArray: function() {
  3921. var result = [];
  3922. this.reset();
  3923. while (this.next())
  3924. result.push(this.current());
  3925. return result
  3926. },
  3927. countable: function() {
  3928. return false
  3929. }
  3930. });
  3931. var ArrayIterator = Iterator.inherit({
  3932. ctor: function(array) {
  3933. this.array = array;
  3934. this.index = -1
  3935. },
  3936. next: function() {
  3937. if (this.index + 1 < this.array.length) {
  3938. this.index++;
  3939. return true
  3940. }
  3941. return false
  3942. },
  3943. current: function() {
  3944. return this.array[this.index]
  3945. },
  3946. reset: function() {
  3947. this.index = -1
  3948. },
  3949. toArray: function() {
  3950. return this.array.slice(0)
  3951. },
  3952. countable: function() {
  3953. return true
  3954. },
  3955. count: function() {
  3956. return this.array.length
  3957. }
  3958. });
  3959. var WrappedIterator = Iterator.inherit({
  3960. ctor: function(iter) {
  3961. this.iter = iter
  3962. },
  3963. next: function() {
  3964. return this.iter.next()
  3965. },
  3966. current: function() {
  3967. return this.iter.current()
  3968. },
  3969. reset: function() {
  3970. return this.iter.reset()
  3971. }
  3972. });
  3973. var MapIterator = WrappedIterator.inherit({
  3974. ctor: function(iter, mapper) {
  3975. this.callBase(iter);
  3976. this.index = -1;
  3977. this.mapper = mapper
  3978. },
  3979. current: function() {
  3980. return this.mapper(this.callBase(), this.index)
  3981. },
  3982. next: function() {
  3983. var hasNext = this.callBase();
  3984. if (hasNext)
  3985. this.index++;
  3986. return hasNext
  3987. }
  3988. });
  3989. var SortIterator = Iterator.inherit({
  3990. ctor: function(iter, getter, desc) {
  3991. if (!(iter instanceof MapIterator))
  3992. iter = new MapIterator(iter, this._wrap);
  3993. this.iter = iter;
  3994. this.rules = [{
  3995. getter: getter,
  3996. desc: desc
  3997. }]
  3998. },
  3999. thenBy: function(getter, desc) {
  4000. var result = new SortIterator(this.sortedIter || this.iter, getter, desc);
  4001. if (!this.sortedIter)
  4002. result.rules = this.rules.concat(result.rules);
  4003. return result
  4004. },
  4005. next: function() {
  4006. this._ensureSorted();
  4007. return this.sortedIter.next()
  4008. },
  4009. current: function() {
  4010. this._ensureSorted();
  4011. return this.sortedIter.current()
  4012. },
  4013. reset: function() {
  4014. delete this.sortedIter
  4015. },
  4016. countable: function() {
  4017. return this.sortedIter || this.iter.countable()
  4018. },
  4019. count: function() {
  4020. if (this.sortedIter)
  4021. return this.sortedIter.count();
  4022. return this.iter.count()
  4023. },
  4024. _ensureSorted: function() {
  4025. if (this.sortedIter)
  4026. return;
  4027. $.each(this.rules, function() {
  4028. this.getter = compileGetter(this.getter)
  4029. });
  4030. this.sortedIter = new MapIterator(new ArrayIterator(this.iter.toArray().sort($.proxy(this._compare, this))), this._unwrap)
  4031. },
  4032. _wrap: function(record, index) {
  4033. return {
  4034. index: index,
  4035. value: record
  4036. }
  4037. },
  4038. _unwrap: function(wrappedItem) {
  4039. return wrappedItem.value
  4040. },
  4041. _compare: function(x, y) {
  4042. var xIndex = x.index,
  4043. yIndex = y.index;
  4044. x = x.value;
  4045. y = y.value;
  4046. if (x === y)
  4047. return xIndex - yIndex;
  4048. for (var i = 0, rulesCount = this.rules.length; i < rulesCount; i++) {
  4049. var rule = this.rules[i],
  4050. xValue = toComparable(rule.getter(x)),
  4051. yValue = toComparable(rule.getter(y)),
  4052. factor = rule.desc ? -1 : 1;
  4053. if (xValue < yValue)
  4054. return -factor;
  4055. if (xValue > yValue)
  4056. return factor;
  4057. if (xValue !== yValue)
  4058. return !xValue ? -factor : factor
  4059. }
  4060. return xIndex - yIndex
  4061. }
  4062. });
  4063. var compileCriteria = function() {
  4064. var compileGroup = function(crit) {
  4065. var operands = [],
  4066. bag = ["return function(d) { return "],
  4067. index = 0,
  4068. pushAnd = false;
  4069. $.each(crit, function() {
  4070. if ($.isArray(this) || $.isFunction(this)) {
  4071. if (pushAnd)
  4072. bag.push(" && ");
  4073. operands.push(compileCriteria(this));
  4074. bag.push("op[", index, "](d)");
  4075. index++;
  4076. pushAnd = true
  4077. }
  4078. else {
  4079. bag.push(/and|&/i.test(this) ? " && " : " || ");
  4080. pushAnd = false
  4081. }
  4082. });
  4083. bag.push(" }");
  4084. return new Function("op", bag.join(""))(operands)
  4085. };
  4086. var toString = function(value) {
  4087. return DX.utils.isDefined(value) ? value.toString() : ''
  4088. };
  4089. var compileBinary = function(crit) {
  4090. crit = data.utils.normalizeBinaryCriterion(crit);
  4091. var getter = compileGetter(crit[0]),
  4092. op = crit[1],
  4093. value = crit[2];
  4094. value = toComparable(value);
  4095. switch (op.toLowerCase()) {
  4096. case"=":
  4097. return compileEquals(getter, value);
  4098. case"<>":
  4099. return compileEquals(getter, value, true);
  4100. case">":
  4101. return function(obj) {
  4102. return toComparable(getter(obj)) > value
  4103. };
  4104. case"<":
  4105. return function(obj) {
  4106. return toComparable(getter(obj)) < value
  4107. };
  4108. case">=":
  4109. return function(obj) {
  4110. return toComparable(getter(obj)) >= value
  4111. };
  4112. case"<=":
  4113. return function(obj) {
  4114. return toComparable(getter(obj)) <= value
  4115. };
  4116. case"startswith":
  4117. return function(obj) {
  4118. return toComparable(toString(getter(obj))).indexOf(value) === 0
  4119. };
  4120. case"endswith":
  4121. return function(obj) {
  4122. var getterValue = toComparable(toString(getter(obj)));
  4123. return getterValue.lastIndexOf(value) === getterValue.length - toString(value).length
  4124. };
  4125. case"contains":
  4126. return function(obj) {
  4127. return toComparable(toString(getter(obj))).indexOf(value) > -1
  4128. };
  4129. case"notcontains":
  4130. return function(obj) {
  4131. return toComparable(toString(getter(obj))).indexOf(value) === -1
  4132. }
  4133. }
  4134. throw Error("Unknown filter operation: " + op);
  4135. };
  4136. function compileEquals(getter, value, negate) {
  4137. return function(obj) {
  4138. obj = toComparable(getter(obj));
  4139. var result = useStrictComparison(value) ? obj === value : obj == value;
  4140. if (negate)
  4141. result = !result;
  4142. return result
  4143. }
  4144. }
  4145. function useStrictComparison(value) {
  4146. return value === "" || value === 0 || value === null || value === false || value === undefined
  4147. }
  4148. return function(crit) {
  4149. if ($.isFunction(crit))
  4150. return crit;
  4151. if ($.isArray(crit[0]))
  4152. return compileGroup(crit);
  4153. return compileBinary(crit)
  4154. }
  4155. }();
  4156. var FilterIterator = WrappedIterator.inherit({
  4157. ctor: function(iter, criteria) {
  4158. this.callBase(iter);
  4159. this.criteria = compileCriteria(criteria)
  4160. },
  4161. next: function() {
  4162. while (this.iter.next())
  4163. if (this.criteria(this.current()))
  4164. return true;
  4165. return false
  4166. }
  4167. });
  4168. var GroupIterator = Iterator.inherit({
  4169. ctor: function(iter, getter) {
  4170. this.iter = iter;
  4171. this.getter = getter
  4172. },
  4173. next: function() {
  4174. this._ensureGrouped();
  4175. return this.groupedIter.next()
  4176. },
  4177. current: function() {
  4178. this._ensureGrouped();
  4179. return this.groupedIter.current()
  4180. },
  4181. reset: function() {
  4182. delete this.groupedIter
  4183. },
  4184. countable: function() {
  4185. return !!this.groupedIter
  4186. },
  4187. count: function() {
  4188. return this.groupedIter.count()
  4189. },
  4190. _ensureGrouped: function() {
  4191. if (this.groupedIter)
  4192. return;
  4193. var hash = {},
  4194. keys = [],
  4195. iter = this.iter,
  4196. getter = compileGetter(this.getter);
  4197. iter.reset();
  4198. while (iter.next()) {
  4199. var current = iter.current(),
  4200. key = getter(current);
  4201. if (key in hash)
  4202. hash[key].push(current);
  4203. else {
  4204. hash[key] = [current];
  4205. keys.push(key)
  4206. }
  4207. }
  4208. this.groupedIter = new ArrayIterator($.map(keys, function(key) {
  4209. return {
  4210. key: key,
  4211. items: hash[key]
  4212. }
  4213. }))
  4214. }
  4215. });
  4216. var SelectIterator = WrappedIterator.inherit({
  4217. ctor: function(iter, getter) {
  4218. this.callBase(iter);
  4219. this.getter = compileGetter(getter)
  4220. },
  4221. current: function() {
  4222. return this.getter(this.callBase())
  4223. },
  4224. countable: function() {
  4225. return this.iter.countable()
  4226. },
  4227. count: function() {
  4228. return this.iter.count()
  4229. }
  4230. });
  4231. var SliceIterator = WrappedIterator.inherit({
  4232. ctor: function(iter, skip, take) {
  4233. this.callBase(iter);
  4234. this.skip = Math.max(0, skip);
  4235. this.take = Math.max(0, take);
  4236. this.pos = 0
  4237. },
  4238. next: function() {
  4239. if (this.pos >= this.skip + this.take)
  4240. return false;
  4241. while (this.pos < this.skip && this.iter.next())
  4242. this.pos++;
  4243. this.pos++;
  4244. return this.iter.next()
  4245. },
  4246. reset: function() {
  4247. this.callBase();
  4248. this.pos = 0
  4249. },
  4250. countable: function() {
  4251. return this.iter.countable()
  4252. },
  4253. count: function() {
  4254. return Math.min(this.iter.count() - this.skip, this.take)
  4255. }
  4256. });
  4257. queryImpl.array = function(iter, queryOptions) {
  4258. queryOptions = queryOptions || {};
  4259. if (!(iter instanceof Iterator))
  4260. iter = new ArrayIterator(iter);
  4261. var handleError = function(error) {
  4262. var handler = queryOptions.errorHandler;
  4263. if (handler)
  4264. handler(error);
  4265. data._handleError(error)
  4266. };
  4267. var aggregate = function(seed, step, finalize) {
  4268. var d = $.Deferred().fail(handleError);
  4269. try {
  4270. iter.reset();
  4271. if (arguments.length < 2) {
  4272. step = arguments[0];
  4273. seed = iter.next() ? iter.current() : undefined
  4274. }
  4275. var accumulator = seed;
  4276. while (iter.next())
  4277. accumulator = step(accumulator, iter.current());
  4278. d.resolve(finalize ? finalize(accumulator) : accumulator)
  4279. }
  4280. catch(x) {
  4281. d.reject(x)
  4282. }
  4283. return d.promise()
  4284. };
  4285. var select = function(getter) {
  4286. if (!$.isFunction(getter) && !$.isArray(getter))
  4287. getter = $.makeArray(arguments);
  4288. return chainQuery(new SelectIterator(iter, getter))
  4289. };
  4290. var selectProp = function(name) {
  4291. return select(compileGetter(name))
  4292. };
  4293. var chainQuery = function(iter) {
  4294. return queryImpl.array(iter, queryOptions)
  4295. };
  4296. return {
  4297. toArray: function() {
  4298. return iter.toArray()
  4299. },
  4300. enumerate: function() {
  4301. var d = $.Deferred().fail(handleError);
  4302. try {
  4303. d.resolve(iter.toArray())
  4304. }
  4305. catch(x) {
  4306. d.reject(x)
  4307. }
  4308. return d.promise()
  4309. },
  4310. sortBy: function(getter, desc) {
  4311. return chainQuery(new SortIterator(iter, getter, desc))
  4312. },
  4313. thenBy: function(getter, desc) {
  4314. if (iter instanceof SortIterator)
  4315. return chainQuery(iter.thenBy(getter, desc));
  4316. throw Error();
  4317. },
  4318. filter: function(criteria) {
  4319. if (!$.isArray(criteria))
  4320. criteria = $.makeArray(arguments);
  4321. return chainQuery(new FilterIterator(iter, criteria))
  4322. },
  4323. slice: function(skip, take) {
  4324. if (take === undefined)
  4325. take = Number.MAX_VALUE;
  4326. return chainQuery(new SliceIterator(iter, skip, take))
  4327. },
  4328. select: select,
  4329. groupBy: function(getter) {
  4330. return chainQuery(new GroupIterator(iter, getter))
  4331. },
  4332. aggregate: aggregate,
  4333. count: function() {
  4334. if (iter.countable()) {
  4335. var d = $.Deferred().fail(handleError);
  4336. try {
  4337. d.resolve(iter.count())
  4338. }
  4339. catch(x) {
  4340. d.reject(x)
  4341. }
  4342. return d.promise()
  4343. }
  4344. return aggregate(0, function(count) {
  4345. return 1 + count
  4346. })
  4347. },
  4348. sum: function(getter) {
  4349. if (getter)
  4350. return selectProp(getter).sum();
  4351. return aggregate(0, function(sum, item) {
  4352. return sum + item
  4353. })
  4354. },
  4355. min: function(getter) {
  4356. if (getter)
  4357. return selectProp(getter).min();
  4358. return aggregate(function(min, item) {
  4359. return item < min ? item : min
  4360. })
  4361. },
  4362. max: function(getter) {
  4363. if (getter)
  4364. return selectProp(getter).max();
  4365. return aggregate(function(max, item) {
  4366. return item > max ? item : max
  4367. })
  4368. },
  4369. avg: function(getter) {
  4370. if (getter)
  4371. return selectProp(getter).avg();
  4372. var count = 0;
  4373. return aggregate(0, function(sum, item) {
  4374. count++;
  4375. return sum + item
  4376. }, function(sum) {
  4377. return count ? sum / count : undefined
  4378. })
  4379. }
  4380. }
  4381. }
  4382. })(jQuery, DevExpress);
  4383. /*! Module core, file data.query.remote.js */
  4384. (function($, DX, undefined) {
  4385. var data = DX.data,
  4386. queryImpl = data.queryImpl;
  4387. queryImpl.remote = function(url, queryOptions, tasks) {
  4388. tasks = tasks || [];
  4389. queryOptions = queryOptions || {};
  4390. var createTask = function(name, args) {
  4391. return {
  4392. name: name,
  4393. args: args
  4394. }
  4395. };
  4396. var exec = function(executorTask) {
  4397. var d = $.Deferred(),
  4398. adapterFactory,
  4399. adapter,
  4400. taskQueue,
  4401. currentTask;
  4402. var rejectWithNotify = function(error) {
  4403. var handler = queryOptions.errorHandler;
  4404. if (handler)
  4405. handler(error);
  4406. data._handleError(error);
  4407. d.reject(error)
  4408. };
  4409. try {
  4410. adapterFactory = queryOptions.adapter || "odata";
  4411. if (!$.isFunction(adapterFactory))
  4412. adapterFactory = data.queryAdapters[adapterFactory];
  4413. adapter = adapterFactory(queryOptions);
  4414. taskQueue = [].concat(tasks).concat(executorTask);
  4415. while (taskQueue.length) {
  4416. currentTask = taskQueue[0];
  4417. if (String(currentTask.name) !== "enumerate")
  4418. if (!adapter[currentTask.name] || adapter[currentTask.name].apply(adapter, currentTask.args) === false)
  4419. break;
  4420. taskQueue.shift()
  4421. }
  4422. adapter.exec(url).done(function(result, extra) {
  4423. if (!taskQueue.length)
  4424. d.resolve(result, extra);
  4425. else {
  4426. var clientChain = queryImpl.array(result, {errorHandler: queryOptions.errorHandler});
  4427. $.each(taskQueue, function() {
  4428. clientChain = clientChain[this.name].apply(clientChain, this.args)
  4429. });
  4430. clientChain.done($.proxy(d.resolve, d)).fail($.proxy(d.reject, d))
  4431. }
  4432. }).fail(rejectWithNotify)
  4433. }
  4434. catch(x) {
  4435. rejectWithNotify(x)
  4436. }
  4437. return d.promise()
  4438. };
  4439. var query = {};
  4440. $.each(["sortBy", "thenBy", "filter", "slice", "select", "groupBy"], function() {
  4441. var name = this;
  4442. query[name] = function() {
  4443. return queryImpl.remote(url, queryOptions, tasks.concat(createTask(name, arguments)))
  4444. }
  4445. });
  4446. $.each(["count", "min", "max", "sum", "avg", "aggregate", "enumerate"], function() {
  4447. var name = this;
  4448. query[name] = function() {
  4449. return exec.call(this, createTask(name, arguments))
  4450. }
  4451. });
  4452. return query
  4453. }
  4454. })(jQuery, DevExpress);
  4455. /*! Module core, file data.odata.js */
  4456. (function($, DX, undefined) {
  4457. var data = DX.data,
  4458. utils = DX.utils,
  4459. Guid = data.Guid;
  4460. 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})$/;
  4461. var VERBOSE_DATE_REGEX = /^\/Date\((-?\d+)((\+|-)?(\d+)?)\)\/$/;
  4462. var ISO8601_DATE_REGEX = /^(\d{4})(?:-?W(\d+)(?:-?(\d+)D?)?|(?:-(\d+))?-(\d+))(?:[T ](\d+):(\d+)(?::(\d+)(?:\.(\d+))?)?)?(?:Z(-?\d*))?$/;
  4463. var TIMEZONE_OFFSET = (new Date).getTimezoneOffset() * 60 * 1000;
  4464. var JSON_VERBOSE_MIME_TYPE = "application/json;odata=verbose";
  4465. function stringify(object) {
  4466. return JSON.stringify(object, replacer);
  4467. function replacer(key, value) {
  4468. if (this[key] instanceof Date)
  4469. return utils.formatIso8601Date(this[key]);
  4470. return value
  4471. }
  4472. }
  4473. var ajaxOptionsForRequest = function(request, requestOptions) {
  4474. request = $.extend({
  4475. method: "get",
  4476. url: "",
  4477. params: {},
  4478. payload: null,
  4479. headers: {}
  4480. }, request);
  4481. requestOptions = requestOptions || {};
  4482. var beforeSend = requestOptions.beforeSend;
  4483. if (beforeSend)
  4484. beforeSend(request);
  4485. var method = (request.method || "get").toLowerCase(),
  4486. isGet = method === "get",
  4487. useJsonp = isGet && requestOptions.jsonp,
  4488. params = $.extend({}, request.params),
  4489. ajaxData = isGet ? params : stringify(request.payload),
  4490. qs = !isGet && $.param(params),
  4491. url = request.url,
  4492. contentType = !isGet && JSON_VERBOSE_MIME_TYPE;
  4493. if (qs)
  4494. url += (url.indexOf("?") > -1 ? "&" : "?") + qs;
  4495. if (useJsonp)
  4496. ajaxData["$format"] = "json";
  4497. return {
  4498. url: url,
  4499. data: ajaxData,
  4500. dataType: useJsonp ? "jsonp" : "json",
  4501. jsonp: useJsonp && "$callback",
  4502. type: method,
  4503. timeout: 30000,
  4504. headers: request.headers,
  4505. contentType: contentType,
  4506. accepts: {json: [JSON_VERBOSE_MIME_TYPE, "text/plain"].join()},
  4507. xhrFields: {withCredentials: requestOptions.withCredentials}
  4508. }
  4509. };
  4510. var sendRequest = function(request, requestOptions) {
  4511. var d = $.Deferred();
  4512. $.ajax(ajaxOptionsForRequest(request, requestOptions)).always(function(obj, textStatus) {
  4513. var tuplet = interpretJsonFormat(obj, textStatus),
  4514. error = tuplet.error,
  4515. data = tuplet.data,
  4516. nextUrl = tuplet.nextUrl,
  4517. extra;
  4518. if (error)
  4519. d.reject(error);
  4520. else if (requestOptions.countOnly)
  4521. d.resolve(tuplet.count);
  4522. else if (nextUrl)
  4523. sendRequest({url: nextUrl}, requestOptions).fail($.proxy(d.reject, d)).done(function(nextData) {
  4524. d.resolve(data.concat(nextData))
  4525. });
  4526. else {
  4527. if (isFinite(tuplet.count))
  4528. extra = {totalCount: tuplet.count};
  4529. d.resolve(data, extra)
  4530. }
  4531. });
  4532. return d.promise()
  4533. };
  4534. var formatDotNetError = function(errorObj) {
  4535. var message,
  4536. currentError = errorObj;
  4537. if ("message" in errorObj)
  4538. if (errorObj.message.value)
  4539. message = errorObj.message.value;
  4540. else
  4541. message = errorObj.message;
  4542. while (currentError = currentError.innererror || currentError.internalexception) {
  4543. message = currentError.message;
  4544. if (currentError.internalexception && message.indexOf("inner exception") === -1)
  4545. break
  4546. }
  4547. return message
  4548. };
  4549. var errorFromResponse = function(obj, textStatus) {
  4550. if (textStatus === "nocontent")
  4551. return null;
  4552. var httpStatus = 200,
  4553. message = "Unknown error",
  4554. response = obj;
  4555. if (textStatus !== "success") {
  4556. httpStatus = obj.status;
  4557. message = data.utils.errorMessageFromXhr(obj, textStatus);
  4558. try {
  4559. response = $.parseJSON(obj.responseText)
  4560. }
  4561. catch(x) {}
  4562. }
  4563. var errorObj = response && (response.error || response["@odata.error"]);
  4564. if (errorObj) {
  4565. message = formatDotNetError(errorObj) || message;
  4566. if (httpStatus === 200)
  4567. httpStatus = 500;
  4568. if (errorObj.code)
  4569. httpStatus = Number(errorObj.code);
  4570. return $.extend(Error(message), {
  4571. httpStatus: httpStatus,
  4572. errorDetails: errorObj
  4573. })
  4574. }
  4575. else if (httpStatus !== 200)
  4576. return $.extend(Error(message), {httpStatus: httpStatus})
  4577. };
  4578. var interpretJsonFormat = function(obj, textStatus) {
  4579. var error = errorFromResponse(obj, textStatus),
  4580. value;
  4581. if (error)
  4582. return {error: error};
  4583. if (!$.isPlainObject(obj))
  4584. return {data: obj};
  4585. if ("d" in obj && (utils.isArray(obj.d) || utils.isObject(obj.d)))
  4586. value = interpretVerboseJsonFormat(obj, textStatus);
  4587. else
  4588. value = interpretLightJsonFormat(obj, textStatus);
  4589. transformTypes(value);
  4590. return value
  4591. };
  4592. var interpretVerboseJsonFormat = function(obj, textStatus) {
  4593. var data = obj.d;
  4594. if (!data)
  4595. return {error: Error("Malformed or unsupported JSON response received")};
  4596. data = data.results || data;
  4597. return {
  4598. data: data,
  4599. nextUrl: obj.d.__next,
  4600. count: parseInt(obj.d.__count, 10)
  4601. }
  4602. };
  4603. var interpretLightJsonFormat = function(obj, textStatus) {
  4604. var data = obj.value || obj;
  4605. if (!data)
  4606. return {error: Error("Malformed or unsupported JSON response received")};
  4607. return {
  4608. data: data,
  4609. nextUrl: obj["@odata.nextLink"],
  4610. count: parseInt(obj["@odata.count"], 10)
  4611. }
  4612. };
  4613. var EdmLiteral = DX.Class.inherit({
  4614. ctor: function(value) {
  4615. this._value = value
  4616. },
  4617. valueOf: function() {
  4618. return this._value
  4619. }
  4620. });
  4621. var transformTypes = function(obj) {
  4622. $.each(obj, function(key, value) {
  4623. if (value !== null && typeof value === "object")
  4624. transformTypes(value);
  4625. else if (typeof value === "string")
  4626. if (GUID_REGEX.test(value))
  4627. obj[key] = new Guid(value);
  4628. else if (value.match(VERBOSE_DATE_REGEX))
  4629. obj[key] = new Date(TIMEZONE_OFFSET + Number(RegExp.$1) + RegExp.$2 * 60000);
  4630. else if (ISO8601_DATE_REGEX.test(value))
  4631. obj[key] = new Date(utils.parseIso8601Date(obj[key]).valueOf())
  4632. })
  4633. };
  4634. var serializeDate = function() {
  4635. var pad = function(part) {
  4636. part = String(part);
  4637. if (part.length < 2)
  4638. part = "0" + part;
  4639. return part
  4640. };
  4641. return function(date) {
  4642. var result = ["datetime'", date.getFullYear(), "-", pad(date.getMonth() + 1), "-", pad(date.getDate())];
  4643. if (date.getHours() || date.getMinutes() || date.getSeconds() || date.getMilliseconds()) {
  4644. result.push("T", pad(date.getHours()), ":", pad(date.getMinutes()), ":", pad(date.getSeconds()));
  4645. if (date.getMilliseconds())
  4646. result.push(".", date.getMilliseconds())
  4647. }
  4648. result.push("'");
  4649. return result.join("")
  4650. }
  4651. }();
  4652. var serializeString = function(value) {
  4653. return "'" + value.replace(/</g, "%26lt").replace(/'/g, "''") + "'"
  4654. };
  4655. var serializePropName = function(propName) {
  4656. if (propName instanceof EdmLiteral)
  4657. return propName.valueOf();
  4658. return propName.replace(/\./g, "/")
  4659. };
  4660. var serializeValueV4 = function(value) {
  4661. if (value instanceof Date)
  4662. return utils.formatIso8601Date(value);
  4663. return serializeValueV2(value)
  4664. };
  4665. var serializeValueV2 = function(value) {
  4666. if (value instanceof Date)
  4667. return serializeDate(value);
  4668. if (value instanceof Guid)
  4669. return "guid'" + value + "'";
  4670. if (value instanceof EdmLiteral)
  4671. return value.valueOf();
  4672. if (typeof value === "string")
  4673. return serializeString(value);
  4674. return String(value)
  4675. };
  4676. var DEFAULT_PROTOCOL_VERSION = 2;
  4677. var serializeValue = function(value, protocolVersion) {
  4678. protocolVersion = protocolVersion || DEFAULT_PROTOCOL_VERSION;
  4679. switch (protocolVersion) {
  4680. case 2:
  4681. case 3:
  4682. return serializeValueV2(value);
  4683. case 4:
  4684. return serializeValueV4(value);
  4685. default:
  4686. throw new Error("Unknown OData protocol version");
  4687. }
  4688. };
  4689. var serializeKey = function(key, protocolVersion) {
  4690. if ($.isPlainObject(key)) {
  4691. var parts = [];
  4692. $.each(key, function(k, v) {
  4693. parts.push(serializePropName(k) + "=" + serializeValue(v, protocolVersion))
  4694. });
  4695. return parts.join()
  4696. }
  4697. return serializeValue(key)
  4698. };
  4699. var keyConverters = {
  4700. String: function(value) {
  4701. return value + ""
  4702. },
  4703. Int32: function(value) {
  4704. return Math.floor(value)
  4705. },
  4706. Int64: function(value) {
  4707. if (value instanceof EdmLiteral)
  4708. return value;
  4709. return new EdmLiteral(value + "L")
  4710. },
  4711. Guid: function(value) {
  4712. if (value instanceof Guid)
  4713. return value;
  4714. return new Guid(value)
  4715. },
  4716. Boolean: function(value) {
  4717. return !!value
  4718. },
  4719. Single: function(value) {
  4720. if (value instanceof EdmLiteral)
  4721. return value;
  4722. return new EdmLiteral(value + "f")
  4723. },
  4724. Decimal: function(value) {
  4725. if (value instanceof EdmLiteral)
  4726. return value;
  4727. return new EdmLiteral(value + "m")
  4728. }
  4729. };
  4730. var compileCriteria = function() {
  4731. var createBinaryOperationFormatter = function(op) {
  4732. return function(prop, val, bag) {
  4733. bag.push(prop, " ", op, " ", val)
  4734. }
  4735. };
  4736. var createStringFuncFormatter = function(op, reverse) {
  4737. return function(prop, val, bag) {
  4738. if (reverse)
  4739. bag.push(op, "(", val, ",", prop, ")");
  4740. else
  4741. bag.push(op, "(", prop, ",", val, ")")
  4742. }
  4743. };
  4744. var formatters = {
  4745. "=": createBinaryOperationFormatter("eq"),
  4746. "<>": createBinaryOperationFormatter("ne"),
  4747. ">": createBinaryOperationFormatter("gt"),
  4748. ">=": createBinaryOperationFormatter("ge"),
  4749. "<": createBinaryOperationFormatter("lt"),
  4750. "<=": createBinaryOperationFormatter("le"),
  4751. startswith: createStringFuncFormatter("startswith"),
  4752. endswith: createStringFuncFormatter("endswith"),
  4753. // yo2dh : 2015-02-11 여기서 변환하지 않고 ODATA URI를 직접 입력
  4754. passby: function(prop, val, bag) {
  4755. bag.push(prop);
  4756. }
  4757. };
  4758. var formattersV2 = $.extend({}, formatters, {
  4759. contains: createStringFuncFormatter("substringof", true),
  4760. notcontains: createStringFuncFormatter("not substringof", true)
  4761. });
  4762. var formattersV4 = $.extend({}, formatters, {
  4763. contains: createStringFuncFormatter("contains"),
  4764. notcontains: createStringFuncFormatter("not contains")
  4765. });
  4766. var compileBinary = function(criteria, bag, protocolVersion) {
  4767. criteria = data.utils.normalizeBinaryCriterion(criteria);
  4768. var op = criteria[1],
  4769. formatters = protocolVersion === 4 ? formattersV4 : formattersV2,
  4770. formatter = formatters[op.toLowerCase()];
  4771. if (!formatter)
  4772. throw Error("Unknown filter operation: " + op);
  4773. formatter(serializePropName(criteria[0]), serializeValue(criteria[2], protocolVersion), bag)
  4774. };
  4775. var compileGroup = function(criteria, bag, protocolVersion) {
  4776. var pushAnd = false;
  4777. $.each(criteria, function() {
  4778. if ($.isArray(this)) {
  4779. if (pushAnd)
  4780. bag.push(" and ");
  4781. bag.push("(");
  4782. compileCore(this, bag, protocolVersion);
  4783. bag.push(")");
  4784. pushAnd = true
  4785. }
  4786. else {
  4787. bag.push(/and|&/i.test(this) ? " and " : " or ");
  4788. pushAnd = false
  4789. }
  4790. })
  4791. };
  4792. var compileCore = function(criteria, bag, protocolVersion) {
  4793. if ($.isArray(criteria[0]))
  4794. compileGroup(criteria, bag, protocolVersion);
  4795. else
  4796. compileBinary(criteria, bag, protocolVersion)
  4797. };
  4798. return function(criteria, protocolVersion) {
  4799. var bag = [];
  4800. compileCore(criteria, bag, protocolVersion);
  4801. return bag.join("")
  4802. }
  4803. }();
  4804. var createODataQueryAdapter = function(queryOptions) {
  4805. var sorting = [],
  4806. criteria = [],
  4807. select,
  4808. skip,
  4809. take,
  4810. countQuery;
  4811. var hasSlice = function() {
  4812. return skip || take !== undefined
  4813. };
  4814. var sortCore = function(getter, desc, reset) {
  4815. if (hasSlice() || typeof getter !== "string")
  4816. return false;
  4817. if (reset)
  4818. sorting = [];
  4819. var rule = serializePropName(getter);
  4820. if (desc)
  4821. rule += " desc";
  4822. sorting.push(rule)
  4823. };
  4824. var generateExpand = function() {
  4825. var hash = {};
  4826. if (queryOptions.expand)
  4827. $.each($.makeArray(queryOptions.expand), function() {
  4828. hash[serializePropName(this)] = 1
  4829. });
  4830. if (select)
  4831. $.each(select, function() {
  4832. var path = this.split(".");
  4833. if (path.length < 2)
  4834. return;
  4835. path.pop();
  4836. hash[serializePropName(path.join("."))] = 1
  4837. });
  4838. return $.map(hash, function(k, v) {
  4839. return v
  4840. }).join() || undefined
  4841. };
  4842. var requestData = function() {
  4843. var result = {};
  4844. if (!countQuery) {
  4845. if (sorting.length)
  4846. result["$orderby"] = sorting.join(",");
  4847. if (skip)
  4848. result["$skip"] = skip;
  4849. if (take !== undefined)
  4850. result["$top"] = take;
  4851. if (select)
  4852. result["$select"] = serializePropName(select.join());
  4853. result["$expand"] = generateExpand()
  4854. }
  4855. if (criteria.length)
  4856. result["$filter"] = compileCriteria(criteria.length < 2 ? criteria[0] : criteria, queryOptions.version);
  4857. if (countQuery)
  4858. result["$top"] = 0;
  4859. if (queryOptions.requireTotalCount || countQuery)
  4860. if (queryOptions.version !== 4)
  4861. result["$inlinecount"] = "allpages";
  4862. else
  4863. result["$count"] = "true";
  4864. return result
  4865. };
  4866. return {
  4867. exec: function(url) {
  4868. return sendRequest({
  4869. url: url,
  4870. params: $.extend(requestData(), queryOptions && queryOptions.params)
  4871. }, {
  4872. beforeSend: queryOptions.beforeSend,
  4873. jsonp: queryOptions.jsonp,
  4874. withCredentials: queryOptions.withCredentials,
  4875. countOnly: countQuery
  4876. })
  4877. },
  4878. sortBy: function(getter, desc) {
  4879. return sortCore(getter, desc, true)
  4880. },
  4881. thenBy: function(getter, desc) {
  4882. return sortCore(getter, desc, false)
  4883. },
  4884. slice: function(skipCount, takeCount) {
  4885. if (hasSlice())
  4886. return false;
  4887. skip = skipCount;
  4888. take = takeCount
  4889. },
  4890. filter: function(criterion) {
  4891. if (hasSlice() || $.isFunction(criterion))
  4892. return false;
  4893. if (!$.isArray(criterion))
  4894. criterion = $.makeArray(arguments);
  4895. if (criteria.length)
  4896. criteria.push("and");
  4897. criteria.push(criterion)
  4898. },
  4899. select: function(expr) {
  4900. if (select || $.isFunction(expr))
  4901. return false;
  4902. if (!$.isArray(expr))
  4903. expr = $.makeArray(arguments);
  4904. select = expr
  4905. },
  4906. count: function() {
  4907. countQuery = true
  4908. }
  4909. }
  4910. };
  4911. $.extend(true, data, {
  4912. EdmLiteral: EdmLiteral,
  4913. utils: {odata: {
  4914. sendRequest: sendRequest,
  4915. serializePropName: serializePropName,
  4916. serializeValue: serializeValue,
  4917. serializeKey: serializeKey,
  4918. keyConverters: keyConverters
  4919. }},
  4920. queryAdapters: {odata: createODataQueryAdapter}
  4921. });
  4922. data.OData__internals = {interpretJsonFormat: interpretJsonFormat}
  4923. })(jQuery, DevExpress);
  4924. /*! Module core, file data.store.abstract.js */
  4925. (function($, DX, undefined) {
  4926. var Class = DX.Class,
  4927. abstract = DX.abstract,
  4928. data = DX.data,
  4929. normalizeSortingInfo = data.utils.normalizeSortingInfo;
  4930. var STORE_CALLBACK_NAMES = ["loading", "loaded", "modifying", "modified", "inserting", "inserted", "updating", "updated", "removing", "removed"];
  4931. function multiLevelGroup(query, groupInfo) {
  4932. query = query.groupBy(groupInfo[0].selector);
  4933. if (groupInfo.length > 1)
  4934. query = query.select(function(g) {
  4935. return $.extend({}, g, {items: multiLevelGroup(data.query(g.items), groupInfo.slice(1)).toArray()})
  4936. });
  4937. return query
  4938. }
  4939. data.utils.multiLevelGroup = multiLevelGroup;
  4940. function arrangeSortingInfo(groupInfo, sortInfo) {
  4941. var filteredGroup = [];
  4942. $.each(groupInfo, function(_, group) {
  4943. var collision = $.grep(sortInfo, function(sort) {
  4944. return group.selector == sort.selector
  4945. });
  4946. if (collision.length < 1)
  4947. filteredGroup.push(group)
  4948. });
  4949. return filteredGroup.concat(sortInfo)
  4950. }
  4951. data.Store = Class.inherit({
  4952. ctor: function(options) {
  4953. var that = this;
  4954. options = options || {};
  4955. $.each(STORE_CALLBACK_NAMES, function() {
  4956. var callbacks = that[this] = $.Callbacks();
  4957. if (this in options)
  4958. callbacks.add(options[this])
  4959. });
  4960. this._key = options.key;
  4961. this._errorHandler = options.errorHandler;
  4962. this._useDefaultSearch = true
  4963. },
  4964. _customLoadOptions: function() {
  4965. return null
  4966. },
  4967. key: function() {
  4968. return this._key
  4969. },
  4970. keyOf: function(obj) {
  4971. if (!this._keyGetter)
  4972. this._keyGetter = data.utils.compileGetter(this.key());
  4973. return this._keyGetter(obj)
  4974. },
  4975. _requireKey: function() {
  4976. if (!this.key())
  4977. throw Error("Key expression is required for this operation");
  4978. },
  4979. load: function(options) {
  4980. var that = this;
  4981. options = options || {};
  4982. this.loading.fire(options);
  4983. return this._loadImpl(options).done(function(result, extra) {
  4984. that.loaded.fire(result, extra)
  4985. })
  4986. },
  4987. _loadImpl: function(options) {
  4988. var filter = options.filter,
  4989. sort = options.sort,
  4990. select = options.select,
  4991. group = options.group,
  4992. skip = options.skip,
  4993. take = options.take,
  4994. q = this.createQuery(options);
  4995. if (filter)
  4996. q = q.filter(filter);
  4997. if (group)
  4998. group = normalizeSortingInfo(group);
  4999. if (sort || group) {
  5000. sort = normalizeSortingInfo(sort || []);
  5001. if (group)
  5002. sort = arrangeSortingInfo(group, sort);
  5003. $.each(sort, function(index) {
  5004. q = q[index ? "thenBy" : "sortBy"](this.selector, this.desc)
  5005. })
  5006. }
  5007. if (select)
  5008. q = q.select(select);
  5009. if (group)
  5010. q = multiLevelGroup(q, group);
  5011. if (take || skip)
  5012. q = q.slice(skip || 0, take);
  5013. return q.enumerate()
  5014. },
  5015. createQuery: abstract,
  5016. totalCount: function(options) {
  5017. return this._addFailHandlers(this._totalCountImpl(options))
  5018. },
  5019. _totalCountImpl: function(options) {
  5020. options = options || {};
  5021. var q = this.createQuery(),
  5022. group = options.group,
  5023. filter = options.filter;
  5024. if (filter)
  5025. q = q.filter(filter);
  5026. if (group) {
  5027. group = normalizeSortingInfo(group);
  5028. q = multiLevelGroup(q, group)
  5029. }
  5030. return q.count()
  5031. },
  5032. byKey: function(key, extraOptions) {
  5033. return this._addFailHandlers(this._byKeyImpl(key, extraOptions))
  5034. },
  5035. _byKeyImpl: abstract,
  5036. insert: function(values) {
  5037. var that = this;
  5038. that.modifying.fire();
  5039. that.inserting.fire(values);
  5040. return that._addFailHandlers(that._insertImpl(values).done(function(callbackValues, callbackKey) {
  5041. that.inserted.fire(callbackValues, callbackKey);
  5042. that.modified.fire()
  5043. }))
  5044. },
  5045. _insertImpl: abstract,
  5046. update: function(key, values) {
  5047. var that = this;
  5048. that.modifying.fire();
  5049. that.updating.fire(key, values);
  5050. return that._addFailHandlers(that._updateImpl(key, values).done(function(callbackKey, callbackValues) {
  5051. that.updated.fire(callbackKey, callbackValues);
  5052. that.modified.fire()
  5053. }))
  5054. },
  5055. _updateImpl: abstract,
  5056. remove: function(key) {
  5057. var that = this;
  5058. that.modifying.fire();
  5059. that.removing.fire(key);
  5060. return that._addFailHandlers(that._removeImpl(key).done(function(callbackKey) {
  5061. that.removed.fire(callbackKey);
  5062. that.modified.fire()
  5063. }))
  5064. },
  5065. _removeImpl: abstract,
  5066. _addFailHandlers: function(deferred) {
  5067. return deferred.fail(this._errorHandler, data._handleError)
  5068. }
  5069. })
  5070. })(jQuery, DevExpress);
  5071. /*! Module core, file data.store.array.js */
  5072. (function($, DX, undefined) {
  5073. var data = DX.data,
  5074. Guid = data.Guid;
  5075. var trivialPromise = function(_) {
  5076. var d = $.Deferred();
  5077. return d.resolve.apply(d, arguments).promise()
  5078. };
  5079. var rejectedPromise = function(_) {
  5080. var d = $.Deferred();
  5081. return d.reject.apply(d, arguments).promise()
  5082. };
  5083. data.ArrayStore = data.Store.inherit({
  5084. ctor: function(options) {
  5085. if ($.isArray(options))
  5086. options = {data: options};
  5087. else
  5088. options = options || {};
  5089. this.callBase(options);
  5090. var initialArray = options.data;
  5091. if (initialArray && !$.isArray(initialArray))
  5092. throw Error("Invalid 'data' option value");
  5093. this._array = initialArray || []
  5094. },
  5095. createQuery: function() {
  5096. return data.query(this._array, {errorHandler: this._errorHandler})
  5097. },
  5098. _byKeyImpl: function(key) {
  5099. return trivialPromise(this._array[this._indexByKey(key)])
  5100. },
  5101. _insertImpl: function(values) {
  5102. var keyExpr = this.key(),
  5103. keyValue,
  5104. obj = {};
  5105. $.extend(obj, values);
  5106. if (keyExpr) {
  5107. keyValue = this.keyOf(obj);
  5108. if (keyValue === undefined || typeof keyValue === "object" && $.isEmptyObject(keyValue)) {
  5109. if ($.isArray(keyExpr))
  5110. throw Error("Compound keys cannot be auto-generated");
  5111. keyValue = obj[keyExpr] = String(new Guid)
  5112. }
  5113. else if (this._array[this._indexByKey(keyValue)] !== undefined)
  5114. return rejectedPromise(Error("Attempt to insert an item with the duplicate key"))
  5115. }
  5116. else
  5117. keyValue = obj;
  5118. this._array.push(obj);
  5119. return trivialPromise(values, keyValue)
  5120. },
  5121. _updateImpl: function(key, values) {
  5122. var target;
  5123. if (this.key()) {
  5124. var index = this._indexByKey(key);
  5125. if (index < 0)
  5126. return rejectedPromise(Error("Data item not found"));
  5127. target = this._array[index]
  5128. }
  5129. else
  5130. target = key;
  5131. DX.utils.deepExtendArraySafe(target, values);
  5132. return trivialPromise(key, values)
  5133. },
  5134. _removeImpl: function(key) {
  5135. var index = this._indexByKey(key);
  5136. if (index > -1)
  5137. this._array.splice(index, 1);
  5138. return trivialPromise(key)
  5139. },
  5140. _indexByKey: function(key) {
  5141. for (var i = 0, arrayLength = this._array.length; i < arrayLength; i++)
  5142. if (data.utils.keysEqual(this.key(), this.keyOf(this._array[i]), key))
  5143. return i;
  5144. return -1
  5145. },
  5146. clear: function() {
  5147. this._array = []
  5148. }
  5149. })
  5150. })(jQuery, DevExpress);
  5151. /*! Module core, file data.store.local.js */
  5152. (function($, DX, undefined) {
  5153. var Class = DX.Class,
  5154. abstract = DX.abstract,
  5155. data = DX.data;
  5156. var LocalStoreBackend = Class.inherit({
  5157. ctor: function(store, storeOptions) {
  5158. this._store = store;
  5159. this._dirty = false;
  5160. var immediate = this._immediate = storeOptions.immediate;
  5161. var flushInterval = Math.max(100, storeOptions.flushInterval || 10 * 1000);
  5162. if (!immediate) {
  5163. var saveProxy = $.proxy(this.save, this);
  5164. setInterval(saveProxy, flushInterval);
  5165. $(window).on("beforeunload", saveProxy);
  5166. if (window.cordova)
  5167. document.addEventListener("pause", saveProxy, false)
  5168. }
  5169. },
  5170. notifyChanged: function() {
  5171. this._dirty = true;
  5172. if (this._immediate)
  5173. this.save()
  5174. },
  5175. load: function() {
  5176. this._store._array = this._loadImpl();
  5177. this._dirty = false
  5178. },
  5179. save: function() {
  5180. if (!this._dirty)
  5181. return;
  5182. this._saveImpl(this._store._array);
  5183. this._dirty = false
  5184. },
  5185. _loadImpl: abstract,
  5186. _saveImpl: abstract
  5187. });
  5188. var DomLocalStoreBackend = LocalStoreBackend.inherit({
  5189. ctor: function(store, storeOptions) {
  5190. this.callBase(store, storeOptions);
  5191. var name = storeOptions.name;
  5192. if (!name)
  5193. throw Error("Name is required");
  5194. this._key = "dx-data-localStore-" + name
  5195. },
  5196. _loadImpl: function() {
  5197. var raw = localStorage.getItem(this._key);
  5198. if (raw)
  5199. return JSON.parse(raw);
  5200. return []
  5201. },
  5202. _saveImpl: function(array) {
  5203. if (!array.length)
  5204. localStorage.removeItem(this._key);
  5205. else
  5206. localStorage.setItem(this._key, JSON.stringify(array))
  5207. }
  5208. });
  5209. var localStoreBackends = {dom: DomLocalStoreBackend};
  5210. data.LocalStore = data.ArrayStore.inherit({
  5211. ctor: function(options) {
  5212. if (typeof options === "string")
  5213. options = {name: options};
  5214. else
  5215. options = options || {};
  5216. this.callBase(options);
  5217. this._backend = new localStoreBackends[options.backend || "dom"](this, options);
  5218. this._backend.load()
  5219. },
  5220. clear: function() {
  5221. this.callBase();
  5222. this._backend.notifyChanged()
  5223. },
  5224. _insertImpl: function(values) {
  5225. var b = this._backend;
  5226. return this.callBase(values).done($.proxy(b.notifyChanged, b))
  5227. },
  5228. _updateImpl: function(key, values) {
  5229. var b = this._backend;
  5230. return this.callBase(key, values).done($.proxy(b.notifyChanged, b))
  5231. },
  5232. _removeImpl: function(key) {
  5233. var b = this._backend;
  5234. return this.callBase(key).done($.proxy(b.notifyChanged, b))
  5235. }
  5236. })
  5237. })(jQuery, DevExpress);
  5238. /*! Module core, file data.store.odata.js */
  5239. (function($, DX, undefined) {
  5240. var Class = DX.Class,
  5241. data = DX.data,
  5242. utils = DX.utils,
  5243. odataUtils = data.utils.odata;
  5244. var escapeServiceOperationParams = function(params, version) {
  5245. if (!params)
  5246. return params;
  5247. var result = {};
  5248. $.each(params, function(k, v) {
  5249. result[k] = odataUtils.serializeValue(v, version)
  5250. });
  5251. return result
  5252. };
  5253. var convertSimpleKey = function(keyType, keyValue) {
  5254. var converter = odataUtils.keyConverters[keyType];
  5255. if (!converter)
  5256. throw Error("Unknown key type: " + keyType);
  5257. return converter(keyValue)
  5258. };
  5259. var SharedMethods = {
  5260. _extractServiceOptions: function(options) {
  5261. options = options || {};
  5262. this._url = String(options.url).replace(/\/+$/, "");
  5263. this._beforeSend = options.beforeSend;
  5264. this._jsonp = options.jsonp;
  5265. this._version = options.version;
  5266. this._withCredentials = options.withCredentials
  5267. },
  5268. _sendRequest: function(url, method, params, payload) {
  5269. return odataUtils.sendRequest({
  5270. url: url,
  5271. method: method,
  5272. params: params || {},
  5273. payload: payload
  5274. }, {
  5275. beforeSend: this._beforeSend,
  5276. jsonp: this._jsonp,
  5277. withCredentials: this._withCredentials
  5278. })
  5279. },
  5280. version: function() {
  5281. return this._version
  5282. }
  5283. };
  5284. var ODataStore = data.Store.inherit({
  5285. ctor: function(options) {
  5286. this.callBase(options);
  5287. this._extractServiceOptions(options);
  5288. this._keyType = options.keyType
  5289. },
  5290. _customLoadOptions: function() {
  5291. return ["expand", "customQueryParams"]
  5292. },
  5293. _byKeyImpl: function(key, extraOptions) {
  5294. var params = {};
  5295. if (extraOptions)
  5296. if (extraOptions.expand)
  5297. params["$expand"] = $.map($.makeArray(extraOptions.expand), odataUtils.serializePropName).join();
  5298. return this._sendRequest(this._byKeyUrl(key), "GET", params)
  5299. },
  5300. createQuery: function(loadOptions) {
  5301. loadOptions = loadOptions || {};
  5302. return data.query(this._url, {
  5303. beforeSend: this._beforeSend,
  5304. errorHandler: this._errorHandler,
  5305. jsonp: this._jsonp,
  5306. version: this._version,
  5307. withCredentials: this._withCredentials,
  5308. params: escapeServiceOperationParams(loadOptions.customQueryParams, this._version),
  5309. expand: loadOptions.expand,
  5310. requireTotalCount: loadOptions.requireTotalCount
  5311. })
  5312. },
  5313. _insertImpl: function(values) {
  5314. this._requireKey();
  5315. var that = this,
  5316. d = $.Deferred();
  5317. $.when(this._sendRequest(this._url, "POST", null, values)).done(function(serverResponse) {
  5318. d.resolve(values, that.keyOf(serverResponse))
  5319. }).fail($.proxy(d.reject, d));
  5320. return d.promise()
  5321. },
  5322. _updateImpl: function(key, values) {
  5323. var d = $.Deferred();
  5324. $.when(this._sendRequest(this._byKeyUrl(key), "MERGE", null, values)).done(function() {
  5325. d.resolve(key, values)
  5326. }).fail($.proxy(d.reject, d));
  5327. return d.promise()
  5328. },
  5329. _removeImpl: function(key) {
  5330. var d = $.Deferred();
  5331. $.when(this._sendRequest(this._byKeyUrl(key), "DELETE")).done(function() {
  5332. d.resolve(key)
  5333. }).fail($.proxy(d.reject, d));
  5334. return d.promise()
  5335. },
  5336. _byKeyUrl: function(key) {
  5337. var keyType = this._keyType;
  5338. if ($.isPlainObject(keyType))
  5339. $.each(keyType, function(subKeyName, subKeyType) {
  5340. key[subKeyName] = convertSimpleKey(subKeyType, key[subKeyName])
  5341. });
  5342. else if (keyType)
  5343. key = convertSimpleKey(keyType, key);
  5344. return this._url + "(" + encodeURIComponent(odataUtils.serializeKey(key, this._version)) + ")"
  5345. }
  5346. }).include(SharedMethods);
  5347. var ODataContext = Class.inherit({
  5348. ctor: function(options) {
  5349. var that = this;
  5350. that._extractServiceOptions(options);
  5351. that._errorHandler = options.errorHandler;
  5352. $.each(options.entities || [], function(entityAlias, entityOptions) {
  5353. that[entityAlias] = new ODataStore($.extend({}, options, {url: that._url + "/" + encodeURIComponent(entityOptions.name || entityAlias)}, entityOptions))
  5354. })
  5355. },
  5356. get: function(operationName, params) {
  5357. return this.invoke(operationName, params, "GET")
  5358. },
  5359. invoke: function(operationName, params, httpMethod) {
  5360. httpMethod = httpMethod || "POST";
  5361. var d = $.Deferred();
  5362. $.when(this._sendRequest(this._url + "/" + encodeURIComponent(operationName), httpMethod, escapeServiceOperationParams(params, this._version))).done(function(r) {
  5363. if (r && operationName in r)
  5364. r = r[operationName];
  5365. d.resolve(r)
  5366. }).fail([this._errorHandler, data._handleError, $.proxy(d.reject, d)]);
  5367. return d.promise()
  5368. },
  5369. objectLink: function(entityAlias, key) {
  5370. var store = this[entityAlias];
  5371. if (!store)
  5372. throw Error("Unknown entity name or alias: " + entityAlias);
  5373. if (!utils.isDefined(key))
  5374. return null;
  5375. return {__metadata: {uri: store._byKeyUrl(key)}}
  5376. }
  5377. }).include(SharedMethods);
  5378. $.extend(data, {
  5379. ODataStore: ODataStore,
  5380. ODataContext: ODataContext
  5381. })
  5382. })(jQuery, DevExpress);
  5383. /*! Module core, file data.store.rest.js */
  5384. (function($, DX, undefined) {
  5385. var data = DX.data;
  5386. function createAjaxFailureHandler(deferred) {
  5387. return function(xhr, textStatus) {
  5388. if (!xhr || !xhr.getResponseHeader)
  5389. deferred.reject.apply(deferred, arguments);
  5390. else
  5391. deferred.reject(Error(data.utils.errorMessageFromXhr(xhr, textStatus)))
  5392. }
  5393. }
  5394. function operationCustomizerPropName(operationName) {
  5395. return "_customize" + DX.inflector.camelize(operationName, true)
  5396. }
  5397. function pathPropName(operationName) {
  5398. return "_" + operationName + "Path"
  5399. }
  5400. data.RestStore = data.Store.inherit({
  5401. ctor: function(options) {
  5402. DX.utils.logger.warn("RestStore is deprecated, use CustomStore instead");
  5403. var that = this;
  5404. that.callBase(options);
  5405. options = options || {};
  5406. that._url = String(options.url).replace(/\/+$/, "");
  5407. that._jsonp = options.jsonp;
  5408. that._withCredentials = options.withCredentials;
  5409. $.each(["Load", "Insert", "Update", "Remove", "ByKey", "Operation"], function() {
  5410. var value = options["customize" + this];
  5411. if (value)
  5412. that[operationCustomizerPropName(this)] = value
  5413. });
  5414. $.each(["load", "insert", "update", "remove", "byKey"], function() {
  5415. var value = options[this + "Path"];
  5416. if (value)
  5417. that[pathPropName(this)] = value
  5418. })
  5419. },
  5420. _loadImpl: function(options) {
  5421. var d = $.Deferred(),
  5422. ajaxOptions = {
  5423. url: this._formatUrlNoKey("load"),
  5424. type: "GET"
  5425. };
  5426. $.when(this._createAjax(ajaxOptions, "load", options)).done($.proxy(d.resolve, d)).fail(createAjaxFailureHandler(d));
  5427. return this._addFailHandlers(d.promise())
  5428. },
  5429. createQuery: function() {
  5430. throw Error("Not supported");
  5431. },
  5432. _insertImpl: function(values) {
  5433. var d = $.Deferred(),
  5434. that = this,
  5435. ajaxOptions = {
  5436. url: this._formatUrlNoKey("insert"),
  5437. type: "POST",
  5438. contentType: "application/json",
  5439. data: JSON.stringify(values)
  5440. };
  5441. $.when(this._createAjax(ajaxOptions, "insert")).done(function(serverResponse) {
  5442. d.resolve(values, that.key() && that.keyOf(serverResponse))
  5443. }).fail(createAjaxFailureHandler(d));
  5444. return d.promise()
  5445. },
  5446. _updateImpl: function(key, values) {
  5447. var d = $.Deferred(),
  5448. ajaxOptions = {
  5449. url: this._formatUrlWithKey("update", key),
  5450. type: "PUT",
  5451. contentType: "application/json",
  5452. data: JSON.stringify(values)
  5453. };
  5454. $.when(this._createAjax(ajaxOptions, "update")).done(function() {
  5455. d.resolve(key, values)
  5456. }).fail(createAjaxFailureHandler(d));
  5457. return d.promise()
  5458. },
  5459. _removeImpl: function(key) {
  5460. var d = $.Deferred(),
  5461. ajaxOptions = {
  5462. url: this._formatUrlWithKey("remove", key),
  5463. type: "DELETE"
  5464. };
  5465. $.when(this._createAjax(ajaxOptions, "remove")).done(function() {
  5466. d.resolve(key)
  5467. }).fail(createAjaxFailureHandler(d));
  5468. return d.promise()
  5469. },
  5470. _byKeyImpl: function(key) {
  5471. var d = $.Deferred(),
  5472. ajaxOptions = {
  5473. url: this._formatUrlWithKey("byKey", key),
  5474. type: "GET"
  5475. };
  5476. $.when(this._createAjax(ajaxOptions, "byKey")).done(function(data) {
  5477. d.resolve(data)
  5478. }).fail(createAjaxFailureHandler(d));
  5479. return d.promise()
  5480. },
  5481. _createAjax: function(ajaxOptions, operationName, extra) {
  5482. var customizationFunc,
  5483. customizationResult;
  5484. function isDeferred(obj) {
  5485. return "done" in obj && "fail" in obj
  5486. }
  5487. if (this._jsonp && ajaxOptions.type === "GET")
  5488. ajaxOptions.dataType = "jsonp";
  5489. else
  5490. $.extend(true, ajaxOptions, {xhrFields: {withCredentials: this._withCredentials}});
  5491. customizationFunc = this[operationCustomizerPropName("operation")];
  5492. if (customizationFunc) {
  5493. customizationResult = customizationFunc(ajaxOptions, operationName, extra);
  5494. if (customizationResult) {
  5495. if (isDeferred(customizationResult))
  5496. return customizationResult;
  5497. ajaxOptions = customizationResult
  5498. }
  5499. }
  5500. customizationFunc = this[operationCustomizerPropName(operationName)];
  5501. if (customizationFunc) {
  5502. customizationResult = customizationFunc(ajaxOptions, extra);
  5503. if (customizationResult) {
  5504. if (isDeferred(customizationResult))
  5505. return customizationResult;
  5506. ajaxOptions = customizationResult
  5507. }
  5508. }
  5509. return $.ajax(ajaxOptions)
  5510. },
  5511. _formatUrlNoKey: function(operationName) {
  5512. var url = this._url,
  5513. path = this[pathPropName(operationName)];
  5514. if (!path)
  5515. return url;
  5516. if ($.isFunction(path))
  5517. return path(url);
  5518. return url + "/" + path
  5519. },
  5520. _formatUrlWithKey: function(operationName, key) {
  5521. var url = this._url,
  5522. path = this[pathPropName(operationName)];
  5523. if (!path)
  5524. return url + "/" + encodeURIComponent(key);
  5525. if ($.isFunction(path))
  5526. return path(url, key);
  5527. return url + "/" + path + "/" + encodeURIComponent(key)
  5528. }
  5529. })
  5530. })(jQuery, DevExpress);
  5531. /*! Module core, file data.store.custom.js */
  5532. (function($, DX, undefined) {
  5533. var data = DX.data;
  5534. var ERROR_QUERY_NOT_SUPPORTED = "CustomStore does not support creating queries",
  5535. ERROR_MISSING_USER_FUNC = "Required option is not specified or is not a function: ",
  5536. ERROR_INVALID_RETURN = "Invalid return value: ";
  5537. var TOTAL_COUNT = "totalCount",
  5538. LOAD = "load",
  5539. BY_KEY = "byKey",
  5540. INSERT = "insert",
  5541. UPDATE = "update",
  5542. REMOVE = "remove";
  5543. function isPromise(obj) {
  5544. return obj && $.isFunction(obj.done) && $.isFunction(obj.fail) && $.isFunction(obj.promise)
  5545. }
  5546. function trivialPromise(value) {
  5547. return $.Deferred().resolve(value).promise()
  5548. }
  5549. function ensureRequiredFuncOption(name, obj) {
  5550. if (!$.isFunction(obj))
  5551. throw Error(ERROR_MISSING_USER_FUNC + name);
  5552. }
  5553. function throwInvalidUserFuncResult(name) {
  5554. throw Error(ERROR_INVALID_RETURN + name);
  5555. }
  5556. function createUserFuncFailureHandler(pendingDeferred) {
  5557. function errorMessageFromXhr(promiseArguments) {
  5558. var xhr = promiseArguments[0],
  5559. textStatus = promiseArguments[1];
  5560. if (!xhr || !xhr.getResponseHeader)
  5561. return null;
  5562. return data.utils.errorMessageFromXhr(xhr, textStatus)
  5563. }
  5564. return function(arg) {
  5565. var error;
  5566. if (arg instanceof Error)
  5567. error = arg;
  5568. else
  5569. error = Error(errorMessageFromXhr(arguments) || arg && String(arg) || "Unknown error");
  5570. pendingDeferred.reject(error)
  5571. }
  5572. }
  5573. data.CustomStore = data.Store.inherit({
  5574. ctor: function(options) {
  5575. options = options || {};
  5576. this.callBase(options);
  5577. this._useDefaultSearch = false;
  5578. this._loadFunc = options[LOAD];
  5579. this._totalCountFunc = options[TOTAL_COUNT];
  5580. this._byKeyFunc = options[BY_KEY] || options.lookup;
  5581. this._insertFunc = options[INSERT];
  5582. this._updateFunc = options[UPDATE];
  5583. this._removeFunc = options[REMOVE]
  5584. },
  5585. createQuery: function() {
  5586. throw Error(ERROR_QUERY_NOT_SUPPORTED);
  5587. },
  5588. _totalCountImpl: function(options) {
  5589. var userFunc = this._totalCountFunc,
  5590. userResult,
  5591. d = $.Deferred();
  5592. ensureRequiredFuncOption(TOTAL_COUNT, userFunc);
  5593. userResult = userFunc(options);
  5594. if (!isPromise(userResult)) {
  5595. userResult = Number(userResult);
  5596. if (!isFinite(userResult))
  5597. throwInvalidUserFuncResult(TOTAL_COUNT);
  5598. userResult = trivialPromise(userResult)
  5599. }
  5600. userResult.done(function(count) {
  5601. d.resolve(Number(count))
  5602. }).fail(createUserFuncFailureHandler(d));
  5603. return d.promise()
  5604. },
  5605. _loadImpl: function(options) {
  5606. var userFunc = this._loadFunc,
  5607. userResult,
  5608. d = $.Deferred();
  5609. ensureRequiredFuncOption(LOAD, userFunc);
  5610. userResult = userFunc(options);
  5611. if ($.isArray(userResult))
  5612. userResult = trivialPromise(userResult);
  5613. else if (userResult === null || userResult === undefined)
  5614. userResult = trivialPromise([]);
  5615. else if (!isPromise(userResult))
  5616. throwInvalidUserFuncResult(LOAD);
  5617. userResult.done(function(data, extra) {
  5618. d.resolve(data, extra)
  5619. }).fail(createUserFuncFailureHandler(d));
  5620. return this._addFailHandlers(d.promise())
  5621. },
  5622. _byKeyImpl: function(key) {
  5623. var userFunc = this._byKeyFunc,
  5624. userResult,
  5625. d = $.Deferred();
  5626. ensureRequiredFuncOption(BY_KEY, userFunc);
  5627. userResult = userFunc(key);
  5628. if (!isPromise(userResult))
  5629. userResult = trivialPromise(userResult);
  5630. userResult.done(function(obj) {
  5631. d.resolve(obj)
  5632. }).fail(createUserFuncFailureHandler(d));
  5633. return d.promise()
  5634. },
  5635. _insertImpl: function(values) {
  5636. var userFunc = this._insertFunc,
  5637. userResult,
  5638. d = $.Deferred();
  5639. ensureRequiredFuncOption(INSERT, userFunc);
  5640. userResult = userFunc(values);
  5641. if (!isPromise(userResult))
  5642. userResult = trivialPromise(userResult);
  5643. userResult.done(function(newKey) {
  5644. d.resolve(values, newKey)
  5645. }).fail(createUserFuncFailureHandler(d));
  5646. return d.promise()
  5647. },
  5648. _updateImpl: function(key, values) {
  5649. var userFunc = this._updateFunc,
  5650. userResult,
  5651. d = $.Deferred();
  5652. ensureRequiredFuncOption(UPDATE, userFunc);
  5653. userResult = userFunc(key, values);
  5654. if (!isPromise(userResult))
  5655. userResult = trivialPromise();
  5656. userResult.done(function() {
  5657. d.resolve(key, values)
  5658. }).fail(createUserFuncFailureHandler(d));
  5659. return d.promise()
  5660. },
  5661. _removeImpl: function(key) {
  5662. var userFunc = this._removeFunc,
  5663. userResult,
  5664. d = $.Deferred();
  5665. ensureRequiredFuncOption(REMOVE, userFunc);
  5666. userResult = userFunc(key);
  5667. if (!isPromise(userResult))
  5668. userResult = trivialPromise();
  5669. userResult.done(function() {
  5670. d.resolve(key)
  5671. }).fail(createUserFuncFailureHandler(d));
  5672. return d.promise()
  5673. }
  5674. });
  5675. data.CustomStore_internals = {ERRORS: {
  5676. QUERY_NOT_SUPPORTED: ERROR_QUERY_NOT_SUPPORTED,
  5677. MISSING_USER_FUNC: ERROR_MISSING_USER_FUNC,
  5678. INVALID_RETURN: ERROR_INVALID_RETURN
  5679. }}
  5680. })(jQuery, DevExpress);
  5681. /*! Module core, file data.dataSource.js */
  5682. (function($, DX, undefined) {
  5683. var data = DX.data,
  5684. CustomStore = data.CustomStore,
  5685. Class = DX.Class;
  5686. var storeTypeRegistry = {
  5687. jaydata: "JayDataStore",
  5688. breeze: "BreezeStore",
  5689. odata: "ODataStore",
  5690. local: "LocalStore",
  5691. array: "ArrayStore"
  5692. };
  5693. function normalizeDataSourceOptions(options) {
  5694. var store;
  5695. function createCustomStoreFromLoadFunc() {
  5696. var storeConfig = {};
  5697. $.each(["key", "load", "byKey", "lookup", "totalCount", "insert", "update", "remove"], function() {
  5698. storeConfig[this] = options[this];
  5699. delete options[this]
  5700. });
  5701. return new CustomStore(storeConfig)
  5702. }
  5703. function createStoreFromConfig(storeConfig) {
  5704. var storeCtor = data[storeTypeRegistry[storeConfig.type]];
  5705. delete storeConfig.type;
  5706. return new storeCtor(storeConfig)
  5707. }
  5708. function createCustomStoreFromUrl(url) {
  5709. return new CustomStore({load: function() {
  5710. return $.getJSON(url)
  5711. }})
  5712. }
  5713. if (typeof options === "string")
  5714. options = createCustomStoreFromUrl(options);
  5715. if (options === undefined)
  5716. options = [];
  5717. if ($.isArray(options) || options instanceof data.Store)
  5718. options = {store: options};
  5719. else
  5720. options = $.extend({}, options);
  5721. if (options.store === undefined)
  5722. options.store = [];
  5723. store = options.store;
  5724. if ("load" in options)
  5725. store = createCustomStoreFromLoadFunc();
  5726. else if ($.isArray(store))
  5727. store = new data.ArrayStore(store);
  5728. else if ($.isPlainObject(store))
  5729. store = createStoreFromConfig($.extend({}, store));
  5730. options.store = store;
  5731. return options
  5732. }
  5733. function normalizeStoreLoadOptionAccessorArguments(originalArguments) {
  5734. switch (originalArguments.length) {
  5735. case 0:
  5736. return undefined;
  5737. case 1:
  5738. return originalArguments[0]
  5739. }
  5740. return $.makeArray(originalArguments)
  5741. }
  5742. function generateStoreLoadOptionAccessor(optionName) {
  5743. return function() {
  5744. var args = normalizeStoreLoadOptionAccessorArguments(arguments);
  5745. if (args !== undefined)
  5746. this._storeLoadOptions[optionName] = args;
  5747. return this._storeLoadOptions[optionName]
  5748. }
  5749. }
  5750. function addOldUserDataSourceBackwardCompatibilityOptions(dataSource, storeLoadOptions) {
  5751. storeLoadOptions.refresh = !dataSource._paginate || dataSource._pageIndex === 0;
  5752. if (storeLoadOptions.searchValue !== null)
  5753. storeLoadOptions.searchString = storeLoadOptions.searchValue
  5754. }
  5755. var DataSource = Class.inherit({
  5756. ctor: function(options) {
  5757. options = normalizeDataSourceOptions(options);
  5758. this._store = options.store;
  5759. this._storeLoadOptions = this._extractLoadOptions(options);
  5760. this._mapFunc = options.map;
  5761. this._postProcessFunc = options.postProcess;
  5762. this._pageIndex = 0;
  5763. this._pageSize = options.pageSize !== undefined ? options.pageSize : 20;
  5764. this._items = [];
  5765. this._totalCount = -1;
  5766. this._isLoaded = false;
  5767. this._loadingCount = 0;
  5768. this._preferSync = options._preferSync;
  5769. this._loadQueue = this._createLoadQueue();
  5770. this._searchValue = "searchValue" in options ? options.searchValue : null;
  5771. this._searchOperation = options.searchOperation || "contains";
  5772. this._searchExpr = options.searchExpr;
  5773. this._paginate = options.paginate;
  5774. if (this._paginate === undefined)
  5775. this._paginate = !this.group();
  5776. this._isLastPage = !this._paginate;
  5777. this._userData = {};
  5778. this.changed = $.Callbacks();
  5779. this.loadError = $.Callbacks();
  5780. this.loadingChanged = $.Callbacks()
  5781. },
  5782. dispose: function() {
  5783. this.changed.empty();
  5784. this.loadError.empty();
  5785. this.loadingChanged.empty();
  5786. delete this._store;
  5787. this._disposed = true
  5788. },
  5789. _extractLoadOptions: function(options) {
  5790. var result = {},
  5791. names = ["sort", "filter", "select", "group", "requireTotalCount"],
  5792. customNames = this._store._customLoadOptions();
  5793. if (customNames)
  5794. names = names.concat(customNames);
  5795. $.each(names, function() {
  5796. result[this] = options[this]
  5797. });
  5798. return result
  5799. },
  5800. loadOptions: function() {
  5801. return this._storeLoadOptions
  5802. },
  5803. items: function() {
  5804. return this._items
  5805. },
  5806. pageIndex: function(newIndex) {
  5807. if (newIndex !== undefined) {
  5808. this._pageIndex = newIndex;
  5809. this._isLastPage = !this._paginate
  5810. }
  5811. return this._pageIndex
  5812. },
  5813. paginate: function(value) {
  5814. if (arguments.length < 1)
  5815. return this._paginate;
  5816. value = !!value;
  5817. if (this._paginate !== value) {
  5818. this._paginate = value;
  5819. this.pageIndex(0)
  5820. }
  5821. },
  5822. isLastPage: function() {
  5823. return this._isLastPage
  5824. },
  5825. sort: generateStoreLoadOptionAccessor("sort"),
  5826. filter: function() {
  5827. var newFilter = normalizeStoreLoadOptionAccessorArguments(arguments);
  5828. if (newFilter !== undefined) {
  5829. this._storeLoadOptions.filter = newFilter;
  5830. this.pageIndex(0)
  5831. }
  5832. return this._storeLoadOptions.filter
  5833. },
  5834. group: generateStoreLoadOptionAccessor("group"),
  5835. select: generateStoreLoadOptionAccessor("select"),
  5836. searchValue: function(value) {
  5837. if (value !== undefined) {
  5838. this.pageIndex(0);
  5839. this._searchValue = value
  5840. }
  5841. return this._searchValue
  5842. },
  5843. searchOperation: function(op) {
  5844. if (op !== undefined) {
  5845. this.pageIndex(0);
  5846. this._searchOperation = op
  5847. }
  5848. return this._searchOperation
  5849. },
  5850. searchExpr: function(expr) {
  5851. var argc = arguments.length;
  5852. if (argc) {
  5853. if (argc > 1)
  5854. expr = $.makeArray(arguments);
  5855. this.pageIndex(0);
  5856. this._searchExpr = expr
  5857. }
  5858. return this._searchExpr
  5859. },
  5860. store: function() {
  5861. return this._store
  5862. },
  5863. key: function() {
  5864. return this._store && this._store.key()
  5865. },
  5866. totalCount: function() {
  5867. return this._totalCount
  5868. },
  5869. isLoaded: function() {
  5870. return this._isLoaded
  5871. },
  5872. isLoading: function() {
  5873. return this._loadingCount > 0
  5874. },
  5875. _createLoadQueue: function() {
  5876. return DX.createQueue()
  5877. },
  5878. _changeLoadingCount: function(increment) {
  5879. var oldLoading = this.isLoading(),
  5880. newLoading;
  5881. this._loadingCount += increment;
  5882. newLoading = this.isLoading();
  5883. if (oldLoading ^ newLoading)
  5884. this.loadingChanged.fire(newLoading)
  5885. },
  5886. _scheduleLoadCallbacks: function(deferred) {
  5887. var thisSource = this;
  5888. thisSource._changeLoadingCount(1);
  5889. deferred.always(function() {
  5890. thisSource._changeLoadingCount(-1)
  5891. })
  5892. },
  5893. _scheduleChangedCallbacks: function(deferred) {
  5894. var that = this;
  5895. deferred.done(function() {
  5896. that.changed.fire()
  5897. })
  5898. },
  5899. loadSingle: function(propName, propValue) {
  5900. var that = this;
  5901. var d = $.Deferred().fail(this.loadError.fire),
  5902. key = this.key(),
  5903. store = this._store,
  5904. loadOptions = this._createStoreLoadOptions();
  5905. function handleSuccess(data) {
  5906. d.resolve(that._transformLoadedData(data)[0])
  5907. }
  5908. if (arguments.length < 2) {
  5909. propValue = propName;
  5910. propName = key
  5911. }
  5912. delete loadOptions.skip;
  5913. delete loadOptions.group;
  5914. delete loadOptions.refresh;
  5915. delete loadOptions.pageIndex;
  5916. delete loadOptions.searchString;
  5917. if (propName === key || store instanceof data.CustomStore)
  5918. store.byKey(propValue, loadOptions).done(handleSuccess).fail(d.reject);
  5919. else {
  5920. loadOptions.take = 1;
  5921. loadOptions._preferSync = true;
  5922. loadOptions.filter = loadOptions.filter ? [loadOptions.filter, [propName, propValue]] : [propName, propValue];
  5923. store.load(loadOptions).done(handleSuccess).fail(d.reject)
  5924. }
  5925. return d.promise()
  5926. },
  5927. load: function() {
  5928. var thisSource = this,
  5929. d = $.Deferred(),
  5930. errorCallback = this.loadError,
  5931. storeLoadOptions;
  5932. this._scheduleLoadCallbacks(d);
  5933. this._scheduleChangedCallbacks(d);
  5934. storeLoadOptions = this._createStoreLoadOptions();
  5935. function loadTask() {
  5936. if (thisSource._disposed)
  5937. return undefined;
  5938. return thisSource._loadFromStore(storeLoadOptions, d)
  5939. }
  5940. this._loadQueue.add(function() {
  5941. loadTask();
  5942. return d.promise()
  5943. }, function() {
  5944. thisSource._changeLoadingCount(-1)
  5945. });
  5946. return d.promise().fail($.proxy(errorCallback.fire, errorCallback))
  5947. },
  5948. _addSearchOptions: function(storeLoadOptions) {
  5949. if (this._disposed)
  5950. return;
  5951. if (this.store()._useDefaultSearch)
  5952. this._addSearchFilter(storeLoadOptions);
  5953. else {
  5954. storeLoadOptions.searchValue = this._searchValue;
  5955. storeLoadOptions.searchExpr = this._searchExpr
  5956. }
  5957. },
  5958. _createStoreLoadOptions: function() {
  5959. var result = $.extend({}, this._storeLoadOptions);
  5960. this._addSearchOptions(result);
  5961. if (this._paginate) {
  5962. result.pageIndex = this._pageIndex;
  5963. if (this._pageSize) {
  5964. result.skip = this._pageIndex * this._pageSize;
  5965. result.take = this._pageSize
  5966. }
  5967. }
  5968. result.userData = this._userData;
  5969. addOldUserDataSourceBackwardCompatibilityOptions(this, result);
  5970. return result
  5971. },
  5972. _addSearchFilter: function(storeLoadOptions) {
  5973. var value = this._searchValue,
  5974. op = this._searchOperation,
  5975. selector = this._searchExpr,
  5976. searchFilter = [];
  5977. if (!value)
  5978. return;
  5979. if (!selector)
  5980. selector = "this";
  5981. if (!$.isArray(selector))
  5982. selector = [selector];
  5983. $.each(selector, function(i, item) {
  5984. if (searchFilter.length)
  5985. searchFilter.push("or");
  5986. searchFilter.push([item, op, value])
  5987. });
  5988. if (storeLoadOptions.filter)
  5989. storeLoadOptions.filter = [searchFilter, storeLoadOptions.filter];
  5990. else
  5991. storeLoadOptions.filter = searchFilter
  5992. },
  5993. _loadFromStore: function(storeLoadOptions, pendingDeferred) {
  5994. var thisSource = this;
  5995. function handleSuccess(data, extra) {
  5996. function processResult() {
  5997. thisSource._processStoreLoadResult(data, extra, storeLoadOptions, pendingDeferred)
  5998. }
  5999. if (thisSource._preferSync)
  6000. processResult();
  6001. else
  6002. DX.utils.executeAsync(processResult)
  6003. }
  6004. return this.store().load(storeLoadOptions).done(handleSuccess).fail($.proxy(pendingDeferred.reject, pendingDeferred))
  6005. },
  6006. _processStoreLoadResult: function(data, extra, storeLoadOptions, pendingDeferred) {
  6007. var thisSource = this;
  6008. function resolvePendingDeferred() {
  6009. thisSource._isLoaded = true;
  6010. thisSource._totalCount = isFinite(extra.totalCount) ? extra.totalCount : -1;
  6011. return pendingDeferred.resolve(data, extra)
  6012. }
  6013. function proceedLoadingTotalCount() {
  6014. thisSource.store().totalCount(storeLoadOptions).done(function(count) {
  6015. extra.totalCount = count;
  6016. resolvePendingDeferred()
  6017. }).fail(function(){})
  6018. }
  6019. if (thisSource._disposed)
  6020. return;
  6021. data = thisSource._transformLoadedData(data);
  6022. if (!$.isPlainObject(extra))
  6023. extra = {};
  6024. thisSource._items = data;
  6025. if (!data.length || !thisSource._paginate || thisSource._pageSize && data.length < thisSource._pageSize)
  6026. thisSource._isLastPage = true;
  6027. if (storeLoadOptions.requireTotalCount && !isFinite(extra.totalCount))
  6028. proceedLoadingTotalCount();
  6029. else
  6030. resolvePendingDeferred()
  6031. },
  6032. _transformLoadedData: function(data) {
  6033. var result = $.makeArray(data);
  6034. if (this._mapFunc)
  6035. result = $.map(result, this._mapFunc);
  6036. if (this._postProcessFunc)
  6037. result = this._postProcessFunc(result);
  6038. return result
  6039. }
  6040. });
  6041. data.Store.redefine({toDataSource: function(options) {
  6042. DX.utils.logger.warn("toDataSource() method is deprecated, use 'new DevExpress.data.DataSource(...)' instead");
  6043. return new DataSource($.extend({store: this}, options))
  6044. }});
  6045. $.extend(true, data, {
  6046. DataSource: DataSource,
  6047. createDataSource: function(options) {
  6048. DX.utils.logger.warn("createDataSource() method is deprecated, use 'new DevExpress.data.DataSource(...)' instead");
  6049. return new DataSource(options)
  6050. },
  6051. utils: {
  6052. storeTypeRegistry: storeTypeRegistry,
  6053. normalizeDataSourceOptions: normalizeDataSourceOptions
  6054. }
  6055. })
  6056. })(jQuery, DevExpress);
  6057. /*! Module core, file ko.js */
  6058. (function($, DX, undefined) {
  6059. if (!DX.support.hasKo)
  6060. return;
  6061. var ko = window.ko;
  6062. (function checkKnockoutVersion(version) {
  6063. version = version.split(".");
  6064. if (version[0] < 2 || version[0] == 2 && version[1] < 3)
  6065. throw Error("Your version of KnockoutJS is too old. Please upgrade KnockoutJS to 2.3.0 or later.");
  6066. })(ko.version)
  6067. })(jQuery, DevExpress);
  6068. /*! Module core, file ng.js */
  6069. (function($, DX, undefined) {
  6070. if (!DX.support.hasNg)
  6071. return;
  6072. DX.ng = {module: window.angular.module("dx", ["ngSanitize"])}
  6073. })(jQuery, DevExpress);
  6074. /*! Module core, file component.js */
  6075. (function($, DX, undefined) {
  6076. var ui = DX.ui,
  6077. utils = DX.utils,
  6078. dataUtils = DX.data.utils;
  6079. var Component = DX.Class.inherit({
  6080. NAME: "Component",
  6081. _deprecatedOptions: {},
  6082. _optionAliases: {},
  6083. _setDefaultOptions: function(){},
  6084. _defaultOptionsRules: function() {
  6085. return []
  6086. },
  6087. _setOptionsByDevice: function() {
  6088. var rules = this._defaultOptionsRules(),
  6089. currentDevice = DX.devices.current(),
  6090. result = {};
  6091. if (this._customRules)
  6092. rules = rules.concat(this._customRules);
  6093. var deviceMatch = function(device, filter) {
  6094. filter = $.makeArray(filter);
  6095. return filter.length === 1 && $.isEmptyObject(filter[0]) || utils.findBestMatches(device, filter).length > 0
  6096. };
  6097. $.each(rules, function(index, rule) {
  6098. var deviceFilter = rule.device || {},
  6099. match;
  6100. if ($.isFunction(deviceFilter))
  6101. match = deviceFilter(currentDevice);
  6102. else
  6103. match = deviceMatch(currentDevice, deviceFilter);
  6104. if (match)
  6105. $.extend(result, rule.options)
  6106. });
  6107. this.option(result)
  6108. },
  6109. _optionsByReference: function() {
  6110. return {}
  6111. },
  6112. ctor: function(options) {
  6113. if (!this.NAME)
  6114. throw Error("NAME is not specified");
  6115. this._options = {};
  6116. this._updateLockCount = 0;
  6117. this.optionChanged = $.Callbacks();
  6118. this.beginUpdate();
  6119. try {
  6120. this._suppressDeprecatedWarnings();
  6121. this._setDefaultOptions();
  6122. this._setOptionsByDevice();
  6123. this._resumeDeprecatedWarnings();
  6124. this._initialOptions = $.extend({}, this.option());
  6125. this._initOptions(options || {})
  6126. }
  6127. finally {
  6128. this.endUpdate()
  6129. }
  6130. },
  6131. _initOptions: function(options) {
  6132. this.option(options)
  6133. },
  6134. _optionValuesEqual: function(name, oldValue, newValue) {
  6135. oldValue = dataUtils.toComparable(oldValue, true);
  6136. newValue = dataUtils.toComparable(newValue, true);
  6137. if (oldValue && newValue && oldValue.jquery && newValue.jquery)
  6138. return newValue.is(oldValue);
  6139. if (oldValue === null || typeof oldValue !== "object")
  6140. return oldValue === newValue;
  6141. return false
  6142. },
  6143. _init: $.noop,
  6144. _optionChanged: $.noop,
  6145. instance: function() {
  6146. return this
  6147. },
  6148. beginUpdate: function() {
  6149. this._updateLockCount++
  6150. },
  6151. endUpdate: function() {
  6152. this._updateLockCount--;
  6153. if (!this._updateLockCount)
  6154. if (!this._initializing && !this._initialized) {
  6155. this._initializing = true;
  6156. try {
  6157. this._init()
  6158. }
  6159. finally {
  6160. this._initializing = false;
  6161. this._initialized = true
  6162. }
  6163. }
  6164. },
  6165. _logWarningIfDeprecated: function(option) {
  6166. var info = this._deprecatedOptions[option];
  6167. if (info && !this._deprecatedOptionsSuppressed)
  6168. this._logDeprecatedWarning(option, info)
  6169. },
  6170. _logDeprecatedWarningCount: 0,
  6171. _logDeprecatedWarning: function(option, info) {
  6172. utils.logger.warn("'" + option + "' option is deprecated since " + info.since + ". " + info.message);
  6173. ++this._logDeprecatedWarningCount
  6174. },
  6175. _suppressDeprecatedWarnings: function() {
  6176. this._deprecatedOptionsSuppressed = true
  6177. },
  6178. _resumeDeprecatedWarnings: function() {
  6179. this._deprecatedOptionsSuppressed = false
  6180. },
  6181. _getOptionAliases: function(option) {
  6182. return $.map(this._optionAliases, function(aliasedOption, alias) {
  6183. return option === aliasedOption ? alias : undefined
  6184. })
  6185. },
  6186. _notifyOptionChanged: function(option, value, previousValue) {
  6187. var that = this,
  6188. optionWithAliases;
  6189. if (this._initialized) {
  6190. optionWithAliases = this._getOptionAliases(option);
  6191. optionWithAliases.push(option);
  6192. $.each(optionWithAliases, function(index, name) {
  6193. var topLevelName = name.split(/[.\[]/)[0];
  6194. that.optionChanged.fireWith(that, [topLevelName, value, previousValue]);
  6195. that._optionChanged(topLevelName, value, previousValue)
  6196. })
  6197. }
  6198. },
  6199. initialOption: function(optionName) {
  6200. var options = this._initialOptions;
  6201. return options[optionName]
  6202. },
  6203. option: function(options) {
  6204. var that = this,
  6205. name = options,
  6206. value = arguments[1];
  6207. if (arguments.length < 2 && $.type(name) !== "object") {
  6208. if (name) {
  6209. this._logWarningIfDeprecated(name);
  6210. if (this._optionAliases[name])
  6211. name = this._optionAliases[name]
  6212. }
  6213. $.each(this._optionAliases, function(alias, option) {
  6214. that._options[alias] = dataUtils.compileGetter(option)(that._options, {functionsAsIs: true})
  6215. });
  6216. return dataUtils.compileGetter(name)(that._options, {functionsAsIs: true})
  6217. }
  6218. if (typeof name === "string") {
  6219. options = {};
  6220. options[name] = value
  6221. }
  6222. that.beginUpdate();
  6223. try {
  6224. $.each(options, function(name, value) {
  6225. that._logWarningIfDeprecated(name);
  6226. if (that._optionAliases[name])
  6227. name = that._optionAliases[name];
  6228. var prevValue = dataUtils.compileGetter(name)(that._options, {functionsAsIs: true});
  6229. if (that._optionValuesEqual(name, prevValue, value))
  6230. return;
  6231. dataUtils.compileSetter(name)(that._options, value, {
  6232. functionsAsIs: true,
  6233. merge: !that._optionsByReference()[name]
  6234. });
  6235. that._notifyOptionChanged(name, value, prevValue)
  6236. })
  6237. }
  6238. finally {
  6239. that.endUpdate()
  6240. }
  6241. }
  6242. });
  6243. $.extend(DX, {Component: Component})
  6244. })(jQuery, DevExpress);
  6245. /*! Module core, file DOMComponent.js */
  6246. (function($, DX, undefined) {
  6247. var windowResizeCallbacks = DX.utils.windowResizeCallbacks;
  6248. var RTL_DIRECTION_CLASS = "dx-rtl",
  6249. COMPONENT_NAMES_DATA_KEY = "dxComponents",
  6250. VISIBILITY_CHANGE_CLASS = "dx-visibility-change-handler",
  6251. VISIBILITY_CHANGE_EVENTNAMESPACE = "dxVisibilityChange";
  6252. var DOMComponent = DX.Component.inherit({
  6253. NAME: "DOMComponent",
  6254. NAMESPACE: DX,
  6255. _setDefaultOptions: function() {
  6256. this.callBase();
  6257. this.option({rtlEnabled: DX.rtlEnabled})
  6258. },
  6259. ctor: function(element, options) {
  6260. this._$element = $(element);
  6261. this._element().data(this.NAME, this);
  6262. this._attachInstanceToElement(this._$element);
  6263. this.disposing = $.Callbacks();
  6264. this.callBase(options)
  6265. },
  6266. _attachInstanceToElement: $.noop,
  6267. _visibilityChanged: DX.abstract,
  6268. _dimensionChanged: DX.abstract,
  6269. _init: function() {
  6270. this.callBase();
  6271. this._attachWindowResizeCallback()
  6272. },
  6273. _attachWindowResizeCallback: function() {
  6274. if (this._isDimensionChangeSupported()) {
  6275. var windowResizeCallBack = this._windowResizeCallBack = $.proxy(this._dimensionChanged, this);
  6276. windowResizeCallbacks.add(windowResizeCallBack)
  6277. }
  6278. },
  6279. _isDimensionChangeSupported: function() {
  6280. return this._dimensionChanged !== DX.abstract
  6281. },
  6282. _render: function() {
  6283. this._toggleRTLDirection(this.option("rtlEnabled"));
  6284. this._renderVisiblityChange()
  6285. },
  6286. _renderVisiblityChange: function() {
  6287. if (!this._isVisibilityChangeSupported())
  6288. return;
  6289. this._element().addClass(VISIBILITY_CHANGE_CLASS);
  6290. this._attachVisiblityChangeHandlers()
  6291. },
  6292. _attachVisiblityChangeHandlers: function() {
  6293. var that = this;
  6294. that._element().off("." + VISIBILITY_CHANGE_EVENTNAMESPACE).on("dxhiding." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
  6295. that._visibilityChanged(false)
  6296. }).on("dxshown." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
  6297. that._visibilityChanged(true)
  6298. })
  6299. },
  6300. _isVisibilityChangeSupported: function() {
  6301. return this._visibilityChanged !== DX.abstract
  6302. },
  6303. _clean: $.noop,
  6304. _modelByElement: $.noop,
  6305. _invalidate: function() {
  6306. if (!this._updateLockCount)
  6307. throw Error("Invalidate called outside update transaction");
  6308. this._requireRefresh = true
  6309. },
  6310. _refresh: function() {
  6311. this._clean();
  6312. this._render()
  6313. },
  6314. _dispose: function() {
  6315. this._clean();
  6316. this._detachWindowResizeCallback();
  6317. this.optionChanged.empty();
  6318. this.disposing.fireWith(this).empty()
  6319. },
  6320. _detachWindowResizeCallback: function() {
  6321. if (this._isDimensionChangeSupported())
  6322. windowResizeCallbacks.remove(this._windowResizeCallBack)
  6323. },
  6324. _toggleRTLDirection: function(rtl) {
  6325. this._element().toggleClass(RTL_DIRECTION_CLASS, rtl)
  6326. },
  6327. _createAction: function(actionSource, config) {
  6328. var that = this;
  6329. config = $.extend({}, config);
  6330. var element = config.element || that._element(),
  6331. model = that._modelByElement(element);
  6332. config.context = model || that;
  6333. config.component = that;
  6334. var action = new DX.Action(actionSource, config);
  6335. return function(e) {
  6336. if (!arguments.length)
  6337. e = {};
  6338. if (e instanceof $.Event)
  6339. throw Error("Action must be executed with jQuery.Event like action({ jQueryEvent: event })");
  6340. if (!$.isPlainObject(e))
  6341. e = {actionValue: e};
  6342. return action.execute.call(action, $.extend(e, {
  6343. component: that,
  6344. element: element,
  6345. model: model
  6346. }))
  6347. }
  6348. },
  6349. _createActionByOption: function(optionName, config) {
  6350. if (typeof optionName !== "string")
  6351. throw Error("Option name type is unexpected");
  6352. this._suppressDeprecatedWarnings();
  6353. var action = this._createAction(this.option(optionName), config);
  6354. this._resumeDeprecatedWarnings();
  6355. return action
  6356. },
  6357. _optionChanged: function(name, value, prevValue) {
  6358. if (name === "rtlEnabled")
  6359. this._invalidate()
  6360. },
  6361. _element: function() {
  6362. return this._$element
  6363. },
  6364. endUpdate: function() {
  6365. var requireRender = !this._initializing && !this._initialized;
  6366. this.callBase.apply(this, arguments);
  6367. if (!this._updateLockCount)
  6368. if (requireRender)
  6369. this._render();
  6370. else if (this._requireRefresh) {
  6371. this._requireRefresh = false;
  6372. this._refresh()
  6373. }
  6374. }
  6375. });
  6376. var registerComponent = function(name, componentClass) {
  6377. componentClass.redefine({_attachInstanceToElement: function($element) {
  6378. $element.data(name, this);
  6379. if (!$element.data(COMPONENT_NAMES_DATA_KEY))
  6380. $element.data(COMPONENT_NAMES_DATA_KEY, []);
  6381. $element.data(COMPONENT_NAMES_DATA_KEY).push(name)
  6382. }});
  6383. componentClass.prototype.NAMESPACE[name] = componentClass;
  6384. componentClass.prototype.NAME = name;
  6385. componentClass.defaultOptions = function(rule) {
  6386. componentClass.prototype._customRules = componentClass.prototype._customRules || [];
  6387. componentClass.prototype._customRules.push(rule)
  6388. };
  6389. $.fn[name] = function(options) {
  6390. var isMemberInvoke = typeof options === "string",
  6391. result;
  6392. if (isMemberInvoke) {
  6393. var memberName = options,
  6394. memberArgs = $.makeArray(arguments).slice(1);
  6395. this.each(function() {
  6396. var instance = $(this).data(name);
  6397. if (!instance)
  6398. throw Error(DX.utils.stringFormat("Component {0} has not been initialized on this element", name));
  6399. var member = instance[memberName],
  6400. memberValue = member.apply(instance, memberArgs);
  6401. if (result === undefined)
  6402. result = memberValue
  6403. })
  6404. }
  6405. else {
  6406. this.each(function() {
  6407. var instance = $(this).data(name);
  6408. if (instance)
  6409. instance.option(options);
  6410. else
  6411. new componentClass(this, options)
  6412. });
  6413. result = this
  6414. }
  6415. return result
  6416. }
  6417. };
  6418. var getComponents = function(element) {
  6419. element = $(element);
  6420. var names = element.data(COMPONENT_NAMES_DATA_KEY);
  6421. if (!names)
  6422. return [];
  6423. return $.map(names, function(name) {
  6424. return element.data(name)
  6425. })
  6426. };
  6427. var disposeComponents = function() {
  6428. $.each(getComponents(this), function() {
  6429. this._dispose()
  6430. })
  6431. };
  6432. var originalCleanData = $.cleanData;
  6433. $.cleanData = function(element) {
  6434. $.each(element, disposeComponents);
  6435. return originalCleanData.apply(this, arguments)
  6436. };
  6437. registerComponent("DOMComponent", DOMComponent);
  6438. DX.registerComponent = registerComponent
  6439. })(jQuery, DevExpress);
  6440. /*! Module core, file social.js */
  6441. DevExpress.social = {};
  6442. /*! Module core, file facebook.js */
  6443. (function($, DX, undefined) {
  6444. function notifyDeprecated() {
  6445. DX.utils.logger.warn("DevExpress.social API is deprecated. Use official Facebook library instead")
  6446. }
  6447. var social = DX.social;
  6448. var location = window.location,
  6449. navigator = window.navigator,
  6450. encodeURIComponent = window.encodeURIComponent,
  6451. decodeURIComponent = window.decodeURIComponent,
  6452. iosStandaloneMode = navigator.standalone,
  6453. cordovaMode = false;
  6454. if (window.cordova)
  6455. $(document).on("deviceready", function() {
  6456. cordovaMode = true
  6457. });
  6458. var ACCESS_TOKEN_KEY = "dx-facebook-access-token",
  6459. IOS_STANDALONE_STEP1_KEY = "dx-facebook-step1",
  6460. IOS_STANDALONE_STEP2_KEY = "dx-facebook-step2";
  6461. var accessToken = null,
  6462. expires = null,
  6463. connectionChanged = $.Callbacks();
  6464. var pendingLoginRedirectUrl;
  6465. var isConnected = function() {
  6466. return !!accessToken
  6467. };
  6468. var getAccessTokenObject = function() {
  6469. return {
  6470. accessToken: accessToken,
  6471. expiresIn: accessToken ? expires : 0
  6472. }
  6473. };
  6474. var FB = social.Facebook = {
  6475. loginRedirectUrl: "FacebookLoginCallback.html",
  6476. connectionChanged: connectionChanged,
  6477. isConnected: isConnected,
  6478. getAccessTokenObject: getAccessTokenObject,
  6479. jsonp: false
  6480. };
  6481. var login = function(appId, options) {
  6482. notifyDeprecated();
  6483. options = options || {};
  6484. if (cordovaMode)
  6485. pendingLoginRedirectUrl = "https://www.facebook.com/connect/login_success.html";
  6486. else
  6487. pendingLoginRedirectUrl = formatLoginRedirectUrl();
  6488. var scope = (options.permissions || []).join(),
  6489. url = "https://www.facebook.com/dialog/oauth?display=popup&client_id=" + appId + "&redirect_uri=" + encodeURIComponent(pendingLoginRedirectUrl) + "&scope=" + encodeURIComponent(scope) + "&response_type=token";
  6490. if (iosStandaloneMode)
  6491. putData(IOS_STANDALONE_STEP1_KEY, location.href);
  6492. if (cordovaMode)
  6493. startLogin_cordova(url);
  6494. else
  6495. startLogin_browser(url)
  6496. };
  6497. var formatLoginRedirectUrl = function() {
  6498. var pathSegments = location.pathname.split(/\//g);
  6499. pathSegments.pop();
  6500. pathSegments.push(FB.loginRedirectUrl);
  6501. return location.protocol + "//" + location.host + pathSegments.join("/")
  6502. };
  6503. var startLogin_browser = function(loginUrl) {
  6504. var width = 512,
  6505. height = 320,
  6506. left = (screen.width - width) / 2,
  6507. top = (screen.height - height) / 2;
  6508. window.open(loginUrl, null, "width=" + width + ",height=" + height + ",toolbar=0,scrollbars=0,status=0,resizable=0,menuBar=0,left=" + left + ",top=" + top)
  6509. };
  6510. var startLogin_cordova = function(loginUrl) {
  6511. var ref = window.open(loginUrl, "_blank");
  6512. ref.addEventListener('exit', function(event) {
  6513. pendingLoginRedirectUrl = null
  6514. });
  6515. ref.addEventListener('loadstop', function(event) {
  6516. var url = unescape(event.url);
  6517. if (url.indexOf(pendingLoginRedirectUrl) === 0) {
  6518. ref.close();
  6519. _processLoginRedirectUrl(url)
  6520. }
  6521. })
  6522. };
  6523. var handleLoginRedirect = function() {
  6524. var opener = window.opener;
  6525. if (iosStandaloneMode) {
  6526. putData(IOS_STANDALONE_STEP2_KEY, location.href);
  6527. location.href = getData(IOS_STANDALONE_STEP1_KEY)
  6528. }
  6529. else if (opener && opener.DevExpress) {
  6530. opener.DevExpress.social.Facebook._processLoginRedirectUrl(location.href);
  6531. window.close()
  6532. }
  6533. };
  6534. var _processLoginRedirectUrl = function(url) {
  6535. var params = parseUrlFragment(url);
  6536. expires = params.expires_in;
  6537. changeToken(params.access_token);
  6538. pendingLoginRedirectUrl = null
  6539. };
  6540. var parseUrlFragment = function(url) {
  6541. var hash = url.split("#")[1];
  6542. if (!hash)
  6543. return {};
  6544. var pairs = hash.split(/&/g),
  6545. result = {};
  6546. $.each(pairs, function(i) {
  6547. var splitPair = this.split("=");
  6548. result[splitPair[0]] = decodeURIComponent(splitPair[1])
  6549. });
  6550. return result
  6551. };
  6552. var logout = function() {
  6553. notifyDeprecated();
  6554. changeToken(null)
  6555. };
  6556. var changeToken = function(value) {
  6557. if (value === accessToken)
  6558. return;
  6559. accessToken = value;
  6560. putData(ACCESS_TOKEN_KEY, value);
  6561. connectionChanged.fire(!!value)
  6562. };
  6563. var api = function(resource, method, params) {
  6564. notifyDeprecated();
  6565. if (!isConnected())
  6566. throw Error("Not connected");
  6567. if (typeof method !== "string") {
  6568. params = method;
  6569. method = undefined
  6570. }
  6571. method = (method || "get").toLowerCase();
  6572. var d = $.Deferred();
  6573. var args = arguments;
  6574. $.ajax({
  6575. url: "https://graph.facebook.com/" + resource,
  6576. type: method,
  6577. data: $.extend({access_token: accessToken}, params),
  6578. dataType: FB.jsonp && method === "get" ? "jsonp" : "json"
  6579. }).done(function(response) {
  6580. response = response || simulateErrorResponse();
  6581. if (response.error)
  6582. d.reject(response.error);
  6583. else
  6584. d.resolve(response)
  6585. }).fail(function(xhr) {
  6586. var response;
  6587. try {
  6588. response = $.parseJSON(xhr.responseText);
  6589. var tries = args[3] || 0;
  6590. if (tries++ < 3 && response.error.code == 190 && response.error.error_subcode == 466) {
  6591. setTimeout(function() {
  6592. api(resource, method, params, tries).done(function(result) {
  6593. d.resolve(result)
  6594. }).fail(function(error) {
  6595. d.reject(error)
  6596. })
  6597. }, 500);
  6598. return
  6599. }
  6600. }
  6601. catch(x) {
  6602. response = simulateErrorResponse()
  6603. }
  6604. d.reject(response.error)
  6605. });
  6606. return d.promise()
  6607. };
  6608. var simulateErrorResponse = function() {
  6609. return {error: {message: "Unknown error"}}
  6610. };
  6611. var ensureStorageBackend = function() {
  6612. if (!hasStorageBackend())
  6613. throw Error("HTML5 sessionStorage or jQuery.cookie plugin is required");
  6614. };
  6615. var hasStorageBackend = function() {
  6616. return !!($.cookie || window.sessionStorage)
  6617. };
  6618. var putData = function(key, data) {
  6619. ensureStorageBackend();
  6620. data = JSON.stringify(data);
  6621. if (window.sessionStorage)
  6622. if (data === null)
  6623. sess.removeItem(key);
  6624. else
  6625. sessionStorage.setItem(key, data);
  6626. else
  6627. $.cookie(key, data)
  6628. };
  6629. var getData = function(key) {
  6630. ensureStorageBackend();
  6631. try {
  6632. return JSON.parse(window.sessionStorage ? sessionStorage.getItem(key) : $.cookie(key))
  6633. }
  6634. catch(x) {
  6635. return null
  6636. }
  6637. };
  6638. if (hasStorageBackend())
  6639. accessToken = getData(ACCESS_TOKEN_KEY);
  6640. if (iosStandaloneMode) {
  6641. var url = getData(IOS_STANDALONE_STEP2_KEY);
  6642. if (url) {
  6643. _processLoginRedirectUrl(url);
  6644. putData(IOS_STANDALONE_STEP1_KEY, null);
  6645. putData(IOS_STANDALONE_STEP2_KEY, null)
  6646. }
  6647. }
  6648. $.extend(FB, {
  6649. login: login,
  6650. logout: logout,
  6651. handleLoginRedirect: handleLoginRedirect,
  6652. _processLoginRedirectUrl: _processLoginRedirectUrl,
  6653. api: api
  6654. })
  6655. })(jQuery, DevExpress);
  6656. /*! Module core, file ui.js */
  6657. (function($, DX, undefined) {
  6658. var ui = DX.ui = {};
  6659. var TemplateProvider = DX.Class.inherit({
  6660. getTemplateClass: function() {
  6661. return Template
  6662. },
  6663. supportDefaultTemplate: function() {
  6664. return false
  6665. },
  6666. getDefaultTemplate: function() {
  6667. return null
  6668. }
  6669. });
  6670. var Template = DX.Class.inherit({
  6671. ctor: function(element, owner) {
  6672. this._template = this._element = $(element).detach();
  6673. this._owner = owner
  6674. },
  6675. render: function(container) {
  6676. var renderedTemplate = this._template.clone();
  6677. container.append(renderedTemplate);
  6678. return renderedTemplate
  6679. },
  6680. dispose: function() {
  6681. this._owner = null
  6682. },
  6683. owner: function() {
  6684. return this._owner
  6685. }
  6686. });
  6687. var GESTURE_LOCK_KEY = "dxGestureLock";
  6688. DX.registerActionExecutor({
  6689. designMode: {validate: function(e) {
  6690. if (DX.designMode)
  6691. e.cancel = true
  6692. }},
  6693. gesture: {validate: function(e) {
  6694. if (!e.args.length)
  6695. return;
  6696. var args = e.args[0],
  6697. element = args[e.validatingTargetName] || args.element;
  6698. while (element && element.length) {
  6699. if (element.data(GESTURE_LOCK_KEY)) {
  6700. e.cancel = true;
  6701. break
  6702. }
  6703. element = element.parent()
  6704. }
  6705. }},
  6706. disabled: {validate: function(e) {
  6707. if (!e.args.length)
  6708. return;
  6709. var args = e.args[0],
  6710. element = args[e.validatingTargetName] || args.element;
  6711. if (element && element.is(".dx-state-disabled, .dx-state-disabled *"))
  6712. e.cancel = true
  6713. }}
  6714. });
  6715. $.extend(ui, {
  6716. TemplateProvider: TemplateProvider,
  6717. Template: Template,
  6718. initViewport: function() {
  6719. DX.utils.logger.warn("DevExpress.ui.initViewport is deprecated. Use DX.utils.initMobileViewport instead");
  6720. DX.utils.initMobileViewport()
  6721. }
  6722. });
  6723. ui.__internals = ui.__internals || {};
  6724. $.extend(ui.__internals, {Template: Template})
  6725. })(jQuery, DevExpress);
  6726. /*! Module core, file ko.components.js */
  6727. (function($, DX, undefined) {
  6728. if (!DX.support.hasKo)
  6729. return;
  6730. var ko = window.ko,
  6731. ui = DX.ui,
  6732. LOCKS_DATA_KEY = "dxKoLocks",
  6733. CREATED_WITH_KO_DATA_KEY = "dxKoCreation";
  6734. var Locks = function() {
  6735. var info = {};
  6736. var currentCount = function(lockName) {
  6737. return info[lockName] || 0
  6738. };
  6739. return {
  6740. obtain: function(lockName) {
  6741. info[lockName] = currentCount(lockName) + 1
  6742. },
  6743. release: function(lockName) {
  6744. var count = currentCount(lockName);
  6745. if (count < 1)
  6746. throw Error("Not locked");
  6747. if (count === 1)
  6748. delete info[lockName];
  6749. else
  6750. info[lockName] = count - 1
  6751. },
  6752. locked: function(lockName) {
  6753. return currentCount(lockName) > 0
  6754. }
  6755. }
  6756. };
  6757. var registerComponentKoBinding = function(componentName) {
  6758. ko.bindingHandlers[componentName] = {init: function(domNode, valueAccessor) {
  6759. var element = $(domNode),
  6760. ctorOptions = {},
  6761. optionNameToModelMap = {};
  6762. var applyModelValueToOption = function(optionName, modelValue) {
  6763. var component = element.data(componentName),
  6764. locks = element.data(LOCKS_DATA_KEY),
  6765. optionValue = ko.utils.unwrapObservable(modelValue);
  6766. if (ko.isWriteableObservable(modelValue))
  6767. optionNameToModelMap[optionName] = modelValue;
  6768. if (component) {
  6769. if (locks.locked(optionName))
  6770. return;
  6771. locks.obtain(optionName);
  6772. try {
  6773. component.option(optionName, optionValue)
  6774. }
  6775. finally {
  6776. locks.release(optionName)
  6777. }
  6778. }
  6779. else
  6780. ctorOptions[optionName] = optionValue
  6781. };
  6782. var handleOptionChanged = function(optionName, optionValue) {
  6783. if (!(optionName in optionNameToModelMap))
  6784. return;
  6785. var element = this._$element,
  6786. locks = element.data(LOCKS_DATA_KEY);
  6787. if (locks.locked(optionName))
  6788. return;
  6789. locks.obtain(optionName);
  6790. try {
  6791. optionNameToModelMap[optionName](optionValue)
  6792. }
  6793. finally {
  6794. locks.release(optionName)
  6795. }
  6796. };
  6797. var createComponent = function() {
  6798. element.data(CREATED_WITH_KO_DATA_KEY, true);
  6799. element[componentName](ctorOptions);
  6800. ctorOptions = null;
  6801. element.data(LOCKS_DATA_KEY, new Locks);
  6802. element.data(componentName).optionChanged.add(handleOptionChanged)
  6803. };
  6804. ko.computed(function() {
  6805. var component = element.data(componentName);
  6806. if (component)
  6807. component.beginUpdate();
  6808. $.each(ko.unwrap(valueAccessor()), function(modelName, modelValueExpr) {
  6809. ko.computed(function() {
  6810. applyModelValueToOption(modelName, modelValueExpr)
  6811. }, null, {disposeWhenNodeIsRemoved: domNode})
  6812. });
  6813. if (component)
  6814. component.endUpdate();
  6815. else
  6816. createComponent()
  6817. }, null, {disposeWhenNodeIsRemoved: domNode});
  6818. return {controlsDescendantBindings: ui[componentName] && ui[componentName].subclassOf(ui.Widget)}
  6819. }}
  6820. };
  6821. var KoComponent = DX.DOMComponent.inherit({_modelByElement: function(element) {
  6822. if (element.length)
  6823. return ko.dataFor(element.get(0))
  6824. }});
  6825. var originalRegisterComponent = DX.registerComponent;
  6826. var registerKoComponent = function(name, componentClass) {
  6827. originalRegisterComponent(name, componentClass);
  6828. registerComponentKoBinding(name)
  6829. };
  6830. ko.bindingHandlers.dxAction = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
  6831. var $element = $(element);
  6832. var unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
  6833. actionSource = unwrappedValue,
  6834. actionOptions = {context: element};
  6835. if (unwrappedValue.execute) {
  6836. actionSource = unwrappedValue.execute;
  6837. $.extend(actionOptions, unwrappedValue)
  6838. }
  6839. var action = new DX.Action(actionSource, actionOptions);
  6840. $element.off(".dxActionBinding").on("dxclick.dxActionBinding", function(e) {
  6841. action.execute({
  6842. element: $element,
  6843. model: viewModel,
  6844. evaluate: function(expression) {
  6845. var context = viewModel;
  6846. if (expression.length > 0 && expression[0] === "$")
  6847. context = ko.contextFor(element);
  6848. var getter = DX.data.utils.compileGetter(expression);
  6849. return getter(context)
  6850. },
  6851. jQueryEvent: e
  6852. });
  6853. if (!actionOptions.bubbling)
  6854. e.stopPropagation()
  6855. })
  6856. }};
  6857. var cleanKoData = function(element, andSelf) {
  6858. var cleanNode = function() {
  6859. ko.cleanNode(this)
  6860. };
  6861. if (andSelf)
  6862. element.each(cleanNode);
  6863. else
  6864. element.find("*").each(cleanNode)
  6865. };
  6866. var originalEmpty = $.fn.empty;
  6867. $.fn.empty = function() {
  6868. cleanKoData(this, false);
  6869. return originalEmpty.apply(this, arguments)
  6870. };
  6871. var originalRemove = $.fn.remove;
  6872. $.fn.remove = function(selector, keepData) {
  6873. if (!keepData) {
  6874. var subject = this;
  6875. if (selector)
  6876. subject = subject.filter(selector);
  6877. cleanKoData(subject, true)
  6878. }
  6879. return originalRemove.call(this, selector, keepData)
  6880. };
  6881. var originalHtml = $.fn.html;
  6882. $.fn.html = function(value) {
  6883. if (typeof value === "string")
  6884. cleanKoData(this, false);
  6885. return originalHtml.apply(this, arguments)
  6886. };
  6887. DX.registerComponent = registerKoComponent;
  6888. registerKoComponent("DOMComponent", KoComponent)
  6889. })(jQuery, DevExpress);
  6890. /*! Module core, file ng.components.js */
  6891. (function($, DX, undefined) {
  6892. if (!DX.support.hasNg)
  6893. return;
  6894. var ui = DX.ui,
  6895. compileSetter = DX.data.utils.compileSetter,
  6896. compileGetter = DX.data.utils.compileGetter;
  6897. var CREATED_WITH_NG_DATA_KEY = "dxNgCreation",
  6898. TEMPLATES_DATA_KEY = "dxTemplates",
  6899. COMPILER_DATA_KEY = "dxNgCompiler",
  6900. DEFAULT_COMPILER_DATA_KEY = "dxDefaultCompilerGetter",
  6901. ANONYMOUS_TEMPLATE_NAME = "template";
  6902. var phoneJsModule = DX.ng.module;
  6903. var ComponentBuilder = DX.Class.inherit({
  6904. ctor: function(options) {
  6905. this._componentName = options.componentName;
  6906. this._$element = options.$element;
  6907. this._$templates = options.$templates;
  6908. this._scope = options.scope;
  6909. this._compile = options.compile;
  6910. this._ngOptions = options.ngOptions;
  6911. this._componentDisposing = $.Callbacks();
  6912. this._$element.data(CREATED_WITH_NG_DATA_KEY, true);
  6913. if (options.ngOptions.data)
  6914. this._initDataScope(options.ngOptions.data)
  6915. },
  6916. initDefaultCompilerGetter: function() {
  6917. var that = this;
  6918. that._$element.data(DEFAULT_COMPILER_DATA_KEY, function($template) {
  6919. return that._compilerByTemplate($template)
  6920. })
  6921. },
  6922. initTemplateCompilers: function() {
  6923. var that = this;
  6924. if (this._$templates)
  6925. this._$templates.each(function(i, template) {
  6926. $(template).data(COMPILER_DATA_KEY, that._compilerByTemplate(template))
  6927. })
  6928. },
  6929. initComponentWithBindings: function() {
  6930. this._initComponent(this._scope);
  6931. this._initComponentBindings()
  6932. },
  6933. _initDataScope: function(data) {
  6934. if (typeof data === "string") {
  6935. var dataStr = data,
  6936. rootScope = this._scope;
  6937. data = rootScope.$eval(data);
  6938. this._scope = rootScope.$new();
  6939. this._synchronizeDataScopes(rootScope, this._scope, data, dataStr)
  6940. }
  6941. $.extend(this._scope, data)
  6942. },
  6943. _synchronizeDataScopes: function(parentScope, childScope, data, parentPrefix) {
  6944. var that = this;
  6945. $.each(data, function(fieldPath) {
  6946. that._synchronizeScopeField({
  6947. parentScope: parentScope,
  6948. childScope: childScope,
  6949. fieldPath: fieldPath,
  6950. parentPrefix: parentPrefix
  6951. })
  6952. })
  6953. },
  6954. _initComponent: function(scope) {
  6955. this._component = this._$element[this._componentName](this._evalOptions(scope)).data(this._componentName)
  6956. },
  6957. _initComponentBindings: function() {
  6958. var that = this,
  6959. optionDependencies = {};
  6960. if (that._ngOptions.bindingOptions)
  6961. $.each(that._ngOptions.bindingOptions, function(optionPath, valuePath) {
  6962. var separatorIndex = optionPath.search(/\[|\./),
  6963. optionForSubscribe = separatorIndex > -1 ? optionPath.substring(0, separatorIndex) : optionPath,
  6964. prevWatchMethod,
  6965. clearWatcher;
  6966. if (!optionDependencies[optionForSubscribe])
  6967. optionDependencies[optionForSubscribe] = {};
  6968. optionDependencies[optionForSubscribe][optionPath] = valuePath;
  6969. var watchCallback = function(newValue, oldValue) {
  6970. if (newValue !== oldValue) {
  6971. that._component.option(optionPath, newValue);
  6972. updateWatcher()
  6973. }
  6974. };
  6975. var updateWatcher = function() {
  6976. var watchMethod = $.isArray(that._scope.$eval(valuePath)) ? "$watchCollection" : "$watch";
  6977. if (prevWatchMethod !== watchMethod) {
  6978. if (clearWatcher)
  6979. clearWatcher();
  6980. clearWatcher = that._scope[watchMethod](valuePath, watchCallback, true);
  6981. prevWatchMethod = watchMethod
  6982. }
  6983. };
  6984. updateWatcher();
  6985. that._component.disposing.add(function() {
  6986. clearWatcher();
  6987. that._componentDisposing.fire()
  6988. })
  6989. });
  6990. that._component.optionChanged.add(function(optionName, optionValue) {
  6991. if (that._scope.$root.$$phase === "$digest" || !optionDependencies || !optionDependencies[optionName])
  6992. return;
  6993. safeApply(function(scope) {
  6994. $.each(optionDependencies[optionName], function(optionPath, valuePath) {
  6995. var setter = compileSetter(valuePath),
  6996. getter = compileGetter(optionPath);
  6997. var tmpData = {};
  6998. tmpData[optionName] = optionValue;
  6999. setter(scope, getter(tmpData))
  7000. })
  7001. }, that._scope)
  7002. })
  7003. },
  7004. _compilerByTemplate: function(template) {
  7005. var that = this,
  7006. scopeItemsPath = this._getScopeItemsPath();
  7007. return function(data, index) {
  7008. var $resultMarkup = $(template).clone(),
  7009. templateScope;
  7010. if (data !== undefined) {
  7011. var dataIsScope = data.$id,
  7012. templateScope = dataIsScope ? data : that._createScopeWithData(data);
  7013. $resultMarkup.on("$destroy", function() {
  7014. var destroyAlreadyCalled = !templateScope.$parent;
  7015. if (destroyAlreadyCalled)
  7016. return;
  7017. templateScope.$destroy()
  7018. })
  7019. }
  7020. else
  7021. templateScope = that._scope;
  7022. if (scopeItemsPath)
  7023. that._synchronizeScopes(templateScope, scopeItemsPath, index);
  7024. safeApply(that._compile($resultMarkup), templateScope);
  7025. return $resultMarkup
  7026. }
  7027. },
  7028. _getScopeItemsPath: function() {
  7029. if (ui[this._componentName].subclassOf(ui.CollectionContainerWidget) && this._ngOptions.bindingOptions)
  7030. return this._ngOptions.bindingOptions.items
  7031. },
  7032. _createScopeWithData: function(data) {
  7033. var newScope = this._scope.$new(true);
  7034. if (typeof data === "object")
  7035. $.extend(newScope, data);
  7036. else
  7037. newScope.scopeValue = data;
  7038. return newScope
  7039. },
  7040. _synchronizeScopes: function(itemScope, parentPrefix, itemIndex) {
  7041. var that = this,
  7042. item = compileGetter(parentPrefix + "[" + itemIndex + "]")(this._scope);
  7043. if (!$.isPlainObject(item))
  7044. item = {scopeValue: item};
  7045. $.each(item, function(itemPath) {
  7046. that._synchronizeScopeField({
  7047. parentScope: that._scope,
  7048. childScope: itemScope,
  7049. fieldPath: itemPath,
  7050. parentPrefix: parentPrefix,
  7051. itemIndex: itemIndex
  7052. })
  7053. })
  7054. },
  7055. _synchronizeScopeField: function(args) {
  7056. var parentScope = args.parentScope,
  7057. childScope = args.childScope,
  7058. fieldPath = args.fieldPath,
  7059. parentPrefix = args.parentPrefix,
  7060. itemIndex = args.itemIndex;
  7061. var innerPathSuffix = fieldPath === "scopeValue" ? "" : "." + fieldPath,
  7062. collectionField = itemIndex !== undefined,
  7063. optionOuterBag = [parentPrefix],
  7064. optionOuterPath;
  7065. if (collectionField)
  7066. optionOuterBag.push("[", itemIndex, "]");
  7067. optionOuterBag.push(innerPathSuffix);
  7068. optionOuterPath = optionOuterBag.join("");
  7069. var clearParentWatcher = parentScope.$watch(optionOuterPath, function(newValue, oldValue) {
  7070. if (newValue !== oldValue)
  7071. compileSetter(fieldPath)(childScope, newValue)
  7072. });
  7073. var clearItemWatcher = childScope.$watch(fieldPath, function(newValue, oldValue) {
  7074. if (newValue !== oldValue) {
  7075. if (collectionField && !compileGetter(parentPrefix)(parentScope)[itemIndex]) {
  7076. clearItemWatcher();
  7077. return
  7078. }
  7079. compileSetter(optionOuterPath)(parentScope, newValue)
  7080. }
  7081. });
  7082. this._componentDisposing.add([clearParentWatcher, clearItemWatcher])
  7083. },
  7084. _evalOptions: function(scope) {
  7085. var result = $.extend({}, this._ngOptions);
  7086. delete result.data;
  7087. delete result.bindingOptions;
  7088. if (this._ngOptions.bindingOptions)
  7089. $.each(this._ngOptions.bindingOptions, function(key, value) {
  7090. result[key] = scope.$eval(value)
  7091. });
  7092. return result
  7093. }
  7094. });
  7095. var safeApply = function(func, scope) {
  7096. if (scope.$root.$$phase)
  7097. func(scope);
  7098. else
  7099. scope.$apply(function() {
  7100. func(scope)
  7101. })
  7102. };
  7103. var extractTemplates = function($element, componentName) {
  7104. if ($element.data(TEMPLATES_DATA_KEY))
  7105. return $element.data(TEMPLATES_DATA_KEY);
  7106. var $templates;
  7107. if (ui[componentName] && ui[componentName].subclassOf(ui.Widget) && $.trim($element.html())) {
  7108. var isAnonymousTemplate = !$element.children().first().attr("data-options");
  7109. if (isAnonymousTemplate)
  7110. $templates = $("<div/>").attr("data-options", "dxTemplate: { name: '" + ANONYMOUS_TEMPLATE_NAME + "' }").append($element.contents());
  7111. else
  7112. $templates = $element.children().detach();
  7113. $element.data(TEMPLATES_DATA_KEY, $templates)
  7114. }
  7115. return $templates
  7116. };
  7117. var NgComponent = DX.DOMComponent.inherit({
  7118. _modelByElement: function(element) {
  7119. if (element.length)
  7120. return element.scope()
  7121. },
  7122. _createAction: function() {
  7123. var action = this.callBase.apply(this, arguments);
  7124. var component = this,
  7125. wrappedAction = function() {
  7126. var that = this,
  7127. scope = component._modelByElement(component._element()),
  7128. args = arguments;
  7129. if (!scope || scope.$root.$$phase)
  7130. return action.apply(that, args);
  7131. return scope.$apply(function() {
  7132. return action.apply(that, args)
  7133. })
  7134. };
  7135. return wrappedAction
  7136. }
  7137. });
  7138. var originalRegisterComponent = DX.registerComponent;
  7139. var registerNgComponent = function(componentName, componentClass) {
  7140. originalRegisterComponent(componentName, componentClass);
  7141. phoneJsModule.directive(componentName, ["$compile", function(compile) {
  7142. return {
  7143. restrict: "A",
  7144. compile: function($element) {
  7145. var $templates = extractTemplates($element, componentName);
  7146. return function(scope, $element, attrs) {
  7147. var componentBuilder = new ComponentBuilder({
  7148. componentName: componentName,
  7149. compile: compile,
  7150. $element: $element,
  7151. scope: scope,
  7152. ngOptions: attrs[componentName] ? scope.$eval(attrs[componentName]) : {},
  7153. $templates: $templates
  7154. });
  7155. componentBuilder.initTemplateCompilers();
  7156. componentBuilder.initDefaultCompilerGetter();
  7157. componentBuilder.initComponentWithBindings()
  7158. }
  7159. }
  7160. }
  7161. }])
  7162. };
  7163. DX.registerComponent = registerNgComponent;
  7164. registerNgComponent("DOMComponent", NgComponent)
  7165. })(jQuery, DevExpress);
  7166. /*! Module core, file ko.templates.js */
  7167. (function($, DX, undefined) {
  7168. if (!DX.support.hasKo)
  7169. return;
  7170. var ko = window.ko,
  7171. ui = DX.ui,
  7172. CREATED_WITH_KO_DATA_KEY = "dxKoCreation";
  7173. var KoTemplate = ui.Template.inherit({
  7174. ctor: function(element) {
  7175. this.callBase.apply(this, arguments);
  7176. this._template = $("<div>").append(element);
  7177. this._registerKoTemplate()
  7178. },
  7179. _cleanTemplateElement: function() {
  7180. this._element.each(function() {
  7181. ko.cleanNode(this)
  7182. })
  7183. },
  7184. _registerKoTemplate: function() {
  7185. var template = this._template.get(0);
  7186. new ko.templateSources.anonymousTemplate(template)['nodes'](template)
  7187. },
  7188. render: function(container, data) {
  7189. data = data !== undefined ? data : ko.dataFor(container.get(0)) || {};
  7190. var containerBindingContext = ko.contextFor(container[0]);
  7191. var bindingContext = containerBindingContext ? containerBindingContext.createChildContext(data) : data;
  7192. var renderBag = $("<div />").appendTo(container);
  7193. ko.renderTemplate(this._template.get(0), bindingContext, null, renderBag.get(0));
  7194. var result = renderBag.contents();
  7195. container.append(result);
  7196. renderBag.remove();
  7197. return result
  7198. },
  7199. dispose: function() {
  7200. this.callBase();
  7201. this._template.remove()
  7202. }
  7203. });
  7204. var KoTemplateProvider = ui.TemplateProvider.inherit({
  7205. getTemplateClass: function(widget) {
  7206. return this._createdWithKo(widget) ? KoTemplate : this.callBase(widget)
  7207. },
  7208. supportDefaultTemplate: function(widget) {
  7209. return this._createdWithKo(widget) ? true : this.callBase(widget)
  7210. },
  7211. getDefaultTemplate: function(widget) {
  7212. if (this._createdWithKo(widget))
  7213. return defaultKoTemplate(widget.NAME)
  7214. },
  7215. _createdWithKo: function(widget) {
  7216. return !!widget._element().data(CREATED_WITH_KO_DATA_KEY)
  7217. }
  7218. });
  7219. var defaultKoTemplate = function() {
  7220. var cache = {};
  7221. return function(widgetName) {
  7222. if (!DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName])
  7223. widgetName = "base";
  7224. if (!cache[widgetName]) {
  7225. var html = DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName](),
  7226. markup = DX.utils.createMarkupFromString(html);
  7227. cache[widgetName] = new KoTemplate(markup)
  7228. }
  7229. return cache[widgetName]
  7230. }
  7231. }();
  7232. var createElementWithBindAttr = function(tagName, bindings, closeTag, additionalProperties) {
  7233. closeTag = closeTag === undefined ? true : closeTag;
  7234. var bindAttr = $.map(bindings, function(value, key) {
  7235. return key + ":" + value
  7236. }).join(",");
  7237. additionalProperties = additionalProperties || "";
  7238. return "<" + tagName + " data-bind=\"" + bindAttr + "\" " + additionalProperties + ">" + (closeTag ? "</" + tagName + ">" : "")
  7239. };
  7240. var defaultKoTemplateBasicBindings = {css: "{ 'dx-state-disabled': $data.disabled, 'dx-state-invisible': !($data.visible === undefined || ko.unwrap($data.visible)) }"};
  7241. var DEFAULT_ITEM_TEMPLATE_GENERATORS = {base: function() {
  7242. var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)],
  7243. htmlBinding = createElementWithBindAttr("div", {html: "html"}),
  7244. textBinding = createElementWithBindAttr("div", {text: "text"}),
  7245. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
  7246. template.push("<!-- ko if: $data.html && !$data.text -->", htmlBinding, "<!-- /ko -->", "<!-- ko if: !$data.html && $data.text -->", textBinding, "<!-- /ko -->", "<!-- ko ifnot: $.isPlainObject($data) -->", primitiveBinding, "<!-- /ko -->", "</div>");
  7247. return template.join("")
  7248. }};
  7249. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxPivotTabs = function() {
  7250. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7251. titleBinding = createElementWithBindAttr("span", {text: "title"});
  7252. var divInnerStart = template.indexOf(">") + 1,
  7253. divInnerFinish = template.length - 6;
  7254. template = [template.substring(0, divInnerStart), titleBinding, template.substring(divInnerFinish, template.length)];
  7255. return template.join("")
  7256. };
  7257. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxPanorama = function() {
  7258. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7259. headerBinding = createElementWithBindAttr("div", {text: "header"}, true, 'class="dx-panorama-item-header"');
  7260. var divInnerStart = template.indexOf(">") + 1;
  7261. template = [template.substring(0, divInnerStart), "<!-- ko if: $data.header -->", headerBinding, "<!-- /ko -->", template.substring(divInnerStart, template.length)];
  7262. return template.join("")
  7263. };
  7264. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxList = function() {
  7265. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7266. keyBinding = createElementWithBindAttr("div", {text: "key"});
  7267. template = [template.substring(0, template.length - 6), "<!-- ko if: $data.key -->" + keyBinding + "<!-- /ko -->", "</div>"];
  7268. return template.join("")
  7269. };
  7270. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxToolbar = function() {
  7271. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base();
  7272. template = [template.substring(0, template.length - 6), "<!-- ko if: $data.widget -->"];
  7273. $.each(["button", "tabs", "dropDownMenu"], function() {
  7274. var bindingName = DX.inflector.camelize(["dx", "-", this].join("")),
  7275. bindingObj = {};
  7276. bindingObj[bindingName] = "$data.options";
  7277. template.push("<!-- ko if: $data.widget === '", this, "' -->", createElementWithBindAttr("div", bindingObj), "<!-- /ko -->")
  7278. });
  7279. template.push("<!-- /ko -->");
  7280. return template.join("")
  7281. };
  7282. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxGallery = function() {
  7283. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7284. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),
  7285. imgBinding = createElementWithBindAttr("img", {attr: "{ src: String($data) }"}, false);
  7286. template = template.replace(primitiveBinding, imgBinding);
  7287. return template
  7288. };
  7289. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs = function() {
  7290. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7291. baseTextBinding = createElementWithBindAttr("div", {text: "text"}),
  7292. iconBinding = createElementWithBindAttr("span", {
  7293. attr: "{ 'class': 'dx-icon-' + $data.icon }",
  7294. css: "{ 'dx-icon': true }"
  7295. }),
  7296. iconSrcBinding = createElementWithBindAttr("img", {
  7297. attr: "{ src: $data.iconSrc }",
  7298. css: "{ 'dx-icon': true }"
  7299. }, false),
  7300. textBinding = "<!-- ko if: $data.icon -->" + iconBinding + "<!-- /ko -->" + "<!-- ko if: !$data.icon && $data.iconSrc -->" + iconSrcBinding + "<!-- /ko -->" + "<span class=\"dx-tab-text\" data-bind=\"text: $data.text\"></span>";
  7301. template = template.replace("<!-- ko if: !$data.html && $data.text -->", "<!-- ko if: !$data.html && ($data.text || $data.icon || $data.iconSrc) -->").replace(baseTextBinding, textBinding);
  7302. return template
  7303. };
  7304. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxActionSheet = function() {
  7305. return createElementWithBindAttr("div", {dxButton: "{ text: $data.text, clickAction: $data.clickAction, type: $data.type, disabled: !!ko.unwrap($data.disabled) }"})
  7306. };
  7307. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxNavBar = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs;
  7308. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu = function() {
  7309. var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)],
  7310. iconBinding = createElementWithBindAttr("span", {
  7311. attr: "{ 'class': 'dx-icon-' + $data.icon }",
  7312. css: "{ 'dx-icon': true }"
  7313. }),
  7314. iconSrcBinding = createElementWithBindAttr("img", {
  7315. attr: "{ src: $data.iconSrc }",
  7316. css: "{ 'dx-icon': true }"
  7317. }),
  7318. textBinding = createElementWithBindAttr("span", {
  7319. text: "text",
  7320. css: "{ 'dx-menu-item-text': true }"
  7321. }),
  7322. primitiveBinding = createElementWithBindAttr("span", {
  7323. text: "String($data)",
  7324. css: "{ 'dx-menu-item-text': true }"
  7325. }),
  7326. popout = '<span class="dx-menu-item-popout-container"><div class="dx-menu-item-popout"></div></span>';
  7327. template.push('<div class="dx-menu-item-content">', '<!-- ko if: $data.icon -->', iconBinding, '<!-- /ko -->', '<!-- ko if: !$data.icon && $data.iconSrc -->', iconSrcBinding, '<!-- /ko -->', '<!-- ko if: $.isPlainObject($data) -->', textBinding, '<!-- /ko -->', '<!-- ko ifnot: $.isPlainObject($data) -->', primitiveBinding, '<!-- /ko -->', '<!-- ko if: $data.items -->', popout, '<!-- /ko -->', '</div>', '</div>');
  7328. return template.join("")
  7329. };
  7330. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxContextMenu = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu;
  7331. $.extend(ui, {
  7332. TemplateProvider: KoTemplateProvider,
  7333. Template: KoTemplate,
  7334. defaultTemplate: defaultKoTemplate
  7335. });
  7336. ui.__internals = ui.__internals || {};
  7337. $.extend(ui.__internals, {KoTemplate: KoTemplate})
  7338. })(jQuery, DevExpress);
  7339. /*! Module core, file ng.templates.js */
  7340. (function($, DX, undefined) {
  7341. if (!DX.support.hasNg)
  7342. return;
  7343. var ui = DX.ui;
  7344. var CREATED_WITH_NG_DATA_KEY = "dxNgCreation",
  7345. COMPILER_DATA_KEY = "dxNgCompiler",
  7346. DEFAULT_COMPILER_DATA_KEY = "dxDefaultCompilerGetter";
  7347. var NgTemplate = ui.Template.inherit({
  7348. ctor: function() {
  7349. this.callBase.apply(this, arguments);
  7350. this._compiler = this._template.data(COMPILER_DATA_KEY)
  7351. },
  7352. render: function(container, data, index) {
  7353. var compiler = this._compiler,
  7354. result = $.isFunction(compiler) ? compiler(data, index) : compiler;
  7355. container.append(result);
  7356. return result
  7357. },
  7358. setCompiler: function(compilerGetter) {
  7359. this._compiler = compilerGetter(this._element)
  7360. }
  7361. });
  7362. var NgTemplateProvider = ui.TemplateProvider.inherit({
  7363. getTemplateClass: function(widget) {
  7364. if (this._createdWithNg(widget))
  7365. return NgTemplate;
  7366. return this.callBase(widget)
  7367. },
  7368. supportDefaultTemplate: function(widget) {
  7369. return this._createdWithNg(widget) ? true : this.callBase(widget)
  7370. },
  7371. getDefaultTemplate: function(widget) {
  7372. if (this._createdWithNg(widget)) {
  7373. var compilerGetter = widget._element().data(DEFAULT_COMPILER_DATA_KEY),
  7374. template = defaultNgTemplate(widget.NAME);
  7375. template.setCompiler(compilerGetter);
  7376. return template
  7377. }
  7378. },
  7379. _createdWithNg: function(widget) {
  7380. return !!widget._element().data(CREATED_WITH_NG_DATA_KEY)
  7381. }
  7382. });
  7383. var defaultNgTemplate = function() {
  7384. var cache = {};
  7385. return function(widgetName) {
  7386. if (!DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName])
  7387. widgetName = "base";
  7388. if (!cache[widgetName])
  7389. cache[widgetName] = DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName]();
  7390. return new NgTemplate(cache[widgetName])
  7391. }
  7392. }();
  7393. var baseElements = {
  7394. container: function() {
  7395. return $("<div>").attr("ng-class", "{ 'dx-state-invisible': !visible && visible != undefined, 'dx-state-disabled': !!disabled }")
  7396. },
  7397. html: function() {
  7398. return $("<div>").attr("ng-if", "html").attr("ng-bind-html", "html")
  7399. },
  7400. text: function() {
  7401. return $("<div>").attr("ng-if", "text").attr("ng-bind", "text")
  7402. },
  7403. primitive: function() {
  7404. return $("<div>").attr("ng-if", "scopeValue").attr("ng-bind-html", "'' + scopeValue")
  7405. }
  7406. };
  7407. var DEFAULT_ITEM_TEMPLATE_GENERATORS = {base: function() {
  7408. return baseElements.container().append(baseElements.html()).append(baseElements.text()).append(baseElements.primitive())
  7409. }};
  7410. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxList = function() {
  7411. return DEFAULT_ITEM_TEMPLATE_GENERATORS.base().append($("<div>").attr("ng-if", "key").attr("ng-bind", "key"))
  7412. };
  7413. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxToolbar = function() {
  7414. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base();
  7415. $.each(["button", "tabs", "dropDownMenu"], function(i, widgetName) {
  7416. var bindingName = "dx-" + DX.inflector.dasherize(this);
  7417. $("<div>").attr("ng-if", "widget === '" + widgetName + "'").attr(bindingName, "options").appendTo(template)
  7418. });
  7419. return template
  7420. };
  7421. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxGallery = function() {
  7422. return baseElements.container().append(baseElements.html()).append(baseElements.text()).append($("<img>").attr("ng-if", "scopeValue").attr("ng-src", "{{'' + scopeValue}}"))
  7423. };
  7424. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs = function() {
  7425. var container = baseElements.container();
  7426. var text = $("<span>").addClass("dx-tab-text").attr("ng-bind", "text").attr("ng-if", "text"),
  7427. icon = $("<span>").attr("ng-if", "icon").addClass("dx-icon").attr("ng-class", "'dx-icon-' + icon"),
  7428. iconSrc = $("<img>").attr("ng-if", "iconSrc").addClass("dx-icon").attr("ng-src", "{{iconSrc}}");
  7429. return container.append(baseElements.html()).append(icon).append(iconSrc).append(text).append(baseElements.primitive())
  7430. };
  7431. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu = function() {
  7432. var container = baseElements.container();
  7433. var content = $("<div>").addClass("dx-menu-item-content"),
  7434. text = $("<span>").attr("ng-if", "text").addClass("dx-menu-item-text").attr("ng-bind", "text"),
  7435. icon = $("<span>").attr("ng-if", "icon").addClass("dx-icon").attr("ng-class", "'dx-icon-' + icon"),
  7436. iconSrc = $("<img>").attr("ng-if", "iconSrc").addClass("dx-icon").attr("ng-src", "{{iconSrc}}"),
  7437. popout = $("<span>").addClass("dx-menu-item-popout-container").attr("ng-if", "items").append($("<div>").addClass("dx-menu-item-popout"));
  7438. content.append(baseElements.html()).append(icon).append(iconSrc).append(text).append(popout).append(baseElements.primitive()).appendTo(container);
  7439. return container
  7440. },
  7441. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxActionSheet = function() {
  7442. return $("<div>").attr("dx-button", "{ bindingOptions: { text: 'text', clickAction: 'clickAction', type: 'type', disabled: 'disabled' } }")
  7443. };
  7444. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxNavBar = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs;
  7445. $.extend(ui, {
  7446. Template: NgTemplate,
  7447. TemplateProvider: NgTemplateProvider
  7448. })
  7449. })(jQuery, DevExpress);
  7450. /*! Module core, file ui.themes.js */
  7451. (function($, DX, undefined) {
  7452. var DX_LINK_SELECTOR = "link[rel=dx-theme]",
  7453. THEME_ATTR = "data-theme",
  7454. ACTIVE_ATTR = "data-active";
  7455. var context,
  7456. $activeThemeLink,
  7457. knownThemes,
  7458. currentThemeName,
  7459. pendingThemeName;
  7460. var THEME_MARKER_PREFIX = "dx.";
  7461. function readThemeMarker() {
  7462. var element = $("<div></div>", context).addClass("dx-theme-marker").appendTo(context.documentElement),
  7463. result;
  7464. try {
  7465. result = element.css("font-family");
  7466. if (!result)
  7467. return null;
  7468. result = result.replace(/["']/g, "");
  7469. if (result.substr(0, THEME_MARKER_PREFIX.length) !== THEME_MARKER_PREFIX)
  7470. return null;
  7471. return result.substr(THEME_MARKER_PREFIX.length)
  7472. }
  7473. finally {
  7474. element.remove()
  7475. }
  7476. }
  7477. function waitForThemeLoad(themeName, callback) {
  7478. var timerId,
  7479. waitStartTime;
  7480. pendingThemeName = themeName;
  7481. function handleLoaded() {
  7482. pendingThemeName = null;
  7483. callback()
  7484. }
  7485. if (isPendingThemeLoaded())
  7486. handleLoaded();
  7487. else {
  7488. waitStartTime = $.now();
  7489. timerId = setInterval(function() {
  7490. var isLoaded = isPendingThemeLoaded(),
  7491. isTimeout = !isLoaded && $.now() - waitStartTime > 15 * 1000;
  7492. if (isTimeout)
  7493. DX.utils.logger.warn("Theme loading timed out: " + pendingThemeName);
  7494. if (isLoaded || isTimeout) {
  7495. clearInterval(timerId);
  7496. handleLoaded()
  7497. }
  7498. }, 10)
  7499. }
  7500. }
  7501. function isPendingThemeLoaded() {
  7502. return !pendingThemeName || readThemeMarker() === pendingThemeName
  7503. }
  7504. function processMarkup() {
  7505. var $allThemeLinks = $(DX_LINK_SELECTOR, context);
  7506. if (!$allThemeLinks.length)
  7507. return;
  7508. knownThemes = {};
  7509. $activeThemeLink = $(DX.utils.createMarkupFromString("<link rel=stylesheet>"), context);
  7510. $allThemeLinks.each(function() {
  7511. var link = $(this, context),
  7512. fullThemeName = link.attr(THEME_ATTR),
  7513. url = link.attr("href"),
  7514. isActive = link.attr(ACTIVE_ATTR) === "true";
  7515. knownThemes[fullThemeName] = {
  7516. url: url,
  7517. isActive: isActive
  7518. }
  7519. });
  7520. $allThemeLinks.last().after($activeThemeLink);
  7521. $allThemeLinks.remove()
  7522. }
  7523. function resolveFullThemeName(desiredThemeName) {
  7524. var desiredThemeParts = desiredThemeName.split("."),
  7525. result = null;
  7526. if (knownThemes)
  7527. $.each(knownThemes, function(knownThemeName, themeData) {
  7528. var knownThemeParts = knownThemeName.split(".");
  7529. if (knownThemeParts[0] !== desiredThemeParts[0])
  7530. return;
  7531. if (desiredThemeParts[1] && desiredThemeParts[1] !== knownThemeParts[1])
  7532. return;
  7533. if (!result || themeData.isActive)
  7534. result = knownThemeName;
  7535. if (themeData.isActive)
  7536. return false
  7537. });
  7538. return result
  7539. }
  7540. function initContext(newContext) {
  7541. try {
  7542. if (newContext !== context)
  7543. knownThemes = null
  7544. }
  7545. catch(x) {
  7546. knownThemes = null
  7547. }
  7548. context = newContext
  7549. }
  7550. function init(options) {
  7551. options = options || {};
  7552. initContext(options.context || document);
  7553. processMarkup();
  7554. currentThemeName = undefined;
  7555. current(options)
  7556. }
  7557. function current(options) {
  7558. if (!arguments.length)
  7559. return currentThemeName || readThemeMarker();
  7560. options = options || {};
  7561. if (typeof options === "string")
  7562. options = {theme: options};
  7563. var isAutoInit = options._autoInit,
  7564. loadCallback = options.loadCallback,
  7565. currentThemeData;
  7566. currentThemeName = options.theme || currentThemeName;
  7567. if (isAutoInit && !currentThemeName)
  7568. currentThemeName = themeNameFromDevice(DX.devices.current());
  7569. currentThemeName = resolveFullThemeName(currentThemeName);
  7570. if (currentThemeName)
  7571. currentThemeData = knownThemes[currentThemeName];
  7572. if (currentThemeData) {
  7573. $activeThemeLink.removeAttr("href");
  7574. $activeThemeLink.attr("href", knownThemes[currentThemeName].url);
  7575. if (loadCallback)
  7576. waitForThemeLoad(currentThemeName, loadCallback);
  7577. else if (pendingThemeName)
  7578. pendingThemeName = currentThemeName
  7579. }
  7580. else if (isAutoInit) {
  7581. if (loadCallback)
  7582. loadCallback()
  7583. }
  7584. else
  7585. throw Error("Unknown theme: " + currentThemeName);
  7586. }
  7587. function themeNameFromDevice(device) {
  7588. var themeName = device.platform,
  7589. majorVersion = device.version && device.version[0];
  7590. if (themeName === "ios" && (!majorVersion || majorVersion > 6))
  7591. themeName += "7";
  7592. return themeName
  7593. }
  7594. function getCssClasses(themeName) {
  7595. themeName = themeName || current();
  7596. var result = [],
  7597. themeNameParts = themeName && themeName.split(".");
  7598. if (themeNameParts) {
  7599. result.push("dx-theme-" + themeNameParts[0], "dx-theme-" + themeNameParts[0] + "-typography");
  7600. if (themeNameParts.length > 1)
  7601. result.push("dx-color-scheme-" + themeNameParts[1])
  7602. }
  7603. return result
  7604. }
  7605. function attachCssClasses(element, themeName) {
  7606. $(element).addClass(getCssClasses(themeName).join(" "))
  7607. }
  7608. function detachCssClasses(element, themeName) {
  7609. $(element).removeClass(getCssClasses(themeName).join(" "))
  7610. }
  7611. $.holdReady(true);
  7612. init({
  7613. _autoInit: true,
  7614. loadCallback: function() {
  7615. $.holdReady(false)
  7616. }
  7617. });
  7618. $(function() {
  7619. if ($(DX_LINK_SELECTOR, context).length)
  7620. throw Error("LINK[rel=dx-theme] tags must go before DevExpress included scripts");
  7621. });
  7622. DX.ui.themes = {
  7623. init: init,
  7624. current: current,
  7625. attachCssClasses: attachCssClasses,
  7626. detachCssClasses: detachCssClasses
  7627. };
  7628. DX.ui.themes.__internals = {
  7629. themeNameFromDevice: themeNameFromDevice,
  7630. waitForThemeLoad: waitForThemeLoad,
  7631. resetTheme: function() {
  7632. $activeThemeLink.attr("href", "about:blank");
  7633. currentThemeName = null;
  7634. pendingThemeName = null
  7635. }
  7636. }
  7637. })(jQuery, DevExpress);
  7638. /*! Module core, file ui.events.js */
  7639. (function($, DX, undefined) {
  7640. var ui = DX.ui,
  7641. eventNS = $.event,
  7642. specialNS = eventNS.special,
  7643. EVENT_SOURCES_REGEX = {
  7644. mouse: /(mouse|wheel|click)/i,
  7645. wheel: /wheel/i,
  7646. touch: /^touch/i,
  7647. keyboard: /^key/i,
  7648. pointer: /pointer/i
  7649. };
  7650. var eventSource = function(e) {
  7651. var result = "other";
  7652. $.each(EVENT_SOURCES_REGEX, function(key) {
  7653. if (this.test(e.type)) {
  7654. result = key;
  7655. return false
  7656. }
  7657. });
  7658. return result
  7659. };
  7660. var isPointerEvent = function(e) {
  7661. return eventSource(e) === "pointer"
  7662. };
  7663. var isMouseEvent = function(e) {
  7664. return eventSource(e) === "mouse" || isPointerEvent(e) && e.pointerType === "mouse"
  7665. };
  7666. var isTouchEvent = function(e) {
  7667. return eventSource(e) === "touch" || isPointerEvent(e) && e.pointerType === "touch"
  7668. };
  7669. var isKeyboardEvent = function(e) {
  7670. return eventSource(e) === "keyboard"
  7671. };
  7672. var isMouseWheelEvent = function(e) {
  7673. return EVENT_SOURCES_REGEX["wheel"].test(e.type)
  7674. };
  7675. var addNamespace = function(eventNames, namespace) {
  7676. if (!namespace)
  7677. throw Error("Namespace is not defined");
  7678. if (typeof eventNames === "string")
  7679. return addNamespace(eventNames.split(/\s+/g), namespace);
  7680. $.each(eventNames, function(index, eventName) {
  7681. eventNames[index] = eventName + "." + namespace
  7682. });
  7683. return eventNames.join(" ")
  7684. };
  7685. var eventData = function(e) {
  7686. if (isPointerEvent(e) && isTouchEvent(e)) {
  7687. var touch = (e.originalEvent.originalEvent || e.originalEvent).changedTouches[0];
  7688. return {
  7689. x: touch.pageX,
  7690. y: touch.pageY,
  7691. time: e.timeStamp
  7692. }
  7693. }
  7694. if (isMouseEvent(e))
  7695. return {
  7696. x: e.pageX,
  7697. y: e.pageY,
  7698. time: e.timeStamp
  7699. };
  7700. if (isTouchEvent(e)) {
  7701. var touch = (e.changedTouches || e.originalEvent.changedTouches)[0];
  7702. return {
  7703. x: touch.pageX,
  7704. y: touch.pageY,
  7705. time: e.timeStamp
  7706. }
  7707. }
  7708. };
  7709. var eventDelta = function(from, to) {
  7710. return {
  7711. x: to.x - from.x,
  7712. y: to.y - from.y,
  7713. time: to.time - from.time || 1
  7714. }
  7715. };
  7716. var hasTouches = function(e) {
  7717. if (isTouchEvent(e))
  7718. return (e.originalEvent.touches || []).length;
  7719. return 0
  7720. };
  7721. var needSkipEvent = function(e) {
  7722. var $target = $(e.target),
  7723. touchInInput = $target.is("input, textarea, select");
  7724. if (isMouseWheelEvent(e) && touchInInput)
  7725. return false;
  7726. if (isMouseEvent(e))
  7727. return touchInInput || e.which > 1;
  7728. if (isTouchEvent(e))
  7729. return touchInInput && $target.is(":focus") || (e.originalEvent.changedTouches || e.originalEvent.originalEvent.changedTouches).length !== 1
  7730. };
  7731. var createEvent = function(sourceEvent, props) {
  7732. var event = $.Event(sourceEvent),
  7733. originalEvent = event.originalEvent,
  7734. propNames = $.event.props.slice();
  7735. if (isMouseEvent(sourceEvent) || isTouchEvent(sourceEvent))
  7736. $.merge(propNames, $.event.mouseHooks.props);
  7737. if (isKeyboardEvent(sourceEvent))
  7738. $.merge(propNames, $.event.keyHooks.props);
  7739. if (originalEvent)
  7740. $.each(propNames, function() {
  7741. event[this] = originalEvent[this]
  7742. });
  7743. if (props)
  7744. $.extend(event, props);
  7745. return event
  7746. };
  7747. var fireEvent = function(props) {
  7748. var event = createEvent(props.originalEvent, props);
  7749. $.event.trigger(event, null, props.target || event.target);
  7750. return event
  7751. };
  7752. var handleGestureEvent = function(e, type) {
  7753. var gestureEvent = $(e.target).data("dxGestureEvent");
  7754. if (!gestureEvent || gestureEvent === type) {
  7755. $(e.target).data("dxGestureEvent", type);
  7756. return true
  7757. }
  7758. return false
  7759. };
  7760. var registerEvent = function(eventName, eventObject) {
  7761. var strategy = {};
  7762. if ("noBubble" in eventObject)
  7763. strategy.noBubble = eventObject.noBubble;
  7764. if ("bindType" in eventObject)
  7765. strategy.bindType = eventObject.bindType;
  7766. if ("delegateType" in eventObject)
  7767. strategy.delegateType = eventObject.delegateType;
  7768. $.each(["setup", "teardown", "add", "remove", "trigger", "handle", "_default", "dispose"], function(_, methodName) {
  7769. if (!eventObject[methodName])
  7770. return;
  7771. strategy[methodName] = function() {
  7772. var args = $.makeArray(arguments);
  7773. args.unshift(this);
  7774. return eventObject[methodName].apply(eventObject, args)
  7775. }
  7776. });
  7777. specialNS[eventName] = strategy
  7778. };
  7779. ui.events = {
  7780. eventSource: eventSource,
  7781. isPointerEvent: isPointerEvent,
  7782. isMouseEvent: isMouseEvent,
  7783. isTouchEvent: isTouchEvent,
  7784. isKeyboardEvent: isKeyboardEvent,
  7785. addNamespace: addNamespace,
  7786. hasTouches: hasTouches,
  7787. eventData: eventData,
  7788. eventDelta: eventDelta,
  7789. needSkipEvent: needSkipEvent,
  7790. createEvent: createEvent,
  7791. fireEvent: fireEvent,
  7792. handleGestureEvent: handleGestureEvent,
  7793. registerEvent: registerEvent
  7794. }
  7795. })(jQuery, DevExpress);
  7796. /*! Module core, file ko.events.js */
  7797. (function($, DX, undefined) {
  7798. if (!DX.support.hasKo)
  7799. return;
  7800. var ko = window.ko,
  7801. events = DX.ui.events;
  7802. var originalRegisterEvent = events.registerEvent;
  7803. var registerKoEvent = function(eventName, eventObject) {
  7804. originalRegisterEvent(eventName, eventObject);
  7805. var koBindingEventName = events.addNamespace(eventName, eventName + "Binding");
  7806. ko.bindingHandlers[eventName] = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
  7807. var $element = $(element),
  7808. unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
  7809. eventSource = unwrappedValue.execute ? unwrappedValue.execute : unwrappedValue;
  7810. $element.off(koBindingEventName).on(koBindingEventName, $.isPlainObject(unwrappedValue) ? unwrappedValue : {}, function(e) {
  7811. eventSource(viewModel, e)
  7812. })
  7813. }}
  7814. };
  7815. $.extend(events, {registerEvent: registerKoEvent})
  7816. })(jQuery, DevExpress);
  7817. /*! Module core, file ng.events.js */
  7818. (function($, DX, undefined) {
  7819. if (!DX.support.hasNg)
  7820. return;
  7821. var events = DX.ui.events;
  7822. var originalRegisterEvent = events.registerEvent;
  7823. var registerNgEvent = function(eventName, eventObject) {
  7824. originalRegisterEvent(eventName, eventObject);
  7825. var ngEventName = eventName.slice(0, 2) + eventName.charAt(2).toUpperCase() + eventName.slice(3);
  7826. DX.ng.module.directive(ngEventName, ['$parse', function($parse) {
  7827. return function(scope, element, attr) {
  7828. var attrValue = $.trim(attr[ngEventName]),
  7829. handler,
  7830. eventOptions = {};
  7831. if (attrValue.charAt(0) === "{") {
  7832. eventOptions = scope.$eval(attrValue);
  7833. handler = $parse(eventOptions.execute)
  7834. }
  7835. else
  7836. handler = $parse(attr[ngEventName]);
  7837. element.on(eventName, eventOptions, function(e) {
  7838. scope.$apply(function() {
  7839. handler(scope, {$event: e})
  7840. })
  7841. })
  7842. }
  7843. }])
  7844. };
  7845. $.extend(events, {registerEvent: registerNgEvent})
  7846. })(jQuery, DevExpress);
  7847. /*! Module core, file ui.hierarchicalKeyDownProcessor.js */
  7848. (function($, DX, undefined) {
  7849. var ui = DX.ui,
  7850. events = ui.events;
  7851. ui.HierarchicalKeyDownProcessor = DX.Class.inherit({
  7852. _keydown: events.addNamespace("keydown", "HierarchicalKeyDownProcessor"),
  7853. codes: {
  7854. "9": "tab",
  7855. "13": "enter",
  7856. "27": "escape",
  7857. "33": "pageUp",
  7858. "34": "pageDown",
  7859. "37": "leftArrow",
  7860. "38": "upArrow",
  7861. "39": "rightArrow",
  7862. "40": "downArrow",
  7863. "32": "space",
  7864. "70": "F",
  7865. "65": "A"
  7866. },
  7867. ctor: function(options) {
  7868. var _this = this;
  7869. options = options || {};
  7870. if (options.element)
  7871. this._element = $(options.element);
  7872. this._handler = options.handler;
  7873. this._context = options.context;
  7874. this._childProcessors = [];
  7875. if (this._element)
  7876. this._element.on(this._keydown, function(e) {
  7877. _this.process(e)
  7878. })
  7879. },
  7880. dispose: function() {
  7881. if (this._element)
  7882. this._element.off(this._keydown);
  7883. this._element = undefined;
  7884. this._handler = undefined;
  7885. this._context = undefined;
  7886. this._childProcessors = undefined
  7887. },
  7888. attachChildProcessor: function() {
  7889. var childProcessor = new ui.HierarchicalKeyDownProcessor;
  7890. this._childProcessors.push(childProcessor);
  7891. return childProcessor
  7892. },
  7893. reinitialize: function(childHandler, childContext) {
  7894. this._context = childContext;
  7895. this._handler = childHandler;
  7896. return this
  7897. },
  7898. process: function(e) {
  7899. var args = {
  7900. key: this.codes[e.which],
  7901. ctrl: e.ctrlKey,
  7902. shift: e.shiftKey,
  7903. originalEvent: e
  7904. };
  7905. if (this.codes[e.which] && this._handler && this._handler.call(this._context, args))
  7906. $.each(this._childProcessors, function(index, childProcessor) {
  7907. childProcessor.process(e)
  7908. })
  7909. }
  7910. })
  7911. })(jQuery, DevExpress);
  7912. /*! Module core, file ui.dialog.js */
  7913. (function($, DX, undefined) {
  7914. var ui = DX.ui,
  7915. utils = DX.utils;
  7916. var DEFAULT_BUTTON = {
  7917. text: "OK",
  7918. clickAction: function() {
  7919. return true
  7920. }
  7921. };
  7922. var DX_DIALOG_CLASSNAME = "dx-dialog",
  7923. DX_DIALOG_WRAPPER_CLASSNAME = DX_DIALOG_CLASSNAME + "-wrapper",
  7924. DX_DIALOG_ROOT_CLASSNAME = DX_DIALOG_CLASSNAME + "-root",
  7925. DX_DIALOG_CONTENT_CLASSNAME = DX_DIALOG_CLASSNAME + "-content",
  7926. DX_DIALOG_MESSAGE_CLASSNAME = DX_DIALOG_CLASSNAME + "-message",
  7927. DX_DIALOG_BUTTONS_CLASSNAME = DX_DIALOG_CLASSNAME + "-buttons",
  7928. DX_DIALOG_BUTTON_CLASSNAME = DX_DIALOG_CLASSNAME + "-button";
  7929. var FakeDialogComponent = DX.Component.inherit({
  7930. NAME: "dxDialog",
  7931. ctor: function(element, options) {
  7932. this.callBase(options)
  7933. },
  7934. _defaultOptionsRules: function() {
  7935. return this.callBase().slice(0).concat([{
  7936. device: [{platform: "ios"}, {platform: "ios7"}],
  7937. options: {width: 276}
  7938. }, {
  7939. device: {platform: "android"},
  7940. options: {
  7941. lWidth: "60%",
  7942. pWidth: "80%"
  7943. }
  7944. }, {
  7945. device: {
  7946. platform: "win8",
  7947. phone: false
  7948. },
  7949. options: {width: function() {
  7950. return $(window).width()
  7951. }}
  7952. }, {
  7953. device: {
  7954. platform: "win8",
  7955. phone: true
  7956. },
  7957. options: {position: {
  7958. my: "top center",
  7959. at: "top center",
  7960. of: window,
  7961. offset: "0 0"
  7962. }}
  7963. }])
  7964. }
  7965. });
  7966. var dialog = function(options) {
  7967. var that = this,
  7968. result;
  7969. if (!ui.dxPopup)
  7970. throw new Error("DevExpress.ui.dxPopup required");
  7971. var deferred = $.Deferred();
  7972. var defaultOptions = (new FakeDialogComponent).option();
  7973. options = $.extend(defaultOptions, options);
  7974. var $holder = $(DX.overlayTargetContainer());
  7975. var $element = $("<div>").addClass(DX_DIALOG_CLASSNAME).appendTo($holder);
  7976. var $message = $("<div>").addClass(DX_DIALOG_MESSAGE_CLASSNAME).html(String(options.message));
  7977. var $buttons = $("<div>").addClass(DX_DIALOG_BUTTONS_CLASSNAME);
  7978. var popupInstance = $element.dxPopup({
  7979. title: options.title || that.title,
  7980. height: "auto",
  7981. width: function() {
  7982. var isPortrait = $(window).height() > $(window).width(),
  7983. key = (isPortrait ? "p" : "l") + "Width",
  7984. widthOption = options.hasOwnProperty(key) ? options[key] : options["width"];
  7985. return $.isFunction(widthOption) ? widthOption() : widthOption
  7986. },
  7987. contentReadyAction: function() {
  7988. popupInstance.content().addClass(DX_DIALOG_CONTENT_CLASSNAME).append($message).append($buttons)
  7989. },
  7990. animation: {
  7991. show: {
  7992. type: "pop",
  7993. duration: 400
  7994. },
  7995. hide: {
  7996. type: "pop",
  7997. duration: 400,
  7998. to: {
  7999. opacity: 0,
  8000. scale: 0
  8001. },
  8002. from: {
  8003. opacity: 1,
  8004. scale: 1
  8005. }
  8006. }
  8007. },
  8008. rtlEnabled: DX.rtlEnabled
  8009. }).data("dxPopup");
  8010. popupInstance._wrapper().addClass(DX_DIALOG_WRAPPER_CLASSNAME);
  8011. if (options.position)
  8012. popupInstance.option("position", options.position);
  8013. $.each(options.buttons || [DEFAULT_BUTTON], function() {
  8014. var button = $("<div>").addClass(DX_DIALOG_BUTTON_CLASSNAME).appendTo($buttons);
  8015. var action = new DX.Action(this.clickAction, {context: popupInstance});
  8016. button.dxButton($.extend(this, {clickAction: function() {
  8017. result = action.execute(arguments);
  8018. hide()
  8019. }}))
  8020. });
  8021. popupInstance._wrapper().addClass(DX_DIALOG_ROOT_CLASSNAME);
  8022. function show() {
  8023. popupInstance.show();
  8024. utils.resetActiveElement();
  8025. return deferred.promise()
  8026. }
  8027. function hide(value) {
  8028. popupInstance.hide().done(function() {
  8029. popupInstance._element().remove()
  8030. });
  8031. deferred.resolve(result || value)
  8032. }
  8033. return {
  8034. show: show,
  8035. hide: hide
  8036. }
  8037. };
  8038. var alert = function(message, title) {
  8039. var dialogInstance,
  8040. options = $.isPlainObject(message) ? message : {
  8041. title: title,
  8042. message: message
  8043. };
  8044. dialogInstance = ui.dialog.custom(options);
  8045. return dialogInstance.show()
  8046. };
  8047. var confirm = function(message, title) {
  8048. var dialogInstance,
  8049. options = $.isPlainObject(message) ? message : {
  8050. title: title,
  8051. message: message,
  8052. buttons: [{
  8053. text: Globalize.localize("Yes"),
  8054. clickAction: function() {
  8055. return true
  8056. }
  8057. }, {
  8058. text: Globalize.localize("No"),
  8059. clickAction: function() {
  8060. return false
  8061. }
  8062. }]
  8063. };
  8064. dialogInstance = ui.dialog.custom(options);
  8065. return dialogInstance.show()
  8066. };
  8067. var notify = function(message, type, displayTime) {
  8068. var options = $.isPlainObject(message) ? message : {message: message};
  8069. if (!ui.dxToast) {
  8070. alert(options.message);
  8071. return
  8072. }
  8073. var userHiddenAction = options.hiddenAction;
  8074. $.extend(options, {
  8075. type: type,
  8076. displayTime: displayTime,
  8077. hiddenAction: function(args) {
  8078. args.element.remove();
  8079. new DX.Action(userHiddenAction, {context: args.model}).execute(arguments)
  8080. }
  8081. });
  8082. $("<div>").appendTo(DX.overlayTargetContainer()).dxToast(options).dxToast("instance").show()
  8083. };
  8084. $.extend(ui, {
  8085. notify: notify,
  8086. dialog: {
  8087. custom: dialog,
  8088. alert: alert,
  8089. confirm: confirm,
  8090. FakeDialogComponent: FakeDialogComponent
  8091. }
  8092. })
  8093. })(jQuery, DevExpress);
  8094. /*! Module core, file ui.dataHelper.js */
  8095. (function($, DX, undefined) {
  8096. var data = DX.data;
  8097. var DATA_SOURCE_OPTIONS_METHOD = "_dataSourceOptions",
  8098. DATA_SOURCE_CHANGED_METHOD = "_handleDataSourceChanged",
  8099. DATA_SOURCE_LOAD_ERROR_METHOD = "_handleDataSourceLoadError",
  8100. DATA_SOURCE_LOADING_CHANGED_METHOD = "_handleDataSourceLoadingChanged";
  8101. DX.ui.DataHelperMixin = {
  8102. ctor: function() {
  8103. this.disposing.add(function() {
  8104. this._disposeDataSource()
  8105. })
  8106. },
  8107. _refreshDataSource: function() {
  8108. this._initDataSource();
  8109. this._loadDataSource()
  8110. },
  8111. _initDataSource: function() {
  8112. var dataSourceOptions = this.option("dataSource"),
  8113. widgetDataSourceOptions,
  8114. dataSourceType;
  8115. this._disposeDataSource();
  8116. if (dataSourceOptions) {
  8117. if (dataSourceOptions instanceof data.DataSource) {
  8118. this._isSharedDataSource = true;
  8119. this._dataSource = dataSourceOptions
  8120. }
  8121. else {
  8122. widgetDataSourceOptions = DATA_SOURCE_OPTIONS_METHOD in this ? this[DATA_SOURCE_OPTIONS_METHOD]() : {};
  8123. dataSourceType = this._dataSourceType ? this._dataSourceType() : data.DataSource;
  8124. this._dataSource = new dataSourceType($.extend(true, {}, widgetDataSourceOptions, data.utils.normalizeDataSourceOptions(dataSourceOptions)))
  8125. }
  8126. this._addDataSourceHandlers()
  8127. }
  8128. },
  8129. _addDataSourceHandlers: function() {
  8130. if (DATA_SOURCE_CHANGED_METHOD in this)
  8131. this._addDataSourceChangeHandler();
  8132. if (DATA_SOURCE_LOAD_ERROR_METHOD in this)
  8133. this._addDataSourceLoadErrorHandler();
  8134. if (DATA_SOURCE_LOADING_CHANGED_METHOD in this)
  8135. this._addDataSourceLoadingChangedHandler()
  8136. },
  8137. _addDataSourceChangeHandler: function() {
  8138. var that = this,
  8139. dataSource = this._dataSource;
  8140. this._dataSourceChangedHandler = function() {
  8141. that[DATA_SOURCE_CHANGED_METHOD](dataSource.items())
  8142. };
  8143. dataSource.changed.add(this._dataSourceChangedHandler)
  8144. },
  8145. _addDataSourceLoadErrorHandler: function() {
  8146. this._dataSourceLoadErrorHandler = $.proxy(this[DATA_SOURCE_LOAD_ERROR_METHOD], this);
  8147. this._dataSource.loadError.add(this._dataSourceLoadErrorHandler)
  8148. },
  8149. _addDataSourceLoadingChangedHandler: function() {
  8150. this._dataSourceLoadingChangedHandler = $.proxy(this[DATA_SOURCE_LOADING_CHANGED_METHOD], this);
  8151. this._dataSource.loadingChanged.add(this._dataSourceLoadingChangedHandler)
  8152. },
  8153. _loadDataSource: function() {
  8154. if (this._dataSource) {
  8155. var dataSource = this._dataSource;
  8156. if (dataSource.isLoaded())
  8157. this._dataSourceChangedHandler();
  8158. else
  8159. dataSource.load()
  8160. }
  8161. },
  8162. _loadSingle: function(key, value) {
  8163. key = key === "this" ? this._dataSource.key() || "this" : key;
  8164. return this._dataSource.loadSingle(key, value)
  8165. },
  8166. _disposeDataSource: function() {
  8167. if (this._dataSource) {
  8168. if (this._isSharedDataSource) {
  8169. delete this._isSharedDataSource;
  8170. this._dataSource.changed.remove(this._dataSourceChangedHandler);
  8171. this._dataSource.loadError.remove(this._dataSourceLoadErrorHandler);
  8172. this._dataSource.loadingChanged.remove(this._dataSourceLoadingChangedHandler)
  8173. }
  8174. else
  8175. this._dataSource.dispose();
  8176. delete this._dataSource;
  8177. delete this._dataSourceChangedHandler;
  8178. delete this._dataSourceLoadErrorHandler;
  8179. delete this._dataSourceLoadingChangedHandler
  8180. }
  8181. }
  8182. }
  8183. })(jQuery, DevExpress);
  8184. /*! Module core, file ui.events.mspointer.js */
  8185. (function($, DX, undefined) {
  8186. var POINTER_TYPE_MAP = {
  8187. 2: "touch",
  8188. 3: "pen",
  8189. 4: "mouse"
  8190. };
  8191. var pointerEventHook = {
  8192. filter: function(event, originalEvent) {
  8193. var pointerType = originalEvent.pointerType;
  8194. if ($.isNumeric(pointerType))
  8195. event.pointerType = POINTER_TYPE_MAP[pointerType];
  8196. return event
  8197. },
  8198. props: $.event.mouseHooks.props.concat(["pointerId", "originalTarget", "namespace", "width", "height", "pressure", "result", "tiltX", "charCode", "tiltY", "detail", "isPrimary", "prevValue"])
  8199. };
  8200. $.each(["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel", "MSPointerOver", "MSPointerOut", "MSPointerEnter", "MSPointerLeave", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave"], function() {
  8201. $.event.fixHooks[this] = pointerEventHook
  8202. })
  8203. })(jQuery, DevExpress);
  8204. /*! Module core, file ui.events.touch.js */
  8205. (function($, DX, undefined) {
  8206. var touchEventHook = {
  8207. filter: function(event, originalEvent) {
  8208. if (originalEvent.changedTouches.length)
  8209. $.each(["pageX", "pageY", "screenX", "screenY", "clientX", "clientY"], function() {
  8210. event[this] = originalEvent.changedTouches[0][this]
  8211. });
  8212. return event
  8213. },
  8214. props: $.event.mouseHooks.props.concat(["touches", "changedTouches", "targetTouches", "detail", "result", "namespace", "originalTarget", "charCode", "prevValue"])
  8215. };
  8216. $.each(["touchstart", "touchmove", "touchend", "touchcancel"], function() {
  8217. $.event.fixHooks[this] = touchEventHook
  8218. })
  8219. })(jQuery, DevExpress);
  8220. /*! Module core, file ui.events.pointer.js */
  8221. (function($, DX, undefined) {
  8222. var ui = DX.ui,
  8223. support = DX.support,
  8224. device = $.proxy(DX.devices.real, DX.devices),
  8225. events = ui.events;
  8226. var POINTER_EVENTS_NAMESPACE = "dxPointerEvents",
  8227. MouseStrategyEventMap = {
  8228. dxpointerdown: "mousedown",
  8229. dxpointermove: "mousemove",
  8230. dxpointerup: "mouseup",
  8231. dxpointercancel: ""
  8232. },
  8233. TouchStrategyEventMap = {
  8234. dxpointerdown: "touchstart",
  8235. dxpointermove: "touchmove",
  8236. dxpointerup: "touchend",
  8237. dxpointercancel: "touchcancel"
  8238. },
  8239. PointerStrategyEventMap = {
  8240. dxpointerdown: "pointerdown",
  8241. dxpointermove: "pointermove",
  8242. dxpointerup: "pointerup",
  8243. dxpointercancel: "pointercancel"
  8244. },
  8245. MouseAndTouchStrategyEventMap = {
  8246. dxpointerdown: "touchstart mousedown",
  8247. dxpointermove: "touchmove mousemove",
  8248. dxpointerup: "touchend mouseup",
  8249. dxpointercancel: "touchcancel"
  8250. };
  8251. var eventMap = function() {
  8252. if (support.touch && !(device().tablet || device().phone))
  8253. return MouseAndTouchStrategyEventMap;
  8254. if (support.pointer)
  8255. return MouseStrategyEventMap;
  8256. if (support.touch)
  8257. return TouchStrategyEventMap;
  8258. return MouseStrategyEventMap
  8259. }();
  8260. var skipTouchWithSameIdentifier = function(pointerEvent) {
  8261. return device().platform === "ios" && (pointerEvent === "dxpointerdown" || pointerEvent === "dxpointerup")
  8262. };
  8263. var SingleEventStrategy = DX.Class.inherit({
  8264. ctor: function(eventName, originalEvents) {
  8265. this._eventName = eventName;
  8266. this._eventNamespace = [POINTER_EVENTS_NAMESPACE, ".", this._eventName].join("");
  8267. this._originalEvents = originalEvents;
  8268. this._pointerId = 0;
  8269. this._handlerCount = 0
  8270. },
  8271. _handler: function(e) {
  8272. if (this._eventName === "dxpointerdown")
  8273. $(e.target).data("dxGestureEvent", null);
  8274. if (events.isTouchEvent(e) && skipTouchWithSameIdentifier(this._eventName)) {
  8275. var touch = e.changedTouches[0];
  8276. if (this._pointerId === touch.identifier && this._pointerId !== 0)
  8277. return;
  8278. this._pointerId = touch.identifier
  8279. }
  8280. return events.fireEvent({
  8281. type: this._eventName,
  8282. pointerType: events.eventSource(e),
  8283. originalEvent: e
  8284. })
  8285. },
  8286. setup: function() {
  8287. if (this._handlerCount > 0)
  8288. return;
  8289. $(document).on(events.addNamespace(this._originalEvents, this._eventNamespace), $.proxy(this._handler, this))
  8290. },
  8291. add: function() {
  8292. this._handlerCount++
  8293. },
  8294. remove: function() {
  8295. this._handlerCount--
  8296. },
  8297. teardown: function() {
  8298. if (this._handlerCount)
  8299. return;
  8300. $(document).off("." + this._eventNamespace)
  8301. },
  8302. dispose: function() {
  8303. $(document).off("." + this._eventNamespace)
  8304. }
  8305. });
  8306. var MultiEventStrategy = SingleEventStrategy.inherit({
  8307. EVENT_LOCK_TIMEOUT: 100,
  8308. _handler: function(e) {
  8309. if (events.isTouchEvent(e))
  8310. this._skipNextEvents = true;
  8311. if (events.isMouseEvent(e) && this._mouseLocked)
  8312. return;
  8313. if (events.isMouseEvent(e) && this._skipNextEvents) {
  8314. this._skipNextEvents = false;
  8315. this._mouseLocked = true;
  8316. clearTimeout(this._unlockMouseTimer);
  8317. this._unlockMouseTimer = setTimeout($.proxy(function() {
  8318. this._mouseLocked = false
  8319. }, this), this.EVENT_LOCK_TIMEOUT);
  8320. return
  8321. }
  8322. return this.callBase(e)
  8323. },
  8324. dispose: function() {
  8325. this.callBase();
  8326. this._skipNextEvents = false;
  8327. this._mouseLocked = false;
  8328. clearTimeout(this._unlockMouseTimer)
  8329. }
  8330. });
  8331. var getStrategy = function() {
  8332. return eventMap === MouseAndTouchStrategyEventMap ? MultiEventStrategy : SingleEventStrategy
  8333. };
  8334. $.each(eventMap, function(pointerEvent, originalEvents) {
  8335. var Strategy = getStrategy();
  8336. events.registerEvent(pointerEvent, new Strategy(pointerEvent, originalEvents))
  8337. });
  8338. DX.ui.events.__internals = DX.ui.events.__internals || {};
  8339. $.extend(DX.ui.events.__internals, {
  8340. SingleEventStrategy: SingleEventStrategy,
  8341. MultiEventStrategy: MultiEventStrategy,
  8342. MouseStrategyEventMap: MouseStrategyEventMap,
  8343. TouchStrategyEventMap: TouchStrategyEventMap,
  8344. PointerStrategyEventMap: PointerStrategyEventMap,
  8345. MouseAndTouchStrategyEventMap: MouseAndTouchStrategyEventMap,
  8346. eventMap: eventMap
  8347. })
  8348. })(jQuery, DevExpress);
  8349. /*! Module core, file ui.events.click.js */
  8350. (function($, DX, wnd, undefined) {
  8351. var ua = navigator.userAgent,
  8352. screen = wnd.screen,
  8353. ui = DX.ui,
  8354. utils = DX.utils,
  8355. events = ui.events,
  8356. support = DX.support,
  8357. device = $.proxy(DX.devices.real, DX.devices),
  8358. EVENTS_NAME_SPACE = "dxSpecialEvents",
  8359. CLICK_NAME_SPACE = "dxClick" + EVENTS_NAME_SPACE,
  8360. CLICK_EVENT_NAME = "dxclick",
  8361. SCROLLABLE_PARENT_DATA_KEY = "dxClickScrollableParent",
  8362. SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY = "dxClickScrollableParentOffset",
  8363. preferNativeClick = function() {
  8364. var iPhone4SAndElder = device().deviceType === "phone" && screen.height <= 480,
  8365. iPad2AndElder = device().deviceType === "tablet" && wnd.devicePixelRatio < 2,
  8366. IOS7AndNewer = device().platform === "ios" && device().version[0] > 6;
  8367. return IOS7AndNewer && (iPhone4SAndElder || iPad2AndElder)
  8368. }(),
  8369. useNativeClick = function() {
  8370. if (!support.touch)
  8371. return true;
  8372. var chromeInfo = ua.match(/Chrome\/([0-9]+)/) || [],
  8373. chrome = !!chromeInfo[0],
  8374. chromeVersion = ~~chromeInfo[1],
  8375. android = device().platform === "android";
  8376. if (chrome)
  8377. if (android) {
  8378. if ($("meta[name=viewport][content*='width=device-width']").length)
  8379. return false;
  8380. if (chromeVersion > 31 && wnd.innerWidth <= screen.width)
  8381. return true;
  8382. if ($("meta[name=viewport][content*='user-scalable=no']").length)
  8383. return true
  8384. }
  8385. else
  8386. return true;
  8387. return false
  8388. }();
  8389. var SimulatedStrategy = DX.Class.inherit({
  8390. TOUCH_BOUNDARY: 10,
  8391. ctor: function() {
  8392. this._startX = 0;
  8393. this._startY = 0;
  8394. this._handlerCount = 0;
  8395. this._target = null
  8396. },
  8397. _touchWasMoved: function(e) {
  8398. var boundary = this.TOUCH_BOUNDARY;
  8399. return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary
  8400. },
  8401. _getClosestScrollable: function($element) {
  8402. var $scrollParent = $();
  8403. if ($element.data(SCROLLABLE_PARENT_DATA_KEY))
  8404. $scrollParent = $element.data(SCROLLABLE_PARENT_DATA_KEY);
  8405. else {
  8406. var $current = $element;
  8407. while ($current.length) {
  8408. if ($current[0].scrollHeight - $current[0].offsetHeight > 1) {
  8409. $scrollParent = $current;
  8410. $element.data(SCROLLABLE_PARENT_DATA_KEY, $scrollParent);
  8411. break
  8412. }
  8413. $current = $current.parent()
  8414. }
  8415. }
  8416. return $scrollParent
  8417. },
  8418. _saveClosestScrollableOffset: function($element) {
  8419. var $scrollable = this._getClosestScrollable($element);
  8420. if ($scrollable.length)
  8421. $element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY, $scrollable.scrollTop())
  8422. },
  8423. _closestScrollableWasMoved: function($element) {
  8424. var $scrollable = $element.data(SCROLLABLE_PARENT_DATA_KEY);
  8425. return $scrollable && $scrollable.scrollTop() !== $element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY)
  8426. },
  8427. _hasClosestScrollable: function($element) {
  8428. var $scrollable = this._getClosestScrollable($element);
  8429. if (!$scrollable.length)
  8430. return false;
  8431. if ($scrollable.is("body"))
  8432. return false;
  8433. if ($scrollable === window)
  8434. return false;
  8435. if ($scrollable.css("overflow") === "hidden")
  8436. return false;
  8437. return true
  8438. },
  8439. _handleStart: function(e) {
  8440. this._reset();
  8441. if (events.isMouseEvent(e) && e.which !== 1)
  8442. return;
  8443. this._saveClosestScrollableOffset($(e.target));
  8444. this._target = e.target;
  8445. this._startX = e.pageX;
  8446. this._startY = e.pageY
  8447. },
  8448. _handleEnd: function(e) {
  8449. var $target = $(e.target);
  8450. if (!$target.is(this._target) || this._touchWasMoved(e))
  8451. return;
  8452. if (this._nativeClickShouldBeUsed($target) || this._closestScrollableWasMoved($target))
  8453. return;
  8454. var targetIsInput = $target.is("input, textarea");
  8455. if (!targetIsInput && !e.dxPreventBlur)
  8456. utils.resetActiveElement();
  8457. this._fireClickEvent(e)
  8458. },
  8459. _handleCancel: function(e) {
  8460. this._reset()
  8461. },
  8462. _reset: function() {
  8463. this._target = null
  8464. },
  8465. _handleClick: function(e) {
  8466. var $target = $(e.target);
  8467. if ($target.is(this._target)) {
  8468. if (this._nativeClickShouldBeUsed($target))
  8469. this._fireClickEvent(e)
  8470. }
  8471. else if ($target.is("input, textarea"))
  8472. utils.resetActiveElement()
  8473. },
  8474. _nativeClickShouldBeUsed: function($target) {
  8475. return preferNativeClick && this._hasClosestScrollable($target)
  8476. },
  8477. _fireClickEvent: function(e) {
  8478. if (events.handleGestureEvent(e, CLICK_EVENT_NAME))
  8479. events.fireEvent({
  8480. type: CLICK_EVENT_NAME,
  8481. originalEvent: e
  8482. })
  8483. },
  8484. _makeElementClickable: function($element) {
  8485. if (!$element.attr("onclick"))
  8486. $element.attr("onclick", "void(0)")
  8487. },
  8488. setup: function(element) {
  8489. var $element = $(element);
  8490. this._makeElementClickable($element);
  8491. if (this._handlerCount > 0)
  8492. return;
  8493. var $doc = $(document).on(events.addNamespace("dxpointerdown", CLICK_NAME_SPACE), $.proxy(this._handleStart, this)).on(events.addNamespace("dxpointerup", CLICK_NAME_SPACE), $.proxy(this._handleEnd, this)).on(events.addNamespace("dxpointercancel", CLICK_NAME_SPACE), $.proxy(this._handleCancel, this)).on(events.addNamespace("click", CLICK_NAME_SPACE), $.proxy(this._handleClick, this))
  8494. },
  8495. add: function() {
  8496. this._handlerCount++
  8497. },
  8498. remove: function() {
  8499. this._handlerCount--
  8500. },
  8501. teardown: function(element) {
  8502. if (this._handlerCount)
  8503. return;
  8504. $(element).off("." + CLICK_NAME_SPACE);
  8505. this.dispose()
  8506. },
  8507. dispose: function() {
  8508. $(document).off("." + CLICK_NAME_SPACE)
  8509. }
  8510. });
  8511. var NativeStrategy = DX.Class.inherit({
  8512. bindType: "click",
  8513. delegateType: "click",
  8514. handle: function(element, event) {
  8515. event.type = "dxclick";
  8516. if (events.handleGestureEvent(event, CLICK_EVENT_NAME))
  8517. return event.handleObj.handler.call(element, event)
  8518. }
  8519. });
  8520. events.registerEvent(CLICK_EVENT_NAME, new(useNativeClick ? NativeStrategy : SimulatedStrategy));
  8521. DX.ui.events.__internals = DX.ui.events.__internals || {};
  8522. $.extend(DX.ui.events.__internals, {
  8523. NativeClickStrategy: NativeStrategy,
  8524. SimulatedClickStrategy: SimulatedStrategy,
  8525. preferNativeClickAccessor: function(value) {
  8526. if (!arguments.length)
  8527. return preferNativeClick;
  8528. preferNativeClick = value
  8529. }
  8530. })
  8531. })(jQuery, DevExpress, window);
  8532. /*! Module core, file ui.events.hold.js */
  8533. (function($, DX, undefined) {
  8534. var ui = DX.ui,
  8535. events = ui.events,
  8536. jqSpecialEvent = $.event.special,
  8537. EVENTS_NAME_SPACE = "dxSpecialEvents",
  8538. HOLD_NAME_SPACE = "dxHold",
  8539. HOLD_EVENT_NAME = "dxhold",
  8540. HOLD_TIMER_DATA_KEY = EVENTS_NAME_SPACE + "HoldTimer";
  8541. var Hold = DX.Class.inherit({
  8542. HOLD_TIMEOUT: 750,
  8543. TOUCH_BOUNDARY: 5,
  8544. _startX: 0,
  8545. _startY: 0,
  8546. _touchWasMoved: function(e) {
  8547. var boundary = this.TOUCH_BOUNDARY;
  8548. return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary
  8549. },
  8550. setup: function(element, data) {
  8551. var $target,
  8552. holdInited = false;
  8553. var handleStart = function(e) {
  8554. if (holdInited)
  8555. return;
  8556. $target = $(e.target);
  8557. holdInited = true;
  8558. if ($target.data(HOLD_TIMER_DATA_KEY))
  8559. return;
  8560. this._startX = e.pageX;
  8561. this._startY = e.pageY;
  8562. var holdTimeout = data && "timeout" in data ? data.timeout : this.HOLD_TIMEOUT;
  8563. var holdTimer = setTimeout(function() {
  8564. $target.removeData(HOLD_TIMER_DATA_KEY);
  8565. if (events.handleGestureEvent(e, HOLD_EVENT_NAME))
  8566. events.fireEvent({
  8567. type: HOLD_EVENT_NAME,
  8568. originalEvent: e
  8569. })
  8570. }, holdTimeout);
  8571. $target.data(HOLD_TIMER_DATA_KEY, holdTimer)
  8572. };
  8573. var handleMove = function(e) {
  8574. if (!this._touchWasMoved(e))
  8575. return;
  8576. handleEnd()
  8577. };
  8578. var handleEnd = function() {
  8579. if ($target) {
  8580. clearTimeout($target.data(HOLD_TIMER_DATA_KEY));
  8581. $target.removeData(HOLD_TIMER_DATA_KEY);
  8582. $target = null;
  8583. holdInited = false
  8584. }
  8585. };
  8586. $(element).on(events.addNamespace("dxpointerdown", HOLD_NAME_SPACE), $.proxy(handleStart, this)).on(events.addNamespace("dxpointermove", HOLD_NAME_SPACE), $.proxy(handleMove, this)).on(events.addNamespace("dxpointerup", HOLD_NAME_SPACE), $.proxy(handleEnd, this))
  8587. },
  8588. teardown: function(element) {
  8589. element = $(element);
  8590. clearTimeout(element.data(HOLD_TIMER_DATA_KEY));
  8591. element.removeData(HOLD_TIMER_DATA_KEY).off("." + HOLD_NAME_SPACE)
  8592. }
  8593. });
  8594. events.registerEvent(HOLD_EVENT_NAME, new Hold)
  8595. })(jQuery, DevExpress);
  8596. /*! Module core, file ui.events.hover.js */
  8597. (function($, DX, undefined) {
  8598. var ui = DX.ui,
  8599. events = ui.events;
  8600. var HOVER_EVENTS_NAMESPACE = "dxSpecialEvents",
  8601. HOVER_START = "dxhoverstart",
  8602. HOVER_END = "dxhoverend",
  8603. MOUSE_ENTER = "mouseenter",
  8604. MOUSE_LEAVE = "mouseleave",
  8605. TOUCH_START = "dxpointerdown";
  8606. var HoverStart = DX.Class.inherit({
  8607. ctor: function() {
  8608. this._wasTouch = false;
  8609. this._selector = undefined
  8610. },
  8611. setup: function(element, data) {
  8612. var $element = $(element);
  8613. this._selector = data ? data.selector : undefined;
  8614. if (!!$element.data("dxHoverStart"))
  8615. return;
  8616. $element.data("dxHoverStart", true).on(events.addNamespace(MOUSE_ENTER, HOVER_EVENTS_NAMESPACE), this._selector, $.proxy(this._handleEnter, this)).on(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE), $.proxy(this._handleTouchStart, this))
  8617. },
  8618. _handleEnter: function(e) {
  8619. if (!this._wasTouch)
  8620. events.fireEvent({
  8621. type: HOVER_START,
  8622. originalEvent: e
  8623. })
  8624. },
  8625. _handleTouchStart: function(e) {
  8626. this._wasTouch = events.isTouchEvent(e)
  8627. },
  8628. teardown: function(element) {
  8629. $(element).data("dxHoverStart", false).off(events.addNamespace(MOUSE_ENTER, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE))
  8630. }
  8631. });
  8632. var HoverEnd = DX.Class.inherit({
  8633. ctor: function() {
  8634. this._wasTouch = false;
  8635. this._selector = undefined
  8636. },
  8637. setup: function(element, data) {
  8638. var $element = $(element);
  8639. this._selector = data ? data.selector : undefined;
  8640. if (!!$element.data("dxHoverEnd"))
  8641. return;
  8642. $element.data("dxHoverEnd", true).on(events.addNamespace(MOUSE_LEAVE, HOVER_EVENTS_NAMESPACE), this._selector, $.proxy(this._handleLeave, this)).on(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE), $.proxy(this._handleTouchStart, this))
  8643. },
  8644. _handleLeave: function(e) {
  8645. if (!this._wasTouch)
  8646. events.fireEvent({
  8647. type: HOVER_END,
  8648. originalEvent: e
  8649. })
  8650. },
  8651. _handleTouchStart: function(e) {
  8652. this._wasTouch = events.isTouchEvent(e)
  8653. },
  8654. teardown: function(element) {
  8655. $(element).data("dxHoverEnd", false).off(events.addNamespace(MOUSE_LEAVE, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE))
  8656. }
  8657. });
  8658. events.registerEvent(HOVER_START, new HoverStart);
  8659. events.registerEvent(HOVER_END, new HoverEnd)
  8660. })(jQuery, DevExpress);
  8661. /*! Module core, file ui.events.wheel.js */
  8662. (function($, DX, undefined) {
  8663. var ui = DX.ui,
  8664. events = ui.events;
  8665. var EVENT_NAME = "dxmousewheel",
  8666. EVENT_NAMESPACE = "dxWheel";
  8667. var WHEEL_DISTANCE = 10;
  8668. $.event.fixHooks["wheel"] = $.event.mouseHooks;
  8669. var wheelEvent = document.onmousewheel !== undefined ? "mousewheel" : "wheel";
  8670. var wheel = {
  8671. setup: function(element, data) {
  8672. var $element = $(element);
  8673. $element.on(events.addNamespace(wheelEvent, EVENT_NAMESPACE), $.proxy(wheel._handleWheel, wheel))
  8674. },
  8675. teardown: function(element) {
  8676. var $element = $(element);
  8677. $element.off("." + EVENT_NAMESPACE)
  8678. },
  8679. _handleWheel: function(e) {
  8680. $(e.target).data("dxGestureEvent", null);
  8681. var delta = this._getWheelDelta(e.originalEvent);
  8682. events.fireEvent({
  8683. type: EVENT_NAME,
  8684. originalEvent: e,
  8685. delta: delta
  8686. });
  8687. e.stopPropagation()
  8688. },
  8689. _getWheelDelta: function(event) {
  8690. return event.wheelDelta / 60 || -event.deltaY
  8691. }
  8692. };
  8693. events.registerEvent(EVENT_NAME, wheel)
  8694. })(jQuery, DevExpress);
  8695. /*! Module core, file ui.gestureEmitter.js */
  8696. (function($, DX, undefined) {
  8697. var ui = DX.ui,
  8698. events = ui.events;
  8699. var GestureEmitter = DX.Class.inherit({
  8700. ctor: function(element) {
  8701. this._$element = $(element);
  8702. this._cancelCallback = $.Callbacks()
  8703. },
  8704. getElement: function() {
  8705. return this._$element
  8706. },
  8707. getDirection: function() {
  8708. return this.direction
  8709. },
  8710. validate: function(e) {
  8711. return e.type !== "dxmousewheel"
  8712. },
  8713. configurate: function(data) {
  8714. $.extend(this, data)
  8715. },
  8716. addCancelCallback: function(callback) {
  8717. this._cancelCallback.add(callback)
  8718. },
  8719. removeCancelCallback: function() {
  8720. this._cancelCallback.empty()
  8721. },
  8722. init: $.noop,
  8723. start: $.noop,
  8724. move: $.noop,
  8725. end: $.noop,
  8726. cancel: $.noop,
  8727. wheel: $.noop,
  8728. _fireEvent: function(eventName, event, params) {
  8729. var eventData = {
  8730. type: eventName,
  8731. originalEvent: event,
  8732. target: this.getElement().get(0)
  8733. };
  8734. event = events.fireEvent($.extend(eventData, params));
  8735. if (event.cancel)
  8736. this._cancel(event);
  8737. return event
  8738. },
  8739. _cancel: function(e) {
  8740. this._cancelCallback.fire()
  8741. }
  8742. });
  8743. var gestureEmitters = [];
  8744. $.extend(ui, {
  8745. GestureEmitter: GestureEmitter,
  8746. gestureEmitters: gestureEmitters
  8747. })
  8748. })(jQuery, DevExpress);
  8749. /*! Module core, file ui.scrollEmitter.js */
  8750. (function($, DX, undefined) {
  8751. var ui = DX.ui,
  8752. events = ui.events;
  8753. var SCROLL_INIT_EVENT = "dxscrollinit",
  8754. SCROLL_START_EVENT = "dxscrollstart",
  8755. SCROLL_MOVE_EVENT = "dxscroll",
  8756. SCROLL_END_EVENT = "dxscrollend",
  8757. SCROLL_STOP_EVENT = "dxscrollstop",
  8758. SCROLL_CANCEL_EVENT = "dxscrollcancel",
  8759. SCROLL_WHEEL_EVENT = "dxscrollwheel",
  8760. INERTIA_TIMEOUT = 100,
  8761. VELOCITY_CALC_TIMEOUT = 200,
  8762. FRAME_DURATION = Math.round(1000 / 60);
  8763. var ScrollEmitter = ui.GestureEmitter.inherit({
  8764. ctor: function(element) {
  8765. this.callBase(element);
  8766. this.direction = "vertical"
  8767. },
  8768. init: function(e) {
  8769. this._savedEventData = this._prevEventData = events.eventData(e);
  8770. this._fireEvent(SCROLL_INIT_EVENT, e)
  8771. },
  8772. start: function(e) {
  8773. this._fireEvent(SCROLL_START_EVENT, e, {delta: events.eventDelta(this._prevEventData, events.eventData(e))})
  8774. },
  8775. move: function(e) {
  8776. var currentEventData = events.eventData(e);
  8777. this._fireEvent(SCROLL_MOVE_EVENT, e, {delta: events.eventDelta(this._prevEventData, currentEventData)});
  8778. var eventDelta = events.eventDelta(this._savedEventData, currentEventData);
  8779. if (eventDelta.time > VELOCITY_CALC_TIMEOUT)
  8780. this._savedEventData = this._prevEventData;
  8781. this._prevEventData = currentEventData
  8782. },
  8783. end: function(e) {
  8784. var endEventDelta = events.eventDelta(this._prevEventData, events.eventData(e));
  8785. var velocity = {
  8786. x: 0,
  8787. y: 0
  8788. };
  8789. if (endEventDelta.time < INERTIA_TIMEOUT) {
  8790. var deltaEventData = events.eventDelta(this._savedEventData, this._prevEventData);
  8791. velocity = {
  8792. x: deltaEventData.x * FRAME_DURATION / deltaEventData.time,
  8793. y: deltaEventData.y * FRAME_DURATION / deltaEventData.time
  8794. }
  8795. }
  8796. this._fireEvent(SCROLL_END_EVENT, e, {velocity: velocity})
  8797. },
  8798. stop: function(e) {
  8799. this._fireEvent(SCROLL_STOP_EVENT, e)
  8800. },
  8801. cancel: function(e) {
  8802. this._fireEvent(SCROLL_CANCEL_EVENT, e)
  8803. },
  8804. wheel: function(e) {
  8805. this._fireEvent(SCROLL_WHEEL_EVENT, e, {delta: e.delta})
  8806. }
  8807. });
  8808. ui.gestureEmitters.push({
  8809. emitter: ScrollEmitter,
  8810. events: [SCROLL_INIT_EVENT, SCROLL_START_EVENT, SCROLL_MOVE_EVENT, SCROLL_END_EVENT, SCROLL_STOP_EVENT, SCROLL_CANCEL_EVENT, SCROLL_WHEEL_EVENT]
  8811. })
  8812. })(jQuery, DevExpress);
  8813. /*! Module core, file ui.swipeEmitter.js */
  8814. (function($, DX, undefined) {
  8815. var ui = DX.ui,
  8816. utils = DX.utils,
  8817. events = ui.events,
  8818. SWIPE_START_EVENT = "dxswipestart",
  8819. SWIPE_EVENT = "dxswipe",
  8820. SWIPE_END_EVENT = "dxswipeend";
  8821. var HorizontalStrategy = {
  8822. defaultItemSizeFunc: function() {
  8823. return this.getElement().width()
  8824. },
  8825. getBounds: function() {
  8826. return [this._maxLeftOffset, this._maxRightOffset]
  8827. },
  8828. calcOffsetRatio: function(e) {
  8829. var endEventData = events.eventData(e);
  8830. return (endEventData.x - (this._startEventData && this._startEventData.x || 0)) / this._itemSizeFunc().call(this, e)
  8831. },
  8832. isFastSwipe: function(e) {
  8833. var endEventData = events.eventData(e);
  8834. return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.x - this._tickData.x) >= endEventData.time - this._tickData.time
  8835. }
  8836. };
  8837. var VerticalStrategy = {
  8838. defaultItemSizeFunc: function() {
  8839. return this.getElement().height()
  8840. },
  8841. getBounds: function() {
  8842. return [this._maxTopOffset, this._maxBottomOffset]
  8843. },
  8844. calcOffsetRatio: function(e) {
  8845. var endEventData = events.eventData(e);
  8846. return (endEventData.y - (this._startEventData && this._startEventData.y || 0)) / this._itemSizeFunc().call(this, e)
  8847. },
  8848. isFastSwipe: function(e) {
  8849. var endEventData = events.eventData(e);
  8850. return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.y - this._tickData.y) >= endEventData.time - this._tickData.time
  8851. }
  8852. };
  8853. var STRATEGIES = {
  8854. horizontal: HorizontalStrategy,
  8855. vertical: VerticalStrategy
  8856. };
  8857. var SwipeEmitter = ui.GestureEmitter.inherit({
  8858. TICK_INTERVAL: 300,
  8859. FAST_SWIPE_SPEED_LIMIT: 5,
  8860. ctor: function(element) {
  8861. this.callBase(element);
  8862. this.direction = "horizontal";
  8863. this.elastic = true
  8864. },
  8865. _getStrategy: function() {
  8866. return STRATEGIES[this.direction]
  8867. },
  8868. _defaultItemSizeFunc: function() {
  8869. return this._getStrategy().defaultItemSizeFunc.call(this)
  8870. },
  8871. _itemSizeFunc: function() {
  8872. return this.itemSizeFunc || this._defaultItemSizeFunc
  8873. },
  8874. init: function(e) {
  8875. this._startEventData = events.eventData(e);
  8876. this._tickData = {time: 0}
  8877. },
  8878. start: function(e) {
  8879. e = this._fireEvent(SWIPE_START_EVENT, e);
  8880. if (!e.cancel) {
  8881. this._maxLeftOffset = e.maxLeftOffset;
  8882. this._maxRightOffset = e.maxRightOffset;
  8883. this._maxTopOffset = e.maxTopOffset;
  8884. this._maxBottomOffset = e.maxBottomOffset
  8885. }
  8886. },
  8887. move: function(e) {
  8888. var strategy = this._getStrategy(),
  8889. moveEventData = events.eventData(e),
  8890. offset = strategy.calcOffsetRatio.call(this, e);
  8891. offset = this._fitOffset(offset, this.elastic);
  8892. if (moveEventData.time - this._tickData.time > this.TICK_INTERVAL)
  8893. this._tickData = moveEventData;
  8894. this._fireEvent(SWIPE_EVENT, e, {offset: offset});
  8895. e.preventDefault()
  8896. },
  8897. end: function(e) {
  8898. var strategy = this._getStrategy(),
  8899. offsetRatio = strategy.calcOffsetRatio.call(this, e),
  8900. isFast = strategy.isFastSwipe.call(this, e),
  8901. startOffset = offsetRatio,
  8902. targetOffset = this._calcTargetOffset(offsetRatio, isFast);
  8903. startOffset = this._fitOffset(startOffset, this.elastic);
  8904. targetOffset = this._fitOffset(targetOffset, false);
  8905. this._fireEvent(SWIPE_END_EVENT, e, {
  8906. offset: startOffset,
  8907. targetOffset: targetOffset
  8908. })
  8909. },
  8910. _fitOffset: function(offset, elastic) {
  8911. var strategy = this._getStrategy(),
  8912. bounds = strategy.getBounds.call(this);
  8913. if (offset < -bounds[0])
  8914. return elastic ? (-2 * bounds[0] + offset) / 3 : -bounds[0];
  8915. if (offset > bounds[1])
  8916. return elastic ? (2 * bounds[1] + offset) / 3 : bounds[1];
  8917. return offset
  8918. },
  8919. _calcTargetOffset: function(offsetRatio, isFast) {
  8920. var result;
  8921. if (isFast) {
  8922. result = Math.ceil(Math.abs(offsetRatio));
  8923. if (offsetRatio < 0)
  8924. result = -result
  8925. }
  8926. else
  8927. result = Math.round(offsetRatio);
  8928. return result
  8929. }
  8930. });
  8931. ui.gestureEmitters.push({
  8932. emitter: SwipeEmitter,
  8933. events: [SWIPE_START_EVENT, SWIPE_EVENT, SWIPE_END_EVENT]
  8934. })
  8935. })(jQuery, DevExpress);
  8936. /*! Module core, file ui.dragEmitter.js */
  8937. (function($, DX, undefined) {
  8938. var ui = DX.ui,
  8939. utils = DX.utils,
  8940. events = ui.events,
  8941. wrapToArray = utils.wrapToArray;
  8942. var DRAG_START_EVENT = "dxdragstart",
  8943. DRAG_EVENT = "dxdrag",
  8944. DRAG_END_EVENT = "dxdragend",
  8945. DRAG_ENTER_EVENT = "dxdragenter",
  8946. DRAG_LEAVE_EVENT = "dxdragleave",
  8947. DROP_EVENT = "dxdrop";
  8948. var knownDropTargets = [],
  8949. knownDropTargetConfigs = [];
  8950. var dropTargetRegistration = {
  8951. setup: function(element, data) {
  8952. var knownDropTarget = $.inArray(element, knownDropTargets) !== -1;
  8953. if (!knownDropTarget) {
  8954. knownDropTargets.push(element);
  8955. knownDropTargetConfigs.push(data || {})
  8956. }
  8957. },
  8958. teardown: function(element, data) {
  8959. var elementEvents = $._data(element, "events"),
  8960. handlersCount = 0;
  8961. $.each([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT], function(_, eventName) {
  8962. var eventHandlers = elementEvents[eventName];
  8963. if (eventHandlers)
  8964. handlersCount += eventHandlers.length
  8965. });
  8966. if (!handlersCount) {
  8967. var index = $.inArray(element, knownDropTargets);
  8968. knownDropTargets.splice(index, 1);
  8969. knownDropTargetConfigs.splice(index, 1)
  8970. }
  8971. }
  8972. };
  8973. events.registerEvent(DRAG_ENTER_EVENT, dropTargetRegistration);
  8974. events.registerEvent(DRAG_LEAVE_EVENT, dropTargetRegistration);
  8975. events.registerEvent(DROP_EVENT, dropTargetRegistration);
  8976. var getItemConfig = function($element) {
  8977. var dropTargetIndex = $.inArray($element.get(0), knownDropTargets);
  8978. return knownDropTargetConfigs[dropTargetIndex]
  8979. };
  8980. var getItemPosition = function($element) {
  8981. var dropTargetConfig = getItemConfig($element);
  8982. if (dropTargetConfig.itemPositionFunc)
  8983. return dropTargetConfig.itemPositionFunc();
  8984. else
  8985. return $element.offset()
  8986. };
  8987. var getItemSize = function($element) {
  8988. var dropTargetConfig = getItemConfig($element);
  8989. if (dropTargetConfig.itemSizeFunc)
  8990. return dropTargetConfig.itemSizeFunc();
  8991. else
  8992. return {
  8993. width: $element.width(),
  8994. height: $element.height()
  8995. }
  8996. };
  8997. var DragEmitter = ui.GestureEmitter.inherit({
  8998. ctor: function(element) {
  8999. this.callBase(element);
  9000. this.direction = "both"
  9001. },
  9002. init: function(e) {
  9003. var eventData = events.eventData(e);
  9004. this._startEventData = eventData
  9005. },
  9006. start: function(e) {
  9007. e = this._fireEvent(DRAG_START_EVENT, e);
  9008. this._maxLeftOffset = e.maxLeftOffset;
  9009. this._maxRightOffset = e.maxRightOffset;
  9010. this._maxTopOffset = e.maxTopOffset;
  9011. this._maxBottomOffset = e.maxBottomOffset;
  9012. var dropTargets = wrapToArray(e.targetElements || knownDropTargets);
  9013. this._$dropTargetElements = $.map(dropTargets, function(element) {
  9014. return $(element)
  9015. })
  9016. },
  9017. move: function(e) {
  9018. var eventData = events.eventData(e),
  9019. dragOffset = this._calculateOffset(eventData);
  9020. this._fireEvent(DRAG_EVENT, e, {offset: dragOffset});
  9021. this._processDropTargets(e, dragOffset);
  9022. e.preventDefault()
  9023. },
  9024. _calculateOffset: function(eventData) {
  9025. return {
  9026. x: this._calculateXOffset(eventData),
  9027. y: this._calculateYOffset(eventData)
  9028. }
  9029. },
  9030. _calculateXOffset: function(eventData) {
  9031. if (this.direction !== "vertical") {
  9032. var offset = eventData.x - this._startEventData.x;
  9033. return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset)
  9034. }
  9035. return 0
  9036. },
  9037. _calculateYOffset: function(eventData) {
  9038. if (this.direction !== "horizontal") {
  9039. var offset = eventData.y - this._startEventData.y;
  9040. return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset)
  9041. }
  9042. return 0
  9043. },
  9044. _fitOffset: function(offset, minOffset, maxOffset) {
  9045. if (minOffset != null)
  9046. offset = Math.max(offset, -minOffset);
  9047. if (maxOffset != null)
  9048. offset = Math.min(offset, maxOffset);
  9049. return offset
  9050. },
  9051. _processDropTargets: function(e, dragOffset) {
  9052. var target = this._findDropTarget(e),
  9053. sameTarget = target === this._$currentDropTarget;
  9054. if (!sameTarget) {
  9055. this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT);
  9056. this._$currentDropTarget = target;
  9057. this._fireDropTargetEvent(e, DRAG_ENTER_EVENT)
  9058. }
  9059. },
  9060. _fireDropTargetEvent: function(event, eventName) {
  9061. if (!this._$currentDropTarget)
  9062. return;
  9063. var eventData = {
  9064. type: eventName,
  9065. originalEvent: event,
  9066. draggingElement: this._$element.get(0),
  9067. target: this._$currentDropTarget.get(0)
  9068. };
  9069. events.fireEvent(eventData)
  9070. },
  9071. _findDropTarget: function(e) {
  9072. var that = this,
  9073. $result;
  9074. $.each(this._$dropTargetElements, function(_, $target) {
  9075. if (that._checkDropTarget($target, e)) {
  9076. $result = $target;
  9077. return false
  9078. }
  9079. });
  9080. return $result
  9081. },
  9082. _checkDropTarget: function($target, e) {
  9083. var isDraggingElement = $target.get(0) === this._$element.get(0);
  9084. if (isDraggingElement)
  9085. return false;
  9086. var targetPosition = getItemPosition($target);
  9087. if (e.pageX < targetPosition.left)
  9088. return false;
  9089. if (e.pageY < targetPosition.top)
  9090. return false;
  9091. var targetSize = getItemSize($target);
  9092. if (e.pageX > targetPosition.left + targetSize.width)
  9093. return false;
  9094. if (e.pageY > targetPosition.top + targetSize.height)
  9095. return false;
  9096. return $target
  9097. },
  9098. end: function(e) {
  9099. var eventData = events.eventData(e);
  9100. this._fireEvent(DRAG_END_EVENT, e, {offset: this._calculateOffset(eventData)});
  9101. this._fireDropTargetEvent(e, DROP_EVENT);
  9102. delete this._$currentDropTarget
  9103. }
  9104. });
  9105. ui.gestureEmitters.push({
  9106. emitter: DragEmitter,
  9107. events: [DRAG_START_EVENT, DRAG_EVENT, DRAG_END_EVENT]
  9108. });
  9109. DX.ui.events.__internals = DX.ui.events.__internals || {};
  9110. $.extend(DX.ui.events.__internals, {dropTargets: knownDropTargets})
  9111. })(jQuery, DevExpress);
  9112. /*! Module core, file ui.events.gesture.js */
  9113. (function($, DX, undefined) {
  9114. var ui = DX.ui,
  9115. events = ui.events,
  9116. utils = DX.utils;
  9117. var abs = Math.abs;
  9118. var GESTURE_EVENT = "dxGesture",
  9119. GESTURE_EVENT_DATA = "dxGestureEmitter",
  9120. GESTURE_LOCK_KEY = "dxGestureLock",
  9121. GESTURE_UNLOCK_TIMEOUT = 400,
  9122. TOUCH_BOUNDARY = 10,
  9123. HORIZONTAL = "horizontal",
  9124. VERTICAL = "vertical",
  9125. BOTH = "both";
  9126. var GestureEventManager = DX.Class.inherit({
  9127. SLEEP: 0,
  9128. INITED: 1,
  9129. STARTED: 2,
  9130. ctor: function() {
  9131. this._attachHandlers();
  9132. this.reset()
  9133. },
  9134. _attachHandlers: function() {
  9135. $(document).on(events.addNamespace("dxpointerdown", GESTURE_EVENT), $.proxy(this._handlePointerDown, this)).on(events.addNamespace("dxpointermove", GESTURE_EVENT), $.proxy(this._handlePointerMove, this)).on(events.addNamespace("dxpointerup dxpointercancel", GESTURE_EVENT), $.proxy(this._handlePointerUp, this)).on(events.addNamespace("dxmousewheel", GESTURE_EVENT), $.proxy(this._handleMouseWheel, this))
  9136. },
  9137. _eachEmitter: function(callback) {
  9138. $.each(this._activeEmitters || {}, function(direction, emitter) {
  9139. return callback(emitter, direction)
  9140. })
  9141. },
  9142. _noEmitters: function() {
  9143. return $.isEmptyObject(this._activeEmitters)
  9144. },
  9145. reset: function() {
  9146. this._eachEmitter(function(emitter) {
  9147. emitter.removeCancelCallback()
  9148. });
  9149. this._forgetGesture();
  9150. this._stage = this.SLEEP;
  9151. this._activeEmitters = {}
  9152. },
  9153. _handlePointerDown: function(e) {
  9154. if (events.needSkipEvent(e) || events.hasTouches(e) > 1)
  9155. return;
  9156. this.reset();
  9157. this._activeEmitters = this._closestEmitter(e);
  9158. if (this._noEmitters())
  9159. return;
  9160. this._startEvent = e;
  9161. this._startEventData = events.eventData(e);
  9162. this._stage = this.INITED;
  9163. this._applyToActive("init", e)
  9164. },
  9165. _applyToActive: function(method) {
  9166. var args = $.makeArray(arguments).slice(1);
  9167. this._eachEmitter(function(emitter) {
  9168. if (method in emitter)
  9169. emitter[method].apply(emitter, args)
  9170. })
  9171. },
  9172. _closestEmitter: function(e) {
  9173. var result = {},
  9174. foundForAllDirections = false,
  9175. $element = $(e.target);
  9176. while ($element.length && !foundForAllDirections) {
  9177. var emitter = $element.data(GESTURE_EVENT_DATA);
  9178. if (emitter && emitter.validate(e)) {
  9179. var direction = emitter.getDirection(e);
  9180. if (direction) {
  9181. emitter.addCancelCallback($.proxy(this._handleCancel, this, emitter, e));
  9182. result[direction] = result[direction] || emitter
  9183. }
  9184. }
  9185. foundForAllDirections = result[HORIZONTAL] && result[VERTICAL] || result[BOTH];
  9186. $element = $element.parent()
  9187. }
  9188. return result
  9189. },
  9190. _handleCancel: function(canceledEmitter, e) {
  9191. var canceledDirection;
  9192. this._eachEmitter(function(emitter, direction) {
  9193. if (emitter === canceledEmitter) {
  9194. canceledDirection = direction;
  9195. emitter.removeCancelCallback()
  9196. }
  9197. });
  9198. this._forgetGesture([canceledEmitter]);
  9199. this._cancelEmitter(canceledEmitter, e);
  9200. if (this._noEmitters())
  9201. this.reset()
  9202. },
  9203. _handlePointerMove: function(e) {
  9204. if (this._stage === this.INITED && this._directionDetected(e))
  9205. this._handleStart(e);
  9206. if (this._stage === this.STARTED)
  9207. this._handleMove(e)
  9208. },
  9209. _directionDetected: function(e) {
  9210. var delta = events.eventDelta(this._startEventData, events.eventData(e));
  9211. return delta.x || delta.y
  9212. },
  9213. _handleStart: function(e) {
  9214. this._filterEmitters(e);
  9215. if (this._noEmitters())
  9216. return;
  9217. this._resetActiveElement();
  9218. this._applyToActive("start", this._startEvent);
  9219. this._stage = this.STARTED
  9220. },
  9221. _resetActiveElement: function() {
  9222. if (DX.devices.real().platform !== "ios")
  9223. return;
  9224. this._eachEmitter(function(emitter) {
  9225. if ($(":focus", emitter.getElement()).length)
  9226. utils.resetActiveElement()
  9227. })
  9228. },
  9229. _filterEmitters: function(e) {
  9230. this._filterByDirection(e);
  9231. if (this._emitersAmount() > 1)
  9232. this._takeFirstEmitter()
  9233. },
  9234. _emitersAmount: function() {
  9235. var result = 0;
  9236. this._eachEmitter(function() {
  9237. result++
  9238. });
  9239. return result
  9240. },
  9241. _filterByDirection: function(e) {
  9242. var delta = events.eventDelta(this._startEventData, events.eventData(e)),
  9243. horizontalMove = abs(delta.y) < abs(delta.x),
  9244. verticalMove = abs(delta.y) > abs(delta.x),
  9245. horizontalEmmiter = this._activeEmitters[HORIZONTAL],
  9246. verticalEmmiter = this._activeEmitters[VERTICAL],
  9247. bothEmitter = this._activeEmitters[BOTH],
  9248. existsHorizontalEmitter = horizontalEmmiter || bothEmitter,
  9249. existsVerticalEmitter = verticalEmmiter || bothEmitter;
  9250. if (horizontalMove && existsHorizontalEmitter)
  9251. this._cancelEmitter(verticalEmmiter, e);
  9252. else if (verticalMove && existsVerticalEmitter)
  9253. this._cancelEmitter(horizontalEmmiter, e)
  9254. },
  9255. _cancelEmitter: function(canceledEmmiter, e) {
  9256. if (!canceledEmmiter)
  9257. return;
  9258. canceledEmmiter.cancel(e);
  9259. delete this._activeEmitters[canceledEmmiter.getDirection(e)]
  9260. },
  9261. _takeFirstEmitter: function() {
  9262. var activeEmitters = {};
  9263. this._eachEmitter(function(emitter, direction) {
  9264. activeEmitters[direction] = emitter;
  9265. return false
  9266. });
  9267. this._activeEmitters = activeEmitters
  9268. },
  9269. _prepareGesture: function() {
  9270. this._gestureLocked = true;
  9271. clearTimeout(this._gestureEndTimer);
  9272. this._eachEmitter(function(emitter) {
  9273. emitter.getElement().data(GESTURE_LOCK_KEY, true)
  9274. });
  9275. ui.feedback.reset()
  9276. },
  9277. _handleMove: function(e) {
  9278. if (!this._gestureLocked) {
  9279. var delta = events.eventDelta(this._startEventData, events.eventData(e));
  9280. if (abs(delta.x) > TOUCH_BOUNDARY || abs(delta.y) > TOUCH_BOUNDARY) {
  9281. events.handleGestureEvent(e, GESTURE_EVENT);
  9282. this._prepareGesture()
  9283. }
  9284. }
  9285. this._applyToActive("move", e)
  9286. },
  9287. _forgetGesture: function(activeEmitters) {
  9288. activeEmitters = activeEmitters || this._activeEmitters;
  9289. if (this._noEmitters())
  9290. return;
  9291. this._gestureLocked = false;
  9292. this._gestureEndTimer = setTimeout(function() {
  9293. $.each(activeEmitters, function(_, emitter) {
  9294. emitter.getElement().data(GESTURE_LOCK_KEY, false)
  9295. })
  9296. }, GESTURE_UNLOCK_TIMEOUT)
  9297. },
  9298. _handlePointerUp: function(e) {
  9299. if (!DX.devices.isRippleEmulator() && events.hasTouches(e))
  9300. return;
  9301. if (this._stage === this.STARTED)
  9302. this._applyToActive("end", e);
  9303. else if (this._stage === this.INITED)
  9304. this._applyToActive("stop", e);
  9305. this.reset()
  9306. },
  9307. _handleMouseWheel: function(e) {
  9308. this._handlePointerDown(e);
  9309. if (this._stage !== this.INITED)
  9310. return;
  9311. this._takeFirstEmitter();
  9312. this._eachEmitter(function(emitter, direction) {
  9313. var prop = direction !== "horizontal" ? "pageY" : "pageX";
  9314. e[prop] += e.delta
  9315. });
  9316. this._handlePointerMove(e);
  9317. this._handlePointerUp(e)
  9318. },
  9319. isActive: function(element) {
  9320. var result = false;
  9321. this._eachEmitter(function(emitter) {
  9322. result = result || emitter.getElement().is(element)
  9323. });
  9324. return result
  9325. }
  9326. });
  9327. var gestureEventManager = new GestureEventManager;
  9328. var registerEmitter = function(emitterConfig) {
  9329. var emitterClass = emitterConfig.emitter;
  9330. $.each(emitterConfig.events, function(_, eventName) {
  9331. events.registerEvent(eventName, {
  9332. noBubble: true,
  9333. setup: function(element, data) {
  9334. var emitter = $(element).data(GESTURE_EVENT_DATA) || new emitterClass(element);
  9335. emitter.configurate(data);
  9336. $(element).data(GESTURE_EVENT_DATA, emitter)
  9337. },
  9338. teardown: function(element) {
  9339. if (gestureEventManager.isActive(element))
  9340. gestureEventManager.reset();
  9341. $(element).removeData(GESTURE_EVENT_DATA)
  9342. }
  9343. })
  9344. })
  9345. };
  9346. $.each(ui.gestureEmitters, function(_, emitterConfig) {
  9347. registerEmitter(emitterConfig)
  9348. });
  9349. events.__internals = events.__internals || {};
  9350. $.extend(events.__internals, {registerEmitter: registerEmitter})
  9351. })(jQuery, DevExpress);
  9352. /*! Module core, file ui.widget.js */
  9353. (function($, DX, undefined) {
  9354. var ui = DX.ui,
  9355. UI_FEEDBACK = "UIFeedback",
  9356. UI_FEEDBACK_CLASS = "dx-feedback",
  9357. ACTIVE_STATE_CLASS = "dx-state-active",
  9358. DISABLED_STATE_CLASS = "dx-state-disabled",
  9359. INVISIBLE_STATE_CLASS = "dx-state-invisible",
  9360. HOVER_STATE_CLASS = "dx-state-hover",
  9361. FEEDBACK_SHOW_TIMEOUT = 30,
  9362. FEEDBACK_HIDE_TIMEOUT = 400,
  9363. HOVER_START = "dxhoverstart",
  9364. HOVER_END = "dxhoverend",
  9365. ANONYMOUS_TEMPLATE_NAME = "template",
  9366. TEMPLATE_SELECTOR = "[data-options*='dxTemplate']",
  9367. TEMPLATES_DATA_KEY = "dxTemplates";
  9368. var getTemplateOptions = function(element) {
  9369. var options = $(element).data("options");
  9370. if ($.trim(options).charAt(0) !== "{")
  9371. options = "{" + options + "}";
  9372. return new Function("return " + options)().dxTemplate
  9373. };
  9374. var activeElement,
  9375. events = ui.events;
  9376. ui.feedback = {reset: function() {
  9377. handleEnd(true)
  9378. }};
  9379. ui.Widget = DX.DOMComponent.inherit({
  9380. NAME: "Widget",
  9381. NAMESPACE: ui,
  9382. _setDefaultOptions: function() {
  9383. this.callBase();
  9384. this.option({
  9385. disabled: false,
  9386. visible: true,
  9387. activeStateEnabled: true,
  9388. width: undefined,
  9389. height: undefined,
  9390. contentReadyAction: null,
  9391. hoverStateEnabled: false
  9392. })
  9393. },
  9394. _init: function() {
  9395. this.callBase();
  9396. this._feedbackShowTimeout = FEEDBACK_SHOW_TIMEOUT;
  9397. this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT;
  9398. if (this._templatesSupported()) {
  9399. this._initTemplates();
  9400. this._initContentReadyAction()
  9401. }
  9402. },
  9403. _templatesSupported: function() {
  9404. return this._renderContentImpl !== DX.abstract
  9405. },
  9406. _initTemplates: function() {
  9407. var that = this,
  9408. templates = {},
  9409. dataTemplateElements = this._element().data(TEMPLATES_DATA_KEY),
  9410. templateElements = dataTemplateElements ? dataTemplateElements : this._element().contents().filter(TEMPLATE_SELECTOR);
  9411. this._templateProvider = new ui.TemplateProvider;
  9412. this._templateClass = this._templateProvider.getTemplateClass(this);
  9413. if (templateElements.length) {
  9414. var templatesMap = {};
  9415. templateElements.each(function() {
  9416. var templateOptions = getTemplateOptions(this);
  9417. if (!templateOptions)
  9418. return;
  9419. if (!templateOptions.name)
  9420. throw Error("Template name was not specified");
  9421. templatesMap[templateOptions.name] = templatesMap[templateOptions.name] || [];
  9422. templatesMap[templateOptions.name].push(this)
  9423. });
  9424. $.each(templatesMap, function(templateName, value) {
  9425. var deviceTemplate = that._findTemplateByDevice(value);
  9426. if (deviceTemplate)
  9427. templates[templateName] = that._createTemplate(deviceTemplate)
  9428. })
  9429. }
  9430. else
  9431. templates[ANONYMOUS_TEMPLATE_NAME] = that._createTemplate(that._element().contents());
  9432. this.option("_templates", templates)
  9433. },
  9434. _getTemplateByOption: function(optionName) {
  9435. return this._getTemplate(this.option(optionName))
  9436. },
  9437. _getTemplate: function(templateName) {
  9438. var result = this._acquireTemplate.apply(this, arguments);
  9439. if (!result && this._templateProvider.supportDefaultTemplate(this)) {
  9440. result = this._templateProvider.getDefaultTemplate(this);
  9441. if (!result)
  9442. throw Error(DX.utils.stringFormat("Template \"{0}\" was not found and no default template specified!", templateName));
  9443. }
  9444. return result
  9445. },
  9446. _acquireTemplate: function(templateSource) {
  9447. if (templateSource == null)
  9448. return templateSource;
  9449. if (templateSource instanceof this._templateClass)
  9450. return templateSource;
  9451. if (templateSource.nodeType || templateSource.jquery) {
  9452. templateSource = $(templateSource);
  9453. if (templateSource.is("script"))
  9454. templateSource = templateSource.html();
  9455. return this._createTemplate(templateSource)
  9456. }
  9457. if (typeof templateSource === "string")
  9458. return this.option("_templates")[templateSource];
  9459. if ($.isFunction(templateSource)) {
  9460. var args = $.makeArray(arguments).slice(1);
  9461. return this._acquireTemplate(templateSource.apply(this, args))
  9462. }
  9463. return this._acquireTemplate(templateSource.toString())
  9464. },
  9465. _createTemplate: function(element) {
  9466. return new this._templateClass(element, this)
  9467. },
  9468. _findTemplateByDevice: function(templates) {
  9469. var suitableTemplate = DX.utils.findBestMatches(DX.devices.current(), templates, function(template) {
  9470. return getTemplateOptions(template)
  9471. })[0];
  9472. $.each(templates, function(index, template) {
  9473. if (template !== suitableTemplate)
  9474. $(template).remove()
  9475. });
  9476. return suitableTemplate
  9477. },
  9478. _cleanTemplates: function() {
  9479. var that = this;
  9480. $.each(this.option("_templates"), function(templateName, template) {
  9481. if (that === template.owner())
  9482. template.dispose()
  9483. })
  9484. },
  9485. _initContentReadyAction: function() {
  9486. this._contentReadyAction = this._createActionByOption("contentReadyAction", {excludeValidators: ["gesture", "designMode", "disabled"]})
  9487. },
  9488. _render: function() {
  9489. this.callBase();
  9490. this._element().addClass("dx-widget");
  9491. this._toggleDisabledState(this.option("disabled"));
  9492. this._toggleVisibility(this.option("visible"));
  9493. this._refreshFeedback();
  9494. this._renderDimensions();
  9495. if (this._templatesSupported())
  9496. this._renderContent();
  9497. this._attachHoverEvents()
  9498. },
  9499. _renderContent: function() {
  9500. this._renderContentImpl();
  9501. this._fireContentReadyAction()
  9502. },
  9503. _renderContentImpl: DX.abstract,
  9504. _fireContentReadyAction: function() {
  9505. this._contentReadyAction({excludeValidators: ["disabled", "gesture"]})
  9506. },
  9507. _dispose: function() {
  9508. if (this._templatesSupported())
  9509. this._cleanTemplates();
  9510. this._contentReadyAction = null;
  9511. this._clearTimers();
  9512. if (activeElement && activeElement.closest(this._element()).length)
  9513. activeElement = null;
  9514. this.callBase()
  9515. },
  9516. _clean: function() {
  9517. this.callBase();
  9518. this._element().empty()
  9519. },
  9520. _clearTimers: function() {
  9521. clearTimeout(this._feedbackHideTimer);
  9522. clearTimeout(this._feedbackShowTimer)
  9523. },
  9524. _toggleVisibility: function(visible) {
  9525. this._element().toggleClass(INVISIBLE_STATE_CLASS, !visible)
  9526. },
  9527. _attachHoverEvents: function() {
  9528. var that = this,
  9529. hoverableSelector = that._activeStateUnit,
  9530. nameStart = events.addNamespace(HOVER_START, UI_FEEDBACK),
  9531. nameEnd = events.addNamespace(HOVER_END, UI_FEEDBACK);
  9532. that._element().off(nameStart, hoverableSelector).off(nameEnd, hoverableSelector);
  9533. if (this.option("hoverStateEnabled")) {
  9534. var startAction = new DX.Action(function(args) {
  9535. var $target = args.element;
  9536. that._refreshHoveredElement($target)
  9537. });
  9538. that._element().on(nameStart, hoverableSelector, {selector: hoverableSelector}, function(e) {
  9539. startAction.execute({element: $(e.target)})
  9540. }).on(nameEnd, hoverableSelector, {selector: hoverableSelector}, function(e) {
  9541. e.stopImmediatePropagation();
  9542. that._forgetHoveredElement()
  9543. })
  9544. }
  9545. else
  9546. this._toggleHoverClass(false)
  9547. },
  9548. _refreshHoveredElement: function(hoveredElement) {
  9549. var selector = this._activeStateUnit || this._element();
  9550. this._forgetHoveredElement();
  9551. this._hoveredElement = hoveredElement.closest(selector);
  9552. this._toggleHoverClass(true)
  9553. },
  9554. _forgetHoveredElement: function() {
  9555. this._toggleHoverClass(false);
  9556. delete this._hoveredElement
  9557. },
  9558. _toggleHoverClass: function(value) {
  9559. if (this._hoveredElement)
  9560. this._hoveredElement.toggleClass(HOVER_STATE_CLASS, value && this.option("hoverStateEnabled"))
  9561. },
  9562. _renderDimensions: function() {
  9563. var width = this.option("width"),
  9564. height = this.option("height");
  9565. this._setDimension(width, "width");
  9566. this._setDimension(height, "height")
  9567. },
  9568. _setDimension: function(dimensionSize, dimension) {
  9569. var $element = this._element();
  9570. dimensionSize = $.isFunction(dimensionSize) ? dimensionSize() : dimensionSize;
  9571. if ($.isNumeric(dimensionSize))
  9572. dimensionSize = dimensionSize + "px";
  9573. if (!dimensionSize && dimension === "width")
  9574. dimensionSize = this._calculateWidth();
  9575. $element.css(dimension, dimensionSize)
  9576. },
  9577. _calculateWidth: function() {
  9578. var $element = this._element(),
  9579. explicitWidth = $element[0].style.width,
  9580. calculatedWidth;
  9581. if (explicitWidth[explicitWidth.length - 1] === "%" && !this.option("width"))
  9582. return explicitWidth;
  9583. else
  9584. calculatedWidth = explicitWidth && explicitWidth !== "auto" && explicitWidth !== "inherit" ? $element.outerWidth() : this.option("width");
  9585. return calculatedWidth
  9586. },
  9587. _refreshFeedback: function() {
  9588. if (this._feedbackDisabled()) {
  9589. this._feedbackOff(true);
  9590. this._element().removeClass(UI_FEEDBACK_CLASS)
  9591. }
  9592. else
  9593. this._element().addClass(UI_FEEDBACK_CLASS)
  9594. },
  9595. _feedbackDisabled: function() {
  9596. return !this.option("activeStateEnabled") || this.option("disabled")
  9597. },
  9598. _feedbackOn: function(element, immediate) {
  9599. if (this._feedbackDisabled())
  9600. return;
  9601. this._clearTimers();
  9602. if (immediate)
  9603. this._feedbackShow(element);
  9604. else
  9605. this._feedbackShowTimer = window.setTimeout($.proxy(this._feedbackShow, this, element), this._feedbackShowTimeout);
  9606. this._saveActiveElement()
  9607. },
  9608. _feedbackShow: function(element) {
  9609. var activeStateElement = this._element();
  9610. if (this._activeStateUnit)
  9611. activeStateElement = $(element).closest(this._activeStateUnit);
  9612. if (!activeStateElement.hasClass(DISABLED_STATE_CLASS)) {
  9613. activeStateElement.addClass(ACTIVE_STATE_CLASS);
  9614. this._toggleHoverClass(false)
  9615. }
  9616. },
  9617. _saveActiveElement: function() {
  9618. activeElement = this._element()
  9619. },
  9620. _feedbackOff: function(immediate) {
  9621. this._clearTimers();
  9622. if (immediate)
  9623. this._feedbackHide();
  9624. else
  9625. this._feedbackHideTimer = window.setTimeout($.proxy(this._feedbackHide, this), this._feedbackHideTimeout)
  9626. },
  9627. _feedbackHide: function() {
  9628. var activeStateElement = this._element();
  9629. if (this._activeStateUnit)
  9630. activeStateElement = activeStateElement.find(this._activeStateUnit);
  9631. activeStateElement.removeClass(ACTIVE_STATE_CLASS);
  9632. this._toggleHoverClass(!this.option("disabled"));
  9633. this._clearActiveElement()
  9634. },
  9635. _clearActiveElement: function() {
  9636. var rootDomElement = this._element().get(0),
  9637. activeDomElement = activeElement && activeElement.get(0);
  9638. if (activeDomElement && (activeDomElement === rootDomElement || $.contains(rootDomElement, activeDomElement)))
  9639. activeElement = null
  9640. },
  9641. _toggleDisabledState: function(value) {
  9642. this._element().toggleClass(DISABLED_STATE_CLASS, Boolean(value));
  9643. this._toggleHoverClass(!value)
  9644. },
  9645. _optionChanged: function(name, value) {
  9646. switch (name) {
  9647. case"disabled":
  9648. this._toggleDisabledState(value);
  9649. this._refreshFeedback();
  9650. break;
  9651. case"activeStateEnabled":
  9652. this._refreshFeedback();
  9653. break;
  9654. case"hoverStateEnabled":
  9655. this._attachHoverEvents();
  9656. break;
  9657. case"visible":
  9658. this._toggleVisibility(value);
  9659. break;
  9660. case"width":
  9661. case"height":
  9662. this._renderDimensions();
  9663. break;
  9664. case"contentReadyAction":
  9665. this._initContentReadyAction();
  9666. break;
  9667. case"_templates":
  9668. this._refresh();
  9669. break;
  9670. default:
  9671. this.callBase.apply(this, arguments)
  9672. }
  9673. },
  9674. repaint: function() {
  9675. this._refresh()
  9676. }
  9677. });
  9678. var handleStart = function(args, immediate) {
  9679. var e = args.jQueryEvent,
  9680. $target = args.element,
  9681. widget;
  9682. if (events.needSkipEvent(e))
  9683. return;
  9684. if (activeElement) {
  9685. widget = getWidget(activeElement);
  9686. if (widget)
  9687. widget._feedbackOff(true)
  9688. }
  9689. var closestFeedbackElement = $target.closest("." + UI_FEEDBACK_CLASS);
  9690. if (closestFeedbackElement.length) {
  9691. widget = getWidget(closestFeedbackElement);
  9692. if (!widget)
  9693. return;
  9694. widget._feedbackOn($target, immediate);
  9695. if (immediate)
  9696. widget._feedbackOff()
  9697. }
  9698. };
  9699. var handleEnd = function(immediate) {
  9700. if (!activeElement)
  9701. return;
  9702. var widget = getWidget(activeElement);
  9703. if (widget)
  9704. widget._feedbackOff(immediate)
  9705. };
  9706. var getWidget = function(widgetElement) {
  9707. var result;
  9708. $.each(widgetElement.data("dxComponents") || [], function(index, componentName) {
  9709. if (ui[componentName] && ui[componentName].subclassOf(ui.Widget)) {
  9710. result = widgetElement.data(componentName);
  9711. return false
  9712. }
  9713. });
  9714. return result
  9715. };
  9716. $(function() {
  9717. var startAction = new DX.Action(handleStart);
  9718. $(document).on(events.addNamespace("dxpointerdown", UI_FEEDBACK), function(e) {
  9719. startAction.execute({
  9720. jQueryEvent: e,
  9721. element: $(e.target)
  9722. })
  9723. }).on(events.addNamespace("dxpointerup dxpointercancel", UI_FEEDBACK), function(e) {
  9724. var activeElementClicked = activeElement && $(e.target).closest("." + UI_FEEDBACK_CLASS).get(0) === activeElement.get(0);
  9725. if (activeElementClicked)
  9726. startAction.execute({
  9727. jQueryEvent: e,
  9728. element: $(e.target)
  9729. }, true);
  9730. handleEnd()
  9731. })
  9732. })
  9733. })(jQuery, DevExpress);
  9734. /*! Module core, file ui.editor.js */
  9735. (function($, DX, undefined) {
  9736. var ui = DX.ui;
  9737. DX.registerComponent("dxEditor", ui.Widget.inherit({
  9738. _setDefaultOptions: function() {
  9739. this.callBase();
  9740. this.option({
  9741. value: undefined,
  9742. valueChangeAction: undefined
  9743. })
  9744. },
  9745. _recreateValueChangeAction: function() {
  9746. this._valueChangeAction = this._createActionByOption("valueChangeAction")
  9747. },
  9748. _suppressValueChangeAction: function() {
  9749. this._valueChangeActionSuppressed = true
  9750. },
  9751. _resumeValueChangeAction: function() {
  9752. this._valueChangeActionSuppressed = false
  9753. },
  9754. _render: function() {
  9755. this._recreateValueChangeAction();
  9756. this.callBase()
  9757. },
  9758. _raiseValueChangeAction: function(value, previousValue, extraArguments) {
  9759. var args = {
  9760. value: value,
  9761. previousValue: previousValue,
  9762. jQueryEvent: this._valueChangeEventInstance
  9763. };
  9764. if (extraArguments)
  9765. args = $.extend(args, extraArguments);
  9766. this._valueChangeAction(args)
  9767. },
  9768. _optionChanged: function(name, value, previousValue) {
  9769. switch (name) {
  9770. case"valueChangeAction":
  9771. this._recreateValueChangeAction();
  9772. break;
  9773. case"value":
  9774. if (!this._valueChangeActionSuppressed)
  9775. this._raiseValueChangeAction(value, previousValue);
  9776. this._valueChangeEventInstance = undefined;
  9777. break;
  9778. default:
  9779. this.callBase.apply(this, arguments)
  9780. }
  9781. }
  9782. }))
  9783. })(jQuery, DevExpress);
  9784. /*! Module core, file ui.template.js */
  9785. (function($, DX, undefined) {
  9786. var isString = DX.utils.isString;
  9787. var currentTemplateEngine;
  9788. var templateEngines = [];
  9789. var BaseTemplate = DevExpress.Class.inherit({
  9790. _compile: function(html, element) {
  9791. return element
  9792. },
  9793. _render: function(template, data) {
  9794. return template
  9795. },
  9796. ctor: function(element) {
  9797. this._element = $(element);
  9798. if (this._element.length === 1) {
  9799. if (this._element[0].nodeName.toLowerCase() !== "script")
  9800. this._element = $("<div />").append(this._element);
  9801. this._template = this._compile(this._element.html() || "", this._element)
  9802. }
  9803. },
  9804. render: function(container, data) {
  9805. var result;
  9806. if (this._template) {
  9807. result = this._render(this._template, data);
  9808. if (isString(result))
  9809. result = $.parseHTML(result);
  9810. result = $(result);
  9811. if (container)
  9812. container.append(result);
  9813. return result
  9814. }
  9815. },
  9816. owner: $.noop,
  9817. dispose: $.noop
  9818. });
  9819. var createTemplateEngine = function(options) {
  9820. if (options && options.compile && options.render)
  9821. return BaseTemplate.inherit({
  9822. allowRenderToDetachedContainer: options.allowRenderToDetachedContainer !== false,
  9823. _compile: options.compile,
  9824. _render: options.render
  9825. });
  9826. else
  9827. throw Error("Template Engine must contains compile and render methods");
  9828. };
  9829. if (window.ko) {
  9830. var koCustomTemplateEngine = function(){};
  9831. koCustomTemplateEngine.prototype = ko.utils.extend(new ko.templateEngine, {
  9832. renderTemplateSource: function(templateSource, bindingContext, options) {
  9833. var precompiledTemplate = templateSource["data"]("precompiledTemplate");
  9834. if (!precompiledTemplate) {
  9835. precompiledTemplate = new currentTemplateEngine(templateSource.domElement);
  9836. templateSource["data"]("precompiledTemplate", precompiledTemplate)
  9837. }
  9838. return precompiledTemplate.render(null, bindingContext.$data)
  9839. },
  9840. allowTemplateRewriting: false
  9841. })
  9842. }
  9843. DevExpress.ui.setTemplateEngine = function(templateEngine) {
  9844. if (isString(templateEngine)) {
  9845. currentTemplateEngine = templateEngines && templateEngines[templateEngine];
  9846. if (!currentTemplateEngine && templateEngine !== "default")
  9847. throw Error(DX.utils.stringFormat("Template Engine \"{0}\" is not supported", templateEngine));
  9848. }
  9849. else
  9850. currentTemplateEngine = createTemplateEngine(templateEngine) || currentTemplateEngine;
  9851. if (window.ko)
  9852. ko.setTemplateEngine(currentTemplateEngine ? new koCustomTemplateEngine : new ko.nativeTemplateEngine)
  9853. };
  9854. DevExpress.ui.TemplateProvider = DevExpress.ui.TemplateProvider.inherit({getTemplateClass: function() {
  9855. if (currentTemplateEngine)
  9856. return currentTemplateEngine;
  9857. return this.callBase.apply(this, arguments)
  9858. }});
  9859. var registerTemplateEngine = function(name, templateOptions) {
  9860. templateEngines[name] = createTemplateEngine(templateOptions)
  9861. };
  9862. registerTemplateEngine("jquery-tmpl", {
  9863. compile: function(html, element) {
  9864. return element
  9865. },
  9866. render: function(template, data) {
  9867. return template.tmpl(data)
  9868. }
  9869. });
  9870. registerTemplateEngine("jsrender", {
  9871. compile: function(html) {
  9872. return $.templates(html)
  9873. },
  9874. render: function(template, data) {
  9875. return template.render(data)
  9876. }
  9877. });
  9878. registerTemplateEngine("mustache", {
  9879. compile: function(html) {
  9880. return Mustache.compile(html)
  9881. },
  9882. render: function(template, data) {
  9883. return template(data)
  9884. }
  9885. });
  9886. registerTemplateEngine("hogan", {
  9887. compile: function(html) {
  9888. return Hogan.compile(html)
  9889. },
  9890. render: function(template, data) {
  9891. return template.render(data)
  9892. }
  9893. });
  9894. registerTemplateEngine("underscore", {
  9895. compile: function(html) {
  9896. return _.template(html)
  9897. },
  9898. render: function(template, data) {
  9899. return template(data)
  9900. }
  9901. });
  9902. registerTemplateEngine("handlebars", {
  9903. compile: function(html) {
  9904. return Handlebars.compile(html)
  9905. },
  9906. render: function(template, data) {
  9907. return template(data)
  9908. }
  9909. });
  9910. registerTemplateEngine("doT", {
  9911. compile: function(html) {
  9912. return doT.template(html)
  9913. },
  9914. render: function(template, data) {
  9915. return template(data)
  9916. }
  9917. })
  9918. })(jQuery, DevExpress);
  9919. /*! Module core, file ui.collectionContainerWidget.js */
  9920. (function($, DX, undefined) {
  9921. var ui = DX.ui,
  9922. events = ui.events;
  9923. var CollectionContainerWidget = ui.Widget.inherit({
  9924. _setDefaultOptions: function() {
  9925. this.callBase();
  9926. this.option({
  9927. items: [],
  9928. itemTemplate: "item",
  9929. itemRender: null,
  9930. itemRenderedAction: null,
  9931. itemClickAction: null,
  9932. itemHoldAction: null,
  9933. itemHoldTimeout: 750,
  9934. noDataText: Globalize.localize("dxCollectionContainerWidget-noDataText"),
  9935. dataSource: null,
  9936. selectedIndex: -1,
  9937. itemSelectAction: null,
  9938. itemTemplateProperty: "template"
  9939. })
  9940. },
  9941. _init: function() {
  9942. this.callBase();
  9943. this._cleanRenderedItems();
  9944. this._refreshDataSource()
  9945. },
  9946. _dataSourceOptions: function() {
  9947. var options = {
  9948. paginate: false,
  9949. _preferSync: false
  9950. };
  9951. if ($.isArray(this.option("dataSource")))
  9952. options._preferSync = true;
  9953. return options
  9954. },
  9955. _cleanRenderedItems: function() {
  9956. this._renderedItemsCount = 0
  9957. },
  9958. _fireSelectItemEvent: function(index, prevIndex) {
  9959. if (this._selectionEnabled()) {
  9960. this._updateSelectedIndex(index, prevIndex);
  9961. this._handleItemEvent(this._selectedItemElement(index), "itemSelectAction", {
  9962. selectedIndex: index,
  9963. previousIndex: prevIndex
  9964. }, {excludeValidators: ["gesture", "disabled"]})
  9965. }
  9966. },
  9967. _optionChanged: function(name, value, prevValue) {
  9968. switch (name) {
  9969. case"items":
  9970. case"itemTemplateProperty":
  9971. if (this._selectionEnabled()) {
  9972. var itemsCount = value && value.length || 0,
  9973. maxIndex = Math.max(itemsCount - 1, 0);
  9974. if (maxIndex < this.option("selectedIndex"))
  9975. this.option("selectedIndex", 0)
  9976. }
  9977. this._cleanRenderedItems();
  9978. this._invalidate();
  9979. break;
  9980. case"dataSource":
  9981. this._refreshDataSource();
  9982. if (!this._dataSource)
  9983. this.option("items", []);
  9984. this._renderEmptyMessage();
  9985. break;
  9986. case"noDataText":
  9987. this._renderEmptyMessage();
  9988. break;
  9989. case"itemTemplate":
  9990. this._invalidate();
  9991. break;
  9992. case"itemRender":
  9993. this._itemRender = null;
  9994. this._invalidate();
  9995. break;
  9996. case"itemRenderedAction":
  9997. this._createItemRenderAction();
  9998. break;
  9999. case"itemClickAction":
  10000. break;
  10001. case"itemHoldAction":
  10002. case"itemHoldTimeout":
  10003. this._attachHoldEvent();
  10004. break;
  10005. case"selectedIndex":
  10006. this._fireSelectItemEvent(value, prevValue);
  10007. break;
  10008. case"itemSelectAction":
  10009. break;
  10010. default:
  10011. this.callBase(name, value, prevValue)
  10012. }
  10013. },
  10014. _expectNextPageLoading: function() {
  10015. this._startIndexForAppendedItems = 0
  10016. },
  10017. _expectLastItemLoading: function() {
  10018. this._startIndexForAppendedItems = -1
  10019. },
  10020. _forgetNextPageLoading: function() {
  10021. this._startIndexForAppendedItems = null
  10022. },
  10023. _handleDataSourceChanged: function(newItems) {
  10024. var items = this.option("items");
  10025. if (this._initialized && items && this._shouldAppendItems()) {
  10026. this._renderedItemsCount = items.length;
  10027. if (!this._dataSource.isLastPage() || this._startIndexForAppendedItems !== -1)
  10028. this.option().items = items.concat(newItems.slice(this._startIndexForAppendedItems));
  10029. this._renderContent();
  10030. this._forgetNextPageLoading()
  10031. }
  10032. else
  10033. this.option("items", newItems)
  10034. },
  10035. _handleDataSourceLoadError: function() {
  10036. this._forgetNextPageLoading()
  10037. },
  10038. _shouldAppendItems: function() {
  10039. return this._startIndexForAppendedItems != null && this._allowDinamicItemsAppend()
  10040. },
  10041. _allowDinamicItemsAppend: function() {
  10042. return false
  10043. },
  10044. _clean: function() {
  10045. this._itemContainer().empty()
  10046. },
  10047. _refresh: function() {
  10048. this._cleanRenderedItems();
  10049. this.callBase.apply(this, arguments)
  10050. },
  10051. _itemContainer: function() {
  10052. return this._element()
  10053. },
  10054. _itemClass: DX.abstract,
  10055. _itemSelector: function() {
  10056. return "." + this._itemClass()
  10057. },
  10058. _itemDataKey: DX.abstract,
  10059. _itemElements: function() {
  10060. return this._itemContainer().find(this._itemSelector())
  10061. },
  10062. _render: function() {
  10063. this.callBase();
  10064. this._attachClickEvent();
  10065. this._attachHoldEvent();
  10066. if (this._selectionEnabled()) {
  10067. this._renderSelectedIndex(this.option("selectedIndex"));
  10068. this._attachSelectedEvent()
  10069. }
  10070. },
  10071. _selectionEnabled: function() {
  10072. return this._renderSelectedIndex !== DX.abstract
  10073. },
  10074. _selectionByClickEnabled: function() {
  10075. return true
  10076. },
  10077. _renderSelectedIndex: DX.abstract,
  10078. _attachSelectedEvent: function() {
  10079. if (!this._selectionByClickEnabled())
  10080. return;
  10081. var itemSelector = this._itemSelector(),
  10082. itemSelectHandler = this._createAction($.proxy(function(e) {
  10083. this._handleItemSelect(e.jQueryEvent)
  10084. }, this), {validatingTargetName: "itemElement"}),
  10085. eventName = events.addNamespace("dxclick", this.NAME);
  10086. this._element().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(function(e) {
  10087. var $itemElement = $(e.target).closest(itemSelector);
  10088. itemSelectHandler({
  10089. itemElement: $itemElement,
  10090. jQueryEvent: e
  10091. });
  10092. this._handleItemClick(e)
  10093. }, this))
  10094. },
  10095. _handleItemSelect: function(e) {
  10096. if (events.needSkipEvent(e))
  10097. return;
  10098. var items = this.option("items"),
  10099. selectedItem = $(e.currentTarget).data(this._itemDataKey()),
  10100. selectedItemIndex = $.inArray(selectedItem, items);
  10101. this.option("selectedIndex", selectedItemIndex)
  10102. },
  10103. _updateSelectedIndex: function() {
  10104. this._renderSelectedIndex.apply(this, arguments)
  10105. },
  10106. _selectedItemElement: function(index) {
  10107. return this._itemElements().eq(index)
  10108. },
  10109. _attachClickEvent: function() {
  10110. if (this._selectionEnabled() && this._selectionByClickEnabled())
  10111. return;
  10112. var itemSelector = this._itemSelector(),
  10113. eventName = events.addNamespace("dxclick", this.NAME);
  10114. this._itemContainer().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(this._handleItemClick, this))
  10115. },
  10116. _handleItemClick: function(e) {
  10117. this._handleItemJQueryEvent(e, "itemClickAction")
  10118. },
  10119. _attachHoldEvent: function() {
  10120. var $itemContainer = this._itemContainer(),
  10121. itemSelector = this._itemSelector(),
  10122. eventName = events.addNamespace("dxhold", this.NAME);
  10123. $itemContainer.off(eventName, itemSelector);
  10124. if (this._shouldAttachHoldEvent())
  10125. $itemContainer.on(eventName, itemSelector, {timeout: this.option("itemHoldTimeout")}, $.proxy(this._handleItemHold, this))
  10126. },
  10127. _shouldAttachHoldEvent: function() {
  10128. return this.option("itemHoldAction")
  10129. },
  10130. _handleItemHold: function(e) {
  10131. this._handleItemJQueryEvent(e, "itemHoldAction")
  10132. },
  10133. _renderContentImpl: function() {
  10134. var items = this.option("items") || [];
  10135. if (this._renderedItemsCount)
  10136. this._renderItems(items.slice(this._renderedItemsCount));
  10137. else
  10138. this._renderItems(items)
  10139. },
  10140. _renderItems: function(items) {
  10141. if (items.length)
  10142. $.each(items, $.proxy(this._renderItem, this));
  10143. this._renderEmptyMessage()
  10144. },
  10145. _renderItem: function(index, itemData, container) {
  10146. container = container || this._itemContainer();
  10147. var itemRenderer = this._getItemRenderer(),
  10148. itemTemplateName = this._getItemTemplateName(itemData),
  10149. itemTemplate = this._getTemplate(itemTemplateName, index, itemData),
  10150. itemElement,
  10151. renderArgs = {
  10152. index: index,
  10153. item: itemData,
  10154. container: container
  10155. };
  10156. if (itemRenderer)
  10157. itemElement = this._createItemByRenderer(itemRenderer, renderArgs);
  10158. else if (itemTemplate)
  10159. itemElement = this._createItemByTemplate(itemTemplate, renderArgs);
  10160. else
  10161. itemElement = this._createItemByRenderer(this._itemRenderDefault, renderArgs);
  10162. itemElement.addClass(this._itemClass()).data(this._itemDataKey(), itemData);
  10163. var postprocessRenderArgs = {
  10164. itemElement: itemElement,
  10165. itemData: itemData,
  10166. itemIndex: index
  10167. };
  10168. this._postprocessRenderItem(postprocessRenderArgs);
  10169. this._getItemRenderAction()({
  10170. itemElement: itemElement,
  10171. itemData: itemData
  10172. });
  10173. return itemElement
  10174. },
  10175. _createItemRenderAction: function() {
  10176. return this._itemRenderAction = this._createActionByOption("itemRenderedAction", {
  10177. element: this._element(),
  10178. excludeValidators: ["gesture", "designMode", "disabled"]
  10179. })
  10180. },
  10181. _getItemRenderAction: function() {
  10182. return this._itemRenderAction || this._createItemRenderAction()
  10183. },
  10184. _getItemRenderer: function() {
  10185. this._itemRender = this._itemRender || this.option("itemRender");
  10186. return this._itemRender
  10187. },
  10188. _createItemByRenderer: function(itemRenderer, renderArgs) {
  10189. var itemElement = $("<div />").appendTo(renderArgs.container);
  10190. var rendererResult = itemRenderer.call(this, renderArgs.item, renderArgs.index, itemElement);
  10191. if (rendererResult != null && itemElement[0] !== rendererResult[0])
  10192. itemElement.append(rendererResult);
  10193. return itemElement
  10194. },
  10195. _getItemTemplateName: function(itemData) {
  10196. var templateProperty = this.option("itemTemplateProperty");
  10197. return itemData && itemData[templateProperty] || this.option("itemTemplate")
  10198. },
  10199. _createItemByTemplate: function(itemTemplate, renderArgs) {
  10200. return itemTemplate.render(renderArgs.container, renderArgs.item, renderArgs.index, "ignoreTarget")
  10201. },
  10202. _itemRenderDefault: function(item, index, itemElement) {
  10203. if ($.isPlainObject(item)) {
  10204. if (item.visible !== undefined && !item.visible)
  10205. itemElement.hide();
  10206. if (item.disabled)
  10207. itemElement.addClass("dx-state-disabled");
  10208. if (item.text)
  10209. itemElement.text(item.text);
  10210. if (item.html)
  10211. itemElement.html(item.html)
  10212. }
  10213. else
  10214. itemElement.html(String(item))
  10215. },
  10216. _postprocessRenderItem: $.noop,
  10217. _renderEmptyMessage: function() {
  10218. if (!this._selectionEnabled()) {
  10219. var noDataText = this.option("noDataText"),
  10220. items = this.option("items"),
  10221. dataSourceLoading = this._dataSource && this._dataSource.isLoading(),
  10222. hideNoData = !noDataText || items && items.length || dataSourceLoading;
  10223. if (hideNoData && this._$nodata) {
  10224. this._$nodata.remove();
  10225. this._$nodata = null
  10226. }
  10227. if (!hideNoData) {
  10228. this._$nodata = this._$nodata || $("<div />").addClass("dx-empty-message");
  10229. this._$nodata.appendTo(this._itemContainer()).text(noDataText)
  10230. }
  10231. }
  10232. },
  10233. _handleItemJQueryEvent: function(jQueryEvent, handlerOptionName, actionArgs, actionConfig) {
  10234. this._handleItemEvent(jQueryEvent.target, handlerOptionName, $.extend(actionArgs, {jQueryEvent: jQueryEvent}), actionConfig)
  10235. },
  10236. _handleItemEvent: function(initiator, handlerOptionName, actionArgs, actionConfig) {
  10237. var action = this._createActionByOption(handlerOptionName, $.extend({validatingTargetName: "itemElement"}, actionConfig));
  10238. return this._handleItemEventImpl(initiator, action, actionArgs)
  10239. },
  10240. _handleItemEventByHandler: function(initiator, handler, actionArgs, actionConfig) {
  10241. var action = this._createAction(handler, $.extend({validatingTargetName: "itemElement"}, actionConfig));
  10242. return this._handleItemEventImpl(initiator, action, actionArgs)
  10243. },
  10244. _handleItemEventImpl: function(initiator, action, actionArgs) {
  10245. var $itemElement = this._closestItemElement($(initiator));
  10246. actionArgs = $.extend({
  10247. itemElement: $itemElement,
  10248. itemData: this._getItemData($itemElement)
  10249. }, actionArgs);
  10250. return action(actionArgs)
  10251. },
  10252. _closestItemElement: function($element) {
  10253. return $($element).closest(this._itemSelector())
  10254. },
  10255. _getItemData: function($itemElement) {
  10256. return $itemElement.data(this._itemDataKey())
  10257. },
  10258. itemElements: function() {
  10259. return this._itemElements()
  10260. },
  10261. itemsContainer: function() {
  10262. return this._itemContainer()
  10263. }
  10264. }).include(ui.DataHelperMixin);
  10265. ui.CollectionContainerWidget = CollectionContainerWidget
  10266. })(jQuery, DevExpress);
  10267. /*! Module core, file ui.tooltip.js */
  10268. (function($, DX, undefined) {
  10269. var $tooltip = null;
  10270. var createTooltip = function(options) {
  10271. options = $.extend({position: "top"}, options);
  10272. var content = options.content;
  10273. delete options.content;
  10274. return $("<div />").html(content).appendTo(DX.overlayTargetContainer()).dxTooltip(options)
  10275. };
  10276. var removeTooltip = function() {
  10277. if (!$tooltip)
  10278. return;
  10279. $tooltip.remove();
  10280. $tooltip = null
  10281. };
  10282. var tooltip = {
  10283. show: function(options) {
  10284. removeTooltip();
  10285. $tooltip = createTooltip(options);
  10286. return $tooltip.dxTooltip("show")
  10287. },
  10288. hide: function() {
  10289. if (!$tooltip)
  10290. return $.when();
  10291. return $tooltip.dxTooltip("hide").done(removeTooltip).promise()
  10292. }
  10293. };
  10294. DX.ui.tooltip = tooltip
  10295. })(jQuery, DevExpress)
  10296. }
  10297. if (!DevExpress.MOD_WIDGETS_BASE) {
  10298. if (!window.DevExpress)
  10299. throw Error('Required module is not referenced: core');
  10300. /*! Module widgets-base, file ui.scrollable.js */
  10301. (function($, DX, undefined) {
  10302. var ui = DX.ui,
  10303. events = ui.events;
  10304. var SCROLLABLE = "dxScrollable",
  10305. SCROLLABLE_STRATEGY = "dxScrollableStrategy",
  10306. SCROLLABLE_CLASS = "dx-scrollable",
  10307. SCROLLABLE_DISABLED_CLASS = "dx-scrollable-disabled",
  10308. SCROLLABLE_CONTAINER_CLASS = "dx-scrollable-container",
  10309. SCROLLABLE_CONTENT_CLASS = "dx-scrollable-content",
  10310. VERTICAL = "vertical",
  10311. HORIZONTAL = "horizontal",
  10312. BOTH = "both";
  10313. DX.registerComponent(SCROLLABLE, DX.DOMComponent.inherit({
  10314. NAMESPACE: ui,
  10315. _setDefaultOptions: function() {
  10316. this.callBase();
  10317. this.option({
  10318. disabled: false,
  10319. scrollAction: null,
  10320. direction: VERTICAL,
  10321. showScrollbar: true,
  10322. useNative: true,
  10323. updateAction: null,
  10324. useSimulatedScrollbar: false,
  10325. useKeyboard: true,
  10326. inertiaEnabled: true,
  10327. bounceEnabled: true,
  10328. scrollByContent: true,
  10329. scrollByThumb: false,
  10330. startAction: null,
  10331. endAction: null,
  10332. bounceAction: null,
  10333. stopAction: null
  10334. })
  10335. },
  10336. _defaultOptionsRules: function() {
  10337. return this.callBase().slice(0).concat([{
  10338. device: function(device) {
  10339. return !DX.support.nativeScrolling
  10340. },
  10341. options: {
  10342. useNative: false,
  10343. useSimulatedScrollbar: true
  10344. }
  10345. }, {
  10346. device: function(device) {
  10347. return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic"
  10348. },
  10349. options: {
  10350. scrollByThumb: true,
  10351. scrollByContent: DX.support.touch,
  10352. showScrollbar: "onHover",
  10353. bounceEnabled: false
  10354. }
  10355. }, {
  10356. device: function(device) {
  10357. return DX.support.nativeScrolling && DX.devices.real().platform === "android"
  10358. },
  10359. options: {useSimulatedScrollbar: true}
  10360. }])
  10361. },
  10362. _init: function() {
  10363. this.callBase();
  10364. this._initMarkup();
  10365. this._attachNativeScrollbarsCustomizationCss();
  10366. this._locked = false
  10367. },
  10368. _visibilityChanged: function(visible) {
  10369. if (visible) {
  10370. this.update();
  10371. this._savedScrollOffset && this.scrollTo(this._savedScrollOffset)
  10372. }
  10373. else
  10374. this._savedScrollOffset = this.scrollOffset()
  10375. },
  10376. _initMarkup: function() {
  10377. var $element = this._element().addClass(SCROLLABLE_CLASS),
  10378. $container = this._$container = $("<div>").addClass(SCROLLABLE_CONTAINER_CLASS),
  10379. $content = this._$content = $("<div>").addClass(SCROLLABLE_CONTENT_CLASS);
  10380. $content.append($element.contents()).appendTo($container);
  10381. $container.appendTo($element)
  10382. },
  10383. _dimensionChanged: function() {
  10384. this.update()
  10385. },
  10386. _attachNativeScrollbarsCustomizationCss: function() {
  10387. if (!(navigator.platform.indexOf('Mac') > -1 && DevExpress.browser['webkit']))
  10388. this._element().addClass("dx-scrollable-customizable-scrollbars")
  10389. },
  10390. _render: function() {
  10391. this._renderDirection();
  10392. this._renderStrategy();
  10393. this._attachEventHandlers();
  10394. this._renderDisabledState();
  10395. this._createActions();
  10396. this.update();
  10397. this.callBase()
  10398. },
  10399. _toggleRTLDirection: function(rtl) {
  10400. this.callBase(rtl);
  10401. if (rtl)
  10402. this.scrollTo({left: this.scrollWidth() - this.clientWidth()})
  10403. },
  10404. _attachEventHandlers: function() {
  10405. var strategy = this._strategy;
  10406. var initEventData = {
  10407. getDirection: $.proxy(strategy.getDirection, strategy),
  10408. validate: $.proxy(this._validate, this)
  10409. };
  10410. this._$container.off("." + SCROLLABLE).on(events.addNamespace("scroll", SCROLLABLE), $.proxy(strategy.handleScroll, strategy)).on(events.addNamespace("dxscrollinit", SCROLLABLE), initEventData, $.proxy(strategy.handleInit, strategy)).on(events.addNamespace("dxscrollstart", SCROLLABLE), $.proxy(strategy.handleStart, strategy)).on(events.addNamespace("dxscroll", SCROLLABLE), $.proxy(strategy.handleMove, strategy)).on(events.addNamespace("dxscrollend", SCROLLABLE), $.proxy(strategy.handleEnd, strategy)).on(events.addNamespace("dxscrollcancel", SCROLLABLE), $.proxy(strategy.handleCancel, strategy)).on(events.addNamespace("dxscrollstop", SCROLLABLE), $.proxy(strategy.handleStop, strategy))
  10411. },
  10412. _validate: function(e) {
  10413. this.update();
  10414. return this._strategy.validate(e)
  10415. },
  10416. _renderDisabledState: function() {
  10417. this._element().toggleClass(SCROLLABLE_DISABLED_CLASS, this.option("disabled"));
  10418. if (this.option("disabled"))
  10419. this._lock();
  10420. else
  10421. this._unlock()
  10422. },
  10423. _renderDirection: function() {
  10424. this._element().removeClass("dx-scrollable-" + HORIZONTAL).removeClass("dx-scrollable-" + VERTICAL).removeClass("dx-scrollable-" + BOTH).addClass("dx-scrollable-" + this.option("direction"))
  10425. },
  10426. _renderStrategy: function() {
  10427. this._createStrategy();
  10428. this._strategy.render();
  10429. this._element().data(SCROLLABLE_STRATEGY, this._strategy)
  10430. },
  10431. _createStrategy: function() {
  10432. this._strategy = this.option("useNative") ? new ui.NativeScrollableStrategy(this) : new ui.SimulatedScrollableStrategy(this)
  10433. },
  10434. _createActions: function() {
  10435. this._strategy.createActions()
  10436. },
  10437. _clean: function() {
  10438. this._strategy.dispose()
  10439. },
  10440. _optionChanged: function(optionName, optionValue) {
  10441. switch (optionName) {
  10442. case"startAction":
  10443. case"endAction":
  10444. case"stopAction":
  10445. case"updateAction":
  10446. case"scrollAction":
  10447. case"bounceAction":
  10448. this._createActions();
  10449. break;
  10450. case"direction":
  10451. this._resetInactiveDirection();
  10452. this._invalidate();
  10453. break;
  10454. case"inertiaEnabled":
  10455. case"bounceEnabled":
  10456. case"scrollByContent":
  10457. case"scrollByThumb":
  10458. case"bounceEnabled":
  10459. case"useNative":
  10460. case"useKeyboard":
  10461. case"showScrollbar":
  10462. case"useSimulatedScrollbar":
  10463. this._invalidate();
  10464. break;
  10465. case"disabled":
  10466. this._renderDisabledState();
  10467. break;
  10468. default:
  10469. this.callBase.apply(this, arguments)
  10470. }
  10471. },
  10472. _resetInactiveDirection: function() {
  10473. var inactiveProp = this._getInactiveProp();
  10474. if (!inactiveProp)
  10475. return;
  10476. var scrollOffset = this.scrollOffset();
  10477. scrollOffset[inactiveProp] = 0;
  10478. this.scrollTo(scrollOffset)
  10479. },
  10480. _getInactiveProp: function() {
  10481. var direction = this.option("direction");
  10482. if (direction === VERTICAL)
  10483. return "left";
  10484. if (direction === HORIZONTAL)
  10485. return "top"
  10486. },
  10487. _location: function() {
  10488. return this._strategy.location()
  10489. },
  10490. _normalizeLocation: function(location) {
  10491. var direction = this.option("direction");
  10492. return {
  10493. left: $.isPlainObject(location) ? -(location.left || location.x || 0) : direction !== VERTICAL ? -location : 0,
  10494. top: $.isPlainObject(location) ? -(location.top || location.y || 0) : direction !== HORIZONTAL ? -location : 0
  10495. }
  10496. },
  10497. _isLocked: function() {
  10498. return this._locked
  10499. },
  10500. _lock: function() {
  10501. this._locked = true
  10502. },
  10503. _unlock: function() {
  10504. this._locked = false
  10505. },
  10506. _isDirection: function(direction) {
  10507. var current = this.option("direction");
  10508. if (direction === VERTICAL)
  10509. return current !== HORIZONTAL;
  10510. if (direction === HORIZONTAL)
  10511. return current !== VERTICAL;
  10512. return current === direction
  10513. },
  10514. _updateAllowedDirection: function() {
  10515. var allowedDirections = this._strategy._allowedDirections();
  10516. if (this._isDirection(BOTH) && allowedDirections.vertical && allowedDirections.horizontal)
  10517. this._allowedDirectionValue = BOTH;
  10518. else if (this._isDirection(HORIZONTAL) && allowedDirections.horizontal)
  10519. this._allowedDirectionValue = HORIZONTAL;
  10520. else if (this._isDirection(VERTICAL) && allowedDirections.vertical)
  10521. this._allowedDirectionValue = VERTICAL;
  10522. else
  10523. this._allowedDirectionValue = null
  10524. },
  10525. _allowedDirection: function() {
  10526. return this._allowedDirectionValue
  10527. },
  10528. content: function() {
  10529. return this._$content
  10530. },
  10531. scrollOffset: function() {
  10532. var location = this._location();
  10533. return {
  10534. top: -location.top,
  10535. left: -location.left
  10536. }
  10537. },
  10538. scrollTop: function() {
  10539. return this.scrollOffset().top
  10540. },
  10541. scrollLeft: function() {
  10542. return this.scrollOffset().left
  10543. },
  10544. clientHeight: function() {
  10545. return this._$container.height()
  10546. },
  10547. scrollHeight: function() {
  10548. return this.content().height()
  10549. },
  10550. clientWidth: function() {
  10551. return this._$container.width()
  10552. },
  10553. scrollWidth: function() {
  10554. return this.content().width()
  10555. },
  10556. update: function() {
  10557. this._strategy.update();
  10558. this._updateAllowedDirection();
  10559. return $.Deferred().resolve().promise()
  10560. },
  10561. scrollBy: function(distance) {
  10562. distance = this._normalizeLocation(distance);
  10563. if (!distance.top && !distance.left)
  10564. return;
  10565. this._strategy.scrollBy(distance)
  10566. },
  10567. scrollTo: function(targetLocation) {
  10568. targetLocation = this._normalizeLocation(targetLocation);
  10569. var location = this._location();
  10570. this.scrollBy({
  10571. left: location.left - targetLocation.left,
  10572. top: location.top - targetLocation.top
  10573. })
  10574. },
  10575. scrollToElement: function(element) {
  10576. var $element = $(element);
  10577. if (!$element.length || !this._element().find($element).length)
  10578. return;
  10579. var position = {
  10580. top: 0,
  10581. left: 0
  10582. };
  10583. var direction = this.option("direction");
  10584. if (direction !== VERTICAL)
  10585. position.left = this._elementPosition($element, HORIZONTAL);
  10586. if (direction !== HORIZONTAL)
  10587. position.top = this._elementPosition($element, VERTICAL);
  10588. this.scrollTo(position)
  10589. },
  10590. _elementPosition: function($element, direction) {
  10591. var elementPosition = $element.position()[direction === VERTICAL ? 'top' : 'left'];
  10592. var elementSize = $element[direction === VERTICAL ? 'outerHeight' : 'outerWidth']();
  10593. var elementBottom = elementPosition + elementSize;
  10594. var scrollLocation = direction === VERTICAL ? this.scrollTop() : this.scrollLeft();
  10595. var clientSize = direction === VERTICAL ? this.clientHeight() : this.clientWidth();
  10596. var isAlreadyVisible = scrollLocation <= elementPosition && elementBottom <= scrollLocation + clientSize;
  10597. var isElementBelowScrollLocation = scrollLocation > elementPosition;
  10598. return isAlreadyVisible ? scrollLocation : elementPosition + (isElementBelowScrollLocation ? 0 : elementSize - clientSize)
  10599. }
  10600. }))
  10601. })(jQuery, DevExpress);
  10602. /*! Module widgets-base, file ui.scrollbar.js */
  10603. (function($, DX, undefined) {
  10604. var ui = DX.ui,
  10605. events = ui.events;
  10606. var SCROLLBAR = "dxScrollbar",
  10607. SCROLLABLE_SCROLLBAR_CLASS = "dx-scrollable-scrollbar",
  10608. SCROLLABLE_SCROLLBAR_ACTIVE_CLASS = SCROLLABLE_SCROLLBAR_CLASS + "-active",
  10609. SCROLLABLE_SCROLL_CLASS = "dx-scrollable-scroll",
  10610. SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden",
  10611. HOVER_ENABLED_STATE = "dx-scrollbar-hoverable",
  10612. VERTICAL = "vertical",
  10613. HORIZONTAL = "horizontal",
  10614. THUMB_MIN_SIZE = 15;
  10615. var SCROLLBAR_VISIBLE = {
  10616. onScroll: "onScroll",
  10617. onHover: "onHover",
  10618. always: "always",
  10619. never: "never"
  10620. };
  10621. DX.registerComponent(SCROLLBAR, ui.Widget.inherit({
  10622. _setDefaultOptions: function() {
  10623. this.callBase();
  10624. this.option({
  10625. direction: null,
  10626. visible: false,
  10627. activeStateEnabled: false,
  10628. visibilityMode: SCROLLBAR_VISIBLE.onScroll,
  10629. containerSize: 0,
  10630. contentSize: 0
  10631. })
  10632. },
  10633. _init: function() {
  10634. this.callBase();
  10635. this._isHovered = false
  10636. },
  10637. _render: function() {
  10638. this._renderThumb();
  10639. this.callBase();
  10640. this._renderDirection();
  10641. this._update();
  10642. this._attachPointerDownHandler();
  10643. this.option("hoverStateEnabled", this._isHoverMode());
  10644. this._element().toggleClass(HOVER_ENABLED_STATE, this.option("hoverStateEnabled"))
  10645. },
  10646. _renderThumb: function() {
  10647. this._$thumb = $("<div>").addClass(SCROLLABLE_SCROLL_CLASS);
  10648. this._element().addClass(SCROLLABLE_SCROLLBAR_CLASS).append(this._$thumb)
  10649. },
  10650. isThumb: function($element) {
  10651. return !!this._element().find($element).length
  10652. },
  10653. _isHoverMode: function() {
  10654. return this.option("visibilityMode") === SCROLLBAR_VISIBLE.onHover
  10655. },
  10656. _renderDirection: function() {
  10657. var direction = this.option("direction");
  10658. this._element().addClass("dx-scrollbar-" + direction);
  10659. this._dimension = direction === HORIZONTAL ? "width" : "height";
  10660. this._prop = direction === HORIZONTAL ? "left" : "top"
  10661. },
  10662. _attachPointerDownHandler: function() {
  10663. this._$thumb.on(events.addNamespace("dxpointerdown", SCROLLBAR), $.proxy(this.feedbackOn, this))
  10664. },
  10665. feedbackOn: function() {
  10666. this._element().addClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);
  10667. activeScrollbar = this
  10668. },
  10669. feedbackOff: function() {
  10670. this._element().removeClass(SCROLLABLE_SCROLLBAR_ACTIVE_CLASS);
  10671. activeScrollbar = null
  10672. },
  10673. cursorEnter: function() {
  10674. this._isHovered = true;
  10675. this.option("visible", true)
  10676. },
  10677. cursorLeave: function() {
  10678. this._isHovered = false;
  10679. this.option("visible", false)
  10680. },
  10681. _renderDimensions: function() {
  10682. this._$thumb.height(this.option("height"));
  10683. this._$thumb.width(this.option("width"))
  10684. },
  10685. _toggleVisibility: function(visible) {
  10686. visible = this._adjustVisibility(visible);
  10687. this.option().visible = visible;
  10688. this._$thumb.toggleClass("dx-state-invisible", !visible)
  10689. },
  10690. _adjustVisibility: function(visible) {
  10691. if (this.containerToContentRatio() && !this._needScrollbar())
  10692. return false;
  10693. switch (this.option("visibilityMode")) {
  10694. case SCROLLBAR_VISIBLE.onScroll:
  10695. break;
  10696. case SCROLLBAR_VISIBLE.onHover:
  10697. visible = visible || !!this._isHovered;
  10698. break;
  10699. case SCROLLBAR_VISIBLE.never:
  10700. visible = false;
  10701. break;
  10702. case SCROLLBAR_VISIBLE.always:
  10703. visible = true;
  10704. break
  10705. }
  10706. return visible
  10707. },
  10708. moveTo: function(location) {
  10709. if (this._isHidden())
  10710. return;
  10711. if ($.isPlainObject(location))
  10712. location = location[this._prop] || 0;
  10713. var scrollBarLocation = {};
  10714. scrollBarLocation[this._prop] = this._calculateScrollBarPosition(location);
  10715. DX.translator.move(this._$thumb, scrollBarLocation)
  10716. },
  10717. _calculateScrollBarPosition: function(location) {
  10718. return -location * this._thumbRatio
  10719. },
  10720. _update: function() {
  10721. var containerSize = this.option("containerSize"),
  10722. contentSize = this.option("contentSize");
  10723. this._containerToContentRatio = containerSize / contentSize;
  10724. var thumbSize = Math.round(Math.max(Math.round(containerSize * this._containerToContentRatio), THUMB_MIN_SIZE));
  10725. this._thumbRatio = (containerSize - thumbSize) / (contentSize - containerSize);
  10726. this.option(this._dimension, thumbSize);
  10727. this._element().toggle(this._needScrollbar())
  10728. },
  10729. _isHidden: function() {
  10730. return this.option("visibilityMode") === SCROLLBAR_VISIBLE.never
  10731. },
  10732. _needScrollbar: function() {
  10733. return !this._isHidden() && this._containerToContentRatio < 1
  10734. },
  10735. containerToContentRatio: function() {
  10736. return this._containerToContentRatio
  10737. },
  10738. _normalizeSize: function(size) {
  10739. return $.isPlainObject(size) ? size[this._dimension] || 0 : size
  10740. },
  10741. _clean: function() {
  10742. this.callBase();
  10743. if (this === activeScrollbar)
  10744. activeScrollbar = null;
  10745. this._$thumb.off("." + SCROLLBAR)
  10746. },
  10747. _optionChanged: function(name, value) {
  10748. if (this._isHidden())
  10749. return;
  10750. switch (name) {
  10751. case"containerSize":
  10752. case"contentSize":
  10753. this.option()[name] = this._normalizeSize(value);
  10754. this._update();
  10755. break;
  10756. case"visibilityMode":
  10757. case"direction":
  10758. this._invalidate();
  10759. break;
  10760. default:
  10761. this.callBase.apply(this, arguments)
  10762. }
  10763. }
  10764. }));
  10765. var activeScrollbar = null;
  10766. $(document).on(events.addNamespace("dxpointerup", SCROLLBAR), function() {
  10767. if (activeScrollbar)
  10768. activeScrollbar.feedbackOff()
  10769. })
  10770. })(jQuery, DevExpress);
  10771. /*! Module widgets-base, file ui.scrollable.native.js */
  10772. (function($, DX, undefined) {
  10773. var ui = DX.ui,
  10774. events = ui.events,
  10775. utils = DX.utils,
  10776. devices = DX.devices,
  10777. abs = Math.abs;
  10778. var SCROLLABLE_NATIVE = "dxNativeScrollable",
  10779. SCROLLABLE_NATIVE_CLASS = "dx-scrollable-native",
  10780. SCROLLABLE_SCROLLBAR_SIMULATED = "dx-scrollable-scrollbar-simulated",
  10781. SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden",
  10782. VERTICAL = "vertical",
  10783. HORIZONTAL = "horizontal",
  10784. GESTURE_LOCK_KEY = "dxGestureLock",
  10785. GESTURE_LOCK_TIMEOUT = 400,
  10786. HIDE_SCROLLBAR_TIMOUT = 500;
  10787. ui.NativeScrollableStrategy = DX.Class.inherit({
  10788. ctor: function(scrollable) {
  10789. this._init(scrollable)
  10790. },
  10791. _init: function(scrollable) {
  10792. this._component = scrollable;
  10793. this._$element = scrollable._element();
  10794. this._$container = scrollable._$container;
  10795. this._$content = scrollable._$content;
  10796. this._direction = scrollable.option("direction");
  10797. this._useSimulatedScrollbar = scrollable.option("useSimulatedScrollbar");
  10798. this._showScrollbar = scrollable.option("showScrollbar");
  10799. this.option = $.proxy(scrollable.option, scrollable);
  10800. this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable);
  10801. this._isLocked = $.proxy(scrollable._isLocked, scrollable);
  10802. this._isDirection = $.proxy(scrollable._isDirection, scrollable);
  10803. this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable)
  10804. },
  10805. render: function() {
  10806. this._$element.addClass(SCROLLABLE_NATIVE_CLASS).addClass(SCROLLABLE_NATIVE_CLASS + "-" + devices.real().platform).toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this._showScrollbar);
  10807. if (this._showScrollbar && this._useSimulatedScrollbar)
  10808. this._renderScrollbars()
  10809. },
  10810. _renderScrollbars: function() {
  10811. this._scrollbars = {};
  10812. this._hideScrollbarTimeout = 0;
  10813. this._$element.addClass(SCROLLABLE_SCROLLBAR_SIMULATED);
  10814. this._renderScrollbar(VERTICAL);
  10815. this._renderScrollbar(HORIZONTAL)
  10816. },
  10817. _renderScrollbar: function(direction) {
  10818. if (!this._isDirection(direction))
  10819. return;
  10820. var $scrollbar = $("<div>").dxScrollbar({direction: direction}).appendTo(this._$element);
  10821. this._scrollbars[direction] = $scrollbar.dxScrollbar("instance")
  10822. },
  10823. handleInit: $.noop,
  10824. handleStart: $.noop,
  10825. handleMove: function(e) {
  10826. if (this._isLocked()) {
  10827. e.cancel = true;
  10828. return
  10829. }
  10830. if (this._allowedDirection())
  10831. e.originalEvent.originalEvent.isScrollingEvent = true
  10832. },
  10833. handleEnd: $.noop,
  10834. handleStop: $.noop,
  10835. _eachScrollbar: function(callback) {
  10836. callback = $.proxy(callback, this);
  10837. $.each(this._scrollbars || {}, function(direction, scrollbar) {
  10838. callback(scrollbar, direction)
  10839. })
  10840. },
  10841. createActions: function() {
  10842. var actionConfig = {excludeValidators: ["gesture"]};
  10843. this._scrollAction = this._createActionByOption("scrollAction", actionConfig);
  10844. this._updateAction = this._createActionByOption("updateAction", actionConfig)
  10845. },
  10846. _createActionArgs: function() {
  10847. var location = this.location();
  10848. return {
  10849. jQueryEvent: this._eventForUserAction,
  10850. scrollOffset: {
  10851. top: -location.top,
  10852. left: -location.left
  10853. },
  10854. reachedLeft: this._isDirection(HORIZONTAL) ? location.left >= 0 : undefined,
  10855. reachedRight: this._isDirection(HORIZONTAL) ? location.left <= this._containerSize.width - this._componentContentSize.width : undefined,
  10856. reachedTop: this._isDirection(VERTICAL) ? location.top >= 0 : undefined,
  10857. reachedBottom: this._isDirection(VERTICAL) ? location.top <= this._containerSize.height - this._componentContentSize.height : undefined
  10858. }
  10859. },
  10860. handleScroll: function(e) {
  10861. if (!this._isScrollLocationChanged()) {
  10862. e.stopImmediatePropagation();
  10863. return
  10864. }
  10865. this._eventForUserAction = e;
  10866. this._moveScrollbars();
  10867. this._scrollAction(this._createActionArgs());
  10868. this._treatNativeGesture();
  10869. this._lastLocation = this.location()
  10870. },
  10871. _isScrollLocationChanged: function() {
  10872. var currentLocation = this.location(),
  10873. lastLocation = this._lastLocation || {},
  10874. isTopChanged = lastLocation.top !== currentLocation.top,
  10875. isLeftChanged = lastLocation.left !== currentLocation.left;
  10876. return isTopChanged || isLeftChanged
  10877. },
  10878. _moveScrollbars: function() {
  10879. this._eachScrollbar(function(scrollbar) {
  10880. scrollbar.moveTo(this.location());
  10881. scrollbar.option("visible", true)
  10882. });
  10883. this._hideScrollbars()
  10884. },
  10885. _hideScrollbars: function() {
  10886. clearTimeout(this._hideScrollbarTimeout);
  10887. this._hideScrollbarTimeout = setTimeout($.proxy(function() {
  10888. this._eachScrollbar(function(scrollbar) {
  10889. scrollbar.option("visible", false)
  10890. })
  10891. }, this), HIDE_SCROLLBAR_TIMOUT)
  10892. },
  10893. _treatNativeGesture: function() {
  10894. this._prepareGesture();
  10895. this._forgetGesture()
  10896. },
  10897. _prepareGesture: function() {
  10898. if (this._gestureEndTimer) {
  10899. clearTimeout(this._gestureEndTimer);
  10900. this._gestureEndTimer = null
  10901. }
  10902. else
  10903. this._$element.data(GESTURE_LOCK_KEY, true)
  10904. },
  10905. _forgetGesture: function() {
  10906. this._gestureEndTimer = setTimeout($.proxy(function() {
  10907. this._$element.data(GESTURE_LOCK_KEY, false);
  10908. this._gestureEndTimer = null
  10909. }, this), GESTURE_LOCK_TIMEOUT)
  10910. },
  10911. location: function() {
  10912. return {
  10913. left: -this._$container.scrollLeft(),
  10914. top: -this._$container.scrollTop()
  10915. }
  10916. },
  10917. disabledChanged: $.noop,
  10918. update: function() {
  10919. this._update();
  10920. this._updateAction(this._createActionArgs())
  10921. },
  10922. _update: function() {
  10923. this._updateDimensions();
  10924. this._updateScrollbars()
  10925. },
  10926. _updateDimensions: function() {
  10927. this._containerSize = {
  10928. height: this._$container.height(),
  10929. width: this._$container.width()
  10930. };
  10931. this._componentContentSize = {
  10932. height: this._component.content().height(),
  10933. width: this._component.content().width()
  10934. };
  10935. this._contentSize = {
  10936. height: this._$content.height(),
  10937. width: this._$content.width()
  10938. }
  10939. },
  10940. _updateScrollbars: function() {
  10941. this._eachScrollbar(function(scrollbar, direction) {
  10942. var dimension = direction === VERTICAL ? "height" : "width";
  10943. scrollbar.option({
  10944. containerSize: this._containerSize[dimension],
  10945. contentSize: this._componentContentSize[dimension]
  10946. })
  10947. })
  10948. },
  10949. _allowedDirections: function() {
  10950. return {
  10951. vertical: this._isDirection(VERTICAL) && this._contentSize.height > this._containerSize.height,
  10952. horizontal: this._isDirection(HORIZONTAL) && this._contentSize.width > this._containerSize.width
  10953. }
  10954. },
  10955. dispose: function() {
  10956. this._$element.removeClass(function(index, className) {
  10957. var scrollableNativeRegexp = new RegExp(SCROLLABLE_NATIVE_CLASS + "\\S*", "g");
  10958. if (scrollableNativeRegexp.test(className))
  10959. return className.match(scrollableNativeRegexp).join(" ")
  10960. });
  10961. this._$element.off("." + SCROLLABLE_NATIVE);
  10962. this._$container.off("." + SCROLLABLE_NATIVE);
  10963. this._removeScrollbars();
  10964. clearTimeout(this._gestureEndTimer)
  10965. },
  10966. _removeScrollbars: function() {
  10967. this._eachScrollbar(function(scrollbar) {
  10968. scrollbar._element().remove()
  10969. })
  10970. },
  10971. scrollBy: function(distance) {
  10972. var location = this.location();
  10973. this._$container.scrollTop(-location.top - distance.top);
  10974. this._$container.scrollLeft(-location.left - distance.left)
  10975. },
  10976. validate: function() {
  10977. return !this.option("disabled") && this._allowedDirection()
  10978. },
  10979. getDirection: function() {
  10980. return this._allowedDirection()
  10981. }
  10982. })
  10983. })(jQuery, DevExpress);
  10984. /*! Module widgets-base, file ui.scrollable.simulated.js */
  10985. (function($, DX, undefined) {
  10986. var ui = DX.ui,
  10987. events = ui.events,
  10988. math = Math;
  10989. var realDevice = DX.devices.real;
  10990. var isSluggishPlatform = realDevice.platform === "win8" || realDevice.platform === "android";
  10991. var SCROLLABLE_SIMULATED = "dxSimulatedScrollable",
  10992. SCROLLABLE_STRATEGY = "dxScrollableStrategy",
  10993. SCROLLABLE_SIMULATED_CURSOR = SCROLLABLE_SIMULATED + "Cursor",
  10994. SCROLLABLE_SIMULATED_KEYBOARD = SCROLLABLE_SIMULATED + "Keyboard",
  10995. SCROLLABLE_SIMULATED_CLASS = "dx-scrollable-simulated",
  10996. SCROLLABLE_SCROLLBARS_HIDDEN = "dx-scrollable-scrollbars-hidden",
  10997. VERTICAL = "vertical",
  10998. HORIZONTAL = "horizontal",
  10999. ACCELERATION = isSluggishPlatform ? 0.95 : 0.92,
  11000. OUT_BOUNDS_ACCELERATION = 0.5,
  11001. MIN_VELOCITY_LIMIT = 1,
  11002. FRAME_DURATION = math.round(1000 / 60),
  11003. SCROLL_LINE_HEIGHT = 20,
  11004. BOUNCE_MIN_VELOCITY_LIMIT = MIN_VELOCITY_LIMIT / 5,
  11005. BOUNCE_DURATION = isSluggishPlatform ? 300 : 400,
  11006. BOUNCE_FRAMES = BOUNCE_DURATION / FRAME_DURATION,
  11007. BOUNCE_ACCELERATION_SUM = (1 - math.pow(ACCELERATION, BOUNCE_FRAMES)) / (1 - ACCELERATION);
  11008. var KEY_CODES = {
  11009. PAGE_UP: 33,
  11010. PAGE_DOWN: 34,
  11011. END: 35,
  11012. HOME: 36,
  11013. LEFT: 37,
  11014. UP: 38,
  11015. RIGHT: 39,
  11016. DOWN: 40
  11017. };
  11018. var InertiaAnimator = DX.Animator.inherit({
  11019. ctor: function(scroller) {
  11020. this.callBase();
  11021. this.scroller = scroller
  11022. },
  11023. VELOCITY_LIMIT: MIN_VELOCITY_LIMIT,
  11024. _isFinished: function() {
  11025. return math.abs(this.scroller._velocity) <= this.VELOCITY_LIMIT
  11026. },
  11027. _step: function() {
  11028. this.scroller._scrollStep(this.scroller._velocity);
  11029. this.scroller._velocity *= this._acceleration()
  11030. },
  11031. _acceleration: function() {
  11032. return this.scroller._inBounds() ? ACCELERATION : OUT_BOUNDS_ACCELERATION
  11033. },
  11034. _complete: function() {
  11035. this.scroller._scrollComplete()
  11036. },
  11037. _stop: function() {
  11038. this.scroller._stopComplete()
  11039. }
  11040. });
  11041. var BounceAnimator = InertiaAnimator.inherit({
  11042. VELOCITY_LIMIT: BOUNCE_MIN_VELOCITY_LIMIT,
  11043. _isFinished: function() {
  11044. return this.scroller._crossBoundOnNextStep() || this.callBase()
  11045. },
  11046. _acceleration: function() {
  11047. return ACCELERATION
  11048. },
  11049. _complete: function() {
  11050. this.scroller._move(this.scroller._bounceLocation);
  11051. this.callBase()
  11052. }
  11053. });
  11054. var isWheelEvent = function(e) {
  11055. return e.type === "dxmousewheel"
  11056. };
  11057. var Scroller = ui.Scroller = DX.Class.inherit({
  11058. ctor: function(options) {
  11059. this._initOptions(options);
  11060. this._initAnimators();
  11061. this._initScrollbar()
  11062. },
  11063. _initOptions: function(options) {
  11064. this._location = 0;
  11065. this._topReached = false;
  11066. this._bottomReached = false;
  11067. this._axis = options.direction === HORIZONTAL ? "x" : "y";
  11068. this._prop = options.direction === HORIZONTAL ? "left" : "top";
  11069. this._dimension = options.direction === HORIZONTAL ? "width" : "height";
  11070. this._scrollProp = options.direction === HORIZONTAL ? "scrollLeft" : "scrollTop";
  11071. $.each(options, $.proxy(function(optionName, optionValue) {
  11072. this["_" + optionName] = optionValue
  11073. }, this))
  11074. },
  11075. _initAnimators: function() {
  11076. this._inertiaAnimator = new InertiaAnimator(this);
  11077. this._bounceAnimator = new BounceAnimator(this)
  11078. },
  11079. _initScrollbar: function() {
  11080. this._$scrollbar = $("<div>").dxScrollbar({
  11081. direction: this._direction,
  11082. visible: this._scrollByThumb,
  11083. visibilityMode: this._visibilityModeNormalize(this._scrollbarVisible),
  11084. containerSize: this._containerSize(),
  11085. contentSize: this._contentSize()
  11086. }).appendTo(this._$container);
  11087. this._scrollbar = this._$scrollbar.dxScrollbar("instance")
  11088. },
  11089. _visibilityModeNormalize: function(mode) {
  11090. return mode === true ? "onScroll" : mode === false ? "never" : mode
  11091. },
  11092. _scrollStep: function(delta) {
  11093. var prevLocation = this._location;
  11094. this._location += delta;
  11095. this._suppressBounce();
  11096. this._move();
  11097. if (prevLocation !== this._location) {
  11098. this._scrollAction();
  11099. this._$element.triggerHandler("scroll")
  11100. }
  11101. },
  11102. _suppressBounce: function() {
  11103. if (this._bounceEnabled || this._inBounds(this._location))
  11104. return;
  11105. this._velocity = 0;
  11106. this._location = this._boundLocation()
  11107. },
  11108. _boundLocation: function() {
  11109. var location = math.min(this._location, this._maxOffset);
  11110. return math.max(location, this._minOffset)
  11111. },
  11112. _move: function(location) {
  11113. this._location = location !== undefined ? location : this._location;
  11114. this._moveContent();
  11115. this._moveScrollbar()
  11116. },
  11117. _moveContent: function() {
  11118. var targetLocation = {};
  11119. targetLocation[this._prop] = this._location;
  11120. DX.translator.move(this._$content, targetLocation)
  11121. },
  11122. _moveScrollbar: function() {
  11123. this._scrollbar.moveTo(this._location)
  11124. },
  11125. _scrollComplete: function() {
  11126. if (this._inBounds()) {
  11127. this._hideScrollbar();
  11128. this._correctLocation();
  11129. if (this._completeDeferred)
  11130. this._completeDeferred.resolve()
  11131. }
  11132. this._scrollToBounds()
  11133. },
  11134. _correctLocation: function() {
  11135. this._location = math.round(this._location);
  11136. this._move()
  11137. },
  11138. _scrollToBounds: function() {
  11139. if (this._inBounds())
  11140. return;
  11141. this._bounceAction();
  11142. this._setupBounce();
  11143. this._bounceAnimator.start()
  11144. },
  11145. _setupBounce: function() {
  11146. var boundLocation = this._bounceLocation = this._boundLocation(),
  11147. bounceDistance = boundLocation - this._location;
  11148. this._velocity = bounceDistance / BOUNCE_ACCELERATION_SUM
  11149. },
  11150. _inBounds: function(location) {
  11151. location = location !== undefined ? location : this._location;
  11152. return location >= this._minOffset && location <= this._maxOffset
  11153. },
  11154. _crossBoundOnNextStep: function() {
  11155. var location = this._location,
  11156. nextLocation = location + this._velocity;
  11157. return location < this._minOffset && nextLocation >= this._minOffset || location > this._maxOffset && nextLocation <= this._maxOffset
  11158. },
  11159. _handleInit: function(e) {
  11160. this._stopDeferred = $.Deferred();
  11161. this._stopScrolling();
  11162. this._prepareThumbScrolling(e);
  11163. return this._stopDeferred.promise()
  11164. },
  11165. _stopScrolling: function() {
  11166. this._hideScrollbar();
  11167. this._inertiaAnimator.stop();
  11168. this._bounceAnimator.stop()
  11169. },
  11170. _prepareThumbScrolling: function(e) {
  11171. if (isWheelEvent(e.originalEvent))
  11172. return;
  11173. var $target = $(e.originalEvent.target);
  11174. var scrollbarClicked = this._isScrollbar($target);
  11175. if (scrollbarClicked)
  11176. this._moveToMouseLocation(e);
  11177. this._thumbScrolling = scrollbarClicked || this._isThumb($target);
  11178. if (this._thumbScrolling)
  11179. this._scrollbar.feedbackOn()
  11180. },
  11181. _moveToMouseLocation: function(e) {
  11182. var mouseLocation = e["page" + this._axis.toUpperCase()] - this._$element.offset()[this._prop];
  11183. var location = this._location + mouseLocation / this._containerToContentRatio() - this._$container.height() / 2;
  11184. this._scrollStep(-location)
  11185. },
  11186. _stopComplete: function() {
  11187. if (this._stopDeferred)
  11188. this._stopDeferred.resolve()
  11189. },
  11190. _handleStart: function() {
  11191. this._showScrollbar()
  11192. },
  11193. _handleMove: function(delta) {
  11194. delta = delta[this._axis];
  11195. if (this._thumbScrolling)
  11196. delta = -delta / this._containerToContentRatio();
  11197. if (!this._inBounds())
  11198. delta *= OUT_BOUNDS_ACCELERATION;
  11199. this._scrollStep(delta)
  11200. },
  11201. _containerToContentRatio: function() {
  11202. return this._scrollbar.containerToContentRatio()
  11203. },
  11204. _handleEnd: function(velocity) {
  11205. this._completeDeferred = $.Deferred();
  11206. this._velocity = velocity[this._axis];
  11207. this._handleInertia();
  11208. this._resetThumbScrolling();
  11209. return this._completeDeferred.promise()
  11210. },
  11211. _handleInertia: function() {
  11212. this._suppressIntertia();
  11213. this._inertiaAnimator.start()
  11214. },
  11215. _suppressIntertia: function() {
  11216. if (!this._inertiaEnabled || this._thumbScrolling)
  11217. this._velocity = 0
  11218. },
  11219. _resetThumbScrolling: function() {
  11220. this._thumbScrolling = false
  11221. },
  11222. _handleStop: function() {
  11223. this._resetThumbScrolling();
  11224. this._scrollToBounds()
  11225. },
  11226. _handleDispose: function() {
  11227. this._stopScrolling();
  11228. this._$scrollbar.remove()
  11229. },
  11230. _handleUpdate: function() {
  11231. this._update();
  11232. this._moveToBounds()
  11233. },
  11234. _update: function() {
  11235. this._stopScrolling();
  11236. this._updateLocation();
  11237. this._updateBounds();
  11238. this._updateScrollbar();
  11239. this._moveScrollbar();
  11240. this._updateScrollbarVisibility()
  11241. },
  11242. _updateLocation: function() {
  11243. this._location = DX.translator.locate(this._$content)[this._prop]
  11244. },
  11245. _updateBounds: function() {
  11246. this._maxOffset = 0;
  11247. this._minOffset = math.min(this._containerSize() - this._contentSize(), 0)
  11248. },
  11249. _updateScrollbar: function() {
  11250. this._scrollbar.option({
  11251. containerSize: this._containerSize(),
  11252. contentSize: this._contentSize()
  11253. })
  11254. },
  11255. _updateScrollbarVisibility: function() {
  11256. this._showScrollbar();
  11257. this._hideScrollbar()
  11258. },
  11259. _moveToBounds: function() {
  11260. this._location = this._boundLocation();
  11261. this._move()
  11262. },
  11263. _handleCreateActions: function(actions) {
  11264. this._scrollAction = actions.scrollAction;
  11265. this._bounceAction = actions.bounceAction
  11266. },
  11267. _showScrollbar: function() {
  11268. this._scrollbar.option("visible", true)
  11269. },
  11270. _hideScrollbar: function() {
  11271. this._scrollbar.option("visible", false)
  11272. },
  11273. _containerSize: function() {
  11274. return this._$container[this._dimension]()
  11275. },
  11276. _contentSize: function() {
  11277. return this._$content[this._dimension]()
  11278. },
  11279. _validateEvent: function(e) {
  11280. var $target = $(e.originalEvent.target);
  11281. if (this._isThumb($target) || this._isScrollbar($target)) {
  11282. e.preventDefault();
  11283. return true
  11284. }
  11285. return this._isContent($target)
  11286. },
  11287. _isThumb: function($element) {
  11288. return this._scrollByThumb && this._scrollbar.isThumb($element)
  11289. },
  11290. _isScrollbar: function($element) {
  11291. return this._scrollByThumb && $element && $element.is(this._$scrollbar)
  11292. },
  11293. _isContent: function($element) {
  11294. return this._scrollByContent && !!$element.closest(this._$element).length
  11295. },
  11296. _reachedMin: function() {
  11297. return this._location <= this._minOffset
  11298. },
  11299. _reachedMax: function() {
  11300. return this._location >= this._maxOffset
  11301. },
  11302. _handleCursorEnter: function() {
  11303. this._scrollbar.cursorEnter()
  11304. },
  11305. _handleCursorLeave: function() {
  11306. this._scrollbar.cursorLeave()
  11307. }
  11308. });
  11309. var hoveredScrollable,
  11310. activeScrollable;
  11311. ui.SimulatedScrollableStrategy = DX.Class.inherit({
  11312. ctor: function(scrollable) {
  11313. this._init(scrollable)
  11314. },
  11315. _init: function(scrollable) {
  11316. this._component = scrollable;
  11317. this._$element = scrollable._element();
  11318. this._$container = scrollable._$container.prop("tabindex", 0);
  11319. this._$content = scrollable._$content;
  11320. this.option = $.proxy(scrollable.option, scrollable);
  11321. this._createActionByOption = $.proxy(scrollable._createActionByOption, scrollable);
  11322. this._isLocked = $.proxy(scrollable._isLocked, scrollable);
  11323. this._isDirection = $.proxy(scrollable._isDirection, scrollable);
  11324. this._allowedDirection = $.proxy(scrollable._allowedDirection, scrollable)
  11325. },
  11326. render: function() {
  11327. this._$element.addClass(SCROLLABLE_SIMULATED_CLASS);
  11328. this._createScrollers();
  11329. this._attachKeyboardHandler();
  11330. this._attachCursorHandlers()
  11331. },
  11332. _createScrollers: function() {
  11333. this._scrollers = {};
  11334. if (this._isDirection(HORIZONTAL))
  11335. this._createScroller(HORIZONTAL);
  11336. if (this._isDirection(VERTICAL))
  11337. this._createScroller(VERTICAL);
  11338. this._$element.toggleClass(SCROLLABLE_SCROLLBARS_HIDDEN, !this.option("showScrollbar"))
  11339. },
  11340. _createScroller: function(direction) {
  11341. this._scrollers[direction] = new Scroller(this._scrollerOptions(direction))
  11342. },
  11343. _scrollerOptions: function(direction) {
  11344. return {
  11345. direction: direction,
  11346. $content: this._$content,
  11347. $container: this._$container,
  11348. $element: this._$element,
  11349. scrollByContent: this.option("scrollByContent"),
  11350. scrollByThumb: this.option("scrollByThumb"),
  11351. scrollbarVisible: this.option("showScrollbar"),
  11352. bounceEnabled: this.option("bounceEnabled"),
  11353. inertiaEnabled: this.option("inertiaEnabled")
  11354. }
  11355. },
  11356. handleInit: function(e) {
  11357. this._supressDirections(e);
  11358. this._eventForUserAction = e;
  11359. this._handleEvent("Init", e).done(this._stopAction)
  11360. },
  11361. _supressDirections: function(e) {
  11362. if (isWheelEvent(e.originalEvent)) {
  11363. this._prepareDirections(true);
  11364. return
  11365. }
  11366. this._prepareDirections();
  11367. this._eachScroller(function(scroller, direction) {
  11368. var isValid = scroller._validateEvent(e);
  11369. this._validDirections[direction] = isValid
  11370. })
  11371. },
  11372. _prepareDirections: function(value) {
  11373. value = value || false;
  11374. this._validDirections = {};
  11375. this._validDirections[HORIZONTAL] = value;
  11376. this._validDirections[VERTICAL] = value
  11377. },
  11378. _eachScroller: function(callback) {
  11379. callback = $.proxy(callback, this);
  11380. $.each(this._scrollers, function(direction, scroller) {
  11381. callback(scroller, direction)
  11382. })
  11383. },
  11384. handleStart: function(e) {
  11385. this._saveActive();
  11386. this._handleEvent("Start").done(this._startAction)
  11387. },
  11388. _saveActive: function() {
  11389. activeScrollable = this
  11390. },
  11391. _resetActive: function() {
  11392. activeScrollable = null
  11393. },
  11394. _validateDirection: function(delta) {
  11395. var result = false;
  11396. this._eachScroller(function(scroller) {
  11397. result = result || scroller._validateDirection(delta)
  11398. });
  11399. return result
  11400. },
  11401. handleMove: function(e) {
  11402. if (this._isLocked()) {
  11403. e.cancel = true;
  11404. this._resetActive();
  11405. return
  11406. }
  11407. e.preventDefault && e.preventDefault();
  11408. this._adjustDistance(e.delta);
  11409. this._eventForUserAction = e;
  11410. this._handleEvent("Move", e.delta)
  11411. },
  11412. _adjustDistance: function(distance) {
  11413. distance.x *= this._validDirections[HORIZONTAL];
  11414. distance.y *= this._validDirections[VERTICAL]
  11415. },
  11416. handleEnd: function(e) {
  11417. this._resetActive();
  11418. this._refreshCursorState(e.originalEvent && e.originalEvent.target);
  11419. this._adjustDistance(e.velocity);
  11420. this._eventForUserAction = e;
  11421. return this._handleEvent("End", e.velocity).done(this._endAction)
  11422. },
  11423. handleCancel: function(e) {
  11424. this._resetActive();
  11425. this._eventForUserAction = e;
  11426. return this._handleEvent("End", {
  11427. x: 0,
  11428. y: 0
  11429. })
  11430. },
  11431. handleStop: function() {
  11432. this._resetActive();
  11433. this._handleEvent("Stop")
  11434. },
  11435. handleScroll: function() {
  11436. var distance = {
  11437. left: this._$container.scrollLeft(),
  11438. top: this._$container.scrollTop()
  11439. };
  11440. this._$container.scrollLeft(-distance.left);
  11441. this._$container.scrollTop(-distance.top);
  11442. this.scrollBy(distance)
  11443. },
  11444. _attachKeyboardHandler: function() {
  11445. this._$element.off("." + SCROLLABLE_SIMULATED_KEYBOARD);
  11446. if (!this.option("disabled") && this.option("useKeyboard"))
  11447. this._$element.on(events.addNamespace("keydown", SCROLLABLE_SIMULATED_KEYBOARD), $.proxy(this._handleKeyDown, this))
  11448. },
  11449. _handleKeyDown: function(e) {
  11450. if (!this._$container.is(document.activeElement))
  11451. return;
  11452. var handled = true;
  11453. switch (e.keyCode) {
  11454. case KEY_CODES.DOWN:
  11455. this._scrollByLine({y: 1});
  11456. break;
  11457. case KEY_CODES.UP:
  11458. this._scrollByLine({y: -1});
  11459. break;
  11460. case KEY_CODES.RIGHT:
  11461. this._scrollByLine({x: 1});
  11462. break;
  11463. case KEY_CODES.LEFT:
  11464. this._scrollByLine({x: -1});
  11465. break;
  11466. case KEY_CODES.PAGE_DOWN:
  11467. this._scrollByPage(1);
  11468. break;
  11469. case KEY_CODES.PAGE_UP:
  11470. this._scrollByPage(-1);
  11471. break;
  11472. case KEY_CODES.HOME:
  11473. this._scrollToHome();
  11474. break;
  11475. case KEY_CODES.END:
  11476. this._scrollToEnd();
  11477. break;
  11478. default:
  11479. handled = false;
  11480. break
  11481. }
  11482. if (handled) {
  11483. e.stopPropagation();
  11484. e.preventDefault()
  11485. }
  11486. },
  11487. _scrollByLine: function(lines) {
  11488. this.scrollBy({
  11489. top: (lines.y || 0) * -SCROLL_LINE_HEIGHT,
  11490. left: (lines.x || 0) * -SCROLL_LINE_HEIGHT
  11491. })
  11492. },
  11493. _scrollByPage: function(page) {
  11494. var prop = this._wheelProp(),
  11495. dimension = this._dimensionByProp(prop);
  11496. var distance = {};
  11497. distance[prop] = page * -this._$container[dimension]();
  11498. this.scrollBy(distance)
  11499. },
  11500. _dimensionByProp: function(prop) {
  11501. return prop === "left" ? "width" : "height"
  11502. },
  11503. _scrollToHome: function() {
  11504. var prop = this._wheelProp();
  11505. var distance = {};
  11506. distance[prop] = 0;
  11507. this._component.scrollTo(distance)
  11508. },
  11509. _scrollToEnd: function() {
  11510. var prop = this._wheelProp(),
  11511. dimension = this._dimensionByProp(prop);
  11512. var distance = {};
  11513. distance[prop] = this._$content[dimension]() - this._$container[dimension]();
  11514. this._component.scrollTo(distance)
  11515. },
  11516. createActions: function() {
  11517. this._startAction = this._createActionHandler("startAction");
  11518. this._stopAction = this._createActionHandler("stopAction");
  11519. this._endAction = this._createActionHandler("endAction");
  11520. this._updateAction = this._createActionHandler("updateAction");
  11521. this._createScrollerActions()
  11522. },
  11523. _createScrollerActions: function() {
  11524. this._handleEvent("CreateActions", {
  11525. scrollAction: this._createActionHandler("scrollAction"),
  11526. bounceAction: this._createActionHandler("bounceAction")
  11527. })
  11528. },
  11529. _createActionHandler: function(optionName) {
  11530. var that = this,
  11531. actionHandler = that._createActionByOption(optionName, {excludeValidators: ["gesture"]});
  11532. return function() {
  11533. actionHandler($.extend(that._createActionArgs(), arguments))
  11534. }
  11535. },
  11536. _createActionArgs: function() {
  11537. var scrollerX = this._scrollers[HORIZONTAL],
  11538. scrollerY = this._scrollers[VERTICAL];
  11539. return {
  11540. jQueryEvent: this._eventForUserAction,
  11541. scrollOffset: {
  11542. top: scrollerY && -scrollerY._location,
  11543. left: scrollerX && -scrollerX._location
  11544. },
  11545. reachedLeft: scrollerX && scrollerX._reachedMax(),
  11546. reachedRight: scrollerX && scrollerX._reachedMin(),
  11547. reachedTop: scrollerY && scrollerY._reachedMax(),
  11548. reachedBottom: scrollerY && scrollerY._reachedMin()
  11549. }
  11550. },
  11551. _handleEvent: function(eventName) {
  11552. var args = $.makeArray(arguments).slice(1),
  11553. deferreds = $.map(this._scrollers, function(scroller) {
  11554. return scroller["_handle" + eventName].apply(scroller, args)
  11555. });
  11556. return $.when.apply($, deferreds).promise()
  11557. },
  11558. location: function() {
  11559. return DX.translator.locate(this._$content)
  11560. },
  11561. disabledChanged: function() {
  11562. this._attachCursorHandlers()
  11563. },
  11564. _attachCursorHandlers: function() {
  11565. this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR);
  11566. if (!this.option("disabled") && this._isHoverMode())
  11567. this._$element.on(events.addNamespace("mouseenter", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._handleCursorEnter, this)).on(events.addNamespace("mouseleave", SCROLLABLE_SIMULATED_CURSOR), $.proxy(this._handleCursorLeave, this))
  11568. },
  11569. _isHoverMode: function() {
  11570. return this.option("showScrollbar") === "onHover"
  11571. },
  11572. _handleCursorEnter: function(e) {
  11573. e = e || {};
  11574. e.originalEvent = e.originalEvent || {};
  11575. if (activeScrollable || e.originalEvent._hoverHandled)
  11576. return;
  11577. if (hoveredScrollable)
  11578. hoveredScrollable._handleCursorLeave();
  11579. hoveredScrollable = this;
  11580. this._handleEvent("CursorEnter");
  11581. e.originalEvent._hoverHandled = true
  11582. },
  11583. _handleCursorLeave: function(e) {
  11584. if (hoveredScrollable !== this || activeScrollable === hoveredScrollable)
  11585. return;
  11586. this._handleEvent("CursorLeave");
  11587. hoveredScrollable = null;
  11588. this._refreshCursorState(e && e.relatedTarget)
  11589. },
  11590. _refreshCursorState: function(target) {
  11591. if (!this._isHoverMode() && (!target || activeScrollable))
  11592. return;
  11593. var $target = $(target);
  11594. var $scrollable = $target.closest("." + SCROLLABLE_SIMULATED_CLASS + ":not(.dx-state-disabled)");
  11595. var targetScrollable = $scrollable.length && $scrollable.data(SCROLLABLE_STRATEGY);
  11596. if (hoveredScrollable && hoveredScrollable !== targetScrollable)
  11597. hoveredScrollable._handleCursorLeave();
  11598. if (targetScrollable)
  11599. targetScrollable._handleCursorEnter()
  11600. },
  11601. update: function() {
  11602. return this._handleEvent("Update").done(this._updateAction)
  11603. },
  11604. _allowedDirections: function() {
  11605. var bounceEnabled = this.option("bounceEnabled");
  11606. return {
  11607. vertical: this._isDirection(VERTICAL) && (this._scrollers[VERTICAL]._minOffset < 0 || bounceEnabled),
  11608. horizontal: this._isDirection(HORIZONTAL) && (this._scrollers[HORIZONTAL]._minOffset < 0 || bounceEnabled)
  11609. }
  11610. },
  11611. scrollBy: function(distance) {
  11612. this._prepareDirections(true);
  11613. this._handleEvent("Start").done(this._startAction);
  11614. this._handleEvent("Move", {
  11615. x: distance.left,
  11616. y: distance.top
  11617. });
  11618. this._handleEvent("End", {
  11619. x: 0,
  11620. y: 0
  11621. }).done(this._endAction)
  11622. },
  11623. validate: function(e) {
  11624. if (this.option("disabled"))
  11625. return false;
  11626. if (this.option("bounceEnabled"))
  11627. return true;
  11628. return isWheelEvent(e) ? this._validateWheel(e) : this._validateMove()
  11629. },
  11630. _validateWheel: function(e) {
  11631. var scroller = this._scrollers[this._wheelDirection()];
  11632. var reachedMin = scroller._reachedMin();
  11633. var reachedMax = scroller._reachedMax();
  11634. var contentGreaterThanContainer = !reachedMin || !reachedMax;
  11635. var locatedNotAtBound = !reachedMin && !reachedMax;
  11636. var scrollFromMin = reachedMin && e.delta > 0;
  11637. var scrollFromMax = reachedMax && e.delta < 0;
  11638. return contentGreaterThanContainer && (locatedNotAtBound || scrollFromMin || scrollFromMax)
  11639. },
  11640. _validateMove: function() {
  11641. return this._allowedDirection()
  11642. },
  11643. getDirection: function(e) {
  11644. return isWheelEvent(e) ? this._wheelDirection() : this._allowedDirection()
  11645. },
  11646. _wheelProp: function() {
  11647. return this._wheelDirection() === HORIZONTAL ? "left" : "top"
  11648. },
  11649. _wheelDirection: function() {
  11650. switch (this.option("direction")) {
  11651. case HORIZONTAL:
  11652. return HORIZONTAL;
  11653. case VERTICAL:
  11654. return VERTICAL;
  11655. default:
  11656. return this._scrollers[VERTICAL]._containerToContentRatio() >= 1 ? HORIZONTAL : VERTICAL
  11657. }
  11658. },
  11659. dispose: function() {
  11660. if (activeScrollable === this)
  11661. activeScrollable = null;
  11662. if (hoveredScrollable === this)
  11663. hoveredScrollable = null;
  11664. this._handleEvent("Dispose");
  11665. this._detachEventHandlers();
  11666. this._$element.removeClass(SCROLLABLE_SIMULATED_CLASS);
  11667. this._eventForUserAction = null;
  11668. clearTimeout(this._gestureEndTimer)
  11669. },
  11670. _detachEventHandlers: function() {
  11671. this._$element.off("." + SCROLLABLE_SIMULATED_CURSOR);
  11672. this._$container.off("." + SCROLLABLE_SIMULATED_KEYBOARD)
  11673. }
  11674. });
  11675. ui.dxScrollable.__internals = $.extend(ui.dxScrollable.__internals || {}, {
  11676. ACCELERATION: ACCELERATION,
  11677. MIN_VELOCITY_LIMIT: MIN_VELOCITY_LIMIT,
  11678. FRAME_DURATION: FRAME_DURATION,
  11679. SCROLL_LINE_HEIGHT: SCROLL_LINE_HEIGHT
  11680. })
  11681. })(jQuery, DevExpress);
  11682. /*! Module widgets-base, file ui.scrollView.js */
  11683. (function($, DX, undefined) {
  11684. var ui = DX.ui;
  11685. var SCROLLVIEW_CLASS = "dx-scrollview",
  11686. SCROLLVIEW_CONTENT_CLASS = SCROLLVIEW_CLASS + "-content",
  11687. SCROLLVIEW_TOP_POCKET_CLASS = SCROLLVIEW_CLASS + "-top-pocket",
  11688. SCROLLVIEW_BOTTOM_POCKET_CLASS = SCROLLVIEW_CLASS + "-bottom-pocket",
  11689. SCROLLVIEW_PULLDOWN_CLASS = SCROLLVIEW_CLASS + "-pull-down",
  11690. SCROLLVIEW_PULLDOWN_IMAGE_CLASS = SCROLLVIEW_PULLDOWN_CLASS + "-image",
  11691. SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = SCROLLVIEW_PULLDOWN_CLASS + "-indicator",
  11692. SCROLLVIEW_PULLDOWN_TEXT_CLASS = SCROLLVIEW_PULLDOWN_CLASS + "-text",
  11693. SCROLLVIEW_REACHBOTTOM_CLASS = SCROLLVIEW_CLASS + "-scrollbottom",
  11694. SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-indicator",
  11695. SCROLLVIEW_REACHBOTTOM_TEXT_CLASS = SCROLLVIEW_REACHBOTTOM_CLASS + "-text",
  11696. SCROLLVIEW_LOADPANEL = SCROLLVIEW_CLASS + "-loadpanel";
  11697. DX.registerComponent("dxScrollView", ui.dxScrollable.inherit({
  11698. _setDefaultOptions: function() {
  11699. this.callBase();
  11700. this.option({
  11701. pullingDownText: Globalize.localize("dxScrollView-pullingDownText"),
  11702. pulledDownText: Globalize.localize("dxScrollView-pulledDownText"),
  11703. refreshingText: Globalize.localize("dxScrollView-refreshingText"),
  11704. reachBottomText: Globalize.localize("dxScrollView-reachBottomText"),
  11705. pullDownAction: null,
  11706. reachBottomAction: null,
  11707. refreshStrategy: "pullDown"
  11708. })
  11709. },
  11710. _defaultOptionsRules: function() {
  11711. return this.callBase().slice(0).concat([{
  11712. device: function(device) {
  11713. return DevExpress.devices.real().platform === "android"
  11714. },
  11715. options: {refreshStrategy: "swipeDown"}
  11716. }, {
  11717. device: function(device) {
  11718. return DevExpress.devices.real().platform === "win8"
  11719. },
  11720. options: {refreshStrategy: "slideDown"}
  11721. }])
  11722. },
  11723. _init: function() {
  11724. this.callBase();
  11725. this._loadingIndicatorEnabled = true
  11726. },
  11727. _initMarkup: function() {
  11728. this.callBase();
  11729. this._element().addClass(SCROLLVIEW_CLASS);
  11730. this._initContent();
  11731. this._initTopPocket();
  11732. this._initBottomPocket();
  11733. this._initLoadPanel()
  11734. },
  11735. _initContent: function() {
  11736. var $content = $("<div>").addClass(SCROLLVIEW_CONTENT_CLASS);
  11737. this._$content.wrapInner($content)
  11738. },
  11739. _initTopPocket: function() {
  11740. var $topPocket = this._$topPocket = $("<div>").addClass(SCROLLVIEW_TOP_POCKET_CLASS),
  11741. $pullDown = this._$pullDown = $("<div>").addClass(SCROLLVIEW_PULLDOWN_CLASS);
  11742. $topPocket.append($pullDown);
  11743. this._$content.prepend($topPocket)
  11744. },
  11745. _initBottomPocket: function() {
  11746. var $bottomPocket = this._$bottomPocket = $("<div>").addClass(SCROLLVIEW_BOTTOM_POCKET_CLASS),
  11747. $reachBottom = this._$reachBottom = $("<div>").addClass(SCROLLVIEW_REACHBOTTOM_CLASS),
  11748. $loadContainer = $("<div>").addClass(SCROLLVIEW_REACHBOTTOM_INDICATOR_CLASS),
  11749. $loadIndicator = $("<div>").dxLoadIndicator(),
  11750. $text = this._$reachBottomText = $("<div>").addClass(SCROLLVIEW_REACHBOTTOM_TEXT_CLASS);
  11751. this._updateReachBottomText();
  11752. $reachBottom.append($loadContainer.append($loadIndicator)).append($text);
  11753. $bottomPocket.append($reachBottom);
  11754. this._$content.append($bottomPocket)
  11755. },
  11756. _initLoadPanel: function() {
  11757. this._loadPanel = $("<div>").addClass(SCROLLVIEW_LOADPANEL).appendTo(this._element()).dxLoadPanel({
  11758. shading: false,
  11759. delay: 400,
  11760. position: {of: this._element()}
  11761. }).dxLoadPanel("instance")
  11762. },
  11763. _updateReachBottomText: function() {
  11764. this._$reachBottomText.text(this.option("reachBottomText"))
  11765. },
  11766. _createStrategy: function() {
  11767. var strategyName = this.option("useNative") ? this.option("refreshStrategy") : "simulated";
  11768. var strategyClass = ui.scrollViewRefreshStrategies[strategyName];
  11769. if (!strategyClass)
  11770. throw Error("Unknown dxScrollView refresh strategy " + this.option("refreshStrategy"));
  11771. this._strategy = new strategyClass(this);
  11772. this._strategy.pullDownCallbacks.add($.proxy(this._handlePullDown, this));
  11773. this._strategy.releaseCallbacks.add($.proxy(this._handleRelease, this));
  11774. this._strategy.reachBottomCallbacks.add($.proxy(this._handleReachBottom, this))
  11775. },
  11776. _createActions: function() {
  11777. this.callBase();
  11778. this._pullDownAction = this._createActionByOption("pullDownAction", {excludeValidators: ["gesture"]});
  11779. this._reachBottomAction = this._createActionByOption("reachBottomAction", {excludeValidators: ["gesture"]});
  11780. this._pullDownEnable(!!this.option("pullDownAction") && !DX.designMode);
  11781. this._reachBottomEnable(!!this.option("reachBottomAction") && !DX.designMode)
  11782. },
  11783. _pullDownEnable: function(enabled) {
  11784. this._$pullDown.toggle(enabled);
  11785. this._strategy.pullDownEnable(enabled)
  11786. },
  11787. _reachBottomEnable: function(enabled) {
  11788. this._$reachBottom.toggle(enabled);
  11789. this._strategy.reachBottomEnable(enabled)
  11790. },
  11791. _handlePullDown: function() {
  11792. this._loadingIndicator(false);
  11793. this._pullDownLoading()
  11794. },
  11795. _loadingIndicator: function(value) {
  11796. if (arguments.length < 1)
  11797. return this._loadingIndicatorEnabled;
  11798. this._loadingIndicatorEnabled = value
  11799. },
  11800. _pullDownLoading: function() {
  11801. this.startLoading();
  11802. this._pullDownAction()
  11803. },
  11804. _handleReachBottom: function() {
  11805. this._loadingIndicator(false);
  11806. this._reachBottomLoading()
  11807. },
  11808. _reachBottomLoading: function() {
  11809. this.startLoading();
  11810. this._reachBottomAction()
  11811. },
  11812. _handleRelease: function() {
  11813. this.finishLoading();
  11814. this._loadingIndicator(true)
  11815. },
  11816. _optionChanged: function(optionName, optionValue) {
  11817. switch (optionName) {
  11818. case"pullDownAction":
  11819. case"reachBottomAction":
  11820. this._createActions();
  11821. break;
  11822. case"pullingDownText":
  11823. case"pulledDownText":
  11824. case"refreshingText":
  11825. case"refreshStrategy":
  11826. this._invalidate();
  11827. break;
  11828. case"reachBottomText":
  11829. this._updateReachBottomText();
  11830. break;
  11831. default:
  11832. this.callBase.apply(this, arguments)
  11833. }
  11834. },
  11835. content: function() {
  11836. return this._$content.children().eq(1)
  11837. },
  11838. release: function(preventReachBottom) {
  11839. if (preventReachBottom !== undefined)
  11840. this.toggleLoading(!preventReachBottom);
  11841. return this._strategy.release()
  11842. },
  11843. toggleLoading: function(showOrHide) {
  11844. this._reachBottomEnable(showOrHide)
  11845. },
  11846. isFull: function() {
  11847. return this.content().height() >= this._$container.height()
  11848. },
  11849. refresh: function() {
  11850. if (!this.option("pullDownAction"))
  11851. return;
  11852. this._strategy.pendingRelease();
  11853. this._pullDownLoading()
  11854. },
  11855. startLoading: function() {
  11856. if (this._loadingIndicator() && this._element().is(":visible"))
  11857. this._loadPanel.show();
  11858. this._lock()
  11859. },
  11860. finishLoading: function() {
  11861. if (this._loadingIndicator())
  11862. this._loadPanel.hide();
  11863. this._unlock()
  11864. },
  11865. _dispose: function() {
  11866. this.callBase();
  11867. if (this._loadPanel)
  11868. this._loadPanel._element().remove()
  11869. }
  11870. }));
  11871. ui.scrollViewRefreshStrategies = {}
  11872. })(jQuery, DevExpress);
  11873. /*! Module widgets-base, file ui.scrollView.native.pullDown.js */
  11874. (function($, DX, undefined) {
  11875. var ui = DX.ui,
  11876. math = Math;
  11877. var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading",
  11878. SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready",
  11879. SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image",
  11880. SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",
  11881. SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text",
  11882. STATE_RELEASED = 0,
  11883. STATE_READY = 1,
  11884. STATE_REFRESHING = 2,
  11885. STATE_LOADING = 3;
  11886. var SCROLLVIEW_CONTENT_PADDING = 2;
  11887. var PullDownNativeScrollViewStrategy = ui.NativeScrollableStrategy.inherit({
  11888. _init: function(scrollView) {
  11889. this.callBase(scrollView);
  11890. this._$topPocket = scrollView._$topPocket;
  11891. this._$pullDown = scrollView._$pullDown;
  11892. this._$bottomPocket = scrollView._$bottomPocket;
  11893. this._$refreshingText = scrollView._$refreshingText;
  11894. this._$scrollViewContent = scrollView.content();
  11895. this._initCallbacks()
  11896. },
  11897. _initCallbacks: function() {
  11898. this.pullDownCallbacks = $.Callbacks();
  11899. this.releaseCallbacks = $.Callbacks();
  11900. this.reachBottomCallbacks = $.Callbacks()
  11901. },
  11902. render: function() {
  11903. this.callBase();
  11904. this._renderPullDown();
  11905. this._releaseState()
  11906. },
  11907. _renderPullDown: function() {
  11908. var $image = $("<div>").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS),
  11909. $loadContainer = $("<div>").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),
  11910. $loadIndicator = $("<div>").dxLoadIndicator(),
  11911. $text = this._$pullDownText = $("<div>").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS);
  11912. this._$pullingDownText = $("<div>").text(this.option("pullingDownText")).appendTo($text);
  11913. this._$pulledDownText = $("<div>").text(this.option("pulledDownText")).appendTo($text);
  11914. this._$refreshingText = $("<div>").text(this.option("refreshingText")).appendTo($text);
  11915. this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text)
  11916. },
  11917. _releaseState: function() {
  11918. this._state = STATE_RELEASED;
  11919. this._refreshPullDownText()
  11920. },
  11921. _refreshPullDownText: function() {
  11922. this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0);
  11923. this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0);
  11924. this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0)
  11925. },
  11926. update: function() {
  11927. this.callBase();
  11928. this._setTopPocketOffset()
  11929. },
  11930. _updateDimensions: function() {
  11931. this.callBase();
  11932. this._topPocketSize = this._$topPocket.height();
  11933. this._bottomPocketSize = this._$bottomPocket.height();
  11934. this._scrollOffset = this._$container.height() - this._$content.height();
  11935. this._pushBackFromBoundary()
  11936. },
  11937. _allowedDirections: function() {
  11938. var allowedDirections = this.callBase();
  11939. allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled;
  11940. return allowedDirections
  11941. },
  11942. _setTopPocketOffset: function() {
  11943. this._$topPocket.css({top: -this._topPocketSize})
  11944. },
  11945. handleEnd: function() {
  11946. this._complete()
  11947. },
  11948. handleStop: function() {
  11949. this._complete()
  11950. },
  11951. _complete: function() {
  11952. if (this._state === STATE_READY) {
  11953. this._setPullDownOffset(this._topPocketSize);
  11954. clearTimeout(this._pullDownRefreshTimeout);
  11955. this._pullDownRefreshTimeout = setTimeout($.proxy(function() {
  11956. this._pullDownRefreshing()
  11957. }, this), 400)
  11958. }
  11959. },
  11960. _setPullDownOffset: function(offset) {
  11961. DX.translator.move(this._$topPocket, {top: offset});
  11962. DX.translator.move(this._$scrollViewContent, {top: offset})
  11963. },
  11964. handleScroll: function(e) {
  11965. this.callBase(e);
  11966. this._pushBackFromBoundary();
  11967. if (this._state === STATE_REFRESHING)
  11968. return;
  11969. this._location = this.location().top;
  11970. if (this._isPullDown())
  11971. this._pullDownReady();
  11972. else if (this._isReachBottom())
  11973. this._reachBottom();
  11974. else
  11975. this._stateReleased()
  11976. },
  11977. _pushBackFromBoundary: function() {
  11978. var scrollTopPos = this._$container.scrollTop(),
  11979. scrollBottomPos = this._scrollOffset + scrollTopPos - SCROLLVIEW_CONTENT_PADDING;
  11980. if (!scrollTopPos)
  11981. this._$container.scrollTop(1);
  11982. else if (!scrollBottomPos)
  11983. this._$container.scrollTop(1 - this._scrollOffset)
  11984. },
  11985. _isPullDown: function() {
  11986. return this._pullDownEnabled && this._location >= this._topPocketSize
  11987. },
  11988. _isReachBottom: function() {
  11989. return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize
  11990. },
  11991. _reachBottom: function() {
  11992. if (this._state === STATE_LOADING)
  11993. return;
  11994. this._state = STATE_LOADING;
  11995. this.reachBottomCallbacks.fire()
  11996. },
  11997. _pullDownReady: function() {
  11998. if (this._state === STATE_READY)
  11999. return;
  12000. this._state = STATE_READY;
  12001. this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
  12002. this._refreshPullDownText()
  12003. },
  12004. _stateReleased: function() {
  12005. if (this._state === STATE_RELEASED)
  12006. return;
  12007. this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
  12008. this._releaseState()
  12009. },
  12010. _pullDownRefreshing: function() {
  12011. if (this._state === STATE_REFRESHING)
  12012. return;
  12013. this._state = STATE_REFRESHING;
  12014. this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
  12015. this._refreshPullDownText();
  12016. this.pullDownCallbacks.fire()
  12017. },
  12018. pullDownEnable: function(enabled) {
  12019. this._pullDownEnabled = enabled
  12020. },
  12021. reachBottomEnable: function(enabled) {
  12022. this._reachBottomEnabled = enabled
  12023. },
  12024. pendingRelease: function() {
  12025. this._state = STATE_READY
  12026. },
  12027. release: function() {
  12028. var deferred = $.Deferred();
  12029. this._updateDimensions();
  12030. clearTimeout(this._releaseTimeout);
  12031. this._releaseTimeout = setTimeout($.proxy(function() {
  12032. this._setPullDownOffset(0);
  12033. this._stateReleased();
  12034. this.releaseCallbacks.fire();
  12035. this._updateAction();
  12036. deferred.resolve()
  12037. }, this), 400);
  12038. return deferred.promise()
  12039. },
  12040. location: function() {
  12041. return {
  12042. left: -this._$container.scrollLeft(),
  12043. top: 1 - this._$container.scrollTop()
  12044. }
  12045. },
  12046. scrollBy: function(distance) {
  12047. var location = this.location();
  12048. this._$container.scrollTop(-location.top - distance.top + 1);
  12049. this._$container.scrollLeft(-location.left - distance.left)
  12050. },
  12051. dispose: function() {
  12052. clearTimeout(this._pullDownRefreshTimeout);
  12053. clearTimeout(this._releaseTimeout);
  12054. this.callBase()
  12055. }
  12056. });
  12057. ui.scrollViewRefreshStrategies.pullDown = PullDownNativeScrollViewStrategy
  12058. })(jQuery, DevExpress);
  12059. /*! Module widgets-base, file ui.scrollView.native.swipeDown.js */
  12060. (function($, DX, undefined) {
  12061. var ui = DX.ui,
  12062. events = ui.events,
  12063. math = Math;
  12064. var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading",
  12065. SCROLLVIEW_OBSOLETE_ANDROID_CLASS = "dx-scrollview-obsolete-android-browser",
  12066. PULLDOWN_HEIGHT = 160,
  12067. STATE_RELEASED = 0,
  12068. STATE_READY = 1,
  12069. STATE_REFRESHING = 2,
  12070. STATE_LOADING = 3,
  12071. STATE_TOUCHED = 4,
  12072. STATE_PULLED = 5;
  12073. var SwipeDownNativeScrollViewStrategy = ui.NativeScrollableStrategy.inherit({
  12074. _init: function(scrollView) {
  12075. this.callBase(scrollView);
  12076. this._$topPocket = scrollView._$topPocket;
  12077. this._$bottomPocket = scrollView._$bottomPocket;
  12078. this._$pullDown = scrollView._$pullDown;
  12079. this._$scrollViewContent = scrollView.content();
  12080. this._initCallbacks();
  12081. this._releaseState();
  12082. this._location = 0
  12083. },
  12084. _initCallbacks: function() {
  12085. this.pullDownCallbacks = $.Callbacks();
  12086. this.releaseCallbacks = $.Callbacks();
  12087. this.reachBottomCallbacks = $.Callbacks()
  12088. },
  12089. render: function() {
  12090. this.callBase();
  12091. this._renderPullDown()
  12092. },
  12093. _renderPullDown: function() {
  12094. this._$pullDown.empty().append($("<div class='dx-scrollview-pulldown-pointer1'>")).append($("<div class='dx-scrollview-pulldown-pointer2'>")).append($("<div class='dx-scrollview-pulldown-pointer3'>")).append($("<div class='dx-scrollview-pulldown-pointer4'>"))
  12095. },
  12096. _releaseState: function() {
  12097. this._state = STATE_RELEASED;
  12098. this._$pullDown.css({
  12099. width: "0%",
  12100. opacity: 0
  12101. });
  12102. this._updateDimensions()
  12103. },
  12104. _updateDimensions: function() {
  12105. this.callBase();
  12106. this._topPocketSize = this._$topPocket.height();
  12107. this._bottomPocketSize = this._$bottomPocket.height();
  12108. this._scrollOffset = this._$container.height() - this._$content.height()
  12109. },
  12110. _allowedDirections: function() {
  12111. var allowedDirections = this.callBase();
  12112. allowedDirections.vertical = allowedDirections.vertical || this._pullDownEnabled;
  12113. return allowedDirections
  12114. },
  12115. handleInit: function(e) {
  12116. this.callBase(e);
  12117. if (this._state === STATE_RELEASED && this._location === 0) {
  12118. this._startClientY = events.eventData(e.originalEvent).y;
  12119. this._state = STATE_TOUCHED
  12120. }
  12121. },
  12122. handleMove: function(e) {
  12123. this.callBase(e);
  12124. this._deltaY = events.eventData(e.originalEvent).y - this._startClientY;
  12125. if (this._state === STATE_TOUCHED)
  12126. if (this._pullDownEnabled && this._deltaY > 0) {
  12127. e.preventDefault();
  12128. this._state = STATE_PULLED
  12129. }
  12130. else
  12131. this._complete();
  12132. if (this._state === STATE_PULLED) {
  12133. if (this._deltaY < 0) {
  12134. this._complete();
  12135. return
  12136. }
  12137. this._$pullDown.css({
  12138. opacity: 1,
  12139. width: math.min(math.abs(this._deltaY * 100 / PULLDOWN_HEIGHT), 100) + "%"
  12140. });
  12141. if (this._isPullDown())
  12142. this._pullDownRefreshing()
  12143. }
  12144. },
  12145. _isPullDown: function() {
  12146. return this._pullDownEnabled && this._deltaY >= PULLDOWN_HEIGHT
  12147. },
  12148. handleEnd: function() {
  12149. this._complete()
  12150. },
  12151. handleStop: function() {
  12152. this._complete()
  12153. },
  12154. _complete: function() {
  12155. if (this._state === STATE_TOUCHED || this._state === STATE_PULLED)
  12156. this._releaseState()
  12157. },
  12158. handleScroll: function(e) {
  12159. this.callBase(e);
  12160. if (this._state === STATE_REFRESHING)
  12161. return;
  12162. var currentLocation = this.location().top,
  12163. scrollDelta = this._location - currentLocation;
  12164. this._location = currentLocation;
  12165. if (scrollDelta > 0 && this._isReachBottom())
  12166. this._reachBottom();
  12167. else
  12168. this._stateReleased()
  12169. },
  12170. _isReachBottom: function() {
  12171. return this._reachBottomEnabled && this._location <= this._scrollOffset + this._bottomPocketSize
  12172. },
  12173. _reachBottom: function() {
  12174. this.reachBottomCallbacks.fire()
  12175. },
  12176. _stateReleased: function() {
  12177. if (this._state === STATE_RELEASED)
  12178. return;
  12179. this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS);
  12180. this._releaseState()
  12181. },
  12182. _pullDownRefreshing: function() {
  12183. if (this._state === STATE_REFRESHING)
  12184. return;
  12185. this._state = STATE_REFRESHING;
  12186. clearTimeout(this._pullDownRefreshTimeout);
  12187. this._pullDownRefreshTimeout = setTimeout($.proxy(function() {
  12188. this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS);
  12189. this.pullDownCallbacks.fire()
  12190. }, this), 400)
  12191. },
  12192. pullDownEnable: function(enabled) {
  12193. this._$topPocket.toggle(enabled);
  12194. this._pullDownEnabled = enabled
  12195. },
  12196. reachBottomEnable: function(enabled) {
  12197. this._reachBottomEnabled = enabled
  12198. },
  12199. pendingRelease: function() {
  12200. this._state = STATE_READY
  12201. },
  12202. release: function() {
  12203. var deferred = $.Deferred();
  12204. this._updateDimensions();
  12205. clearTimeout(this._releaseTimeout);
  12206. this._releaseTimeout = setTimeout($.proxy(function() {
  12207. this._stateReleased();
  12208. this.releaseCallbacks.fire();
  12209. this._updateAction();
  12210. deferred.resolve()
  12211. }, this), 800);
  12212. return deferred.promise()
  12213. },
  12214. dispose: function() {
  12215. clearTimeout(this._pullDownRefreshTimeout);
  12216. clearTimeout(this._releaseTimeout);
  12217. this.callBase()
  12218. }
  12219. });
  12220. ui.scrollViewRefreshStrategies.swipeDown = SwipeDownNativeScrollViewStrategy
  12221. })(jQuery, DevExpress);
  12222. /*! Module widgets-base, file ui.scrollView.native.slideDown.js */
  12223. (function($, DX, undefined) {
  12224. var ui = DX.ui;
  12225. var DX_SLIDE_DOWN_NATIVE_SCROLLVIEW_STRATEGY = "dxSlideDownNativeScrollViewStrategy",
  12226. STATE_RELEASED = 0,
  12227. STATE_READY = 1,
  12228. STATE_LOADING = 2,
  12229. LOADING_HEIGHT = 80;
  12230. var SlideDownNativeScrollViewStrategy = ui.NativeScrollableStrategy.inherit({
  12231. _init: function(scrollView) {
  12232. this.callBase(scrollView);
  12233. this._$topPocket = scrollView._$topPocket;
  12234. this._$bottomPocket = scrollView._$bottomPocket;
  12235. this._initCallbacks()
  12236. },
  12237. _initCallbacks: function() {
  12238. this.pullDownCallbacks = $.Callbacks();
  12239. this.releaseCallbacks = $.Callbacks();
  12240. this.reachBottomCallbacks = $.Callbacks()
  12241. },
  12242. render: function() {
  12243. this.callBase();
  12244. this._renderPullDown();
  12245. this._renderBottom();
  12246. this._releaseState();
  12247. this._updateDimensions()
  12248. },
  12249. _renderPullDown: function() {
  12250. this._$topPocket.empty()
  12251. },
  12252. _renderBottom: function() {
  12253. this._$bottomPocket.empty().append("<progress>")
  12254. },
  12255. _releaseState: function() {
  12256. if (this._state === STATE_RELEASED)
  12257. return;
  12258. this._state = STATE_RELEASED
  12259. },
  12260. _updateDimensions: function() {
  12261. this._scrollOffset = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight");
  12262. this._containerSize = {
  12263. height: this._$container.prop("clientHeight"),
  12264. width: this._$container.prop("clientWidth")
  12265. };
  12266. this._contentSize = this._componentContentSize = {
  12267. height: this._$container.prop("scrollHeight"),
  12268. width: this._$container.prop("scrollWidth")
  12269. }
  12270. },
  12271. handleScroll: function(e) {
  12272. this.callBase(e);
  12273. if (this._isReachBottom(this._lastLocation.top))
  12274. this._reachBottom()
  12275. },
  12276. _isReachBottom: function(location) {
  12277. this._scrollContent = this._$container.prop("scrollHeight") - this._$container.prop("clientHeight");
  12278. return this._reachBottomEnabled && location < -this._scrollContent + LOADING_HEIGHT
  12279. },
  12280. _reachBottom: function() {
  12281. if (this._state === STATE_LOADING)
  12282. return;
  12283. this._state = STATE_LOADING;
  12284. this.reachBottomCallbacks.fire()
  12285. },
  12286. pullDownEnable: function(enabled) {
  12287. this._pullDownEnabled = enabled
  12288. },
  12289. reachBottomEnable: function(enabled) {
  12290. this._reachBottomEnabled = enabled;
  12291. this._$bottomPocket.toggle(enabled)
  12292. },
  12293. pendingRelease: function() {
  12294. this._state = STATE_READY
  12295. },
  12296. release: function() {
  12297. var deferred = $.Deferred();
  12298. this._state = STATE_RELEASED;
  12299. this.releaseCallbacks.fire();
  12300. this.update();
  12301. return deferred.resolve().promise()
  12302. }
  12303. });
  12304. ui.scrollViewRefreshStrategies.slideDown = SlideDownNativeScrollViewStrategy
  12305. })(jQuery, DevExpress);
  12306. /*! Module widgets-base, file ui.scrollView.simulated.js */
  12307. (function($, DX, undefined) {
  12308. var ui = DX.ui,
  12309. math = Math;
  12310. var SCROLLVIEW_PULLDOWN_REFRESHING_CLASS = "dx-scrollview-pull-down-loading",
  12311. SCROLLVIEW_PULLDOWN_READY_CLASS = "dx-scrollview-pull-down-ready",
  12312. SCROLLVIEW_PULLDOWN_IMAGE_CLASS = "dx-scrollview-pull-down-image",
  12313. SCROLLVIEW_PULLDOWN_INDICATOR_CLASS = "dx-scrollview-pull-down-indicator",
  12314. SCROLLVIEW_PULLDOWN_TEXT_CLASS = "dx-scrollview-pull-down-text",
  12315. STATE_RELEASED = 0,
  12316. STATE_READY = 1,
  12317. STATE_REFRESHING = 2,
  12318. STATE_LOADING = 3;
  12319. var ScrollViewScroller = ui.ScrollViewScroller = ui.Scroller.inherit({
  12320. ctor: function() {
  12321. this.callBase.apply(this, arguments);
  12322. this._initCallbacks();
  12323. this._releaseState()
  12324. },
  12325. _releaseState: function() {
  12326. this._state = STATE_RELEASED;
  12327. this._refreshPullDownText()
  12328. },
  12329. _refreshPullDownText: function() {
  12330. this._$pullingDownText.css("opacity", this._state === STATE_RELEASED ? 1 : 0);
  12331. this._$pulledDownText.css("opacity", this._state === STATE_READY ? 1 : 0);
  12332. this._$refreshingText.css("opacity", this._state === STATE_REFRESHING ? 1 : 0)
  12333. },
  12334. _initCallbacks: function() {
  12335. this.pullDownCallbacks = $.Callbacks();
  12336. this.releaseCallbacks = $.Callbacks();
  12337. this.reachBottomCallbacks = $.Callbacks()
  12338. },
  12339. _updateBounds: function() {
  12340. var considerPockets = this._direction !== "horizontal";
  12341. this._topPocketSize = considerPockets ? this._$topPocket[this._dimension]() : 0;
  12342. this._bottomPocketSize = considerPockets ? this._$bottomPocket[this._dimension]() : 0;
  12343. this._updateOffsets()
  12344. },
  12345. _updateOffsets: function() {
  12346. this._minOffset = math.min(this._containerSize() - this._contentSize() + this._bottomPocketSize, -this._topPocketSize);
  12347. this._maxOffset = -this._topPocketSize;
  12348. this._bottomBound = this._minOffset - this._bottomPocketSize
  12349. },
  12350. _updateScrollbar: function() {
  12351. this._scrollbar.option({
  12352. containerSize: this._containerSize(),
  12353. contentSize: this._contentSize() - this._topPocketSize - this._bottomPocketSize
  12354. })
  12355. },
  12356. _moveContent: function() {
  12357. this.callBase();
  12358. if (this._isPullDown())
  12359. this._pullDownReady();
  12360. else if (this._isReachBottom())
  12361. this._reachBottomReady();
  12362. else if (this._state !== STATE_RELEASED)
  12363. this._stateReleased()
  12364. },
  12365. _moveScrollbar: function() {
  12366. this._scrollbar.moveTo(this._topPocketSize + this._location)
  12367. },
  12368. _isPullDown: function() {
  12369. return this._pullDownEnabled && this._location >= 0
  12370. },
  12371. _isReachBottom: function() {
  12372. return this._reachBottomEnabled && this._location <= this._bottomBound
  12373. },
  12374. _scrollComplete: function() {
  12375. if (this._inBounds() && this._state === STATE_READY)
  12376. this._pullDownRefreshing();
  12377. else if (this._inBounds() && this._state === STATE_LOADING)
  12378. this._reachBottomLoading();
  12379. else
  12380. this.callBase()
  12381. },
  12382. _reachBottomReady: function() {
  12383. if (this._state === STATE_LOADING)
  12384. return;
  12385. this._state = STATE_LOADING;
  12386. this._minOffset = math.min(this._containerSize() - this._contentSize(), 0)
  12387. },
  12388. _reachBottomLoading: function() {
  12389. this.reachBottomCallbacks.fire()
  12390. },
  12391. _pullDownReady: function() {
  12392. if (this._state === STATE_READY)
  12393. return;
  12394. this._state = STATE_READY;
  12395. this._maxOffset = 0;
  12396. this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
  12397. this._refreshPullDownText()
  12398. },
  12399. _stateReleased: function() {
  12400. if (this._state === STATE_RELEASED)
  12401. return;
  12402. this._releaseState();
  12403. this._updateOffsets();
  12404. this._$pullDown.removeClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
  12405. this.releaseCallbacks.fire()
  12406. },
  12407. _pullDownRefreshing: function() {
  12408. if (this._state === STATE_REFRESHING)
  12409. return;
  12410. this._state = STATE_REFRESHING;
  12411. this._$pullDown.addClass(SCROLLVIEW_PULLDOWN_REFRESHING_CLASS).removeClass(SCROLLVIEW_PULLDOWN_READY_CLASS);
  12412. this._refreshPullDownText();
  12413. this.pullDownCallbacks.fire()
  12414. },
  12415. _handleRelease: function() {
  12416. if (this._state === STATE_RELEASED)
  12417. this._moveToBounds();
  12418. this._update();
  12419. return DX.utils.executeAsync($.proxy(this._release, this))
  12420. },
  12421. _release: function() {
  12422. this._stateReleased();
  12423. this._scrollComplete()
  12424. },
  12425. _handleReachBottomEnabling: function(enabled) {
  12426. if (this._reachBottomEnabled === enabled)
  12427. return;
  12428. this._reachBottomEnabled = enabled;
  12429. this._updateBounds()
  12430. },
  12431. _handlePullDownEnabling: function(enabled) {
  12432. if (this._pullDownEnabled === enabled)
  12433. return;
  12434. this._pullDownEnabled = enabled;
  12435. this._considerTopPocketChange();
  12436. this._handleUpdate()
  12437. },
  12438. _considerTopPocketChange: function() {
  12439. this._location -= this._$topPocket.height() || -this._topPocketSize;
  12440. this._move()
  12441. },
  12442. _handlePendingRelease: function() {
  12443. this._state = STATE_READY
  12444. }
  12445. });
  12446. var SimulatedScrollViewStrategy = ui.SimulatedScrollableStrategy.inherit({
  12447. _init: function(scrollView) {
  12448. this.callBase(scrollView);
  12449. this._$pullDown = scrollView._$pullDown;
  12450. this._$topPocket = scrollView._$topPocket;
  12451. this._$bottomPocket = scrollView._$bottomPocket;
  12452. this._initCallbacks()
  12453. },
  12454. _initCallbacks: function() {
  12455. this.pullDownCallbacks = $.Callbacks();
  12456. this.releaseCallbacks = $.Callbacks();
  12457. this.reachBottomCallbacks = $.Callbacks()
  12458. },
  12459. render: function() {
  12460. this._renderPullDown();
  12461. this.callBase()
  12462. },
  12463. _renderPullDown: function() {
  12464. var $image = $("<div>").addClass(SCROLLVIEW_PULLDOWN_IMAGE_CLASS),
  12465. $loadContainer = $("<div>").addClass(SCROLLVIEW_PULLDOWN_INDICATOR_CLASS),
  12466. $loadIndicator = $("<div>").dxLoadIndicator(),
  12467. $text = this._$pullDownText = $("<div>").addClass(SCROLLVIEW_PULLDOWN_TEXT_CLASS);
  12468. this._$pullingDownText = $("<div>").text(this.option("pullingDownText")).appendTo($text);
  12469. this._$pulledDownText = $("<div>").text(this.option("pulledDownText")).appendTo($text);
  12470. this._$refreshingText = $("<div>").text(this.option("refreshingText")).appendTo($text);
  12471. this._$pullDown.empty().append($image).append($loadContainer.append($loadIndicator)).append($text)
  12472. },
  12473. pullDownEnable: function(enabled) {
  12474. this._handleEvent("PullDownEnabling", enabled)
  12475. },
  12476. reachBottomEnable: function(enabled) {
  12477. this._handleEvent("ReachBottomEnabling", enabled)
  12478. },
  12479. _createScroller: function(direction) {
  12480. var that = this;
  12481. var scroller = that._scrollers[direction] = new ScrollViewScroller(that._scrollerOptions(direction));
  12482. scroller.pullDownCallbacks.add(function() {
  12483. that.pullDownCallbacks.fire()
  12484. });
  12485. scroller.releaseCallbacks.add(function() {
  12486. that.releaseCallbacks.fire()
  12487. });
  12488. scroller.reachBottomCallbacks.add(function() {
  12489. that.reachBottomCallbacks.fire()
  12490. })
  12491. },
  12492. _scrollerOptions: function(direction) {
  12493. return $.extend(this.callBase(direction), {
  12494. $topPocket: this._$topPocket,
  12495. $bottomPocket: this._$bottomPocket,
  12496. $pullDown: this._$pullDown,
  12497. $pullDownText: this._$pullDownText,
  12498. $pullingDownText: this._$pullingDownText,
  12499. $pulledDownText: this._$pulledDownText,
  12500. $refreshingText: this._$refreshingText
  12501. })
  12502. },
  12503. pendingRelease: function() {
  12504. this._handleEvent("PendingRelease")
  12505. },
  12506. release: function() {
  12507. return this._handleEvent("Release").done(this._updateAction)
  12508. }
  12509. });
  12510. ui.scrollViewRefreshStrategies.simulated = SimulatedScrollViewStrategy
  12511. })(jQuery, DevExpress);
  12512. /*! Module widgets-base, file ui.map.js */
  12513. (function($, DX, undefined) {
  12514. var ui = DX.ui,
  12515. events = ui.events,
  12516. utils = DX.utils,
  12517. winJS = DX.support.winJS,
  12518. wrapToArray = utils.wrapToArray,
  12519. removeDublicates = utils.removeDublicates,
  12520. titleize = DX.inflector.titleize;
  12521. ui.MapProvider = DX.Class.inherit({
  12522. _defaultRouteWeight: function() {
  12523. return 5
  12524. },
  12525. _defaultRouteOpacity: function() {
  12526. return .5
  12527. },
  12528. _defaultRouteColor: function() {
  12529. return "#0000FF"
  12530. },
  12531. ctor: function(map, $container) {
  12532. this._mapWidget = map;
  12533. this._$container = $container
  12534. },
  12535. load: $.noop,
  12536. render: function() {
  12537. var deferred = $.Deferred(),
  12538. that = this;
  12539. this._renderImpl().done(function() {
  12540. var markersPromise = that.addMarkers(that._option("markers"));
  12541. var routesPromise = that.addRoutes(that._option("routes"));
  12542. $.when(markersPromise, routesPromise).done(function() {
  12543. deferred.resolve(true)
  12544. })
  12545. });
  12546. return deferred.promise()
  12547. },
  12548. _renderImpl: DX.abstract,
  12549. updateDimensions: DX.abstract,
  12550. updateMapType: DX.abstract,
  12551. updateCenter: DX.abstract,
  12552. updateZoom: DX.abstract,
  12553. updateControls: DX.abstract,
  12554. updateMarkers: function(markerOptionsToRemove, markerOptionsToAdd) {
  12555. var deferred = $.Deferred(),
  12556. that = this;
  12557. this.removeMarkers(markerOptionsToRemove).done(function() {
  12558. that.addMarkers(markerOptionsToAdd).done(function() {
  12559. deferred.resolve.apply(deferred, arguments)
  12560. })
  12561. });
  12562. return deferred.promise()
  12563. },
  12564. addMarkers: DX.abstract,
  12565. removeMarkers: DX.abstract,
  12566. adjustViewport: DX.abstract,
  12567. updateRoutes: function(routeOptionsToRemove, routeOptionsToAdd) {
  12568. var deferred = $.Deferred(),
  12569. that = this;
  12570. this.removeRoutes(routeOptionsToRemove).done(function() {
  12571. that.addRoutes(routeOptionsToAdd).done(function() {
  12572. deferred.resolve.apply(deferred, arguments)
  12573. })
  12574. });
  12575. return deferred.promise()
  12576. },
  12577. addRoutes: DX.abstract,
  12578. removeRoutes: DX.abstract,
  12579. clean: DX.abstract,
  12580. cancelEvents: false,
  12581. map: function() {
  12582. return this._map
  12583. },
  12584. mapRendered: function() {
  12585. return !!this._map
  12586. },
  12587. _option: function(name, value) {
  12588. if (value === undefined)
  12589. return this._mapWidget.option(name);
  12590. this._mapWidget.setOptionSilent(name, value)
  12591. },
  12592. _keyOption: function(providerName) {
  12593. var key = this._option("key");
  12594. return key[providerName] === undefined ? key : key[providerName]
  12595. },
  12596. _parseTooltipOptions: function(option) {
  12597. return {
  12598. text: option.text || option,
  12599. visible: option.isShown || false
  12600. }
  12601. },
  12602. _addEventNamespace: function(name) {
  12603. return events.addNamespace(name, this._mapWidget.NAME)
  12604. },
  12605. _createAction: function() {
  12606. var mapWidget = this._mapWidget;
  12607. return mapWidget._createAction.apply(mapWidget, arguments)
  12608. },
  12609. _fireAction: function(name, actionArguments) {
  12610. var option = this._option(name);
  12611. if (option)
  12612. this._createAction(option)(actionArguments)
  12613. },
  12614. _fireClickAction: function(actionArguments) {
  12615. this._fireAction("clickAction", actionArguments)
  12616. },
  12617. _fireMarkerAddedAction: function(actionArguments) {
  12618. this._fireAction("markerAddedAction", actionArguments)
  12619. },
  12620. _fireMarkerRemovedAction: function(actionArguments) {
  12621. this._fireAction("markerRemovedAction", actionArguments)
  12622. },
  12623. _fireRouteAddedAction: function(actionArguments) {
  12624. this._fireAction("routeAddedAction", actionArguments)
  12625. },
  12626. _fireRouteRemovedAction: function(actionArguments) {
  12627. this._fireAction("routeRemovedAction", actionArguments)
  12628. }
  12629. });
  12630. var providers = {};
  12631. ui.registerMapProvider = function(name, provider) {
  12632. providers[name] = provider
  12633. };
  12634. var MAP_CLASS = "dx-map",
  12635. MAP_CONTAINER_CLASS = "dx-map-container",
  12636. MAP_SHIELD_CLASS = "dx-map-shield";
  12637. DX.registerComponent("dxMap", ui.Widget.inherit({
  12638. ctor: function() {
  12639. this.callBase.apply(this, arguments);
  12640. this.addMarker = $.proxy(this._addFunction, this, "markers");
  12641. this.removeMarker = $.proxy(this._removeFunction, this, "markers");
  12642. this.addRoute = $.proxy(this._addFunction, this, "routes");
  12643. this.removeRoute = $.proxy(this._removeFunction, this, "routes")
  12644. },
  12645. _addFunction: function(optionName, addingValue) {
  12646. var deferred = $.Deferred(),
  12647. that = this,
  12648. providerDeffered = $.Deferred(),
  12649. optionValue = this.option(optionName),
  12650. addingValues = wrapToArray(addingValue);
  12651. optionValue.push.apply(optionValue, addingValues);
  12652. this._notificationDeffered = providerDeffered;
  12653. this.option(optionName, optionValue);
  12654. providerDeffered.done(function(instance) {
  12655. deferred.resolveWith(that, instance && instance.length > 1 ? [instance] : instance)
  12656. });
  12657. return deferred.promise()
  12658. },
  12659. _removeFunction: function(optionName, removingValue) {
  12660. var deferred = $.Deferred(),
  12661. that = this,
  12662. providerDeffered = $.Deferred(),
  12663. optionValue = this.option(optionName),
  12664. removingValues = wrapToArray(removingValue);
  12665. $.each(removingValues, function(_, removingValue) {
  12666. var index = $.isNumeric(removingValue) ? removingValue : $.inArray(removingValue, optionValue);
  12667. if (index !== -1)
  12668. optionValue.splice(index, 1);
  12669. else
  12670. throw new Error(titleize(optionName.substring(0, optionName.length - 1)) + " '" + removingValue + "' you are trying to remove does not exist");
  12671. });
  12672. this._notificationDeffered = providerDeffered;
  12673. this.option(optionName, optionValue);
  12674. providerDeffered.done(function() {
  12675. deferred.resolveWith(that)
  12676. });
  12677. return deferred.promise()
  12678. },
  12679. _deprecatedOptions: {location: {
  12680. since: "14.1",
  12681. message: "Use the 'center' option instead."
  12682. }},
  12683. _optionAliases: {center: "location"},
  12684. _setDefaultOptions: function() {
  12685. this.callBase();
  12686. this.option({
  12687. center: {
  12688. lat: 0,
  12689. lng: 0
  12690. },
  12691. location: {
  12692. lat: 0,
  12693. lng: 0
  12694. },
  12695. width: 300,
  12696. height: 300,
  12697. zoom: 1,
  12698. type: "roadmap",
  12699. provider: "google",
  12700. autoAdjust: true,
  12701. markers: [],
  12702. markerIconSrc: null,
  12703. markerAddedAction: null,
  12704. markerRemovedAction: null,
  12705. routes: [],
  12706. routeAddedAction: null,
  12707. routeRemovedAction: null,
  12708. key: {
  12709. bing: "",
  12710. google: "",
  12711. googleStatic: ""
  12712. },
  12713. controls: false,
  12714. readyAction: null,
  12715. updateAction: null,
  12716. clickAction: null
  12717. })
  12718. },
  12719. _init: function() {
  12720. this._checkMarkersOption(this.option("markers"));
  12721. this._checkRoutesOption(this.option("routes"));
  12722. this.callBase();
  12723. this._initContainer();
  12724. this._grabEvents();
  12725. this._initProvider();
  12726. this._cleanRenderedMarkers();
  12727. this._cleanRenderedRoutes()
  12728. },
  12729. _cleanRenderedMarkers: function() {
  12730. this._renderedMarkers = []
  12731. },
  12732. _cleanRenderedRoutes: function(routes) {
  12733. this._renderedRoutes = []
  12734. },
  12735. _checkMarkersOption: function(markers) {
  12736. if (!$.isArray(markers))
  12737. throw new Error("Markers option should be an array");
  12738. },
  12739. _checkRoutesOption: function(routes) {
  12740. if (!$.isArray(routes))
  12741. throw new Error("Routes option should be an array");
  12742. },
  12743. _visibilityChanged: function(visible) {
  12744. if (visible)
  12745. this._dimensionChanged()
  12746. },
  12747. _dimensionChanged: function() {
  12748. this._execAsyncProviderAction("updateDimensions")
  12749. },
  12750. _initContainer: function() {
  12751. this._$container = $("<div />").addClass(MAP_CONTAINER_CLASS);
  12752. this._element().append(this._$container)
  12753. },
  12754. _grabEvents: function() {
  12755. var eventName = events.addNamespace("dxpointerdown", this.NAME);
  12756. this._element().on(eventName, $.proxy(this._cancelEvent, this))
  12757. },
  12758. _cancelEvent: function(e) {
  12759. var cancelByProvider = this._provider.cancelEvents && !this.option("disabled");
  12760. if (!DX.designMode && cancelByProvider)
  12761. e.stopPropagation()
  12762. },
  12763. _initProvider: function() {
  12764. var provider = this.option("provider");
  12765. if (winJS && this.option("provider") === "google")
  12766. throw new Error("Google provider cannot be used in winJS application");
  12767. this._cleanProvider();
  12768. this._provider = new providers[provider](this, this._$container);
  12769. this._mapLoader = this._provider.load()
  12770. },
  12771. _render: function() {
  12772. this.callBase();
  12773. this._element().addClass(MAP_CLASS);
  12774. this._renderShield();
  12775. this._execAsyncProviderAction("render").done($.proxy(function() {
  12776. this._saveRenderedMarkers();
  12777. this._saveRenderedRoutes()
  12778. }, this))
  12779. },
  12780. _saveRenderedMarkers: function(markers) {
  12781. markers = markers || this.option("markers");
  12782. this._renderedMarkers = markers.slice()
  12783. },
  12784. _saveRenderedRoutes: function(routes) {
  12785. routes = routes || this.option("routes");
  12786. this._renderedRoutes = routes.slice()
  12787. },
  12788. _renderShield: function() {
  12789. if (DX.designMode || this.option("disabled")) {
  12790. var $shield = $("<div/>").addClass(MAP_SHIELD_CLASS);
  12791. this._element().append($shield)
  12792. }
  12793. else {
  12794. var $shield = this._element().find("." + MAP_SHIELD_CLASS);
  12795. $shield.remove()
  12796. }
  12797. },
  12798. _clean: function() {
  12799. this._cleanProvider();
  12800. this._cleanRenderedMarkers();
  12801. this._cleanRenderedRoutes()
  12802. },
  12803. _cleanProvider: function() {
  12804. if (this._provider)
  12805. this._provider.clean()
  12806. },
  12807. _optionChanged: function(name, value, prevValue) {
  12808. if (this._cancelOptionChange)
  12809. return;
  12810. var notificationDeffered = this._notificationDeffered;
  12811. delete this._notificationDeffered;
  12812. switch (name) {
  12813. case"disabled":
  12814. this._renderShield();
  12815. this.callBase.apply(this, arguments);
  12816. break;
  12817. case"width":
  12818. case"height":
  12819. this.callBase.apply(this, arguments);
  12820. this._dimensionChanged();
  12821. break;
  12822. case"type":
  12823. this._execAsyncProviderAction("updateMapType");
  12824. break;
  12825. case"center":
  12826. this._execAsyncProviderAction("updateCenter");
  12827. break;
  12828. case"zoom":
  12829. this._execAsyncProviderAction("updateZoom");
  12830. break;
  12831. case"controls":
  12832. this._execAsyncProviderAction("updateControls");
  12833. break;
  12834. case"markers":
  12835. this._checkMarkersOption(value);
  12836. this._execAsyncProviderAction("updateMarkers", $.proxy(function() {
  12837. return notificationDeffered ? removeDublicates(this._renderedMarkers, value) : this._renderedMarkers
  12838. }, this), $.proxy(function() {
  12839. return notificationDeffered ? removeDublicates(value, this._renderedMarkers) : value
  12840. }, this)).done($.proxy(function() {
  12841. this._saveRenderedMarkers(value);
  12842. if (notificationDeffered)
  12843. notificationDeffered.resolve.apply(notificationDeffered, arguments)
  12844. }, this));
  12845. break;
  12846. case"markerIconSrc":
  12847. this._execAsyncProviderAction("updateMarkers", prevValue, value);
  12848. break;
  12849. case"autoAdjust":
  12850. this._execAsyncProviderAction("adjustViewport");
  12851. break;
  12852. case"routes":
  12853. this._checkRoutesOption(value);
  12854. this._execAsyncProviderAction("updateRoutes", $.proxy(function() {
  12855. return notificationDeffered ? removeDublicates(this._renderedRoutes, value) : this._renderedRoutes
  12856. }, this), $.proxy(function() {
  12857. return notificationDeffered ? removeDublicates(value, this._renderedRoutes) : value
  12858. }, this)).done($.proxy(function() {
  12859. this._saveRenderedRoutes(value);
  12860. if (notificationDeffered)
  12861. notificationDeffered.resolve.apply(notificationDeffered, arguments)
  12862. }, this));
  12863. break;
  12864. case"key":
  12865. utils.logger.warn("Key option can not be modified after initialization");
  12866. case"provider":
  12867. this._initProvider();
  12868. this._invalidate();
  12869. break;
  12870. case"readyAction":
  12871. case"updateAction":
  12872. case"markerAddedAction":
  12873. case"markerRemovedAction":
  12874. case"routeAddedAction":
  12875. case"routeRemovedAction":
  12876. case"clickAction":
  12877. break;
  12878. default:
  12879. this.callBase.apply(this, arguments)
  12880. }
  12881. },
  12882. _execAsyncProviderAction: function(name) {
  12883. if (!this._provider.mapRendered() && !(name === "render"))
  12884. return $.when(undefined).promise();
  12885. var deferred = $.Deferred(),
  12886. that = this,
  12887. options = $.makeArray(arguments).slice(1);
  12888. $.when(this._mapLoader).done(function() {
  12889. var provider = that._provider;
  12890. $.each(options, function(index, option) {
  12891. if ($.isFunction(option))
  12892. options[index] = option()
  12893. });
  12894. provider[name].apply(provider, options).done(function(mapRefreshed) {
  12895. deferred.resolve.apply(deferred, $.makeArray(arguments).slice(1));
  12896. if (mapRefreshed)
  12897. that._triggerReadyAction();
  12898. else
  12899. that._triggerUpdateAction()
  12900. })
  12901. });
  12902. return deferred.promise()
  12903. },
  12904. _triggerReadyAction: function() {
  12905. this._createActionByOption("readyAction")({originalMap: this._provider.map()})
  12906. },
  12907. _triggerUpdateAction: function() {
  12908. this._createActionByOption("updateAction")()
  12909. },
  12910. setOptionSilent: function(name, value) {
  12911. this._cancelOptionChange = true;
  12912. this.option(name, value);
  12913. this._cancelOptionChange = false
  12914. }
  12915. }))
  12916. })(jQuery, DevExpress);
  12917. /*! Module widgets-base, file ui.map.bing.js */
  12918. (function($, DX, undefined) {
  12919. var ui = DX.ui,
  12920. winJS = DX.support.winJS;
  12921. var BING_MAP_READY = "_bingScriptReady",
  12922. BING_URL = "https://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0&s=1&onScriptLoad=" + BING_MAP_READY,
  12923. BING_LOCAL_FILES1 = "ms-appx:///Bing.Maps.JavaScript/js/veapicore.js",
  12924. BING_LOCAL_FILES2 = "ms-appx:///Bing.Maps.JavaScript/js/veapiModules.js",
  12925. BING_CREDENTIALS = "AhuxC0dQ1DBTNo8L-H9ToVMQStmizZzBJdraTSgCzDSWPsA1Qd8uIvFSflzxdaLH",
  12926. MIN_LOCATION_RECT_LENGTH = 0.0000000000000001;
  12927. var msMapsLoader;
  12928. ui.registerMapProvider("bing", ui.MapProvider.inherit({
  12929. _mapType: function(type) {
  12930. var mapTypes = {
  12931. roadmap: Microsoft.Maps.MapTypeId.road,
  12932. hybrid: Microsoft.Maps.MapTypeId.aerial
  12933. };
  12934. return mapTypes[type] || mapTypes.roadmap
  12935. },
  12936. _movementMode: function(type) {
  12937. var movementTypes = {
  12938. driving: Microsoft.Maps.Directions.RouteMode.driving,
  12939. walking: Microsoft.Maps.Directions.RouteMode.walking
  12940. };
  12941. return movementTypes[type] || movementTypes.driving
  12942. },
  12943. _resolveLocation: function(location) {
  12944. var d = $.Deferred();
  12945. if (typeof location === "string") {
  12946. var searchManager = new Microsoft.Maps.Search.SearchManager(this._map);
  12947. var searchRequest = {
  12948. where: location,
  12949. count: 1,
  12950. callback: function(searchResponse) {
  12951. var boundsBox = searchResponse.results[0].location;
  12952. d.resolve(new Microsoft.Maps.Location(boundsBox.latitude, boundsBox.longitude))
  12953. }
  12954. };
  12955. searchManager.geocode(searchRequest)
  12956. }
  12957. else if ($.isPlainObject(location) && $.isNumeric(location.lat) && $.isNumeric(location.lng))
  12958. d.resolve(new Microsoft.Maps.Location(location.lat, location.lng));
  12959. else if ($.isArray(location))
  12960. d.resolve(new Microsoft.Maps.Location(location[0], location[1]));
  12961. return d.promise()
  12962. },
  12963. _normalizeLocation: function(location) {
  12964. return {
  12965. lat: location.latitude,
  12966. lng: location.longitude
  12967. }
  12968. },
  12969. load: function() {
  12970. if (!msMapsLoader) {
  12971. msMapsLoader = $.Deferred();
  12972. window[BING_MAP_READY] = $.proxy(this._mapReady, this);
  12973. if (winJS)
  12974. $.when($.getScript(BING_LOCAL_FILES1), $.getScript(BING_LOCAL_FILES2)).done(function() {
  12975. Microsoft.Maps.loadModule("Microsoft.Maps.Map", {callback: window[BING_MAP_READY]})
  12976. });
  12977. else
  12978. $.getScript(BING_URL)
  12979. }
  12980. this._markers = [];
  12981. this._routes = [];
  12982. return msMapsLoader
  12983. },
  12984. _mapReady: function() {
  12985. try {
  12986. delete window[BING_MAP_READY]
  12987. }
  12988. catch(e) {
  12989. window[BING_MAP_READY] = undefined
  12990. }
  12991. var searchModulePromise = $.Deferred();
  12992. var directionsModulePromise = $.Deferred();
  12993. Microsoft.Maps.loadModule('Microsoft.Maps.Search', {callback: $.proxy(searchModulePromise.resolve, searchModulePromise)});
  12994. Microsoft.Maps.loadModule('Microsoft.Maps.Directions', {callback: $.proxy(directionsModulePromise.resolve, directionsModulePromise)});
  12995. $.when(searchModulePromise, directionsModulePromise).done(function() {
  12996. msMapsLoader.resolve()
  12997. })
  12998. },
  12999. _renderImpl: function() {
  13000. var deferred = $.Deferred(),
  13001. initPromise = $.Deferred(),
  13002. controls = this._option("controls");
  13003. var options = {
  13004. credentials: this._keyOption("bing") || BING_CREDENTIALS,
  13005. mapTypeId: this._mapType(this._option("type")),
  13006. zoom: this._option("zoom"),
  13007. showDashboard: controls,
  13008. showMapTypeSelector: controls,
  13009. showScalebar: controls
  13010. };
  13011. this._map = new Microsoft.Maps.Map(this._$container[0], options);
  13012. var handler = Microsoft.Maps.Events.addHandler(this._map, 'tiledownloadcomplete', $.proxy(initPromise.resolve, initPromise));
  13013. this._viewChangeHandler = Microsoft.Maps.Events.addHandler(this._map, 'viewchange', $.proxy(this._handleViewChange, this));
  13014. this._clickHandler = Microsoft.Maps.Events.addHandler(this._map, 'click', $.proxy(this._handleClickAction, this));
  13015. var locationPromise = this._renderCenter();
  13016. $.when(initPromise, locationPromise).done(function() {
  13017. Microsoft.Maps.Events.removeHandler(handler);
  13018. deferred.resolve()
  13019. });
  13020. return deferred.promise()
  13021. },
  13022. _handleViewChange: function() {
  13023. var center = this._map.getCenter();
  13024. this._option("center", this._normalizeLocation(center));
  13025. if (!this._preventZoomChangeEvent)
  13026. this._option("zoom", this._map.getZoom())
  13027. },
  13028. updateDimensions: function() {
  13029. this._map.setOptions({
  13030. width: this._$container.width(),
  13031. height: this._$container.height()
  13032. });
  13033. return $.Deferred().resolve().promise()
  13034. },
  13035. updateMapType: function() {
  13036. this._map.setView({mapTypeId: this._mapType(this._option("type"))});
  13037. return $.Deferred().resolve().promise()
  13038. },
  13039. updateCenter: function() {
  13040. return this._renderCenter()
  13041. },
  13042. _renderCenter: function() {
  13043. var deferred = $.Deferred(),
  13044. that = this;
  13045. this._resolveLocation(this._option("center")).done(function(location) {
  13046. that._map.setView({
  13047. animate: false,
  13048. center: location
  13049. });
  13050. deferred.resolve()
  13051. });
  13052. return deferred.promise()
  13053. },
  13054. updateZoom: function() {
  13055. this._map.setView({
  13056. animate: false,
  13057. zoom: this._option("zoom")
  13058. });
  13059. return $.Deferred().resolve().promise()
  13060. },
  13061. updateControls: function() {
  13062. this.clean();
  13063. return this.render()
  13064. },
  13065. addMarkers: function(options) {
  13066. var deferred = $.Deferred(),
  13067. that = this;
  13068. var markerPromises = $.map(options, function(options) {
  13069. return that._addMarker(options)
  13070. });
  13071. $.when.apply($, markerPromises).done(function() {
  13072. var instances = $.map($.makeArray(arguments), function(markerObject) {
  13073. return markerObject.pushpin
  13074. });
  13075. deferred.resolve(false, instances)
  13076. });
  13077. return deferred.promise()
  13078. },
  13079. _addMarker: function(options) {
  13080. var that = this;
  13081. return this._renderMarker(options).done(function(markerObject) {
  13082. that._markers.push($.extend({options: options}, markerObject));
  13083. that._updateMarkersBounds();
  13084. that._fitBounds();
  13085. that._fireMarkerAddedAction({
  13086. options: options,
  13087. originalMarker: markerObject.pushpin
  13088. })
  13089. })
  13090. },
  13091. _renderMarker: function(options) {
  13092. var d = $.Deferred(),
  13093. that = this;
  13094. this._resolveLocation(options.location).done(function(location) {
  13095. var pushpin = new Microsoft.Maps.Pushpin(location, {icon: options.iconSrc || that._option("markerIconSrc")});
  13096. that._map.entities.push(pushpin);
  13097. var infobox = that._renderTooltip(location, options.tooltip);
  13098. var handler;
  13099. if (options.clickAction || options.tooltip) {
  13100. var markerClickAction = that._createAction(options.clickAction || $.noop),
  13101. markerNormalizedLocation = that._normalizeLocation(location);
  13102. handler = Microsoft.Maps.Events.addHandler(pushpin, "click", function() {
  13103. markerClickAction({location: markerNormalizedLocation});
  13104. if (infobox)
  13105. infobox.setOptions({visible: true})
  13106. })
  13107. }
  13108. d.resolve({
  13109. location: location,
  13110. pushpin: pushpin,
  13111. infobox: infobox,
  13112. handler: handler
  13113. })
  13114. });
  13115. return d.promise()
  13116. },
  13117. _renderTooltip: function(location, options) {
  13118. if (!options)
  13119. return;
  13120. options = this._parseTooltipOptions(options);
  13121. var infobox = new Microsoft.Maps.Infobox(location, {
  13122. description: options.text,
  13123. offset: new Microsoft.Maps.Point(0, 33),
  13124. visible: options.visible
  13125. });
  13126. this._map.entities.push(infobox, null);
  13127. return infobox
  13128. },
  13129. removeMarkers: function(options) {
  13130. var that = this;
  13131. $.each(options, function(_, options) {
  13132. that._removeMarker(options)
  13133. });
  13134. return $.Deferred().resolve().promise()
  13135. },
  13136. _removeMarker: function(options) {
  13137. var that = this;
  13138. $.each(this._markers, function(markerIndex, markerObject) {
  13139. if (markerObject.options !== options)
  13140. return true;
  13141. var marker = that._markers[markerIndex];
  13142. that._map.entities.remove(marker.pushpin);
  13143. if (marker.infobox)
  13144. that._map.entities.remove(marker.infobox);
  13145. if (marker.handler)
  13146. Microsoft.Maps.Events.removeHandler(marker.handler);
  13147. that._markers.splice(markerIndex, 1);
  13148. that._updateMarkersBounds();
  13149. that._fitBounds();
  13150. that._fireMarkerRemovedAction({options: options});
  13151. return false
  13152. })
  13153. },
  13154. _updateMarkersBounds: function() {
  13155. var that = this;
  13156. this._clearBounds();
  13157. $.each(this._markers, function(_, markerObject) {
  13158. that._extendBounds(markerObject.location)
  13159. })
  13160. },
  13161. _clearMarkers: function() {
  13162. for (var i = 0; this._markers.length > 0; )
  13163. this._removeMarker(this._markers[0].options)
  13164. },
  13165. adjustViewport: function() {
  13166. return this._fitBounds()
  13167. },
  13168. _clearBounds: function() {
  13169. this._bounds = null
  13170. },
  13171. _extendBounds: function(location) {
  13172. if (this._bounds)
  13173. this._bounds = new Microsoft.Maps.LocationRect.fromLocations(this._bounds.getNorthwest(), this._bounds.getSoutheast(), location);
  13174. else
  13175. this._bounds = new Microsoft.Maps.LocationRect(location, MIN_LOCATION_RECT_LENGTH, MIN_LOCATION_RECT_LENGTH)
  13176. },
  13177. _fitBounds: function() {
  13178. var autoAdjust = this._option("autoAdjust");
  13179. if (this._bounds && autoAdjust) {
  13180. var zoomBeforeFitting = this._map.getZoom();
  13181. this._preventZoomChangeEvent = true;
  13182. var bounds = this._bounds.clone();
  13183. bounds.height = bounds.height * 1.1;
  13184. bounds.width = bounds.width * 1.1;
  13185. this._map.setView({
  13186. animate: false,
  13187. bounds: bounds
  13188. });
  13189. var zoomAfterFitting = this._map.getZoom();
  13190. if (zoomBeforeFitting < zoomAfterFitting)
  13191. this._map.setView({
  13192. animate: false,
  13193. zoom: zoomBeforeFitting
  13194. });
  13195. else
  13196. this._option("zoom", zoomAfterFitting);
  13197. delete this._preventZoomChangeEvent
  13198. }
  13199. return $.Deferred().resolve().promise()
  13200. },
  13201. addRoutes: function(options) {
  13202. var deferred = $.Deferred(),
  13203. that = this;
  13204. var routePromises = $.map(options, function(options) {
  13205. return that._addRoute(options)
  13206. });
  13207. $.when.apply($, routePromises).done(function() {
  13208. deferred.resolve(false, $.makeArray(arguments))
  13209. });
  13210. return deferred.promise()
  13211. },
  13212. _addRoute: function(options) {
  13213. var that = this;
  13214. return this._renderRoute(options).done(function(instance) {
  13215. that._routes.push({
  13216. options: options,
  13217. instance: instance
  13218. });
  13219. that._fireRouteAddedAction({
  13220. options: options,
  13221. originalRoute: instance
  13222. })
  13223. })
  13224. },
  13225. _renderRoute: function(options) {
  13226. var d = $.Deferred(),
  13227. that = this;
  13228. var points = $.map(options.locations, function(point) {
  13229. return that._resolveLocation(point)
  13230. });
  13231. $.when.apply($, points).done(function() {
  13232. var locations = $.makeArray(arguments),
  13233. direction = new Microsoft.Maps.Directions.DirectionsManager(that._map),
  13234. color = new DX.Color(options.color || that._defaultRouteColor()).toHex(),
  13235. routeColor = new Microsoft.Maps.Color.fromHex(color);
  13236. routeColor.a = (options.opacity || that._defaultRouteOpacity()) * 255;
  13237. direction.setRenderOptions({
  13238. autoUpdateMapView: false,
  13239. displayRouteSelector: false,
  13240. waypointPushpinOptions: {visible: false},
  13241. drivingPolylineOptions: {
  13242. strokeColor: routeColor,
  13243. strokeThickness: options.weight || that._defaultRouteWeight()
  13244. },
  13245. walkingPolylineOptions: {
  13246. strokeColor: routeColor,
  13247. strokeThickness: options.weight || that._defaultRouteWeight()
  13248. }
  13249. });
  13250. direction.setRequestOptions({
  13251. routeMode: that._movementMode(options.mode),
  13252. routeDraggable: false
  13253. });
  13254. $.each(locations, function(_, location) {
  13255. var waypoint = new Microsoft.Maps.Directions.Waypoint({location: location});
  13256. direction.addWaypoint(waypoint)
  13257. });
  13258. var handler = Microsoft.Maps.Events.addHandler(direction, 'directionsUpdated', function() {
  13259. Microsoft.Maps.Events.removeHandler(handler);
  13260. d.resolve(direction)
  13261. });
  13262. direction.calculateDirections()
  13263. });
  13264. return d.promise()
  13265. },
  13266. removeRoutes: function(options) {
  13267. var that = this;
  13268. $.each(options, function(routeIndex, options) {
  13269. that._removeRoute(options)
  13270. });
  13271. return $.Deferred().resolve().promise()
  13272. },
  13273. _removeRoute: function(options) {
  13274. var that = this;
  13275. $.each(this._routes, function(routeIndex, routeObject) {
  13276. if (routeObject.options !== options)
  13277. return true;
  13278. that._routes[routeIndex].instance.dispose();
  13279. that._routes.splice(routeIndex, 1);
  13280. that._fireRouteRemovedAction({options: options});
  13281. return false
  13282. })
  13283. },
  13284. _clearRoutes: function() {
  13285. for (var i = 0; this._routes.length > 0; )
  13286. this._removeRoute(this._routes[0].options)
  13287. },
  13288. _handleClickAction: function(e) {
  13289. if (e.targetType == "map") {
  13290. var point = new Microsoft.Maps.Point(e.getX(), e.getY()),
  13291. location = e.target.tryPixelToLocation(point);
  13292. this._fireClickAction({location: this._normalizeLocation(location)})
  13293. }
  13294. },
  13295. clean: function() {
  13296. if (this._map) {
  13297. Microsoft.Maps.Events.removeHandler(this._viewChangeHandler);
  13298. Microsoft.Maps.Events.removeHandler(this._clickHandler);
  13299. this._clearMarkers();
  13300. this._clearRoutes();
  13301. this._map.dispose()
  13302. }
  13303. },
  13304. cancelEvents: true
  13305. }));
  13306. if (!ui.dxMap.__internals)
  13307. ui.dxMap.__internals = {};
  13308. $.extend(ui.dxMap.__internals, {remapBingConstant: function(newValue) {
  13309. BING_URL = newValue
  13310. }})
  13311. })(jQuery, DevExpress);
  13312. /*! Module widgets-base, file ui.map.google.js */
  13313. (function($, DX, undefined) {
  13314. var ui = DX.ui;
  13315. var GOOGLE_MAP_READY = "_googleScriptReady",
  13316. GOOGLE_URL = "https://maps.google.com/maps/api/js?v=3.9&sensor=false&callback=" + GOOGLE_MAP_READY;
  13317. var googleMapsLoader;
  13318. ui.registerMapProvider("google", ui.MapProvider.inherit({
  13319. _mapType: function(type) {
  13320. var mapTypes = {
  13321. hybrid: google.maps.MapTypeId.HYBRID,
  13322. roadmap: google.maps.MapTypeId.ROADMAP
  13323. };
  13324. return mapTypes[type] || mapTypes.hybrid
  13325. },
  13326. _movementMode: function(type) {
  13327. var movementTypes = {
  13328. driving: google.maps.TravelMode.DRIVING,
  13329. walking: google.maps.TravelMode.WALKING
  13330. };
  13331. return movementTypes[type] || movementTypes.driving
  13332. },
  13333. _resolveLocation: function(location) {
  13334. var d = $.Deferred();
  13335. if (typeof location === "string") {
  13336. var geocoder = new google.maps.Geocoder;
  13337. geocoder.geocode({address: location}, function(results, status) {
  13338. if (status === google.maps.GeocoderStatus.OK)
  13339. d.resolve(results[0].geometry.location)
  13340. })
  13341. }
  13342. else if ($.isArray(location))
  13343. d.resolve(new google.maps.LatLng(location[0], location[1]));
  13344. else if ($.isPlainObject(location) && $.isNumeric(location.lat) && $.isNumeric(location.lng))
  13345. d.resolve(new google.maps.LatLng(location.lat, location.lng));
  13346. return d.promise()
  13347. },
  13348. _normalizeLocation: function(location) {
  13349. return {
  13350. lat: location.lat(),
  13351. lng: location.lng()
  13352. }
  13353. },
  13354. load: function() {
  13355. if (!googleMapsLoader) {
  13356. googleMapsLoader = $.Deferred();
  13357. var key = this._keyOption("google");
  13358. window[GOOGLE_MAP_READY] = $.proxy(this._mapReady, this);
  13359. $.getScript(GOOGLE_URL + (key ? "&key=" + key : ""))
  13360. }
  13361. this._markers = [];
  13362. this._routes = [];
  13363. return googleMapsLoader.promise()
  13364. },
  13365. _mapReady: function() {
  13366. try {
  13367. delete window[GOOGLE_MAP_READY]
  13368. }
  13369. catch(e) {
  13370. window[GOOGLE_MAP_READY] = undefined
  13371. }
  13372. googleMapsLoader.resolve()
  13373. },
  13374. _renderImpl: function() {
  13375. var deferred = $.Deferred(),
  13376. initPromise = $.Deferred(),
  13377. controls = this._option("controls");
  13378. var options = {
  13379. zoom: this._option("zoom"),
  13380. center: new google.maps.LatLng(0, 0),
  13381. mapTypeId: this._mapType(this._option("type")),
  13382. panControl: controls,
  13383. zoomControl: controls,
  13384. mapTypeControl: controls,
  13385. streetViewControl: controls
  13386. };
  13387. this._map = new google.maps.Map(this._$container[0], options);
  13388. var listner = google.maps.event.addListener(this._map, 'idle', $.proxy(initPromise.resolve, initPromise));
  13389. this._zoomChangeListener = google.maps.event.addListener(this._map, 'zoom_changed', $.proxy(this._handleZoomChange, this));
  13390. this._centerChangeListener = google.maps.event.addListener(this._map, 'center_changed', $.proxy(this._handleCenterChange, this));
  13391. this._clickListener = google.maps.event.addListener(this._map, 'click', $.proxy(this._handleClickAction, this));
  13392. var locationPromise = this._renderCenter();
  13393. $.when(initPromise, locationPromise).done(function() {
  13394. google.maps.event.removeListener(listner);
  13395. deferred.resolve()
  13396. });
  13397. return deferred.promise()
  13398. },
  13399. updateDimensions: function() {
  13400. google.maps.event.trigger(this._map, 'resize');
  13401. return $.Deferred().resolve().promise()
  13402. },
  13403. updateMapType: function() {
  13404. this._map.setMapTypeId(this._mapType(this._option("type")));
  13405. return $.Deferred().resolve().promise()
  13406. },
  13407. updateCenter: function() {
  13408. return this._renderCenter()
  13409. },
  13410. _handleCenterChange: function() {
  13411. var center = this._map.getCenter();
  13412. this._option("center", this._normalizeLocation(center))
  13413. },
  13414. _renderCenter: function() {
  13415. var deferred = $.Deferred(),
  13416. that = this;
  13417. this._resolveLocation(this._option("center")).done(function(location) {
  13418. that._map.setCenter(location);
  13419. deferred.resolve()
  13420. });
  13421. return deferred.promise()
  13422. },
  13423. _handleZoomChange: function() {
  13424. if (!this._preventZoomChangeEvent)
  13425. this._option("zoom", this._map.getZoom())
  13426. },
  13427. updateZoom: function() {
  13428. this._map.setZoom(this._option("zoom"));
  13429. return $.Deferred().resolve().promise()
  13430. },
  13431. updateControls: function() {
  13432. var controls = this._option("controls");
  13433. this._map.setOptions({
  13434. panControl: controls,
  13435. zoomControl: controls,
  13436. mapTypeControl: controls,
  13437. streetViewControl: controls
  13438. });
  13439. return $.Deferred().resolve().promise()
  13440. },
  13441. addMarkers: function(options) {
  13442. var deferred = $.Deferred(),
  13443. that = this;
  13444. var markerPromises = $.map(options, function(options) {
  13445. return that._addMarker(options)
  13446. });
  13447. $.when.apply($, markerPromises).done(function() {
  13448. var instances = $.map($.makeArray(arguments), function(markerObject) {
  13449. return markerObject.marker
  13450. });
  13451. deferred.resolve(false, instances)
  13452. });
  13453. return deferred.promise()
  13454. },
  13455. _addMarker: function(options) {
  13456. var that = this;
  13457. return this._renderMarker(options).done(function(markerObject) {
  13458. that._markers.push($.extend({options: options}, markerObject));
  13459. that._updateMarkersBounds();
  13460. that._fitBounds();
  13461. that._fireMarkerAddedAction({
  13462. options: options,
  13463. originalMarker: markerObject.marker
  13464. })
  13465. })
  13466. },
  13467. _renderMarker: function(options) {
  13468. var d = $.Deferred(),
  13469. that = this;
  13470. this._resolveLocation(options.location).done(function(location) {
  13471. var marker = new google.maps.Marker({
  13472. position: location,
  13473. map: that._map,
  13474. icon: options.iconSrc || that._option("markerIconSrc")
  13475. }),
  13476. listner;
  13477. var infoWindow = that._renderTooltip(marker, options.tooltip);
  13478. if (options.clickAction || options.tooltip) {
  13479. var markerClickAction = that._createAction(options.clickAction || $.noop),
  13480. markerNormalizedLocation = that._normalizeLocation(location);
  13481. listner = google.maps.event.addListener(marker, "click", function() {
  13482. markerClickAction({location: markerNormalizedLocation});
  13483. if (infoWindow)
  13484. infoWindow.open(that._map, marker)
  13485. })
  13486. }
  13487. d.resolve({
  13488. location: location,
  13489. marker: marker,
  13490. listner: listner
  13491. })
  13492. });
  13493. return d.promise()
  13494. },
  13495. _renderTooltip: function(marker, options) {
  13496. if (!options)
  13497. return;
  13498. options = this._parseTooltipOptions(options);
  13499. var infoWindow = new google.maps.InfoWindow({content: options.text});
  13500. if (options.visible)
  13501. infoWindow.open(this._map, marker);
  13502. return infoWindow
  13503. },
  13504. removeMarkers: function(markersOptionsToRemove) {
  13505. var that = this;
  13506. $.each(markersOptionsToRemove, function(_, markerOptionToRemove) {
  13507. that._removeMarker(markerOptionToRemove)
  13508. });
  13509. return $.Deferred().resolve().promise()
  13510. },
  13511. _removeMarker: function(markersOptionToRemove) {
  13512. var that = this;
  13513. $.each(this._markers, function(markerIndex, markerObject) {
  13514. if (markerObject.options !== markersOptionToRemove)
  13515. return true;
  13516. var marker = that._markers[markerIndex];
  13517. marker.marker.setMap(null);
  13518. if (marker.listner)
  13519. google.maps.event.removeListener(marker.listner);
  13520. that._markers.splice(markerIndex, 1);
  13521. that._updateMarkersBounds();
  13522. that._fitBounds();
  13523. that._fireMarkerRemovedAction({options: markerObject.options});
  13524. return false
  13525. })
  13526. },
  13527. _updateMarkersBounds: function() {
  13528. var that = this;
  13529. this._clearBounds();
  13530. $.each(this._markers, function(_, markerObject) {
  13531. that._extendBounds(markerObject.location)
  13532. })
  13533. },
  13534. _clearMarkers: function() {
  13535. for (var i = 0; this._markers.length > 0; )
  13536. this._removeMarker(this._markers[0].options)
  13537. },
  13538. adjustViewport: function() {
  13539. return this._fitBounds()
  13540. },
  13541. _extendBounds: function(location) {
  13542. if (this._bounds)
  13543. this._bounds.extend(location);
  13544. else {
  13545. this._bounds = new google.maps.LatLngBounds;
  13546. this._bounds.extend(location)
  13547. }
  13548. },
  13549. _fitBounds: function() {
  13550. var autoAdjust = this._option("autoAdjust");
  13551. if (this._bounds && autoAdjust) {
  13552. var zoomBeforeFitting = this._map.getZoom();
  13553. this._preventZoomChangeEvent = true;
  13554. this._map.fitBounds(this._bounds);
  13555. var zoomAfterFitting = this._map.getZoom();
  13556. if (zoomBeforeFitting < zoomAfterFitting)
  13557. this._map.setZoom(zoomBeforeFitting);
  13558. else
  13559. this._option("zoom", zoomAfterFitting);
  13560. delete this._preventZoomChangeEvent
  13561. }
  13562. return $.Deferred().resolve().promise()
  13563. },
  13564. _clearBounds: function() {
  13565. this._bounds = null
  13566. },
  13567. addRoutes: function(options) {
  13568. var deferred = $.Deferred(),
  13569. that = this;
  13570. var routePromises = $.map(options, function(options) {
  13571. return that._addRoute(options)
  13572. });
  13573. $.when.apply($, routePromises).done(function() {
  13574. deferred.resolve(false, $.makeArray(arguments))
  13575. });
  13576. return deferred.promise()
  13577. },
  13578. _addRoute: function(options) {
  13579. var that = this;
  13580. return this._renderRoute(options).done(function(instance) {
  13581. that._routes.push({
  13582. options: options,
  13583. instance: instance
  13584. });
  13585. that._fireRouteAddedAction({
  13586. options: options,
  13587. originalRoute: instance
  13588. })
  13589. })
  13590. },
  13591. _renderRoute: function(options) {
  13592. var d = $.Deferred(),
  13593. that = this,
  13594. directionsService = new google.maps.DirectionsService;
  13595. var points = $.map(options.locations, function(point) {
  13596. return that._resolveLocation(point)
  13597. });
  13598. $.when.apply($, points).done(function() {
  13599. var locations = $.makeArray(arguments),
  13600. origin = locations.shift(),
  13601. destination = locations.pop(),
  13602. waypoints = $.map(locations, function(location) {
  13603. return {
  13604. location: location,
  13605. stopover: true
  13606. }
  13607. });
  13608. var request = {
  13609. origin: origin,
  13610. destination: destination,
  13611. waypoints: waypoints,
  13612. optimizeWaypoints: true,
  13613. travelMode: that._movementMode(options.mode)
  13614. };
  13615. directionsService.route(request, function(response, status) {
  13616. if (status === google.maps.DirectionsStatus.OK) {
  13617. var color = new DX.Color(options.color || that._defaultRouteColor()).toHex(),
  13618. directionOptions = {
  13619. directions: response,
  13620. map: that._map,
  13621. suppressMarkers: true,
  13622. preserveViewport: true,
  13623. polylineOptions: {
  13624. strokeWeight: options.weight || that._defaultRouteWeight(),
  13625. strokeOpacity: options.opacity || that._defaultRouteOpacity(),
  13626. strokeColor: color
  13627. }
  13628. };
  13629. var route = new google.maps.DirectionsRenderer(directionOptions);
  13630. d.resolve(route)
  13631. }
  13632. })
  13633. });
  13634. return d.promise()
  13635. },
  13636. removeRoutes: function(options) {
  13637. var that = this;
  13638. $.each(options, function(routeIndex, options) {
  13639. that._removeRoute(options)
  13640. });
  13641. return $.Deferred().resolve().promise()
  13642. },
  13643. _removeRoute: function(options) {
  13644. var that = this;
  13645. $.each(this._routes, function(routeIndex, routeObject) {
  13646. if (routeObject.options !== options)
  13647. return true;
  13648. that._routes[routeIndex].instance.setMap(null);
  13649. that._routes.splice(routeIndex, 1);
  13650. that._fireRouteRemovedAction({options: options});
  13651. return false
  13652. })
  13653. },
  13654. _clearRoutes: function() {
  13655. for (var i = 0; this._routes.length > 0; )
  13656. this._removeRoute(this._routes[0].options)
  13657. },
  13658. _handleClickAction: function(e) {
  13659. this._fireClickAction({location: this._normalizeLocation(e.latLng)})
  13660. },
  13661. clean: function() {
  13662. if (this._map) {
  13663. google.maps.event.removeListener(this._zoomChangeListener);
  13664. google.maps.event.removeListener(this._centerChangeListener);
  13665. google.maps.event.removeListener(this._clickListener);
  13666. this._clearMarkers();
  13667. this._clearRoutes();
  13668. delete this._map;
  13669. this._$container.empty()
  13670. }
  13671. },
  13672. cancelEvents: true
  13673. }));
  13674. if (!ui.dxMap.__internals)
  13675. ui.dxMap.__internals = {};
  13676. $.extend(ui.dxMap.__internals, {remapGoogleConstant: function(newValue) {
  13677. GOOGLE_URL = newValue
  13678. }})
  13679. })(jQuery, DevExpress);
  13680. /*! Module widgets-base, file ui.map.googleStatic.js */
  13681. (function($, DX, undefined) {
  13682. var ui = DX.ui;
  13683. var GOOGLE_STATIC_URL = "https://maps.google.com/maps/api/staticmap?";
  13684. ui.registerMapProvider("googleStatic", ui.MapProvider.inherit({
  13685. _locationToString: function(location) {
  13686. return !$.isPlainObject(location) ? location.toString().replace(/ /g, "+") : location.lat + "," + location.lng
  13687. },
  13688. _renderImpl: function() {
  13689. return this._updateMap()
  13690. },
  13691. updateDimensions: function() {
  13692. return this._updateMap()
  13693. },
  13694. updateMapType: function() {
  13695. return this._updateMap()
  13696. },
  13697. updateCenter: function() {
  13698. return this._updateMap()
  13699. },
  13700. updateZoom: function() {
  13701. return this._updateMap()
  13702. },
  13703. updateControls: function() {
  13704. return $.Deferred().resolve().promise()
  13705. },
  13706. addMarkers: function(options) {
  13707. var that = this;
  13708. return this._updateMap().done(function() {
  13709. $.each(options, function(_, options) {
  13710. that._fireMarkerAddedAction({options: options})
  13711. })
  13712. })
  13713. },
  13714. removeMarkers: function(options) {
  13715. var that = this;
  13716. return this._updateMap().done(function() {
  13717. $.each(options, function(_, options) {
  13718. that._fireMarkerRemovedAction({options: options})
  13719. })
  13720. })
  13721. },
  13722. adjustViewport: function() {
  13723. return $.Deferred().resolve().promise()
  13724. },
  13725. addRoutes: function(options) {
  13726. var that = this;
  13727. return this._updateMap().done(function() {
  13728. $.each(options, function(_, options) {
  13729. that._fireRouteAddedAction({options: options})
  13730. })
  13731. })
  13732. },
  13733. removeRoutes: function(options) {
  13734. var that = this;
  13735. return this._updateMap().done(function() {
  13736. $.each(options, function(_, options) {
  13737. that._fireRouteRemovedAction({options: options})
  13738. })
  13739. })
  13740. },
  13741. clean: function() {
  13742. this._$container.css("background-image", "none");
  13743. this._$container.off(this._addEventNamespace("dxclick"))
  13744. },
  13745. mapRendered: function() {
  13746. return true
  13747. },
  13748. _updateMap: function() {
  13749. var key = this._keyOption("googleStatic");
  13750. var requestOptions = ["sensor=false", "size=" + this._option("width") + "x" + this._option("height"), "maptype=" + this._option("type"), "center=" + this._locationToString(this._option("center")), "zoom=" + this._option("zoom"), this._markersSubstring()];
  13751. requestOptions.push.apply(requestOptions, this._routeSubstrings());
  13752. if (key)
  13753. requestOptions.push("key=" + key);
  13754. var request = GOOGLE_STATIC_URL + requestOptions.join("&");
  13755. this._$container.css("background", "url(\"" + request + "\") no-repeat 0 0");
  13756. this._attachClickEvent();
  13757. return $.Deferred().resolve(true).promise()
  13758. },
  13759. _markersSubstring: function() {
  13760. var that = this,
  13761. markers = [],
  13762. markerIcon = this._option("markerIconSrc");
  13763. if (markerIcon)
  13764. markers.push("icon:" + markerIcon);
  13765. $.each(this._option("markers"), function(_, marker) {
  13766. markers.push(that._locationToString(marker.location))
  13767. });
  13768. return "markers=" + markers.join("|")
  13769. },
  13770. _routeSubstrings: function() {
  13771. var that = this,
  13772. routes = [];
  13773. $.each(this._option("routes"), function(_, route) {
  13774. var color = new DX.Color(route.color || that._defaultRouteColor()).toHex().replace('#', '0x'),
  13775. opacity = Math.round((route.opacity || that._defaultRouteOpacity()) * 255).toString(16),
  13776. width = route.weight || that._defaultRouteWeight(),
  13777. locations = [];
  13778. $.each(route.locations, function(_, routePoint) {
  13779. locations.push(that._locationToString(routePoint))
  13780. });
  13781. routes.push("path=color:" + color + opacity + "|weight:" + width + "|" + locations.join("|"))
  13782. });
  13783. return routes
  13784. },
  13785. _attachClickEvent: function() {
  13786. var that = this,
  13787. eventName = this._addEventNamespace("dxclick");
  13788. this._$container.off(eventName).on(eventName, function(e) {
  13789. that._fireClickAction({jQueryEvent: e})
  13790. })
  13791. }
  13792. }));
  13793. if (!ui.dxMap.__internals)
  13794. ui.dxMap.__internals = {};
  13795. $.extend(ui.dxMap.__internals, {remapGoogleStaticConstant: function(newValue) {
  13796. GOOGLE_STATIC_URL = newValue
  13797. }})
  13798. })(jQuery, DevExpress);
  13799. /*! Module widgets-base, file ui.swipeable.js */
  13800. (function($, DX, undefined) {
  13801. var ui = DX.ui,
  13802. events = ui.events,
  13803. DX_SWIPEABLE = "dxSwipeable",
  13804. SWIPEABLE_CLASS = "dx-swipeable",
  13805. ACTION_TO_EVENT_MAP = {
  13806. startAction: "dxswipestart",
  13807. updateAction: "dxswipe",
  13808. endAction: "dxswipeend",
  13809. cancelAction: "dxswipecancel"
  13810. };
  13811. DX.registerComponent(DX_SWIPEABLE, DX.DOMComponent.inherit({
  13812. NAMESPACE: ui,
  13813. _setDefaultOptions: function() {
  13814. this.callBase();
  13815. this.option({
  13816. elastic: true,
  13817. direction: "horizontal",
  13818. itemSizeFunc: null,
  13819. startAction: null,
  13820. updateAction: null,
  13821. endAction: null,
  13822. cancelAction: null
  13823. })
  13824. },
  13825. _render: function() {
  13826. this.callBase();
  13827. this._element().addClass(SWIPEABLE_CLASS);
  13828. this._attachEventHandlers()
  13829. },
  13830. _attachEventHandlers: function() {
  13831. this._detachEventHanlers();
  13832. if (this.option("disabled"))
  13833. return;
  13834. var NAME = this.NAME;
  13835. this._createEventData();
  13836. $.each(ACTION_TO_EVENT_MAP, $.proxy(function(actionName, eventName) {
  13837. var action = this._createActionByOption(actionName, {
  13838. context: this,
  13839. excludeValidators: ["gesture"]
  13840. });
  13841. eventName = events.addNamespace(eventName, NAME);
  13842. this._element().on(eventName, this._eventData, function(e) {
  13843. return action({jQueryEvent: e})
  13844. })
  13845. }, this))
  13846. },
  13847. _createEventData: function() {
  13848. this._eventData = {
  13849. elastic: this.option("elastic"),
  13850. itemSizeFunc: this.option("itemSizeFunc"),
  13851. direction: this.option("direction")
  13852. }
  13853. },
  13854. _detachEventHanlers: function() {
  13855. this._element().off("." + DX_SWIPEABLE)
  13856. },
  13857. _optionChanged: function(name) {
  13858. switch (name) {
  13859. case"disabled":
  13860. case"startAction":
  13861. case"updateAction":
  13862. case"endAction":
  13863. case"cancelAction":
  13864. case"elastic":
  13865. case"itemSizeFunc":
  13866. case"direction":
  13867. this._detachEventHanlers();
  13868. this._attachEventHandlers();
  13869. break;
  13870. case"rtlEnabled":
  13871. break;
  13872. default:
  13873. this.callBase.apply(this, arguments)
  13874. }
  13875. }
  13876. }))
  13877. })(jQuery, DevExpress);
  13878. /*! Module widgets-base, file ui.button.js */
  13879. (function($, DX, undefined) {
  13880. var ui = DX.ui,
  13881. events = ui.events;
  13882. var BUTTON_CLASS = "dx-button",
  13883. BUTTON_CONTENT_CLASS = "dx-button-content",
  13884. BUTTON_CONTENT_SELECTOR = ".dx-button-content",
  13885. BUTTON_TEXT_CLASS = "dx-button-text",
  13886. BUTTON_HAS_TEXT_CLASS = "dx-button-has-text",
  13887. BUTTON_HAS_ICON_CLASS = "dx-button-has-icon",
  13888. BUTTON_TEXT_SELECTOR = ".dx-button-text",
  13889. BUTTON_BACK_ARROW_CLASS = "dx-button-back-arrow",
  13890. ICON_CLASS = "dx-icon",
  13891. ICON_SELECTOR = ".dx-icon",
  13892. BUTTON_FEEDBACK_HIDE_TIMEOUT = 100;
  13893. DX.registerComponent("dxButton", ui.Widget.inherit({
  13894. _setDefaultOptions: function() {
  13895. this.callBase();
  13896. this.option({
  13897. clickAction: null,
  13898. type: "normal",
  13899. text: "",
  13900. icon: "",
  13901. iconSrc: "",
  13902. hoverStateEnabled: true
  13903. })
  13904. },
  13905. _init: function() {
  13906. this.callBase();
  13907. this._feedbackHideTimeout = BUTTON_FEEDBACK_HIDE_TIMEOUT
  13908. },
  13909. _render: function() {
  13910. this.callBase();
  13911. this._element().addClass(BUTTON_CLASS).append($("<div />").addClass(BUTTON_CONTENT_CLASS));
  13912. this._renderClick();
  13913. this._renderIcon();
  13914. this._renderType();
  13915. this._renderText()
  13916. },
  13917. _renderClick: function() {
  13918. var that = this,
  13919. eventName = events.addNamespace("dxclick", this.NAME);
  13920. this._clickAction = this._createActionByOption("clickAction");
  13921. this._element().off(eventName).on(eventName, function(e) {
  13922. that._clickAction({jQueryEvent: e})
  13923. })
  13924. },
  13925. _removeTypesCss: function() {
  13926. var css = this._element().attr("class");
  13927. css = css.replace(/\bdx-button-[-a-z0-9]+\b/gi, "");
  13928. this._element().attr("class", css)
  13929. },
  13930. _renderIcon: function() {
  13931. var contentElement = this._element().find(BUTTON_CONTENT_SELECTOR),
  13932. iconElement = contentElement.find(ICON_SELECTOR),
  13933. icon = this.option("icon"),
  13934. iconSrc = this.option("iconSrc");
  13935. iconElement.remove();
  13936. if (this.option("type") === "back" && !icon)
  13937. icon = "back";
  13938. if (!icon && !iconSrc)
  13939. return;
  13940. if (icon)
  13941. iconElement = $("<span />").addClass("dx-icon-" + icon);
  13942. else if (iconSrc)
  13943. iconElement = $("<img />").attr("src", iconSrc);
  13944. contentElement.prepend(iconElement.addClass(ICON_CLASS));
  13945. this._element().addClass(BUTTON_HAS_ICON_CLASS)
  13946. },
  13947. _renderType: function() {
  13948. var type = this.option("type");
  13949. if (type)
  13950. this._element().addClass("dx-button-" + type);
  13951. if (type === "back")
  13952. this._element().prepend($("<span />").addClass(BUTTON_BACK_ARROW_CLASS))
  13953. },
  13954. _renderText: function() {
  13955. var text = this.option("text"),
  13956. contentElement = this._element().find(BUTTON_CONTENT_SELECTOR),
  13957. back = this.option("type") === "back";
  13958. var textElement = contentElement.find(BUTTON_TEXT_SELECTOR);
  13959. if (!text && !back) {
  13960. textElement.remove();
  13961. return
  13962. }
  13963. if (!textElement.length)
  13964. textElement = $('<span />').addClass(BUTTON_TEXT_CLASS).appendTo(contentElement);
  13965. textElement.text(text || DX.localization.localizeString("@Back"));
  13966. this._element().addClass(BUTTON_HAS_TEXT_CLASS)
  13967. },
  13968. _clean: function() {
  13969. this.callBase();
  13970. this._removeTypesCss()
  13971. },
  13972. _optionChanged: function(name) {
  13973. switch (name) {
  13974. case"clickAction":
  13975. this._renderClick();
  13976. break;
  13977. case"icon":
  13978. case"iconSrc":
  13979. this._renderIcon();
  13980. break;
  13981. case"text":
  13982. this._renderText();
  13983. break;
  13984. case"type":
  13985. this._invalidate();
  13986. break;
  13987. default:
  13988. this.callBase.apply(this, arguments)
  13989. }
  13990. }
  13991. }))
  13992. })(jQuery, DevExpress);
  13993. /*! Module widgets-base, file ui.checkBox.js */
  13994. (function($, DX, undefined) {
  13995. var ui = DX.ui,
  13996. events = ui.events;
  13997. var CHECKBOX_CLASS = "dx-checkbox",
  13998. CHECKBOX_ICON_CLASS = "dx-checkbox-icon",
  13999. CHECKBOX_CHECKED_CLASS = "dx-checkbox-checked",
  14000. CHECKBOX_INDETERMINATE_CLASS = "dx-checkbox-indeterminate",
  14001. CHECKBOX_FEEDBACK_HIDE_TIMEOUT = 100,
  14002. CHECKBOX_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxCheckBox");
  14003. DX.registerComponent("dxCheckBox", ui.dxEditor.inherit({
  14004. _deprecatedOptions: {checked: {
  14005. since: "14.1",
  14006. message: "Use the 'value' option instead."
  14007. }},
  14008. _optionAliases: {checked: "value"},
  14009. _setDefaultOptions: function() {
  14010. this.callBase();
  14011. this.option({
  14012. value: undefined,
  14013. valueChangeAction: null,
  14014. hoverStateEnabled: true
  14015. })
  14016. },
  14017. _init: function() {
  14018. this.callBase();
  14019. this._feedbackHideTimeout = CHECKBOX_FEEDBACK_HIDE_TIMEOUT
  14020. },
  14021. _render: function() {
  14022. this.callBase();
  14023. this._element().addClass(CHECKBOX_CLASS);
  14024. this._$iconContainer = $("<span />");
  14025. this._$iconContainer.addClass(CHECKBOX_ICON_CLASS).appendTo(this._element());
  14026. this._renderValue();
  14027. this._renderClick();
  14028. this._updateContentSize()
  14029. },
  14030. _renderDimensions: function() {
  14031. this.callBase();
  14032. this._updateContentSize()
  14033. },
  14034. _updateContentSize: function() {
  14035. var $element = this._element(),
  14036. width = this.option("width"),
  14037. height = this.option("height");
  14038. if (this._$iconContainer && (width || height)) {
  14039. width = this._element().width();
  14040. height = this._element().height();
  14041. var minDimention = Math.min(height, width);
  14042. this._$iconContainer.css({
  14043. height: minDimention,
  14044. width: minDimention,
  14045. "margin-top": (height - minDimention) / 2,
  14046. "margin-left": (width - minDimention) / 2
  14047. })
  14048. }
  14049. },
  14050. _renderClick: function() {
  14051. var clickAction = this._createAction(this._handleClick);
  14052. this._element().off(CHECKBOX_DXCLICK_EVENT_NAME).on(CHECKBOX_DXCLICK_EVENT_NAME, function(e) {
  14053. clickAction({jQueryEvent: e})
  14054. })
  14055. },
  14056. _handleClick: function(args) {
  14057. var that = args.component;
  14058. that._valueChangeEventInstance = args.jQueryEvent;
  14059. that.option("value", !that.option("value"))
  14060. },
  14061. _renderValue: function() {
  14062. var $element = this._element(),
  14063. checked = this.option("value"),
  14064. indeterminate = checked === undefined;
  14065. $element.toggleClass(CHECKBOX_CHECKED_CLASS, Boolean(checked));
  14066. $element.toggleClass(CHECKBOX_INDETERMINATE_CLASS, indeterminate)
  14067. },
  14068. _optionChanged: function(name) {
  14069. switch (name) {
  14070. case"value":
  14071. this._renderValue();
  14072. default:
  14073. this.callBase.apply(this, arguments)
  14074. }
  14075. }
  14076. }))
  14077. })(jQuery, DevExpress);
  14078. /*! Module widgets-base, file ui.textEditor.js */
  14079. (function($, DX, undefined) {
  14080. var ui = DX.ui,
  14081. events = ui.events;
  14082. var TEXTEDITOR_CLASS = "dx-texteditor",
  14083. TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input",
  14084. TEXTEDITOR_INPUT_SELECTOR = "." + TEXTEDITOR_INPUT_CLASS,
  14085. TEXTEDITOR_BORDER_CLASS = "dx-texteditor-border",
  14086. TEXTEDITOR_PLACEHOLDER_CLASS = "dx-placeholder",
  14087. TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS = "dx-show-clear-button",
  14088. TEXTEDITOR_CLEAR_ICON_CLASS = "dx-icon-clear",
  14089. TEXTEDITOR_CLEAR_BUTTON_CLASS = "dx-clear-button-area",
  14090. TEXTEDITOR_EMPTY_INPUT_CLASS = "dx-texteditor-empty",
  14091. TEXTEDITOR_STATE_FOCUSED_CLASS = "dx-state-focused",
  14092. EVENTS_LIST = ["focusIn", "focusOut", "keyDown", "keyPress", "keyUp", "change", "cut", "copy", "paste", "input"];
  14093. var nativeClearButtonCancelSupport = function() {
  14094. return DX.browser["msie"] && DX.browser.version > 9 || !DX.browser["msie"]
  14095. }();
  14096. DX.registerComponent("dxTextEditor", ui.dxEditor.inherit({
  14097. _deprecatedOptions: {
  14098. valueUpdateEvent: {
  14099. since: "14.1",
  14100. message: "Use the 'valueChangeEvent' option instead."
  14101. },
  14102. valueUpdateAction: {
  14103. since: "14.1",
  14104. message: "Use the 'valueChangeAction' option instead."
  14105. }
  14106. },
  14107. _optionAliases: {valueUpdateEvent: "valueChangeEvent"},
  14108. _setDefaultOptions: function() {
  14109. this.callBase();
  14110. this.option({
  14111. value: "",
  14112. showClearButton: false,
  14113. valueChangeEvent: "change",
  14114. valueUpdateAction: null,
  14115. placeholder: "",
  14116. readOnly: false,
  14117. focusInAction: null,
  14118. focusOutAction: null,
  14119. keyDownAction: null,
  14120. keyPressAction: null,
  14121. keyUpAction: null,
  14122. changeAction: null,
  14123. inputAction: null,
  14124. cutAction: null,
  14125. copyAction: null,
  14126. pasteAction: null,
  14127. enterKeyAction: null,
  14128. mode: "text",
  14129. activeStateEnabled: false,
  14130. hoverStateEnabled: true
  14131. })
  14132. },
  14133. _input: function() {
  14134. return this._element().find(TEXTEDITOR_INPUT_SELECTOR)
  14135. },
  14136. _render: function() {
  14137. this._element().addClass(TEXTEDITOR_CLASS);
  14138. this._renderInput();
  14139. this._renderInputType();
  14140. this._renderValue();
  14141. this._renderProps();
  14142. this._renderPlaceholder();
  14143. this._renderEvents();
  14144. this._toggleClearButton();
  14145. this._renderEnterKeyAction();
  14146. this._renderEmptinessEvent();
  14147. this._renderFocusEvent();
  14148. this.callBase()
  14149. },
  14150. _renderInput: function(inputContainer) {
  14151. (inputContainer || this._element()).append($("<div>").addClass(TEXTEDITOR_BORDER_CLASS).append($("<input>").addClass(TEXTEDITOR_INPUT_CLASS)))
  14152. },
  14153. _renderValue: function(formattedValue) {
  14154. var text = formattedValue || this.option("value");
  14155. if (this._input().val() !== text) {
  14156. this._input().val(text);
  14157. this._toggleEmptinessEventHandler()
  14158. }
  14159. },
  14160. _isValueValid: function() {
  14161. var validity = this._input().get(0).validity;
  14162. if (validity)
  14163. return validity.valid;
  14164. return true
  14165. },
  14166. _toggleEmptiness: function(visibility) {
  14167. this._element().toggleClass(TEXTEDITOR_EMPTY_INPUT_CLASS, visibility)
  14168. },
  14169. _togglePlaceholderVisibility: function(visibility) {
  14170. if (!this._$placeholder)
  14171. return;
  14172. if (DX.browser["msie"])
  14173. this._$placeholder.toggle(!this._input().is(":focus") && visibility);
  14174. else
  14175. this._$placeholder.toggle(visibility)
  14176. },
  14177. _renderProps: function() {
  14178. this._input().prop({
  14179. readOnly: this._readOnlyPropValue(),
  14180. disabled: this.option("disabled")
  14181. })
  14182. },
  14183. _readOnlyPropValue: function() {
  14184. return this.option("readOnly")
  14185. },
  14186. _renderPlaceholder: function() {
  14187. var that = this,
  14188. $input = that._input(),
  14189. placeholderText = that.option("placeholder"),
  14190. $placeholder = this._$placeholder = $('<div>').attr("data-dx_placeholder", placeholderText),
  14191. startEvent = events.addNamespace("dxclick", this.NAME);
  14192. $placeholder.on(startEvent, function() {
  14193. $input.focus()
  14194. });
  14195. $placeholder.appendTo($input.parent());
  14196. $placeholder.addClass(TEXTEDITOR_PLACEHOLDER_CLASS)
  14197. },
  14198. _toggleClearButton: function() {
  14199. if (!nativeClearButtonCancelSupport)
  14200. return;
  14201. var $element = this._element(),
  14202. showing = this.option("showClearButton") && !this.option("readOnly");
  14203. $element.toggleClass(TEXTEDITOR_SHOW_CLEAR_BUTTON_CLASS, showing);
  14204. if (showing)
  14205. this._renderClearButton();
  14206. else
  14207. this._$clearButton && this._$clearButton.remove()
  14208. },
  14209. _renderClearButton: function() {
  14210. var $clearButton = $("<span>").addClass(TEXTEDITOR_CLEAR_BUTTON_CLASS).append($("<span>").addClass(TEXTEDITOR_CLEAR_ICON_CLASS)).on(events.addNamespace("dxpointerdown", this.NAME), function() {
  14211. return false
  14212. }).on(events.addNamespace("dxpointerup", this.NAME), $.proxy(this._handleClearValue, this));
  14213. this._element().append($clearButton);
  14214. this._$clearButton = $clearButton
  14215. },
  14216. _handleClearValue: function() {
  14217. var $input = this._input();
  14218. this.option("value", "");
  14219. if ($input.is(":focus")) {
  14220. $input.val("");
  14221. this._toggleEmptinessEventHandler()
  14222. }
  14223. else
  14224. $input.trigger("focus")
  14225. },
  14226. _renderEvents: function() {
  14227. var that = this,
  14228. $input = that._input();
  14229. that._renderValueUpdateEvent();
  14230. $.each(EVENTS_LIST, function(_, event) {
  14231. var eventName = events.addNamespace(event.toLowerCase(), that.NAME),
  14232. action = that._createActionByOption(event + "Action");
  14233. $input.off(eventName).on(eventName, function(e) {
  14234. action({jQueryEvent: e})
  14235. })
  14236. })
  14237. },
  14238. _renderValueUpdateEvent: function() {
  14239. var eventNamespace = this.NAME + "ValueUpdate";
  14240. var valueChangeEvent = events.addNamespace(this.option("valueChangeEvent"), eventNamespace);
  14241. this._input().off("." + eventNamespace).on(valueChangeEvent, $.proxy(this._handleValueChangeEvent, this));
  14242. this._valueUpdateAction = this._createActionByOption("valueUpdateAction")
  14243. },
  14244. _renderFocusEvent: function() {
  14245. var $element = this._element();
  14246. $element.find("." + TEXTEDITOR_INPUT_CLASS).focusin(function() {
  14247. $element.addClass(TEXTEDITOR_STATE_FOCUSED_CLASS)
  14248. }).focusout(function() {
  14249. $element.removeClass(TEXTEDITOR_STATE_FOCUSED_CLASS)
  14250. }).filter(":focus").addClass(TEXTEDITOR_STATE_FOCUSED_CLASS);
  14251. if (DX.browser["msie"])
  14252. this._input().on('focus', $.proxy(function() {
  14253. this._togglePlaceholderVisibility(false)
  14254. }, this))
  14255. },
  14256. _renderEmptinessEvent: function() {
  14257. var $input = this._input();
  14258. $input.on("input blur", $.proxy(this._toggleEmptinessEventHandler, this));
  14259. this._toggleEmptinessEventHandler()
  14260. },
  14261. _toggleEmptinessEventHandler: function(value) {
  14262. var value = this._input().val(),
  14263. visibility = (value === "" || value === null) && this._isValueValid();
  14264. this._toggleEmptiness(visibility);
  14265. this._togglePlaceholderVisibility(visibility)
  14266. },
  14267. _handleValueChangeEvent: function(e, formattedValue) {
  14268. this._valueChangeEventInstance = e;
  14269. this._suppressValueUpdateAction = true;
  14270. this.option("value", arguments.length > 1 ? formattedValue : this._input().val());
  14271. this._suppressValueUpdateAction = false;
  14272. this._valueUpdateAction({
  14273. value: this.option("value"),
  14274. jQueryEvent: e
  14275. })
  14276. },
  14277. _renderEnterKeyAction: function() {
  14278. if (this.option("enterKeyAction")) {
  14279. this._enterKeyAction = this._createActionByOption("enterKeyAction");
  14280. this._input().on("keyup.enterKey.dxTextEditor", $.proxy(this._handleEnterKeyUp, this))
  14281. }
  14282. else {
  14283. this._input().off("keyup.enterKey.dxTextEditor");
  14284. this._enterKeyAction = undefined
  14285. }
  14286. },
  14287. _handleEnterKeyUp: function(e) {
  14288. if (e.which === 13)
  14289. this._enterKeyAction({jQueryEvent: e})
  14290. },
  14291. _toggleDisabledState: function() {
  14292. this.callBase.apply(this, arguments);
  14293. this._renderProps()
  14294. },
  14295. _updateValue: function() {
  14296. this._renderValue();
  14297. if (!this._suppressValueUpdateAction)
  14298. this._valueUpdateAction({value: this.option("value")})
  14299. },
  14300. _suppressUpdateValue: function() {
  14301. this._valueUpdateSuppressed = true
  14302. },
  14303. _resumeUpdateValue: function() {
  14304. this._valueUpdateSuppressed = false
  14305. },
  14306. _optionChanged: function(optionName) {
  14307. if ($.inArray(optionName.replace("Action", ""), EVENTS_LIST) > -1) {
  14308. this._renderEvents();
  14309. return
  14310. }
  14311. switch (optionName) {
  14312. case"valueChangeEvent":
  14313. case"valueUpdateAction":
  14314. this._renderValueUpdateEvent();
  14315. break;
  14316. case"readOnly":
  14317. this._renderProps();
  14318. this._toggleClearButton();
  14319. break;
  14320. case"mode":
  14321. this._renderInputType();
  14322. break;
  14323. case"enterKeyAction":
  14324. this._renderEnterKeyAction();
  14325. break;
  14326. case"placeholder":
  14327. this._invalidate();
  14328. break;
  14329. case"showClearButton":
  14330. this._toggleClearButton();
  14331. break;
  14332. case"value":
  14333. if (!this._valueUpdateSuppressed)
  14334. this._updateValue();
  14335. default:
  14336. this.callBase.apply(this, arguments)
  14337. }
  14338. },
  14339. _renderInputType: function() {
  14340. this._setInputType(this.option("mode"))
  14341. },
  14342. _setInputType: function(type) {
  14343. var input = this._input();
  14344. if (type === "search")
  14345. type = "text";
  14346. try {
  14347. input.prop("type", type)
  14348. }
  14349. catch(e) {
  14350. input.prop("type", "text")
  14351. }
  14352. },
  14353. focus: function() {
  14354. this._input().focus()
  14355. },
  14356. blur: function() {
  14357. if (this._input().is(document.activeElement))
  14358. DX.utils.resetActiveElement()
  14359. }
  14360. }))
  14361. })(jQuery, DevExpress);
  14362. /*! Module widgets-base, file ui.textBox.js */
  14363. (function($, DX, undefined) {
  14364. var ui = DX.ui,
  14365. events = ui.events,
  14366. devices = DX.devices,
  14367. ua = window.navigator.userAgent,
  14368. ignoreCode = [8, 9, 13, 33, 34, 35, 36, 37, 38, 39, 40, 46],
  14369. TEXTBOX_CLASS = "dx-textbox",
  14370. SEARCHBOX_CLASS = "dx-searchbox",
  14371. SEARCH_ICON_CLASS = "dx-icon-search";
  14372. DX.registerComponent("dxTextBox", ui.dxTextEditor.inherit({
  14373. _setDefaultOptions: function() {
  14374. this.callBase();
  14375. this.option({
  14376. mode: "text",
  14377. maxLength: null
  14378. })
  14379. },
  14380. _render: function() {
  14381. this.callBase();
  14382. this._element().addClass(TEXTBOX_CLASS);
  14383. this._renderMaxLengthHandlers();
  14384. this._renderSearchMode()
  14385. },
  14386. _renderMaxLengthHandlers: function() {
  14387. if (this._isAndroid())
  14388. this._input().on(events.addNamespace("keydown", this.NAME), $.proxy(this._onKeyDownAndroidHandler, this)).on(events.addNamespace("change", this.NAME), $.proxy(this._onChangeAndroidHandler, this))
  14389. },
  14390. _renderProps: function() {
  14391. this.callBase();
  14392. if (this._isAndroid())
  14393. return;
  14394. var maxLength = this.option("maxLength");
  14395. if (maxLength > 0)
  14396. this._input().prop("maxLength", maxLength)
  14397. },
  14398. _renderSearchMode: function() {
  14399. var $element = this._$element;
  14400. if (this.option("mode") === "search") {
  14401. this._renderSearchIcon();
  14402. $element.addClass(SEARCHBOX_CLASS);
  14403. this._showClearButton = this.option("showClearButton");
  14404. this.option("showClearButton", true)
  14405. }
  14406. if (this.option("mode") !== "search") {
  14407. $element.removeClass(SEARCHBOX_CLASS);
  14408. this._$searchIcon && this._$searchIcon.remove();
  14409. this.option("showClearButton", this._showClearButton === undefined ? this.option("showClearButton") : this._showClearButton)
  14410. }
  14411. },
  14412. _renderSearchIcon: function() {
  14413. var $searchIcon = $("<div>").addClass(SEARCH_ICON_CLASS);
  14414. $searchIcon.prependTo(this._input().parent());
  14415. this._$searchIcon = $searchIcon
  14416. },
  14417. _optionChanged: function(name) {
  14418. switch (name) {
  14419. case"maxLength":
  14420. this._renderProps();
  14421. this._renderMaxLengthHandlers();
  14422. break;
  14423. case"mode":
  14424. this._renderSearchMode();
  14425. default:
  14426. this.callBase.apply(this, arguments)
  14427. }
  14428. },
  14429. _onKeyDownAndroidHandler: function(e) {
  14430. var maxLength = this.option("maxLength");
  14431. if (maxLength) {
  14432. var $input = $(e.target),
  14433. code = e.keyCode;
  14434. this._cutOffExtraChar($input);
  14435. return $input.val().length < maxLength || $.inArray(code, ignoreCode) !== -1 || window.getSelection().toString() !== ""
  14436. }
  14437. else
  14438. return true
  14439. },
  14440. _onChangeAndroidHandler: function(e) {
  14441. var $input = $(e.target);
  14442. if (this.option("maxLength"))
  14443. this._cutOffExtraChar($input)
  14444. },
  14445. _cutOffExtraChar: function($input) {
  14446. var maxLength = this.option("maxLength"),
  14447. textInput = $input.val();
  14448. if (textInput.length > maxLength)
  14449. $input.val(textInput.substr(0, maxLength))
  14450. },
  14451. _isAndroid: function() {
  14452. var realDevice = devices.real();
  14453. var version = realDevice.version.join(".");
  14454. return realDevice.platform === "android" && version && /^(2\.|4\.1)/.test(version) && !/chrome/i.test(ua)
  14455. }
  14456. }));
  14457. ui.dxTextBox.__internals = {
  14458. uaAccessor: function(value) {
  14459. if (!arguments.length)
  14460. return ui;
  14461. ua = value
  14462. },
  14463. SEARCHBOX_CLASS: SEARCHBOX_CLASS,
  14464. SEARCH_ICON_CLASS: SEARCH_ICON_CLASS
  14465. }
  14466. })(jQuery, DevExpress);
  14467. /*! Module widgets-base, file ui.dropDownEditor.js */
  14468. (function($, DX, undefined) {
  14469. var ui = DX.ui,
  14470. events = ui.events,
  14471. DROP_DOWN_EDITOR_CLASS = "dx-dropdowneditor",
  14472. DROP_DOWN_EDITOR_READONLY_CLASS = "dx-dropdowneditor-readonly",
  14473. DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS = "dx-dropdowneditor-input-wrapper",
  14474. DROP_DOWN_EDITOR_BUTTON_CLASS = "dx-dropdowneditor-button",
  14475. DROP_DOWN_EDITOR_BUTTON_ICON = "dx-dropdowneditor-icon",
  14476. DROP_DOWN_EDITOR_OVERLAY = "dx-dropdowneditor-overlay",
  14477. DROP_DOWN_EDITOR_ACTIVE = "dx-dropdowneditor-active",
  14478. DROP_DOWN_EDITOR_BUTTON_VISIBLE = "dx-dropdowneditor-button-visible",
  14479. DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxDropDownEditor"),
  14480. DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME = events.addNamespace("mousedown", "dxDropDownEditor"),
  14481. keyboardKeys = {
  14482. upArrow: 38,
  14483. downArrow: 40
  14484. };
  14485. DX.registerComponent("dxDropDownEditor", ui.dxTextBox.inherit({
  14486. _setDefaultOptions: function() {
  14487. this.callBase();
  14488. this.option({
  14489. openAction: null,
  14490. closeAction: null
  14491. })
  14492. },
  14493. open: function() {
  14494. this._showDropDown()
  14495. },
  14496. close: function() {
  14497. this._hideDropDown()
  14498. },
  14499. _clean: function() {
  14500. this.callBase();
  14501. if (this._dropDownContainer) {
  14502. this._dropDownContainer.remove();
  14503. this._dropDown = undefined
  14504. }
  14505. },
  14506. _render: function() {
  14507. this._dropDownContainerRendered = false;
  14508. this._element().addClass(DROP_DOWN_EDITOR_CLASS);
  14509. this._renderButton();
  14510. this.callBase();
  14511. this._renderKeyboardEvents();
  14512. var that = this;
  14513. this._input().on("blur", function(e) {
  14514. if (that._hideOnBlur() && !that._needToPreventBlur)
  14515. that._hideDropDown();
  14516. that._needToPreventBlur = false
  14517. })
  14518. },
  14519. _renderInput: function(inputContainer) {
  14520. this._inputWrapper = inputContainer || $("<div>");
  14521. this._inputWrapper.addClass(DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS);
  14522. this._element().prepend(this._inputWrapper);
  14523. this.callBase(this._inputWrapper)
  14524. },
  14525. _renderButton: function(hideButton) {
  14526. this._button = $("<div>").addClass(DROP_DOWN_EDITOR_BUTTON_CLASS);
  14527. this._attachButtonEvents();
  14528. this._updateButtonReadonlyState();
  14529. this._buttonIcon = $("<div>").addClass(DROP_DOWN_EDITOR_BUTTON_ICON).appendTo(this._button);
  14530. this._button.appendTo(this._element());
  14531. if (hideButton) {
  14532. this._element().removeClass(DROP_DOWN_EDITOR_BUTTON_VISIBLE);
  14533. this._button.hide()
  14534. }
  14535. else
  14536. this._element().addClass(DROP_DOWN_EDITOR_BUTTON_VISIBLE)
  14537. },
  14538. _attachButtonEvents: function() {
  14539. var that = this,
  14540. dxClickAction,
  14541. mouseDownAction;
  14542. this._button.off(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME).off(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME);
  14543. if (!this.option("readOnly")) {
  14544. dxClickAction = this._createAction(function() {
  14545. that._toggleDropDown();
  14546. that._dropDownClickHandler()
  14547. });
  14548. mouseDownAction = this._createAction(function(args) {
  14549. that._mouseDownFocusKeeper(args.jQueryEvent)
  14550. });
  14551. this._button.on(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME, function(e) {
  14552. dxClickAction({jQueryEvent: e})
  14553. }).on(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME, function(e) {
  14554. mouseDownAction({jQueryEvent: e})
  14555. })
  14556. }
  14557. },
  14558. _updateButtonReadonlyState: function() {
  14559. this._button.removeClass(DROP_DOWN_EDITOR_READONLY_CLASS);
  14560. if (this.option("readOnly"))
  14561. this._button.addClass(DROP_DOWN_EDITOR_READONLY_CLASS)
  14562. },
  14563. _renderKeyboardEvents: function() {
  14564. this._input().off(events.addNamespace("keydown", "dxDropDownEditor")).on(events.addNamespace("keydown", "dxDropDownEditor"), $.proxy(this._onKeyDownHandler, this))
  14565. },
  14566. _dropDownClickHandler: function() {
  14567. if (!this._deviceHasTouchScreen() && !this._input().is(":focus"))
  14568. this.focus();
  14569. this._needToPreventBlur = false
  14570. },
  14571. _mouseDownFocusKeeper: function(e) {
  14572. this._needToPreventBlur = true;
  14573. if (e && e.preventDefault)
  14574. e.preventDefault()
  14575. },
  14576. _deviceHasTouchScreen: function() {
  14577. var device = DevExpress.devices.real();
  14578. return device.phone || device.tablet
  14579. },
  14580. _hideOnBlur: function() {
  14581. return true
  14582. },
  14583. _renderDropDownContent: function() {
  14584. return []
  14585. },
  14586. _dropDownVisible: function() {
  14587. return this._dropDown && this._dropDown.option("visible")
  14588. },
  14589. _toggleDropDown: function() {
  14590. this._dropDownVisible() ? this._hideDropDown() : this._showDropDown()
  14591. },
  14592. _showDropDown: function() {
  14593. if (!this._dropDownVisible()) {
  14594. this._renderDropDownContainer();
  14595. this._dropDown.show();
  14596. this._element().addClass(DROP_DOWN_EDITOR_ACTIVE)
  14597. }
  14598. },
  14599. _hideDropDown: function() {
  14600. if (this._dropDownVisible()) {
  14601. this._element().removeClass(DROP_DOWN_EDITOR_ACTIVE);
  14602. this._dropDown.hide()
  14603. }
  14604. },
  14605. _renderDropDownContainer: function() {
  14606. var that = this,
  14607. dropDownContent;
  14608. if (!this._dropDownContainerRendered) {
  14609. this._dropDownContainer = $("<div>").addClass(DROP_DOWN_EDITOR_OVERLAY).addClass(that.option("customOverlayCssClass"));
  14610. this._element().append(this._dropDownContainer);
  14611. this._createDropDown();
  14612. dropDownContent = this._renderDropDownContent();
  14613. if (!$.isArray(dropDownContent))
  14614. dropDownContent = [dropDownContent];
  14615. $.each(dropDownContent, function(index, contentElement) {
  14616. contentElement.off(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME).on(DROP_DOWN_EDITOR_MOUSE_DOWN_EVENT_NAME, function(e) {
  14617. that._mouseDownFocusKeeper(e)
  14618. }).off(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME).on(DROP_DOWN_EDITOR_DXCLICK_EVENT_NAME, function() {
  14619. that._dropDownClickHandler()
  14620. });
  14621. that._dropDownContainer.append(contentElement)
  14622. });
  14623. this._dropDownContainerRendered = true
  14624. }
  14625. },
  14626. _createDropDown: function(options) {
  14627. this._dropDown = this._dropDownContainer.dxOverlay($.extend(true, {
  14628. position: {
  14629. offset: "0 -1",
  14630. my: "left top",
  14631. at: "left bottom",
  14632. of: this._element(),
  14633. collision: "flip flip"
  14634. },
  14635. showTitle: false,
  14636. width: "auto",
  14637. height: "auto",
  14638. shading: false,
  14639. rtlEnabled: this.option("rtlEnabled"),
  14640. closeOnTargetScroll: $.proxy(this._closeOnScrollHandler, this),
  14641. closeOnOutsideClick: $.proxy(this._closeOutsideDropDownHandler, this),
  14642. animation: {
  14643. show: false,
  14644. hide: false
  14645. },
  14646. shownAction: this.option("openAction"),
  14647. hiddenAction: this.option("closeAction")
  14648. }, options)).dxOverlay("instance")
  14649. },
  14650. _closeOnScrollHandler: function(e) {
  14651. this._hideDropDown();
  14652. return true
  14653. },
  14654. _closeOutsideDropDownHandler: function(e, ignoreContainerClicks) {
  14655. if (e.target !== this._input()[0] && e.target !== this._button[0] && !this._button.find($(e.target)).length && (!ignoreContainerClicks || !this._dropDown._container().find($(e.target)).length))
  14656. this._hideDropDown();
  14657. return false
  14658. },
  14659. _onKeyDownHandler: function(e) {
  14660. if (e.altKey) {
  14661. if (e.which === keyboardKeys.downArrow)
  14662. this._showDropDown();
  14663. if (e.which === keyboardKeys.upArrow)
  14664. this._hideDropDown()
  14665. }
  14666. },
  14667. _optionChanged: function(name, value) {
  14668. switch (name) {
  14669. case"rtlEnabled":
  14670. this.callBase.apply(this, arguments);
  14671. if (this._dropDownContainerRendered)
  14672. this._dropDown.option(name, value);
  14673. break;
  14674. case"openAction":
  14675. if (this._dropDownContainerRendered)
  14676. this._dropDown.option("shownAction", value);
  14677. break;
  14678. case"closeAction":
  14679. if (this._dropDownContainerRendered)
  14680. this._dropDown.option("hiddenAction", value);
  14681. break;
  14682. case"readOnly":
  14683. this._attachButtonEvents();
  14684. this._updateButtonReadonlyState();
  14685. default:
  14686. this.callBase.apply(this, arguments)
  14687. }
  14688. }
  14689. }));
  14690. ui.dxDropDownEditor.__internals = {
  14691. DROP_DOWN_EDITOR_CLASS: DROP_DOWN_EDITOR_CLASS,
  14692. DROP_DOWN_EDITOR_READONLY_CLASS: DROP_DOWN_EDITOR_READONLY_CLASS,
  14693. DROP_DOWN_EDITOR_BUTTON_ICON: DROP_DOWN_EDITOR_BUTTON_ICON,
  14694. DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS: DROP_DOWN_EDITOR_INPUT_WRAPPER_CLASS,
  14695. DROP_DOWN_EDITOR_BUTTON_CLASS: DROP_DOWN_EDITOR_BUTTON_CLASS,
  14696. DROP_DOWN_EDITOR_OVERLAY: DROP_DOWN_EDITOR_OVERLAY,
  14697. DROP_DOWN_EDITOR_ACTIVE: DROP_DOWN_EDITOR_ACTIVE,
  14698. DROP_DOWN_EDITOR_BUTTON_VISIBLE: DROP_DOWN_EDITOR_BUTTON_VISIBLE
  14699. }
  14700. })(jQuery, DevExpress);
  14701. /*! Module widgets-base, file ui.textArea.js */
  14702. (function($, DX, undefined) {
  14703. var ui = DX.ui,
  14704. events = ui.events;
  14705. var TEXTAREA_CLASS = "dx-textarea",
  14706. TEXTEDITOR_INPUT_CLASS = "dx-texteditor-input",
  14707. TEXTEDITOR_BORDER_CLASS = "dx-texteditor-border";
  14708. DX.registerComponent("dxTextArea", ui.dxTextBox.inherit({
  14709. _setDefaultOptions: function() {
  14710. this.callBase();
  14711. this.option({})
  14712. },
  14713. _render: function() {
  14714. this.callBase();
  14715. this._element().addClass(TEXTAREA_CLASS)
  14716. },
  14717. _renderInput: function() {
  14718. this._element().append($("<div />").addClass(TEXTEDITOR_BORDER_CLASS).append($("<textarea />").addClass(TEXTEDITOR_INPUT_CLASS)));
  14719. this._renderScrollHandler()
  14720. },
  14721. _renderScrollHandler: function() {
  14722. var $input = this._input(),
  14723. eventY = 0;
  14724. $input.on(events.addNamespace("dxpointerdown", this.NAME), function(e) {
  14725. eventY = events.eventData(e).y
  14726. });
  14727. $input.on(events.addNamespace("dxpointermove", this.NAME), function(e) {
  14728. var scrollTopPos = $input.scrollTop(),
  14729. scrollBottomPos = $input.prop("scrollHeight") - $input.prop("clientHeight") - scrollTopPos;
  14730. if (scrollTopPos === 0 && scrollBottomPos === 0)
  14731. return;
  14732. var currentEventY = events.eventData(e).y;
  14733. var isScrollFromTop = scrollTopPos === 0 && eventY >= currentEventY,
  14734. isScrollFromBottom = scrollBottomPos === 0 && eventY <= currentEventY,
  14735. isScrollFromMiddle = scrollTopPos > 0 && scrollBottomPos > 0;
  14736. if (isScrollFromTop || isScrollFromBottom || isScrollFromMiddle)
  14737. e.originalEvent.isScrollingEvent = true;
  14738. eventY = currentEventY
  14739. })
  14740. },
  14741. _renderInputType: $.noop
  14742. }))
  14743. })(jQuery, DevExpress);
  14744. /*! Module widgets-base, file ui.numberBox.js */
  14745. (function($, DX, undefined) {
  14746. var ui = DX.ui,
  14747. math = Math,
  14748. events = ui.events,
  14749. WIDGET_CLASS = "dx-numberbox",
  14750. SPIN_CLASS = WIDGET_CLASS + "-spin",
  14751. SPIN_CONTAINER_CLASS = SPIN_CLASS + "-container",
  14752. SPIN_UP_CLASS = SPIN_CLASS + "-up",
  14753. SPIN_DOWN_CLASS = SPIN_CLASS + "-down",
  14754. SPIN_BUTTON_CLASS = SPIN_CLASS + "-button",
  14755. SPIN_UP_SELECTOR = "." + SPIN_UP_CLASS,
  14756. SPIN_DOWN_SELECTOR = "." + SPIN_DOWN_CLASS,
  14757. SPIN_HOLD_DELAY = 150,
  14758. CONTROL_KEYS = ["Del", "Backspace", "Left", "Right", "Home", "End"];
  14759. DX.registerComponent("dxSpinButton", ui.Widget.inherit({
  14760. _setDefaultOptions: function() {
  14761. this.callBase();
  14762. this.option({
  14763. direction: "up",
  14764. changeAction: null
  14765. })
  14766. },
  14767. _render: function() {
  14768. this.callBase();
  14769. var that = this,
  14770. $element = this._element(),
  14771. pointerDownEvent = events.addNamespace("dxpointerdown", this.NAME),
  14772. direction = SPIN_CLASS + "-" + this.option("direction");
  14773. $element.addClass(SPIN_BUTTON_CLASS).addClass(direction).off(pointerDownEvent).on(pointerDownEvent, $.proxy(this._handleSpinHold, this));
  14774. this._spinIcon = $("<div>").addClass(direction + "-icon").appendTo(this._element());
  14775. this._handleSpinChange = this._createActionByOption("changeAction")
  14776. },
  14777. _handleSpinHold: function(e) {
  14778. e.preventDefault();
  14779. var pointerUpEvent = events.addNamespace("dxpointerup", this.NAME),
  14780. pointerCancelEvent = events.addNamespace("dxpointercancel", this.NAME);
  14781. this._clearTimer();
  14782. $(document).off(pointerUpEvent).off(pointerCancelEvent).on(pointerUpEvent, $.proxy(this._clearTimer, this)).on(pointerCancelEvent, $.proxy(this._clearTimer, this));
  14783. this._handleSpinChange({jQueryEvent: e});
  14784. this._holdTimer = setInterval(this._handleSpinChange, SPIN_HOLD_DELAY, {jQueryEvent: e})
  14785. },
  14786. _dispose: function() {
  14787. this._clearTimer();
  14788. this.callBase()
  14789. },
  14790. _clearTimer: function(e) {
  14791. if (this._holdTimer)
  14792. clearInterval(this._holdTimer)
  14793. },
  14794. _optionChanged: function(name, value, prevValue) {
  14795. switch (name) {
  14796. case"changeAction":
  14797. case"direction":
  14798. this._invalidate();
  14799. break;
  14800. default:
  14801. this.callBase(name, value, prevValue)
  14802. }
  14803. }
  14804. }));
  14805. DX.registerComponent("dxNumberBox", ui.dxTextEditor.inherit({
  14806. _setDefaultOptions: function() {
  14807. this.callBase();
  14808. this.option({
  14809. value: 0,
  14810. min: undefined,
  14811. max: undefined,
  14812. mode: "number",
  14813. showSpinButtons: false,
  14814. alignment: undefined, // yo2dh 2015-02-10
  14815. step: 1
  14816. })
  14817. },
  14818. _init: function() {
  14819. this.callBase();
  14820. this._initSpinButtons()
  14821. },
  14822. _initSpinButtons: function() {
  14823. var eventName = events.addNamespace("dxpointerdown", this.NAME);
  14824. this._$spinContainer = $("<div>").addClass(SPIN_CONTAINER_CLASS).off(eventName).on(eventName, $.proxy(this._handleSpinButtonsClick, this));
  14825. this._$spinUp = $("<div>").dxSpinButton({
  14826. direction: "up",
  14827. changeAction: $.proxy(this._handleSpinUpChange, this)
  14828. }).appendTo(this._$spinContainer);
  14829. this._$spinDown = $("<div>").dxSpinButton({
  14830. direction: "down",
  14831. changeAction: $.proxy(this._handleSpinDownChange, this)
  14832. }).appendTo(this._$spinContainer)
  14833. },
  14834. _handleSpinButtonsClick: function() {
  14835. var $input = this._input();
  14836. if (document.activeElement !== $input[0])
  14837. $input.trigger("focus")
  14838. },
  14839. _render: function() {
  14840. this.callBase();
  14841. this._element().addClass(WIDGET_CLASS);
  14842. this._renderSpinButtons();
  14843. this._handleKeyPressEvent()
  14844. },
  14845. _handleKeyPressEvent: function() {
  14846. var that = this;
  14847. this._input().keypress(function(e) {
  14848. var ch = String.fromCharCode(e.which),
  14849. validCharRegExp = /[\d.,eE\-+]/,
  14850. isInputCharValid = validCharRegExp.test(ch);
  14851. if (!isInputCharValid)
  14852. if (!(e.key && $.inArray(e.key, CONTROL_KEYS) >= 0)) {
  14853. e.preventDefault();
  14854. return false
  14855. }
  14856. that._isIncompleteValue = false;
  14857. if (that._isValueIncomplete(that._input().val() + ch))
  14858. that._isIncompleteValue = true
  14859. })
  14860. },
  14861. _isValueIncomplete: function(value) {
  14862. var expRegex = /\d+e$/,
  14863. negRegex = /^-/;
  14864. return expRegex.test(value) || negRegex.test(value)
  14865. },
  14866. _renderSpinButtons: function() {
  14867. this._element().toggleClass(SPIN_CLASS, this.option("showSpinButtons"));
  14868. if (this.option("showSpinButtons"))
  14869. this._$spinContainer.appendTo(this._element());
  14870. else
  14871. this._$spinContainer.detach()
  14872. },
  14873. _handleSpinUpChange: function() {
  14874. this._handleSpinChangeValue(1)
  14875. },
  14876. _handleSpinDownChange: function() {
  14877. this._handleSpinChangeValue(-1)
  14878. },
  14879. _handleSpinChangeValue: function(sgn) {
  14880. this._input().trigger(this.option("valueChangeEvent"));
  14881. var value = parseFloat(this.option().value || 0),
  14882. step = parseFloat(this.option().step);
  14883. value = this._correctRounding(value, step * sgn);
  14884. this.option("value", value)
  14885. },
  14886. _correctRounding: function(value, step) {
  14887. var regex = /[,|.](.*)/;
  14888. var isFloatValue = regex.test(value),
  14889. isFloatStep = regex.test(step);
  14890. if (isFloatValue || isFloatStep) {
  14891. var valueAccuracy = isFloatValue ? regex.exec(value)[0].length : 0,
  14892. stepAccuracy = isFloatStep ? regex.exec(step)[0].length : 0,
  14893. accuracy = Math.max(valueAccuracy, stepAccuracy);
  14894. value = this._round(value + step, accuracy);
  14895. return value
  14896. }
  14897. return value + step
  14898. },
  14899. _round: function(value, precision) {
  14900. precision = precision || 0;
  14901. var multiplier = Math.pow(10, precision);
  14902. value *= multiplier;
  14903. value = Math.round(value) / multiplier;
  14904. return value
  14905. },
  14906. _renderValue: function() {
  14907. var value = this.option("value") ? this.option("value").toString() : this.option("value");
  14908. if (this._input().val() !== value) {
  14909. var inputType = this._input().attr("type");
  14910. this._setInputType("text");
  14911. this._input().val(this.option("value"));
  14912. // yo2dh: 2015-02-10 - dxNumberBox는 무조건 왼쪽 정렬.
  14913. // 이를 alignment option값에 따라 변경되도록 수정함.
  14914. var alignment = this.option('alignment');
  14915. if (alignment) {
  14916. this._input().css('text-align', alignment);
  14917. }
  14918. this._setInputType(inputType);
  14919. this._toggleEmptinessEventHandler()
  14920. }
  14921. },
  14922. _renderProps: function() {
  14923. this.callBase();
  14924. this._input().prop({
  14925. min: this.option("min"),
  14926. max: this.option("max"),
  14927. step: this.option("step")
  14928. })
  14929. },
  14930. _trimInputValue: function() {
  14931. var $input = this._input(),
  14932. value = $.trim($input.val());
  14933. if (value[value.length - 1] === ".")
  14934. value = value.slice(0, -1);
  14935. this._forceRefreshInputValue(value)
  14936. },
  14937. _inputInvalidHandler: function() {
  14938. var $input = this._input(),
  14939. value = $input.val();
  14940. if (this._oldValue) {
  14941. this.option("value", this._oldValue);
  14942. $input.val(this._oldValue);
  14943. this._oldValue = null
  14944. }
  14945. else {
  14946. this.option("value", "");
  14947. $input.val("")
  14948. }
  14949. },
  14950. _forceRefreshInputValue: function(value) {
  14951. var $input = this._input();
  14952. $input.val("").val(value)
  14953. },
  14954. _renderValueUpdateEvent: function() {
  14955. this.callBase();
  14956. this._input().focusout($.proxy(this._trimInputValue, this))
  14957. },
  14958. _handleValueChangeEvent: function(e) {
  14959. var $input = this._input(),
  14960. value = $.trim($input.val()),
  14961. input = $input.get(0);
  14962. value = value.replace(",", ".");
  14963. this._valueChangeEventInstance = e;
  14964. if (!this._isIncompleteValue)
  14965. if (!this._validateValue(value)) {
  14966. this._inputInvalidHandler();
  14967. return
  14968. }
  14969. if (value !== "") {
  14970. if (this._isIncompleteValue)
  14971. return;
  14972. value = this._parseValue(value);
  14973. if (!value && value !== 0)
  14974. return;
  14975. this.callBase(e, value);
  14976. if ($input.val() != value)
  14977. $input.val(value)
  14978. }
  14979. else
  14980. this.option("value", "")
  14981. },
  14982. _validateValue: function(value) {
  14983. var isValueValid = this._isValueValid();
  14984. if (!value && isValueValid) {
  14985. this.option("value", "");
  14986. return true
  14987. }
  14988. var isNumber = /^-?\d*\.?\d*$/.test(value),
  14989. isExponent = /^-?\d+e[-+]?\d+$/.test(value);
  14990. this._oldValue = this.option("value");
  14991. if (!isNumber && !isExponent && !isValueValid)
  14992. return false;
  14993. return true
  14994. },
  14995. _parseValue: function(value) {
  14996. var number = parseFloat(value);
  14997. if (this.option("min") !== undefined)
  14998. number = math.max(number, this.option("min"));
  14999. if (this.option("max") !== undefined)
  15000. number = math.min(number, this.option("max"));
  15001. return number
  15002. },
  15003. _setValue: function(value, prevValue) {
  15004. if (!value && value !== 0) {
  15005. this.option("value", "");
  15006. return
  15007. }
  15008. if ($.type(value) === "string")
  15009. value = value.replace(",", ".");
  15010. value = this._parseValue(value);
  15011. if (!value && value !== 0) {
  15012. this.option("value", prevValue);
  15013. return
  15014. }
  15015. this.option("value", value)
  15016. },
  15017. _invalidate: function() {
  15018. this._$spinContainer.detach();
  15019. this.callBase()
  15020. },
  15021. _dispose: function() {
  15022. this._$spinContainer.remove();
  15023. this.callBase()
  15024. },
  15025. _optionChanged: function(name, value, prevValue) {
  15026. switch (name) {
  15027. case"value":
  15028. this._setValue(value, prevValue);
  15029. this.callBase.apply(this, arguments);
  15030. break;
  15031. case"step":
  15032. case"min":
  15033. case"max":
  15034. this._renderProps();
  15035. break;
  15036. case"showSpinButtons":
  15037. this._renderSpinButtons();
  15038. break;
  15039. default:
  15040. this.callBase.apply(this, arguments)
  15041. }
  15042. }
  15043. }));
  15044. ui.dxNumberBox.__internals = {
  15045. WIDGET_CLASS: WIDGET_CLASS,
  15046. SPIN_CLASS: SPIN_CLASS,
  15047. SPIN_CONTAINER_CLASS: SPIN_CONTAINER_CLASS,
  15048. SPIN_UP_CLASS: SPIN_UP_CLASS,
  15049. SPIN_DOWN_CLASS: SPIN_DOWN_CLASS
  15050. }
  15051. })(jQuery, DevExpress);
  15052. /*! Module widgets-base, file ui.radioButton.js */
  15053. (function($, DX, undefined) {
  15054. var ui = DX.ui,
  15055. events = ui.events;
  15056. var RADIO_BUTTON = "dxRadioButton",
  15057. RADIO_BUTTON_CLASS = "dx-radio-button",
  15058. RADIO_BUTTON_ICON_CLASS = "dx-radio-button-icon",
  15059. RADIO_BUTTON_CHECKED_CLASS = "dx-radio-button-checked",
  15060. RADIO_BUTTON_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", RADIO_BUTTON);
  15061. DX.registerComponent(RADIO_BUTTON, ui.dxEditor.inherit({
  15062. _setDefaultOptions: function() {
  15063. this.callBase();
  15064. this.option({
  15065. value: false,
  15066. hoverStateEnabled: true
  15067. })
  15068. },
  15069. _init: function() {
  15070. this.callBase();
  15071. this._element().addClass(RADIO_BUTTON_CLASS)
  15072. },
  15073. _render: function() {
  15074. this.callBase();
  15075. this._renderIcon();
  15076. this._renderCheckedState(this.option("value"));
  15077. this._renderClick()
  15078. },
  15079. _renderIcon: function() {
  15080. var $icon = $("<div />").addClass(RADIO_BUTTON_ICON_CLASS);
  15081. this._element().append($icon)
  15082. },
  15083. _renderCheckedState: function(checked) {
  15084. this._element().toggleClass(RADIO_BUTTON_CHECKED_CLASS, checked)
  15085. },
  15086. _renderClick: function() {
  15087. var clickAction = this._createAction($.proxy(function(args) {
  15088. this._handleClick(args.jQueryEvent)
  15089. }, this));
  15090. this._element().off(RADIO_BUTTON_DXCLICK_EVENT_NAME).on(RADIO_BUTTON_DXCLICK_EVENT_NAME, function(e) {
  15091. clickAction({jQueryEvent: e})
  15092. })
  15093. },
  15094. _handleClick: function(e) {
  15095. this._valueChangeEventInstance = e;
  15096. this.option("value", true)
  15097. },
  15098. _optionChanged: function(name, value) {
  15099. switch (name) {
  15100. case"value":
  15101. this._renderCheckedState(value);
  15102. this.callBase.apply(this, arguments);
  15103. break;
  15104. default:
  15105. this.callBase.apply(this, arguments)
  15106. }
  15107. }
  15108. }))
  15109. })(jQuery, DevExpress);
  15110. /*! Module widgets-base, file ui.radioGroup.js */
  15111. (function($, DX, undefined) {
  15112. var ui = DX.ui,
  15113. events = ui.events;
  15114. var RADIO_GROUP_CLASS = "dx-radio-group",
  15115. RADIO_GROUP_VERTICAL_CLASS = "dx-radio-group-vertical",
  15116. RADIO_GROUP_HORIZONTAL_CLASS = "dx-radio-group-horizontal",
  15117. RADIO_BUTTON_CLASS = "dx-radio-button",
  15118. RADIO_BUTTON_ICON_CLASS = "dx-radio-button-icon",
  15119. RADIO_VALUE_CONTAINER_CLASS = "dx-radio-value-container",
  15120. RADIO_BUTTON_CHECKED_CLASS = "dx-radio-button-checked",
  15121. RADIO_BUTTON_DATA_KEY = "dxRadioButtonData",
  15122. RADIO_FEEDBACK_HIDE_TIMEOUT = 100;
  15123. DX.registerComponent("dxRadioGroup", ui.CollectionContainerWidget.inherit({
  15124. _activeStateUnit: "." + RADIO_BUTTON_CLASS,
  15125. _setDefaultOptions: function() {
  15126. this.callBase();
  15127. this.option({
  15128. layout: "vertical",
  15129. value: undefined,
  15130. valueExpr: null,
  15131. hoverStateEnabled: true
  15132. })
  15133. },
  15134. _defaultOptionsRules: function() {
  15135. return this.callBase().slice(0).concat([{
  15136. device: {tablet: true},
  15137. options: {layout: "horizontal"}
  15138. }])
  15139. },
  15140. _optionsByReference: function() {
  15141. return $.extend(this.callBase(), {value: true})
  15142. },
  15143. _itemClass: function() {
  15144. return RADIO_BUTTON_CLASS
  15145. },
  15146. _itemDataKey: function() {
  15147. return RADIO_BUTTON_DATA_KEY
  15148. },
  15149. _itemContainer: function() {
  15150. return this._element()
  15151. },
  15152. _init: function() {
  15153. this.callBase();
  15154. if (!this._dataSource)
  15155. this._itemsToDataSource();
  15156. this._feedbackHideTimeout = RADIO_FEEDBACK_HIDE_TIMEOUT
  15157. },
  15158. _itemsToDataSource: function() {
  15159. this._dataSource = new DevExpress.data.DataSource(this.option("items"))
  15160. },
  15161. _render: function() {
  15162. this._element().addClass(RADIO_GROUP_CLASS);
  15163. this._compileValueGetter();
  15164. this.callBase();
  15165. this._renderLayout();
  15166. this._renderValue();
  15167. this._updateContentSize()
  15168. },
  15169. _renderDimensions: function() {
  15170. this.callBase();
  15171. this._updateContentSize()
  15172. },
  15173. _updateContentSize: function() {
  15174. if (this.option("layout") === "horizontal")
  15175. this._itemElements().css("height", "auto");
  15176. else {
  15177. var itemsCount = this.option("items").length;
  15178. this._itemElements().css("height", 100 / itemsCount + "%")
  15179. }
  15180. },
  15181. _compileValueGetter: function() {
  15182. this._valueGetter = DX.data.utils.compileGetter(this._valueGetterExpr())
  15183. },
  15184. _valueGetterExpr: function() {
  15185. return this.option("valueExpr") || this._dataSource && this._dataSource._store._key || "this"
  15186. },
  15187. _renderLayout: function() {
  15188. var layout = this.option("layout");
  15189. this._element().toggleClass(RADIO_GROUP_VERTICAL_CLASS, layout === "vertical");
  15190. this._element().toggleClass(RADIO_GROUP_HORIZONTAL_CLASS, layout === "horizontal")
  15191. },
  15192. _renderValue: function() {
  15193. var value = this.option("value");
  15194. value != null && value !== undefined ? this._setIndexByValue() : this._setValueByIndex()
  15195. },
  15196. _setIndexByValue: function(value) {
  15197. var that = this;
  15198. value = value === undefined ? that.option("value") : value;
  15199. that._searchValue(value).done(function(item) {
  15200. if (that._dataSource.isLoaded())
  15201. that._setIndexByItem(item);
  15202. else
  15203. that._dataSource.load().done(function() {
  15204. that._setIndexByItem(item)
  15205. })
  15206. })
  15207. },
  15208. _setIndexByItem: function(item) {
  15209. var selectedIndex = -1;
  15210. $.each(this.option("items"), $.proxy(function(index, dataSourceItem) {
  15211. if (this._valuesEqual(item, dataSourceItem)) {
  15212. selectedIndex = index;
  15213. return false
  15214. }
  15215. }, this));
  15216. this.option("selectedIndex", selectedIndex)
  15217. },
  15218. _valuesEqual: function(item1, item2) {
  15219. var dataSourceKey = this._dataSource && this._dataSource.key();
  15220. var result = item1 === item2;
  15221. if (dataSourceKey && !result) {
  15222. var item1Key = DX.utils.unwrapObservable(item1[dataSourceKey]);
  15223. var item2Key = DX.utils.unwrapObservable(item2[dataSourceKey]);
  15224. result = item1Key === item2Key
  15225. }
  15226. return result
  15227. },
  15228. _searchValue: function(value) {
  15229. var that = this,
  15230. store = that._dataSource.store(),
  15231. valueExpr = that._valueGetterExpr();
  15232. var deffered = $.Deferred();
  15233. if (valueExpr === store.key() || store instanceof DX.data.CustomStore)
  15234. store.byKey(value).done(function(result) {
  15235. deffered.resolveWith(that, [result])
  15236. });
  15237. else
  15238. store.load({filter: [valueExpr, value]}).done(function(result) {
  15239. deffered.resolveWith(that, result)
  15240. });
  15241. return deffered.promise()
  15242. },
  15243. _setValueByIndex: function() {
  15244. var index = this.option("selectedIndex"),
  15245. $items = this._itemElements();
  15246. if (index < 0 || index >= $items.length) {
  15247. this.option("value", null);
  15248. return
  15249. }
  15250. var itemElement = this._selectedItemElement(index),
  15251. itemData = this._getItemData(itemElement);
  15252. this.option("value", this._getItemValue(itemData))
  15253. },
  15254. _getItemValue: function(item) {
  15255. return !!this._valueGetter ? this._valueGetter(item) : item.text
  15256. },
  15257. _renderSelectedIndex: function(index) {
  15258. var $radioButtons = this._itemElements();
  15259. $radioButtons.removeClass(RADIO_BUTTON_CHECKED_CLASS);
  15260. if (index >= 0 && index < $radioButtons.length)
  15261. $radioButtons.eq(index).addClass(RADIO_BUTTON_CHECKED_CLASS)
  15262. },
  15263. _createItemByRenderer: function(itemRenderer, renderArgs) {
  15264. var $itemElement = this.callBase.apply(this, arguments);
  15265. this._renderInput($itemElement, renderArgs.item);
  15266. return $itemElement
  15267. },
  15268. _createItemByTemplate: function(itemTemplate, renderArgs) {
  15269. var $itemElement = this.callBase.apply(this, arguments);
  15270. this._renderInput($itemElement, renderArgs.item);
  15271. return $itemElement
  15272. },
  15273. _renderInput: function($element, item) {
  15274. if (item.html)
  15275. return;
  15276. var $radio = $("<div>").addClass(RADIO_BUTTON_ICON_CLASS),
  15277. $radioContainer = $("<div>").append($radio).addClass(RADIO_VALUE_CONTAINER_CLASS);
  15278. $element.prepend($radioContainer)
  15279. },
  15280. _optionChanged: function(name, value) {
  15281. switch (name) {
  15282. case"value":
  15283. this._setIndexByValue(value);
  15284. break;
  15285. case"selectedIndex":
  15286. this.callBase.apply(this, arguments);
  15287. this._setValueByIndex();
  15288. break;
  15289. case"layout":
  15290. this._renderLayout();
  15291. this._updateContentSize();
  15292. break;
  15293. case"valueExpr":
  15294. this._compileValueGetter();
  15295. this._setValueByIndex();
  15296. break;
  15297. default:
  15298. this.callBase.apply(this, arguments)
  15299. }
  15300. }
  15301. }))
  15302. })(jQuery, DevExpress);
  15303. /*! Module widgets-base, file ui.tabs.js */
  15304. (function($, DX, undefined) {
  15305. var ui = DX.ui,
  15306. events = ui.events,
  15307. TABS_CLASS = "dx-tabs",
  15308. TABS_WRAPPER_CLASS = "dx-indent-wrapper",
  15309. TABS_ITEM_CLASS = "dx-tab",
  15310. TABS_ITEM_SELECTOR = ".dx-tab",
  15311. TABS_ITEM_SELECTED_CLASS = "dx-tab-selected",
  15312. TABS_ITEM_TEXT_CLASS = "dx-tab-text",
  15313. ICON_CLASS = "dx-icon",
  15314. TABS_ITEM_DATA_KEY = "dxTabData",
  15315. FEEDBACK_HIDE_TIMEOUT = 100,
  15316. ACTIVE_STATE_CLASS = "dx-state-active";
  15317. DX.registerComponent("dxTabs", ui.CollectionContainerWidget.inherit({
  15318. _activeStateUnit: TABS_ITEM_SELECTOR,
  15319. _setDefaultOptions: function() {
  15320. this.callBase();
  15321. this.option({hoverStateEnabled: true})
  15322. },
  15323. _init: function() {
  15324. this.callBase();
  15325. this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT
  15326. },
  15327. _itemClass: function() {
  15328. return TABS_ITEM_CLASS
  15329. },
  15330. _itemDataKey: function() {
  15331. return TABS_ITEM_DATA_KEY
  15332. },
  15333. _itemRenderDefault: function(item, index, itemElement) {
  15334. this.callBase(item, index, itemElement);
  15335. if (item.html)
  15336. return;
  15337. var text = item.text,
  15338. icon = item.icon,
  15339. iconSrc = item.iconSrc,
  15340. iconElement;
  15341. if (text)
  15342. itemElement.wrapInner($("<span />").addClass(TABS_ITEM_TEXT_CLASS));
  15343. if (icon)
  15344. iconElement = $("<span />").addClass(ICON_CLASS + "-" + icon);
  15345. else if (iconSrc)
  15346. iconElement = $("<img />").attr("src", iconSrc);
  15347. if (iconElement)
  15348. iconElement.addClass(ICON_CLASS).prependTo(itemElement)
  15349. },
  15350. _render: function() {
  15351. this.callBase();
  15352. var $element = this._element();
  15353. $element.addClass(TABS_CLASS);
  15354. this._renderWrapper();
  15355. $element.addClass(ACTIVE_STATE_CLASS).removeClass(ACTIVE_STATE_CLASS)
  15356. },
  15357. _renderWrapper: function() {
  15358. this._element().wrapInner($("<div />").addClass(TABS_WRAPPER_CLASS))
  15359. },
  15360. _renderSelectedIndex: function(current, previous) {
  15361. var $tabs = this._itemElements();
  15362. if (previous >= 0)
  15363. $tabs.eq(previous).removeClass(TABS_ITEM_SELECTED_CLASS);
  15364. if (current >= 0)
  15365. $tabs.eq(current).addClass(TABS_ITEM_SELECTED_CLASS)
  15366. }
  15367. }))
  15368. })(jQuery, DevExpress);
  15369. /*! Module widgets-base, file ui.navBar.js */
  15370. (function($, DX, undefined) {
  15371. var ui = DX.ui,
  15372. NAVBAR_CLASS = "dx-navbar",
  15373. NABAR_ITEM_CLASS = "dx-nav-item",
  15374. NAVBAR_ITEM_CONTENT_CLASS = "dx-nav-item-content",
  15375. NAVBAR_ITEM_BADGE_CLASS = "dx-navbar-item-badge";
  15376. DX.registerComponent("dxNavBar", ui.dxTabs.inherit({
  15377. _render: function() {
  15378. this.callBase();
  15379. this._element().addClass(NAVBAR_CLASS)
  15380. },
  15381. _postprocessRenderItem: function(args) {
  15382. var $itemElement = args.itemElement,
  15383. itemData = args.itemData,
  15384. badge = itemData.badge;
  15385. if (badge)
  15386. $("<div>").addClass(NAVBAR_ITEM_BADGE_CLASS).text(badge).appendTo($itemElement);
  15387. $itemElement.addClass(NABAR_ITEM_CLASS);
  15388. $itemElement.wrapInner($("<div>").addClass(NAVBAR_ITEM_CONTENT_CLASS));
  15389. if (!itemData.icon && !itemData.iconSrc)
  15390. $itemElement.addClass("dx-navbar-text-item")
  15391. }
  15392. }))
  15393. })(jQuery, DevExpress);
  15394. /*! Module widgets-base, file ui.toolbar.js */
  15395. (function($, DX, undefined) {
  15396. var ui = DX.ui,
  15397. fx = DX.fx,
  15398. utils = DX.utils,
  15399. translator = DX.translator;
  15400. var TOOLBAR_CLASS = "dx-toolbar",
  15401. TOOLBAR_BOTTOM_CLASS = "dx-toolbar-bottom",
  15402. TOOLBAR_MINI_CLASS = "dx-toolbar-mini",
  15403. TOOLBAR_ITEM_CLASS = "dx-toolbar-item",
  15404. TOOLBAR_LABEL_CLASS = "dx-toolbar-label",
  15405. TOOLBAR_BUTTON_CLASS = "dx-toolbar-button",
  15406. TOOLBAR_MENU_CONTAINER_CLASS = "dx-toolbar-menu-container",
  15407. TOOLBAR_MENU_BUTTON_CLASS = "dx-toolbar-menu-button",
  15408. TOOLBAR_ITEMS_CONTAINER_CLASS = "dx-toolbar-items-container",
  15409. TOOLBAR_LABEL_SELECTOR = "." + TOOLBAR_LABEL_CLASS,
  15410. TOOLBAR_ITEM_DATA_KEY = "dxToolbarItemDataKey",
  15411. SUBMENU_SWIPE_EASING = "easeOutCubic",
  15412. SUBMENU_HIDE_DURATION = 200,
  15413. SUBMENU_SHOW_DURATION = 400;
  15414. var slideSubmenu = function($element, position, isShowAnimation) {
  15415. var duration = isShowAnimation ? SUBMENU_SHOW_DURATION : SUBMENU_HIDE_DURATION;
  15416. fx.animate($element, {
  15417. type: "slide",
  15418. to: {top: position},
  15419. easing: SUBMENU_SWIPE_EASING,
  15420. duration: duration
  15421. })
  15422. };
  15423. DX.registerComponent("dxToolbar", ui.CollectionContainerWidget.inherit({
  15424. _setDefaultOptions: function() {
  15425. this.callBase();
  15426. this.option({
  15427. menuItemRender: null,
  15428. menuItemTemplate: "item",
  15429. submenuType: "dxDropDownMenu",
  15430. renderAs: "topToolbar"
  15431. })
  15432. },
  15433. _defaultOptionsRules: function() {
  15434. return this.callBase().slice(0).concat([{
  15435. device: [{platform: "ios"}, {platform: "ios7"}],
  15436. options: {submenuType: "dxActionSheet"}
  15437. }, {
  15438. device: {platform: "android"},
  15439. options: {submenuType: "dxDropDownMenu"}
  15440. }, {
  15441. device: {platform: "win8"},
  15442. options: {submenuType: "dxList"}
  15443. }])
  15444. },
  15445. _itemContainer: function() {
  15446. return this._$toolbarItemsContainer.find([".dx-toolbar-before", ".dx-toolbar-center", ".dx-toolbar-after"].join(","))
  15447. },
  15448. _itemClass: function() {
  15449. return TOOLBAR_ITEM_CLASS
  15450. },
  15451. _itemDataKey: function() {
  15452. return TOOLBAR_ITEM_DATA_KEY
  15453. },
  15454. _itemRenderDefault: function(item, index, itemElement) {
  15455. this.callBase(item, index, itemElement);
  15456. var widget = item.widget;
  15457. if (widget) {
  15458. var widgetElement = $("<div>").appendTo(itemElement),
  15459. widgetName = DX.inflector.camelize("dx-" + widget),
  15460. options = item.options || {};
  15461. widgetElement[widgetName](options)
  15462. }
  15463. else if (item.text)
  15464. itemElement.wrapInner("<div>")
  15465. },
  15466. _dimensionChanged: function() {
  15467. if (this._menu)
  15468. this._toggleMenuVisibility(false, true);
  15469. this._arrangeTitle()
  15470. },
  15471. _render: function() {
  15472. this._renderToolbar();
  15473. this._renderSections();
  15474. this.callBase();
  15475. this._renderMenu();
  15476. this._arrangeTitle()
  15477. },
  15478. _renderToolbar: function() {
  15479. this._element().addClass(TOOLBAR_CLASS).toggleClass(TOOLBAR_BOTTOM_CLASS, this.option("renderAs") === "bottomToolbar");
  15480. this._$toolbarItemsContainer = $("<div>").appendTo(this._element());
  15481. this._$toolbarItemsContainer.addClass(TOOLBAR_ITEMS_CONTAINER_CLASS)
  15482. },
  15483. _renderSections: function() {
  15484. var $container = this._$toolbarItemsContainer,
  15485. that = this;
  15486. $.each(["before", "center", "after"], function() {
  15487. var sectionClass = "dx-toolbar-" + this,
  15488. $section = $container.find("." + sectionClass);
  15489. if (!$section.length)
  15490. that["_$" + this + "Section"] = $section = $("<div>").addClass(sectionClass).appendTo($container)
  15491. })
  15492. },
  15493. _arrangeTitle: function() {
  15494. if (this._$element.is(":hidden")) {
  15495. this._titleUpdateIsNeeded = true;
  15496. return
  15497. }
  15498. this._titleUpdateIsNeeded = false;
  15499. var $container = this._$toolbarItemsContainer,
  15500. $centerSection = this._$centerSection,
  15501. $label = $centerSection.children(TOOLBAR_LABEL_SELECTOR).eq(0);
  15502. if ($label.length === 0)
  15503. return;
  15504. var containerWidth = $container.width(),
  15505. beforeWidth = this._$beforeSection.outerWidth(),
  15506. afterWidth = this._$afterSection.outerWidth();
  15507. var elemsAtCenterWidth = 10;
  15508. $centerSection.children().not(TOOLBAR_LABEL_SELECTOR).each(function() {
  15509. elemsAtCenterWidth += $(this).outerWidth()
  15510. });
  15511. var maxLabelWidth = containerWidth - beforeWidth - afterWidth - elemsAtCenterWidth;
  15512. var labelLongerThanMax = $label.width() > maxLabelWidth;
  15513. $centerSection.css({
  15514. marginLeft: labelLongerThanMax ? beforeWidth : "",
  15515. marginRight: labelLongerThanMax ? afterWidth : ""
  15516. });
  15517. $label.css("max-width", maxLabelWidth)
  15518. },
  15519. _renderItem: function(index, item) {
  15520. if (item.align)
  15521. utils.logger.warn("dxToolbar.items.align is deprecated. Please use dxToolbar.items.location instead.");
  15522. var align = item.location || item.align || "center";
  15523. if (align === "left") {
  15524. align = "before";
  15525. utils.logger.warn("dxToolbar.items.location: value 'left' is deprecated. Please use 'before' instead.")
  15526. }
  15527. else if (align === "right") {
  15528. align = "after";
  15529. utils.logger.warn("dxToolbar.items.location: value 'right' is deprecated. Please use 'after' instead.")
  15530. }
  15531. var container = this._$toolbarItemsContainer.find(".dx-toolbar-" + align);
  15532. var itemElement = this.callBase(index, item, container);
  15533. itemElement.addClass(TOOLBAR_BUTTON_CLASS);
  15534. if (item.text)
  15535. itemElement.addClass(TOOLBAR_LABEL_CLASS).removeClass(TOOLBAR_BUTTON_CLASS);
  15536. return itemElement
  15537. },
  15538. _hasVisibleMenuItems: function() {
  15539. var menuItems = this._getMenuItems(),
  15540. result = false;
  15541. var optionGetter = DevExpress.data.utils.compileGetter("visible");
  15542. $.each(menuItems, function(index, item) {
  15543. var itemVisible = optionGetter(item, {functionsAsIs: true});
  15544. if (itemVisible !== false)
  15545. result = true
  15546. });
  15547. return result
  15548. },
  15549. _getToolbarItems: function() {
  15550. return $.grep(this.option("items") || [], function(item) {
  15551. return item.location !== "menu"
  15552. })
  15553. },
  15554. _getMenuItems: function() {
  15555. return $.grep(this.option("items") || [], function(item) {
  15556. return item.location === "menu"
  15557. })
  15558. },
  15559. _renderContentImpl: function() {
  15560. var items = this._getToolbarItems();
  15561. this._element().toggleClass(TOOLBAR_MINI_CLASS, items.length === 0);
  15562. if (this._renderedItemsCount)
  15563. this._renderItems(items.slice(this._renderedItemsCount));
  15564. else
  15565. this._renderItems(items)
  15566. },
  15567. _renderMenu: function() {
  15568. var that = this,
  15569. itemClickAction = this._createActionByOption("itemClickAction");
  15570. var options = {
  15571. itemRender: this.option("menuItemRender"),
  15572. itemTemplate: this.option("menuItemTemplate"),
  15573. itemClickAction: function(e) {
  15574. that._toggleMenuVisibility(false, true);
  15575. itemClickAction(e)
  15576. },
  15577. rtlEnabled: this.option("rtlEnabled")
  15578. };
  15579. this._menuType = this.option("submenuType");
  15580. if (this._menuType === "dxList" && this.option("renderAs") === "topToolbar")
  15581. this._menuType = "dxDropDownMenu";
  15582. switch (this._menuType) {
  15583. case"dxActionSheet":
  15584. this._renderActionSheet(options);
  15585. break;
  15586. case"dxDropDownMenu":
  15587. this._renderDropDown(options);
  15588. break;
  15589. case"dxList":
  15590. this._renderList(options);
  15591. break
  15592. }
  15593. },
  15594. _renderMenuButton: function(options) {
  15595. var buttonOptions = $.extend({clickAction: $.proxy(this._handleMenuButtonClick, this)}, options);
  15596. this._renderMenuButtonContainer();
  15597. this._$button = $("<div>").appendTo(this._$menuButtonContainer).addClass(TOOLBAR_MENU_BUTTON_CLASS).dxButton(buttonOptions)
  15598. },
  15599. _renderMenuButtonContainer: function() {
  15600. var $afterSection = this._$afterSection;
  15601. this._$menuButtonContainer = $("<div>").appendTo($afterSection).addClass(TOOLBAR_BUTTON_CLASS).addClass(TOOLBAR_MENU_CONTAINER_CLASS)
  15602. },
  15603. _renderDropDown: function(options) {
  15604. if (!this._hasVisibleMenuItems())
  15605. return;
  15606. this._renderMenuButtonContainer();
  15607. this._menu = $("<div>").appendTo(this._$menuButtonContainer).dxDropDownMenu(options).dxDropDownMenu("instance");
  15608. this._renderMenuItems()
  15609. },
  15610. _renderActionSheet: function(options) {
  15611. if (!this._hasVisibleMenuItems())
  15612. return;
  15613. this._renderMenuButton({icon: "overflow"});
  15614. var actionSheetOptions = $.extend({
  15615. target: this._$button,
  15616. showTitle: false
  15617. }, options);
  15618. this._menu = $("<div>").appendTo(this._element()).dxActionSheet(actionSheetOptions).dxActionSheet("instance");
  15619. this._renderMenuItems()
  15620. },
  15621. _renderList: function(options) {
  15622. this._renderMenuButton({
  15623. activeStateEnabled: false,
  15624. text: "..."
  15625. });
  15626. var listOptions = $.extend({
  15627. width: "100%",
  15628. indicateLoading: false
  15629. }, options);
  15630. this._renderListOverlay();
  15631. this._renderContainerSwipe();
  15632. if (this._hasVisibleMenuItems()) {
  15633. this._menu = $("<div>").appendTo(this._listOverlay.content()).dxList(listOptions).dxList("instance");
  15634. this._renderMenuItems()
  15635. }
  15636. this._changeListVisible(this.option("visible"))
  15637. },
  15638. _renderMenuItems: function() {
  15639. this._menu.option("items", this._getMenuItems())
  15640. },
  15641. _getListHeight: function() {
  15642. var listHeight = this._listOverlay.content().find(".dx-list").height(),
  15643. semiHiddenHeight = this._$toolbarItemsContainer.height() - this._element().height();
  15644. return listHeight + semiHiddenHeight
  15645. },
  15646. _renderListOverlay: function() {
  15647. var element = this._element();
  15648. this._listOverlay = $("<div>").appendTo(element).dxOverlay({
  15649. targetContainer: false,
  15650. deferRendering: false,
  15651. shading: false,
  15652. height: "auto",
  15653. width: "100%",
  15654. showTitle: false,
  15655. closeOnOutsideClick: $.proxy(this._handleListOutsideClick, this),
  15656. position: null,
  15657. animation: null,
  15658. hideTopOverlayHandler: null
  15659. }).dxOverlay("instance")
  15660. },
  15661. _hideTopOverlayHandler: function() {
  15662. this._toggleMenuVisibility(false, true)
  15663. },
  15664. _toggleHideTopOverlayCallback: function() {
  15665. if (this._closeCallback)
  15666. DX.hideTopOverlayCallback.remove(this._closeCallback);
  15667. if (this._menuShown) {
  15668. this._closeCallback = $.proxy(this._hideTopOverlayHandler, this);
  15669. DX.hideTopOverlayCallback.add(this._closeCallback)
  15670. }
  15671. },
  15672. _renderContainerSwipe: function() {
  15673. this._$toolbarItemsContainer.appendTo(this._listOverlay.content()).dxSwipeable({
  15674. elastic: false,
  15675. startAction: $.proxy(this._handleSwipeStart, this),
  15676. updateAction: $.proxy(this._handleSwipeUpdate, this),
  15677. endAction: $.proxy(this._handleSwipeEnd, this),
  15678. itemSizeFunc: $.proxy(this._getListHeight, this),
  15679. direction: "vertical"
  15680. })
  15681. },
  15682. _handleListOutsideClick: function(e) {
  15683. if (!$(e.target).closest(this._listOverlay.content()).length)
  15684. this._toggleMenuVisibility(false, true)
  15685. },
  15686. _calculatePixelOffset: function(offset) {
  15687. offset = (offset || 0) - 1;
  15688. var maxOffset = this._getListHeight();
  15689. return offset * maxOffset
  15690. },
  15691. _handleSwipeStart: function(e) {
  15692. e.jQueryEvent.maxTopOffset = this._menuShown ? 0 : 1;
  15693. e.jQueryEvent.maxBottomOffset = this._menuShown ? 1 : 0
  15694. },
  15695. _handleSwipeUpdate: function(e) {
  15696. var offset = this._menuShown ? e.jQueryEvent.offset : 1 + e.jQueryEvent.offset;
  15697. this._renderMenuPosition(offset, false)
  15698. },
  15699. _handleSwipeEnd: function(e) {
  15700. var targetOffset = e.jQueryEvent.targetOffset;
  15701. targetOffset -= this._menuShown - 1;
  15702. this._toggleMenuVisibility(targetOffset === 0, true)
  15703. },
  15704. _renderMenuPosition: function(offset, animate) {
  15705. var pos = this._calculatePixelOffset(offset),
  15706. element = this._listOverlay.content();
  15707. if (animate)
  15708. slideSubmenu(element, pos, this._menuShown);
  15709. else
  15710. translator.move(element, {top: pos})
  15711. },
  15712. _handleMenuButtonClick: function() {
  15713. this._toggleMenuVisibility(!this._menuShown, true)
  15714. },
  15715. _toggleMenuVisibility: function(visible, animate) {
  15716. this._menuShown = visible;
  15717. switch (this._menuType) {
  15718. case"dxList":
  15719. this._toggleHideTopOverlayCallback();
  15720. this._renderMenuPosition(this._menuShown ? 0 : 1, animate);
  15721. break;
  15722. case"dxActionSheet":
  15723. this._menu.toggle(this._menuShown);
  15724. this._menuShown = false;
  15725. break
  15726. }
  15727. },
  15728. _renderEmptyMessage: $.noop,
  15729. _clean: function() {
  15730. this._$toolbarItemsContainer.children().empty();
  15731. this._element().empty()
  15732. },
  15733. _changeMenuOption: function(name, value) {
  15734. if (this._menu)
  15735. this._menu.option(name, value)
  15736. },
  15737. _changeListVisible: function(value) {
  15738. if (this._listOverlay) {
  15739. this._listOverlay.option("visible", value);
  15740. this._toggleMenuVisibility(false, false)
  15741. }
  15742. },
  15743. _visibilityChanged: function(visible) {
  15744. if (visible && this._titleUpdateIsNeeded)
  15745. this._arrangeTitle()
  15746. },
  15747. _optionChanged: function(name, value) {
  15748. switch (name) {
  15749. case"renderAs":
  15750. case"submenuType":
  15751. this._invalidate();
  15752. break;
  15753. case"visible":
  15754. this._changeListVisible(value);
  15755. this.callBase.apply(this, arguments);
  15756. break;
  15757. case"menuItemRender":
  15758. this._changeMenuOption("itemRender", value);
  15759. break;
  15760. case"menuItemTemplate":
  15761. this._changeMenuOption("itemTemplate", value);
  15762. break;
  15763. case"itemClickAction":
  15764. this._changeMenuOption(name, value);
  15765. this.callBase.apply(this, arguments);
  15766. break;
  15767. default:
  15768. this.callBase.apply(this, arguments)
  15769. }
  15770. }
  15771. }))
  15772. })(jQuery, DevExpress);
  15773. /*! Module widgets-base, file ui.list.js */
  15774. (function($, DX, undefined) {
  15775. var ui = DX.ui,
  15776. events = ui.events,
  15777. utils = DX.utils;
  15778. var LIST_CLASS = "dx-list",
  15779. LIST_ITEM_CLASS = "dx-list-item",
  15780. LIST_ITEM_SELECTOR = "." + LIST_ITEM_CLASS,
  15781. LIST_GROUP_CLASS = "dx-list-group",
  15782. LIST_GROUP_HEADER_CLASS = "dx-list-group-header",
  15783. LIST_HAS_NEXT_CLASS = "dx-has-next",
  15784. LIST_NEXT_BUTTON_CLASS = "dx-list-next-button",
  15785. LIST_ITEM_DATA_KEY = "dxListItemData",
  15786. LIST_FEEDBACK_SHOW_TIMEOUT = 70;
  15787. DX.registerComponent("dxList", ui.CollectionContainerWidget.inherit({
  15788. _activeStateUnit: LIST_ITEM_SELECTOR,
  15789. _setDefaultOptions: function() {
  15790. this.callBase();
  15791. this.option({
  15792. pullRefreshEnabled: false,
  15793. autoPagingEnabled: true,
  15794. scrollingEnabled: true,
  15795. showScrollbar: true,
  15796. useNativeScrolling: true,
  15797. pullingDownText: Globalize.localize("dxList-pullingDownText"),
  15798. pulledDownText: Globalize.localize("dxList-pulledDownText"),
  15799. refreshingText: Globalize.localize("dxList-refreshingText"),
  15800. pageLoadingText: Globalize.localize("dxList-pageLoadingText"),
  15801. scrollAction: null,
  15802. pullRefreshAction: null,
  15803. pageLoadingAction: null,
  15804. showNextButton: false,
  15805. nextButtonText: Globalize.localize("dxList-nextButtonText"),
  15806. itemSwipeAction: null,
  15807. grouped: false,
  15808. groupTemplate: "group",
  15809. groupRender: null,
  15810. indicateLoading: true,
  15811. hoverStateEnabled: true
  15812. })
  15813. },
  15814. _defaultOptionsRules: function() {
  15815. return this.callBase().slice(0).concat([{
  15816. device: function(device) {
  15817. return !DX.support.nativeScrolling
  15818. },
  15819. options: {useNativeScrolling: false}
  15820. }, {
  15821. device: function(device) {
  15822. return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic"
  15823. },
  15824. options: {
  15825. showScrollbar: "onHover",
  15826. showNextButton: true,
  15827. autoPagingEnabled: false
  15828. }
  15829. }])
  15830. },
  15831. _itemClass: function() {
  15832. return LIST_ITEM_CLASS
  15833. },
  15834. _itemDataKey: function() {
  15835. return LIST_ITEM_DATA_KEY
  15836. },
  15837. _itemContainer: function() {
  15838. return this._$container
  15839. },
  15840. _allowDinamicItemsAppend: function() {
  15841. return true
  15842. },
  15843. _init: function() {
  15844. this.callBase();
  15845. this._$container = this._element();
  15846. this._initScrollView();
  15847. this._feedbackShowTimeout = LIST_FEEDBACK_SHOW_TIMEOUT
  15848. },
  15849. _dataSourceOptions: function() {
  15850. return $.extend(this.callBase(), {paginate: true})
  15851. },
  15852. _initScrollView: function() {
  15853. var scrollingEnabled = this.option("scrollingEnabled"),
  15854. pullRefreshEnabled = scrollingEnabled && this.option("pullRefreshEnabled"),
  15855. autoPagingEnabled = scrollingEnabled && this.option("autoPagingEnabled") && !!this._dataSource;
  15856. var $scrollView = this._element().dxScrollView({
  15857. rtlEnabled: this.option("rtlEnabled"),
  15858. disabled: this.option("disabled") || !scrollingEnabled,
  15859. scrollAction: $.proxy(this._handleScroll, this),
  15860. pullDownAction: pullRefreshEnabled ? $.proxy(this._handlePullDown, this) : null,
  15861. reachBottomAction: autoPagingEnabled ? $.proxy(this._handleScrollBottom, this) : null,
  15862. showScrollbar: this.option("showScrollbar"),
  15863. useNative: this.option("useNativeScrolling"),
  15864. pullingDownText: this.option("pullingDownText"),
  15865. pulledDownText: this.option("pulledDownText"),
  15866. refreshingText: this.option("refreshingText"),
  15867. reachBottomText: this.option("pageLoadingText")
  15868. });
  15869. this._scrollView = $scrollView.dxScrollView("instance");
  15870. this._scrollView.toggleLoading(autoPagingEnabled);
  15871. this._$container = this._scrollView.content();
  15872. this._createScrollViewActions();
  15873. this._afterItemsRendered()
  15874. },
  15875. _createScrollViewActions: function() {
  15876. this._scrollAction = this._createActionByOption("scrollAction", {excludeValidators: ["gesture"]});
  15877. this._pullRefreshAction = this._createActionByOption("pullRefreshAction", {excludeValidators: ["gesture"]});
  15878. this._pageLoadingAction = this._createActionByOption("pageLoadingAction", {excludeValidators: ["gesture"]})
  15879. },
  15880. _handleScroll: function(e) {
  15881. this._scrollAction(e)
  15882. },
  15883. _afterItemsRendered: function(tryLoadMore) {
  15884. var isLastPage = this._isLastPage(),
  15885. allDataLoaded = !tryLoadMore || isLastPage,
  15886. autoPagingEnabled = this.option("autoPagingEnabled"),
  15887. stopLoading = !autoPagingEnabled || allDataLoaded,
  15888. scrollViewIsFull = this._scrollViewIsFull();
  15889. if (stopLoading || scrollViewIsFull) {
  15890. this._scrollView.release(stopLoading);
  15891. this._loadIndicationSuppressed = false;
  15892. if (this._shouldRenderNextButton() && this._dataSource.isLoaded())
  15893. this._toggleNextButton(!allDataLoaded)
  15894. }
  15895. else
  15896. this._infiniteDataLoading()
  15897. },
  15898. _shouldRenderNextButton: function() {
  15899. return this.option("showNextButton") && this._dataSource
  15900. },
  15901. _handleDataSourceLoadingChanged: function(isLoading) {
  15902. if (this._loadIndicationSuppressed)
  15903. return;
  15904. if (isLoading && this.option("indicateLoading"))
  15905. this._showLoadingIndicatorTimer = setTimeout($.proxy(function() {
  15906. this._scrollView && this._scrollView.startLoading()
  15907. }, this));
  15908. else {
  15909. clearTimeout(this._showLoadingIndicatorTimer);
  15910. this._scrollView && this._scrollView.finishLoading()
  15911. }
  15912. },
  15913. _hideLoadingIfLoadIndicationOff: function() {
  15914. if (!this.option("indicateLoading"))
  15915. this._handleDataSourceLoadingChanged(false)
  15916. },
  15917. _suppressLoadingIndication: function() {
  15918. this._loadIndicationSuppressed = true
  15919. },
  15920. _isLastPage: function() {
  15921. return !this._dataSource || this._dataSource.isLastPage()
  15922. },
  15923. _scrollViewIsFull: function() {
  15924. return !this._scrollView || this._scrollView.isFull()
  15925. },
  15926. _handlePullDown: function(e) {
  15927. this._pullRefreshAction(e);
  15928. if (this._dataSource && !this._dataSource.isLoading()) {
  15929. this._dataSource.pageIndex(0);
  15930. this._dataSource.load()
  15931. }
  15932. else
  15933. this._afterItemsRendered()
  15934. },
  15935. _infiniteDataLoading: function() {
  15936. var dataSource = this._dataSource;
  15937. if (!this._scrollViewIsFull() && dataSource && !dataSource.isLoading() && !this._isLastPage())
  15938. this._loadNextPageTimer = setTimeout($.proxy(this._loadNextPage, this))
  15939. },
  15940. _handleScrollBottom: function(e) {
  15941. this._pageLoadingAction(e);
  15942. var dataSource = this._dataSource;
  15943. if (dataSource && !dataSource.isLoading())
  15944. this._loadNextPage();
  15945. else
  15946. this._afterItemsRendered()
  15947. },
  15948. _loadNextPage: function() {
  15949. var dataSource = this._dataSource;
  15950. this._expectNextPageLoading();
  15951. dataSource.pageIndex(1 + dataSource.pageIndex());
  15952. return dataSource.load()
  15953. },
  15954. _renderItems: function(items) {
  15955. if (this.option("grouped")) {
  15956. $.each(items, $.proxy(this._renderGroup, this));
  15957. this._renderEmptyMessage()
  15958. }
  15959. else
  15960. this.callBase.apply(this, arguments);
  15961. this._afterItemsRendered(true)
  15962. },
  15963. _handleDataSourceLoadError: function() {
  15964. this.callBase.apply(this, arguments);
  15965. if (this._initialized)
  15966. this._afterItemsRendered()
  15967. },
  15968. _render: function() {
  15969. this._element().addClass(LIST_CLASS);
  15970. this.callBase()
  15971. },
  15972. _postprocessRenderItem: function(args) {
  15973. if (this.option("itemSwipeAction"))
  15974. this._attachSwipeEvent($(args.itemElement))
  15975. },
  15976. _attachSwipeEvent: function($itemElement) {
  15977. var endEventName = events.addNamespace("dxswipeend", this.NAME);
  15978. $itemElement.on(endEventName, $.proxy(this._handleItemSwipeEnd, this))
  15979. },
  15980. _handleItemSwipeEnd: function(e) {
  15981. this._handleItemJQueryEvent(e, "itemSwipeAction", {direction: e.offset < 0 ? "left" : "right"}, {excludeValidators: ["gesture"]})
  15982. },
  15983. _handleNextButton: function() {
  15984. var source = this._dataSource;
  15985. if (source && !source.isLoading()) {
  15986. this._scrollView.toggleLoading(true);
  15987. this._$nextButton.detach();
  15988. this._suppressLoadingIndication();
  15989. this._loadNextPage()
  15990. }
  15991. },
  15992. _groupRenderDefault: function(group) {
  15993. return String(group.key || group)
  15994. },
  15995. _renderGroup: function(index, group) {
  15996. var that = this;
  15997. var groupElement = $("<div>").addClass(LIST_GROUP_CLASS).appendTo(that._itemContainer());
  15998. var groupRenderer = that.option("groupRender"),
  15999. groupTemplateName = that.option("groupTemplate"),
  16000. groupTemplate = that._getTemplate(group.template || groupTemplateName, index, group),
  16001. groupHeaderElement,
  16002. renderArgs = {
  16003. index: index,
  16004. group: group,
  16005. container: groupElement
  16006. };
  16007. if (groupRenderer)
  16008. groupHeaderElement = that._createGroupByRenderer(groupRenderer, renderArgs);
  16009. else if (groupTemplate)
  16010. groupHeaderElement = that._createGroupByTemplate(groupTemplate, renderArgs);
  16011. else
  16012. groupHeaderElement = that._createGroupByRenderer(that._groupRenderDefault, renderArgs);
  16013. groupHeaderElement.addClass(LIST_GROUP_HEADER_CLASS);
  16014. this._renderingGroupIndex = index;
  16015. $.each(group.items || [], function(index, item) {
  16016. that._renderItem(index, item, groupElement)
  16017. })
  16018. },
  16019. _createGroupByRenderer: function(groupRenderer, renderArgs) {
  16020. var groupElement = $("<div>").appendTo(renderArgs.container);
  16021. var rendererResult = groupRenderer(renderArgs.group, renderArgs.index, groupElement);
  16022. if (rendererResult && groupElement[0] !== rendererResult[0])
  16023. groupElement.append(rendererResult);
  16024. return groupElement
  16025. },
  16026. _createGroupByTemplate: function(groupTemplate, renderArgs) {
  16027. return groupTemplate.render(renderArgs.container, renderArgs.group)
  16028. },
  16029. _clean: function() {
  16030. if (this._$nextButton) {
  16031. this._$nextButton.remove();
  16032. this._$nextButton = null
  16033. }
  16034. this.callBase.apply(this, arguments)
  16035. },
  16036. _dispose: function() {
  16037. clearTimeout(this._holdTimer);
  16038. clearTimeout(this._loadNextPageTimer);
  16039. clearTimeout(this._showLoadingIndicatorTimer);
  16040. this.callBase()
  16041. },
  16042. _toggleDisabledState: function(value) {
  16043. this.callBase(value);
  16044. this._scrollView.option("disabled", value || !this.option("scrollingEnabled"))
  16045. },
  16046. _toggleNextButton: function(value) {
  16047. var dataSource = this._dataSource,
  16048. $nextButton = this._getNextButton();
  16049. this._element().toggleClass(LIST_HAS_NEXT_CLASS, value);
  16050. if (value && dataSource && dataSource.isLoaded())
  16051. $nextButton.appendTo(this._itemContainer());
  16052. if (!value)
  16053. $nextButton.detach()
  16054. },
  16055. _getNextButton: function() {
  16056. if (!this._$nextButton)
  16057. this._$nextButton = this._createNextButton();
  16058. return this._$nextButton
  16059. },
  16060. _createNextButton: function() {
  16061. var $result = $("<div>").addClass(LIST_NEXT_BUTTON_CLASS);
  16062. $result.append($("<div>").dxButton({
  16063. text: this.option("nextButtonText"),
  16064. clickAction: $.proxy(this._handleNextButton, this)
  16065. }));
  16066. return $result
  16067. },
  16068. _optionChanged: function(name, value, prevValue) {
  16069. switch (name) {
  16070. case"showNextButton":
  16071. this._toggleNextButton(value);
  16072. break;
  16073. case"dataSource":
  16074. this.callBase.apply(this, arguments);
  16075. this._initScrollView();
  16076. break;
  16077. case"pullingDownText":
  16078. case"pulledDownText":
  16079. case"refreshingText":
  16080. case"pageLoadingText":
  16081. case"useNativeScrolling":
  16082. case"showScrollbar":
  16083. case"scrollingEnabled":
  16084. case"pullRefreshEnabled":
  16085. case"autoPagingEnabled":
  16086. this._initScrollView();
  16087. break;
  16088. case"nextButtonText":
  16089. case"itemSwipeAction":
  16090. this._invalidate();
  16091. break;
  16092. case"scrollAction":
  16093. case"pullRefreshAction":
  16094. case"pageLoadingAction":
  16095. this._createScrollViewActions();
  16096. this._invalidate();
  16097. break;
  16098. case"grouped":
  16099. case"groupTemplate":
  16100. case"groupRender":
  16101. this._invalidate();
  16102. break;
  16103. case"items":
  16104. this._invalidate();
  16105. break;
  16106. case"width":
  16107. case"height":
  16108. this.callBase.apply(this, arguments);
  16109. this._scrollView.update();
  16110. break;
  16111. case"indicateLoading":
  16112. this._hideLoadingIfLoadIndicationOff();
  16113. break;
  16114. case"visible":
  16115. this.callBase.apply(this, arguments);
  16116. this._scrollView.update();
  16117. break;
  16118. case"rtlEnabled":
  16119. this._initScrollView();
  16120. this.callBase.apply(this, arguments);
  16121. break;
  16122. default:
  16123. this.callBase.apply(this, arguments)
  16124. }
  16125. },
  16126. update: function() {
  16127. utils.logger.warn("'update' method is deprecated since 14.1. Use the 'updateDimensions' method instead.");
  16128. return this.updateDimensions.apply(this, arguments)
  16129. },
  16130. updateDimensions: function() {
  16131. var that = this,
  16132. deferred = $.Deferred();
  16133. if (that._scrollView)
  16134. that._scrollView.update().done(function() {
  16135. deferred.resolveWith(that)
  16136. });
  16137. else
  16138. deferred.resolveWith(that);
  16139. return deferred.promise()
  16140. },
  16141. refresh: function() {
  16142. utils.logger.warn("'refresh' method is deprecated since 14.1. Use the 'reload' method instead.");
  16143. return this.reload.apply(this, arguments)
  16144. },
  16145. reload: function() {
  16146. this.scrollTo(0);
  16147. this._handlePullDown()
  16148. },
  16149. scrollTop: function() {
  16150. return this._scrollView.scrollOffset().top
  16151. },
  16152. clientHeight: function() {
  16153. return this._scrollView.clientHeight()
  16154. },
  16155. scrollHeight: function() {
  16156. return this._scrollView.scrollHeight()
  16157. },
  16158. scrollBy: function(distance) {
  16159. this._scrollView.scrollBy(distance)
  16160. },
  16161. scrollTo: function(location) {
  16162. this._scrollView.scrollTo(location)
  16163. },
  16164. scrollToItem: function(itemElement) {
  16165. this._scrollView.scrollToElement(itemElement)
  16166. }
  16167. }))
  16168. })(jQuery, DevExpress);
  16169. /*! Module widgets-base, file ui.list.edit.strategies.js */
  16170. (function($, DX, undefined) {
  16171. var ui = DX.ui;
  16172. var ListEditStrategy = DX.Class.inherit({
  16173. ctor: function(list) {
  16174. this._list = list
  16175. },
  16176. getNormalizedIndex: function(value) {
  16177. if (this._isNormalisedItemIndex(value))
  16178. return value;
  16179. if (this._isItemIndex(value))
  16180. return this._normalizeItemIndex(value);
  16181. return this._getNormalizedItemIndex(value)
  16182. },
  16183. getIndex: function(value) {
  16184. if (this._isNormalisedItemIndex(value))
  16185. return this._denormalizeItemIndex(value);
  16186. if (this._isItemIndex(value))
  16187. return value;
  16188. return this._denormalizeItemIndex(this._getNormalizedItemIndex(value))
  16189. },
  16190. getItemElement: function(value) {
  16191. if (this._isNormalisedItemIndex(value))
  16192. return this._getItemByNormalizedIndex(value);
  16193. if (this._isItemIndex(value))
  16194. return this._getItemByNormalizedIndex(this._normalizeItemIndex(value));
  16195. return $(value)
  16196. },
  16197. deleteItemAtIndex: DX.abstract,
  16198. updateSelectionAfterDelete: DX.abstract,
  16199. fetchSelectedItems: DX.abstract,
  16200. selectedItemIndecies: DX.abstract,
  16201. itemPlacementFunc: function(movingIndex, destinationIndex) {
  16202. return this._itemsFromSameParent(movingIndex, destinationIndex) && movingIndex < destinationIndex ? "after" : "before"
  16203. },
  16204. moveItemAtIndexToIndex: DX.abstract,
  16205. getSelectedItemsAfterReorderItem: function() {
  16206. return this._list.option("selectedItems")
  16207. },
  16208. _isNormalisedItemIndex: function(index) {
  16209. return $.isNumeric(index)
  16210. },
  16211. _isItemIndex: DX.abstract,
  16212. _getNormalizedItemIndex: DX.abstract,
  16213. _normalizeItemIndex: DX.abstract,
  16214. _denormalizeItemIndex: DX.abstract,
  16215. _getItemByNormalizedIndex: DX.abstract,
  16216. _itemsFromSameParent: DX.abstract
  16217. });
  16218. ui.PlainListEditStrategy = ListEditStrategy.inherit({
  16219. deleteItemAtIndex: function(index) {
  16220. this._list.option("items").splice(index, 1)
  16221. },
  16222. updateSelectionAfterDelete: function(fromIndex) {
  16223. var selectedItemIndices = this._list._selectedItemIndices;
  16224. $.each(selectedItemIndices, function(i, index) {
  16225. if (index > fromIndex)
  16226. selectedItemIndices[i] -= 1
  16227. })
  16228. },
  16229. fetchSelectedItems: function(indecies) {
  16230. indecies = indecies || this._list._selectedItemIndices;
  16231. var items = this._list.option("items"),
  16232. selectedItems = [];
  16233. $.each(indecies, function(_, index) {
  16234. selectedItems.push(items[index])
  16235. });
  16236. return selectedItems
  16237. },
  16238. selectedItemIndecies: function() {
  16239. var selectedIndices = [],
  16240. items = this._list.option("items"),
  16241. selected = this._list.option("selectedItems");
  16242. $.each(selected, function(_, selectedItem) {
  16243. var index = $.inArray(selectedItem, items);
  16244. if (index !== -1)
  16245. selectedIndices.push(index);
  16246. else
  16247. throw new Error("Item '" + selectedItem + "' you are trying to select does not exist");
  16248. });
  16249. return selectedIndices
  16250. },
  16251. moveItemAtIndexToIndex: function(movingIndex, destinationIndex) {
  16252. var items = this._list.option("items"),
  16253. movedItemData = items[movingIndex];
  16254. items.splice(movingIndex, 1);
  16255. items.splice(destinationIndex, 0, movedItemData)
  16256. },
  16257. _isItemIndex: function(index) {
  16258. return $.isNumeric(index)
  16259. },
  16260. _getNormalizedItemIndex: function(itemElement) {
  16261. return this._list._itemElements().index(itemElement)
  16262. },
  16263. _normalizeItemIndex: function(index) {
  16264. return index
  16265. },
  16266. _denormalizeItemIndex: function(index) {
  16267. return index
  16268. },
  16269. _getItemByNormalizedIndex: function(index) {
  16270. return this._list._itemElements().eq(index)
  16271. },
  16272. _itemsFromSameParent: function() {
  16273. return true
  16274. }
  16275. });
  16276. var LIST_ITEM_CLASS = "dx-list-item",
  16277. LIST_GROUP_CLASS = "dx-list-group";
  16278. var SELECTION_SHIFT = 20,
  16279. SELECTION_MASK = 0x8FF;
  16280. var combineIndex = function(indices) {
  16281. return (indices.group << SELECTION_SHIFT) + indices.item
  16282. };
  16283. var splitIndex = function(combinedIndex) {
  16284. return {
  16285. group: combinedIndex >> SELECTION_SHIFT,
  16286. item: combinedIndex & SELECTION_MASK
  16287. }
  16288. };
  16289. var createGroupSelection = function(group, selectedItems) {
  16290. var groupItems = group.items,
  16291. groupSelection = {
  16292. key: group.key,
  16293. items: []
  16294. };
  16295. $.each(selectedItems, function(_, itemIndex) {
  16296. groupSelection.items.push(groupItems[itemIndex])
  16297. });
  16298. return groupSelection
  16299. };
  16300. var groupByKey = function(groups, key) {
  16301. var length = groups.length;
  16302. for (var i = 0; i < length; i++)
  16303. if (groups[i].key === key)
  16304. return groups[i]
  16305. };
  16306. ui.GroupedListEditStrategy = ListEditStrategy.inherit({
  16307. _groupElements: function() {
  16308. return this._list._itemContainer().find("." + LIST_GROUP_CLASS)
  16309. },
  16310. _groupItemElements: function($group) {
  16311. return $group.find("." + LIST_ITEM_CLASS)
  16312. },
  16313. deleteItemAtIndex: function(index) {
  16314. var indices = splitIndex(index),
  16315. itemGroup = this._list.option("items")[indices.group].items;
  16316. itemGroup.splice(indices.item, 1)
  16317. },
  16318. updateSelectionAfterDelete: function(fromIndex) {
  16319. var deletedIndices = splitIndex(fromIndex),
  16320. selectedItemIndices = this._list._selectedItemIndices;
  16321. $.each(selectedItemIndices, function(i, index) {
  16322. var indices = splitIndex(index);
  16323. if (indices.group === deletedIndices.group && indices.item > deletedIndices.item)
  16324. selectedItemIndices[i] -= 1
  16325. })
  16326. },
  16327. fetchSelectedItems: function(indecies) {
  16328. indecies = indecies || this._list._selectedItemIndices;
  16329. var items = this._list.option("items"),
  16330. selectedItems = [];
  16331. indecies.sort(function(a, b) {
  16332. return a - b
  16333. });
  16334. var currentGroupIndex = 0,
  16335. groupSelectedIndices = [];
  16336. $.each(indecies, function(_, combinedIndex) {
  16337. var index = splitIndex(combinedIndex);
  16338. if (index.group !== currentGroupIndex && groupSelectedIndices.length) {
  16339. selectedItems.push(createGroupSelection(items[currentGroupIndex], groupSelectedIndices));
  16340. groupSelectedIndices.length = 0
  16341. }
  16342. currentGroupIndex = index.group;
  16343. groupSelectedIndices.push(index.item)
  16344. });
  16345. if (groupSelectedIndices.length)
  16346. selectedItems.push(createGroupSelection(items[currentGroupIndex], groupSelectedIndices));
  16347. return selectedItems
  16348. },
  16349. selectedItemIndecies: function() {
  16350. var selectedIndices = [],
  16351. items = this._list.option("items"),
  16352. selected = this._list.option("selectedItems");
  16353. $.each(selected, function(_, selectionInGroup) {
  16354. var group = groupByKey(items, selectionInGroup.key),
  16355. groupIndex = $.inArray(group, items);
  16356. if (!group)
  16357. throw new Error("Group with key '" + selectionInGroup.key + "' in which you are trying to select items does not exist.");
  16358. $.each(selectionInGroup.items, function(_, selectedGroupItem) {
  16359. var itemIndex = $.inArray(selectedGroupItem, group.items);
  16360. if (itemIndex !== -1)
  16361. selectedIndices.push(combineIndex({
  16362. group: groupIndex,
  16363. item: itemIndex
  16364. }));
  16365. else
  16366. throw new Error("Item '" + selectedGroupItem + "' you are trying to select in group '" + selectionInGroup.key + "' does not exist");
  16367. })
  16368. });
  16369. return selectedIndices
  16370. },
  16371. moveItemAtIndexToIndex: function(movingIndex, destinationIndex) {
  16372. var items = this._list.option("items"),
  16373. movingIndices = splitIndex(movingIndex),
  16374. destinationIndices = splitIndex(destinationIndex),
  16375. movingItemGroup = items[movingIndices.group].items,
  16376. destinationItemGroup = items[destinationIndices.group].items,
  16377. movedItemData = movingItemGroup[movingIndices.item];
  16378. movingItemGroup.splice(movingIndices.item, 1);
  16379. destinationItemGroup.splice(destinationIndices.item, 0, movedItemData)
  16380. },
  16381. getSelectedItemsAfterReorderItem: function(movingIndex, destinationIndex) {
  16382. if (this._itemsFromSameParent(movingIndex, destinationIndex) || $.inArray(movingIndex, this._list._selectedItemIndices))
  16383. return this.callBase();
  16384. var items = this._list.option("items"),
  16385. selectedItems = this._list.option("selectedItems"),
  16386. movingIndices = splitIndex(movingIndex),
  16387. destinationIndices = splitIndex(destinationIndex),
  16388. movingSelectedItemGroup = selectedItems[movingIndices.group].items,
  16389. destinationSelectedItemGroup = selectedItems[destinationIndices.group].items,
  16390. movedItemData = items[movingIndices.group].items[movingIndices.item],
  16391. movedItemSelectedIndex = $.inArray(movedItemData, movingSelectedItemGroup);
  16392. movingSelectedItemGroup.splice(movedItemSelectedIndex, 1);
  16393. destinationSelectedItemGroup.push(movedItemData);
  16394. return selectedItems
  16395. },
  16396. _isItemIndex: function(index) {
  16397. return $.isNumeric(index.group) && $.isNumeric(index.item)
  16398. },
  16399. _getNormalizedItemIndex: function(itemElement) {
  16400. var $item = $(itemElement),
  16401. $group = $item.closest("." + LIST_GROUP_CLASS);
  16402. return combineIndex({
  16403. group: this._groupElements().index($group),
  16404. item: this._groupItemElements($group).index($item)
  16405. })
  16406. },
  16407. _normalizeItemIndex: function(index) {
  16408. return combineIndex(index)
  16409. },
  16410. _denormalizeItemIndex: function(index) {
  16411. return splitIndex(index)
  16412. },
  16413. _getItemByNormalizedIndex: function(index) {
  16414. var indices = splitIndex(index),
  16415. $group = this._groupElements().eq(indices.group);
  16416. return this._groupItemElements($group).eq(indices.item)
  16417. },
  16418. _itemsFromSameParent: function(firstIndex, secondIndex) {
  16419. return splitIndex(firstIndex).group === splitIndex(secondIndex).group
  16420. }
  16421. })
  16422. })(jQuery, DevExpress);
  16423. /*! Module widgets-base, file ui.list.edit.decorators.js */
  16424. (function($, DX, undefined) {
  16425. var ui = DX.ui,
  16426. events = ui.events,
  16427. translator = DX.translator,
  16428. fx = DX.fx,
  16429. support = DX.support,
  16430. utils = DX.utils;
  16431. ui.ListEditDecoratorsRegistry = {};
  16432. var registerDecorator = function(option, type, decoratorClass) {
  16433. var decoratorsRegistry = ui.ListEditDecoratorsRegistry;
  16434. var decoratorConfig = {};
  16435. decoratorConfig[option] = decoratorsRegistry[option] ? decoratorsRegistry[option] : {};
  16436. decoratorConfig[option][type] = decoratorClass;
  16437. decoratorsRegistry = $.extend(decoratorsRegistry, decoratorConfig)
  16438. };
  16439. var LIST_ITEM_CONTENT_CLASS = "dx-list-item-content",
  16440. LIST_ITEM_BAG_CONTAINER_CLASS = "dx-list-item-bag-container";
  16441. var LIST_EDIT_DECORATOR = "dxListEditDecorator",
  16442. SWIPE_START_EVENT_NAME = events.addNamespace("dxswipestart", LIST_EDIT_DECORATOR),
  16443. SWIPE_UPDATE_EVENT_NAME = events.addNamespace("dxswipe", LIST_EDIT_DECORATOR),
  16444. SWIPE_END_EVENT_NAME = events.addNamespace("dxswipeend", LIST_EDIT_DECORATOR),
  16445. DRAG_START_EVENT_NAME = events.addNamespace("dxdragstart", LIST_EDIT_DECORATOR),
  16446. DRAG_UPDATE_EVENT_NAME = events.addNamespace("dxdrag", LIST_EDIT_DECORATOR),
  16447. DRAG_END_EVENT_NAME = events.addNamespace("dxdragend", LIST_EDIT_DECORATOR),
  16448. POINTER_DOWN_EVENT_NAME = events.addNamespace("dxpointerdown", LIST_EDIT_DECORATOR),
  16449. CLICK_EVENT_NAME = events.addNamespace("dxclick", LIST_EDIT_DECORATOR);
  16450. var ListEditDecorator = DX.Class.inherit({
  16451. ctor: function(list) {
  16452. this._list = list;
  16453. this._init()
  16454. },
  16455. _init: $.noop,
  16456. _shouldHandleSwipe: false,
  16457. _attachSwipeEvent: function(config) {
  16458. var swipeConfig = {itemSizeFunc: $.proxy(function() {
  16459. if (this._clearSwipeCache) {
  16460. this._itemWidthCache = this._list._element().width();
  16461. this._clearSwipeCache = false
  16462. }
  16463. return this._itemWidthCache
  16464. }, this)};
  16465. config.$itemElement.on(SWIPE_START_EVENT_NAME, swipeConfig, $.proxy(this._handleItemSwipeStart, this)).on(SWIPE_UPDATE_EVENT_NAME, $.proxy(this._handleItemSwipeUpdate, this)).on(SWIPE_END_EVENT_NAME, $.proxy(this._handleItemSwipeEnd, this))
  16466. },
  16467. _handleItemSwipeStart: function(e) {
  16468. var $itemElement = $(e.currentTarget);
  16469. if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *")) {
  16470. e.cancel = true;
  16471. return
  16472. }
  16473. this._handleSwipeStart($itemElement, e)
  16474. },
  16475. _handleItemSwipeUpdate: function(e) {
  16476. var $itemElement = $(e.currentTarget);
  16477. this._handleSwipeUpdate($itemElement, e)
  16478. },
  16479. _handleItemSwipeEnd: function(e) {
  16480. var $itemElement = $(e.currentTarget);
  16481. this._handleSwipeEnd($itemElement, e);
  16482. this._clearSwipeCache = true
  16483. },
  16484. beforeBag: $.noop,
  16485. afterBag: $.noop,
  16486. modifyElement: function(config) {
  16487. if (this._shouldHandleSwipe) {
  16488. this._attachSwipeEvent(config);
  16489. this._clearSwipeCache = true
  16490. }
  16491. },
  16492. handleClick: $.noop,
  16493. handleHold: $.noop,
  16494. _handleSwipeStart: $.noop,
  16495. _handleSwipeUpdate: $.noop,
  16496. _handleSwipeEnd: $.noop,
  16497. dispose: $.noop
  16498. });
  16499. var MENU_POSITIONING_CLASS = "dx-list-menu-positioning";
  16500. var MenuDecorator = ListEditDecorator.inherit({
  16501. _menuEnabled: function() {
  16502. return !!this._menuItems().length
  16503. },
  16504. _menuItems: function() {
  16505. return this._list.option("editConfig.menuItems")
  16506. },
  16507. _deleteEnabled: function() {
  16508. return this._list.option("editConfig.deleteEnabled")
  16509. },
  16510. _fireMenuAction: function($itemElement, action) {
  16511. this._list._handleItemEventByHandler($itemElement, action)
  16512. }
  16513. });
  16514. var SWITCHABLE_DELETE_READY_CLASS = "dx-list-switchable-delete-ready",
  16515. SWITCHABLE_DELETE_TOP_SHIELD_CLASS = "dx-list-switchable-delete-top-shield",
  16516. SWITCHABLE_DELETE_BOTTOM_SHIELD_CLASS = "dx-list-switchable-delete-bottom-shield",
  16517. SWITCHABLE_DELETE_ITEM_CONTENT_SHIELD_CLASS = "dx-list-switchable-delete-item-content-shield";
  16518. var SwitchableMenuDecorator = MenuDecorator.inherit({
  16519. _init: function() {
  16520. this._$topShield = $("<div />").addClass(SWITCHABLE_DELETE_TOP_SHIELD_CLASS);
  16521. this._$bottomShield = $("<div />").addClass(SWITCHABLE_DELETE_BOTTOM_SHIELD_CLASS);
  16522. this._$itemContentShield = $("<div />").addClass(SWITCHABLE_DELETE_ITEM_CONTENT_SHIELD_CLASS);
  16523. this._$topShield.on(POINTER_DOWN_EVENT_NAME, $.proxy(this._cancelDeleteReadyItem, this));
  16524. this._$bottomShield.on(POINTER_DOWN_EVENT_NAME, $.proxy(this._cancelDeleteReadyItem, this));
  16525. this._list._element().append(this._$topShield.toggle(false)).append(this._$bottomShield.toggle(false));
  16526. if (this._animatePrepareDeleteReady === DX.abstract)
  16527. this._animatePrepareDeleteReady = function() {
  16528. return $.when().promise()
  16529. };
  16530. if (this._animateForgetDeleteReady === DX.abstract)
  16531. this._animateForgetDeleteReady = function() {
  16532. return $.when().promise()
  16533. };
  16534. this._list._element().on("dxpreparetodelete", ".dx-list-item", $.proxy(function(e) {
  16535. this._toggleDeleteReady($(e.currentTarget))
  16536. }, this))
  16537. },
  16538. handleClick: function($itemElement) {
  16539. return this._cancelDeleteReadyItem()
  16540. },
  16541. _cancelDeleteReadyItem: function() {
  16542. if (!this._$readyToDeleteItem)
  16543. return false;
  16544. this._cancelDelete(this._$readyToDeleteItem);
  16545. return true
  16546. },
  16547. _cancelDelete: function($itemElement) {
  16548. this._toggleDeleteReady($itemElement, false)
  16549. },
  16550. _toggleDeleteReady: function($itemElement, readyToDelete) {
  16551. if (readyToDelete === undefined)
  16552. readyToDelete = !this._isReadyToDelete($itemElement);
  16553. this._toggleShields($itemElement, readyToDelete);
  16554. this._toggleScrolling(readyToDelete);
  16555. this._cacheReadyToDeleteItem($itemElement, readyToDelete);
  16556. this._animateToggleDelete($itemElement, readyToDelete)
  16557. },
  16558. _isReadyToDelete: function($itemElement) {
  16559. return $itemElement.hasClass(SWITCHABLE_DELETE_READY_CLASS)
  16560. },
  16561. _toggleShields: function($itemElement, enabled) {
  16562. this._$topShield.toggle(enabled);
  16563. this._$bottomShield.toggle(enabled);
  16564. if (enabled)
  16565. this._updateShieldsHeight($itemElement);
  16566. this._toggleContentShield($itemElement, enabled)
  16567. },
  16568. _updateShieldsHeight: function($itemElement) {
  16569. var $list = this._list._element(),
  16570. listTopOffset = $list.offset().top,
  16571. listHeight = $list.outerHeight(),
  16572. itemTopOffset = $itemElement.offset().top,
  16573. itemHeight = $itemElement.outerHeight(),
  16574. dirtyTopShieldHeight = itemTopOffset - listTopOffset,
  16575. dirtyBottomShieldHeight = listHeight - itemHeight - dirtyTopShieldHeight;
  16576. this._$topShield.height(Math.max(dirtyTopShieldHeight, 0));
  16577. this._$bottomShield.height(Math.max(dirtyBottomShieldHeight, 0))
  16578. },
  16579. _toggleContentShield: function($itemElement, enabled) {
  16580. if (enabled)
  16581. $itemElement.find("." + LIST_ITEM_CONTENT_CLASS).append(this._$itemContentShield);
  16582. else
  16583. this._$itemContentShield.detach()
  16584. },
  16585. _toggleScrolling: function(readyToDelete) {
  16586. var scrollView = this._list._element().dxScrollView("instance");
  16587. if (readyToDelete) {
  16588. this._scrollViewDisabled = scrollView.option("disabled");
  16589. scrollView.option("disabled", true)
  16590. }
  16591. else
  16592. scrollView.option("disabled", this._scrollViewDisabled)
  16593. },
  16594. _cacheReadyToDeleteItem: function($itemElement, cache) {
  16595. if (cache)
  16596. this._$readyToDeleteItem = $itemElement;
  16597. else
  16598. delete this._$readyToDeleteItem
  16599. },
  16600. _animateToggleDelete: function($itemElement, readyToDelete) {
  16601. if (readyToDelete) {
  16602. this._enablePositioning($itemElement);
  16603. this._prepareDeleteReady($itemElement);
  16604. this._animatePrepareDeleteReady($itemElement)
  16605. }
  16606. else {
  16607. this._forgetDeleteReady($itemElement);
  16608. this._animateForgetDeleteReady($itemElement).done($.proxy(this._disablePositioning, this, $itemElement))
  16609. }
  16610. },
  16611. _enablePositioning: function($itemElement) {
  16612. $itemElement.addClass(MENU_POSITIONING_CLASS)
  16613. },
  16614. _disablePositioning: function($itemElement) {
  16615. $itemElement.removeClass(MENU_POSITIONING_CLASS)
  16616. },
  16617. _prepareDeleteReady: function($itemElement) {
  16618. $itemElement.addClass(SWITCHABLE_DELETE_READY_CLASS)
  16619. },
  16620. _forgetDeleteReady: function($itemElement) {
  16621. $itemElement.removeClass(SWITCHABLE_DELETE_READY_CLASS)
  16622. },
  16623. _animatePrepareDeleteReady: DX.abstract,
  16624. _animateForgetDeleteReady: DX.abstract,
  16625. _deleteItem: function($itemElement) {
  16626. $itemElement = $itemElement || this._$readyToDeleteItem;
  16627. if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))
  16628. return;
  16629. this._cancelDelete($itemElement);
  16630. this._list.deleteItem($itemElement)
  16631. },
  16632. _isRtlEnabled: function() {
  16633. return this._list.option("rtlEnabled")
  16634. },
  16635. dispose: function() {
  16636. if (this._$topShield)
  16637. this._$topShield.remove();
  16638. if (this._$bottomShield)
  16639. this._$bottomShield.remove();
  16640. this.callBase.apply(this, arguments)
  16641. }
  16642. });
  16643. registerDecorator("menu", "_switchable", SwitchableMenuDecorator);
  16644. var SWITCHABLE_DELETE_BUTTON_CONTAINER_CLASS = "dx-list-switchable-delete-button-container",
  16645. SWITCHABLE_DELETE_BUTTON_WRAPPER_CLASS = "dx-list-switchable-delete-button-wrapper",
  16646. SWITCHABLE_DELETE_BUTTON_INNER_WRAPPER_CLASS = "dx-list-switchable-delete-button-inner-wrapper",
  16647. SWITCHABLE_DELETE_BUTTON_CLASS = "dx-list-switchable-delete-button",
  16648. SWITCHABLE_DELETE_MENU_CLASS = "dx-list-switchable-delete-menu",
  16649. SWITCHABLE_DELETE_BUTTON_ANIMATION_DURATION = 200;
  16650. var SwitchableButtonDeleteDecorator = SwitchableMenuDecorator.inherit({
  16651. _init: function() {
  16652. this.callBase.apply(this, arguments);
  16653. var $buttonContainer = $("<div >").addClass(SWITCHABLE_DELETE_BUTTON_CONTAINER_CLASS),
  16654. $buttonWrapper = $("<div />").addClass(SWITCHABLE_DELETE_BUTTON_WRAPPER_CLASS),
  16655. $buttonInnerWrapper = $("<div />").addClass(SWITCHABLE_DELETE_BUTTON_INNER_WRAPPER_CLASS),
  16656. $button = $("<div />").addClass(SWITCHABLE_DELETE_BUTTON_CLASS);
  16657. $button.dxButton({
  16658. text: Globalize.localize("dxListEditDecorator-delete"),
  16659. type: "danger",
  16660. clickAction: $.proxy(function(e) {
  16661. this._deleteItem();
  16662. e.jQueryEvent.stopPropagation()
  16663. }, this)
  16664. });
  16665. $buttonContainer.append($buttonWrapper);
  16666. $buttonWrapper.append($buttonInnerWrapper);
  16667. $buttonInnerWrapper.append($button);
  16668. this._$buttonContainer = $buttonContainer
  16669. },
  16670. _enablePositioning: function($itemElement) {
  16671. this.callBase.apply(this, arguments);
  16672. fx.stop(this._$buttonContainer, true);
  16673. this._$buttonContainer.appendTo($itemElement)
  16674. },
  16675. _disablePositioning: function() {
  16676. this.callBase.apply(this, arguments);
  16677. this._$buttonContainer.detach()
  16678. },
  16679. _animatePrepareDeleteReady: function() {
  16680. var rtl = this._isRtlEnabled(),
  16681. listWidth = this._list._element().width(),
  16682. buttonWidth = this._buttonWidth(),
  16683. fromValue = rtl ? listWidth : -buttonWidth,
  16684. toValue = rtl ? listWidth - buttonWidth : 0;
  16685. return fx.animate(this._$buttonContainer, {
  16686. type: "custom",
  16687. duration: SWITCHABLE_DELETE_BUTTON_ANIMATION_DURATION,
  16688. from: {right: fromValue},
  16689. to: {right: toValue}
  16690. })
  16691. },
  16692. _animateForgetDeleteReady: function() {
  16693. var rtl = this._isRtlEnabled(),
  16694. listWidth = this._list._element().width(),
  16695. buttonWidth = this._buttonWidth(),
  16696. fromValue = rtl ? listWidth - buttonWidth : 0,
  16697. toValue = rtl ? listWidth : -buttonWidth;
  16698. return fx.animate(this._$buttonContainer, {
  16699. type: "custom",
  16700. duration: SWITCHABLE_DELETE_BUTTON_ANIMATION_DURATION,
  16701. from: {right: fromValue},
  16702. to: {right: toValue}
  16703. })
  16704. },
  16705. _buttonWidth: function() {
  16706. if (!this._buttonContainerWidth)
  16707. this._buttonContainerWidth = this._$buttonContainer.outerWidth();
  16708. return this._buttonContainerWidth
  16709. },
  16710. dispose: function() {
  16711. if (this._$buttonContainer)
  16712. this._$buttonContainer.remove();
  16713. this.callBase.apply(this, arguments)
  16714. }
  16715. });
  16716. registerDecorator("menu", "_switchableButton", SwitchableButtonDeleteDecorator);
  16717. var TOGGLE_DELETE_SWITCH_CONTAINER_CLASS = "dx-list-toggle-delete-switch-container",
  16718. TOGGLE_DELETE_SWITCH_CLASS = "dx-list-toggle-delete-switch";
  16719. registerDecorator("delete", "toggle", SwitchableButtonDeleteDecorator.inherit({beforeBag: function(config) {
  16720. var $itemElement = config.$itemElement,
  16721. $container = config.$container;
  16722. var $toggle = $("<div />").dxButton({
  16723. icon: "toggle-delete",
  16724. clickAction: $.proxy(function(e) {
  16725. this._toggleDeleteReady($itemElement);
  16726. e.jQueryEvent.stopPropagation()
  16727. }, this)
  16728. }).addClass(TOGGLE_DELETE_SWITCH_CLASS);
  16729. $container.addClass(TOGGLE_DELETE_SWITCH_CONTAINER_CLASS);
  16730. $container.append($toggle)
  16731. }}));
  16732. registerDecorator("delete", "slideButton", SwitchableButtonDeleteDecorator.inherit({
  16733. _shouldHandleSwipe: true,
  16734. _handleSwipeEnd: function($itemElement, args) {
  16735. if (args.targetOffset !== 0)
  16736. this._toggleDeleteReady($itemElement);
  16737. return true
  16738. }
  16739. }));
  16740. var SLIDE_MENU_WRAPPER_CLASS = "dx-list-slide-menu-wrapper",
  16741. SLIDE_MENU_CONTENT_CLASS = "dx-list-slide-menu-content",
  16742. SLIDE_MENU_BUTTONS_CONTAINER_CLASS = "dx-list-slide-menu-buttons-container",
  16743. SLIDE_MENU_BUTTONS_CLASS = "dx-list-slide-menu-buttons",
  16744. SLIDE_MENU_BUTTON_CLASS = "dx-list-slide-menu-button",
  16745. SLIDE_MENU_BUTTON_MENU_CLASS = "dx-list-slide-menu-button-menu",
  16746. SLIDE_MENU_BUTTON_DELETE_CLASS = "dx-list-slide-menu-button-delete",
  16747. SLIDE_MENU_CLASS = "dx-list-slide-menu";
  16748. registerDecorator("menu", "slide", SwitchableMenuDecorator.inherit({
  16749. _shouldHandleSwipe: true,
  16750. _init: function() {
  16751. this.callBase.apply(this, arguments);
  16752. this._$buttonsContainer = $("<div/>").addClass(SLIDE_MENU_BUTTONS_CONTAINER_CLASS);
  16753. this._$buttons = $("<div/>").addClass(SLIDE_MENU_BUTTONS_CLASS).appendTo(this._$buttonsContainer);
  16754. this._renderMenu();
  16755. this._renderDeleteButton()
  16756. },
  16757. _renderMenu: function() {
  16758. if (!this._menuEnabled())
  16759. return;
  16760. var menuItems = this._menuItems();
  16761. if (menuItems.length === 1) {
  16762. var menuItem = menuItems[0];
  16763. this._renderMenuButton(menuItem.text, $.proxy(function() {
  16764. this._fireAction(menuItem)
  16765. }, this))
  16766. }
  16767. else {
  16768. var $menu = $("<div />").addClass(SLIDE_MENU_CLASS);
  16769. $menu.dxActionSheet({
  16770. showTitle: false,
  16771. items: menuItems,
  16772. itemClickAction: $.proxy(function(args) {
  16773. this._fireAction(args.itemData)
  16774. }, this)
  16775. });
  16776. $menu.appendTo(this._list._element());
  16777. this._menu = $menu.dxActionSheet("instance");
  16778. var $menuButton = this._renderMenuButton(Globalize.localize("dxListEditDecorator-more"), $.proxy(this._menu.show, this._menu));
  16779. this._menu.option("target", $menuButton)
  16780. }
  16781. },
  16782. _renderMenuButton: function(text, action) {
  16783. var $menuButton = $("<div/>").addClass(SLIDE_MENU_BUTTON_CLASS).addClass(SLIDE_MENU_BUTTON_MENU_CLASS).text(text);
  16784. this._$buttons.append($menuButton);
  16785. $menuButton.on(CLICK_EVENT_NAME, action);
  16786. return $menuButton
  16787. },
  16788. _renderDeleteButton: function() {
  16789. if (!this._deleteEnabled())
  16790. return;
  16791. var $deleteButton = $("<div/>").addClass(SLIDE_MENU_BUTTON_CLASS).addClass(SLIDE_MENU_BUTTON_DELETE_CLASS).text(Globalize.localize("dxListEditDecorator-delete"));
  16792. $deleteButton.on(CLICK_EVENT_NAME, $.proxy(function() {
  16793. this._deleteItem()
  16794. }, this));
  16795. this._$buttons.append($deleteButton)
  16796. },
  16797. _fireAction: function(menuItem) {
  16798. this._fireMenuAction($(this._cachedNode), menuItem.action);
  16799. this._cancelDeleteReadyItem()
  16800. },
  16801. modifyElement: function(config) {
  16802. this.callBase.apply(this, arguments);
  16803. var $itemElement = config.$itemElement;
  16804. $itemElement.addClass(SLIDE_MENU_WRAPPER_CLASS).removeClass(LIST_ITEM_BAG_CONTAINER_CLASS);
  16805. var $slideMenuContent = $("<div/>").addClass(SLIDE_MENU_CONTENT_CLASS).addClass(LIST_ITEM_BAG_CONTAINER_CLASS);
  16806. $itemElement.wrapInner($slideMenuContent)
  16807. },
  16808. handleClick: function(_, e) {
  16809. if ($(e.target).closest("." + SLIDE_MENU_CONTENT_CLASS).length)
  16810. return this.callBase.apply(this, arguments);
  16811. return true
  16812. },
  16813. _handleSwipeStart: function($itemElement) {
  16814. this._enablePositioning($itemElement);
  16815. this._cacheItemData($itemElement)
  16816. },
  16817. _handleSwipeUpdate: function($itemElement, args) {
  16818. var rtl = this._isRtlEnabled(),
  16819. signCorrection = rtl ? -1 : 1,
  16820. offset = this._cachedItemWidth * args.offset,
  16821. startOffset = this._isReadyToDelete($itemElement) ? -this._cachedButtonWidth * signCorrection : 0,
  16822. correctedOffset = (offset + startOffset) * signCorrection,
  16823. contentPosition = correctedOffset < 0 ? offset + startOffset : 0,
  16824. buttonPosition = correctedOffset < 0 ? correctedOffset : 0;
  16825. translator.move(this._$cachedContent, {left: contentPosition});
  16826. this._$buttonsContainer.css(rtl ? "right" : "left", Math.max(this._cachedItemWidth + buttonPosition, this._minButtonContainerLeftOffset()));
  16827. return true
  16828. },
  16829. _cacheItemData: function($itemElement) {
  16830. if ($itemElement[0] === this._cachedNode)
  16831. return;
  16832. this._$cachedContent = $itemElement.find("." + SLIDE_MENU_CONTENT_CLASS);
  16833. this._cachedItemWidth = $itemElement.outerWidth();
  16834. this._cachedButtonWidth = this._cachedButtonWidth || $itemElement.find("." + SLIDE_MENU_BUTTONS_CLASS).outerWidth();
  16835. if (this._$cachedContent.length)
  16836. this._cachedNode = $itemElement[0]
  16837. },
  16838. _minButtonContainerLeftOffset: function() {
  16839. return this._cachedItemWidth - this._cachedButtonWidth
  16840. },
  16841. _handleSwipeEnd: function($itemElement, args) {
  16842. this._cacheItemData($itemElement);
  16843. var signCorrection = this._isRtlEnabled() ? 1 : -1,
  16844. offset = this._cachedItemWidth * args.offset,
  16845. endedAtReadyToDelete = !this._isReadyToDelete($itemElement) && offset * signCorrection > this._cachedButtonWidth * .2,
  16846. readyToDelete = args.targetOffset === signCorrection || endedAtReadyToDelete;
  16847. this._toggleDeleteReady($itemElement, readyToDelete);
  16848. return true
  16849. },
  16850. _enablePositioning: function($itemElement) {
  16851. this.callBase.apply(this, arguments);
  16852. this._$buttonsContainer.appendTo($itemElement)
  16853. },
  16854. _disablePositioning: function($itemElement) {
  16855. this.callBase.apply(this, arguments);
  16856. this._$buttonsContainer.detach()
  16857. },
  16858. _animatePrepareDeleteReady: function() {
  16859. var rtl = this._isRtlEnabled(),
  16860. directionCorrection = rtl ? 1 : -1;
  16861. this._$buttonsContainer.css(rtl ? "left" : "right", "0");
  16862. var contentAnimation = fx.animate(this._$cachedContent, {
  16863. to: {left: this._cachedButtonWidth * directionCorrection},
  16864. type: "slide",
  16865. duration: 200
  16866. });
  16867. var direction = rtl ? "right" : "left",
  16868. buttonToAnimation = {};
  16869. buttonToAnimation[direction] = this._minButtonContainerLeftOffset();
  16870. var buttonAnimation = fx.animate(this._$buttonsContainer, {
  16871. to: buttonToAnimation,
  16872. duration: 200
  16873. });
  16874. return $.when(contentAnimation, buttonAnimation).promise()
  16875. },
  16876. _animateForgetDeleteReady: function($itemElement) {
  16877. this._cacheItemData($itemElement);
  16878. var rtl = this._isRtlEnabled();
  16879. this._$buttonsContainer.css(rtl ? "left" : "right", "0");
  16880. var contentAnimation = fx.animate(this._$cachedContent, {
  16881. to: {left: 0},
  16882. type: "slide",
  16883. duration: 200
  16884. });
  16885. var direction = rtl ? "right" : "left",
  16886. buttonToAnimation = {};
  16887. buttonToAnimation[direction] = this._cachedItemWidth;
  16888. var buttonAnimation = fx.animate(this._$buttonsContainer, {
  16889. to: buttonToAnimation,
  16890. duration: 200,
  16891. complete: $.proxy(function() {
  16892. this._$buttonsContainer.css(direction, "100%")
  16893. }, this)
  16894. });
  16895. return $.when(contentAnimation, buttonAnimation).promise()
  16896. },
  16897. dispose: function() {
  16898. if (this._menu)
  16899. this._menu._element().remove();
  16900. if (this._$buttonsContainer)
  16901. this._$buttonsContainer.remove();
  16902. this.callBase.apply(this, arguments)
  16903. }
  16904. }));
  16905. registerDecorator("delete", "swipe", ListEditDecorator.inherit({
  16906. _shouldHandleSwipe: true,
  16907. _renderItemPosition: function($itemElement, offset, animate) {
  16908. var deferred = $.Deferred(),
  16909. itemOffset = offset * this._itemElementWidth;
  16910. if (animate)
  16911. fx.animate($itemElement, {
  16912. to: {left: itemOffset},
  16913. type: "slide",
  16914. complete: function() {
  16915. deferred.resolve($itemElement, offset)
  16916. }
  16917. });
  16918. else {
  16919. translator.move($itemElement, {left: itemOffset});
  16920. deferred.resolve()
  16921. }
  16922. return deferred.promise()
  16923. },
  16924. _handleSwipeStart: function($itemElement) {
  16925. this._itemElementWidth = $itemElement.width();
  16926. return true
  16927. },
  16928. _handleSwipeUpdate: function($itemElement, args) {
  16929. this._renderItemPosition($itemElement, args.offset);
  16930. return true
  16931. },
  16932. _handleSwipeEnd: function($itemElement, args) {
  16933. var offset = args.targetOffset;
  16934. this._renderItemPosition($itemElement, offset, true).done($.proxy(function($itemElement, offset) {
  16935. if (Math.abs(offset))
  16936. this._list.deleteItem($itemElement)
  16937. }, this));
  16938. return true
  16939. }
  16940. }));
  16941. var HOLDDELETE_MENU = "dx-list-holddelete-menu",
  16942. HOLDDELETE_MENUCONTENT = "dx-list-holddelete-menucontent";
  16943. registerDecorator("menu", "hold", MenuDecorator.inherit({
  16944. _init: function() {
  16945. var $menu = $("<div/>").addClass(HOLDDELETE_MENU);
  16946. this._list._element().append($menu);
  16947. this._menu = this._renderOverlay($menu)
  16948. },
  16949. _renderOverlay: function($element) {
  16950. return $element.dxOverlay({
  16951. shading: false,
  16952. deferRendering: true,
  16953. closeOnTargetScroll: true,
  16954. closeOnOutsideClick: function(e) {
  16955. return !$(e.target).closest("." + HOLDDELETE_MENU).length
  16956. },
  16957. animation: {
  16958. show: {
  16959. type: "slide",
  16960. duration: 300,
  16961. from: {
  16962. height: 0,
  16963. opacity: 1
  16964. },
  16965. to: {
  16966. height: $.proxy(function() {
  16967. return this._$menuList.outerHeight()
  16968. }, this),
  16969. opacity: 1
  16970. }
  16971. },
  16972. hide: {
  16973. type: "slide",
  16974. duration: 0,
  16975. from: {opacity: 1},
  16976. to: {opacity: 0}
  16977. }
  16978. },
  16979. height: $.proxy(function() {
  16980. return this._$menuList ? this._$menuList.outerHeight() : 0
  16981. }, this),
  16982. width: $.proxy(function() {
  16983. return this._list._element().outerWidth()
  16984. }, this),
  16985. contentReadyAction: $.proxy(this._renderMenuContent, this)
  16986. }).dxOverlay("instance")
  16987. },
  16988. _renderMenuContent: function(e) {
  16989. var $overlayContent = e.component.content();
  16990. var items = this._menuItems().slice();
  16991. if (this._deleteEnabled())
  16992. items.push({
  16993. text: Globalize.localize("dxListEditDecorator-delete"),
  16994. action: $.proxy(this._deleteItem, this)
  16995. });
  16996. this._$menuList = $("<div>").dxList({
  16997. items: items,
  16998. itemClickAction: $.proxy(this._handleMenuItemClick, this),
  16999. height: "auto"
  17000. });
  17001. $overlayContent.addClass(HOLDDELETE_MENUCONTENT);
  17002. $overlayContent.append(this._$menuList)
  17003. },
  17004. _handleMenuItemClick: function(args) {
  17005. this._menu.hide();
  17006. this._fireMenuAction(this._$itemWithMenu, args.itemData.action)
  17007. },
  17008. _deleteItem: function() {
  17009. this._list.deleteItem(this._$itemWithMenu)
  17010. },
  17011. handleHold: function($itemElement) {
  17012. this._$itemWithMenu = $itemElement;
  17013. this._menu.option({position: {
  17014. my: "top",
  17015. at: "bottom",
  17016. of: $itemElement,
  17017. collision: "flip"
  17018. }});
  17019. this._menu.show();
  17020. return true
  17021. },
  17022. dispose: function() {
  17023. if (this._menu)
  17024. this._menu._element().remove();
  17025. this.callBase.apply(this, arguments)
  17026. }
  17027. }));
  17028. var LIST_ITEM_SELECTED_CLASS = "dx-list-item-selected",
  17029. SELECT_DECORATOR_ENABLED_CLASS = "dx-list-select-decorator-enabled",
  17030. SELECT_CHECKBOX_CONTAINER_CLASS = "dx-list-select-checkbox-container",
  17031. SELECT_CHECKBOX_CLASS = "dx-list-select-checkbox",
  17032. SELECT_RADIO_BUTTON_CONTAINER_CLASS = "dx-list-select-radio-button-container",
  17033. SELECT_RADIO_BUTTON_CLASS = "dx-list-select-radio-button";
  17034. registerDecorator("selection", "control", ListEditDecorator.inherit({
  17035. _init: function() {
  17036. this.callBase.apply(this, arguments);
  17037. var selectionMode = this._list.option("selectionMode");
  17038. this._singleStrategy = selectionMode === "single";
  17039. this._containerClass = this._singleStrategy ? SELECT_RADIO_BUTTON_CONTAINER_CLASS : SELECT_CHECKBOX_CONTAINER_CLASS;
  17040. this._controlClass = this._singleStrategy ? SELECT_RADIO_BUTTON_CLASS : SELECT_CHECKBOX_CLASS;
  17041. this._controlWidget = this._singleStrategy ? "dxRadioButton" : "dxCheckBox";
  17042. this._list._element().addClass(SELECT_DECORATOR_ENABLED_CLASS)
  17043. },
  17044. beforeBag: function(config) {
  17045. var $itemElement = config.$itemElement,
  17046. $container = config.$container;
  17047. var $control = $("<div />").addClass(this._controlClass);
  17048. $control[this._controlWidget]({
  17049. value: this._isSelected($itemElement),
  17050. valueChangeAction: $.proxy(function(e) {
  17051. this._processCheckedState($itemElement, e.value);
  17052. if (e.jQueryEvent)
  17053. e.jQueryEvent.stopPropagation()
  17054. }, this)
  17055. });
  17056. $container.addClass(this._containerClass);
  17057. $container.append($control)
  17058. },
  17059. modifyElement: function(config) {
  17060. this.callBase.apply(this, arguments);
  17061. var $itemElement = config.$itemElement,
  17062. control = $itemElement.find("." + this._controlClass)[this._controlWidget]("instance");
  17063. $itemElement.on("stateChanged", $.proxy(function() {
  17064. control.option("value", this._isSelected($itemElement))
  17065. }, this))
  17066. },
  17067. _isSelected: function($itemElement) {
  17068. return $itemElement.hasClass(LIST_ITEM_SELECTED_CLASS)
  17069. },
  17070. _processCheckedState: function($itemElement, checked) {
  17071. if (checked)
  17072. this._list.selectItem($itemElement);
  17073. else
  17074. this._list.unselectItem($itemElement)
  17075. },
  17076. dispose: function() {
  17077. this._list._element().removeClass(SELECT_DECORATOR_ENABLED_CLASS);
  17078. this.callBase.apply(this, arguments)
  17079. }
  17080. }));
  17081. registerDecorator("selection", "item", ui.ListEditDecoratorsRegistry.selection.control.inherit({handleClick: function($itemElement) {
  17082. var newState = !this._isSelected($itemElement) || this._singleStrategy;
  17083. this._processCheckedState($itemElement, newState);
  17084. return true
  17085. }}));
  17086. var REORDER_HANDLE_CONTAINER_CLASS = "dx-list-reorder-handle-container",
  17087. REORDER_HANDLE_CLASS = "dx-list-reorder-handle",
  17088. REOREDERING_ITEM_CLASS = "dx-list-item-reordering",
  17089. REOREDERING_ITEM_GHOST_CLASS = "dx-list-item-ghost-reordering",
  17090. LIST_REORDER_COMPATIBILITY_MODE_CLASS = "dx-list-reorder-compatibility-mode";
  17091. var fromRange = function(value, minValue, maxValue) {
  17092. return Math.min(Math.max(value, minValue), maxValue)
  17093. };
  17094. var ReorderScrollAnimator = DX.Animator.inherit({
  17095. ctor: function(strategy) {
  17096. this.callBase();
  17097. this._strategy = strategy
  17098. },
  17099. _isFinished: function() {
  17100. return this._strategy.scrollFinished()
  17101. },
  17102. _step: function() {
  17103. this._strategy.scrollByStep()
  17104. }
  17105. });
  17106. registerDecorator("reorder", "default", ListEditDecorator.inherit({
  17107. _init: function() {
  17108. this._groupedEnabled = this._list.option("grouped");
  17109. this._initAnimator()
  17110. },
  17111. _initAnimator: function() {
  17112. this._scrollAnimator = new ReorderScrollAnimator(this)
  17113. },
  17114. _startAnimator: function() {
  17115. if (!this._scrollAnimator.inProgress())
  17116. this._scrollAnimator.start()
  17117. },
  17118. _stopAnimator: function() {
  17119. this._scrollAnimator.stop()
  17120. },
  17121. afterBag: function(config) {
  17122. var $itemElement = config.$itemElement,
  17123. $container = config.$container;
  17124. var $handle = $("<div>").addClass(REORDER_HANDLE_CLASS);
  17125. $handle.on(DRAG_START_EVENT_NAME, {direction: "vertical"}, $.proxy(this._handleDragStart, this, $itemElement));
  17126. $handle.on(DRAG_UPDATE_EVENT_NAME, $.proxy(this._handleDrag, this, $itemElement));
  17127. $handle.on(DRAG_END_EVENT_NAME, $.proxy(this._handleDragEnd, this, $itemElement));
  17128. $container.addClass(REORDER_HANDLE_CONTAINER_CLASS);
  17129. $container.append($handle)
  17130. },
  17131. _handleDragStart: function($itemElement, e) {
  17132. this._stopPreviousAnimation();
  17133. e.targetElements = [];
  17134. this._cacheItemsPositions();
  17135. this._startPointerOffset = e.pageY - $itemElement.offset().top;
  17136. this._elementHeight = $itemElement.outerHeight();
  17137. var itemIndex = this._list.getFlatIndexByItemElement($itemElement);
  17138. this._startIndex = itemIndex;
  17139. this._lastIndex = itemIndex;
  17140. this._cacheScrollData();
  17141. this._createGhost($itemElement);
  17142. $itemElement.addClass(REOREDERING_ITEM_CLASS);
  17143. this._toggleCompatibilityMode(true)
  17144. },
  17145. _stopPreviousAnimation: function() {
  17146. fx.stop(this._$ghostItem, true)
  17147. },
  17148. _toggleCompatibilityMode: function(enabled) {
  17149. this._list._element().toggleClass(LIST_REORDER_COMPATIBILITY_MODE_CLASS, !support.transform3d && enabled)
  17150. },
  17151. _cacheItemsPositions: function() {
  17152. this._itemPositions = [];
  17153. $.each(this._list.itemElements(), $.proxy(function(index, item) {
  17154. this._itemPositions.push($(item).position().top)
  17155. }, this))
  17156. },
  17157. _getDraggingElementPosition: function() {
  17158. return this._itemPositions[this._startIndex]
  17159. },
  17160. _getLastElementPosition: function() {
  17161. return this._itemPositions[this._lastIndex]
  17162. },
  17163. _cacheScrollData: function() {
  17164. this._list.updateDimensions();
  17165. this._startScrollTop = this._list.scrollTop();
  17166. this._scrollOffset = 0;
  17167. this._scrollHeight = this._list.scrollHeight();
  17168. this._clientHeight = this._list.clientHeight()
  17169. },
  17170. _scrollTop: function() {
  17171. return this._startScrollTop + this._scrollOffset
  17172. },
  17173. _createGhost: function($itemElement) {
  17174. this._$ghostItem = $itemElement.clone();
  17175. this._$ghostItem.addClass(REOREDERING_ITEM_GHOST_CLASS).appendTo(this._list.itemsContainer());
  17176. this._startGhostPosition = this._getDraggingElementPosition() - this._$ghostItem.position().top;
  17177. translator.move(this._$ghostItem, {top: this._startGhostPosition})
  17178. },
  17179. _handleDrag: function($itemElement, e) {
  17180. this._topOffset = e.offset.y;
  17181. this._updateItemPositions();
  17182. var pointerPosition = this._getPonterPosition();
  17183. this._toggleScroll(pointerPosition)
  17184. },
  17185. _getPonterPosition: function() {
  17186. return this._getDraggingElementPosition() + this._startPointerOffset + this._scrollOffset + this._topOffset
  17187. },
  17188. _toggleScroll: function(pointerPosition) {
  17189. if (this._scrollHeight <= this._clientHeight)
  17190. return;
  17191. var minOffset = this._elementHeight * .7,
  17192. topOffset = this._clientHeight - (pointerPosition - this._scrollTop()),
  17193. topOffsetRatio = topOffset / minOffset,
  17194. bottomOffset = pointerPosition - this._scrollTop(),
  17195. bottomOffsetRatio = bottomOffset / minOffset;
  17196. if (topOffsetRatio < 1) {
  17197. this._stepSize = this._adjustRationIntoRange(topOffsetRatio);
  17198. this._startAnimator()
  17199. }
  17200. else if (bottomOffsetRatio < 1) {
  17201. this._stepSize = -this._adjustRationIntoRange(bottomOffsetRatio);
  17202. this._startAnimator()
  17203. }
  17204. else
  17205. this._stopAnimator()
  17206. },
  17207. _adjustRationIntoRange: function(ratio) {
  17208. return fromRange(Math.round(Math.abs(ratio - 1) * 7), 1, 7)
  17209. },
  17210. _updateItemPositions: function() {
  17211. this._updateGhostPosition();
  17212. this._updateOthersPositions()
  17213. },
  17214. _updateGhostPosition: function() {
  17215. translator.move(this._$ghostItem, {top: this._startGhostPosition + this._scrollOffset + this._topOffset})
  17216. },
  17217. _updateOthersPositions: function() {
  17218. var currentIndex = this._findItemIndexByPosition(this._getPonterPosition());
  17219. if (this._lastIndex === currentIndex || this._groupedEnabled && !this._sameParent(currentIndex))
  17220. return;
  17221. var currentIndexOffset = currentIndex - this._startIndex,
  17222. currentDirection = utils.sign(currentIndexOffset),
  17223. minIndex = Math.min(currentIndex, this._lastIndex),
  17224. maxIndex = Math.max(currentIndex, this._lastIndex);
  17225. for (var itemIndex = minIndex; itemIndex <= maxIndex; itemIndex++) {
  17226. if (itemIndex === this._startIndex)
  17227. continue;
  17228. var $item = this._list.getItemElementByFlatIndex(itemIndex),
  17229. itemIndexOffset = itemIndex - this._startIndex,
  17230. itemDirection = utils.sign(itemIndexOffset),
  17231. offsetsDifference = Math.abs(itemIndexOffset) <= Math.abs(currentIndexOffset),
  17232. sameDirections = currentDirection === itemDirection,
  17233. setupPosition = offsetsDifference && sameDirections,
  17234. resetPosition = !offsetsDifference || !sameDirections;
  17235. fx.stop($item);
  17236. if (setupPosition)
  17237. fx.animate($item, {
  17238. type: "slide",
  17239. to: {top: this._elementHeight * -currentDirection},
  17240. duration: 300
  17241. });
  17242. if (resetPosition)
  17243. fx.animate($item, {
  17244. type: "slide",
  17245. to: {top: 0},
  17246. duration: 300
  17247. })
  17248. }
  17249. this._lastIndex = currentIndex
  17250. },
  17251. _sameParent: function(index) {
  17252. var $dragging = this._list.getItemElementByFlatIndex(this._startIndex),
  17253. $over = this._list.getItemElementByFlatIndex(index);
  17254. return $over.parent().get(0) === $dragging.parent().get(0)
  17255. },
  17256. scrollByStep: function() {
  17257. this._scrollOffset += this._stepSize;
  17258. this._list.scrollBy(this._stepSize);
  17259. this._updateItemPositions()
  17260. },
  17261. scrollFinished: function() {
  17262. var scrollTop = this._scrollTop(),
  17263. rejectScrollTop = scrollTop <= 0 && this._stepSize < 0,
  17264. rejectScrollBottom = scrollTop >= this._scrollHeight - this._clientHeight && this._stepSize > 0;
  17265. return rejectScrollTop || rejectScrollBottom
  17266. },
  17267. _handleDragEnd: function($itemElement) {
  17268. this._scrollAnimator.stop();
  17269. fx.animate(this._$ghostItem, {
  17270. type: "slide",
  17271. to: {top: this._startGhostPosition + this._getLastElementPosition() - this._getDraggingElementPosition()},
  17272. duration: 300
  17273. }).done($.proxy(function() {
  17274. $itemElement.removeClass(REOREDERING_ITEM_CLASS);
  17275. this._resetPositions();
  17276. this._list.reorderItem($itemElement, this._list.getItemElementByFlatIndex(this._lastIndex));
  17277. this._deleteGhost();
  17278. this._toggleCompatibilityMode(false)
  17279. }, this))
  17280. },
  17281. _deleteGhost: function() {
  17282. this._$ghostItem.remove()
  17283. },
  17284. _resetPositions: function() {
  17285. var minIndex = Math.min(this._startIndex, this._lastIndex),
  17286. maxIndex = Math.max(this._startIndex, this._lastIndex);
  17287. for (var itemIndex = minIndex; itemIndex <= maxIndex; itemIndex++) {
  17288. var $item = this._list.getItemElementByFlatIndex(itemIndex);
  17289. translator.resetPosition($item)
  17290. }
  17291. },
  17292. _findItemIndexByPosition: function(position) {
  17293. var minIndex = 0;
  17294. var maxIndex = this._itemPositions.length - 1;
  17295. var currentIndex;
  17296. var currentPosition;
  17297. while (minIndex <= maxIndex) {
  17298. currentIndex = (minIndex + maxIndex) / 2 | 0;
  17299. currentPosition = this._itemPositions[currentIndex];
  17300. if (currentPosition < position)
  17301. minIndex = currentIndex + 1;
  17302. else if (currentPosition > position)
  17303. maxIndex = currentIndex - 1;
  17304. else
  17305. return currentIndex
  17306. }
  17307. return fromRange(minIndex, 0, Math.max(maxIndex, 0))
  17308. }
  17309. }))
  17310. })(jQuery, DevExpress);
  17311. /*! Module widgets-base, file ui.list.edit.provider.js */
  17312. (function($, DX, undefined) {
  17313. var ui = DX.ui,
  17314. events = ui.events,
  17315. utils = DX.utils;
  17316. var editOptionsRegistry = [];
  17317. var registerOption = function(enabledFunc, decoratorTypeFunc, decoratorSubTypeFunc) {
  17318. editOptionsRegistry.push({
  17319. enabled: enabledFunc,
  17320. decoratorType: decoratorTypeFunc,
  17321. decoratorSubType: decoratorSubTypeFunc
  17322. })
  17323. };
  17324. registerOption(function(config) {
  17325. return config.menuItems.length
  17326. }, function() {
  17327. return "menu"
  17328. }, function(config) {
  17329. return config.menuType
  17330. });
  17331. registerOption(function(config) {
  17332. return !config.menuItems.length && config.deleteEnabled
  17333. }, function(config, defaultConfig) {
  17334. var deleteType = config.deleteMode !== defaultConfig.deleteMode ? config.deleteMode : config.deleteType;
  17335. return deleteType === "toggle" || deleteType === "slideButton" || deleteType === "swipe" ? "delete" : "menu"
  17336. }, function(config, defaultConfig) {
  17337. var deleteType;
  17338. if (config.deleteMode !== defaultConfig.deleteMode) {
  17339. utils.logger.warn("'deleteMode' option is deprecated since 14.1. Use the 'deleteType' option instead.");
  17340. deleteType = config.deleteMode
  17341. }
  17342. else
  17343. deleteType = config.deleteType;
  17344. if (deleteType === "slideItem")
  17345. deleteType = "slide";
  17346. return deleteType
  17347. });
  17348. registerOption(function(config) {
  17349. return config.selectionEnabled
  17350. }, function() {
  17351. return "selection"
  17352. }, function(config, defaultConfig) {
  17353. var selectionType;
  17354. if (config.selectionMode !== defaultConfig.selectionMode) {
  17355. utils.logger.warn("'selectionMode' option is deprecated since 14.1. Use the 'selectionType' option instead.");
  17356. selectionType = config.selectionMode
  17357. }
  17358. else
  17359. selectionType = config.selectionType;
  17360. return selectionType
  17361. });
  17362. registerOption(function(config) {
  17363. return config.reorderEnabled
  17364. }, function() {
  17365. return "reorder"
  17366. }, function() {
  17367. return "default"
  17368. });
  17369. var LIST_ITEM_BAG_CONTAINER_CLASS = "dx-list-item-bag-container",
  17370. LIST_ITEM_CONTENT_CLASS = "dx-list-item-content",
  17371. LIST_ITEM_BEFORE_BAG_CLASS = "dx-list-item-before-bag",
  17372. LIST_ITEM_AFTER_BAG_CLASS = "dx-list-item-after-bag",
  17373. DECORATOR_BEFORE_BAG_CREATE_METHOD = "beforeBag",
  17374. DECORATOR_AFTER_BAG_CREATE_METHOD = "afterBag",
  17375. DECORATOR_MODIFY_ELEMENT_METHOD = "modifyElement";
  17376. ui.ListEditProvider = DX.Class.inherit({
  17377. ctor: function(list, config, defaultConfig) {
  17378. this._list = list;
  17379. this._config = config;
  17380. this._defaultConfig = defaultConfig;
  17381. if (this.isModifyingByDecorators())
  17382. this._fetchRequiredDecorators()
  17383. },
  17384. dispose: function() {
  17385. if (this._decorators && this._decorators.length)
  17386. $.each(this._decorators, function(_, decorator) {
  17387. decorator.dispose()
  17388. })
  17389. },
  17390. isModifyingByDecorators: function(itemData) {
  17391. return !(this.isRenderingByRenderer() || this.isRenderingByTemplate(itemData))
  17392. },
  17393. isRenderingByRenderer: function() {
  17394. return !!this.getItemRenderer()
  17395. },
  17396. getItemRenderer: function() {
  17397. return this._config.itemRender
  17398. },
  17399. isRenderingByTemplate: function(itemData) {
  17400. return !!this.getItemTemplateName(itemData)
  17401. },
  17402. getItemTemplateName: function(itemData) {
  17403. return itemData && itemData.editTemplate || this._config.itemTemplate
  17404. },
  17405. _fetchRequiredDecorators: function() {
  17406. this._decorators = [];
  17407. var config = this._config,
  17408. defaultConfig = this._defaultConfig;
  17409. $.each(editOptionsRegistry, $.proxy(function(_, option) {
  17410. var optionEnabled = option.enabled(config, defaultConfig);
  17411. if (optionEnabled) {
  17412. var decoratorType = option.decoratorType(config, defaultConfig),
  17413. decoratorSubType = option.decoratorSubType(config, defaultConfig),
  17414. decorator = this._createDecorator(decoratorType, decoratorSubType);
  17415. this._decorators.push(decorator)
  17416. }
  17417. }, this))
  17418. },
  17419. _createDecorator: function(type, subType) {
  17420. var decoratorClass = this._findDecorator(type, subType);
  17421. return new decoratorClass(this._list)
  17422. },
  17423. _findDecorator: function(type, subType) {
  17424. var foundDecorator = ui.ListEditDecoratorsRegistry[type][subType];
  17425. if (!foundDecorator)
  17426. throw new Error("Decorator with editing type: \"" + type + "\" and sub type: \"" + subType + "\" not found");
  17427. return foundDecorator
  17428. },
  17429. modifyItemElement: function(args) {
  17430. var $itemElement = $(args.itemElement);
  17431. $itemElement.addClass(LIST_ITEM_BAG_CONTAINER_CLASS);
  17432. this._wrapContent($itemElement);
  17433. var config = {$itemElement: $itemElement};
  17434. this._prependBeforeBags($itemElement, config);
  17435. this._appendAfterBags($itemElement, config);
  17436. this._applyDecorators(DECORATOR_MODIFY_ELEMENT_METHOD, config)
  17437. },
  17438. _wrapContent: function($itemElement) {
  17439. var $contentContainer = $("<div />").addClass(LIST_ITEM_CONTENT_CLASS);
  17440. $itemElement.wrapInner($contentContainer)
  17441. },
  17442. _prependBeforeBags: function($itemElement, config) {
  17443. var $beforeBags = this._collectDecoratorsMarkup(DECORATOR_BEFORE_BAG_CREATE_METHOD, config, LIST_ITEM_BEFORE_BAG_CLASS);
  17444. $itemElement.prepend($beforeBags)
  17445. },
  17446. _appendAfterBags: function($itemElement, config) {
  17447. var $afterBags = this._collectDecoratorsMarkup(DECORATOR_AFTER_BAG_CREATE_METHOD, config, LIST_ITEM_AFTER_BAG_CLASS);
  17448. $itemElement.append($afterBags)
  17449. },
  17450. _collectDecoratorsMarkup: function(method, config, containerClass) {
  17451. var $collector = $("<div />");
  17452. $.each(this._decorators, function() {
  17453. var $container = $("<div />").addClass(containerClass);
  17454. this[method]($.extend({$container: $container}, config));
  17455. if ($container.children().length)
  17456. $collector.append($container)
  17457. });
  17458. return $collector.children()
  17459. },
  17460. _applyDecorators: function(method, config) {
  17461. $.each(this._decorators, function() {
  17462. this[method](config)
  17463. })
  17464. },
  17465. _handlerExists: function(name) {
  17466. if (!this._decorators)
  17467. return false;
  17468. var decorators = this._decorators,
  17469. length = decorators.length;
  17470. for (var i = 0; i < length; i++)
  17471. if (decorators[i][name] !== $.noop)
  17472. return true;
  17473. return false
  17474. },
  17475. _handleEvent: function(name, $itemElement, e) {
  17476. if (!this._decorators)
  17477. return false;
  17478. var response = false,
  17479. decorators = this._decorators,
  17480. length = decorators.length;
  17481. for (var i = 0; i < length; i++) {
  17482. response = decorators[i][name]($itemElement, e);
  17483. if (response)
  17484. break
  17485. }
  17486. return response
  17487. },
  17488. handleClick: function($itemElement, e) {
  17489. return this._handleEvent("handleClick", $itemElement, e)
  17490. },
  17491. holdHandlerExists: function() {
  17492. return this._handlerExists("handleHold")
  17493. },
  17494. handleHold: function($itemElement, e) {
  17495. return this._handleEvent("handleHold", $itemElement, e)
  17496. }
  17497. })
  17498. })(jQuery, DevExpress);
  17499. /*! Module widgets-base, file ui.list.edit.js */
  17500. (function($, DX, undefined) {
  17501. var ui = DX.ui,
  17502. utils = DX.utils,
  17503. removeDublicates = utils.removeDublicates;
  17504. var LIST_EDITING_CLASS = "dx-list-editing",
  17505. LIST_ITEM_SELECTED_CLASS = "dx-list-item-selected",
  17506. LIST_ITEM_RESPONSE_WAIT_CLASS = "dx-list-item-response-wait";
  17507. DX.registerComponent("dxList", ui.dxList.inherit({
  17508. _setDefaultOptions: function() {
  17509. this.callBase();
  17510. this.option({
  17511. editEnabled: false,
  17512. editConfig: {
  17513. itemTemplate: null,
  17514. itemRender: null,
  17515. menuType: "hold",
  17516. menuItems: [],
  17517. deleteEnabled: false,
  17518. deleteMode: "toggle",
  17519. deleteType: "toggle",
  17520. selectionEnabled: false,
  17521. selectionMode: "item",
  17522. selectionType: "item",
  17523. reorderEnabled: false
  17524. },
  17525. itemDeleteAction: null,
  17526. selectionMode: 'multi',
  17527. selectedItems: [],
  17528. itemSelectAction: null,
  17529. itemUnselectAction: null,
  17530. itemReorderAction: null
  17531. })
  17532. },
  17533. _defaultOptionsRules: function() {
  17534. return this.callBase().slice(0).concat([{
  17535. device: {platform: "ios"},
  17536. options: {editConfig: {
  17537. deleteType: "slideButton",
  17538. deleteMode: "slideButton"
  17539. }}
  17540. }, {
  17541. device: {platform: "ios7"},
  17542. options: {editConfig: {
  17543. menuType: "slide",
  17544. deleteType: "slideItem",
  17545. deleteMode: "slideItem"
  17546. }}
  17547. }, {
  17548. device: {platform: "android"},
  17549. options: {editConfig: {
  17550. deleteType: "swipe",
  17551. deleteMode: "swipe"
  17552. }}
  17553. }, {
  17554. device: {platform: "win8"},
  17555. options: {editConfig: {
  17556. deleteType: "hold",
  17557. deleteMode: "hold"
  17558. }}
  17559. }, {
  17560. device: {platform: "generic"},
  17561. options: {editConfig: {
  17562. deleteType: "slideItem",
  17563. deleteMode: "slideItem"
  17564. }}
  17565. }])
  17566. },
  17567. _init: function() {
  17568. this.callBase();
  17569. this._initEditProvider();
  17570. this._initEditStrategy(this.option("grouped"));
  17571. this._initSelectedItems()
  17572. },
  17573. _initEditProvider: function() {
  17574. var defaultConfig = this.initialOption("editConfig");
  17575. this._editProvider = new ui.ListEditProvider(this, this.option("editConfig"), defaultConfig)
  17576. },
  17577. _disposeEditProvider: function() {
  17578. if (this._editProvider)
  17579. this._editProvider.dispose()
  17580. },
  17581. _refreshEditProvider: function() {
  17582. this._disposeEditProvider();
  17583. this._initEditProvider()
  17584. },
  17585. _initEditStrategy: function(grouped) {
  17586. var strategy = grouped ? ui.GroupedListEditStrategy : ui.PlainListEditStrategy;
  17587. this._editStrategy = new strategy(this)
  17588. },
  17589. _initSelectedItems: function() {
  17590. this._selectedItemIndices = this._editStrategy.selectedItemIndecies(this.option("selectedItems"))
  17591. },
  17592. _clearSelectedItems: function() {
  17593. this._selectedItemIndices = [];
  17594. this.option("selectedItems", [])
  17595. },
  17596. _render: function() {
  17597. this._renderEditing();
  17598. this.callBase();
  17599. this._normalizeSelectedItems()
  17600. },
  17601. _renderEditing: function() {
  17602. this._element().toggleClass(LIST_EDITING_CLASS, this.option("editEnabled"))
  17603. },
  17604. _handleItemClick: function(e) {
  17605. var $itemElement = $(e.currentTarget);
  17606. if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))
  17607. return;
  17608. var handledByEditProvider = this.option("editEnabled") && this._editProvider.handleClick($itemElement, e);
  17609. if (handledByEditProvider)
  17610. return;
  17611. this.callBase.apply(this, arguments)
  17612. },
  17613. _shouldAttachHoldEvent: function() {
  17614. return this.callBase.apply(this, arguments) || this._editProvider.holdHandlerExists()
  17615. },
  17616. _handleItemHold: function(e) {
  17617. var $itemElement = $(e.currentTarget);
  17618. if ($itemElement.is(".dx-state-disabled, .dx-state-disabled *"))
  17619. return;
  17620. var handledByEditProvider = this.option("editEnabled") && this._editProvider.handleHold($itemElement, e);
  17621. if (handledByEditProvider)
  17622. return;
  17623. this.callBase.apply(this, arguments)
  17624. },
  17625. _getItemRenderer: function() {
  17626. if (this.option("editEnabled") && this._editProvider.isRenderingByRenderer())
  17627. return this._editProvider.getItemRenderer();
  17628. return this.callBase.apply(this, arguments)
  17629. },
  17630. _getItemTemplateName: function(itemData) {
  17631. if (this.option("editEnabled") && this._editProvider.isRenderingByTemplate(itemData))
  17632. return this._editProvider.getItemTemplateName(itemData);
  17633. return this.callBase.apply(this, arguments)
  17634. },
  17635. _postprocessRenderItem: function(args) {
  17636. this.callBase.apply(this, arguments);
  17637. var $itemElement = $(args.itemElement);
  17638. if (this._isItemSelected(this._editStrategy.getNormalizedIndex($itemElement)))
  17639. $itemElement.addClass(LIST_ITEM_SELECTED_CLASS);
  17640. if (this.option("editEnabled") && this._editProvider.isModifyingByDecorators(args.itemData))
  17641. this._editProvider.modifyItemElement(args)
  17642. },
  17643. _dispose: function() {
  17644. this._disposeEditProvider();
  17645. this.callBase.apply(this, arguments)
  17646. },
  17647. _optionChanged: function(name, value, prevValue) {
  17648. switch (name) {
  17649. case"rtlEnabled":
  17650. this._refreshEditProvider();
  17651. this.callBase.apply(this, arguments);
  17652. break;
  17653. case"items":
  17654. this._clearSelectedItems();
  17655. this.callBase.apply(this, arguments);
  17656. break;
  17657. case"grouped":
  17658. this._clearSelectedItems();
  17659. delete this._renderingGroupIndex;
  17660. this._initEditStrategy(value);
  17661. this.callBase.apply(this, arguments);
  17662. break;
  17663. case"editEnabled":
  17664. this._clearSelectedItems();
  17665. this._refreshEditProvider();
  17666. this._invalidate();
  17667. break;
  17668. case"editConfig":
  17669. this._refreshEditProvider();
  17670. this._invalidate();
  17671. break;
  17672. case"selectionMode":
  17673. this._refreshEditProvider();
  17674. this._invalidate();
  17675. break;
  17676. case"selectedItems":
  17677. this._normalizeSelectedItems();
  17678. break;
  17679. case"itemDeleteAction":
  17680. case"itemSelectAction":
  17681. case"itemUnselectAction":
  17682. case"itemReorderAction":
  17683. break;
  17684. default:
  17685. this.callBase.apply(this, arguments)
  17686. }
  17687. },
  17688. _isItemSelected: function(index) {
  17689. return $.inArray(index, this._selectedItemIndices) > -1
  17690. },
  17691. _normalizeSelectedItems: function() {
  17692. if (this.option("selectionMode") === "single") {
  17693. var newSelection = this._editStrategy.selectedItemIndecies(this.option("selectedItems"));
  17694. if (newSelection.length > 1) {
  17695. var normalizedSelection = [newSelection[0]];
  17696. this.option("selectedItems", this._editStrategy.fetchSelectedItems(normalizedSelection))
  17697. }
  17698. else
  17699. this._updateSelectedItems()
  17700. }
  17701. else
  17702. this._updateSelectedItems()
  17703. },
  17704. _updateSelectedItems: function() {
  17705. var that = this,
  17706. oldSelection = this._selectedItemIndices.slice(),
  17707. newSelection = this._editStrategy.selectedItemIndecies();
  17708. var unselected = removeDublicates(oldSelection, newSelection);
  17709. $.each(unselected, function(_, normalizedIndex) {
  17710. that._unselectItem(normalizedIndex)
  17711. });
  17712. var selected = removeDublicates(newSelection, oldSelection);
  17713. $.each(selected, function(_, normalizedIndex) {
  17714. that._selectItem(normalizedIndex)
  17715. })
  17716. },
  17717. _updateSelectionAfterDelete: function(fromIndex) {
  17718. var that = this,
  17719. itemIndex = $.inArray(fromIndex, this._selectedItemIndices);
  17720. if (itemIndex > -1)
  17721. this._selectedItemIndices.splice(itemIndex, 1);
  17722. this._editStrategy.updateSelectionAfterDelete(fromIndex);
  17723. this.option("selectedItems", this._editStrategy.fetchSelectedItems())
  17724. },
  17725. _selectItem: function(normalizedIndex) {
  17726. var $itemElement = this._editStrategy.getItemElement(normalizedIndex);
  17727. if (this.option("editEnabled") && normalizedIndex > -1 && !this._isItemSelected(normalizedIndex)) {
  17728. $itemElement.addClass(LIST_ITEM_SELECTED_CLASS);
  17729. this._selectedItemIndices.push(normalizedIndex);
  17730. $itemElement.trigger("stateChanged");
  17731. this._handleItemEvent($itemElement, "itemSelectAction", {}, {excludeValidators: ["gesture", "disabled"]})
  17732. }
  17733. },
  17734. _unselectItem: function(normalizedIndex) {
  17735. var $itemElement = this._editStrategy.getItemElement(normalizedIndex),
  17736. itemSelectionIndex = $.inArray(normalizedIndex, this._selectedItemIndices);
  17737. if (this.option("editEnabled") && itemSelectionIndex > -1) {
  17738. $itemElement.removeClass(LIST_ITEM_SELECTED_CLASS);
  17739. this._selectedItemIndices.splice(itemSelectionIndex, 1);
  17740. $itemElement.trigger("stateChanged");
  17741. this._handleItemEvent($itemElement, "itemUnselectAction", {}, {excludeValidators: ["gesture", "disabled"]})
  17742. }
  17743. },
  17744. _deleteItemFromDS: function($item) {
  17745. var that = this,
  17746. deferred = $.Deferred(),
  17747. disabledState = this.option("disabled"),
  17748. dataStore = this._dataSource.store();
  17749. this.option("disabled", true);
  17750. if (!dataStore.remove)
  17751. throw new Error("You have to implement 'remove' method in dataStore used by dxList to be able to delete items");
  17752. dataStore.remove(dataStore.keyOf(this._getItemData($item))).done(function(key) {
  17753. if (key !== undefined)
  17754. deferred.resolveWith(that);
  17755. else
  17756. deferred.rejectWith(that)
  17757. }).fail(function() {
  17758. deferred.rejectWith(that)
  17759. });
  17760. deferred.always(function() {
  17761. that.option("disabled", disabledState)
  17762. });
  17763. return deferred
  17764. },
  17765. _refreshLastPage: function() {
  17766. this._expectLastItemLoading();
  17767. return this._dataSource.load()
  17768. },
  17769. getFlatIndexByItemElement: function(itemElement) {
  17770. return this._itemElements().index(itemElement)
  17771. },
  17772. getItemElementByFlatIndex: function(flatIndex) {
  17773. var $itemElements = this._itemElements();
  17774. if (flatIndex < 0 || flatIndex >= $itemElements.length)
  17775. return $();
  17776. return $itemElements.eq(flatIndex)
  17777. },
  17778. getItemByIndex: function(index) {
  17779. return this._getItemData(this._itemElements().eq(index))
  17780. },
  17781. deleteItem: function(itemElement) {
  17782. var that = this,
  17783. deferred = $.Deferred(),
  17784. $item = this._editStrategy.getItemElement(itemElement),
  17785. index = this._editStrategy.getNormalizedIndex(itemElement),
  17786. changingOption;
  17787. if (this.option("editEnabled") && index > -1) {
  17788. $item.addClass(LIST_ITEM_RESPONSE_WAIT_CLASS);
  17789. if (this._dataSource) {
  17790. changingOption = "dataSource";
  17791. deferred = this._deleteItemFromDS($item)
  17792. }
  17793. else {
  17794. changingOption = "items";
  17795. deferred.resolveWith(this)
  17796. }
  17797. }
  17798. else
  17799. deferred.rejectWith(this);
  17800. deferred.done(function() {
  17801. $item.detach();
  17802. that._editStrategy.deleteItemAtIndex(index);
  17803. that.optionChanged.fireWith(that, [changingOption, that.option(changingOption)]);
  17804. that._updateSelectionAfterDelete(index);
  17805. that._handleItemEvent($item, "itemDeleteAction", {}, {excludeValidators: ["gesture", "disabled"]});
  17806. that._renderEmptyMessage()
  17807. }).fail(function() {
  17808. $item.removeClass(LIST_ITEM_RESPONSE_WAIT_CLASS)
  17809. });
  17810. if (this._isLastPage() || this.option("grouped"))
  17811. return deferred.promise();
  17812. var pageRefreshDeffered = $.Deferred();
  17813. deferred.done(function() {
  17814. that._refreshLastPage().done(function() {
  17815. pageRefreshDeffered.resolveWith(that)
  17816. })
  17817. }).fail(function() {
  17818. pageRefreshDeffered.rejectWith(that)
  17819. });
  17820. return pageRefreshDeffered.promise()
  17821. },
  17822. isItemSelected: function(itemElement) {
  17823. return this._isItemSelected(this._editStrategy.getNormalizedIndex(itemElement))
  17824. },
  17825. selectItem: function(itemElement) {
  17826. if (!this.option("editEnabled"))
  17827. return;
  17828. var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);
  17829. if (itemIndex === -1)
  17830. return;
  17831. var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);
  17832. if (itemSelectionIndex !== -1)
  17833. return;
  17834. if (this.option("selectionMode") === "single")
  17835. this.option("selectedItems", this._editStrategy.fetchSelectedItems([itemIndex]));
  17836. else {
  17837. var newSelectedIndices = this._selectedItemIndices.slice();
  17838. newSelectedIndices.push(itemIndex);
  17839. this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))
  17840. }
  17841. },
  17842. unselectItem: function(itemElement) {
  17843. if (!this.option("editEnabled"))
  17844. return;
  17845. var itemIndex = this._editStrategy.getNormalizedIndex(itemElement);
  17846. if (itemIndex === -1)
  17847. return;
  17848. var itemSelectionIndex = $.inArray(itemIndex, this._selectedItemIndices);
  17849. if (itemSelectionIndex === -1)
  17850. return;
  17851. var newSelectedIndices = this._selectedItemIndices.slice();
  17852. newSelectedIndices.splice(itemSelectionIndex, 1);
  17853. this.option("selectedItems", this._editStrategy.fetchSelectedItems(newSelectedIndices))
  17854. },
  17855. reorderItem: function(itemElement, toItemElement) {
  17856. var deferred = $.Deferred(),
  17857. that = this,
  17858. strategy = this._editStrategy,
  17859. $movingItem = strategy.getItemElement(itemElement),
  17860. $destinationItem = strategy.getItemElement(toItemElement),
  17861. movingIndex = strategy.getNormalizedIndex(itemElement),
  17862. destinationIndex = strategy.getNormalizedIndex(toItemElement),
  17863. changingOption;
  17864. var canMoveItems = movingIndex > -1 && destinationIndex > -1 && movingIndex !== destinationIndex;
  17865. if (this.option("editEnabled") && canMoveItems)
  17866. if (this._dataSource) {
  17867. changingOption = "dataSource";
  17868. deferred.resolveWith(this)
  17869. }
  17870. else {
  17871. changingOption = "items";
  17872. deferred.resolveWith(this)
  17873. }
  17874. else
  17875. deferred.rejectWith(this);
  17876. return deferred.promise().done(function() {
  17877. $destinationItem[strategy.itemPlacementFunc(movingIndex, destinationIndex)]($movingItem);
  17878. var newSelectedItems = strategy.getSelectedItemsAfterReorderItem(movingIndex, destinationIndex);
  17879. strategy.moveItemAtIndexToIndex(movingIndex, destinationIndex);
  17880. that._selectedItemIndices = strategy.selectedItemIndecies(newSelectedItems);
  17881. that.option("selectedItems", strategy.fetchSelectedItems());
  17882. that.optionChanged.fireWith(that, [changingOption, that.option(changingOption)]);
  17883. that._handleItemEvent($movingItem, "itemReorderAction", {
  17884. fromIndex: strategy.getIndex(movingIndex),
  17885. toIndex: strategy.getIndex(destinationIndex)
  17886. }, {excludeValidators: ["gesture", "disabled"]})
  17887. })
  17888. }
  17889. }))
  17890. })(jQuery, DevExpress);
  17891. /*! Module widgets-base, file ui.gallery.js */
  17892. (function($, DX, undefined) {
  17893. var ui = DX.ui,
  17894. utils = DX.utils,
  17895. events = ui.events,
  17896. fx = DX.fx,
  17897. translator = DX.translator,
  17898. GALLERY_CLASS = "dx-gallery",
  17899. GALLERY_WRAPPER_CLASS = GALLERY_CLASS + "-wrapper",
  17900. GALLERY_LOOP_CLASS = "dx-gallery-loop",
  17901. GALLERY_ITEM_CONTAINER_CLASS = GALLERY_CLASS + "-container",
  17902. GALLERY_ACTIVE_CLASS = GALLERY_CLASS + "-active",
  17903. GALLERY_ITEM_CLASS = GALLERY_CLASS + "-item",
  17904. GALLERY_LOOP_ITEM_CLASS = GALLERY_ITEM_CLASS + "-loop",
  17905. GALLERY_ITEM_SELECTOR = "." + GALLERY_ITEM_CLASS,
  17906. GALLERY_ITEM_SELECTED_CLASS = GALLERY_ITEM_CLASS + "-selected",
  17907. GALLERY_INDICATOR_CLASS = GALLERY_CLASS + "-indicator",
  17908. GALLERY_INDICATOR_ITEM_CLASS = GALLERY_INDICATOR_CLASS + "-item",
  17909. GALLERY_INDICATOR_ITEM_SELECTOR = "." + GALLERY_INDICATOR_ITEM_CLASS,
  17910. GALLERY_INDICATOR_ITEM_SELECTED_CLASS = GALLERY_INDICATOR_ITEM_CLASS + "-selected",
  17911. GALLERY_ITEM_DATA_KEY = "dxGalleryItemData";
  17912. DX.registerComponent("dxGalleryNavButton", ui.Widget.inherit({
  17913. _setDefaultOptions: function() {
  17914. this.callBase();
  17915. this.option({
  17916. direction: "next",
  17917. clickAction: null,
  17918. hoverStateEnabled: true
  17919. })
  17920. },
  17921. _render: function() {
  17922. this.callBase();
  17923. var that = this,
  17924. $element = this._element(),
  17925. eventName = events.addNamespace("dxclick", this.NAME);
  17926. $element.addClass(GALLERY_CLASS + "-nav-button-" + this.option("direction")).off(eventName).on(eventName, function(e) {
  17927. that._createActionByOption("clickAction")({jQueryEvent: e})
  17928. })
  17929. },
  17930. _optionChanged: function(name, value, prevValue) {
  17931. switch (name) {
  17932. case"clickAction":
  17933. case"direction":
  17934. this._invalidate();
  17935. break;
  17936. default:
  17937. this.callBase(name, value, prevValue)
  17938. }
  17939. }
  17940. }));
  17941. DX.registerComponent("dxGallery", ui.CollectionContainerWidget.inherit({
  17942. _activeStateUnit: GALLERY_ITEM_SELECTOR,
  17943. _setDefaultOptions: function() {
  17944. this.callBase();
  17945. this.option({
  17946. activeStateEnabled: false,
  17947. animationDuration: 400,
  17948. loop: false,
  17949. swipeEnabled: true,
  17950. indicatorEnabled: true,
  17951. showIndicator: true,
  17952. selectedIndex: 0,
  17953. slideshowDelay: 0,
  17954. showNavButtons: false
  17955. })
  17956. },
  17957. _dataSourceOptions: function() {
  17958. return {paginate: false}
  17959. },
  17960. _itemContainer: function() {
  17961. return this._$container
  17962. },
  17963. _itemClass: function() {
  17964. return GALLERY_ITEM_CLASS
  17965. },
  17966. _itemDataKey: function() {
  17967. return GALLERY_ITEM_DATA_KEY
  17968. },
  17969. _itemWidth: function() {
  17970. if (!this._itemWidthCache)
  17971. this._itemWidthCache = this._itemElements().first().outerWidth();
  17972. return this._itemWidthCache
  17973. },
  17974. _clearItemWidthCache: function() {
  17975. delete this._itemWidthCache
  17976. },
  17977. _itemsCount: function() {
  17978. return (this.option("items") || []).length
  17979. },
  17980. _offsetDirection: function() {
  17981. return this.option("rtlEnabled") ? -1 : 1
  17982. },
  17983. _itemRenderDefault: function(item, index, itemElement) {
  17984. itemElement.append($("<img />").attr("src", String(item)))
  17985. },
  17986. _renderSelectedIndex: $.noop,
  17987. _render: function() {
  17988. this._element().addClass(GALLERY_CLASS);
  17989. this._element().toggleClass(GALLERY_LOOP_CLASS, this.option("loop"));
  17990. this._renderDragHandler();
  17991. this._renderWrapper();
  17992. this._renderItemContainer();
  17993. this.callBase();
  17994. this._renderContainerPosition();
  17995. this._renderItemPositions();
  17996. this._renderIndicator();
  17997. this._renderSelectedIndicatorItem();
  17998. this._renderUserInteraction();
  17999. this._renderNavButtons();
  18000. this._setupSlideShow();
  18001. this._reviseDimensions()
  18002. },
  18003. _dimensionChanged: function() {
  18004. this._clearItemWidthCache();
  18005. this._renderDuplicateItems();
  18006. this._renderItemPositions();
  18007. this._renderContainerPosition()
  18008. },
  18009. _renderDragHandler: function() {
  18010. var eventName = events.addNamespace("dragstart", this.NAME);
  18011. this._element().off(eventName).on(eventName, "img", function() {
  18012. return false
  18013. })
  18014. },
  18015. _renderWrapper: function() {
  18016. if (this._$wrapper)
  18017. return;
  18018. this._$wrapper = $("<div />").addClass(GALLERY_WRAPPER_CLASS).appendTo(this._element())
  18019. },
  18020. _renderItems: function(items) {
  18021. this.callBase(items);
  18022. this._renderDuplicateItems()
  18023. },
  18024. _renderItemContainer: function() {
  18025. if (this._$container)
  18026. return;
  18027. this._$container = $("<div>").addClass(GALLERY_ITEM_CONTAINER_CLASS).appendTo(this._$wrapper)
  18028. },
  18029. _renderDuplicateItems: function() {
  18030. var items = this.option("items") || [],
  18031. itemsCount = items.length;
  18032. if (!itemsCount)
  18033. return;
  18034. this._element().find("." + GALLERY_LOOP_ITEM_CLASS).remove();
  18035. var itemsPerPage = this._element().width() / this._itemWidth(),
  18036. duplicateCount = Math.min(itemsPerPage, itemsCount);
  18037. for (var i = 0; i < duplicateCount; i++)
  18038. this._renderItem(0, items[i]).addClass(GALLERY_LOOP_ITEM_CLASS);
  18039. this._renderItem(0, items[this._itemsCount() - 1]).addClass(GALLERY_LOOP_ITEM_CLASS)
  18040. },
  18041. _renderItemPositions: function() {
  18042. var itemWidth = this._itemWidth(),
  18043. loopItemsCount = this._element().find("." + GALLERY_LOOP_ITEM_CLASS).length,
  18044. lastItemDuplicateIndex = this._itemsCount() + loopItemsCount - 1,
  18045. offsetDirection = this._offsetDirection();
  18046. this._itemElements().each(function(index) {
  18047. var realIndex = index;
  18048. if (index === lastItemDuplicateIndex)
  18049. realIndex = -1;
  18050. translator.move($(this), {left: offsetDirection * realIndex * itemWidth})
  18051. })
  18052. },
  18053. _renderContainerPosition: function(offset, animate) {
  18054. offset = offset || 0;
  18055. var that = this,
  18056. itemWidth = this._itemWidth(),
  18057. selectedIndex = this.option("selectedIndex"),
  18058. targetIndex = offset - selectedIndex,
  18059. targetPosition = this._offsetDirection() * targetIndex * itemWidth,
  18060. positionReady;
  18061. if (animate) {
  18062. that._startSwipe();
  18063. positionReady = that._animate(targetPosition).done($.proxy(that._endSwipe, that))
  18064. }
  18065. else {
  18066. translator.move(this._$container, {left: targetPosition});
  18067. positionReady = $.Deferred().resolveWith(that)
  18068. }
  18069. return positionReady.promise()
  18070. },
  18071. _startSwipe: function() {
  18072. this._element().addClass(GALLERY_ACTIVE_CLASS)
  18073. },
  18074. _endSwipe: function() {
  18075. this._element().removeClass(GALLERY_ACTIVE_CLASS)
  18076. },
  18077. _animate: function(targetPosition, extraConfig) {
  18078. var that = this,
  18079. animationComplete = $.Deferred();
  18080. fx.animate(this._$container, $.extend({
  18081. type: "slide",
  18082. to: {left: targetPosition},
  18083. duration: that.option("animationDuration"),
  18084. complete: function() {
  18085. animationComplete.resolveWith(that)
  18086. }
  18087. }, extraConfig || {}));
  18088. return animationComplete
  18089. },
  18090. _reviseDimensions: function() {
  18091. var that = this,
  18092. $firstItem = that._itemElements().first();
  18093. if (!$firstItem)
  18094. return;
  18095. if (!that.option("height"))
  18096. that.option("height", $firstItem.outerHeight());
  18097. if (!that.option("width"))
  18098. that.option("width", $firstItem.outerWidth());
  18099. this._dimensionChanged()
  18100. },
  18101. _renderIndicator: function() {
  18102. if (!this.option("showIndicator")) {
  18103. this._cleanIndicators();
  18104. return
  18105. }
  18106. var indicator = this._$indicator = $("<div>").addClass(GALLERY_INDICATOR_CLASS).appendTo(this._$wrapper);
  18107. $.each(this.option("items") || [], function() {
  18108. $("<div>").addClass(GALLERY_INDICATOR_ITEM_CLASS).appendTo(indicator)
  18109. })
  18110. },
  18111. _cleanIndicators: function() {
  18112. if (this._$indicator)
  18113. this._$indicator.remove()
  18114. },
  18115. _renderSelectedIndicatorItem: function() {
  18116. var selectedIndex = this.option("selectedIndex");
  18117. this._itemElements().removeClass(GALLERY_ITEM_SELECTED_CLASS).eq(selectedIndex).addClass(GALLERY_ITEM_SELECTED_CLASS);
  18118. this._element().find(GALLERY_INDICATOR_ITEM_SELECTOR).removeClass(GALLERY_INDICATOR_ITEM_SELECTED_CLASS).eq(selectedIndex).addClass(GALLERY_INDICATOR_ITEM_SELECTED_CLASS)
  18119. },
  18120. _renderUserInteraction: function() {
  18121. var that = this,
  18122. rootElement = that._element(),
  18123. swipeEnabled = that.option("swipeEnabled") && this._itemsCount() > 1,
  18124. cursor = swipeEnabled ? "pointer" : "default";
  18125. rootElement.dxSwipeable({
  18126. disabled: this.option("disabled") || !swipeEnabled,
  18127. startAction: $.proxy(that._handleSwipeStart, that),
  18128. updateAction: $.proxy(that._handleSwipeUpdate, that),
  18129. endAction: $.proxy(that._handleSwipeEnd, that),
  18130. itemSizeFunc: $.proxy(that._itemWidth, that)
  18131. });
  18132. var indicatorSelectAction = this._createAction(this._handleIndicatorSelect);
  18133. rootElement.find(GALLERY_INDICATOR_ITEM_SELECTOR).off(events.addNamespace("dxclick", this.NAME)).on(events.addNamespace("dxclick", this.NAME), function(e) {
  18134. indicatorSelectAction({jQueryEvent: e})
  18135. })
  18136. },
  18137. _handleIndicatorSelect: function(args) {
  18138. var e = args.jQueryEvent,
  18139. instance = args.component;
  18140. if (events.needSkipEvent(e))
  18141. return;
  18142. if (!instance.option("indicatorEnabled"))
  18143. return;
  18144. var index = $(e.target).index();
  18145. instance._renderContainerPosition(instance.option("selectedIndex") - index, true).done(function() {
  18146. this._suppressRenderItemPositions = true;
  18147. instance.option("selectedIndex", index)
  18148. })
  18149. },
  18150. _renderNavButtons: function() {
  18151. var that = this;
  18152. if (!that.option("showNavButtons")) {
  18153. that._cleanNavButtons();
  18154. return
  18155. }
  18156. that._prevNavButton = $("<div />").dxGalleryNavButton({
  18157. direction: "prev",
  18158. clickAction: function() {
  18159. that.prevItem(true)
  18160. }
  18161. }).appendTo(this._$wrapper);
  18162. that._nextNavButton = $("<div />").dxGalleryNavButton({
  18163. direction: "next",
  18164. clickAction: function() {
  18165. that.nextItem(true)
  18166. }
  18167. }).appendTo(this._$wrapper);
  18168. this._renderNavButtonsVisibility()
  18169. },
  18170. _cleanNavButtons: function() {
  18171. if (this._prevNavButton)
  18172. this._prevNavButton.remove();
  18173. if (this._prevNavButton)
  18174. this._nextNavButton.remove()
  18175. },
  18176. _renderNavButtonsVisibility: function() {
  18177. if (!this.option("showNavButtons"))
  18178. return;
  18179. var selectedIndex = this.option("selectedIndex"),
  18180. loop = this.option("loop"),
  18181. itemsCount = this._itemsCount();
  18182. this._prevNavButton.show();
  18183. this._nextNavButton.show();
  18184. if (loop)
  18185. return;
  18186. var nextHidden = itemsCount < 2 || selectedIndex === itemsCount - 1,
  18187. prevHidden = itemsCount < 2 || selectedIndex === 0;
  18188. if (prevHidden)
  18189. this._prevNavButton.hide();
  18190. if (nextHidden)
  18191. this._nextNavButton.hide()
  18192. },
  18193. _setupSlideShow: function() {
  18194. var that = this,
  18195. slideshowDelay = that.option("slideshowDelay");
  18196. if (!slideshowDelay)
  18197. return;
  18198. clearTimeout(that._slideshowTimer);
  18199. that._slideshowTimer = setTimeout(function() {
  18200. if (that._userInteraction) {
  18201. that._setupSlideShow();
  18202. return
  18203. }
  18204. that.nextItem(true).done(that._setupSlideShow)
  18205. }, slideshowDelay)
  18206. },
  18207. _handleSwipeStart: function(e) {
  18208. var itemsCount = this._itemsCount();
  18209. if (!itemsCount) {
  18210. e.jQueryEvent.cancel = true;
  18211. return
  18212. }
  18213. this._stopItemAnimations();
  18214. this._startSwipe();
  18215. this._userInteraction = true;
  18216. if (!this.option("loop")) {
  18217. var selectedIndex = this.option("selectedIndex"),
  18218. startOffset = itemsCount - selectedIndex - 1,
  18219. endOffset = selectedIndex,
  18220. rtlEnabled = this.option("rtlEnabled");
  18221. e.jQueryEvent.maxLeftOffset = rtlEnabled ? endOffset : startOffset;
  18222. e.jQueryEvent.maxRightOffset = rtlEnabled ? startOffset : endOffset
  18223. }
  18224. },
  18225. _stopItemAnimations: function() {
  18226. if (fx.isAnimating(this._$container))
  18227. fx.stop(this._$container, true)
  18228. },
  18229. _handleSwipeUpdate: function(e) {
  18230. this._renderContainerPosition(this._offsetDirection() * e.jQueryEvent.offset)
  18231. },
  18232. _handleSwipeEnd: function(e) {
  18233. var targetOffset = e.jQueryEvent.targetOffset * this._offsetDirection();
  18234. this._renderContainerPosition(targetOffset, true).done(function() {
  18235. var selectedIndex = this.option("selectedIndex"),
  18236. newIndex = this._fitIndex(selectedIndex - targetOffset);
  18237. this._suppressRenderItemPositions = true;
  18238. this.option("selectedIndex", newIndex);
  18239. this._renderContainerPosition();
  18240. this._userInteraction = false;
  18241. this._setupSlideShow()
  18242. })
  18243. },
  18244. _flipIndex: function(index) {
  18245. if (!this.option("loop"))
  18246. return index;
  18247. var itemsCount = this._itemsCount();
  18248. index = index % itemsCount;
  18249. if (index > (itemsCount + 1) / 2)
  18250. index -= itemsCount;
  18251. if (index < -(itemsCount - 1) / 2)
  18252. index += itemsCount;
  18253. return index
  18254. },
  18255. _fitIndex: function(index) {
  18256. if (!this.option("loop"))
  18257. return index;
  18258. var itemsCount = this._itemsCount();
  18259. index = index % itemsCount;
  18260. if (index < 0)
  18261. index += itemsCount;
  18262. return index
  18263. },
  18264. _clean: function() {
  18265. this.callBase();
  18266. this._cleanIndicators();
  18267. this._cleanNavButtons()
  18268. },
  18269. _dispose: function() {
  18270. clearTimeout(this._slideshowTimer);
  18271. this.callBase()
  18272. },
  18273. _handleSelectedIndexChanged: function() {
  18274. if (!this._suppressRenderItemPositions)
  18275. this._renderContainerPosition();
  18276. this._suppressRenderItemPositions = false;
  18277. this._renderSelectedIndicatorItem();
  18278. this._renderNavButtonsVisibility()
  18279. },
  18280. _visibilityChanged: function(visible) {
  18281. if (visible)
  18282. this._dimensionChanged()
  18283. },
  18284. _optionChanged: function(name, value) {
  18285. switch (name) {
  18286. case"width":
  18287. this.callBase.apply(this, arguments);
  18288. this._dimensionChanged();
  18289. break;
  18290. case"animationDuration":
  18291. this._renderNavButtonsVisibility();
  18292. break;
  18293. case"loop":
  18294. this._element().toggleClass(GALLERY_LOOP_CLASS, value);
  18295. this._renderNavButtonsVisibility();
  18296. return;
  18297. case"selectedIndex":
  18298. this._handleSelectedIndexChanged();
  18299. this.callBase.apply(this, arguments);
  18300. return;
  18301. case"showIndicator":
  18302. this._renderIndicator();
  18303. return;
  18304. case"showNavButtons":
  18305. this._renderNavButtons();
  18306. return;
  18307. case"slideshowDelay":
  18308. this._setupSlideShow();
  18309. return;
  18310. case"swipeEnabled":
  18311. case"indicatorEnabled":
  18312. this._renderUserInteraction();
  18313. return;
  18314. default:
  18315. this.callBase.apply(this, arguments)
  18316. }
  18317. },
  18318. goToItem: function(itemIndex, animation) {
  18319. var d = new $.Deferred,
  18320. selectedIndex = this.option("selectedIndex"),
  18321. itemsCount = this._itemsCount();
  18322. itemIndex = this._fitIndex(itemIndex);
  18323. if (itemIndex > itemsCount - 1 || itemIndex < 0)
  18324. return d.resolveWith(this).promise();
  18325. this._renderContainerPosition(selectedIndex - itemIndex, animation).done(function() {
  18326. this._suppressRenderItemPositions = true;
  18327. this.option("selectedIndex", itemIndex);
  18328. d.resolveWith(this)
  18329. });
  18330. return d.promise()
  18331. },
  18332. prevItem: function(animation) {
  18333. return this.goToItem(this.option("selectedIndex") - 1, animation)
  18334. },
  18335. nextItem: function(animation) {
  18336. return this.goToItem(this.option("selectedIndex") + 1, animation)
  18337. }
  18338. }))
  18339. })(jQuery, DevExpress);
  18340. /*! Module widgets-base, file ui.overlay.js */
  18341. (function($, DX, undefined) {
  18342. var ui = DX.ui,
  18343. utils = DX.utils,
  18344. events = ui.events,
  18345. fx = DX.fx,
  18346. translator = DX.translator;
  18347. var OVERLAY_CLASS = "dx-overlay",
  18348. OVERLAY_WRAPPER_CLASS = "dx-overlay-wrapper",
  18349. OVERLAY_CONTENT_CLASS = "dx-overlay-content",
  18350. OVERLAY_SHADER_CLASS = "dx-overlay-shader",
  18351. OVERLAY_MODAL_CLASS = "dx-overlay-modal",
  18352. RTL_DIRECTION_CLASS = "dx-rtl",
  18353. ACTIONS = ["showingAction", "shownAction", "hidingAction", "hiddenAction", "positioningAction", "positionedAction"],
  18354. FIRST_Z_INDEX = 1000,
  18355. Z_INDEX_STACK = [],
  18356. DISABLED_STATE_CLASS = "dx-state-disabled";
  18357. var realDevice = DX.devices.real(),
  18358. android4_0nativeBrowser = realDevice.platform === "android" && /^4\.0(\.\d)?/.test(realDevice.version.join(".")) && navigator.userAgent.indexOf("Chrome") === -1;
  18359. var forceRepaint = function($element) {
  18360. $element.width();
  18361. if (android4_0nativeBrowser) {
  18362. var $parents = $element.parents(),
  18363. inScrollView = $parents.is(".dx-scrollable-native");
  18364. if (!inScrollView) {
  18365. $parents.css("backface-visibility", "hidden");
  18366. $parents.css("backface-visibility");
  18367. $parents.css("backface-visibility", "visible")
  18368. }
  18369. }
  18370. };
  18371. var getElement = function(value) {
  18372. return $(value instanceof $.Event ? value.target : value)
  18373. };
  18374. DX.registerComponent("dxOverlay", ui.Widget.inherit({
  18375. _setDefaultOptions: function() {
  18376. this.callBase();
  18377. this.option({
  18378. activeStateEnabled: false,
  18379. visible: false,
  18380. deferRendering: true,
  18381. shading: true,
  18382. shadingColor: "",
  18383. position: {
  18384. my: "center",
  18385. at: "center",
  18386. of: window
  18387. },
  18388. width: function() {
  18389. return $(window).width() * 0.8
  18390. },
  18391. height: function() {
  18392. return $(window).height() * 0.8
  18393. },
  18394. animation: {
  18395. show: {
  18396. type: "pop",
  18397. duration: 400
  18398. },
  18399. hide: {
  18400. type: "pop",
  18401. duration: 400,
  18402. to: {
  18403. opacity: 0,
  18404. scale: 0
  18405. },
  18406. from: {
  18407. opacity: 1,
  18408. scale: 1
  18409. }
  18410. }
  18411. },
  18412. closeOnOutsideClick: false,
  18413. showingAction: null,
  18414. shownAction: null,
  18415. hidingAction: null,
  18416. hiddenAction: null,
  18417. contentTemplate: "template",
  18418. targetContainer: undefined,
  18419. hideTopOverlayHandler: undefined,
  18420. closeOnTargetScroll: false,
  18421. positioningAction: null,
  18422. positionedAction: null
  18423. })
  18424. },
  18425. _defaultOptionsRules: function() {
  18426. return this.callBase().slice(0).concat([{
  18427. device: function(device) {
  18428. var realDevice = DX.devices.real(),
  18429. realPlatform = realDevice.platform,
  18430. realVersion = realDevice.version;
  18431. return realPlatform === "android" && (realVersion[0] < 4 || realVersion[0] == 4 && realVersion[1] <= 1)
  18432. },
  18433. options: {animation: {
  18434. show: {
  18435. type: "fade",
  18436. duration: 400
  18437. },
  18438. hide: {
  18439. type: "fade",
  18440. duration: 400,
  18441. to: {opacity: 0},
  18442. from: {opacity: 1}
  18443. }
  18444. }}
  18445. }])
  18446. },
  18447. _optionsByReference: function() {
  18448. return $.extend(this.callBase(), {animation: true})
  18449. },
  18450. _wrapper: function() {
  18451. return this._$wrapper
  18452. },
  18453. _container: function() {
  18454. return this._$container
  18455. },
  18456. _init: function() {
  18457. this.callBase();
  18458. this._initActions();
  18459. this._initCloseOnOutsideClickHandler();
  18460. this._$wrapper = $("<div>").addClass(OVERLAY_WRAPPER_CLASS);
  18461. this._$container = $("<div>").addClass(OVERLAY_CONTENT_CLASS);
  18462. var $element = this._element();
  18463. this._$wrapper.addClass($element.attr("class"));
  18464. $element.addClass(OVERLAY_CLASS);
  18465. this._$wrapper.on("MSPointerDown", $.noop)
  18466. },
  18467. _clean: $.noop,
  18468. _initOptions: function(options) {
  18469. this._initTargetContainer(options.targetContainer);
  18470. this._initHideTopOverlayHandler(options.hideTopOverlayHandler);
  18471. this.callBase(options)
  18472. },
  18473. _initTargetContainer: function(targetContainer) {
  18474. targetContainer = targetContainer === undefined ? DX.overlayTargetContainer() : targetContainer;
  18475. var $element = this._element(),
  18476. $targetContainer = $element.closest(targetContainer);
  18477. if (!$targetContainer.length)
  18478. $targetContainer = $(targetContainer).first();
  18479. this._$targetContainer = $targetContainer.length ? $targetContainer : $element.parent()
  18480. },
  18481. _targetContainer: function() {
  18482. return this._$targetContainer
  18483. },
  18484. _initHideTopOverlayHandler: function(handler) {
  18485. this._hideTopOverlayHandler = handler !== undefined ? handler : $.proxy(this._defaultHideTopOverlayHandler, this)
  18486. },
  18487. _defaultHideTopOverlayHandler: function() {
  18488. this.hide()
  18489. },
  18490. _initActions: function() {
  18491. this._actions = {};
  18492. $.each(ACTIONS, $.proxy(function(_, action) {
  18493. this._actions[action] = this._createActionByOption(action) || $.noop
  18494. }, this))
  18495. },
  18496. _visibilityChanged: function(visible) {
  18497. if (visible)
  18498. this._dimensionChanged()
  18499. },
  18500. _dimensionChanged: function() {
  18501. this._renderGeometry()
  18502. },
  18503. _initCloseOnOutsideClickHandler: function() {
  18504. this._documentDownHandler = $.proxy(function() {
  18505. this._handleDocumentDown.apply(this, arguments)
  18506. }, this)
  18507. },
  18508. _handleDocumentDown: function(e) {
  18509. if (!this._isTopOverlay())
  18510. return;
  18511. var closeOnOutsideClick = this.option("closeOnOutsideClick");
  18512. if ($.isFunction(closeOnOutsideClick))
  18513. closeOnOutsideClick = closeOnOutsideClick(e);
  18514. if (closeOnOutsideClick) {
  18515. var $container = this._$container,
  18516. outsideClick = !$container.is(e.target) && !$.contains($container.get(0), e.target);
  18517. if (outsideClick) {
  18518. e.preventDefault();
  18519. this.hide()
  18520. }
  18521. }
  18522. },
  18523. _isTopOverlay: function() {
  18524. var zIndexStack = this._zIndexStack();
  18525. return zIndexStack[zIndexStack.length - 1] === this._zIndex
  18526. },
  18527. _zIndexStack: function() {
  18528. return Z_INDEX_STACK
  18529. },
  18530. _zIndexInitValue: function() {
  18531. return FIRST_Z_INDEX
  18532. },
  18533. _renderVisibilityAnimate: function() {
  18534. var visible = this.option("visible");
  18535. if (visible)
  18536. this._showTimestamp = $.now();
  18537. this._stopAnimation();
  18538. if (visible)
  18539. return this._makeVisible();
  18540. else
  18541. return this._makeHidden()
  18542. },
  18543. _updateRegistration: function(enabled) {
  18544. var zIndexStack = this._zIndexStack();
  18545. if (enabled) {
  18546. if (!this._zIndex) {
  18547. var length = zIndexStack.length;
  18548. this._zIndex = (length ? zIndexStack[length - 1] : this._zIndexInitValue()) + 1;
  18549. zIndexStack.push(this._zIndex)
  18550. }
  18551. }
  18552. else if (this._zIndex) {
  18553. var index = $.inArray(this._zIndex, zIndexStack);
  18554. zIndexStack.splice(index, 1);
  18555. delete this._zIndex
  18556. }
  18557. },
  18558. _normalizePosition: function() {
  18559. this._position = this.option("position")
  18560. },
  18561. _makeVisible: function() {
  18562. this._normalizePosition();
  18563. var that = this,
  18564. deferred = $.Deferred(),
  18565. animation = that.option("animation") || {},
  18566. showAnimation = animation.show,
  18567. completeShowAnimation = showAnimation && showAnimation.complete || $.noop;
  18568. this._updateRegistration(true);
  18569. if (showAnimation && showAnimation.to) {
  18570. showAnimation = $.extend({type: "slide"}, showAnimation);
  18571. $.extend(showAnimation.to, {position: this._position})
  18572. }
  18573. if (this._isHidingActionCancelled) {
  18574. delete this._isHidingActionCancelled;
  18575. deferred.resolve()
  18576. }
  18577. else {
  18578. this._actions.showingAction();
  18579. this._$wrapper.css("z-index", this._zIndex);
  18580. this._$container.css("z-index", this._zIndex);
  18581. this._toggleVisibility(true);
  18582. this._animate(showAnimation, function() {
  18583. completeShowAnimation.apply(this, arguments);
  18584. that._actions.shownAction();
  18585. deferred.resolve()
  18586. })
  18587. }
  18588. return deferred.promise()
  18589. },
  18590. _makeHidden: function() {
  18591. var that = this,
  18592. deferred = $.Deferred(),
  18593. animation = this.option("animation") || {},
  18594. hideAnimation = animation.hide,
  18595. completeHideAnimation = hideAnimation && hideAnimation.complete || $.noop;
  18596. var hidingArgs = {cancel: false};
  18597. this._actions.hidingAction(hidingArgs);
  18598. if (hidingArgs.cancel) {
  18599. this._isHidingActionCancelled = true;
  18600. this.option("visible", true);
  18601. deferred.resolve()
  18602. }
  18603. else {
  18604. this._toggleShading(false);
  18605. this._animate(hideAnimation, function() {
  18606. that._toggleVisibility(false);
  18607. completeHideAnimation.apply(this, arguments);
  18608. that._updateRegistration(false);
  18609. that._actions.hiddenAction();
  18610. deferred.resolve()
  18611. })
  18612. }
  18613. return deferred.promise()
  18614. },
  18615. _animate: function(animation, completeCallback) {
  18616. if (animation)
  18617. fx.animate(this._$container, $.extend({}, animation, {complete: completeCallback}));
  18618. else
  18619. completeCallback()
  18620. },
  18621. _stopAnimation: function() {
  18622. fx.stop(this._$container, true)
  18623. },
  18624. _toggleVisibility: function(visible) {
  18625. this._stopAnimation();
  18626. if (!visible)
  18627. utils.triggerHidingEvent(this.content());
  18628. this.callBase.apply(this, arguments);
  18629. this._$container.toggle(visible);
  18630. this._toggleShading(visible);
  18631. if (visible) {
  18632. this._renderContent();
  18633. this._moveToTargetContainer();
  18634. this._renderGeometry();
  18635. utils.triggerShownEvent(this.content())
  18636. }
  18637. else
  18638. this._moveFromTargetContainer();
  18639. this._toggleSubscriptions(visible);
  18640. this._updateRegistration(visible)
  18641. },
  18642. _toggleShading: function(visible) {
  18643. this._$wrapper.toggleClass(OVERLAY_MODAL_CLASS, this.option("shading") && !this.option("targetContainer"));
  18644. this._$wrapper.toggleClass(OVERLAY_SHADER_CLASS, visible && this.option("shading"));
  18645. this._$wrapper.css("background-color", this.option("shading") ? this.option("shadingColor") : "")
  18646. },
  18647. _toggleSubscriptions: function(enabled) {
  18648. this._toggleHideTopOverlayCallback(enabled);
  18649. this._toggleDocumentDownHandler(enabled);
  18650. this._toggleParentsScrollSubscription(enabled)
  18651. },
  18652. _toggleHideTopOverlayCallback: function(subscribe) {
  18653. if (!this._hideTopOverlayHandler)
  18654. return;
  18655. if (subscribe)
  18656. DX.hideTopOverlayCallback.add(this._hideTopOverlayHandler);
  18657. else
  18658. DX.hideTopOverlayCallback.remove(this._hideTopOverlayHandler)
  18659. },
  18660. _toggleDocumentDownHandler: function(enabled) {
  18661. var that = this,
  18662. eventName = events.addNamespace("dxpointerdown", that.NAME);
  18663. if (enabled)
  18664. $(document).on(eventName, this._documentDownHandler);
  18665. else
  18666. $(document).off(eventName, this._documentDownHandler)
  18667. },
  18668. _toggleParentsScrollSubscription: function(subscribe) {
  18669. var position = this._position;
  18670. if (!position || !position.of)
  18671. return;
  18672. var that = this,
  18673. closeOnScroll = that.option("closeOnTargetScroll"),
  18674. scrollEventName = events.addNamespace("scroll", that.NAME),
  18675. $parents = getElement(position.of).parents().add(window);
  18676. that._proxiedTargetScrollHandler = that._proxiedTargetScrollHandler || function() {
  18677. return that._targetScrollHandler.apply(that, arguments)
  18678. };
  18679. $parents[subscribe && closeOnScroll ? "on" : "off"](scrollEventName, that._proxiedTargetScrollHandler)
  18680. },
  18681. _targetScrollHandler: function(e) {
  18682. var closeOnScroll = this.option("closeOnTargetScroll"),
  18683. closeHandled = false;
  18684. if ($.isFunction(closeOnScroll))
  18685. closeHandled = closeOnScroll(e);
  18686. if (!closeHandled)
  18687. this.hide()
  18688. },
  18689. _renderContent: function() {
  18690. if (this._contentAlreadyRendered || !this.option("visible") && this.option("deferRendering"))
  18691. return;
  18692. this._contentAlreadyRendered = true;
  18693. this.callBase()
  18694. },
  18695. _renderContentImpl: function(template) {
  18696. var $element = this._element(),
  18697. contentTemplate = template || this._getTemplate(this.option("contentTemplate"));
  18698. this._$container.append($element.contents()).appendTo($element);
  18699. if (contentTemplate)
  18700. contentTemplate.render(this.content())
  18701. },
  18702. _fireContentReadyAction: function() {
  18703. if (this.option("visible"))
  18704. this._moveToTargetContainer();
  18705. this.callBase.apply(this, arguments)
  18706. },
  18707. _moveFromTargetContainer: function() {
  18708. this._$container.appendTo(this._element());
  18709. this._detachWrapperToTargetContainer()
  18710. },
  18711. _detachWrapperToTargetContainer: function() {
  18712. this._$wrapper.detach()
  18713. },
  18714. _moveToTargetContainer: function() {
  18715. this._attachWrapperToTargetContainer();
  18716. this._$container.appendTo(this._$wrapper)
  18717. },
  18718. _attachWrapperToTargetContainer: function() {
  18719. var $element = this._element();
  18720. if (this._$targetContainer && !(this._$targetContainer[0] === $element.parent()[0]))
  18721. this._$wrapper.appendTo(this._$targetContainer);
  18722. else
  18723. this._$wrapper.appendTo($element)
  18724. },
  18725. _renderGeometry: function() {
  18726. if (this.option("visible"))
  18727. this._renderGeometryImpl()
  18728. },
  18729. _renderGeometryImpl: function() {
  18730. this._stopAnimation();
  18731. this._normalizePosition();
  18732. this._renderShading();
  18733. this._renderDimensions();
  18734. this._renderPosition()
  18735. },
  18736. _renderShading: function() {
  18737. var $wrapper = this._$wrapper,
  18738. $targetContainer = this._getTargetContainer();
  18739. $wrapper.css("position", $targetContainer.get(0) === window ? "fixed" : "absolute");
  18740. if (this.option("shading"))
  18741. $wrapper.show();
  18742. this._renderShadingDimensions();
  18743. this._renderShadingPosition()
  18744. },
  18745. _renderShadingPosition: function() {
  18746. if (this.option("shading")) {
  18747. var $targetContainer = this._getTargetContainer();
  18748. DX.position(this._$wrapper, {
  18749. my: "top left",
  18750. at: "top left",
  18751. of: $targetContainer
  18752. })
  18753. }
  18754. },
  18755. _renderShadingDimensions: function() {
  18756. if (this.option("shading")) {
  18757. var $targetContainer = this._getTargetContainer();
  18758. this._$wrapper.css({
  18759. width: $targetContainer.outerWidth(),
  18760. height: $targetContainer.outerHeight()
  18761. })
  18762. }
  18763. },
  18764. _getTargetContainer: function() {
  18765. var position = this._position,
  18766. targetContainer = this.option("targetContainer"),
  18767. positionOf = position ? position.of : null;
  18768. return getElement(targetContainer || positionOf)
  18769. },
  18770. _renderDimensions: function() {
  18771. this._$container.outerWidth(this.option("width")).outerHeight(this.option("height"))
  18772. },
  18773. _renderPosition: function() {
  18774. translator.resetPosition(this._$container);
  18775. var position = this._position,
  18776. containerPosition = DX.calculatePosition(this._$container, position);
  18777. this._actions.positioningAction({position: containerPosition});
  18778. var resultPosition = DX.position(this._$container, containerPosition);
  18779. this._actions.positionedAction({position: resultPosition});
  18780. forceRepaint(this._$container)
  18781. },
  18782. _dispose: function() {
  18783. this._stopAnimation();
  18784. this._toggleSubscriptions(false);
  18785. this._updateRegistration(false);
  18786. this._actions = null;
  18787. this.callBase();
  18788. this._$wrapper.remove();
  18789. this._$container.remove()
  18790. },
  18791. _toggleDisabledState: function(value) {
  18792. this.callBase.apply(this, arguments);
  18793. this._$container.toggleClass(DISABLED_STATE_CLASS, value)
  18794. },
  18795. _toggleRTLDirection: function(rtl) {
  18796. this._$container.toggleClass(RTL_DIRECTION_CLASS, rtl)
  18797. },
  18798. _optionChanged: function(name, value) {
  18799. if ($.inArray(name, ACTIONS) > -1) {
  18800. this._initActions();
  18801. return
  18802. }
  18803. switch (name) {
  18804. case"shading":
  18805. case"shadingColor":
  18806. this._toggleShading(this.option("visible"));
  18807. break;
  18808. case"width":
  18809. case"height":
  18810. case"position":
  18811. this._renderGeometry();
  18812. break;
  18813. case"visible":
  18814. this._renderVisibilityAnimate(value).done($.proxy(function() {
  18815. if (!this._animateDeferred)
  18816. return;
  18817. this._animateDeferred.resolveWith(this);
  18818. delete this._animateDeferred
  18819. }, this));
  18820. break;
  18821. case"targetContainer":
  18822. this._initTargetContainer(value);
  18823. this._invalidate();
  18824. break;
  18825. case"deferRendering":
  18826. case"contentTemplate":
  18827. this._invalidate();
  18828. break;
  18829. case"closeOnOutsideClick":
  18830. this._toggleDocumentDownHandler(this.option("visible"));
  18831. break;
  18832. case"closeOnTargetScroll":
  18833. this._toggleParentsScrollSubscription(this.option("visible"));
  18834. break;
  18835. case"animation":
  18836. break;
  18837. case"rtlEnabled":
  18838. this._toggleRTLDirection(value);
  18839. break;
  18840. default:
  18841. this.callBase.apply(this, arguments)
  18842. }
  18843. },
  18844. toggle: function(showing) {
  18845. showing = showing === undefined ? !this.option("visible") : showing;
  18846. if (showing === this.option("visible"))
  18847. return $.Deferred().resolve().promise();
  18848. var animateDeferred = $.Deferred();
  18849. this._animateDeferred = animateDeferred;
  18850. this.option("visible", showing);
  18851. return animateDeferred.promise()
  18852. },
  18853. show: function() {
  18854. return this.toggle(true)
  18855. },
  18856. hide: function() {
  18857. return this.toggle(false)
  18858. },
  18859. content: function() {
  18860. return this._$container
  18861. },
  18862. repaint: function() {
  18863. this._renderGeometry()
  18864. }
  18865. }));
  18866. ui.dxOverlay.__internals = {
  18867. OVERLAY_CLASS: OVERLAY_CLASS,
  18868. OVERLAY_WRAPPER_CLASS: OVERLAY_WRAPPER_CLASS,
  18869. OVERLAY_CONTENT_CLASS: OVERLAY_CONTENT_CLASS,
  18870. OVERLAY_SHADER_CLASS: OVERLAY_SHADER_CLASS,
  18871. OVERLAY_MODAL_CLASS: OVERLAY_MODAL_CLASS
  18872. }
  18873. })(jQuery, DevExpress);
  18874. /*! Module widgets-base, file ui.toast.js */
  18875. (function($, DX, undefined) {
  18876. var ui = DX.ui;
  18877. var TOAST_CLASS = "dx-toast",
  18878. TOAST_CLASS_PREFIX = TOAST_CLASS + "-",
  18879. TOAST_WRAPPER_CLASS = TOAST_CLASS_PREFIX + "wrapper",
  18880. TOAST_CONTENT_CLASS = TOAST_CLASS_PREFIX + "content",
  18881. TOAST_MESSAGE_CLASS = TOAST_CLASS_PREFIX + "message",
  18882. TOAST_ICON_CLASS = TOAST_CLASS_PREFIX + "icon",
  18883. WIDGET_NAME = "dxToast",
  18884. toastTypes = ["info", "warning", "error", "success"],
  18885. Z_INDEX_STACK = [],
  18886. FIRST_Z_INDEX = 9000;
  18887. DX.registerComponent(WIDGET_NAME, ui.dxOverlay.inherit({
  18888. _setDefaultOptions: function() {
  18889. this.callBase();
  18890. this.option({
  18891. message: "",
  18892. type: "info",
  18893. displayTime: 2000,
  18894. position: {
  18895. my: "bottom center",
  18896. at: "bottom center",
  18897. of: window,
  18898. offset: "0 -20"
  18899. },
  18900. animation: {
  18901. show: {
  18902. type: "fade",
  18903. duration: 400,
  18904. from: 0,
  18905. to: 1
  18906. },
  18907. hide: {
  18908. type: "fade",
  18909. duration: 400,
  18910. to: 0
  18911. }
  18912. },
  18913. shading: false,
  18914. height: "auto"
  18915. })
  18916. },
  18917. _defaultOptionsRules: function() {
  18918. return this.callBase().slice(0).concat([{
  18919. device: {platform: "win8"},
  18920. options: {
  18921. position: {
  18922. my: "top center",
  18923. at: "top center",
  18924. of: window,
  18925. offset: "0 0"
  18926. },
  18927. width: function() {
  18928. return $(window).width()
  18929. }
  18930. }
  18931. }])
  18932. },
  18933. _renderContentImpl: function() {
  18934. if (this.option("message"))
  18935. this._message = $("<div>").addClass(TOAST_MESSAGE_CLASS).text(this.option("message")).appendTo(this.content());
  18936. if ($.inArray(this.option("type").toLowerCase(), toastTypes) > -1)
  18937. this.content().prepend($("<div>").addClass(TOAST_ICON_CLASS));
  18938. this.callBase()
  18939. },
  18940. _render: function() {
  18941. this.callBase();
  18942. this._element().addClass(TOAST_CLASS);
  18943. this._wrapper().addClass(TOAST_WRAPPER_CLASS);
  18944. this._$container.addClass(TOAST_CLASS_PREFIX + String(this.option("type")).toLowerCase());
  18945. this.content().addClass(TOAST_CONTENT_CLASS)
  18946. },
  18947. _makeVisible: function() {
  18948. return this.callBase.apply(this, arguments).done($.proxy(function() {
  18949. clearTimeout(this._hideTimeout);
  18950. this._hideTimeout = setTimeout($.proxy(function() {
  18951. this.hide()
  18952. }, this), this.option("displayTime"))
  18953. }, this))
  18954. },
  18955. _zIndexStack: function() {
  18956. return Z_INDEX_STACK
  18957. },
  18958. _zIndexInitValue: function() {
  18959. return FIRST_Z_INDEX
  18960. },
  18961. _dispose: function() {
  18962. clearTimeout(this._hideTimeout);
  18963. this.callBase()
  18964. },
  18965. _optionChanged: function(name, value, prevValue) {
  18966. switch (name) {
  18967. case"type":
  18968. this._$container.removeClass(TOAST_CLASS_PREFIX + prevValue);
  18969. this._$container.addClass(TOAST_CLASS_PREFIX + String(value).toLowerCase());
  18970. break;
  18971. case"message":
  18972. if (this._message)
  18973. this._message.text(value);
  18974. break;
  18975. case"displayTime":
  18976. break;
  18977. default:
  18978. this.callBase.apply(this, arguments)
  18979. }
  18980. }
  18981. }));
  18982. ui.dxToast.__internals = {
  18983. TOAST_CLASS: TOAST_CLASS,
  18984. TOAST_WRAPPER_CLASS: TOAST_WRAPPER_CLASS,
  18985. TOAST_CONTENT_CLASS: TOAST_CONTENT_CLASS,
  18986. TOAST_MESSAGE_CLASS: TOAST_MESSAGE_CLASS,
  18987. TOAST_ICON_CLASS: TOAST_ICON_CLASS,
  18988. TOAST_CLASS_PREFIX: TOAST_CLASS_PREFIX,
  18989. WIDGET_NAME: WIDGET_NAME
  18990. }
  18991. })(jQuery, DevExpress);
  18992. /*! Module widgets-base, file ui.popup.js */
  18993. (function($, DX, undefined) {
  18994. var ui = DX.ui,
  18995. events = ui.events,
  18996. translator = DX.translator;
  18997. var POPUP_CLASS = "dx-popup",
  18998. POPUP_WRAPPER_CLASS = "dx-popup-wrapper",
  18999. POPUP_FULL_SCREEN_CLASS = "dx-popup-fullscreen",
  19000. POPUP_CONTENT_CLASS = "dx-popup-content",
  19001. POPUP_DRAGGABLE_CLASS = "dx-popup-draggable",
  19002. POPUP_TITLE_CLASS = "dx-popup-title",
  19003. POPUP_TITLE_SELECTOR = "." + POPUP_TITLE_CLASS,
  19004. POPUP_TITLE_CLOSEBUTTON_CLASS = "dx-closebutton",
  19005. POPUP_TITLE_HAS_BUTTON_CLASS = "dx-popup-title-has-button",
  19006. POPUP_BOTTOM_CLASS = "dx-popup-bottom",
  19007. TOOLBAR_LEFT_CLASS = "dx-toolbar-before",
  19008. TOOLBAR_RIGHT_CLASS = "dx-toolbar-after",
  19009. OVERLAY_CONTENT_SELECTOR = ".dx-overlay-content",
  19010. MIN_POPUP_STICK_SIZE = 40;
  19011. var getButtonContainer = function(force) {
  19012. var device = DX.devices.current(force),
  19013. container = {
  19014. cancel: {subclass: "dx-popup-cancel"},
  19015. clear: {subclass: "dx-popup-clear"},
  19016. done: {subclass: "dx-popup-done"}
  19017. };
  19018. if (device.ios) {
  19019. $.extend(container.cancel, {
  19020. parent: POPUP_TITLE_SELECTOR,
  19021. wraperClass: TOOLBAR_LEFT_CLASS
  19022. });
  19023. $.extend(container.clear, {
  19024. parent: POPUP_TITLE_SELECTOR,
  19025. wraperClass: TOOLBAR_RIGHT_CLASS
  19026. });
  19027. $.extend(container.done, {wraperClass: POPUP_BOTTOM_CLASS})
  19028. }
  19029. if (device.android || device.platform === "desktop" || device.win8 || device.tizen || device.generic) {
  19030. $.extend(container.cancel, {wraperClass: POPUP_BOTTOM_CLASS});
  19031. $.extend(container.clear, {wraperClass: POPUP_BOTTOM_CLASS});
  19032. $.extend(container.done, {wraperClass: POPUP_BOTTOM_CLASS})
  19033. }
  19034. return container
  19035. };
  19036. DX.registerComponent("dxPopup", ui.dxOverlay.inherit({
  19037. _setDefaultOptions: function() {
  19038. this.callBase();
  19039. this.option({
  19040. title: "",
  19041. showTitle: true,
  19042. fullScreen: false,
  19043. titleTemplate: "title",
  19044. dragEnabled: false,
  19045. cancelButton: null,
  19046. doneButton: null,
  19047. clearButton: null,
  19048. closeButton: null
  19049. })
  19050. },
  19051. _defaultOptionsRules: function() {
  19052. return this.callBase().slice(0).concat([{
  19053. device: {platform: "win8"},
  19054. options: {width: function() {
  19055. return $(window).width()
  19056. }}
  19057. }, {
  19058. device: {
  19059. platform: "win8",
  19060. phone: true
  19061. },
  19062. options: {position: {
  19063. my: "top center",
  19064. at: "top center",
  19065. of: window,
  19066. offset: "0 0"
  19067. }}
  19068. }, {
  19069. device: [{platform: "ios"}, {platform: "ios7"}],
  19070. options: {animation: this._iosAnimation}
  19071. }, {
  19072. device: function(device) {
  19073. return DX.devices.real().platform === "generic" && device.platform === "generic"
  19074. },
  19075. options: {dragEnabled: true}
  19076. }])
  19077. },
  19078. _iosAnimation: {
  19079. show: {
  19080. type: "slide",
  19081. duration: 400,
  19082. from: {position: {
  19083. my: "top",
  19084. at: "bottom",
  19085. of: window
  19086. }},
  19087. to: {position: {
  19088. my: "center",
  19089. at: "center",
  19090. of: window
  19091. }}
  19092. },
  19093. hide: {
  19094. type: "slide",
  19095. duration: 400,
  19096. from: {
  19097. opacity: 1,
  19098. position: {
  19099. my: "center",
  19100. at: "center",
  19101. of: window
  19102. }
  19103. },
  19104. to: {
  19105. opacity: 1,
  19106. position: {
  19107. my: "top",
  19108. at: "bottom",
  19109. of: window
  19110. }
  19111. }
  19112. }
  19113. },
  19114. _init: function() {
  19115. this.callBase();
  19116. this._$content = this._container().wrapInner($("<div />").addClass(POPUP_CONTENT_CLASS)).children().eq(0)
  19117. },
  19118. _render: function() {
  19119. this._element().addClass(POPUP_CLASS);
  19120. this._wrapper().addClass(POPUP_WRAPPER_CLASS);
  19121. this._container().toggleClass(POPUP_DRAGGABLE_CLASS, this.option("dragEnabled")).toggleClass(POPUP_FULL_SCREEN_CLASS, this.option("fullScreen"));
  19122. this.callBase()
  19123. },
  19124. _renderContentImpl: function() {
  19125. this.callBase(this.option("_templates").content);
  19126. this._renderTitle();
  19127. this._renderDrag();
  19128. this._renderButtons()
  19129. },
  19130. _renderTitle: function() {
  19131. if (this.option("showTitle")) {
  19132. this._$title = this._$title || $("<div />").addClass(POPUP_TITLE_CLASS);
  19133. this._$title.empty();
  19134. this._element().append(this._$title);
  19135. if (this.option("title"))
  19136. this._defaultTitleRender();
  19137. else {
  19138. var titleTemplate = this._getTemplateByOption("titleTemplate");
  19139. if (titleTemplate)
  19140. titleTemplate.render(this._$title)
  19141. }
  19142. this._$title.prependTo(this._container())
  19143. }
  19144. else if (this._$title)
  19145. this._$title.detach()
  19146. },
  19147. _renderDrag: function() {
  19148. if (!this._$title)
  19149. return;
  19150. var startEventName = events.addNamespace("dxdragstart", this.NAME),
  19151. updateEventName = events.addNamespace("dxdrag", this.NAME);
  19152. this._$title.off(startEventName).off(updateEventName);
  19153. if (!this.option("dragEnabled"))
  19154. return;
  19155. this._$title.on(startEventName, $.proxy(this._handleTitleDragStart, this)).on(updateEventName, $.proxy(this._handleTitleDragUpdate, this))
  19156. },
  19157. _handleTitleDragStart: function(e) {
  19158. e.targetElements = [];
  19159. this._prevOffset = {
  19160. x: 0,
  19161. y: 0
  19162. };
  19163. this._dragHandled = true;
  19164. var position = translator.locate(this._container()),
  19165. allowedOffsets = this._allowedOffsets();
  19166. e.maxLeftOffset = position.left + allowedOffsets.left;
  19167. e.maxRightOffset = -position.left + allowedOffsets.right;
  19168. e.maxTopOffset = position.top + allowedOffsets.top;
  19169. e.maxBottomOffset = -position.top + allowedOffsets.bottom
  19170. },
  19171. _handleTitleDragUpdate: function(e) {
  19172. var position = translator.locate(this._container()),
  19173. offset = e.offset,
  19174. prevOffset = this._prevOffset;
  19175. translator.move(this._container(), {
  19176. left: position.left + (offset.x - prevOffset.x),
  19177. top: position.top + (offset.y - prevOffset.y)
  19178. });
  19179. this._prevOffset = offset
  19180. },
  19181. _allowedOffsets: function() {
  19182. var $container = this._container(),
  19183. $targetContainer = this._targetContainer(),
  19184. containerWidth = $container.outerWidth(),
  19185. targetContainerWidth = $targetContainer.width(),
  19186. targetContainerHeight = $targetContainer.height();
  19187. return {
  19188. top: 0,
  19189. bottom: targetContainerHeight - MIN_POPUP_STICK_SIZE,
  19190. left: containerWidth - MIN_POPUP_STICK_SIZE,
  19191. right: targetContainerWidth - MIN_POPUP_STICK_SIZE
  19192. }
  19193. },
  19194. _renderButtons: function() {
  19195. var buttonsName = DX.devices.current().win8 ? ["Close", "Done", "Clear", "Cancel"] : ["Close", "Cancel", "Clear", "Done"];
  19196. buttonsName.extractButtonName = this.option("rtlEnabled") ? buttonsName.pop : buttonsName.shift;
  19197. while (!!buttonsName.length) {
  19198. var buttonName = buttonsName.extractButtonName();
  19199. this["_render" + buttonName + "Button"]()
  19200. }
  19201. },
  19202. _defaultTitleRender: function() {
  19203. this._$title.text(this.option("title"))
  19204. },
  19205. _renderCloseButton: function() {
  19206. var renderButtonRequired = !this.option("_templates").title && !!this.option("closeButton") && this.option("showTitle");
  19207. this._$title && this._$title.toggleClass(POPUP_TITLE_HAS_BUTTON_CLASS, renderButtonRequired);
  19208. if (renderButtonRequired) {
  19209. var clickAction = this._createButtonAction();
  19210. $("<div/>").addClass(POPUP_TITLE_CLOSEBUTTON_CLASS).on(ui.events.addNamespace("dxclick", this.NAME + "TitleCloseButton"), function(e) {
  19211. clickAction({jQueryEvent: e})
  19212. }).appendTo(this._$title)
  19213. }
  19214. },
  19215. _renderCancelButton: function() {
  19216. this._renderSpecificButton(this.option("cancelButton"), {
  19217. type: "cancel",
  19218. text: Globalize.localize("Cancel")
  19219. })
  19220. },
  19221. _renderClearButton: function() {
  19222. this._renderSpecificButton(this.option("clearButton"), {
  19223. type: "clear",
  19224. text: Globalize.localize("Clear")
  19225. })
  19226. },
  19227. _renderDoneButton: function() {
  19228. this._renderSpecificButton(this.option("doneButton"), {
  19229. type: "done",
  19230. text: Globalize.localize("Done")
  19231. })
  19232. },
  19233. _renderSpecificButton: function(show, buttonConfig) {
  19234. var renderParams = this._getRenderButtonParams(buttonConfig.type);
  19235. this._removeButton(renderParams);
  19236. this._wrapper().toggleClass(POPUP_CLASS + "-" + buttonConfig.type + "-visible", !!show);
  19237. if (!show)
  19238. return;
  19239. var userButtonOptions = this.option(buttonConfig.type + "Button");
  19240. this._renderButton({
  19241. text: userButtonOptions.text || buttonConfig.text,
  19242. clickAction: this._createButtonAction(userButtonOptions.clickAction)
  19243. }, renderParams)
  19244. },
  19245. _createButtonAction: function(clickAction) {
  19246. return this._createAction(clickAction, {afterExecute: function(e) {
  19247. e.component.hide()
  19248. }})
  19249. },
  19250. _getRenderButtonParams: function(type) {
  19251. return $.extend({}, getButtonContainer()[type])
  19252. },
  19253. _renderButton: function(buttonParams, renderParams) {
  19254. var $button = $("<div/>").addClass(renderParams.subclass).dxButton(buttonParams),
  19255. $parentContainer = renderParams.parent ? this._container().find(renderParams.parent) : this._container(),
  19256. $buttonContainer = this._container().find("." + renderParams.wraperClass);
  19257. if (!$buttonContainer.length)
  19258. $buttonContainer = $("<div/>").addClass(renderParams.wraperClass).appendTo($parentContainer);
  19259. $button.appendTo($buttonContainer);
  19260. this._container().find("." + POPUP_BOTTOM_CLASS).addClass(renderParams.subclass)
  19261. },
  19262. _removeButton: function(params) {
  19263. var removeSelector = "." + (params.subclass || params.wraperClass);
  19264. if (this.content())
  19265. this.content().removeClass(params.subclass);
  19266. this._container().find(removeSelector).remove()
  19267. },
  19268. _renderGeometryImpl: function() {
  19269. this.callBase.apply(this, arguments);
  19270. this._setContentHeight()
  19271. },
  19272. _renderDimensions: function() {
  19273. if (this.option("fullScreen"))
  19274. this._container().css({
  19275. width: "100%",
  19276. height: "100%"
  19277. });
  19278. else
  19279. this.callBase.apply(this, arguments)
  19280. },
  19281. _renderShadingDimensions: function() {
  19282. if (this.option("fullScreen"))
  19283. this._wrapper().css({
  19284. width: "100%",
  19285. height: "100%"
  19286. });
  19287. else
  19288. this.callBase.apply(this, arguments)
  19289. },
  19290. _renderPosition: function() {
  19291. if (this.option("fullScreen"))
  19292. translator.move(this._container(), {
  19293. top: 0,
  19294. left: 0
  19295. });
  19296. else if (this._dragHandled) {
  19297. var $container = this._container(),
  19298. position = translator.locate($container),
  19299. allowedOffsets = this._allowedOffsets();
  19300. translator.move($container, {
  19301. top: Math.min(Math.max(-allowedOffsets.top, position.top), allowedOffsets.bottom),
  19302. left: Math.min(Math.max(-allowedOffsets.left, position.left), allowedOffsets.right)
  19303. })
  19304. }
  19305. else
  19306. this.callBase.apply(this, arguments)
  19307. },
  19308. _setContentHeight: function() {
  19309. if (!this._$content)
  19310. return;
  19311. var contentHeight = this._$container.height(),
  19312. hasBottomButtons = this.option("cancelButton") || this.option("doneButton") || this.option("clearButton"),
  19313. $bottomButtons = this._$wrapper.find(".dx-popup-bottom");
  19314. if (this._$title)
  19315. contentHeight -= this._$title.outerHeight(true) || 0;
  19316. if (hasBottomButtons) {
  19317. var bottomButtonsMargin = $bottomButtons.outerHeight(true) || 0;
  19318. contentHeight -= bottomButtonsMargin;
  19319. this._$content.css("margin-bottom", bottomButtonsMargin)
  19320. }
  19321. if (this.option("height") === "auto")
  19322. this._$content.css("height", "auto");
  19323. else if (contentHeight > 0)
  19324. this._$content.css("height", contentHeight)
  19325. },
  19326. _optionChanged: function(name, value) {
  19327. switch (name) {
  19328. case"visible":
  19329. delete this._dragHandled;
  19330. this.callBase.apply(this, arguments);
  19331. break;
  19332. case"showTitle":
  19333. case"title":
  19334. case"titleTemplate":
  19335. this._renderTitle();
  19336. this._renderCloseButton();
  19337. this._setContentHeight();
  19338. break;
  19339. case"dragEnabled":
  19340. this._renderDrag();
  19341. break;
  19342. case"cancelButton":
  19343. this._renderCancelButton();
  19344. break;
  19345. case"clearButton":
  19346. this._renderClearButton();
  19347. break;
  19348. case"doneButton":
  19349. this._renderDoneButton();
  19350. break;
  19351. case"closeButton":
  19352. this._renderCloseButton();
  19353. break;
  19354. case"height":
  19355. this.callBase.apply(this, arguments);
  19356. this._setContentHeight();
  19357. break;
  19358. case"fullScreen":
  19359. this._container().toggleClass(POPUP_FULL_SCREEN_CLASS, value);
  19360. this._refresh();
  19361. break;
  19362. default:
  19363. this.callBase.apply(this, arguments)
  19364. }
  19365. },
  19366. content: function() {
  19367. return this._$content
  19368. },
  19369. container: function() {
  19370. return this._$container
  19371. }
  19372. }));
  19373. ui.dxPopup.__internals = {
  19374. POPUP_CLASS: POPUP_CLASS,
  19375. POPUP_WRAPPER_CLASS: POPUP_WRAPPER_CLASS,
  19376. POPUP_CONTENT_CLASS: POPUP_CONTENT_CLASS,
  19377. POPUP_FULL_SCREEN_CLASS: POPUP_FULL_SCREEN_CLASS,
  19378. POPUP_TITLE_CLASS: POPUP_TITLE_CLASS,
  19379. POPUP_TITLE_CLOSEBUTTON_CLASS: POPUP_TITLE_CLOSEBUTTON_CLASS,
  19380. POPUP_TITLE_HAS_BUTTON_CLASS: POPUP_TITLE_HAS_BUTTON_CLASS
  19381. }
  19382. })(jQuery, DevExpress);
  19383. /*! Module widgets-base, file ui.popover.js */
  19384. (function($, DX, undefined) {
  19385. var ui = DX.ui,
  19386. fx = DX.fx;
  19387. var POPOVER_CLASS = "dx-popover",
  19388. POPOVER_WRAPPER_CLASS = "dx-popover-wrapper",
  19389. POPOVER_ARROW_CLASS = "dx-popover-arrow",
  19390. POPOVER_WITHOUT_TITLE_CLASS = "dx-popover-without-title",
  19391. POSITION_FLIP_MAP = {
  19392. left: "right",
  19393. top: "bottom",
  19394. right: "left",
  19395. bottom: "top"
  19396. },
  19397. POSITION_ALIASES = {
  19398. top: {
  19399. my: "bottom center",
  19400. at: "top center"
  19401. },
  19402. bottom: {
  19403. my: "top center",
  19404. at: "bottom center"
  19405. },
  19406. right: {
  19407. my: "left center",
  19408. at: "right center"
  19409. },
  19410. left: {
  19411. my: "right center",
  19412. at: "left center"
  19413. },
  19414. topNone: {
  19415. my: "bottom center",
  19416. at: "top center",
  19417. collision: "none"
  19418. },
  19419. bottomNone: {
  19420. my: "top center",
  19421. at: "bottom center",
  19422. collision: "none"
  19423. },
  19424. rightNone: {
  19425. my: "left center",
  19426. at: "right center",
  19427. collision: "none"
  19428. },
  19429. leftNone: {
  19430. my: "right center",
  19431. at: "left center",
  19432. collision: "none"
  19433. }
  19434. },
  19435. DEFAULT_VIEWPORT_OFFSET = "10 10";
  19436. DX.registerComponent("dxPopover", ui.dxPopup.inherit({
  19437. _setDefaultOptions: function() {
  19438. this.callBase();
  19439. this.option({
  19440. target: window,
  19441. shading: false,
  19442. position: 'bottom',
  19443. closeOnOutsideClick: $.proxy(this._isOutsideClick, this),
  19444. animation: {
  19445. show: {
  19446. type: "fade",
  19447. from: 0,
  19448. to: 1
  19449. },
  19450. hide: {
  19451. type: "fade",
  19452. to: 0
  19453. }
  19454. },
  19455. showTitle: false,
  19456. width: "auto",
  19457. height: "auto",
  19458. dragEnabled: false,
  19459. fullScreen: false,
  19460. closeOnTargetScroll: true
  19461. })
  19462. },
  19463. _defaultOptionsRules: function() {
  19464. return []
  19465. },
  19466. _render: function() {
  19467. this._element().addClass(POPOVER_CLASS);
  19468. this._wrapper().addClass(POPOVER_WRAPPER_CLASS);
  19469. this._renderArrow();
  19470. this.callBase()
  19471. },
  19472. _renderArrow: function() {
  19473. this._$arrow = $("<div>").addClass(POPOVER_ARROW_CLASS).appendTo(this._wrapper())
  19474. },
  19475. _setContentHeight: function(fullUpdate) {
  19476. if (fullUpdate)
  19477. this.callBase()
  19478. },
  19479. _updateContentSize: function(containerLocation) {
  19480. if (!this._$content)
  19481. return;
  19482. var positionAt = this._position.at.split(" ")[0];
  19483. if (containerLocation.h.oversize > 0 && (positionAt === "left" || positionAt === "right")) {
  19484. var newContainerWidth = this._$container.width() - containerLocation.h.oversize;
  19485. this._$container.width(newContainerWidth)
  19486. }
  19487. if (containerLocation.v.oversize > 0 && (positionAt === "top" || positionAt === "bottom")) {
  19488. var titleSize = this._$title ? this._$title.outerHeight() : 0,
  19489. newContainerHeight = this._$container.height() - containerLocation.v.oversize;
  19490. this._$container.height(newContainerHeight);
  19491. this._$content.outerHeight(newContainerHeight - titleSize)
  19492. }
  19493. },
  19494. _isOutsideClick: function(e) {
  19495. return !$(e.target).closest(this.option("target")).length
  19496. },
  19497. _animate: function(animation) {
  19498. if (animation)
  19499. DX.fx.animate(this._$arrow, $.extend({}, animation, {complete: $.noop}));
  19500. if (animation && animation.to)
  19501. $.extend(animation.to, {position: this._contentPosition});
  19502. this.callBase.apply(this, arguments)
  19503. },
  19504. _stopAnimation: function() {
  19505. this.callBase.apply(this, arguments);
  19506. fx.stop(this._$arrow)
  19507. },
  19508. _renderTitle: function() {
  19509. this._wrapper().toggleClass(POPOVER_WITHOUT_TITLE_CLASS, !this.option("showTitle"));
  19510. this.callBase()
  19511. },
  19512. _isPopoverLargerThanTarget: function() {
  19513. var position = this._position.at.split(" ")[0],
  19514. $target = $(this._position.of),
  19515. popoverSize,
  19516. targetSize;
  19517. switch (position) {
  19518. case"top":
  19519. case"bottom":
  19520. popoverSize = this._$container.width();
  19521. targetSize = $target.outerWidth() + this._$arrow.width();
  19522. break;
  19523. case"left":
  19524. case"right":
  19525. popoverSize = this._$container.height();
  19526. targetSize = $target.outerHeight() + this._$arrow.height();
  19527. break
  19528. }
  19529. return popoverSize > targetSize / 2
  19530. },
  19531. _renderPosition: function() {
  19532. this.callBase();
  19533. this._renderOverlayPosition();
  19534. this._renderArrowPosition()
  19535. },
  19536. _renderOverlayPosition: function() {
  19537. this._setContentHeight(true);
  19538. this._togglePositionClass("dx-position-" + this._positionAlias);
  19539. DX.translator.move(this._$arrow, {
  19540. left: 0,
  19541. top: 0
  19542. });
  19543. DX.translator.move(this._$container, {
  19544. left: 0,
  19545. top: 0
  19546. });
  19547. var contentPosition = $.extend({}, this._position);
  19548. var containerPosition = $.extend({}, contentPosition, {offset: this._$arrow.width() + " " + this._$arrow.height()}),
  19549. containerLocation = DX.calculatePosition(this._$container, containerPosition),
  19550. isFlippedByVertical = containerLocation.v.flip,
  19551. isFlippedByHorizontal = containerLocation.h.flip;
  19552. this._updateContentSize(containerLocation);
  19553. if (this._position.collision === "flip")
  19554. contentPosition.collision = "fit";
  19555. var positionClass = "dx-position-" + (isFlippedByVertical || isFlippedByHorizontal ? POSITION_FLIP_MAP[this._positionAlias] : this._positionAlias);
  19556. this._togglePositionClass(positionClass);
  19557. if (isFlippedByVertical || isFlippedByHorizontal)
  19558. $.extend(contentPosition, {
  19559. my: contentPosition.at,
  19560. at: contentPosition.my
  19561. });
  19562. contentPosition.offset = this._updateContentOffset(isFlippedByVertical, isFlippedByHorizontal, contentPosition.offset);
  19563. DX.position(this._$container, contentPosition);
  19564. this._contentPosition = contentPosition
  19565. },
  19566. _renderArrowPosition: function() {
  19567. var isPopoverLarger = this._isPopoverLargerThanTarget(),
  19568. contentPositionMy = this._contentPosition.my.split(" ")[0],
  19569. contentPositionAt = this._contentPosition.at.split(" ")[0];
  19570. var arrowPosition;
  19571. if (isPopoverLarger)
  19572. arrowPosition = {
  19573. my: contentPositionMy,
  19574. at: contentPositionAt,
  19575. of: $(this.option("target"))
  19576. };
  19577. else {
  19578. var arrowPosition = contentPositionAt;
  19579. arrowPosition = {
  19580. my: contentPositionAt,
  19581. at: contentPositionMy,
  19582. of: this._$container,
  19583. offset: this._updateArrowOffset(arrowPosition)
  19584. }
  19585. }
  19586. arrowPosition.my += " center";
  19587. arrowPosition.at += " center";
  19588. DX.position(this._$arrow, arrowPosition)
  19589. },
  19590. _renderShadingPosition: function() {
  19591. if (this.option("shading"))
  19592. this._$wrapper.css({
  19593. top: 0,
  19594. left: 0
  19595. })
  19596. },
  19597. _renderShadingDimensions: function() {
  19598. if (this.option("shading"))
  19599. this._$wrapper.css({
  19600. width: "100%",
  19601. height: "100%"
  19602. })
  19603. },
  19604. _togglePositionClass: function(positionClass) {
  19605. this._$wrapper.removeClass("dx-position-left dx-position-right dx-position-top dx-position-bottom");
  19606. this._$wrapper.addClass(positionClass)
  19607. },
  19608. _normalizePosition: function() {
  19609. var position = this.option("position");
  19610. if (DX.utils.isString(position))
  19611. position = $.extend({}, POSITION_ALIASES[position]);
  19612. if (!position.of)
  19613. position.of = this.option("target");
  19614. if (!position.collision)
  19615. position.collision = "flip";
  19616. if (!position.boundaryOffset)
  19617. position.boundaryOffset = DEFAULT_VIEWPORT_OFFSET;
  19618. this._positionAlias = position.at.split(" ")[0];
  19619. this._position = position
  19620. },
  19621. _getOffsetObject: function(offset) {
  19622. var result = DX.utils.stringPairToObject(offset);
  19623. return {
  19624. h: result.x,
  19625. v: result.y
  19626. }
  19627. },
  19628. _updateContentOffset: function(isFlippedByVertical, isFlippedByHorizontal, offsetString) {
  19629. var position = this._positionAlias,
  19630. offset = this._getOffsetObject(offsetString);
  19631. var isTopPosition = position === "top" && !isFlippedByVertical || position === "bottom" && isFlippedByVertical,
  19632. isBottomPosition = position === "bottom" && !isFlippedByVertical || position === "top" && isFlippedByVertical,
  19633. isLeftPosition = position === "left" && !isFlippedByHorizontal || position === "right" && isFlippedByHorizontal,
  19634. isRightPosition = position === "right" && !isFlippedByHorizontal || position === "left" && isFlippedByHorizontal;
  19635. if (isTopPosition)
  19636. return offset.h + " " + (offset.v - (this._$arrow.height() - 1));
  19637. if (isBottomPosition)
  19638. return offset.h + " " + (offset.v + (this._$arrow.height() - 1));
  19639. if (isLeftPosition)
  19640. return offset.h - (this._$arrow.width() - 1) + " " + offset.v;
  19641. if (isRightPosition)
  19642. return offset.h + (this._$arrow.width() - 1) + " " + offset.v
  19643. },
  19644. _updateArrowOffset: function(position) {
  19645. switch (position) {
  19646. case"top":
  19647. return "0 -1";
  19648. case"bottom":
  19649. return "0 1";
  19650. case"left":
  19651. return "-1 0";
  19652. case"right":
  19653. return "1 0"
  19654. }
  19655. },
  19656. _optionChanged: function(name, value) {
  19657. switch (name) {
  19658. case"showTitle":
  19659. case"title":
  19660. case"titleTemplate":
  19661. this.callBase.apply(this, arguments);
  19662. this._normalizePosition();
  19663. this._renderPosition();
  19664. break;
  19665. case"target":
  19666. this._normalizePosition();
  19667. this._renderPosition();
  19668. break;
  19669. case"fullScreen":
  19670. if (value)
  19671. this.option("fullScreen", false);
  19672. break;
  19673. default:
  19674. this.callBase.apply(this, arguments)
  19675. }
  19676. }
  19677. }));
  19678. ui.dxPopover.__internals = {
  19679. POPOVER_CLASS: POPOVER_CLASS,
  19680. POPOVER_WRAPPER_CLASS: POPOVER_WRAPPER_CLASS,
  19681. POPOVER_ARROW_CLASS: POPOVER_ARROW_CLASS,
  19682. POPOVER_WITHOUT_TITLE_CLASS: POPOVER_WITHOUT_TITLE_CLASS,
  19683. DEFAULT_VIEWPORT_OFFSET: DEFAULT_VIEWPORT_OFFSET
  19684. }
  19685. })(jQuery, DevExpress);
  19686. /*! Module widgets-base, file ui.tooltip.js */
  19687. (function($, DX, undefined) {
  19688. var ui = DX.ui,
  19689. TOOLTIP_CLASS = "dx-tooltip",
  19690. TOOLTIP_WRAPPER_CLASS = TOOLTIP_CLASS + "-wrapper";
  19691. DX.registerComponent("dxTooltip", ui.dxPopover.inherit({
  19692. _setDefaultOptions: function() {
  19693. this.callBase();
  19694. this.option({
  19695. showTitle: false,
  19696. title: undefined,
  19697. titleTemplate: undefined
  19698. })
  19699. },
  19700. _render: function() {
  19701. this._element().addClass(TOOLTIP_CLASS);
  19702. this._wrapper().addClass(TOOLTIP_WRAPPER_CLASS);
  19703. this.callBase()
  19704. }
  19705. }));
  19706. ui.dxTooltip.__internals = {
  19707. TOOLTIP_CLASS: TOOLTIP_CLASS,
  19708. TOOLTIP_WRAPPER_CLASS: TOOLTIP_WRAPPER_CLASS
  19709. }
  19710. })(jQuery, DevExpress);
  19711. /*! Module widgets-base, file ui.slider.js */
  19712. (function($, DX, undefined) {
  19713. var ui = DX.ui,
  19714. events = ui.events,
  19715. fx = DX.fx,
  19716. utils = DX.utils,
  19717. translator = DX.translator,
  19718. transionEndEventName = DX.support.transitionEndEventName;
  19719. var SLIDER_CLASS = "dx-slider",
  19720. SLIDER_WRAPPER_CLASS = SLIDER_CLASS + "-wrapper",
  19721. SLIDER_HANDLE_CLASS = SLIDER_CLASS + "-handle",
  19722. SLIDER_HANDLE_SELECTOR = "." + SLIDER_HANDLE_CLASS,
  19723. SLIDER_BAR_CLASS = SLIDER_CLASS + "-bar",
  19724. SLIDER_RANGE_CLASS = SLIDER_CLASS + "-range",
  19725. SLIDER_RANGE_VISIBLE_CLASS = SLIDER_RANGE_CLASS + "-visible",
  19726. SLIDER_LABEL_CLASS = SLIDER_CLASS + "-label",
  19727. SLIDER_LABEL_POSITION_CLASS_PREFIX = SLIDER_LABEL_CLASS + "-position-",
  19728. SLIDER_TOOLTIP_CLASS = SLIDER_CLASS + "-tooltip",
  19729. SLIDER_TOOLTIP_POSITION_CLASS_PREFIX = SLIDER_TOOLTIP_CLASS + "-position-",
  19730. SLIDER_TOOLTIP_ON_HOVER_ENABLED = SLIDER_TOOLTIP_CLASS + "-on-hover-enabled";
  19731. DX.registerComponent("dxSliderHandle", ui.Widget.inherit({
  19732. _setDefaultOptions: function() {
  19733. this.callBase();
  19734. this.option({
  19735. activeStateEnabled: false,
  19736. hoverStateEnabled: false,
  19737. value: 50,
  19738. tooltipEnabled: false,
  19739. tooltipFormat: function(v) {
  19740. return v
  19741. },
  19742. tooltipPosition: "top",
  19743. tooltipShowMode: "onHover",
  19744. tooltipFitIn: null
  19745. })
  19746. },
  19747. _render: function() {
  19748. this.callBase();
  19749. this._element().addClass(SLIDER_HANDLE_CLASS);
  19750. this._renderTooltip()
  19751. },
  19752. _renderTooltip: function() {
  19753. if (this.option("tooltipEnabled")) {
  19754. if (!this._$tooltip) {
  19755. this._$tooltip = $("<div>").appendTo(this._element()).dxTooltip({
  19756. visible: true,
  19757. height: undefined,
  19758. target: this._element(),
  19759. closeOnOutsideClick: false,
  19760. closeOnTargetScroll: false,
  19761. targetContainer: this._element(),
  19762. hideTopOverlayHandler: null
  19763. });
  19764. this._tooltip = this._$tooltip.dxTooltip("instance")
  19765. }
  19766. this._renderTooltipPosition();
  19767. this._renderTooltipShowMode();
  19768. this._renderValue()
  19769. }
  19770. else
  19771. this._removeTooltip()
  19772. },
  19773. _visibilityChanged: function() {
  19774. this._dimensionChanged()
  19775. },
  19776. _dimensionChanged: function() {
  19777. this._repaintTooltip()
  19778. },
  19779. _removeTooltip: function() {
  19780. if (!this._$tooltip)
  19781. return;
  19782. this._$tooltip.remove();
  19783. delete this._$tooltip;
  19784. delete this._tooltip
  19785. },
  19786. _renderTooltipPosition: function() {
  19787. if (!this._tooltip)
  19788. return;
  19789. var position = this.option("tooltipPosition");
  19790. if ($.type(position) === "string")
  19791. position = position + "None";
  19792. this._tooltip.option("position", position)
  19793. },
  19794. _repaintTooltip: function() {
  19795. if (this._tooltip)
  19796. this._tooltip.repaint()
  19797. },
  19798. _renderValue: function() {
  19799. if (!this._tooltip)
  19800. return;
  19801. var format = this.option("tooltipFormat"),
  19802. value = format(this.option("value"));
  19803. this._tooltip.content().html(value);
  19804. this._fitTooltipPosition()
  19805. },
  19806. _renderTooltipShowMode: function() {
  19807. this._element().toggleClass("dx-slider-tooltip-on-hover", /^onhover$/i.test(this.option("tooltipShowMode")))
  19808. },
  19809. _fitTooltipPosition: function() {
  19810. if (!this._$tooltip)
  19811. return;
  19812. var $tooltipContent = this._tooltip.content().parent(),
  19813. tooltipWidth = $tooltipContent.outerWidth(),
  19814. $boundElement = this.option("tooltipFitIn"),
  19815. boundElementWidth = $boundElement.outerWidth(),
  19816. boundElementLeft = $boundElement.offset().left,
  19817. boundElementRight = boundElementLeft + boundElementWidth,
  19818. $element = this._element(),
  19819. elementWidth = $element.outerWidth(),
  19820. elementLeft = $element.offset().left,
  19821. elementRight = elementLeft + elementWidth,
  19822. idealOffset = Math.round(elementWidth / 2 - tooltipWidth / 2),
  19823. minOffset = Math.ceil(boundElementLeft - elementLeft),
  19824. maxOffset = Math.floor(boundElementRight - elementRight) + idealOffset * 2,
  19825. newOffset = Math.min(Math.max(minOffset, idealOffset), maxOffset);
  19826. translator.move($tooltipContent, {left: newOffset})
  19827. },
  19828. _optionChanged: function(name, value, prevValue) {
  19829. switch (name) {
  19830. case"tooltipFormat":
  19831. this._renderValue();
  19832. break;
  19833. case"value":
  19834. this._renderValue();
  19835. break;
  19836. case"tooltipEnabled":
  19837. this._renderTooltip();
  19838. break;
  19839. case"tooltipPosition":
  19840. this._renderTooltipPosition();
  19841. break;
  19842. case"tooltipShowMode":
  19843. this._renderTooltipShowMode();
  19844. break;
  19845. case"tooltipFitIn":
  19846. this._fitTooltipPosition();
  19847. break;
  19848. default:
  19849. this.callBase.apply(this, arguments)
  19850. }
  19851. },
  19852. fitTooltipPosition: function() {
  19853. this._fitTooltipPosition()
  19854. },
  19855. repaint: function() {
  19856. this._repaintTooltip();
  19857. this._renderTooltipPosition();
  19858. this._fitTooltipPosition()
  19859. }
  19860. }));
  19861. DX.registerComponent("dxSlider", ui.dxEditor.inherit({
  19862. _activeStateUnit: SLIDER_HANDLE_SELECTOR,
  19863. _setDefaultOptions: function() {
  19864. this.callBase();
  19865. this.option({
  19866. min: 0,
  19867. max: 100,
  19868. step: 1,
  19869. value: 50,
  19870. showRange: true,
  19871. tooltip: {
  19872. enabled: false,
  19873. format: function(value) {
  19874. return value
  19875. },
  19876. position: "top",
  19877. showMode: "onHover"
  19878. },
  19879. label: {
  19880. visible: false,
  19881. position: "bottom",
  19882. format: function(value) {
  19883. return value
  19884. }
  19885. }
  19886. })
  19887. },
  19888. _render: function() {
  19889. this._element().addClass(SLIDER_CLASS);
  19890. this._renderBar();
  19891. this._renderRange();
  19892. this._renderWrapper();
  19893. this._$wrapper.dxSwipeable({
  19894. elastic: false,
  19895. startAction: $.proxy(this._handleSwipeStart, this),
  19896. updateAction: $.proxy(this._handleSwipeUpdate, this),
  19897. endAction: $.proxy(this._handleSwipeEnd, this),
  19898. itemSizeFunc: $.proxy(this._itemWidthFunc, this)
  19899. });
  19900. this._renderHandle();
  19901. this.callBase();
  19902. this._renderValue();
  19903. this._renderLabels();
  19904. this._renderStartHandler()
  19905. },
  19906. _visibilityChanged: function() {
  19907. this.repaint()
  19908. },
  19909. _renderWrapper: function() {
  19910. this._$wrapper = $("<div>").addClass(SLIDER_WRAPPER_CLASS).append(this._$bar).appendTo(this._element())
  19911. },
  19912. _renderBar: function() {
  19913. this._$bar = $("<div>").addClass(SLIDER_BAR_CLASS);
  19914. this._$bar.off(transionEndEventName + "." + this.NAME).on(transionEndEventName, $.proxy(this._fitHandleTooltipPosition, this))
  19915. },
  19916. _renderRange: function() {
  19917. this._$selectedRange = $("<div>").addClass(SLIDER_RANGE_CLASS).appendTo(this._$bar);
  19918. this._renderRangeVisibility()
  19919. },
  19920. _renderRangeVisibility: function() {
  19921. this._$selectedRange.toggleClass(SLIDER_RANGE_VISIBLE_CLASS, Boolean(this.option("showRange")))
  19922. },
  19923. _renderHandle: function() {
  19924. this._$handle = this._renderHandleImpl(this.option("value"), this._$handle)
  19925. },
  19926. _renderHandleImpl: function(value, $element) {
  19927. var $handle = $element || $("<div>").appendTo(this._$selectedRange),
  19928. format = this._normalizeFormat(this.option("tooltip.format")),
  19929. tooltipEnabled = this.option("tooltip.enabled"),
  19930. tooltipPosition = this.option("tooltip.position");
  19931. this._element().toggleClass(SLIDER_TOOLTIP_ON_HOVER_ENABLED, tooltipEnabled && DX.devices.real().platform !== "ios").toggleClass(SLIDER_TOOLTIP_POSITION_CLASS_PREFIX + "bottom", tooltipEnabled && tooltipPosition === "bottom").toggleClass(SLIDER_TOOLTIP_POSITION_CLASS_PREFIX + "top", tooltipEnabled && tooltipPosition === "top");
  19932. return $handle.dxSliderHandle({
  19933. value: value,
  19934. tooltipEnabled: tooltipEnabled,
  19935. tooltipPosition: tooltipPosition,
  19936. tooltipFormat: format,
  19937. tooltipShowMode: this.option("tooltip.showMode"),
  19938. tooltipFitIn: this._element()
  19939. })
  19940. },
  19941. _renderLabels: function() {
  19942. this._element().removeClass(SLIDER_LABEL_POSITION_CLASS_PREFIX + "bottom").removeClass(SLIDER_LABEL_POSITION_CLASS_PREFIX + "top");
  19943. if (this.option("label.visible")) {
  19944. var min = this.option("min"),
  19945. max = this.option("max"),
  19946. position = this.option("label.position"),
  19947. format = this._normalizeFormat(this.option("label.format"));
  19948. if (!this._$minLabel)
  19949. this._$minLabel = $("<div>").addClass(SLIDER_LABEL_CLASS).appendTo(this._$wrapper);
  19950. this._$minLabel.html(format(min));
  19951. if (!this._$maxLabel)
  19952. this._$maxLabel = $("<div>").addClass(SLIDER_LABEL_CLASS).appendTo(this._$wrapper);
  19953. this._$maxLabel.html(format(max));
  19954. this._element().addClass(SLIDER_LABEL_POSITION_CLASS_PREFIX + position)
  19955. }
  19956. else {
  19957. if (this._$minLabel) {
  19958. this._$minLabel.remove();
  19959. delete this._$minLabel
  19960. }
  19961. if (this._$maxLabel) {
  19962. this._$maxLabel.remove();
  19963. delete this._$maxLabel
  19964. }
  19965. }
  19966. },
  19967. _normalizeFormat: function(formatSource) {
  19968. var format = formatSource;
  19969. if (typeof formatSource === "string")
  19970. format = function(value) {
  19971. return Globalize.format(value, formatSource)
  19972. };
  19973. else if ($.isFunction(formatSource))
  19974. format = $.proxy(format, this);
  19975. else
  19976. format = function(value) {
  19977. return value
  19978. };
  19979. return format
  19980. },
  19981. _renderDimensions: function() {
  19982. this.callBase();
  19983. if (this._$bar) {
  19984. var barMarginWidth = this._$bar.outerWidth(true) - this._$bar.outerWidth();
  19985. this._$bar.width(this.option("width") - barMarginWidth)
  19986. }
  19987. },
  19988. _renderStartHandler: function() {
  19989. var eventName = events.addNamespace("dxpointerdown", this.NAME),
  19990. startAction = this._createAction($.proxy(this._handleStart, this), {excludeValidators: ["gesture"]});
  19991. this._element().off(eventName).on(eventName, function(e) {
  19992. e.preventDefault();
  19993. startAction({jQueryEvent: e})
  19994. })
  19995. },
  19996. _itemWidthFunc: function() {
  19997. return this._element().width() / this._swipePixelRatio()
  19998. },
  19999. _handleSwipeStart: function(e) {
  20000. var rtlEnabled = this.option("rtlEnabled"),
  20001. startOffset,
  20002. endOffset;
  20003. this._startOffset = this._currentRatio;
  20004. startOffset = this._startOffset * this._swipePixelRatio();
  20005. endOffset = (1 - this._startOffset) * this._swipePixelRatio();
  20006. e.jQueryEvent.maxLeftOffset = rtlEnabled ? endOffset : startOffset;
  20007. e.jQueryEvent.maxRightOffset = rtlEnabled ? startOffset : endOffset;
  20008. this._swipeHandled = true
  20009. },
  20010. _handleSwipeEnd: function(e) {
  20011. var offsetDirection = this.option("rtlEnabled") ? -1 : 1;
  20012. delete this._swipeHandled;
  20013. this._changeValueOnSwipe(this._startOffset + offsetDirection * e.jQueryEvent.targetOffset / this._swipePixelRatio());
  20014. delete this._startOffset;
  20015. this._renderValue()
  20016. },
  20017. _activeHandle: function() {
  20018. return this._$handle
  20019. },
  20020. _handleSwipeUpdate: function(e) {
  20021. this._valueChangeEventInstance = e;
  20022. this._updateHandlePosition(e)
  20023. },
  20024. _updateHandlePosition: function(e) {
  20025. var offsetDirection = this.option("rtlEnabled") ? -1 : 1;
  20026. var newRatio = this._startOffset + offsetDirection * e.jQueryEvent.offset / this._swipePixelRatio();
  20027. this._$selectedRange.width(newRatio * 100 + "%");
  20028. this._changeValueOnSwipe(newRatio)
  20029. },
  20030. _swipePixelRatio: function() {
  20031. var min = this.option("min"),
  20032. max = this.option("max"),
  20033. step = this._valueStep();
  20034. return (max - min) / step
  20035. },
  20036. _valueStep: function() {
  20037. var step = this.option("step");
  20038. if (!step || isNaN(step))
  20039. step = 1;
  20040. step = parseFloat(step.toFixed(5));
  20041. if (step === 0)
  20042. step = 0.00001;
  20043. return step
  20044. },
  20045. _changeValueOnSwipe: function(ratio) {
  20046. var min = this.option("min"),
  20047. max = this.option("max"),
  20048. step = this._valueStep(),
  20049. newChange = ratio * (max - min),
  20050. newValue = min + newChange;
  20051. if (step < 0)
  20052. return;
  20053. if (newValue === max || newValue === min)
  20054. this.option("value", newValue);
  20055. else {
  20056. var stepChunks = (step + "").split('.'),
  20057. exponent = stepChunks.length > 1 ? stepChunks[1].length : exponent;
  20058. newValue = Number((Math.round(newChange / step) * step + min).toFixed(exponent));
  20059. this.option("value", Math.max(Math.min(newValue, max), min))
  20060. }
  20061. },
  20062. _handleStart: function(args) {
  20063. var e = args.jQueryEvent;
  20064. if (events.needSkipEvent(e))
  20065. return;
  20066. this._feedbackOn(this._activeHandle(), true);
  20067. this._currentRatio = (ui.events.eventData(e).x - this._$bar.offset().left) / this._$bar.width();
  20068. if (this.option("rtlEnabled"))
  20069. this._currentRatio = 1 - this._currentRatio;
  20070. this._valueChangeEventInstance = e;
  20071. this._changeValueOnSwipe(this._currentRatio)
  20072. },
  20073. _renderValue: function() {
  20074. var val = this.option("value"),
  20075. min = this.option("min"),
  20076. max = this.option("max");
  20077. if (min > max)
  20078. return;
  20079. if (val < min) {
  20080. this.option("value", min);
  20081. this._currentRatio = 0;
  20082. return
  20083. }
  20084. if (val > max) {
  20085. this.option("value", max);
  20086. this._currentRatio = 1;
  20087. return
  20088. }
  20089. var ratio = min === max ? 0 : (val - min) / (max - min);
  20090. this._animateRange({width: ratio * 100 + "%"});
  20091. this._currentRatio = ratio;
  20092. this._activeHandle().dxSliderHandle("option", "value", this.option("value"))
  20093. },
  20094. _animateRange: function(configTo) {
  20095. fx.stop(this._$selectedRange);
  20096. if (!this._swipeHandled)
  20097. fx.animate(this._$selectedRange, {
  20098. type: "custom",
  20099. duration: 100,
  20100. to: configTo,
  20101. complete: $.proxy(this._fitHandleTooltipPosition, this)
  20102. })
  20103. },
  20104. _fitHandleTooltipPosition: function() {
  20105. if (this._activeHandle())
  20106. this._activeHandle().dxSliderHandle("fitTooltipPosition")
  20107. },
  20108. _repaintHandle: function() {
  20109. this._$handle.dxSliderHandle("repaint")
  20110. },
  20111. _optionChanged: function(name) {
  20112. switch (name) {
  20113. case"visible":
  20114. this.callBase.apply(this, arguments);
  20115. this._renderHandle();
  20116. this._repaintHandle();
  20117. break;
  20118. case"min":
  20119. case"max":
  20120. this._renderValue();
  20121. this._renderLabels();
  20122. break;
  20123. case"step":
  20124. this._renderValue();
  20125. break;
  20126. case"value":
  20127. this._renderValue();
  20128. this.callBase.apply(this, arguments);
  20129. break;
  20130. case"showRange":
  20131. this._renderRangeVisibility();
  20132. break;
  20133. case"tooltip":
  20134. this._renderHandle();
  20135. break;
  20136. case"label":
  20137. this._renderLabels();
  20138. break;
  20139. case"rtlEnabled":
  20140. this._toggleRTLDirection();
  20141. this._renderValue();
  20142. break;
  20143. default:
  20144. this.callBase.apply(this, arguments)
  20145. }
  20146. },
  20147. _dispose: function() {
  20148. fx.stop(this._$selectedRange);
  20149. this.callBase.apply(this, arguments)
  20150. },
  20151. _refresh: function() {
  20152. this._renderDimensions();
  20153. this._renderValue();
  20154. this._renderHandle()
  20155. },
  20156. _feedbackOff: function(immediate, isGestureStart) {
  20157. if (immediate && !isGestureStart)
  20158. return;
  20159. this.callBase.apply(this, arguments)
  20160. }
  20161. }))
  20162. })(jQuery, DevExpress);
  20163. /*! Module widgets-base, file ui.rangeSlider.js */
  20164. (function($, DX, undefined) {
  20165. var ui = DX.ui,
  20166. events = ui.events;
  20167. var SLIDER_HANDLE_CLASS = "dx-slider-handle",
  20168. RANGE_SLIDER_CLASS = "dx-range-slider",
  20169. RANGE_SLIDER_START_HANDLE_CLASS = RANGE_SLIDER_CLASS + "-start-handle";
  20170. DX.registerComponent("dxRangeSlider", ui.dxSlider.inherit({
  20171. _setDefaultOptions: function() {
  20172. this.callBase();
  20173. this.option({
  20174. start: 40,
  20175. end: 60,
  20176. value: 50
  20177. })
  20178. },
  20179. _render: function() {
  20180. this.callBase();
  20181. this._element().addClass(RANGE_SLIDER_CLASS)
  20182. },
  20183. _renderHandle: function() {
  20184. this._$handleStart = this._renderHandleImpl(this.option("start"), this._$handleStart).addClass(RANGE_SLIDER_START_HANDLE_CLASS);
  20185. this._$handleEnd = this._renderHandleImpl(this.option("end"), this._$handleEnd)
  20186. },
  20187. _handleStart: function(args) {
  20188. var e = args.jQueryEvent,
  20189. $range = this._$selectedRange,
  20190. rangeWidth = $range.width(),
  20191. eventOffsetX = events.eventData(e).x - this._$bar.offset().left,
  20192. startHandleX = $range.position().left,
  20193. endHandleX = $range.position().left + rangeWidth,
  20194. rtlEnabled = this.option("rtlEnabled"),
  20195. startHandleIsClosest = (rtlEnabled ? -1 : 1) * ((startHandleX + endHandleX) / 2 - eventOffsetX) > 0;
  20196. this._feedbackOff(true, true);
  20197. this._capturedHandle = startHandleIsClosest ? this._$handleStart : this._$handleEnd;
  20198. this.callBase(args)
  20199. },
  20200. _activeHandle: function() {
  20201. return this._capturedHandle
  20202. },
  20203. _updateHandlePosition: function(e) {
  20204. var rtlEnabled = this.option("rtlEnabled"),
  20205. offsetDirection = rtlEnabled ? -1 : 1,
  20206. max = this.option("max"),
  20207. min = this.option("min");
  20208. var newRatio = this._startOffset + offsetDirection * e.jQueryEvent.offset / this._swipePixelRatio(),
  20209. newRatio = newRatio.toPrecision(12),
  20210. newValue = newRatio * (max - min) + min;
  20211. this._updateSelectedRangePosition(newRatio, newRatio);
  20212. this._changeValueOnSwipe(newRatio);
  20213. var startValue = this.option("start"),
  20214. endValue = this.option("end"),
  20215. $nextHandle;
  20216. if (startValue === endValue) {
  20217. if (newValue < startValue)
  20218. $nextHandle = this._$handleStart;
  20219. else
  20220. $nextHandle = this._$handleEnd;
  20221. if ($nextHandle && $nextHandle !== this._capturedHandle) {
  20222. this._updateSelectedRangePosition((startValue - min) / (max - min), (endValue - min) / (max - min));
  20223. this._feedbackOff(true, true);
  20224. this._feedbackOn($nextHandle, true);
  20225. this._capturedHandle = $nextHandle
  20226. }
  20227. this._updateSelectedRangePosition(newRatio, newRatio);
  20228. this._changeValueOnSwipe(newRatio)
  20229. }
  20230. },
  20231. _updateSelectedRangePosition: function(leftRatio, rightRatio) {
  20232. var rtlEnabled = this.option("rtlEnabled"),
  20233. moveRight = this._capturedHandle === this._$handleStart && rtlEnabled || this._capturedHandle === this._$handleEnd && !rtlEnabled;
  20234. var prop = moveRight ? "right" : "left";
  20235. if (rtlEnabled ^ moveRight)
  20236. this._$selectedRange.css(prop, 100 - rightRatio * 100 + "%");
  20237. else
  20238. this._$selectedRange.css(prop, leftRatio * 100 + "%")
  20239. },
  20240. _changeValueOnSwipe: function(ratio) {
  20241. this._suppressValueChangeAction();
  20242. this.callBase(ratio);
  20243. this._resumeValueChangeAction();
  20244. var option = this._capturedHandle === this._$handleStart ? "start" : "end",
  20245. start = this.option("start"),
  20246. end = this.option("end"),
  20247. newValue = this.option("value"),
  20248. max = this.option("max"),
  20249. min = this.option("min");
  20250. if (start > max) {
  20251. start = max;
  20252. this.option("start", max)
  20253. }
  20254. if (start < min) {
  20255. start = min;
  20256. this.option("start", min)
  20257. }
  20258. if (end > max) {
  20259. end = max;
  20260. this.option("end", max)
  20261. }
  20262. if (newValue > end && option === "start")
  20263. newValue = end;
  20264. if (newValue < start && option === "end")
  20265. newValue = start;
  20266. this.option(option, newValue)
  20267. },
  20268. _renderValue: function() {
  20269. var valStart = this.option("start"),
  20270. valEnd = this.option("end"),
  20271. min = this.option("min"),
  20272. max = this.option("max"),
  20273. rtlEnabled = this.option("rtlEnabled");
  20274. valStart = Math.max(min, Math.min(valStart, max));
  20275. valEnd = Math.max(valStart, Math.min(valEnd, max));
  20276. this.option("start", valStart);
  20277. this.option("end", valEnd);
  20278. var ratio1 = max === min ? 0 : (valStart - min) / (max - min),
  20279. ratio2 = max === min ? 0 : (valEnd - min) / (max - min);
  20280. var startOffset = parseFloat((ratio1 * 100).toPrecision(12)) + "%",
  20281. endOffset = parseFloat(((1 - ratio2) * 100).toPrecision(12)) + "%";
  20282. this._animateRange({
  20283. right: rtlEnabled ? startOffset : endOffset,
  20284. left: rtlEnabled ? endOffset : startOffset
  20285. });
  20286. this._renderHandle()
  20287. },
  20288. _repaintHandle: function() {
  20289. this._$handleStart.dxSliderHandle("repaint");
  20290. this._$handleEnd.dxSliderHandle("repaint")
  20291. },
  20292. _optionChanged: function(name) {
  20293. switch (name) {
  20294. case"start":
  20295. case"end":
  20296. this._renderValue();
  20297. this._createActionByOption("valueChangeAction")({
  20298. start: this.option("start"),
  20299. end: this.option("end")
  20300. });
  20301. break;
  20302. default:
  20303. this.callBase.apply(this, arguments)
  20304. }
  20305. }
  20306. }))
  20307. })(jQuery, DevExpress);
  20308. /*! Module widgets-base, file ui.calendar.js */
  20309. (function($, DX, undefined) {
  20310. var ui = DX.ui,
  20311. fx = DX.fx,
  20312. support = DX.support,
  20313. events = ui.events,
  20314. utils = DX.utils,
  20315. CALENDAR_CLASS = "dx-calendar",
  20316. CALENDAR_BODY_CLASS = "dx-calendar-body",
  20317. CALENDAR_NAVIGATOR_CLASS = "dx-calendar-navigator",
  20318. CALENDAR_OTHER_MONTH_CLASS = "dx-calendar-other-month",
  20319. CALENDAR_EMPTY_CELL_CLASS = "dx-calendar-empty-cell",
  20320. CALENDAR_DISABLED_NAVIGATOR_LINK_CLASS = "dx-calendar-disabled-navigator-link",
  20321. CALENDAR_TODAY_CLASS = "dx-calendar-today",
  20322. CALENDAR_SELECTED_DATE_CLASS = "dx-calendar-selected-date",
  20323. CALENDAR_CONTOURED_DATE_CLASS = "dx-calendar-contoured-date",
  20324. CALENDAR_NAVIGATOR_PREVIOUS_YEAR_CLASS = "dx-calendar-navigator-previous-year",
  20325. CALENDAR_NAVIGATOR_PREVIOUS_MONTH_CLASS = "dx-calendar-navigator-previous-month",
  20326. CALENDAR_NAVIGATOR_NEXT_MONTH_CLASS = "dx-calendar-navigator-next-month",
  20327. CALENDAR_NAVIGATOR_NEXT_YEAR_CLASS = "dx-calendar-navigator-next-year",
  20328. CALENDAR_MONTHVIEW_VALUECHANGED_EVENT_NAME = "dxCalendar.MonthView.ValueChanged",
  20329. CALENDAR_MONTHVIEW_CONTOUREDDATECHANGED_EVENT_NAME = "dxCalendar.MonthView.ContouredDateChanged",
  20330. CALENDAR_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxCalendar"),
  20331. CALENDAR_BLUR_EVENT_NAME = events.addNamespace("blur", "dxCalendar");
  20332. var BaseView = DX.Class.inherit({
  20333. ctor: function(options) {
  20334. this.date = options.date || new Date;
  20335. this.rtl = options.rtl
  20336. },
  20337. render: function(rootElement) {
  20338. this.rootElement = rootElement;
  20339. this.renderCore()
  20340. },
  20341. renderCore: $.noop
  20342. }),
  20343. views = {MonthView: BaseView.inherit({
  20344. ctor: function(options) {
  20345. options = options || {};
  20346. this.callBase(options);
  20347. this.firstDayOfWeek = options.firstDayOfWeek || 0;
  20348. if (options.keyDownProcessor && !options.disabled)
  20349. this.keyDownProcessor = options.keyDownProcessor.reinitialize(this.keyDownHandler, this);
  20350. if (options.contouredDate)
  20351. this.contouredDate = this.calculateContouredDate(options.contouredDate, options.value);
  20352. this.weeks = 6;
  20353. this.days = 7;
  20354. this.initialValue = options.value;
  20355. this.keyboardNavigationUsed = options.keyboardNavigationUsed;
  20356. this.min = options.min;
  20357. this.max = options.max;
  20358. this.disabled = options.disabled
  20359. },
  20360. dispose: function() {
  20361. if (this.keyDownProcessor)
  20362. this.keyDownProcessor.dispose();
  20363. $(this.table).remove()
  20364. },
  20365. detachKeyDownProcessor: function() {
  20366. var processor = this.keyDownProcessor;
  20367. this.keyDownProcessor = undefined;
  20368. return processor
  20369. },
  20370. renderCore: function() {
  20371. var that = this;
  20372. this.table = document.createElement("table");
  20373. this.renderHeader();
  20374. this.renderBody();
  20375. this.setValue(this.initialValue);
  20376. if (!this.disabled)
  20377. $(this.table).off(CALENDAR_DXCLICK_EVENT_NAME).on(CALENDAR_DXCLICK_EVENT_NAME, "td", function(e) {
  20378. that.cellClickHandler(e)
  20379. });
  20380. if (!this.keyDownProcessor && !this.disabled) {
  20381. this.table.setAttribute("tabindex", -1);
  20382. this.keyDownProcessor = new ui.HierarchicalKeyDownProcessor({
  20383. element: this.table,
  20384. handler: this.keyDownHandler,
  20385. context: this
  20386. })
  20387. }
  20388. this.setContouredDate(this.contouredDate, true);
  20389. this.rootElement.appendChild(this.table)
  20390. },
  20391. renderHeader: function() {
  20392. var that = this,
  20393. header = this.table.createTHead(),
  20394. headerRow = header.insertRow(-1),
  20395. th,
  20396. caption;
  20397. this.iterateDays(function(i) {
  20398. th = document.createElement("th");
  20399. caption = document.createTextNode(that.getDayCaption(that.firstDayOfWeek + i));
  20400. th.appendChild(caption);
  20401. headerRow.appendChild(th)
  20402. })
  20403. },
  20404. renderBody: function() {
  20405. var that = this,
  20406. tbody = document.createElement("tbody"),
  20407. i,
  20408. row,
  20409. cell,
  20410. cellDate,
  20411. caption,
  20412. today = new Date;
  20413. this.table.appendChild(tbody);
  20414. for (i = 0; i < this.weeks; ++i) {
  20415. row = tbody.insertRow(-1);
  20416. this.iterateDays(function(j) {
  20417. cell = row.insertCell(-1);
  20418. cellDate = that.getDate(i, j);
  20419. if (utils.sameMonthAndYear(cellDate, today) && cellDate.getDate() === today.getDate())
  20420. cell.setAttribute("class", CALENDAR_TODAY_CLASS);
  20421. if (!utils.dateInRange(cellDate, that.min, that.max))
  20422. cell.setAttribute("class", CALENDAR_EMPTY_CELL_CLASS);
  20423. else if (cellDate.getMonth() !== that.date.getMonth())
  20424. cell.setAttribute("class", CALENDAR_OTHER_MONTH_CLASS);
  20425. cell.setAttribute("data-value", that.getShortDate(cellDate));
  20426. caption = document.createTextNode(cellDate.getDate());
  20427. cell.appendChild(caption)
  20428. })
  20429. }
  20430. },
  20431. getDayCaption: function(day) {
  20432. day = day < 7 ? day : Math.abs(day % 7);
  20433. return Globalize.culture().calendar.days.namesShort[day]
  20434. },
  20435. getNavigatorCaption: function() {
  20436. var navigatorMonth = Globalize.culture().calendar.months.names[this.date.getMonth()],
  20437. navigatorYear = this.date.getFullYear();
  20438. return this.rtl ? navigatorYear + " " + navigatorMonth : navigatorMonth + " " + navigatorYear
  20439. },
  20440. getDate: function(week, day) {
  20441. var firstDay = utils.getFirstMonthDate(this.date),
  20442. firstMonthDayPosition = firstDay.getDay() - this.firstDayOfWeek,
  20443. firstWeekDay = 7 * week - firstMonthDayPosition;
  20444. firstWeekDay = firstMonthDayPosition < 0 ? firstWeekDay - 7 : firstWeekDay;
  20445. firstDay.setDate(firstDay.getDate() + firstWeekDay + day);
  20446. return firstDay
  20447. },
  20448. getShortDate: function(date) {
  20449. return date.getFullYear() + "/" + date.getMonth() + "/" + date.getDate()
  20450. },
  20451. getDateFromShortDate: function(shortDate) {
  20452. var dateParts = shortDate.split("/");
  20453. return new Date(dateParts[0], dateParts[1], dateParts[2])
  20454. },
  20455. iterateDays: function(delegate) {
  20456. var i = this.rtl ? this.days - 1 : 0;
  20457. while (this.rtl ? i >= 0 : i < this.days) {
  20458. delegate(i);
  20459. this.rtl ? --i : ++i
  20460. }
  20461. },
  20462. cellClickHandler: function(e) {
  20463. var cellDate = this.getDateFromShortDate(e.target.getAttribute("data-value"));
  20464. if (utils.dateInRange(cellDate, this.min, this.max)) {
  20465. if (this.table.getAttribute("tabindex") && this.table !== document.activeElement)
  20466. $(this.table).focus();
  20467. this.setValue(cellDate, e.target)
  20468. }
  20469. },
  20470. keyDownHandler: function(options) {
  20471. var dayDifference,
  20472. contouredDate;
  20473. switch (options.key) {
  20474. case"leftArrow":
  20475. this.keyboardNavigationUsed = true;
  20476. dayDifference = this.rtl ? 1 : -1;
  20477. break;
  20478. case"rightArrow":
  20479. this.keyboardNavigationUsed = true;
  20480. dayDifference = this.rtl ? -1 : 1;
  20481. break;
  20482. case"upArrow":
  20483. this.keyboardNavigationUsed = true;
  20484. dayDifference = -7;
  20485. break;
  20486. case"downArrow":
  20487. this.keyboardNavigationUsed = true;
  20488. dayDifference = 7;
  20489. break;
  20490. case"enter":
  20491. this.keyboardNavigationUsed = true;
  20492. if (this.contouredDate)
  20493. this.setValue(this.contouredDate, this.tryGetCell(this.contouredDate));
  20494. return;
  20495. default:
  20496. return
  20497. }
  20498. options.originalEvent.stopPropagation();
  20499. options.originalEvent.preventDefault();
  20500. contouredDate = this.calculateContouredDate(this.contouredDate, this.value);
  20501. this.setContouredDate(new Date(contouredDate.getFullYear(), contouredDate.getMonth(), contouredDate.getDate() + dayDifference))
  20502. },
  20503. calculateContouredDate: function(contouredDate, value) {
  20504. var calculatedContouredDate;
  20505. if (utils.sameMonthAndYear(contouredDate, this.date))
  20506. calculatedContouredDate = contouredDate;
  20507. if (!calculatedContouredDate && utils.sameMonthAndYear(value, this.date))
  20508. calculatedContouredDate = value;
  20509. return calculatedContouredDate || utils.getFirstMonthDate(this.date)
  20510. },
  20511. setContouredDate: function(date, suppressChangedEvent) {
  20512. if (this.keyboardNavigationUsed) {
  20513. date = utils.normalizeDate(date, this.min, this.max);
  20514. var dateCell;
  20515. if (this.contouredDate) {
  20516. dateCell = this.tryGetCell(this.contouredDate);
  20517. if (dateCell)
  20518. dateCell.removeClass(CALENDAR_CONTOURED_DATE_CLASS)
  20519. }
  20520. this.contouredDate = date;
  20521. dateCell = this.tryGetCell(this.contouredDate);
  20522. if (dateCell)
  20523. dateCell.addClass(CALENDAR_CONTOURED_DATE_CLASS);
  20524. if (!suppressChangedEvent)
  20525. $(this.table).trigger(CALENDAR_MONTHVIEW_CONTOUREDDATECHANGED_EVENT_NAME, date)
  20526. }
  20527. },
  20528. setValue: function(value, cell) {
  20529. if (this.value !== value) {
  20530. this.value = value;
  20531. this.onValueChanged(value, cell)
  20532. }
  20533. },
  20534. tryGetCell: function(date) {
  20535. var foundCell = date ? $(this.table).find("td[data-value='" + this.getShortDate(date) + "']") : [];
  20536. return foundCell.length > 0 ? foundCell : undefined
  20537. },
  20538. onValueChanged: function(newValue, selectedCell) {
  20539. $(this.selectedCell).removeClass(CALENDAR_SELECTED_DATE_CLASS);
  20540. this.selectedCell = selectedCell || this.tryGetCell(newValue);
  20541. $(this.selectedCell).addClass(CALENDAR_SELECTED_DATE_CLASS);
  20542. if (selectedCell) {
  20543. this.setContouredDate(newValue);
  20544. $(this.rootElement).trigger(CALENDAR_MONTHVIEW_VALUECHANGED_EVENT_NAME, newValue)
  20545. }
  20546. }
  20547. })};
  20548. DX.registerComponent("dxCalendar", ui.dxEditor.inherit({
  20549. _setDefaultOptions: function() {
  20550. this.callBase();
  20551. this.option({
  20552. monthViewType: views.MonthView,
  20553. firstDayOfWeek: 1,
  20554. min: undefined,
  20555. max: undefined
  20556. })
  20557. },
  20558. _initOptions: function(options) {
  20559. options.currentDate = utils.normalizeDate(options.currentDate || options.value || new Date, options.min, options.max);
  20560. this.callBase(options)
  20561. },
  20562. _clean: function() {
  20563. if (!this.option("keyDownProcessor") && this._keyDownProcessor)
  20564. this._keyDownProcessor.dispose();
  20565. if (this._view)
  20566. this._view.dispose();
  20567. this.callBase()
  20568. },
  20569. _refresh: function() {
  20570. this._render()
  20571. },
  20572. _render: function() {
  20573. var that = this,
  20574. viewKeyDownProcessor;
  20575. this.callBase();
  20576. this._element().addClass(CALENDAR_CLASS);
  20577. this._initializeKeyDownProcessor();
  20578. this._oldView = this._view;
  20579. viewKeyDownProcessor = this._oldView ? this._oldView.detachKeyDownProcessor() : this._keyDownProcessor.attachChildProcessor();
  20580. this._view = this._initializeMonthView(viewKeyDownProcessor);
  20581. this._renderNavigator();
  20582. if (!this._body) {
  20583. this._body = $("<div />").addClass(CALENDAR_BODY_CLASS);
  20584. this._element().append(this._body)
  20585. }
  20586. this._renderMonthView();
  20587. if (!this._swipeable)
  20588. this._swipeable = this._element().dxSwipeable({
  20589. elastic: false,
  20590. startAction: function(e) {
  20591. that._handleSwipeStart(e)
  20592. },
  20593. updateAction: $.noop,
  20594. endAction: function(e) {
  20595. that._handleSwipeEnd(e)
  20596. },
  20597. itemWidthFunc: function() {
  20598. return this._element().width()
  20599. }
  20600. }).dxSwipeable("instance")
  20601. },
  20602. _initializeKeyDownProcessor: function() {
  20603. var that = this;
  20604. this._keyDownProcessor = this._keyDownProcessor || this.option("keyDownProcessor");
  20605. if (!this._keyDownProcessor) {
  20606. this._element().attr("tabindex", -1).on(CALENDAR_DXCLICK_EVENT_NAME, function() {
  20607. that._element().focus()
  20608. }).on(CALENDAR_BLUR_EVENT_NAME, function() {
  20609. that._view.setContouredDate(undefined)
  20610. });
  20611. this._keyDownProcessor = new ui.HierarchicalKeyDownProcessor({element: this._element()})
  20612. }
  20613. this._keyDownProcessor.reinitialize(this._keyDownHandler, this)
  20614. },
  20615. _keyDownHandler: function(options) {
  20616. var monthDifference;
  20617. switch (options.key) {
  20618. case"leftArrow":
  20619. if (options.ctrl)
  20620. monthDifference = this.option("rtlEnabled") ? 1 : -1;
  20621. break;
  20622. case"rightArrow":
  20623. if (options.ctrl)
  20624. monthDifference = this.option("rtlEnabled") ? -1 : 1;
  20625. break;
  20626. case"pageUp":
  20627. monthDifference = -1;
  20628. break;
  20629. case"pageDown":
  20630. monthDifference = 1;
  20631. break;
  20632. default:
  20633. break
  20634. }
  20635. if (monthDifference) {
  20636. options.originalEvent.stopPropagation();
  20637. options.originalEvent.preventDefault();
  20638. this._navigate(monthDifference)
  20639. }
  20640. else
  20641. return true
  20642. },
  20643. _handleSwipeStart: function(e) {
  20644. this._swipeInProgress = true
  20645. },
  20646. _handleSwipeEnd: function(e) {
  20647. if (this._swipeInProgress) {
  20648. this._swipeInProgress = false;
  20649. if (e.jQueryEvent.targetOffset !== 0)
  20650. this._navigate(this.option("rtlEnabled") ? e.jQueryEvent.targetOffset : -e.jQueryEvent.targetOffset)
  20651. }
  20652. },
  20653. _initializeMonthView: function(keyDownProcessor) {
  20654. var monthViewType = this.option("monthViewType");
  20655. return new monthViewType({
  20656. date: this.option("currentDate"),
  20657. min: this.option("min"),
  20658. max: this.option("max"),
  20659. firstDayOfWeek: this.option("firstDayOfWeek"),
  20660. value: this.option("value"),
  20661. rtl: this.option("rtlEnabled"),
  20662. disabled: this.option("disabled") || DevExpress.designMode,
  20663. keyDownProcessor: keyDownProcessor,
  20664. contouredDate: this._oldView ? this._oldView.contouredDate : undefined,
  20665. keyboardNavigationUsed: this._oldView ? this._oldView.keyboardNavigationUsed : undefined
  20666. })
  20667. },
  20668. _renderNavigator: function() {
  20669. var that = this,
  20670. previousYearLinkDelta = this.option("rtlEnabled") ? 12 : -12,
  20671. previousMonthLinkDelta = this.option("rtlEnabled") ? 1 : -1,
  20672. nextMonthLinkDelta = this.option("rtlEnabled") ? -1 : 1,
  20673. nextYearLinkDelta = this.option("rtlEnabled") ? -12 : 12;
  20674. if (this._navigator)
  20675. this._navigatorCaption.html(this._view.getNavigatorCaption());
  20676. else {
  20677. this._previousYearLink = $("<a href='javascript:void(0)'></a>").addClass(CALENDAR_NAVIGATOR_PREVIOUS_YEAR_CLASS);
  20678. this._previousMonthLink = $("<a href='javascript:void(0)'></a>").addClass(CALENDAR_NAVIGATOR_PREVIOUS_MONTH_CLASS);
  20679. this._navigatorCaption = $("<span />").html(this._view.getNavigatorCaption()),
  20680. this._nextMonthLink = $("<a href='javascript:void(0)'></a>").addClass(CALENDAR_NAVIGATOR_NEXT_MONTH_CLASS);
  20681. this._nextYearLink = $("<a href='javascript:void(0)'></a>").addClass(CALENDAR_NAVIGATOR_NEXT_YEAR_CLASS);
  20682. if (!(this.option("disabled") || DevExpress.designMode)) {
  20683. this._previousYearLink.off(CALENDAR_DXCLICK_EVENT_NAME).on(CALENDAR_DXCLICK_EVENT_NAME, function() {
  20684. that._navigate(previousYearLinkDelta)
  20685. });
  20686. this._previousMonthLink.off(CALENDAR_DXCLICK_EVENT_NAME).on(CALENDAR_DXCLICK_EVENT_NAME, function() {
  20687. that._navigate(previousMonthLinkDelta)
  20688. });
  20689. this._nextMonthLink.off(CALENDAR_DXCLICK_EVENT_NAME).on(CALENDAR_DXCLICK_EVENT_NAME, function() {
  20690. that._navigate(nextMonthLinkDelta)
  20691. });
  20692. this._nextYearLink.off(CALENDAR_DXCLICK_EVENT_NAME).on(CALENDAR_DXCLICK_EVENT_NAME, function() {
  20693. that._navigate(nextYearLinkDelta)
  20694. })
  20695. }
  20696. this._navigator = $("<div />").addClass(CALENDAR_NAVIGATOR_CLASS).append(this._previousYearLink).append(this._previousMonthLink).append(this._navigatorCaption).append(this._nextMonthLink).append(this._nextYearLink);
  20697. this._element().append(this._navigator)
  20698. }
  20699. this._applyNavigatorLinkVisibility(this._previousYearLink, previousYearLinkDelta);
  20700. this._applyNavigatorLinkVisibility(this._previousMonthLink, previousMonthLinkDelta);
  20701. this._applyNavigatorLinkVisibility(this._nextMonthLink, nextMonthLinkDelta);
  20702. this._applyNavigatorLinkVisibility(this._nextYearLink, nextYearLinkDelta)
  20703. },
  20704. _applyNavigatorLinkVisibility: function(link, monthDifference) {
  20705. if (this._canNavigate(monthDifference))
  20706. link.removeClass(CALENDAR_DISABLED_NAVIGATOR_LINK_CLASS);
  20707. else
  20708. link.addClass(CALENDAR_DISABLED_NAVIGATOR_LINK_CLASS)
  20709. },
  20710. _renderMonthView: function() {
  20711. var that = this,
  20712. transitions;
  20713. this._view.render(this._body[0]);
  20714. this._element().off(CALENDAR_MONTHVIEW_VALUECHANGED_EVENT_NAME).on(CALENDAR_MONTHVIEW_VALUECHANGED_EVENT_NAME, function(event, newValue) {
  20715. that.option("value", newValue)
  20716. });
  20717. this._element().off(CALENDAR_MONTHVIEW_CONTOUREDDATECHANGED_EVENT_NAME).on(CALENDAR_MONTHVIEW_CONTOUREDDATECHANGED_EVENT_NAME, function(event, date) {
  20718. if (date)
  20719. if (!utils.sameMonthAndYear(that.option("currentDate"), date))
  20720. that.option("currentDate", utils.getFirstMonthDate(date))
  20721. });
  20722. if (this._oldView) {
  20723. this._initalizeViewDimensions();
  20724. this.animating = true;
  20725. transitions = this._getViewChangeAnimation(this._oldView, this._view, this._viewWidth, this.option("rtlEnabled"));
  20726. transitions.oldView.then(transitions.newView).then($.proxy(this._stopAnimationCallback, this))
  20727. }
  20728. },
  20729. _initalizeViewDimensions: function() {
  20730. this._viewWidth = this._viewWidth || this._body.width();
  20731. this._viewHeight = this._viewHeight || this._body.height()
  20732. },
  20733. _canNavigate: function(monthDifference) {
  20734. var date = this.option("currentDate"),
  20735. testCurrentDate = monthDifference < 0 ? new Date(date.getFullYear(), date.getMonth() + monthDifference + 1, 0) : new Date(date.getFullYear(), date.getMonth() + monthDifference, 1);
  20736. return utils.dateInRange(testCurrentDate, this.option("min"), this.option("max"))
  20737. },
  20738. _navigate: function(monthDifference) {
  20739. if (this._canNavigate(monthDifference))
  20740. this.option("currentDate", new Date(this.option("currentDate").getFullYear(), this.option("currentDate").getMonth() + monthDifference, 1))
  20741. },
  20742. _stopAnimationCallback: function() {
  20743. this._forceStopAnimation();
  20744. this._oldView.dispose();
  20745. this._oldView = undefined
  20746. },
  20747. _forceStopAnimation: function() {
  20748. if (this.animating) {
  20749. fx.stop($(this._oldView.table), true);
  20750. fx.stop($(this._view.table), true);
  20751. this.animating = false
  20752. }
  20753. },
  20754. _getViewChangeAnimation: function(oldView, newView, width, rtl) {
  20755. var transitionProperties = this._getViewChangeAnimationProperties(oldView, newView, width, rtl);
  20756. return {
  20757. oldView: fx.animate($(oldView.table), transitionProperties.oldViewAnimation),
  20758. newView: fx.animate($(newView.table), transitionProperties.newViewAnimation)
  20759. }
  20760. },
  20761. _getViewChangeAnimationProperties: function(oldView, newView, width, rtl) {
  20762. var type = "slide",
  20763. duration = oldView.date === newView.date ? 0 : 300,
  20764. easing = "cubic-bezier(.40, .80, .60, 1)",
  20765. oldViewAnimation = {
  20766. type: type,
  20767. duration: duration,
  20768. easing: support.transition ? easing : undefined
  20769. },
  20770. newViewAnimation = {
  20771. type: type,
  20772. duration: duration,
  20773. easing: support.transition ? easing : undefined
  20774. };
  20775. if (newView.date > oldView.date && !rtl || newView.date < oldView.date && rtl) {
  20776. oldViewAnimation.from = {left: 0};
  20777. oldViewAnimation.to = {left: -width};
  20778. newViewAnimation.from = {left: width};
  20779. newViewAnimation.to = {left: 0}
  20780. }
  20781. else {
  20782. oldViewAnimation.from = {left: 0};
  20783. oldViewAnimation.to = {left: width};
  20784. newViewAnimation.from = {left: -width};
  20785. newViewAnimation.to = {left: 0}
  20786. }
  20787. return {
  20788. oldViewAnimation: oldViewAnimation,
  20789. newViewAnimation: newViewAnimation
  20790. }
  20791. },
  20792. _invalidate: function() {
  20793. this._forceStopAnimation();
  20794. this.callBase()
  20795. },
  20796. _optionChanged: function(name, value, previousValue) {
  20797. var normalizedDate;
  20798. switch (name) {
  20799. case"monthViewType":
  20800. case"keyDownProcessor":
  20801. break;
  20802. case"currentDate":
  20803. this._forceStopAnimation();
  20804. normalizedDate = utils.normalizeDate(value, this.option("min"), this.option("max"));
  20805. this.option("currentDate", new Date(normalizedDate.getFullYear(), normalizedDate.getMonth(), 1));
  20806. case"min":
  20807. case"max":
  20808. case"firstDayOfWeek":
  20809. case"rtlEnabled":
  20810. this._invalidate();
  20811. break;
  20812. case"value":
  20813. if (!value || utils.sameMonthAndYear(this._view.date, value)) {
  20814. normalizedDate = utils.normalizeDate(value, this.option("min"), this.option("max"));
  20815. this._view.setValue(normalizedDate);
  20816. this.option("value", normalizedDate)
  20817. }
  20818. else
  20819. this.option("currentDate", utils.getFirstMonthDate(value));
  20820. default:
  20821. this.callBase.apply(this, arguments)
  20822. }
  20823. }
  20824. }));
  20825. ui.dxCalendar.__internals = {
  20826. BaseView: BaseView,
  20827. views: views,
  20828. CALENDAR_CLASS: CALENDAR_CLASS,
  20829. CALENDAR_BODY_CLASS: CALENDAR_BODY_CLASS,
  20830. CALENDAR_NAVIGATOR_CLASS: CALENDAR_NAVIGATOR_CLASS,
  20831. CALENDAR_OTHER_MONTH_CLASS: CALENDAR_OTHER_MONTH_CLASS,
  20832. CALENDAR_DISABLED_NAVIGATOR_LINK_CLASS: CALENDAR_DISABLED_NAVIGATOR_LINK_CLASS,
  20833. CALENDAR_EMPTY_CELL_CLASS: CALENDAR_EMPTY_CELL_CLASS,
  20834. CALENDAR_TODAY_CLASS: CALENDAR_TODAY_CLASS,
  20835. CALENDAR_SELECTED_DATE_CLASS: CALENDAR_SELECTED_DATE_CLASS,
  20836. CALENDAR_CONTOURED_DATE_CLASS: CALENDAR_CONTOURED_DATE_CLASS,
  20837. CALENDAR_NAVIGATOR_PREVIOUS_YEAR_CLASS: CALENDAR_NAVIGATOR_PREVIOUS_YEAR_CLASS,
  20838. CALENDAR_NAVIGATOR_PREVIOUS_MONTH_CLASS: CALENDAR_NAVIGATOR_PREVIOUS_MONTH_CLASS,
  20839. CALENDAR_NAVIGATOR_NEXT_MONTH_CLASS: CALENDAR_NAVIGATOR_NEXT_MONTH_CLASS,
  20840. CALENDAR_NAVIGATOR_NEXT_YEAR_CLASS: CALENDAR_NAVIGATOR_NEXT_YEAR_CLASS,
  20841. CALENDAR_MONTHVIEW_VALUECHANGED_EVENT_NAME: CALENDAR_MONTHVIEW_VALUECHANGED_EVENT_NAME,
  20842. CALENDAR_MONTHVIEW_CONTOUREDDATECHANGED_EVENT_NAME: CALENDAR_MONTHVIEW_CONTOUREDDATECHANGED_EVENT_NAME
  20843. }
  20844. })(jQuery, DevExpress);
  20845. /*! Module widgets-base, file ui.calendarPicker.js */
  20846. (function($, DX, undefined) {
  20847. var ui = DX.ui,
  20848. utils = DX.utils,
  20849. events = ui.events,
  20850. CALENDAR_PICKER_CLASS = "dx-calendar-picker",
  20851. CALENDAR_PICKER_CALENDAR_CONTAINER_CLASS = CALENDAR_PICKER_CLASS + "-calendar-container",
  20852. CALENDAR_PICKER_OVERLAY = CALENDAR_PICKER_CLASS + "-overlay",
  20853. CALENDAR_PICKER_INPUT_WRAPPER_CLASS = CALENDAR_PICKER_CLASS + "-input-wrapper",
  20854. CALENDAR_PICKER_INPUT_WIDER_THAN_CALENDAR_CONTAINER_CLASS = CALENDAR_PICKER_CLASS + "-input-wider-than-calendar-container",
  20855. CALENDAR_PICKER_POSITION_CLASS_PREFIX = CALENDAR_PICKER_CLASS + "-",
  20856. CALENDAR_PICKER_DXPOINTERUP_EVENT_NAME = events.addNamespace("dxpointerup", "dxCalendarPicker"),
  20857. getLongestCaptionIndex = function(captionArray) {
  20858. var longestIndex = 0,
  20859. longestCaptionLength = 0,
  20860. i;
  20861. for (i = 0; i < captionArray.length; ++i)
  20862. if (captionArray[i].length > longestCaptionLength) {
  20863. longestIndex = i;
  20864. longestCaptionLength = captionArray[i].length
  20865. }
  20866. return longestIndex
  20867. },
  20868. expandPattern = function(pattern) {
  20869. return pattern.length === 1 ? Globalize.culture().calendar.patterns[pattern] : pattern
  20870. },
  20871. formatUsesMonthName = function(format) {
  20872. return expandPattern(format).indexOf("MMMM") !== -1
  20873. },
  20874. formatUsesDayName = function(format) {
  20875. return expandPattern(format).indexOf("dddd") !== -1
  20876. },
  20877. getLongestDate = function(format, monthNames, dayNames) {
  20878. var longestDate = new Date(1888, formatUsesMonthName(format) ? getLongestCaptionIndex(monthNames) : 9, 28 - 7, 23, 59, 59, 999);
  20879. if (formatUsesDayName(format))
  20880. longestDate.setDate(longestDate.getDate() - longestDate.getDay() + getLongestCaptionIndex(dayNames));
  20881. return longestDate
  20882. };
  20883. ui.calculateMaximumDateFormatWidth = function(format, customFontStyles, rootElement) {
  20884. if (!rootElement || $(rootElement).is(":visible")) {
  20885. var width,
  20886. ieRoundingError = 2,
  20887. longestTextDiv = $("<div>" + Globalize.format(getLongestDate(format, Globalize.culture().calendar.months.names, Globalize.culture().calendar.days.names), format) + "</div>").css({
  20888. visibility: "hidden",
  20889. "white-space": "nowrap",
  20890. position: "absolute",
  20891. float: "left"
  20892. });
  20893. if (customFontStyles)
  20894. longestTextDiv.css(customFontStyles);
  20895. longestTextDiv.appendTo(rootElement ? $(rootElement) : $("body"));
  20896. width = longestTextDiv.width() + ieRoundingError;
  20897. longestTextDiv.remove();
  20898. return width
  20899. }
  20900. };
  20901. ui.dxCalendarPicker = ui.dxDropDownEditor.inherit({
  20902. NAME: "dxDateBox",
  20903. _setDefaultOptions: function() {
  20904. this.callBase();
  20905. this.option({
  20906. valueChangeEvent: "keyup keydown keypress",
  20907. formatString: Globalize.culture().calendar.patterns["d"],
  20908. formatWidthCalculator: ui.calculateMaximumDateFormatWidth,
  20909. closeOnValueChange: true
  20910. })
  20911. },
  20912. _formatWidthCalculator: function() {
  20913. var $bearingElement = this._element().find(".dx-texteditor-input"),
  20914. buttonWidth = this._button.outerWidth(),
  20915. bearingElementPaddings = $bearingElement.innerWidth() - $bearingElement.width(),
  20916. formatCalculator = this.option("formatWidthCalculator"),
  20917. width;
  20918. if (formatCalculator)
  20919. width = bearingElementPaddings + buttonWidth + formatCalculator(this.option("formatString"), {
  20920. "font-style": $bearingElement.css("font-style"),
  20921. "font-variant": $bearingElement.css("font-variant"),
  20922. "font-weight": $bearingElement.css("font-weight"),
  20923. "font-size": $bearingElement.css("font-size"),
  20924. "font-family": $bearingElement.css("font-family"),
  20925. "letter-spacing": $bearingElement.css("letter-spacing")
  20926. }, this._element());
  20927. return width
  20928. },
  20929. _clean: function() {
  20930. if (this._keyDownProcessor)
  20931. this._keyDownProcessor.dispose();
  20932. if (this._calendarKeyDownProcessor)
  20933. this._calendarKeyDownProcessor.dispose();
  20934. if (this._calendarContainer)
  20935. this._calendarContainer.remove();
  20936. this.callBase()
  20937. },
  20938. _render: function() {
  20939. this.callBase();
  20940. this._element().addClass(CALENDAR_PICKER_CLASS);
  20941. this._keyDownProcessor = new ui.HierarchicalKeyDownProcessor({
  20942. element: this._input(),
  20943. handler: this._keyDownHandler,
  20944. context: this
  20945. });
  20946. this._calendarKeyDownProcessor = this._keyDownProcessor.attachChildProcessor()
  20947. },
  20948. _calculateWidth: function(rawValue) {
  20949. return this.callBase() || this._formatWidthCalculator()
  20950. },
  20951. _keyDownHandler: function(options) {
  20952. switch (options.key) {
  20953. case"escape":
  20954. options.originalEvent.preventDefault();
  20955. this._blur();
  20956. return;
  20957. default:
  20958. if (this._calendarContainer && $(this._calendarContainer).is(":visible"))
  20959. return true;
  20960. return
  20961. }
  20962. },
  20963. _applyDropDownDirectionClasses: function(directions, calendarInnerWidth) {
  20964. if (this._element().width() > calendarInnerWidth)
  20965. this._dropDown._wrapper().addClass(CALENDAR_PICKER_INPUT_WIDER_THAN_CALENDAR_CONTAINER_CLASS);
  20966. else
  20967. this._dropDown._wrapper().removeClass(CALENDAR_PICKER_INPUT_WIDER_THAN_CALENDAR_CONTAINER_CLASS);
  20968. this._cleanDirections(this._dropDown._wrapper()).addClass(directions.horizontalClass + " " + directions.verticalClass)
  20969. },
  20970. _cleanDirections: function(element) {
  20971. return element.removeClass(CALENDAR_PICKER_POSITION_CLASS_PREFIX + "left " + CALENDAR_PICKER_POSITION_CLASS_PREFIX + "right " + CALENDAR_PICKER_POSITION_CLASS_PREFIX + "top " + CALENDAR_PICKER_POSITION_CLASS_PREFIX + "bottom")
  20972. },
  20973. _createDropDown: function() {
  20974. var that = this,
  20975. horizontalAlign = this.option("rtlEnabled") ? "right" : "left",
  20976. verticalAlign = "bottom";
  20977. this.callBase({
  20978. position: {
  20979. my: horizontalAlign + " " + DX.inverseAlign(verticalAlign),
  20980. at: horizontalAlign + " " + verticalAlign
  20981. },
  20982. positioningAction: function(options) {
  20983. if (that._calendarContainer)
  20984. that._applyDropDownDirectionClasses({
  20985. horizontalClass: CALENDAR_PICKER_POSITION_CLASS_PREFIX + (options.position.h.flip ? horizontalAlign : DX.inverseAlign(horizontalAlign)),
  20986. verticalClass: CALENDAR_PICKER_POSITION_CLASS_PREFIX + (options.position.v.flip ? DX.inverseAlign(verticalAlign) : verticalAlign)
  20987. }, that._calendarContainer.innerWidth())
  20988. }
  20989. })
  20990. },
  20991. _closeOutsideDropDownHandler: function(e, ignoreContainerClicks) {
  20992. this.callBase(e, true)
  20993. },
  20994. _renderDropDownContent: function() {
  20995. var that = this;
  20996. this._calendarContainer = $("<div />").addClass(CALENDAR_PICKER_CALENDAR_CONTAINER_CLASS);
  20997. this._calendar = this._calendarContainer.dxCalendar($.extend(this.option("calendarOptions"), {
  20998. value: this.option("value"),
  20999. rtlEnabled: this.option("rtlEnabled"),
  21000. keyDownProcessor: this._calendarKeyDownProcessor,
  21001. min: this.option("min"),
  21002. max: this.option("max")
  21003. })).dxCalendar("instance");
  21004. this._calendarContainer.on(CALENDAR_PICKER_DXPOINTERUP_EVENT_NAME, function(e) {
  21005. that._calendarContainerPointerUpHandler(e)
  21006. });
  21007. return [this._calendarContainer]
  21008. },
  21009. _showDropDown: function() {
  21010. if (!this._dropDownVisible()) {
  21011. var containerRendered = this._dropDownContainerRendered;
  21012. this.callBase();
  21013. if (!containerRendered) {
  21014. this._calendar.optionChanged.add($.proxy(this._calendarOptionChangedCallback, this));
  21015. this._dropDown._wrapper().addClass(CALENDAR_PICKER_OVERLAY)
  21016. }
  21017. }
  21018. },
  21019. _calendarContainerPointerUpHandler: function(e) {
  21020. e.dxPreventBlur = true
  21021. },
  21022. _calendarOptionChangedCallback: function(name, value, previousValue) {
  21023. switch (name) {
  21024. case"value":
  21025. this.option("value", value);
  21026. default:
  21027. break
  21028. }
  21029. },
  21030. _optionValuesEqual: function(name, oldValue, newValue) {
  21031. if (name === "value" && newValue === null)
  21032. return false;
  21033. return this.callBase.apply(this, arguments)
  21034. },
  21035. _renderValue: function(formattedValue) {
  21036. this.callBase(Globalize.format(this.option("value"), this.option("formatString")))
  21037. },
  21038. _handleValueChangeEvent: function(e, formattedValue) {
  21039. this._suppressUpdateValue();
  21040. var date = Globalize.parseDate(this._input().val(), this.option("formatString"));
  21041. this.callBase(e, date);
  21042. this._resumeUpdateValue()
  21043. },
  21044. _blur: function() {
  21045. this._input().blur()
  21046. },
  21047. _visibilityChanged: function(visible) {
  21048. if (visible)
  21049. this._renderDimensions()
  21050. },
  21051. _optionChanged: function(name, value, previousValue) {
  21052. var that = this,
  21053. normalizedDate;
  21054. switch (name) {
  21055. case"min":
  21056. case"max":
  21057. case"formatString":
  21058. case"calendarOptions":
  21059. this._invalidate();
  21060. break;
  21061. case"type":
  21062. case"formatWidthCalculator":
  21063. case"closeOnValueChange":
  21064. break;
  21065. case"value":
  21066. if (value) {
  21067. normalizedDate = utils.normalizeDate(value, this.option("min"), this.option("max"));
  21068. this.option("value", normalizedDate);
  21069. if (this._calendar)
  21070. this._calendar.option("value", value);
  21071. if (this._dropDownVisible() && this.option("closeOnValueChange"))
  21072. setTimeout($.proxy(that._hideDropDown, that), 50)
  21073. }
  21074. default:
  21075. this.callBase.apply(this, arguments)
  21076. }
  21077. }
  21078. });
  21079. DX.registerComponent("dxDateBoxTypeCalendarForDebugTests", ui.dxCalendarPicker.inherit({NAME: "dxDateBoxTypeCalendarForDebugTests"}));
  21080. ui.dxCalendarPicker.__internals = {
  21081. getLongestCaptionIndex: getLongestCaptionIndex,
  21082. getLongestDate: getLongestDate,
  21083. calculateMaximumDateFormatWidth: ui.calculateMaximumDateFormatWidth,
  21084. CALENDAR_PICKER_OVERLAY: CALENDAR_PICKER_OVERLAY,
  21085. CALENDAR_PICKER_INPUT_WIDER_THAN_CALENDAR_CONTAINER_CLASS: CALENDAR_PICKER_INPUT_WIDER_THAN_CALENDAR_CONTAINER_CLASS,
  21086. CALENDAR_PICKER_INPUT_WRAPPER_CLASS: CALENDAR_PICKER_INPUT_WRAPPER_CLASS,
  21087. CALENDAR_PICKER_POSITION_CLASS_PREFIX: CALENDAR_PICKER_POSITION_CLASS_PREFIX
  21088. }
  21089. })(jQuery, DevExpress);
  21090. /*! Module widgets-base, file ui.calendarPickerTimeBox.js */
  21091. (function($, DX, undefined) {
  21092. var ui = DX.ui,
  21093. events = ui.events,
  21094. CALENDAR_PICKER_TIME_BOX_CLASS = "dx-calendar-picker-time-box",
  21095. TEXTEDITOR_INPUT_WRAPPER_CLASS = "dx-texteditor-input-wrapper",
  21096. CALENDAR_PICKER_TIME_BOX_DXCLICK_EVENT_NAME = events.addNamespace("dxclick", "dxCalendarPickerTimeBox");
  21097. DX.registerComponent("dxCalendarPickerTimeBox", ui.dxTextEditor.inherit({
  21098. _processingKeyPress: undefined,
  21099. _setDefaultOptions: function() {
  21100. this.callBase();
  21101. this.option({
  21102. valueChangeEvent: "keyup keydown keypress",
  21103. formatString: Globalize.culture().calendar.patterns["t"],
  21104. formatWidthCalculator: ui.calculateMaximumDateFormatWidth
  21105. })
  21106. },
  21107. _formatWidthCalculator: function() {
  21108. var $element = this._element(),
  21109. $bearingElement = $element.find(".dx-texteditor-input"),
  21110. paddingWidth = $element.innerWidth() - $element.width(),
  21111. formatWidthCalculator = this.option("formatWidthCalculator"),
  21112. width;
  21113. if (formatWidthCalculator)
  21114. width = paddingWidth + formatWidthCalculator(this.option("formatString"), {
  21115. "font-style": $bearingElement.css("font-style"),
  21116. "font-variant": $bearingElement.css("font-variant"),
  21117. "font-weight": $bearingElement.css("font-weight"),
  21118. "font-size": $bearingElement.css("font-size"),
  21119. "font-family": $bearingElement.css("font-family"),
  21120. "letter-spacing": $bearingElement.css("letter-spacing")
  21121. });
  21122. return width
  21123. },
  21124. _render: function() {
  21125. var that = this,
  21126. $element = this._element();
  21127. $element.addClass(CALENDAR_PICKER_TIME_BOX_CLASS);
  21128. this.callBase();
  21129. $element.off(CALENDAR_PICKER_TIME_BOX_DXCLICK_EVENT_NAME).on(CALENDAR_PICKER_TIME_BOX_DXCLICK_EVENT_NAME, function() {
  21130. that.focus()
  21131. });
  21132. this._repositionIcon($element.width())
  21133. },
  21134. _calculateWidth: function(rawValue) {
  21135. var width = this.callBase();
  21136. if (!width)
  21137. width = this._formatWidthCalculator();
  21138. return width
  21139. },
  21140. _renderValue: function(formattedValue) {
  21141. this.callBase(Globalize.format(this.option("value"), this.option("formatString")))
  21142. },
  21143. _renderInput: function() {
  21144. this.callBase();
  21145. this._element().addClass(TEXTEDITOR_INPUT_WRAPPER_CLASS)
  21146. },
  21147. _repositionIcon: function(inputWidth) {
  21148. if (this.option("rtlEnabled"))
  21149. return;
  21150. var ie8 = DX.browser.msie && DX.browser.version < 9,
  21151. backgroundPosition = ie8 ? [this._element().css("backgroundPositionX"), this._element().css("backgroundPositionY")] : this._element().css("background-position").split(" ");
  21152. this._iconWidth = this._iconWidth || parseInt(backgroundPosition[0], 10);
  21153. if (ie8) {
  21154. this._element().css("backgroundPositionX", inputWidth + this._iconWidth + "px");
  21155. this._element().css("backgroundPositionY", backgroundPosition[1])
  21156. }
  21157. else
  21158. this._element().css("background-position", inputWidth + this._iconWidth + "px " + backgroundPosition[1])
  21159. },
  21160. _handleValueChangeEvent: function(e, formattedValue) {
  21161. this._suppressUpdateValue();
  21162. var time = Globalize.parseDate(this._input().val(), this.option("formatString"));
  21163. this.callBase(e, time);
  21164. this._resumeUpdateValue()
  21165. },
  21166. _optionChanged: function(name, value, previousValue) {
  21167. switch (name) {
  21168. case"formatWidthCalculator":
  21169. break;
  21170. case"formatString":
  21171. this._invalidate();
  21172. break;
  21173. case"width":
  21174. this.callBase.apply(this, arguments);
  21175. this._repositionIcon(this._element().width());
  21176. break;
  21177. default:
  21178. this.callBase.apply(this, arguments)
  21179. }
  21180. }
  21181. }));
  21182. ui.dxCalendarPickerTimeBox.__internals = {TEXTEDITOR_INPUT_WRAPPER_CLASS: TEXTEDITOR_INPUT_WRAPPER_CLASS}
  21183. })(jQuery, DevExpress);
  21184. /*! Module widgets-base, file ui.dateBox.js */
  21185. (function($, DX, undefined) {
  21186. var ui = DX.ui,
  21187. events = ui.events,
  21188. support = DX.support,
  21189. devices = DX.devices,
  21190. globalize = Globalize;
  21191. var DATEBOX_CLASS = "dx-datebox",
  21192. DATEPICKER_CLASS = "dx-datepicker",
  21193. DATEPICKER_WRAPPER_CLASS = "dx-datepicker-wrapper",
  21194. DATEPICKER_ROLLER_CONTAINER_CLASS = "dx-datepicker-rollers",
  21195. DATEPICKER_ROLLER_CLASS = "dx-datepicker-roller",
  21196. DATEPICKER_ROLLER_ACTIVE_CLASS = "dx-state-active",
  21197. DATEPICKER_ROLLER_CURRENT_CLASS = "dx-datepicker-roller-current",
  21198. DATEPICKER_ROLLER_ITEM_CLASS = "dx-datepicker-item",
  21199. DATEPICKER_ROLLER_ITEM_SELECTED_CLASS = "dx-datepicker-item-selected",
  21200. DATEPICKER_ROLLER_ITEM_SELECTED_FRAME_CLASS = "dx-datepicker-item-selected-frame",
  21201. DATEPICKER_ROLLER_ITEM_SELECTED_BORDER_CLASS = "dx-datepicker-item-selected-border",
  21202. DATEPICKER_ROLLER_BUTTON_UP_CLASS = "dx-datepicker-button-up",
  21203. DATEPICKER_ROLLER_BUTTON_DOWN_CLASS = "dx-datepicker-button-down",
  21204. DATEPICKER_FORMATTER_CONTAINER = "dx-datepicker-formatter-container",
  21205. DATEPICKER_VALUE_FORMATTER = "dx-datepicker-value-formatter",
  21206. DATEPICKER_NAME_FORMATTER = "dx-datepicker-name-formatter",
  21207. SUPPORTED_FORMATS = ["date", "time", "datetime"],
  21208. DEFAULT_FORMATTER = function(value) {
  21209. return value
  21210. },
  21211. DATE_COMPONENT_TEXT_FORMATTER = function(value, name) {
  21212. var $container = $("<div>").addClass(DATEPICKER_FORMATTER_CONTAINER);
  21213. $("<span>").text(value).addClass(DATEPICKER_VALUE_FORMATTER).appendTo($container);
  21214. $("<span>").text(name).addClass(DATEPICKER_NAME_FORMATTER).appendTo($container);
  21215. return $container
  21216. },
  21217. YEAR = "year",
  21218. MONTH = "month",
  21219. DAY = "day",
  21220. HOURS = "hours",
  21221. MINUTES = "minutes",
  21222. SECONDS = "seconds",
  21223. MILLISECONDS = "milliseconds",
  21224. TEN_YEARS = 1000 * 60 * 60 * 24 * 365 * 10;
  21225. var DATE_COMPONENTS_INFO = {};
  21226. DATE_COMPONENTS_INFO[YEAR] = {
  21227. getter: "getFullYear",
  21228. setter: "setFullYear",
  21229. possibleFormats: ["yy", "yyyy"],
  21230. formatter: DEFAULT_FORMATTER,
  21231. startValue: undefined,
  21232. endValue: undefined
  21233. };
  21234. DATE_COMPONENTS_INFO[DAY] = {
  21235. getter: "getDate",
  21236. setter: "setDate",
  21237. possibleFormats: ["d", "dd"],
  21238. formatter: function(value, showNames, date) {
  21239. if (!showNames)
  21240. return value;
  21241. var formatDate = new Date(date.getTime());
  21242. formatDate.setDate(value);
  21243. return DATE_COMPONENT_TEXT_FORMATTER(value, globalize.culture().calendar.days.names[formatDate.getDay()])
  21244. },
  21245. startValue: 1,
  21246. endValue: undefined
  21247. };
  21248. DATE_COMPONENTS_INFO[MONTH] = {
  21249. getter: "getMonth",
  21250. setter: "setMonth",
  21251. possibleFormats: ["M", "MM", "MMM", "MMMM"],
  21252. formatter: function(value, showNames) {
  21253. var monthName = globalize.culture().calendar.months.names[value];
  21254. return showNames ? DATE_COMPONENT_TEXT_FORMATTER(value + 1, monthName) : monthName
  21255. },
  21256. startValue: 0,
  21257. endValue: 11
  21258. };
  21259. DATE_COMPONENTS_INFO[HOURS] = {
  21260. getter: "getHours",
  21261. setter: "setHours",
  21262. possibleFormats: ["H", "HH", "h", "hh"],
  21263. formatter: function(value) {
  21264. return globalize.format(new Date(0, 0, 0, value), "HH")
  21265. },
  21266. startValue: 0,
  21267. endValue: 23
  21268. };
  21269. DATE_COMPONENTS_INFO[MINUTES] = {
  21270. getter: "getMinutes",
  21271. setter: "setMinutes",
  21272. possibleFormats: ["m", "mm"],
  21273. formatter: function(value) {
  21274. return globalize.format(new Date(0, 0, 0, 0, value), "mm")
  21275. },
  21276. startValue: 0,
  21277. endValue: 59
  21278. };
  21279. DATE_COMPONENTS_INFO[SECONDS] = {
  21280. getter: "getSeconds",
  21281. setter: "setSeconds",
  21282. possibleFormats: ["s", "ss"],
  21283. formatter: function(value) {
  21284. return globalize.format(new Date(0, 0, 0, 0, 0, value), "ss")
  21285. },
  21286. startValue: 0,
  21287. endValue: 59
  21288. };
  21289. DATE_COMPONENTS_INFO[MILLISECONDS] = {
  21290. getter: "getMilliseconds",
  21291. setter: "setMilliseconds",
  21292. possibleFormats: ["f", "ff", "fff"],
  21293. formatter: function(value) {
  21294. return globalize.format(new Date(0, 0, 0, 0, 0, 0, value), "fff")
  21295. },
  21296. startValue: 0,
  21297. endValue: 999
  21298. };
  21299. var dateCopmotents = function() {
  21300. return [YEAR, DAY, MONTH, DAY]
  21301. };
  21302. var FORMATS_INFO = {
  21303. date: {
  21304. standardPattern: "yyyy-MM-dd",
  21305. components: dateCopmotents()
  21306. },
  21307. time: {
  21308. standardPattern: "HH:mm",
  21309. components: [HOURS, MINUTES]
  21310. },
  21311. datetime: {
  21312. standardPattern: "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'",
  21313. components: dateCopmotents().concat([HOURS, MINUTES, SECONDS, MILLISECONDS])
  21314. },
  21315. "datetime-local": {
  21316. standardPattern: "yyyy'-'MM'-'dd'T'HH':'mm",
  21317. components: dateCopmotents().concat([HOURS, MINUTES, SECONDS])
  21318. }
  21319. },
  21320. FORMATS_MAP = {
  21321. date: "d",
  21322. time: "t",
  21323. datetime: "S",
  21324. "datetime-local": "f"
  21325. };
  21326. var toStandardDateFormat = function(date, mode, pattern) {
  21327. pattern = pattern || FORMATS_INFO[mode].standardPattern;
  21328. var datePattern = FORMATS_INFO[mode].standardPattern;
  21329. return Globalize.format(date, pattern)
  21330. };
  21331. (function androidFormatDetection() {
  21332. var androidFormatPattern = "yyyy'-'MM'-'dd'T'HH':'mm'Z'";
  21333. var $input = $("<input>").attr("type", "datetime");
  21334. $input.val(toStandardDateFormat(new Date, "datetime", androidFormatPattern));
  21335. if (!$input.val())
  21336. FORMATS_INFO.datetime.standardPattern = androidFormatPattern
  21337. })();
  21338. var fromStandardDateFormat = function(date) {
  21339. return Globalize.parseDate(date, FORMATS_INFO["datetime"].standardPattern) || Globalize.parseDate(date, FORMATS_INFO["datetime-local"].standardPattern) || Globalize.parseDate(date, FORMATS_INFO["time"].standardPattern) || Globalize.parseDate(date, FORMATS_INFO["date"].standardPattern) || Date.parse && Date.parse(date) && new Date(Date.parse(date))
  21340. };
  21341. var getMaxMonthDay = function(year, month) {
  21342. return new Date(year, month + 1, 0).getDate()
  21343. };
  21344. var mergeDates = function(target, source, format) {
  21345. if (!source)
  21346. return undefined;
  21347. if (isNaN(target.getTime()))
  21348. target = new Date(0, 0, 0, 0, 0, 0);
  21349. var formatInfo = FORMATS_INFO[format];
  21350. $.each(formatInfo.components, function() {
  21351. var componentInfo = DATE_COMPONENTS_INFO[this];
  21352. target[componentInfo.setter](source[componentInfo.getter]())
  21353. });
  21354. return target
  21355. };
  21356. DX.registerComponent("dxDatePickerRoller", ui.dxScrollable.inherit({
  21357. _setDefaultOptions: function() {
  21358. this.callBase();
  21359. this.option({
  21360. clickableItems: false,
  21361. showScrollbar: false,
  21362. useNative: false,
  21363. selectedIndex: 0,
  21364. items: []
  21365. })
  21366. },
  21367. _defaultOptionsRules: function() {
  21368. return this.callBase().slice(0).concat([{
  21369. device: {platform: "win8"},
  21370. options: {clickableItems: true}
  21371. }, {
  21372. device: {platform: "generic"},
  21373. options: {scrollByContent: true}
  21374. }])
  21375. },
  21376. _init: function() {
  21377. this.callBase();
  21378. this._renderSelectedItemFrame();
  21379. this._renderControlButtons()
  21380. },
  21381. _render: function() {
  21382. this.callBase();
  21383. $.each(this._strategy._scrollers, function(index, scroller) {
  21384. scroller._correctLocation = $.noop
  21385. });
  21386. this._element().addClass(DATEPICKER_ROLLER_CLASS);
  21387. this._renderItems();
  21388. this._renderSelectedValue();
  21389. this._renderItemsClick();
  21390. this._wrapAction("_endAction", $.proxy(this._handleEndAction, this))
  21391. },
  21392. _wrapAction: function(actionName, callback) {
  21393. var strategy = this._strategy,
  21394. originalAction = strategy[actionName];
  21395. strategy[actionName] = function() {
  21396. callback.apply(this, arguments);
  21397. return originalAction.apply(this, arguments)
  21398. }
  21399. },
  21400. _renderItems: function() {
  21401. var items = this.option("items") || [],
  21402. $items = $();
  21403. this._$content.empty();
  21404. $.each(items, function() {
  21405. $items = $items.add($("<div>").addClass(DATEPICKER_ROLLER_ITEM_CLASS).append(this))
  21406. });
  21407. this._$content.append($items);
  21408. this._$items = $items;
  21409. this.update()
  21410. },
  21411. _renderSelectedItemFrame: function() {
  21412. $("<div>").addClass(DATEPICKER_ROLLER_ITEM_SELECTED_FRAME_CLASS).append($("<div>").addClass(DATEPICKER_ROLLER_ITEM_SELECTED_BORDER_CLASS)).appendTo(this._$container)
  21413. },
  21414. _renderControlButtons: function() {
  21415. $("<div>").addClass(DATEPICKER_ROLLER_BUTTON_UP_CLASS).insertAfter(this._$container).dxButton({clickAction: $.proxy(this._handleUpButtonClick, this)});
  21416. $("<div>").addClass(DATEPICKER_ROLLER_BUTTON_DOWN_CLASS).insertAfter(this._$container).dxButton({clickAction: $.proxy(this._handleDownButtonClick, this)})
  21417. },
  21418. _renderSelectedValue: function(selectedIndex) {
  21419. if (selectedIndex === undefined)
  21420. selectedIndex = this.option("selectedIndex");
  21421. selectedIndex = this._fitIndex(selectedIndex);
  21422. var correctedPosition = this._getItemPosition(selectedIndex);
  21423. this.option().selectedIndex = selectedIndex;
  21424. this._moveTo({top: correctedPosition});
  21425. this._renderActiveStateItem()
  21426. },
  21427. _fitIndex: function(index) {
  21428. var items = this.option("items") || [],
  21429. itemCount = items.length;
  21430. if (index >= itemCount)
  21431. return itemCount - 1;
  21432. if (index < 0)
  21433. return 0;
  21434. return index
  21435. },
  21436. _renderItemsClick: function() {
  21437. var itemSelector = "." + DATEPICKER_ROLLER_ITEM_CLASS,
  21438. eventName = events.addNamespace("dxclick", this.NAME);
  21439. this._element().off(eventName, itemSelector);
  21440. if (this.option("clickableItems"))
  21441. this._element().on(eventName, itemSelector, $.proxy(this._handleItemClick, this))
  21442. },
  21443. _handleItemClick: function(e) {
  21444. this._renderSelectedValue(this._itemElementIndex(this._closestItemElement(e)))
  21445. },
  21446. _itemElementIndex: function(itemElement) {
  21447. return this._itemElements().index(itemElement)
  21448. },
  21449. _closestItemElement: function(e) {
  21450. return e.currentTarget
  21451. },
  21452. _itemElements: function() {
  21453. return this._element().find("." + DATEPICKER_ROLLER_ITEM_CLASS)
  21454. },
  21455. _renderActiveStateItem: function() {
  21456. var selectedIndex = this.option("selectedIndex");
  21457. $.each(this._$items, function(index) {
  21458. $(this).toggleClass(DATEPICKER_ROLLER_ITEM_SELECTED_CLASS, selectedIndex === index)
  21459. })
  21460. },
  21461. _handleUpButtonClick: function() {
  21462. this._animation = true;
  21463. this.option("selectedIndex", this.option("selectedIndex") - 1)
  21464. },
  21465. _handleDownButtonClick: function() {
  21466. this._animation = true;
  21467. this.option("selectedIndex", this.option("selectedIndex") + 1)
  21468. },
  21469. _getItemPosition: function(index) {
  21470. return Math.round(this._itemHeight() * index)
  21471. },
  21472. _moveTo: function(targetLocation) {
  21473. targetLocation = this._normalizeLocation(targetLocation);
  21474. var location = this._location(),
  21475. delta = {
  21476. x: -(location.left - targetLocation.left),
  21477. y: -(location.top - targetLocation.top)
  21478. };
  21479. if (this._isVisible() && (delta.x || delta.y)) {
  21480. this._strategy._prepareDirections(true);
  21481. if (this._animation) {
  21482. DX.fx.animate(this._$content, {
  21483. duration: 200,
  21484. type: "slide",
  21485. to: {top: targetLocation.top}
  21486. });
  21487. delete this._animation
  21488. }
  21489. else
  21490. this._strategy.handleMove({delta: delta})
  21491. }
  21492. },
  21493. _handleEndAction: function() {
  21494. if (this._changedByIndex) {
  21495. this._changedByIndex = false;
  21496. this._renderSelectedValue();
  21497. return
  21498. }
  21499. var ratio = -this._location().top / this._itemHeight(),
  21500. selectedIndex = Math.round(ratio);
  21501. this._animation = true;
  21502. this._renderSelectedValue(selectedIndex)
  21503. },
  21504. _itemHeight: function() {
  21505. var $item = this._$items.first(),
  21506. height = $item.outerHeight() + parseFloat($item.css("margin-top") || 0);
  21507. return height
  21508. },
  21509. _toggleActive: function(state) {
  21510. this._element().toggleClass(DATEPICKER_ROLLER_ACTIVE_CLASS, state)
  21511. },
  21512. _isVisible: function() {
  21513. return this._$container.is(":visible")
  21514. },
  21515. _optionChanged: function(name) {
  21516. switch (name) {
  21517. case"selectedIndex":
  21518. this._renderSelectedValue();
  21519. this._changedByIndex = true;
  21520. this._strategy.update();
  21521. this._strategy.handleEnd({velocity: {
  21522. x: 0,
  21523. y: 0
  21524. }});
  21525. break;
  21526. case"items":
  21527. this._renderItems();
  21528. this._renderSelectedValue();
  21529. break;
  21530. case"clickableItems":
  21531. this._renderItemsClick();
  21532. break;
  21533. default:
  21534. this.callBase.apply(this, arguments)
  21535. }
  21536. }
  21537. }));
  21538. DX.registerComponent("dxDatePicker", ui.dxPopup.inherit({
  21539. _valueOption: function() {
  21540. return new Date(this.option("value")) == "Invalid Date" ? new Date : new Date(this.option("value"))
  21541. },
  21542. _setDefaultOptions: function() {
  21543. this.callBase();
  21544. this.option({
  21545. minDate: new Date(1),
  21546. maxDate: new Date($.now() + TEN_YEARS),
  21547. format: "date",
  21548. value: new Date,
  21549. culture: Globalize.culture().name,
  21550. showNames: false,
  21551. cancelButton: {
  21552. icon: "close",
  21553. clickAction: $.proxy(function() {
  21554. this._value = this._valueOption()
  21555. }, this)
  21556. },
  21557. doneButton: {
  21558. icon: "save",
  21559. clickAction: $.proxy(function() {
  21560. this.option("value", new Date(this._value));
  21561. this.hide()
  21562. }, this)
  21563. }
  21564. })
  21565. },
  21566. _defaultOptionsRules: function() {
  21567. return this.callBase().slice(0).concat([{
  21568. device: {platform: "win8"},
  21569. options: {showNames: true}
  21570. }, {
  21571. device: {
  21572. platform: "win8",
  21573. phone: true
  21574. },
  21575. options: {fullScreen: true}
  21576. }, {
  21577. device: function(device) {
  21578. return device.platform !== "win8"
  21579. },
  21580. options: {
  21581. width: 333,
  21582. height: 331
  21583. }
  21584. }, {
  21585. device: function(device) {
  21586. return device.platform === "generic"
  21587. },
  21588. options: {
  21589. width: "auto",
  21590. height: "auto"
  21591. }
  21592. }])
  21593. },
  21594. _render: function() {
  21595. this._value = this._valueOption();
  21596. this.callBase();
  21597. this._element().addClass(DATEPICKER_CLASS);
  21598. this._wrapper().addClass(DATEPICKER_WRAPPER_CLASS)
  21599. },
  21600. _renderContentImpl: function() {
  21601. this.callBase();
  21602. this._renderRollers()
  21603. },
  21604. _renderRollers: function() {
  21605. var that = this;
  21606. if (!that._$rollersContainer)
  21607. that._$rollersContainer = $("<div>").appendTo(that.content()).addClass(DATEPICKER_ROLLER_CONTAINER_CLASS);
  21608. that._$rollersContainer.empty();
  21609. that._createRollerConfigs();
  21610. that._rollers = {};
  21611. $.each(that._rollerConfigs, function(name) {
  21612. var $roller = $("<div>").appendTo(that._$rollersContainer).addClass(DATEPICKER_ROLLER_CLASS + "-" + that._rollerConfigs[name].type).dxDatePickerRoller({
  21613. items: that._rollerConfigs[name].displayItems,
  21614. selectedIndex: that._rollerConfigs[name].selectedIndex,
  21615. showScrollbar: false,
  21616. startAction: function(e) {
  21617. var roller = e.component;
  21618. roller._toggleActive(true);
  21619. that._setActiveRoller(that._rollerConfigs[name], roller.option("selectedIndex"))
  21620. },
  21621. endAction: function(e) {
  21622. var roller = e.component;
  21623. that._setRollerState(that._rollerConfigs[name], roller.option("selectedIndex"));
  21624. roller._toggleActive(false)
  21625. }
  21626. });
  21627. that._rollers[that._rollerConfigs[name].type] = $roller.dxDatePickerRoller("instance")
  21628. })
  21629. },
  21630. _setActiveRoller: function(currentRoller) {
  21631. var activeRoller = currentRoller && this._rollers[currentRoller.type];
  21632. $.each(this._rollers, function() {
  21633. this._$element.toggleClass(DATEPICKER_ROLLER_CURRENT_CLASS, this === activeRoller)
  21634. })
  21635. },
  21636. _refreshRollers: function() {
  21637. var that = this;
  21638. $.each(this._rollers, function(type) {
  21639. var correctIndex = that._rollerConfigs[type].getIndex(that._value);
  21640. this.update();
  21641. this._renderSelectedValue(correctIndex)
  21642. })
  21643. },
  21644. _setRollerState: function(roller, selectedIndex) {
  21645. if (selectedIndex !== roller.selectedIndex) {
  21646. var value = roller.valueItems[selectedIndex],
  21647. setValue = roller.setValue,
  21648. currentDate = this._value.getDate();
  21649. if (roller.type === MONTH) {
  21650. currentDate = Math.min(currentDate, getMaxMonthDay(this._value.getFullYear(), value));
  21651. this._value.setDate(currentDate)
  21652. }
  21653. else if (roller.type === YEAR) {
  21654. currentDate = Math.min(currentDate, getMaxMonthDay(value, this._value.getMonth()));
  21655. this._value.setDate(currentDate)
  21656. }
  21657. this._value[setValue](value);
  21658. roller.selectedIndex = selectedIndex
  21659. }
  21660. if (roller.type === YEAR) {
  21661. this._refreshMonthRoller();
  21662. this._refreshDayRoller()
  21663. }
  21664. if (roller.type === MONTH)
  21665. this._refreshDayRoller()
  21666. },
  21667. _refreshMonthRoller: function() {
  21668. var monthRoller = this._rollers[MONTH];
  21669. if (monthRoller) {
  21670. this._createRollerConfig(MONTH);
  21671. var monthRollerConfig = this._rollerConfigs[MONTH];
  21672. this._deferredRenderMonthTimeout = window.setTimeout(function() {
  21673. if (monthRollerConfig.displayItems.length === monthRoller.option("items").length)
  21674. return;
  21675. monthRoller.option({
  21676. items: monthRollerConfig.displayItems,
  21677. selectedIndex: monthRollerConfig.selectedIndex
  21678. })
  21679. }, 100)
  21680. }
  21681. },
  21682. _refreshDayRoller: function() {
  21683. var dayRoller = this._rollers[DAY];
  21684. if (dayRoller) {
  21685. this._createRollerConfig(DAY);
  21686. var dayRollerConfig = this._rollerConfigs[DAY];
  21687. this._deferredRenderDayTimeout = window.setTimeout(function() {
  21688. if (dayRollerConfig.displayItems.length === dayRoller.option("items").length)
  21689. return;
  21690. dayRoller.option({
  21691. items: dayRollerConfig.displayItems,
  21692. selectedIndex: dayRollerConfig.selectedIndex
  21693. })
  21694. }, 100)
  21695. }
  21696. },
  21697. _createRollerConfigs: function(format) {
  21698. var that = this;
  21699. format = format || that.option("format");
  21700. that._rollerConfigs = {};
  21701. $.each(that._getFormatPattern(format).split(/\W+/), function(_, formatPart) {
  21702. $.each(DATE_COMPONENTS_INFO, function(componentName, componentInfo) {
  21703. if ($.inArray(formatPart, componentInfo.possibleFormats) > -1)
  21704. that._createRollerConfig(componentName)
  21705. })
  21706. })
  21707. },
  21708. _getFormatPattern: function(format) {
  21709. var culture = Globalize.culture(this.option("culture")),
  21710. result = "";
  21711. if (format === "date")
  21712. result = culture.calendar.patterns.d;
  21713. else if (format === "time")
  21714. result = culture.calendar.patterns.t;
  21715. else if (format === "datetime")
  21716. result = [culture.calendar.patterns.d, culture.calendar.patterns.t].join(" ");
  21717. return result
  21718. },
  21719. _createRollerConfig: function(componentName) {
  21720. var componentInfo = DATE_COMPONENTS_INFO[componentName],
  21721. valueRange = this._calculateRollerConfigValueRange(componentName),
  21722. startValue = valueRange.startValue,
  21723. endValue = valueRange.endValue,
  21724. formatter = componentInfo.formatter,
  21725. showNames = this.option("showNames"),
  21726. curDate = this._value;
  21727. var config = {
  21728. type: componentName,
  21729. setValue: componentInfo.setter,
  21730. valueItems: [],
  21731. displayItems: [],
  21732. getIndex: function(value) {
  21733. return value[componentInfo.getter]() - startValue
  21734. }
  21735. };
  21736. for (var i = startValue; i <= endValue; i++) {
  21737. config.valueItems.push(i);
  21738. config.displayItems.push(formatter(i, showNames, curDate))
  21739. }
  21740. config.selectedIndex = config.getIndex(this._value);
  21741. this._rollerConfigs[componentName] = config
  21742. },
  21743. _calculateRollerConfigValueRange: function(componentName) {
  21744. var curDate = this._value,
  21745. minDate = this.option("minDate"),
  21746. maxDate = this.option("maxDate"),
  21747. minYear = curDate.getFullYear() === minDate.getFullYear(),
  21748. minMonth = minYear && curDate.getMonth() === minDate.getMonth(),
  21749. maxYear = curDate.getFullYear() === maxDate.getFullYear(),
  21750. maxMonth = maxYear && curDate.getMonth() === maxDate.getMonth(),
  21751. componentInfo = DATE_COMPONENTS_INFO[componentName],
  21752. startValue = componentInfo.startValue,
  21753. endValue = componentInfo.endValue;
  21754. if (componentName === YEAR) {
  21755. startValue = minDate.getFullYear();
  21756. endValue = maxDate.getFullYear()
  21757. }
  21758. if (componentName === MONTH) {
  21759. if (minYear)
  21760. startValue = minDate.getMonth();
  21761. if (maxYear)
  21762. endValue = maxDate.getMonth()
  21763. }
  21764. if (componentName === DAY) {
  21765. endValue = getMaxMonthDay(curDate.getFullYear(), curDate.getMonth());
  21766. if (minMonth)
  21767. startValue = minDate.getDate();
  21768. if (maxYear)
  21769. endValue = maxDate.getDate()
  21770. }
  21771. return {
  21772. startValue: startValue,
  21773. endValue: endValue
  21774. }
  21775. },
  21776. _optionChanged: function(name, value, prevValue) {
  21777. switch (name) {
  21778. case"showNames":
  21779. case"minDate":
  21780. case"maxDate":
  21781. case"culture":
  21782. case"format":
  21783. this._renderRollers();
  21784. break;
  21785. case"visible":
  21786. this.callBase(name, value, prevValue);
  21787. if (value) {
  21788. this._refreshRollers();
  21789. this._setActiveRoller()
  21790. }
  21791. break;
  21792. case"value":
  21793. this._value = this._valueOption();
  21794. this._renderRollers();
  21795. break;
  21796. default:
  21797. this.callBase(name, value, prevValue)
  21798. }
  21799. },
  21800. _dispose: function() {
  21801. clearTimeout(this._deferredRenderDayTimeout);
  21802. clearTimeout(this._deferredRenderMonthTimeout);
  21803. this.callBase()
  21804. }
  21805. }));
  21806. DX.registerComponent("dxDateBox", ui.dxTextEditor.inherit({
  21807. ctor: function(element, options) {
  21808. options = options || {};
  21809. var preferCalendar = devices.current().platform === "generic" && (options.format === "date" || !options.format),
  21810. useCalendar = options && options.useCalendar;
  21811. if (useCalendar === undefined)
  21812. useCalendar = preferCalendar;
  21813. if (useCalendar)
  21814. new ui.dxCalendarPicker(element, options);
  21815. else
  21816. this.callBase(element, options)
  21817. },
  21818. _setDefaultOptions: function() {
  21819. this.callBase();
  21820. this.option({
  21821. format: "date",
  21822. value: new Date,
  21823. min: new Date(1),
  21824. max: new Date($.now() + TEN_YEARS),
  21825. useCalendar: false,
  21826. useNativePicker: true
  21827. })
  21828. },
  21829. _defaultOptionsRules: function() {
  21830. return this.callBase().slice(0).concat([{
  21831. device: function(device) {
  21832. return device.win8 || device.android && (device.version[0] < 4 || device.version[0] == 4 && device.version[1] < 4)
  21833. },
  21834. options: {useNativePicker: false}
  21835. }])
  21836. },
  21837. _init: function() {
  21838. this.callBase();
  21839. this._initFormat()
  21840. },
  21841. _render: function() {
  21842. this.callBase();
  21843. this._element().addClass(DATEBOX_CLASS);
  21844. this._renderDatePicker()
  21845. },
  21846. _renderDatePicker: function() {
  21847. if (this._usingNativeDatePicker() || this.option("readOnly")) {
  21848. if (this._datePicker) {
  21849. this._datePicker._element().remove();
  21850. this._datePicker = null
  21851. }
  21852. return
  21853. }
  21854. var datePickerOptions = {
  21855. value: this.option("value"),
  21856. format: this.option("format"),
  21857. title: this._getDataPickerTitle(),
  21858. minDate: this.option("min"),
  21859. maxDate: this.option("max")
  21860. };
  21861. if (this._datePicker)
  21862. this._datePicker.option(datePickerOptions);
  21863. else {
  21864. this._datePicker = $("<div>").appendTo(this._element()).dxDatePicker($.extend(datePickerOptions, {hidingAction: $.proxy(function(e) {
  21865. this.option("value", e.component.option("value"))
  21866. }, this)})).dxDatePicker("instance");
  21867. var inputClickAction = this._createAction(function(e) {
  21868. e.component._datePicker.show()
  21869. });
  21870. this._input().on(events.addNamespace("dxclick", this.NAME), function(e) {
  21871. return inputClickAction({jQuery: e})
  21872. })
  21873. }
  21874. },
  21875. _renderFocusEvent: function() {
  21876. this.callBase();
  21877. this._input().on('focus', $.proxy(function() {
  21878. this._togglePlaceholderVisibility(false)
  21879. }, this))
  21880. },
  21881. _initFormat: function() {
  21882. var format = this.option("format");
  21883. if ($.inArray(format, SUPPORTED_FORMATS) === -1) {
  21884. format = "date";
  21885. this.option("format", format)
  21886. }
  21887. else if (format === "datetime" && !support.inputType(format))
  21888. format = "datetime-local";
  21889. this.option("mode", format)
  21890. },
  21891. _usingNativeDatePicker: function() {
  21892. return support.inputType(this.option("mode")) && this.option("useNativePicker")
  21893. },
  21894. _readOnlyPropValue: function() {
  21895. if (this._usingNativeDatePicker())
  21896. return this.callBase();
  21897. return true
  21898. },
  21899. _handleValueChangeEvent: function() {
  21900. var value = fromStandardDateFormat(this._input().val()),
  21901. modelValue = new Date(this.option("value") && this.option("value").valueOf()),
  21902. newValue = mergeDates(modelValue, value, this.option("mode"));
  21903. this.option({value: newValue});
  21904. if (newValue !== modelValue)
  21905. this._renderValue()
  21906. },
  21907. _renderValue: function() {
  21908. var mode = this.option("mode"),
  21909. patternKey = FORMATS_MAP[mode],
  21910. pattern = support.inputType(mode) ? false : globalize.culture().calendar.patterns[patternKey],
  21911. value = toStandardDateFormat(this.option("value"), mode, pattern);
  21912. this._input().val(value);
  21913. this._togglePlaceholderVisibility(value === "" || value === null)
  21914. },
  21915. _renderProps: function() {
  21916. this.callBase();
  21917. this._input().attr("autocomplete", "off")
  21918. },
  21919. _getDataPickerTitle: function() {
  21920. var result = this.option("placeholder");
  21921. if (!result) {
  21922. var format = this.option("format");
  21923. if (format === "time")
  21924. result = Globalize.localize("dxDateBox-simulatedDataPickerTitleTime");
  21925. else if (format === "date")
  21926. result = Globalize.localize("dxDateBox-simulatedDataPickerTitleDate");
  21927. else if (format === "datetime")
  21928. result = Globalize.localize("dxDateBox-simulatedDataPickerTitleDateTime")
  21929. }
  21930. return result
  21931. },
  21932. _optionChanged: function(name, value, prevValue) {
  21933. switch (name) {
  21934. case"useCalendar":
  21935. break;
  21936. case"format":
  21937. this._initFormat();
  21938. this._renderValue();
  21939. this._renderDatePicker();
  21940. break;
  21941. case"readOnly":
  21942. this._invalidate();
  21943. break;
  21944. case"useNativePicker":
  21945. this._renderDatePicker();
  21946. this._renderProps();
  21947. break;
  21948. case"placeholder":
  21949. if (this._datePicker)
  21950. this._datePicker.option("title", this._getDataPickerTitle());
  21951. break;
  21952. case"type":
  21953. throw new Error("type cannot be changed after instantiation");
  21954. break;
  21955. case"min":
  21956. case"max":
  21957. if (this._datePicker)
  21958. this._datePicker.option(name + "Date", value);
  21959. break;
  21960. case"value":
  21961. this._renderValue();
  21962. this._renderDatePicker();
  21963. default:
  21964. this.callBase(name, value, prevValue)
  21965. }
  21966. }
  21967. }));
  21968. ui.dxDatePicker.__internals = {
  21969. DATEPICKER_CLASS: DATEPICKER_CLASS,
  21970. DATEPICKER_WRAPPER_CLASS: DATEPICKER_WRAPPER_CLASS,
  21971. DATEPICKER_ROLLER_CONTAINER_CLASS: DATEPICKER_ROLLER_CONTAINER_CLASS,
  21972. DATEPICKER_ROLLER_CLASS: DATEPICKER_ROLLER_CLASS,
  21973. DATEPICKER_ROLLER_ACTIVE_CLASS: DATEPICKER_ROLLER_ACTIVE_CLASS,
  21974. DATEPICKER_ROLLER_ITEM_CLASS: DATEPICKER_ROLLER_ITEM_CLASS,
  21975. DATEPICKER_ROLLER_ITEM_SELECTED_CLASS: DATEPICKER_ROLLER_ITEM_SELECTED_CLASS,
  21976. DATEPICKER_ROLLER_ITEM_SELECTED_FRAME_CLASS: DATEPICKER_ROLLER_ITEM_SELECTED_FRAME_CLASS,
  21977. DATEPICKER_ROLLER_ITEM_SELECTED_BORDER_CLASS: DATEPICKER_ROLLER_ITEM_SELECTED_BORDER_CLASS,
  21978. DATEPICKER_ROLLER_BUTTON_UP_CLASS: DATEPICKER_ROLLER_BUTTON_UP_CLASS,
  21979. DATEPICKER_ROLLER_BUTTON_DOWN_CLASS: DATEPICKER_ROLLER_BUTTON_DOWN_CLASS,
  21980. DATEPICKER_ROLLER_CURRENT_CLASS: DATEPICKER_ROLLER_CURRENT_CLASS
  21981. };
  21982. ui.dxDateBox.__internals = {
  21983. toStandardDateFormat: toStandardDateFormat,
  21984. fromStandardDateFormat: fromStandardDateFormat,
  21985. FORMATS_MAP: FORMATS_MAP
  21986. }
  21987. })(jQuery, DevExpress);
  21988. /*! Module widgets-base, file ui.loadIndicator.js */
  21989. (function($, DX, undefined) {
  21990. var ui = DX.ui;
  21991. var LOADINDICATOR_CLASS = "dx-loadindicator",
  21992. LOADINDICATOR_WRAPPER = "dx-loadindicator-wrapper",
  21993. LOADINDICATOR_ICON = "dx-loadindicator-icon",
  21994. LOADINDICATOR_SEGMENT = "dx-loadindicator-segment",
  21995. LOADINDICATOR_SEGMENT_N = "dx-loadindicator-segment",
  21996. LOADINDICATOR_SEGMENT_WIN8 = "dx-loadindicator-win8-segment",
  21997. LOADINDICATOR_SEGMENT_N_WIN8 = "dx-loadindicator-win8-segment",
  21998. LOADINDICATOR_INNER_SEGMENT_WIN8 = "dx-loadindicator-win8-inner-segment",
  21999. LOADINDICATOR_IMAGE = "dx-loadindicator-image";
  22000. DX.registerComponent("dxLoadIndicator", ui.Widget.inherit({
  22001. _setDefaultOptions: function() {
  22002. this.callBase();
  22003. this.option({
  22004. indicatorSrc: "",
  22005. hoverStateEnabled: false
  22006. })
  22007. },
  22008. _defaultOptionsRules: function() {
  22009. return this.callBase().slice(0).concat([{
  22010. device: function() {
  22011. var realDevice = DevExpress.devices.real(),
  22012. obsoleteAndroid = realDevice.platform === "android" && !/chrome/i.test(navigator.userAgent);
  22013. return DevExpress.browser.msie && DevExpress.browser.version < 10 || obsoleteAndroid
  22014. },
  22015. options: {viaImage: true}
  22016. }])
  22017. },
  22018. _init: function() {
  22019. this.callBase();
  22020. this._element().addClass(LOADINDICATOR_CLASS)
  22021. },
  22022. _render: function() {
  22023. this._renderWrapper();
  22024. this._renderMarkup();
  22025. this.callBase()
  22026. },
  22027. _renderWrapper: function() {
  22028. this._$wrapper = $("<div>").addClass(LOADINDICATOR_WRAPPER);
  22029. this._element().append(this._$wrapper)
  22030. },
  22031. _renderMarkup: function() {
  22032. if (DX.support.animation && !this.option("viaImage") && !this.option("indicatorSrc"))
  22033. this._renderMarkupForAnimation();
  22034. else
  22035. this._renderMarkupForImage()
  22036. },
  22037. _renderMarkupForAnimation: function() {
  22038. this._$indicator = $("<div>").addClass(LOADINDICATOR_ICON);
  22039. for (var i = 15; i >= 0; --i) {
  22040. var $segment = $("<div>").addClass(LOADINDICATOR_SEGMENT).addClass(LOADINDICATOR_SEGMENT_N + i);
  22041. this._$indicator.append($segment)
  22042. }
  22043. for (var i = 1; i <= 5; ++i) {
  22044. var $innerSegment = $("<div>").addClass(LOADINDICATOR_INNER_SEGMENT_WIN8),
  22045. $segment = $("<div>").addClass(LOADINDICATOR_SEGMENT_WIN8).addClass(LOADINDICATOR_SEGMENT_N_WIN8 + i);
  22046. $segment.append($innerSegment);
  22047. this._$indicator.append($segment)
  22048. }
  22049. this._$wrapper.append(this._$indicator)
  22050. },
  22051. _renderMarkupForImage: function() {
  22052. var indicatorSrc = this.option("indicatorSrc");
  22053. this._$wrapper.addClass(LOADINDICATOR_IMAGE);
  22054. if (indicatorSrc)
  22055. this._$wrapper.css("background-image", "url(" + indicatorSrc + ")")
  22056. },
  22057. _renderDimensions: function() {
  22058. this.callBase();
  22059. this._updateContentSize()
  22060. },
  22061. _updateContentSize: function() {
  22062. var $element = this._element(),
  22063. width = this.option("width"),
  22064. height = this.option("height");
  22065. if (width || height) {
  22066. width = this._element().width();
  22067. height = this._element().height();
  22068. var minDimention = Math.min(height, width);
  22069. this._$wrapper.css({
  22070. height: minDimention,
  22071. width: minDimention,
  22072. "margin-top": (height - minDimention) / 2,
  22073. "margin-left": (width - minDimention) / 2
  22074. });
  22075. if (this._$indicator)
  22076. this._$indicator.find("." + LOADINDICATOR_SEGMENT).css("border-width", 0.125 * minDimention)
  22077. }
  22078. },
  22079. _clean: function() {
  22080. this.callBase();
  22081. this._removeMarkupForAnimation();
  22082. this._removeMarkupForImage()
  22083. },
  22084. _removeMarkupForAnimation: function() {
  22085. if (this._$indicator)
  22086. this._$indicator.remove()
  22087. },
  22088. _removeMarkupForImage: function() {
  22089. this._$wrapper.css("background-image", "none")
  22090. },
  22091. _optionChanged: function(name) {
  22092. switch (name) {
  22093. case"indicatorSrc":
  22094. this._invalidate();
  22095. break;
  22096. default:
  22097. this.callBase.apply(this, arguments)
  22098. }
  22099. }
  22100. }))
  22101. })(jQuery, DevExpress);
  22102. /*! Module widgets-base, file ui.loadPanel.js */
  22103. (function($, DX, undefined) {
  22104. var ui = DX.ui;
  22105. var LOADPANEL_CLASS = "dx-loadpanel",
  22106. LOADPANEL_WRAPPER_CLASS = "dx-loadpanel-wrapper",
  22107. LOADPANEL_INDICATOR_CLASS = "dx-loadpanel-indicator",
  22108. LOADPANEL_MESSAGE_CLASS = "dx-loadpanel-message",
  22109. LOADPANEL_CONTENT_CLASS = "dx-loadpanel-content",
  22110. LOADPANEL_CONTENT_WRAPPER_CLASS = "dx-loadpanel-content-wrapper",
  22111. LOADPANEL_PANE_HIDDEN_CLASS = "dx-loadpanel-pane-hidden";
  22112. DX.registerComponent("dxLoadPanel", ui.dxOverlay.inherit({
  22113. _setDefaultOptions: function() {
  22114. this.callBase();
  22115. this.option({
  22116. message: Globalize.localize("Loading"),
  22117. width: 222,
  22118. height: 90,
  22119. animation: null,
  22120. showIndicator: true,
  22121. indicatorSrc: "",
  22122. showPane: true,
  22123. delay: 0
  22124. })
  22125. },
  22126. _init: function() {
  22127. this.callBase.apply(this, arguments);
  22128. this._$contentWrapper = $("<div>").addClass(LOADPANEL_CONTENT_WRAPPER_CLASS);
  22129. this._$contentWrapper.appendTo(this._container())
  22130. },
  22131. _render: function() {
  22132. this.callBase();
  22133. this._element().addClass(LOADPANEL_CLASS);
  22134. this._wrapper().addClass(LOADPANEL_WRAPPER_CLASS)
  22135. },
  22136. _renderContentImpl: function() {
  22137. this.callBase();
  22138. this.content().addClass(LOADPANEL_CONTENT_CLASS);
  22139. this._togglePaneVisible();
  22140. this._cleanPreviousContent();
  22141. this._renderLoadIndicator();
  22142. this._renderMessage()
  22143. },
  22144. _makeVisible: function() {
  22145. var delay = this.option("delay");
  22146. if (!delay)
  22147. return this.callBase();
  22148. var deferred = $.Deferred();
  22149. var callBase = $.proxy(this.callBase, this);
  22150. this._clearShowTimeout();
  22151. this._showTimeout = setTimeout(function() {
  22152. callBase().done(function() {
  22153. deferred.resolve()
  22154. })
  22155. }, delay);
  22156. return deferred.promise()
  22157. },
  22158. _makeHidden: function() {
  22159. this._clearShowTimeout();
  22160. return this.callBase()
  22161. },
  22162. _clearShowTimeout: function() {
  22163. clearTimeout(this._showTimeout)
  22164. },
  22165. _renderMessage: function() {
  22166. var message = this.option("message");
  22167. if (!message)
  22168. return;
  22169. var $message = $("<div>").addClass(LOADPANEL_MESSAGE_CLASS).text(message);
  22170. this._$contentWrapper.append($message)
  22171. },
  22172. _renderLoadIndicator: function() {
  22173. if (!this.option("showIndicator"))
  22174. return;
  22175. this._$indicator = $("<div>").addClass(LOADPANEL_INDICATOR_CLASS).dxLoadIndicator({indicatorSrc: this.option("indicatorSrc")}).appendTo(this._$contentWrapper)
  22176. },
  22177. _cleanPreviousContent: function() {
  22178. this.content().find("." + LOADPANEL_MESSAGE_CLASS).remove();
  22179. this.content().find("." + LOADPANEL_INDICATOR_CLASS).remove()
  22180. },
  22181. _togglePaneVisible: function() {
  22182. this.content().toggleClass(LOADPANEL_PANE_HIDDEN_CLASS, !this.option("showPane"))
  22183. },
  22184. _optionChanged: function(name, value) {
  22185. switch (name) {
  22186. case"delay":
  22187. break;
  22188. case"message":
  22189. case"showIndicator":
  22190. this._cleanPreviousContent();
  22191. this._renderLoadIndicator();
  22192. this._renderMessage();
  22193. break;
  22194. case"showPane":
  22195. this._togglePaneVisible();
  22196. break;
  22197. case"indicatorSrc":
  22198. if (this._$indicator)
  22199. this._$indicator.dxLoadIndicator({indicatorSrc: this.option("indicatorSrc")});
  22200. break;
  22201. default:
  22202. this.callBase.apply(this, arguments)
  22203. }
  22204. },
  22205. _dispose: function() {
  22206. this._clearShowTimeout();
  22207. this.callBase()
  22208. },
  22209. _defaultHideTopOverlayHandler: $.noop
  22210. }));
  22211. ui.dxLoadPanel.__internals = {
  22212. LOADPANEL_CLASS: LOADPANEL_CLASS,
  22213. LOADPANEL_WRAPPER_CLASS: LOADPANEL_WRAPPER_CLASS,
  22214. LOADPANEL_MESSAGE_CLASS: LOADPANEL_MESSAGE_CLASS,
  22215. LOADPANEL_CONTENT_CLASS: LOADPANEL_CONTENT_CLASS,
  22216. LOADPANEL_PANE_HIDDEN_CLASS: LOADPANEL_PANE_HIDDEN_CLASS
  22217. }
  22218. })(jQuery, DevExpress);
  22219. /*! Module widgets-base, file ui.lookup.js */
  22220. (function($, DX, undefined) {
  22221. var ui = DX.ui,
  22222. utils = DX.utils,
  22223. dataUtils = DX.data.utils,
  22224. events = ui.events;
  22225. var LOOKUP_CLASS = "dx-lookup",
  22226. LOOKUP_SELECTED_CLASS = LOOKUP_CLASS + "-selected",
  22227. LOOKUP_SEARCH_CLASS = LOOKUP_CLASS + "-search",
  22228. LOOKUP_SEARCH_WRAPPER_CLASS = LOOKUP_CLASS + "-search-wrapper",
  22229. LOOKUP_FIELD_CLASS = LOOKUP_CLASS + "-field",
  22230. LOOKUP_FIELD_WRAPPER_CLASS = LOOKUP_FIELD_CLASS + "-wrapper",
  22231. LOOKUP_POPUP_CLASS = LOOKUP_CLASS + "-popup",
  22232. LOOKUP_POPUP_WRAPPER_CLASS = LOOKUP_POPUP_CLASS + "-wrapper",
  22233. LOOKUP_POPUP_SEARCH_CLASS = LOOKUP_POPUP_CLASS + "-search",
  22234. LOOKUP_POPOVER_MODE = LOOKUP_CLASS + "-popover-mode",
  22235. LOOKUP_EMPTY_CLASS = LOOKUP_CLASS + "-empty",
  22236. LIST_ITEM_SELECTOR = ".dx-list-item",
  22237. LIST_ITEM_DATA_KEY = "dxListItemData",
  22238. POPUP_HIDE_TIMEOUT = 200;
  22239. DX.registerComponent("dxLookup", ui.dxEditor.inherit({
  22240. _deprecatedOptions: {
  22241. shownAction: {
  22242. since: "14.1",
  22243. message: "Use the 'openAction' option instead."
  22244. },
  22245. hiddenAction: {
  22246. since: "14.1",
  22247. message: "Use the 'closeAction' option instead."
  22248. }
  22249. },
  22250. _optionAliases: {
  22251. openAction: "shownAction",
  22252. closeAction: "hiddenAction"
  22253. },
  22254. _setDefaultOptions: function() {
  22255. this.callBase();
  22256. this.option({
  22257. items: [],
  22258. dataSource: null,
  22259. value: undefined,
  22260. displayValue: undefined,
  22261. title: "",
  22262. titleTemplate: "title",
  22263. valueExpr: null,
  22264. displayExpr: "this",
  22265. placeholder: Globalize.localize("Select"),
  22266. searchPlaceholder: Globalize.localize("Search"),
  22267. searchEnabled: true,
  22268. noDataText: Globalize.localize("dxCollectionContainerWidget-noDataText"),
  22269. searchTimeout: 1000,
  22270. minFilterLength: 0,
  22271. fullScreen: false,
  22272. valueChangeAction: null,
  22273. itemTemplate: "item",
  22274. itemRender: null,
  22275. showCancelButton: true,
  22276. cancelButtonText: Globalize.localize("Cancel"),
  22277. showClearButton: false,
  22278. clearButtonText: Globalize.localize("Clear"),
  22279. showDoneButton: false,
  22280. doneButtonText: Globalize.localize("Done"),
  22281. contentReadyAction: null,
  22282. shownAction: null,
  22283. openAction: null,
  22284. hiddenAction: null,
  22285. closeAction: null,
  22286. popupWidth: function() {
  22287. return $(window).width() * 0.8
  22288. },
  22289. popupHeight: function() {
  22290. return $(window).height() * 0.8
  22291. },
  22292. shading: true,
  22293. closeOnOutsideClick: false,
  22294. position: undefined,
  22295. animation: undefined,
  22296. pullRefreshEnabled: false,
  22297. autoPagingEnabled: true,
  22298. useNativeScrolling: true,
  22299. pullingDownText: Globalize.localize("dxList-pullingDownText"),
  22300. pulledDownText: Globalize.localize("dxList-pulledDownText"),
  22301. refreshingText: Globalize.localize("dxList-refreshingText"),
  22302. pageLoadingText: Globalize.localize("dxList-pageLoadingText"),
  22303. scrollAction: null,
  22304. pullRefreshAction: null,
  22305. pageLoadingAction: null,
  22306. showNextButton: false,
  22307. nextButtonText: Globalize.localize("dxList-nextButtonText"),
  22308. grouped: false,
  22309. groupTemplate: "group",
  22310. groupRender: null,
  22311. usePopover: false
  22312. })
  22313. },
  22314. _defaultOptionsRules: function() {
  22315. return this.callBase().slice(0).concat([{
  22316. device: function(device) {
  22317. return !DX.support.nativeScrolling
  22318. },
  22319. options: {useNativeScrolling: false}
  22320. }, {
  22321. device: function(device) {
  22322. return !DX.support.nativeScrolling && !DX.devices.isSimulator() && DX.devices.real().platform === "generic" && device.platform === "generic"
  22323. },
  22324. options: {
  22325. showNextButton: true,
  22326. autoPagingEnabled: false
  22327. }
  22328. }, {
  22329. device: {
  22330. platform: "win8",
  22331. phone: true
  22332. },
  22333. options: {
  22334. showCancelButton: false,
  22335. fullScreen: true
  22336. }
  22337. }, {
  22338. device: {
  22339. platform: "win8",
  22340. phone: false
  22341. },
  22342. options: {popupWidth: function() {
  22343. return $(window).width()
  22344. }}
  22345. }, {
  22346. device: [{
  22347. platform: "ios",
  22348. phone: true
  22349. }, {
  22350. platform: "ios7",
  22351. phone: true
  22352. }],
  22353. options: {fullScreen: true}
  22354. }, {
  22355. device: [{
  22356. platform: "ios",
  22357. tablet: true
  22358. }, {
  22359. platform: "ios7",
  22360. tablet: true
  22361. }],
  22362. options: {
  22363. popupWidth: function() {
  22364. return Math.min($(window).width(), $(window).height()) * 0.4
  22365. },
  22366. popupHeight: function() {
  22367. return Math.min($(window).width(), $(window).height()) * 0.4
  22368. },
  22369. usePopover: true
  22370. }
  22371. }])
  22372. },
  22373. _optionsByReference: function() {
  22374. return $.extend(this.callBase(), {value: true})
  22375. },
  22376. _init: function() {
  22377. this.callBase();
  22378. this._initDataSource();
  22379. this._searchTimer = null;
  22380. this._compileValueGetter();
  22381. this._compileDisplayGetter();
  22382. this._suppressValueChangeAction();
  22383. if (!this._dataSource)
  22384. this._itemsToDataSource()
  22385. },
  22386. _compileValueGetter: function() {
  22387. this._valueGetter = dataUtils.compileGetter(this._valueGetterExpr())
  22388. },
  22389. _valueGetterExpr: function() {
  22390. return this.option("valueExpr") || "this"
  22391. },
  22392. _compileDisplayGetter: function() {
  22393. this._displayGetter = dataUtils.compileGetter(this.option("displayExpr"))
  22394. },
  22395. _itemsToDataSource: function() {
  22396. this._dataSource = new DevExpress.data.DataSource(this.option("items"))
  22397. },
  22398. _render: function() {
  22399. this.callBase();
  22400. this._element().addClass(LOOKUP_CLASS).toggleClass(LOOKUP_POPOVER_MODE, this.option("usePopover"));
  22401. this._renderField();
  22402. this._needRenderContent = true;
  22403. this._calcSelectedItem($.proxy(this._setFieldText, this))
  22404. },
  22405. _renderContent: $.noop,
  22406. _renderContentImpl: $.noop,
  22407. _renderField: function() {
  22408. var that = this,
  22409. fieldClickAction = this._createAction(this._handleFieldClick);
  22410. this._$fieldWrapper = $("<div>").addClass(LOOKUP_FIELD_WRAPPER_CLASS);
  22411. this._$field = $("<div>").addClass(LOOKUP_FIELD_CLASS).appendTo(this._$fieldWrapper).on(events.addNamespace("dxclick", this.NAME), function(e) {
  22412. if (that.option("readOnly"))
  22413. return;
  22414. fieldClickAction({jQueryEvent: e})
  22415. });
  22416. this._$fieldWrapper.appendTo(this._element())
  22417. },
  22418. _handleFieldClick: function(args) {
  22419. var that = args.component;
  22420. that._renderContentIfNeed();
  22421. that._setListDataSource();
  22422. that._refreshSelected();
  22423. that._popup.show();
  22424. that._lastSelectedItem = that._selectedItem
  22425. },
  22426. _renderContentIfNeed: function() {
  22427. if (this._needRenderContent) {
  22428. this._renderPopup();
  22429. this._needRenderContent = false
  22430. }
  22431. },
  22432. _renderPopup: function() {
  22433. var $popup = $("<div>").addClass(LOOKUP_POPUP_CLASS).appendTo(this._element());
  22434. var popupOptions = {
  22435. rtlEnabled: this.option("rtlEnabled"),
  22436. showTitle: true,
  22437. title: this.option("title"),
  22438. titleTemplate: this._getTemplateByOption("titleTemplate"),
  22439. contentReadyAction: $.proxy(this._popupContentReadyAction, this),
  22440. cancelButton: this._getCancelButtonConfig(),
  22441. doneButton: this._getDoneButtonConfig(),
  22442. clearButton: this._getClearButtonConfig(),
  22443. shownAction: this._createActionByOption("shownAction"),
  22444. hiddenAction: this._createActionByOption("hiddenAction")
  22445. };
  22446. this._popup = this.option("usePopover") && !this.option("fullScreen") ? this._createPopover($popup, popupOptions) : this._createPopup($popup, popupOptions);
  22447. this._setPopupOption("position", "position");
  22448. this._setPopupOption("animation", "animation");
  22449. this._setPopupOption("popupWidth", "width");
  22450. this._setPopupOption("popupHeight", "height");
  22451. this._popup._wrapper().addClass(LOOKUP_POPUP_WRAPPER_CLASS).toggleClass(LOOKUP_POPUP_SEARCH_CLASS, this.option("searchEnabled"))
  22452. },
  22453. _setPopupOption: function(option, popupOption) {
  22454. var option = this.option(option);
  22455. option = option === undefined ? this._popup.initialOption(popupOption) : option;
  22456. this._popup.option(popupOption, option)
  22457. },
  22458. _createPopover: function($element, options) {
  22459. return $element.dxPopover($.extend(options, {target: this._element()})).dxPopover("instance")
  22460. },
  22461. _createPopup: function($element, options) {
  22462. return $element.dxPopup($.extend(options, {
  22463. fullScreen: this.option("fullScreen"),
  22464. shading: this.option("shading"),
  22465. closeOnOutsideClick: this.option("closeOnOutsideClick")
  22466. })).dxPopup("instance")
  22467. },
  22468. _getCancelButtonConfig: function() {
  22469. return this.option("showCancelButton") ? {text: this.option("cancelButtonText")} : null
  22470. },
  22471. _getDoneButtonConfig: function() {
  22472. return this.option("showDoneButton") ? {
  22473. text: this.option("doneButtonText"),
  22474. clickAction: $.proxy(function() {
  22475. this.option("value", this._valueGetter(this._lastSelectedItem))
  22476. }, this)
  22477. } : null
  22478. },
  22479. _getClearButtonConfig: function() {
  22480. return this.option("showClearButton") ? {
  22481. text: this.option("clearButtonText"),
  22482. clickAction: $.proxy(function() {
  22483. this.option("value", undefined)
  22484. }, this)
  22485. } : null
  22486. },
  22487. _renderCancelButton: function() {
  22488. this._popup && this._popup.option("cancelButton", this._getCancelButtonConfig())
  22489. },
  22490. _renderDoneButton: function() {
  22491. this._popup && this._popup.option("doneButton", this._getDoneButtonConfig())
  22492. },
  22493. _renderClearButton: function() {
  22494. this._popup && this._popup.option("clearButton", this._getClearButtonConfig())
  22495. },
  22496. _popupContentReadyAction: function() {
  22497. this._renderSearch();
  22498. this._renderList()
  22499. },
  22500. _renderSearch: function() {
  22501. this._$search = $("<div>").addClass(LOOKUP_SEARCH_CLASS).dxTextBox({
  22502. mode: "search",
  22503. placeholder: this._getSearchPlaceholder(),
  22504. valueChangeEvent: "change input",
  22505. valueChangeAction: $.proxy(this._searchChangedHandler, this),
  22506. rtlEnabled: this.option("rtlEnabled")
  22507. }).appendTo(this._popup.content()).wrap($("<div>").addClass(LOOKUP_SEARCH_WRAPPER_CLASS).toggle(this.option("searchEnabled")));
  22508. this._search = this._$search.dxTextBox("instance")
  22509. },
  22510. _getSearchPlaceholder: function() {
  22511. var minFilterLength = this.option("minFilterLength"),
  22512. placeholder = this.option("searchPlaceholder");
  22513. if (minFilterLength && placeholder === Globalize.localize("Search"))
  22514. return utils.stringFormat(Globalize.localize("dxLookup-searchPlaceholder"), minFilterLength);
  22515. return placeholder
  22516. },
  22517. _renderList: function() {
  22518. this._list = $("<div>").appendTo(this._popup.content()).dxList({
  22519. _templates: this.option("_templates"),
  22520. dataSource: null,
  22521. itemClickAction: $.proxy(function(e) {
  22522. this._toggleSelectedClass(e.jQueryEvent);
  22523. this._updateOptions(e)
  22524. }, this),
  22525. itemRenderedAction: $.proxy(function(e) {
  22526. this._setSelectedClass(e.itemElement, e.itemData)
  22527. }, this),
  22528. itemRender: this._getItemRender(),
  22529. itemTemplate: this._getTemplateByOption("itemTemplate"),
  22530. noDataText: this.option("noDataText"),
  22531. pullRefreshEnabled: this.option("pullRefreshEnabled"),
  22532. autoPagingEnabled: this.option("autoPagingEnabled"),
  22533. useNativeScrolling: this.option("useNativeScrolling"),
  22534. pullingDownText: this.option("pullingDownText"),
  22535. pulledDownText: this.option("pulledDownText"),
  22536. refreshingText: this.option("refreshingText"),
  22537. pageLoadingText: this.option("pageLoadingText"),
  22538. scrollAction: this.option("scrollAction"),
  22539. pullRefreshAction: this.option("pullRefreshAction"),
  22540. pageLoadingAction: this.option("pageLoadingAction"),
  22541. showNextButton: this.option("showNextButton"),
  22542. nextButtonText: this.option("nextButtonText"),
  22543. grouped: this.option("grouped"),
  22544. groupTemplate: this._getTemplateByOption("groupTemplate"),
  22545. groupRender: this.option("groupRender"),
  22546. rtlEnabled: this.option("rtlEnabled")
  22547. }).data("dxList");
  22548. if (this._needSetItemRenderToList) {
  22549. this._updateListItemRender();
  22550. this._needSetItemRenderToList = false
  22551. }
  22552. this._setListDataSource();
  22553. this._list.option("contentReadyAction", this.option("contentReadyAction"));
  22554. this._list._fireContentReadyAction()
  22555. },
  22556. _setListDataSource: function(force) {
  22557. if (!this._list)
  22558. return;
  22559. var needsToLoad = this._search.option("value").length >= this.option("minFilterLength"),
  22560. dataSourceLoaded = !!this._list.option("dataSource"),
  22561. skip = needsToLoad === dataSourceLoaded;
  22562. if (!force && skip)
  22563. return;
  22564. this._list.option("dataSource", needsToLoad ? this._dataSource : null);
  22565. if (!needsToLoad)
  22566. this._list.option("items", undefined)
  22567. },
  22568. _refreshSelected: function() {
  22569. var that = this;
  22570. if (!that._list)
  22571. return;
  22572. $.each(this._list._element().find(LIST_ITEM_SELECTOR), function() {
  22573. var item = $(this);
  22574. that._setSelectedClass(item, item.data(LIST_ITEM_DATA_KEY))
  22575. })
  22576. },
  22577. _calcSelectedItem: function(callback) {
  22578. var ds = this._dataSource,
  22579. store,
  22580. valueExpr,
  22581. thisWidget = this,
  22582. value = this._unwrapedValue();
  22583. function handleLoadSuccess(result) {
  22584. thisWidget._selectedItem = result;
  22585. callback()
  22586. }
  22587. if (!ds || value === undefined) {
  22588. this._selectedItem = undefined;
  22589. callback();
  22590. return
  22591. }
  22592. store = ds.store();
  22593. valueExpr = this._valueGetterExpr();
  22594. this._loadSingle(valueExpr, value).done(function(result) {
  22595. handleLoadSuccess(result)
  22596. })
  22597. },
  22598. _unwrapedValue: function() {
  22599. var value = this.option("value");
  22600. var valueExpr = this._valueGetterExpr();
  22601. if (!this._dataSource && valueExpr !== "this")
  22602. return value;
  22603. var key = this._dataSource.store().key();
  22604. if (key && typeof value === "object")
  22605. value = value[key];
  22606. return $.isFunction(value) ? value() : value
  22607. },
  22608. _setFieldText: function(text) {
  22609. if (!arguments.length)
  22610. text = this._getDisplayText();
  22611. this._$field.text(text);
  22612. this.option("displayValue", text);
  22613. this._toggleEmptyClass()
  22614. },
  22615. _getDisplayText: function() {
  22616. if (this.option("value") === undefined || !this._dataSource)
  22617. return this.option("placeholder");
  22618. return this._displayGetter(this._selectedItem) || this.option("placeholder")
  22619. },
  22620. _searchChangedHandler: function() {
  22621. if (!this._search)
  22622. return;
  22623. var searchValue = this._search.option("value"),
  22624. needsToLoad = searchValue.length >= this.option("minFilterLength");
  22625. clearTimeout(this._searchTimer);
  22626. this._search.option("placeholder", this._getSearchPlaceholder());
  22627. if (!needsToLoad) {
  22628. this._setListDataSource();
  22629. return
  22630. }
  22631. if (this.option("searchTimeout"))
  22632. this._searchTimer = setTimeout($.proxy(this._doSearch, this, searchValue), this.option("searchTimeout"));
  22633. else
  22634. this._doSearch(searchValue)
  22635. },
  22636. _doSearch: function(searchValue) {
  22637. if (!this._dataSource)
  22638. return;
  22639. if (!arguments.length)
  22640. searchValue = this.option("searchEnabled") ? this._search.option("value") : "";
  22641. this._filterStore(searchValue).done($.proxy(function() {
  22642. if (this._dataSource.items().length)
  22643. this._setListDataSource()
  22644. }, this))
  22645. },
  22646. _filterStore: function(searchValue) {
  22647. if (!this._dataSource.searchExpr())
  22648. this._dataSource.searchExpr(this.option("displayExpr"));
  22649. this._dataSource.searchValue(searchValue);
  22650. this._dataSource.pageIndex(0);
  22651. return this._dataSource.load()
  22652. },
  22653. _updateOptions: function(e) {
  22654. if (this._lastSelectedItem === e.itemData)
  22655. this._updateAndHidePopup();
  22656. this._lastSelectedItem = e.itemData;
  22657. if (!this.option("showDoneButton"))
  22658. this._updateAndHidePopup()
  22659. },
  22660. _setSelectedClass: function(item, itemData) {
  22661. itemData = this._valueGetter(itemData);
  22662. var value = this.option("value");
  22663. var dataSourceKey = this._dataSource && this._dataSource.key();
  22664. var selected = this._optionValuesEqual("value", itemData, value);
  22665. if (dataSourceKey && !selected && value) {
  22666. var valueKey = utils.unwrapObservable(value[dataSourceKey]);
  22667. var itemDataKey = utils.unwrapObservable(itemData[dataSourceKey]) || itemData;
  22668. selected = valueKey === itemDataKey
  22669. }
  22670. item.toggleClass(LOOKUP_SELECTED_CLASS, selected)
  22671. },
  22672. _getItemRender: function() {
  22673. var templateName = this.option("itemTemplate");
  22674. if (!templateName || !(templateName in this.option("_templates")))
  22675. return this.option("itemRender") || $.proxy(this._displayGetter, this)
  22676. },
  22677. _toggleSelectedClass: function(e) {
  22678. var $selectedItem = this._list._element().find("." + LOOKUP_SELECTED_CLASS);
  22679. if ($selectedItem.length)
  22680. $selectedItem.removeClass(LOOKUP_SELECTED_CLASS);
  22681. $(e.target).closest(LIST_ITEM_SELECTOR).addClass(LOOKUP_SELECTED_CLASS)
  22682. },
  22683. _toggleEmptyClass: function() {
  22684. var empty = !this._selectedItem;
  22685. this._element().toggleClass(LOOKUP_EMPTY_CLASS, empty)
  22686. },
  22687. _hidePopup: function() {
  22688. this._popup.hide()
  22689. },
  22690. _updateAndHidePopup: function() {
  22691. this.option("value", this._valueGetter(this._lastSelectedItem));
  22692. clearTimeout(this._hidePopupTimer);
  22693. this._hidePopupTimer = setTimeout($.proxy(this._hidePopup, this), POPUP_HIDE_TIMEOUT);
  22694. this._setFieldText(this._displayGetter(this._lastSelectedItem))
  22695. },
  22696. _updateListItemRender: function() {
  22697. if (this._list)
  22698. this._list.option("itemRender", this._getItemRender());
  22699. else
  22700. this._needSetItemRenderToList = true
  22701. },
  22702. _updateListItemTemplate: function() {
  22703. if (this._list)
  22704. this._list.option("itemTemplate", this.option("itemTemplate"))
  22705. },
  22706. _clean: function() {
  22707. if (this._popup)
  22708. this._popup._element().remove();
  22709. if (this._$field)
  22710. this._$field.remove();
  22711. if (this._$fieldWrapper)
  22712. this._$fieldWrapper.remove()
  22713. },
  22714. _dispose: function() {
  22715. clearTimeout(this._searchTimer);
  22716. clearTimeout(this._hidePopupTimer);
  22717. $(window).off(events.addNamespace("popstate", this.NAME));
  22718. this.callBase()
  22719. },
  22720. _changeListOption: function(name, value) {
  22721. if (this._list)
  22722. this._list.option(name, value)
  22723. },
  22724. _changePopupOption: function(name, value) {
  22725. if (this._popup)
  22726. this._popup.option(name, value)
  22727. },
  22728. _optionChanged: function(name, value, previousValue) {
  22729. switch (name) {
  22730. case"valueExpr":
  22731. case"value":
  22732. this._calcSelectedItem($.proxy(function() {
  22733. if (name === "value")
  22734. this._raiseValueChangeAction(value, previousValue, {selectedItem: this._selectedItem});
  22735. this._compileValueGetter();
  22736. this._compileDisplayGetter();
  22737. this._refreshSelected();
  22738. this._setFieldText()
  22739. }, this));
  22740. break;
  22741. case"displayExpr":
  22742. this._compileDisplayGetter();
  22743. this._updateListItemRender();
  22744. this._refreshSelected();
  22745. this._setFieldText();
  22746. break;
  22747. case"displayValue":
  22748. break;
  22749. case"itemRender":
  22750. this._updateListItemRender();
  22751. case"itemTemplate":
  22752. this._updateListItemTemplate();
  22753. break;
  22754. case"items":
  22755. case"dataSource":
  22756. if (name === "items")
  22757. this._itemsToDataSource();
  22758. else
  22759. this._initDataSource();
  22760. this._setListDataSource(true);
  22761. this._compileValueGetter();
  22762. this._calcSelectedItem($.proxy(this._setFieldText, this));
  22763. break;
  22764. case"searchEnabled":
  22765. if (this._$search)
  22766. this._$search.toggle(value);
  22767. if (this._popup)
  22768. this._popup._wrapper().toggleClass(LOOKUP_POPUP_SEARCH_CLASS, value);
  22769. break;
  22770. case"minFilterLength":
  22771. this._setListDataSource();
  22772. this._setFieldText();
  22773. this._searchChangedHandler();
  22774. break;
  22775. case"placeholder":
  22776. this._setFieldText();
  22777. break;
  22778. case"searchPlaceholder":
  22779. if (this._$search)
  22780. this._$search.dxTextBox("instance").option("placeholder", value);
  22781. break;
  22782. case"shownAction":
  22783. case"hiddenAction":
  22784. case"openAction":
  22785. case"closeAction":
  22786. case"animation":
  22787. this._renderPopup();
  22788. break;
  22789. case"title":
  22790. case"titleTemplate":
  22791. this._changePopupOption(name, value);
  22792. break;
  22793. case"position":
  22794. case"shading":
  22795. case"closeOnOutsideClick":
  22796. if (!this.option("usePopover"))
  22797. this._changePopupOption(name, value);
  22798. break;
  22799. case"fullScreen":
  22800. if (this._popup)
  22801. if (!this.option("usePopover"))
  22802. this._popup.option(name, value);
  22803. else
  22804. this._renderPopup();
  22805. break;
  22806. case"clearButtonText":
  22807. case"showClearButton":
  22808. this._renderClearButton();
  22809. break;
  22810. case"cancelButtonText":
  22811. case"showCancelButton":
  22812. this._renderCancelButton();
  22813. break;
  22814. case"doneButtonText":
  22815. case"showDoneButton":
  22816. this._renderDoneButton();
  22817. break;
  22818. case"popupWidth":
  22819. this._changePopupOption("width", value === "auto" ? this.initialOption("popupWidth") : value);
  22820. break;
  22821. case"popupHeight":
  22822. this._changePopupOption("height", value === "auto" ? this.initialOption("popupHeight") : value);
  22823. break;
  22824. case"usePopover":
  22825. this._invalidate();
  22826. break;
  22827. case"pullRefreshEnabled":
  22828. case"autoPagingEnabled":
  22829. case"useNativeScrolling":
  22830. case"pullingDownText":
  22831. case"pulledDownText":
  22832. case"refreshingText":
  22833. case"pageLoadingText":
  22834. case"scrollAction":
  22835. case"pullRefreshAction":
  22836. case"pageLoadingAction":
  22837. case"showNextButton":
  22838. case"nextButtonText":
  22839. case"grouped":
  22840. case"groupRender":
  22841. case"noDataText":
  22842. case"contentReadyAction":
  22843. this._changeListOption(name, value);
  22844. break;
  22845. case"groupTemplate":
  22846. this._changeListOption(name, this._getTemplateByOption(name));
  22847. case"searchTimeout":
  22848. break;
  22849. default:
  22850. this.callBase.apply(this, arguments)
  22851. }
  22852. },
  22853. open: function() {
  22854. this._renderContentIfNeed();
  22855. this._popup.show()
  22856. },
  22857. close: function() {
  22858. this._renderContentIfNeed();
  22859. this._popup.hide()
  22860. }
  22861. }).include(ui.DataHelperMixin))
  22862. })(jQuery, DevExpress);
  22863. /*! Module widgets-base, file ui.autocomplete.js */
  22864. (function($, DX, undefined) {
  22865. var ui = DX.ui,
  22866. events = ui.events,
  22867. utils = DX.utils;
  22868. var KEY_DOWN = 40,
  22869. KEY_UP = 38,
  22870. KEY_ENTER = 13,
  22871. KEY_ESC = 27,
  22872. KEY_RIGHT = 39,
  22873. KEY_TAB = 9,
  22874. AUTOCOMPLETE_CLASS = "dx-autocomplete",
  22875. AUTOCOMPLETE_POPUP_WRAPPER_CLASS = "dx-autocomplete-popup-wrapper",
  22876. SELECTED_ITEM_CLASS = "dx-autocomplete-selected",
  22877. SELECTED_ITEM_SELECTOR = "." + SELECTED_ITEM_CLASS,
  22878. LIST_SELECTOR = ".dx-list",
  22879. LIST_ITEM_SELECTOR = ".dx-list-item",
  22880. LIST_ITEM_DATA_KEY = "dxListItemData",
  22881. SEARCH_MODES = ["startswith", "contains", "endwith", "notcontains"],
  22882. AUTOCOMPLETE_KEYDOWN_EVENT_NAME = events.addNamespace("keydown", "dxAutocomplete"),
  22883. AUTOCOMPLETE_KEYUP_EVENT_NAME = events.addNamespace("keyup", "dxAutocomplete"),
  22884. AUTOCOMPLETE_FOCUSIN_EVENT_NAME = events.addNamespace("focusin", "dxAutocomplete"),
  22885. AUTOCOMPLETE_FOCUSOUT_EVENT_NAME = events.addNamespace("focusout", "dxAutocomplete");
  22886. DX.registerComponent("dxAutocomplete", ui.dxDropDownEditor.inherit({
  22887. _setDefaultOptions: function() {
  22888. this.callBase();
  22889. this.option({
  22890. value: "",
  22891. items: [],
  22892. dataSource: null,
  22893. itemTemplate: "item",
  22894. itemRender: null,
  22895. minSearchLength: 1,
  22896. searchTimeout: 0,
  22897. searchMode: "contains",
  22898. displayExpr: "this",
  22899. valueChangeEvent: "change keyup",
  22900. shouldActivateFocusOut: true,
  22901. maxLength: null
  22902. })
  22903. },
  22904. _listElement: function() {
  22905. return this._dropDown.content().find(LIST_SELECTOR)
  22906. },
  22907. _listItemElement: function() {
  22908. return this._dropDown.content().find(LIST_ITEM_SELECTOR)
  22909. },
  22910. _listSelectedItemElement: function() {
  22911. return this._dropDown.content().find(this._getSelectedItemSelector())
  22912. },
  22913. _init: function() {
  22914. this.callBase();
  22915. this._validateSearchMode();
  22916. this._compileDisplayGetter();
  22917. this._initDataSource();
  22918. this._fillDataSourceFromItemsIfNeeded()
  22919. },
  22920. _fillDataSourceFromItemsIfNeeded: function() {
  22921. if (!this.option("dataSource") && this.option("items"))
  22922. this._itemsToDataSource()
  22923. },
  22924. _validateSearchMode: function() {
  22925. var searchMode = this.option("searchMode"),
  22926. normalizedSearchMode = searchMode.toLowerCase();
  22927. if ($.inArray(normalizedSearchMode, SEARCH_MODES) > -1)
  22928. return;
  22929. throw Error(DX.utils.stringFormat("Search mode \"{0}\" is unavailable", searchMode));
  22930. },
  22931. _compileDisplayGetter: function() {
  22932. this._displayGetter = DX.data.utils.compileGetter(this.option("displayExpr"))
  22933. },
  22934. _render: function() {
  22935. this.callBase();
  22936. this._element().addClass(AUTOCOMPLETE_CLASS);
  22937. this._renderInputEvents()
  22938. },
  22939. _renderDimensions: function() {
  22940. this.callBase();
  22941. if (this._dropDown)
  22942. this._dropDown.option("width", this.option("width"))
  22943. },
  22944. _renderContentImpl: function() {
  22945. this._caretPosition = {
  22946. start: 0,
  22947. end: 0
  22948. };
  22949. this._renderDropDownContainer()
  22950. },
  22951. _renderButton: function(hideButton) {
  22952. this.callBase(hideButton === false ? false : true)
  22953. },
  22954. _renderInputEvents: function() {
  22955. this._input().on(AUTOCOMPLETE_KEYDOWN_EVENT_NAME, $.proxy(this._handleInputKeyDown, this)).on(AUTOCOMPLETE_KEYUP_EVENT_NAME, $.proxy(this._handleInputKeyUp, this)).on(AUTOCOMPLETE_FOCUSIN_EVENT_NAME, $.proxy(function() {
  22956. this._setFocusSelection()
  22957. }, this)).on(AUTOCOMPLETE_FOCUSOUT_EVENT_NAME, $.proxy(function() {
  22958. if (this.option("shouldActivateFocusOut"))
  22959. this._hideDropDown();
  22960. this._toggleElementSelectedClass(false)
  22961. }, this))
  22962. },
  22963. _setFocusSelection: function() {
  22964. this._toggleElementSelectedClass(true)
  22965. },
  22966. _hasUpdateEvent: function(eventName) {
  22967. return eventName && this.option("valueUpdateEvent").indexOf(eventName) !== -1
  22968. },
  22969. _handleInputKeyDown: function(e) {
  22970. var $list = this._listElement(),
  22971. preventedKeys = [KEY_TAB, KEY_UP, KEY_DOWN],
  22972. key = e.which;
  22973. if ($list.is(":hidden"))
  22974. return;
  22975. if ($.inArray(key, preventedKeys) > -1)
  22976. e.preventDefault();
  22977. else if (key !== KEY_ENTER)
  22978. this._toggleElementSelectedClass(true)
  22979. },
  22980. _handleInputKeyUp: function(e) {
  22981. var key = e.which;
  22982. this._caretPosition = {
  22983. start: this._input().prop("selectionStart"),
  22984. end: this._input().prop("selectionEnd")
  22985. };
  22986. switch (key) {
  22987. case KEY_DOWN:
  22988. this._handleInputDownKey();
  22989. break;
  22990. case KEY_UP:
  22991. this._handleInputUpKey();
  22992. break;
  22993. case KEY_ENTER:
  22994. this._handleInputEnterKey();
  22995. break;
  22996. case KEY_RIGHT:
  22997. case KEY_TAB:
  22998. this._handleInputCompleteKeys();
  22999. break;
  23000. case KEY_ESC:
  23001. this._hideDropDown();
  23002. break;
  23003. default:
  23004. return
  23005. }
  23006. },
  23007. _handleInputDownKey: function() {
  23008. var $selectedItem = this._listSelectedItemElement(),
  23009. $nextItem;
  23010. if ($selectedItem.length) {
  23011. $nextItem = $selectedItem.next();
  23012. if ($nextItem.length)
  23013. $nextItem.addClass(this._getSelectedItemClass());
  23014. else
  23015. this._toggleElementSelectedClass(true);
  23016. $selectedItem.removeClass(this._getSelectedItemClass());
  23017. this._list.scrollToItem($nextItem)
  23018. }
  23019. else {
  23020. this._listItemElement().first().addClass(this._getSelectedItemClass());
  23021. this._list.scrollToItem(this._listItemElement().first());
  23022. this._toggleElementSelectedClass(false)
  23023. }
  23024. },
  23025. _handleInputUpKey: function() {
  23026. var $selectedItem = this._listSelectedItemElement(),
  23027. $prevItem,
  23028. $list = this._listElement();
  23029. if ($list.is(":hidden"))
  23030. return;
  23031. if (!$selectedItem.length) {
  23032. this._listItemElement().last().addClass(this._getSelectedItemClass());
  23033. this._list.scrollToItem(this._listItemElement().last());
  23034. this._toggleElementSelectedClass(false);
  23035. return
  23036. }
  23037. $selectedItem.removeClass(this._getSelectedItemClass());
  23038. $prevItem = $selectedItem.prev();
  23039. if ($prevItem.length) {
  23040. $prevItem.addClass(this._getSelectedItemClass());
  23041. this._list.scrollToItem($prevItem)
  23042. }
  23043. else
  23044. this._toggleElementSelectedClass(true)
  23045. },
  23046. _handleInputEnterKey: function() {
  23047. var $selectedItem = this._listSelectedItemElement(),
  23048. receivedValue;
  23049. if (!$selectedItem.length) {
  23050. this._hideDropDown();
  23051. return
  23052. }
  23053. receivedValue = this._selectedItemDataGetter();
  23054. this._caretPosition = {
  23055. start: receivedValue.length,
  23056. end: receivedValue.length
  23057. };
  23058. this.option("value", receivedValue);
  23059. this._hideDropDown();
  23060. this._input().blur()
  23061. },
  23062. _handleInputCompleteKeys: function() {
  23063. var $list = this._listElement(),
  23064. newValue,
  23065. receivedValue;
  23066. if ($list.is(":hidden"))
  23067. return;
  23068. receivedValue = this._selectedItemDataGetter();
  23069. newValue = receivedValue.length ? receivedValue : this._dataSource.items()[0];
  23070. this._caretPosition = {
  23071. start: newValue.length,
  23072. end: newValue.length
  23073. };
  23074. newValue = this._displayGetter(newValue);
  23075. this.option("value", newValue);
  23076. this._hideDropDown()
  23077. },
  23078. _toggleElementSelectedClass: function(isToggle) {
  23079. this._element().toggleClass(this._getSelectedItemClass(), isToggle)
  23080. },
  23081. _selectedItemDataGetter: function() {
  23082. var $selectedItem = this._listSelectedItemElement();
  23083. return $selectedItem.length ? this._displayGetter($selectedItem.data(LIST_ITEM_DATA_KEY)) : []
  23084. },
  23085. _createDropDown: function() {
  23086. var popupWidth = this.option("width"),
  23087. vOffset = 0,
  23088. hOffset = 0;
  23089. if (DX.devices.current().win8)
  23090. vOffset = -6;
  23091. else if (DX.devices.current().platform === "generic" || DX.devices.current().tizen)
  23092. vOffset = -1;
  23093. this._dropDown = $("<div>").appendTo(this._element()).dxPopup({
  23094. rtlEnabled: this.option("rtlEnabled"),
  23095. shading: false,
  23096. closeOnOutsideClick: false,
  23097. closeOnTargetScroll: true,
  23098. showTitle: false,
  23099. width: popupWidth,
  23100. showingAction: $.proxy(this._dimensionChanged, this),
  23101. deferRendering: false,
  23102. shownAction: this.option("openAction"),
  23103. hiddenAction: this.option("closeAction"),
  23104. position: {
  23105. my: "left top",
  23106. at: "left bottom",
  23107. of: this._$element,
  23108. offset: {
  23109. h: hOffset,
  23110. v: vOffset
  23111. },
  23112. collision: "flip"
  23113. },
  23114. animation: {
  23115. show: {
  23116. type: "pop",
  23117. duration: 400,
  23118. from: {
  23119. opacity: 0,
  23120. scale: 1
  23121. },
  23122. to: {
  23123. opacity: 1,
  23124. scale: 1
  23125. }
  23126. },
  23127. hide: {
  23128. type: "fade",
  23129. duration: 400,
  23130. from: 1,
  23131. to: 0
  23132. }
  23133. }
  23134. }).dxPopup("instance");
  23135. this._dropDown._wrapper().addClass(AUTOCOMPLETE_POPUP_WRAPPER_CLASS);
  23136. this._renderList()
  23137. },
  23138. _dimensionChanged: function() {
  23139. this._calculatePopupDimensions()
  23140. },
  23141. _calculatePopupDimensions: function() {
  23142. this._calculatePopupHeight();
  23143. this._calculatePopupWidth()
  23144. },
  23145. _calculatePopupHeight: function() {
  23146. var popup = this._dropDown;
  23147. popup.option("height", "auto");
  23148. var list = this._list;
  23149. this._heightApplyingTimer = setTimeout(function() {
  23150. var popupHeight = popup.container().outerHeight();
  23151. var maxHeight = $(window).height() * 0.5;
  23152. popup.option("height", Math.min(popupHeight, maxHeight));
  23153. list.updateDimensions()
  23154. })
  23155. },
  23156. _calculatePopupWidth: function() {
  23157. var textWidth = this._element().outerWidth();
  23158. this._dropDown.option("width", textWidth)
  23159. },
  23160. _getSelectedItemClass: function() {
  23161. return SELECTED_ITEM_CLASS
  23162. },
  23163. _getSelectedItemSelector: function() {
  23164. return SELECTED_ITEM_SELECTOR
  23165. },
  23166. _renderList: function() {
  23167. this._list = $("<div>").appendTo(this._dropDown.content()).dxList({
  23168. _templates: this.option("_templates"),
  23169. itemClickAction: $.proxy(this._handleListItemClick, this),
  23170. itemTemplate: this._getTemplateByOption("itemTemplate"),
  23171. itemRender: this._getItemRender(),
  23172. noDataText: "",
  23173. showNextButton: false,
  23174. autoPagingEnabled: false,
  23175. dataSource: this._dataSource,
  23176. indicateLoading: false
  23177. }).dxList("instance")
  23178. },
  23179. _getItemRender: function() {
  23180. var templateName = this.option("itemTemplate");
  23181. if (!templateName || !(templateName in this.option("_templates")))
  23182. return this.option("itemRender") || $.proxy(this._displayGetter, this)
  23183. },
  23184. _handleListItemClick: function(e) {
  23185. var value = this._displayGetter(e.itemData);
  23186. this._caretPosition = {
  23187. start: value.length,
  23188. end: value.length
  23189. };
  23190. this.option("value", value);
  23191. this._hideDropDown();
  23192. this._input().blur()
  23193. },
  23194. _itemsToDataSource: function() {
  23195. this._dataSource = new DevExpress.data.DataSource(this.option("items"));
  23196. return this._dataSource
  23197. },
  23198. _filterDataSource: function() {
  23199. this._reloadDataSource(this.option("value"));
  23200. this._clearSearchTimer()
  23201. },
  23202. _reloadDataSource: function(searchValue, searchMethod) {
  23203. var that = this,
  23204. ds = that._dataSource;
  23205. ds.searchExpr(that.option("displayExpr"));
  23206. ds.searchOperation(searchMethod || that.option("searchMode"));
  23207. ds.searchValue(searchValue);
  23208. that._dataSource.pageIndex(0);
  23209. that._dataSource.load().done(function() {
  23210. that._refreshVisibility()
  23211. })
  23212. },
  23213. _refreshVisibility: function() {
  23214. var canFilter = this.option("value").length >= this.option("minSearchLength"),
  23215. dataSource = this._dataSource,
  23216. items = dataSource && dataSource.items(),
  23217. hasResults = items.length;
  23218. if (canFilter && hasResults)
  23219. if (items.length === 1 && this._displayGetter(items[0]) === this.option("value"))
  23220. this._hideDropDown();
  23221. else if (this._displayGetter(items[0]).length < this.option("value").length)
  23222. this._hideDropDown();
  23223. else {
  23224. this._dropDown._refresh();
  23225. this._dropDown.show();
  23226. this._calculatePopupHeight()
  23227. }
  23228. else
  23229. this._hideDropDown()
  23230. },
  23231. _closeOutsideDropDownHandler: function(e, ignoreContainerClicks) {
  23232. this.callBase(e, true)
  23233. },
  23234. _clean: function() {
  23235. this.callBase();
  23236. delete this._dropDown
  23237. },
  23238. _dispose: function() {
  23239. clearTimeout(this._heightApplyingTimer);
  23240. this._clearSearchTimer();
  23241. this.callBase()
  23242. },
  23243. _optionChanged: function(name, value) {
  23244. switch (name) {
  23245. case"items":
  23246. case"dataSource":
  23247. if (name === "items")
  23248. this._itemsToDataSource();
  23249. else
  23250. this._initDataSource();
  23251. case"itemTemplate":
  23252. case"itemRender":
  23253. this._list.option(name, value);
  23254. break;
  23255. case"searchMode":
  23256. this._validateSearchMode();
  23257. break;
  23258. case"displayExpr":
  23259. this._compileDisplayGetter();
  23260. this._list.option("itemRender", this._getItemRender());
  23261. break;
  23262. case"minSearchLength":
  23263. case"searchTimeout":
  23264. break;
  23265. case"shouldActivateFocusOut":
  23266. this._invalidate();
  23267. break;
  23268. default:
  23269. this.callBase.apply(this, arguments)
  23270. }
  23271. },
  23272. _handleValueChangeEvent: function() {
  23273. var prevValue = this.option("value");
  23274. this.callBase.apply(this, arguments);
  23275. if (prevValue !== this.option("value"))
  23276. this._applyFilter()
  23277. },
  23278. _applyFilter: function() {
  23279. var canFilter = this.option("value").length >= this.option("minSearchLength");
  23280. if (!canFilter) {
  23281. this._clearSearchTimer();
  23282. this._hideDropDown();
  23283. return
  23284. }
  23285. if (this.option("searchTimeout") > 0) {
  23286. if (!this._searchTimer)
  23287. this._searchTimer = setTimeout($.proxy(this._filterDataSource, this), this.option("searchTimeout"))
  23288. }
  23289. else
  23290. this._filterDataSource()
  23291. },
  23292. _clearSearchTimer: function() {
  23293. clearTimeout(this._searchTimer);
  23294. delete this._searchTimer
  23295. }
  23296. }).include(ui.DataHelperMixin))
  23297. })(jQuery, DevExpress);
  23298. /*! Module widgets-base, file ui.selectBox.js */
  23299. (function($, DX, undefined) {
  23300. var ui = DX.ui,
  23301. events = ui.events,
  23302. WIDGET_CLASS = "dx-selectbox",
  23303. POPUP_CLASS = "dx-selectbox-popup",
  23304. SELECTBOX_SELECTED_CLASS = "dx-selectbox-selected",
  23305. SELECTBOX_MULTISELECT_CLASS = "dx-selectbox-multiselect",
  23306. SELECTBOX_CONTAINER_CLASS = "dx-selectbox-container",
  23307. SELECTBOX_ARROW_CLASS = "dx-selectbox-arrow",
  23308. SELECTBOX_ARROW_CONTAINER_CLASS = "dx-selectbox-arrow-container",
  23309. SELECTBOX_TAG_CONTAINER_CLASS = "dx-selectbox-tag-container",
  23310. SELECTBOX_TAG_ITEM_CLASS = "dx-selectbox-tag-item",
  23311. SELECTBOX_TAG_ITEM_CONTAINER_CLASS = "dx-selectbox-tag-item-container",
  23312. SELECTBOX_TAG_ITEM_CLOSE_BUTTON_CLASS = "dx-selectbox-tag-item-close-button",
  23313. EMPTY_INPUT_CLASS = "dx-texteditor-empty",
  23314. LIST_ITEM_DATA_KEY = "dxListItemData",
  23315. LIST_ITEM_SELECTOR = ".dx-list-item",
  23316. TEXTEDITOR_BORDER_SELECTOR = ".dx-texteditor-border";
  23317. DX.registerComponent("dxSelectBox", ui.dxAutocomplete.inherit({
  23318. _setDefaultOptions: function() {
  23319. this.callBase();
  23320. this.option({
  23321. items: [],
  23322. value: undefined,
  23323. valueChangeAction: null,
  23324. placeholder: Globalize.localize("Select"),
  23325. valueExpr: null,
  23326. multiSelectEnabled: false,
  23327. values: [],
  23328. valueChangeEvent: "",
  23329. fieldTemplate: null,
  23330. displayValue: undefined,
  23331. tooltipEnabled: false,
  23332. shouldActivateFocusOut: false
  23333. })
  23334. },
  23335. _optionsByReference: function() {
  23336. return $.extend(this.callBase(), {value: true})
  23337. },
  23338. _init: function() {
  23339. this.callBase();
  23340. if (!this._dataSource)
  23341. this._itemsToDataSource();
  23342. this._selectedItems = []
  23343. },
  23344. _itemsToDataSource: function() {
  23345. this._dataSource = new DevExpress.data.DataSource(this.option("items"))
  23346. },
  23347. _getValueWidth: function(value) {
  23348. var $div = $("<div>").html(value).css({
  23349. width: "auto",
  23350. position: "fixed",
  23351. top: "-3000px",
  23352. left: "-3000px"
  23353. }).appendTo("body");
  23354. return $div.width()
  23355. },
  23356. _setTooltip: function(value) {
  23357. if (!this.option("tooltipEnabled"))
  23358. return;
  23359. if (this._$element.context.scrollWidth <= this._getValueWidth(value))
  23360. this._$element.context.title = value;
  23361. else
  23362. this._$element.context.title = ""
  23363. },
  23364. _render: function() {
  23365. this._compileValueGetter();
  23366. this.callBase();
  23367. var value = this.option("value");
  23368. if (value)
  23369. this._searchValue(value).done($.proxy(this._updateTextBox, this));
  23370. else
  23371. this._updateTextBox();
  23372. var multiSelectEnabled = this.option("multiSelectEnabled");
  23373. this._element().toggleClass(SELECTBOX_MULTISELECT_CLASS, multiSelectEnabled);
  23374. this._$placeholder = this._$container.find(".dx-placeholder").eq(0);
  23375. if (multiSelectEnabled)
  23376. this._renderTags();
  23377. this._setWidgetClasses();
  23378. this._setTooltip(this.option("value"));
  23379. this._shouldHide = false
  23380. },
  23381. _renderTags: function() {
  23382. var that = this;
  23383. if (that._$tagContainer)
  23384. that._$tagContainer.remove();
  23385. that._$tagContainer = $("<div>").addClass(SELECTBOX_TAG_CONTAINER_CLASS);
  23386. var values = that.option("values") || [];
  23387. var clickEventName = events.addNamespace("dxclick", that.NAME);
  23388. var itemLoadDeferreds = [];
  23389. that._selectedItems = [];
  23390. $.each(values, function(index, value) {
  23391. var displayValue;
  23392. var $container = $("<div>").addClass(SELECTBOX_TAG_ITEM_CONTAINER_CLASS),
  23393. $tag = $("<div>").addClass(SELECTBOX_TAG_ITEM_CLASS).appendTo($container),
  23394. $close = $("<div>").addClass(SELECTBOX_TAG_ITEM_CLOSE_BUTTON_CLASS).appendTo($container);
  23395. itemLoadDeferreds.push(that._searchValue(value).done(function(result) {
  23396. displayValue = that._displayGetter(result);
  23397. $tag.append(displayValue);
  23398. that._selectedItems.push(result)
  23399. }));
  23400. $close.off(clickEventName).on(clickEventName, $.proxy(that._deleteTag, that));
  23401. $container.appendTo(that._$tagContainer)
  23402. });
  23403. that._$tagContainer.appendTo(that._$container);
  23404. that._element().toggleClass(EMPTY_INPUT_CLASS, !values.length);
  23405. that._input().val(values.length ? " " : null);
  23406. $.when.apply($, itemLoadDeferreds).done(function() {
  23407. that._renderInputTemplate()
  23408. });
  23409. values.length > 0 ? that._$placeholder.hide() : that._$placeholder.show()
  23410. },
  23411. _deleteTag: function(event) {
  23412. event.stopPropagation();
  23413. var $item = $(event.currentTarget.parentElement),
  23414. index = $item.index(),
  23415. values = this.option("values");
  23416. this.option().value = this.option("values")[index];
  23417. values.splice(index, 1);
  23418. this.option("values", values)
  23419. },
  23420. _renderInput: function(inputContainer) {
  23421. this._$container = inputContainer || $("<div>");
  23422. this._$container.addClass(SELECTBOX_CONTAINER_CLASS);
  23423. this._element().append(this._$container);
  23424. this.callBase(this._$container)
  23425. },
  23426. _renderInputTemplate: function() {
  23427. var fieldTemplate = this._getTemplateByOption("fieldTemplate");
  23428. if (this.option("fieldTemplate") && fieldTemplate) {
  23429. this._$container.empty();
  23430. var templateData = this.option("multiSelectEnabled") ? this._selectedItems : this._selectedItem;
  23431. fieldTemplate.render(this._$container, templateData);
  23432. if (!this._input().length)
  23433. DX.utils.logger.warn("A template should contain dxTextBox widget")
  23434. }
  23435. },
  23436. _handleValueChangeEvent: function(e) {
  23437. var args = [e];
  23438. if (!this._input().val())
  23439. args.push(undefined);
  23440. this.callBase.apply(this, args)
  23441. },
  23442. _renderButton: function(hideButton) {
  23443. this.callBase(false)
  23444. },
  23445. _renderValue: function(formattedValue) {
  23446. if (this.option("value") !== undefined) {
  23447. var callBase = $.proxy(this.callBase, this);
  23448. this._searchValue(this.option("value")).done($.proxy(function(result) {
  23449. if (result === undefined)
  23450. result = this.option("value");
  23451. this._selectedItem = result;
  23452. this.option("displayValue", this._displayGetter(result));
  23453. this._setTooltip(result);
  23454. if (this.option("fieldTemaplte"))
  23455. this._renderInputTemplate();
  23456. else
  23457. callBase(this._displayGetter(result))
  23458. }, this))
  23459. }
  23460. else {
  23461. this._selectedItem = null;
  23462. this.option("displayValue", null);
  23463. this._setTooltip(null);
  23464. this.callBase(null)
  23465. }
  23466. },
  23467. _readOnlyPropValue: function() {
  23468. return true
  23469. },
  23470. _createDropDown: function() {
  23471. var that = this;
  23472. this.callBase();
  23473. this._dropDown.beginUpdate();
  23474. if (DX.devices.current().win8) {
  23475. var popupPosition = this._dropDown.option("position");
  23476. $.extend(popupPosition, {
  23477. at: "left top",
  23478. offset: {
  23479. h: 0,
  23480. v: 0
  23481. }
  23482. });
  23483. this._dropDown.option("position", popupPosition)
  23484. }
  23485. this._dropDown.option("closeOnOutsideClick", $.proxy(this._closeOutsideDropDownHandler, this));
  23486. this._dropDown.endUpdate()
  23487. },
  23488. _setWidgetClasses: function() {
  23489. var $selectbox = this._element(),
  23490. $popup = this._dropDown._element();
  23491. $selectbox.addClass(WIDGET_CLASS);
  23492. $popup.addClass(POPUP_CLASS)
  23493. },
  23494. _pointerDownHandler: function() {
  23495. if (this._dropDown.option("visible"))
  23496. this._shouldHide = true
  23497. },
  23498. _clickHandler: function() {
  23499. if (!this._dropDown.option("visible") && !this._shouldHide) {
  23500. if (!this.option("readOnly"))
  23501. this._showDropDown()
  23502. }
  23503. else
  23504. this._shouldHide = false
  23505. },
  23506. _applyFilter: $.noop,
  23507. _updateTextBox: function(result) {
  23508. var that = this,
  23509. clickEventName = events.addNamespace("dxclick", this.NAME),
  23510. pointerDownEventName = events.addNamespace("dxpointerdown", this.NAME);
  23511. this._clickAction = this._createAction(function() {
  23512. that._clickHandler()
  23513. });
  23514. this._selectedItem = result;
  23515. this._renderInputTemplate();
  23516. this._$container.off(clickEventName).off(pointerDownEventName).on(clickEventName, function() {
  23517. that._clickAction()
  23518. }).on(pointerDownEventName, $.proxy(this._pointerDownHandler, this))
  23519. },
  23520. _compileValueGetter: function() {
  23521. this._valueGetter = DX.data.utils.compileGetter(this._valueGetterExpr())
  23522. },
  23523. _valueGetterExpr: function() {
  23524. return this.option("valueExpr") || this._dataSource && this._dataSource._store._key || "this"
  23525. },
  23526. _setSelectedClass: function(item, itemData) {
  23527. itemData = itemData;
  23528. if (this.option("multiSelectEnabled"))
  23529. $.each(this._getSelected(), function() {
  23530. $(this).addClass(SELECTBOX_SELECTED_CLASS)
  23531. });
  23532. else {
  23533. item = item || this._getSelected();
  23534. if (item === null)
  23535. return;
  23536. var selected = itemData !== undefined ? this._optionValuesEqual("value", this._valueGetter(itemData), this.option("value")) : true;
  23537. item.toggleClass(SELECTBOX_SELECTED_CLASS, selected)
  23538. }
  23539. },
  23540. _getSelected: function() {
  23541. var items = [],
  23542. listElement = this._list._element(),
  23543. values = this.option("multiSelectEnabled") ? this.option("values") : [this.option("value")],
  23544. valueGetter = this._valueGetter;
  23545. $.each(this._list.option("items"), function(index, val) {
  23546. if ($.inArray(valueGetter(val), values) !== -1)
  23547. items.push(listElement.find(LIST_ITEM_SELECTOR).eq(index))
  23548. });
  23549. if (!this.option("multiSelectEnabled"))
  23550. return items[0] || null;
  23551. return items
  23552. },
  23553. _removeSelectedClass: function() {
  23554. this._list._element().find("." + SELECTBOX_SELECTED_CLASS).removeClass(SELECTBOX_SELECTED_CLASS)
  23555. },
  23556. _updateSelectedItems: function(item, itemData) {
  23557. this._removeSelectedClass();
  23558. this._setSelectedClass(item, itemData)
  23559. },
  23560. _handleListItemClick: function(e) {
  23561. this._hideDropDown();
  23562. this._shouldHide = false;
  23563. if (this.option("multiSelectEnabled")) {
  23564. this.option().value = this._valueGetter(e.itemData);
  23565. this._addTagValue(this.option("value"))
  23566. }
  23567. else
  23568. this.option("value", this._valueGetter(e.itemData))
  23569. },
  23570. _handleInputEnterKey: function() {
  23571. this.callBase();
  23572. if (this.option("multiSelectEnabled") && this.option("value"))
  23573. this._addTagValue(this.option("value"))
  23574. },
  23575. _selectedItemDataGetter: function() {
  23576. var $selectedItem = this._listSelectedItemElement();
  23577. return $selectedItem.length ? this._valueGetter($selectedItem.data(LIST_ITEM_DATA_KEY)) : []
  23578. },
  23579. _addTagValue: function(value) {
  23580. var values = this.option("values") || [],
  23581. newValues = [];
  23582. if ($.inArray(value, values) === -1) {
  23583. newValues.push.apply(newValues, values);
  23584. newValues.push(value);
  23585. this.option("values", newValues)
  23586. }
  23587. },
  23588. _searchValue: function(value) {
  23589. var valueExpr = this._valueGetterExpr();
  23590. return this._loadSingle(valueExpr, value)
  23591. },
  23592. _changeValueExpr: function() {
  23593. this._compileValueGetter();
  23594. this.option("value", this._valueGetter(this._selectedItem))
  23595. },
  23596. _getSelectedItemClass: function() {
  23597. return SELECTBOX_SELECTED_CLASS
  23598. },
  23599. _getSelectedItemSelector: function() {
  23600. return "." + SELECTBOX_SELECTED_CLASS
  23601. },
  23602. _renderList: function() {
  23603. this.callBase();
  23604. this._list.option({
  23605. autoPagingEnabled: true,
  23606. itemRenderedAction: $.proxy(function(e) {
  23607. this._setSelectedClass(e.itemElement, e.itemData)
  23608. }, this)
  23609. })
  23610. },
  23611. _hideOnBlur: function() {
  23612. return false
  23613. },
  23614. _handleClearValue: function() {
  23615. if (this.option("multiSelectEnabled"))
  23616. this.option("values", []);
  23617. this.option("value", null)
  23618. },
  23619. _optionChanged: function(name, value, previousValue) {
  23620. switch (name) {
  23621. case"value":
  23622. this.callBase.apply(this, arguments);
  23623. this._updateSelectedItems();
  23624. this._renderInputTemplate();
  23625. break;
  23626. case"displayValue":
  23627. break;
  23628. case"tooltipEnabled":
  23629. this._setTooltip(this.option("value"));
  23630. break;
  23631. case"valueExpr":
  23632. this._changeValueExpr();
  23633. break;
  23634. case"displayExpr":
  23635. this._compileDisplayGetter();
  23636. this._refresh();
  23637. break;
  23638. case"fieldTemplate":
  23639. this._renderInputTemplate();
  23640. break;
  23641. case"values":
  23642. if (this.option("multiSelectEnabled")) {
  23643. this._renderTags();
  23644. this._updateSelectedItems();
  23645. this._raiseValueChangeAction(this.option("value"), previousValue, {values: value})
  23646. }
  23647. break;
  23648. case"multiSelectEnabled":
  23649. this._refresh();
  23650. break;
  23651. default:
  23652. this.callBase.apply(this, arguments)
  23653. }
  23654. }
  23655. }))
  23656. })(jQuery, DevExpress);
  23657. /*! Module widgets-base, file ui.multiView.js */
  23658. (function($, DX, undefined) {
  23659. var ui = DX.ui,
  23660. events = ui.events,
  23661. utils = DX.utils,
  23662. fx = DX.fx,
  23663. translator = DX.translator;
  23664. var MULTIVIEW_CLASS = "dx-multiview",
  23665. MULTIVIEW_WRAPPER_CLASS = "dx-multiview-wrapper",
  23666. MULTIVIEW_ITEM_CONTAINER_CLASS = "dx-multiview-item-container",
  23667. MULTIVIEW_ITEM_CLASS = "dx-multiview-item",
  23668. MULTIVIEW_ITEM_HIDDEN_CLASS = "dx-multiview-item-hidden",
  23669. MULTIVIEW_ITEM_DATA_KEY = "dxMultiViewItemData";
  23670. var position = function($element) {
  23671. return translator.locate($element).left
  23672. };
  23673. var move = function($element, position) {
  23674. translator.move($element, {left: position})
  23675. };
  23676. var animation = {
  23677. moveTo: function($element, position, completeAction) {
  23678. fx.animate($element, {
  23679. type: "slide",
  23680. to: {left: position},
  23681. duration: 200,
  23682. complete: completeAction
  23683. })
  23684. },
  23685. complete: function($element) {
  23686. fx.stop($element, true)
  23687. }
  23688. };
  23689. DX.registerComponent("dxMultiView", ui.CollectionContainerWidget.inherit({
  23690. _setDefaultOptions: function() {
  23691. this.callBase();
  23692. this.option({
  23693. selectedIndex: 0,
  23694. swipeEnabled: true,
  23695. animationEnabled: true,
  23696. loop: false
  23697. })
  23698. },
  23699. _itemClass: function() {
  23700. return MULTIVIEW_ITEM_CLASS
  23701. },
  23702. _itemDataKey: function() {
  23703. return MULTIVIEW_ITEM_DATA_KEY
  23704. },
  23705. _itemContainer: function() {
  23706. return this._$itemContainer
  23707. },
  23708. _selectionByClickEnabled: function() {
  23709. return false
  23710. },
  23711. _itemWidth: function() {
  23712. if (!this._itemWidthValue)
  23713. this._itemWidthValue = this._$wrapper.width();
  23714. return this._itemWidthValue
  23715. },
  23716. _clearItemWidthCache: function() {
  23717. delete this._itemWidthValue
  23718. },
  23719. _itemsCount: function() {
  23720. return this.option("items").length
  23721. },
  23722. _normalizeIndex: function(index) {
  23723. var count = this._itemsCount();
  23724. if (index < 0)
  23725. index = index + count;
  23726. if (index >= count)
  23727. index = index - count;
  23728. return index
  23729. },
  23730. _init: function() {
  23731. this.callBase.apply(this, arguments);
  23732. var $element = this._element();
  23733. $element.addClass(MULTIVIEW_CLASS);
  23734. this._$wrapper = $("<div>").addClass(MULTIVIEW_WRAPPER_CLASS);
  23735. this._$wrapper.appendTo($element);
  23736. this._$itemContainer = $("<div>").addClass(MULTIVIEW_ITEM_CONTAINER_CLASS);
  23737. this._$itemContainer.appendTo(this._$wrapper);
  23738. this._initSwipeable()
  23739. },
  23740. _dimensionChanged: function() {
  23741. this._clearItemWidthCache()
  23742. },
  23743. _renderSelectedIndex: function(selectedIndex) {
  23744. this._updateItems(selectedIndex)
  23745. },
  23746. _updateItems: function(selectedIndex, newIndex) {
  23747. this._updateItemsPosition(selectedIndex, newIndex);
  23748. this._updateItemsVisibility(selectedIndex, newIndex)
  23749. },
  23750. _updateItemsVisibility: function(selectedIndex, newIndex) {
  23751. var $itemElements = this._itemElements();
  23752. $itemElements.each(function(itemIndex, item) {
  23753. var $item = $(item),
  23754. isHidden = itemIndex !== selectedIndex && itemIndex !== newIndex;
  23755. $item.toggleClass(MULTIVIEW_ITEM_HIDDEN_CLASS, isHidden)
  23756. })
  23757. },
  23758. _updateItemsPosition: function(selectedIndex, newIndex) {
  23759. var $itemElements = this._itemElements(),
  23760. positionSign = -this._animationDirection(newIndex, selectedIndex);
  23761. move($itemElements.eq(selectedIndex), 0);
  23762. move($itemElements.eq(newIndex), positionSign * 100 + "%")
  23763. },
  23764. _updateSelectedIndex: function(newIndex, prevIndex) {
  23765. animation.complete(this._$itemContainter);
  23766. this._updateItems(prevIndex, newIndex);
  23767. var animationDirection = this._animationDirection(newIndex, prevIndex);
  23768. this._animateItemContainer(animationDirection * this._itemWidth(), $.proxy(function() {
  23769. move(this._$itemContainer, 0);
  23770. this._updateItems(newIndex);
  23771. this._$itemContainer.width()
  23772. }, this))
  23773. },
  23774. _animateItemContainer: function(position, completeCallback) {
  23775. if (this.option("animationEnabled"))
  23776. animation.moveTo(this._$itemContainer, position, completeCallback);
  23777. else
  23778. completeCallback()
  23779. },
  23780. _animationDirection: function(newIndex, prevIndex) {
  23781. var containerPosition = position(this._$itemContainer),
  23782. indexDifference = (prevIndex - newIndex) * this._getRTLSignCorrection(),
  23783. isSwipePresent = containerPosition !== 0,
  23784. directionSignVariable = isSwipePresent ? containerPosition : indexDifference;
  23785. return utils.sign(directionSignVariable)
  23786. },
  23787. _initSwipeable: function() {
  23788. this._element().dxSwipeable({
  23789. disabled: !this.option("swipeEnabled"),
  23790. elastic: false,
  23791. itemSizeFunc: $.proxy(this._itemWidth, this),
  23792. startAction: $.proxy(function(args) {
  23793. this._handleSwipeStart(args.jQueryEvent)
  23794. }, this),
  23795. updateAction: $.proxy(function(args) {
  23796. this._handleSwipeUpdate(args.jQueryEvent)
  23797. }, this),
  23798. endAction: $.proxy(function(args) {
  23799. this._handleSwipeEnd(args.jQueryEvent)
  23800. }, this)
  23801. })
  23802. },
  23803. _handleSwipeStart: function(e) {
  23804. animation.complete(this._$itemContainer);
  23805. var selectedIndex = this.option("selectedIndex"),
  23806. loop = this.option("loop"),
  23807. lastIndex = this._itemsCount() - 1,
  23808. rtl = this.option("rtlEnabled");
  23809. e.maxLeftOffset = loop || (rtl ? selectedIndex > 0 : selectedIndex < lastIndex);
  23810. e.maxRightOffset = loop || (rtl ? selectedIndex < lastIndex : selectedIndex > 0)
  23811. },
  23812. _handleSwipeUpdate: function(e) {
  23813. var offset = e.offset,
  23814. swipeDirection = utils.sign(offset) * this._getRTLSignCorrection();
  23815. move(this._$itemContainer, offset * 100 + "%");
  23816. if (swipeDirection !== this._swipeDirection) {
  23817. this._swipeDirection = swipeDirection;
  23818. var selectedIndex = this.option("selectedIndex"),
  23819. newIndex = this._normalizeIndex(selectedIndex - swipeDirection);
  23820. this._updateItems(selectedIndex, newIndex)
  23821. }
  23822. },
  23823. _handleSwipeEnd: function(e) {
  23824. var targetOffset = e.targetOffset * this._getRTLSignCorrection();
  23825. if (targetOffset)
  23826. this.option("selectedIndex", this._normalizeIndex(this.option("selectedIndex") - targetOffset));
  23827. else
  23828. this._animateItemContainer(0, $.noop);
  23829. delete this._swipeDirection
  23830. },
  23831. _getRTLSignCorrection: function() {
  23832. return this.option("rtlEnabled") ? -1 : 1
  23833. },
  23834. _visibilityChanged: function(visible) {
  23835. if (visible)
  23836. this._clearItemWidthCache()
  23837. },
  23838. _optionChanged: function(name, value, prevValue) {
  23839. switch (name) {
  23840. case"loop":
  23841. case"animationEnabled":
  23842. break;
  23843. case"swipeEnabled":
  23844. this._element().dxSwipeable("option", "disabled", !value);
  23845. break;
  23846. default:
  23847. this.callBase.apply(this, arguments)
  23848. }
  23849. }
  23850. }));
  23851. ui.dxMultiView.__internals = {animation: animation}
  23852. })(jQuery, DevExpress);
  23853. DevExpress.MOD_WIDGETS_BASE = true
  23854. }
  23855. if (!DevExpress.MOD_WIDGETS_MOBILE) {
  23856. if (!DevExpress.MOD_WIDGETS_BASE)
  23857. throw Error('Required module is not referenced: widgets-base');
  23858. /*! Module widgets-mobile, file ui.switch.js */
  23859. (function($, DX, undefined) {
  23860. var ui = DX.ui,
  23861. events = ui.events,
  23862. fx = DX.fx;
  23863. var SWITCH_CLASS = "dx-switch",
  23864. SWITCH_WRAPPER_CLASS = SWITCH_CLASS + "-wrapper",
  23865. SWITCH_CONTAINER_CLASS = SWITCH_CLASS + "-container",
  23866. SWITCH_INNER_CLASS = SWITCH_CLASS + "-inner",
  23867. SWITCH_HANDLE_CLASS = SWITCH_CLASS + "-handle",
  23868. SWITCH_ON_VALUE_CLASS = SWITCH_CLASS + "-on-value",
  23869. SWITCH_ON_CLASS = SWITCH_CLASS + "-on",
  23870. SWITCH_OFF_CLASS = SWITCH_CLASS + "-off",
  23871. SWITCH_ANIMATION_DURATION = 100;
  23872. DX.registerComponent("dxSwitch", ui.dxEditor.inherit({
  23873. _setDefaultOptions: function() {
  23874. this.callBase();
  23875. this.option({
  23876. hoverStateEnabled: true,
  23877. onText: Globalize.localize("dxSwitch-onText"),
  23878. offText: Globalize.localize("dxSwitch-offText"),
  23879. value: false
  23880. })
  23881. },
  23882. _init: function() {
  23883. this.callBase();
  23884. this._animating = false;
  23885. this._animationDuration = SWITCH_ANIMATION_DURATION
  23886. },
  23887. _recreateValueChangeAction: function() {
  23888. this._valueChangeAction = this._createActionByOption("valueChangeAction", {excludeValidators: ["gesture"]})
  23889. },
  23890. _render: function() {
  23891. var element = this._element();
  23892. this._$switchInner = $("<div>").addClass(SWITCH_INNER_CLASS);
  23893. this._$handle = $("<div>").addClass(SWITCH_HANDLE_CLASS).appendTo(this._$switchInner);
  23894. this._$labelOn = $("<div>").addClass(SWITCH_ON_CLASS).prependTo(this._$switchInner);
  23895. this._$labelOff = $("<div>").addClass(SWITCH_OFF_CLASS).appendTo(this._$switchInner);
  23896. this._$switchContainer = $("<div>").addClass(SWITCH_CONTAINER_CLASS).append(this._$switchInner);
  23897. this._$switchWrapper = $("<div>").addClass(SWITCH_WRAPPER_CLASS).append(this._$switchContainer);
  23898. element.addClass(SWITCH_CLASS).append(this._$switchWrapper);
  23899. element.dxSwipeable({
  23900. elastic: false,
  23901. startAction: $.proxy(this._handleSwipeStart, this),
  23902. updateAction: $.proxy(this._handleSwipeUpdate, this),
  23903. endAction: $.proxy(this._handleSwipeEnd, this)
  23904. });
  23905. this._renderLabels();
  23906. this.callBase();
  23907. this._updateMarginBound();
  23908. this._renderValue();
  23909. this._renderClick()
  23910. },
  23911. _updateMarginBound: function() {
  23912. this._marginBound = this._$switchContainer.outerWidth(true) - this._$handle.outerWidth()
  23913. },
  23914. _marginDirection: function() {
  23915. return this.option("rtlEnabled") ? "Right" : "Left"
  23916. },
  23917. _offsetDirection: function() {
  23918. return this.option("rtlEnabled") ? -1 : 1
  23919. },
  23920. _renderPosition: function(state, swipeOffset) {
  23921. var stateInt = state ? 1 : 0,
  23922. marginDirection = this._marginDirection(),
  23923. resetMarginDirection = marginDirection === "Left" ? "Right" : "Left";
  23924. this._$switchInner.css("margin" + marginDirection, this._marginBound * (stateInt + swipeOffset - 1));
  23925. this._$switchInner.css("margin" + resetMarginDirection, 0)
  23926. },
  23927. _validateValue: function() {
  23928. var check = this.option("value");
  23929. if (typeof check !== "boolean")
  23930. this._options["value"] = !!check
  23931. },
  23932. _renderClick: function() {
  23933. var eventName = events.addNamespace("dxclick", this.NAME),
  23934. clickAction = this._createAction($.proxy(this._handleClick, this));
  23935. this._element().off(eventName).on(eventName, function(e) {
  23936. clickAction({jQueryEvent: e})
  23937. })
  23938. },
  23939. _handleClick: function(args) {
  23940. var e = args.jQueryEvent;
  23941. this._valueChangeEventInstance = e;
  23942. if (this._animating || this._swiping)
  23943. return;
  23944. this._animating = true;
  23945. var that = this,
  23946. startValue = this.option("value"),
  23947. endValue = !startValue,
  23948. marginDirection = this._marginDirection(),
  23949. resetMarginDirection = marginDirection === "Left" ? "Right" : "Left",
  23950. fromConfig = {},
  23951. toConfig = {};
  23952. this._$switchInner.css("margin" + resetMarginDirection, 0);
  23953. fromConfig["margin" + marginDirection] = (Number(startValue) - 1) * this._marginBound;
  23954. toConfig["margin" + marginDirection] = (Number(endValue) - 1) * this._marginBound;
  23955. fx.animate(this._$switchInner, {
  23956. from: fromConfig,
  23957. to: toConfig,
  23958. duration: this._animationDuration,
  23959. complete: function() {
  23960. that._animating = false;
  23961. that.option("value", endValue)
  23962. }
  23963. })
  23964. },
  23965. _handleSwipeStart: function(e) {
  23966. var state = this.option("value"),
  23967. rtlEnabled = this.option("rtlEnabled"),
  23968. maxOffOffset = rtlEnabled ? 0 : 1,
  23969. maxOnOffset = rtlEnabled ? 1 : 0;
  23970. e.jQueryEvent.maxLeftOffset = state ? maxOffOffset : maxOnOffset;
  23971. e.jQueryEvent.maxRightOffset = state ? maxOnOffset : maxOffOffset;
  23972. this._swiping = true;
  23973. this._feedbackShow(this._element())
  23974. },
  23975. _handleSwipeUpdate: function(e) {
  23976. this._renderPosition(this.option("value"), this._offsetDirection() * e.jQueryEvent.offset)
  23977. },
  23978. _handleSwipeEnd: function(e) {
  23979. var that = this,
  23980. offsetDirection = this._offsetDirection(),
  23981. toConfig = {};
  23982. toConfig["margin" + this._marginDirection()] = this._marginBound * (that.option("value") + offsetDirection * e.jQueryEvent.targetOffset - 1);
  23983. fx.animate(this._$switchInner, {
  23984. to: toConfig,
  23985. duration: that._animationDuration,
  23986. complete: function() {
  23987. that._swiping = false;
  23988. var pos = that.option("value") + offsetDirection * e.jQueryEvent.targetOffset;
  23989. that.option("value", Boolean(pos));
  23990. that._feedbackOff()
  23991. }
  23992. })
  23993. },
  23994. _renderValue: function() {
  23995. this._validateValue();
  23996. var val = this.option("value");
  23997. this._renderPosition(val, 0);
  23998. this._element().toggleClass(SWITCH_ON_VALUE_CLASS, val)
  23999. },
  24000. _renderLabels: function() {
  24001. this._$labelOn.text(this.option("onText"));
  24002. this._$labelOff.text(this.option("offText"))
  24003. },
  24004. _visibilityChanged: function(visible) {
  24005. if (visible)
  24006. this.repaint()
  24007. },
  24008. _feedbackOff: function() {
  24009. if (this._swiping) {
  24010. this._clearTimers();
  24011. return
  24012. }
  24013. this.callBase.apply(this, arguments)
  24014. },
  24015. _optionChanged: function(name, value, prevValue) {
  24016. switch (name) {
  24017. case"visible":
  24018. case"width":
  24019. this._refresh();
  24020. break;
  24021. case"onText":
  24022. case"offText":
  24023. this._renderLabels();
  24024. break;
  24025. case"value":
  24026. this._renderValue();
  24027. this.callBase(name, value, prevValue);
  24028. break;
  24029. default:
  24030. this.callBase(name, value, prevValue)
  24031. }
  24032. }
  24033. }))
  24034. })(jQuery, DevExpress);
  24035. /*! Module widgets-mobile, file ui.pivotTabs.js */
  24036. (function($, DX, undefined) {
  24037. var ui = DX.ui,
  24038. fx = DX.fx,
  24039. utils = DX.utils,
  24040. translator = DX.translator,
  24041. events = ui.events;
  24042. var PIVOT_TABS_CLASS = "dx-pivottabs",
  24043. PIVOT_TAB_CLASS = "dx-pivottabs-tab",
  24044. PIVOT_TAB_SELECTED_CLASS = "dx-pivottabs-tab-selected",
  24045. PIVOT_GHOST_TAB_CLASS = "dx-pivottabs-ghosttab",
  24046. PIVOT_TAB_DATA_KEY = "dxPivotTabData",
  24047. PIVOT_TAB_MOVE_DURATION = 200,
  24048. PIVOT_TAB_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)";
  24049. var animation = {
  24050. moveTo: function($tab, position, completeAction) {
  24051. return fx.animate($tab, {
  24052. type: "slide",
  24053. to: {left: position},
  24054. duration: PIVOT_TAB_MOVE_DURATION,
  24055. easing: PIVOT_TAB_MOVE_EASING,
  24056. complete: completeAction
  24057. })
  24058. },
  24059. slideAppear: function($tab, position) {
  24060. return fx.animate($tab, {
  24061. type: "slide",
  24062. to: {
  24063. left: position,
  24064. opacity: 1
  24065. },
  24066. duration: PIVOT_TAB_MOVE_DURATION,
  24067. easing: PIVOT_TAB_MOVE_EASING
  24068. })
  24069. },
  24070. slideDisappear: function($tab, position) {
  24071. return fx.animate($tab, {
  24072. type: "slide",
  24073. to: {
  24074. left: position,
  24075. opacity: 0
  24076. },
  24077. duration: PIVOT_TAB_MOVE_DURATION,
  24078. easing: PIVOT_TAB_MOVE_EASING
  24079. })
  24080. },
  24081. complete: function(elements) {
  24082. if (!elements)
  24083. return;
  24084. $.each(elements, function(_, $element) {
  24085. fx.stop($element, true)
  24086. })
  24087. },
  24088. stop: function(elements) {
  24089. if (!elements)
  24090. return;
  24091. $.each(elements, function(_, $element) {
  24092. fx.stop($element)
  24093. })
  24094. }
  24095. };
  24096. DX.registerComponent("dxPivotTabs", ui.CollectionContainerWidget.inherit({
  24097. _setDefaultOptions: function() {
  24098. this.callBase();
  24099. this.option({
  24100. selectedIndex: 0,
  24101. prepareAction: null,
  24102. updatePositionAction: null,
  24103. rollbackAction: null
  24104. })
  24105. },
  24106. _itemClass: function() {
  24107. return PIVOT_TAB_CLASS
  24108. },
  24109. _itemDataKey: function() {
  24110. return PIVOT_TAB_DATA_KEY
  24111. },
  24112. _itemContainer: function() {
  24113. return this._element()
  24114. },
  24115. _elementWidth: function() {
  24116. if (!this._elementWidthCache)
  24117. this._elementWidthCache = this._element().width();
  24118. return this._elementWidthCache
  24119. },
  24120. _clearElementWidthCache: function() {
  24121. delete this._elementWidthCache
  24122. },
  24123. _itemWidths: function() {
  24124. if (!this._itemWidthsCache) {
  24125. var $tabs = this._itemElements(),
  24126. widths = [];
  24127. $tabs.each(function() {
  24128. widths.push($(this).outerWidth())
  24129. });
  24130. this._itemWidthsCache = widths
  24131. }
  24132. return this._itemWidthsCache
  24133. },
  24134. _init: function() {
  24135. this.callBase();
  24136. this._initGhostTab();
  24137. this._initSwipeHandlers();
  24138. this._initActions()
  24139. },
  24140. _dimensionChanged: function() {
  24141. this._clearElementWidthCache();
  24142. this._cleanPositionCache();
  24143. this._updateTabsPositions()
  24144. },
  24145. _initGhostTab: function() {
  24146. this._$ghostTab = $("<div>").addClass(PIVOT_GHOST_TAB_CLASS)
  24147. },
  24148. _initActions: function() {
  24149. var excludeValidators = {excludeValidators: ["gesture"]};
  24150. this._updatePositionAction = this._createActionByOption("updatePositionAction", excludeValidators);
  24151. this._rollbackAction = this._createActionByOption("rollbackAction", excludeValidators);
  24152. this._prepareAction = this._createActionByOption("prepareAction", excludeValidators)
  24153. },
  24154. _render: function() {
  24155. this._element().addClass(PIVOT_TABS_CLASS);
  24156. this.callBase();
  24157. this._renderGhostTab()
  24158. },
  24159. _renderGhostTab: function() {
  24160. this._itemContainer().append(this._$ghostTab);
  24161. this._toggleGhostTab(false)
  24162. },
  24163. _toggleGhostTab: function(visible) {
  24164. var $ghostTab = this._$ghostTab;
  24165. if (visible) {
  24166. this._updateGhostTabContent();
  24167. $ghostTab.css("opacity", 1)
  24168. }
  24169. else
  24170. $ghostTab.css("opacity", 0)
  24171. },
  24172. _isGhostTabVisible: function() {
  24173. return this._$ghostTab.css("opacity") == 1
  24174. },
  24175. _updateGhostTabContent: function(prevIndex) {
  24176. prevIndex = prevIndex === undefined ? this._previousIndex() : prevIndex;
  24177. var $ghostTab = this._$ghostTab,
  24178. $items = this._itemElements();
  24179. $ghostTab.html($items.eq(prevIndex).html())
  24180. },
  24181. _updateTabsPositions: function(offset) {
  24182. var $tabs = this._allTabElements(),
  24183. offset = this._applyOffsetBoundaries(offset),
  24184. isPrevSwipeHandled = this.option("rtlEnabled") ^ offset > 0 && offset !== 0,
  24185. tabPositions = this._calculateTabPositions(isPrevSwipeHandled ? "replace" : "append");
  24186. this._moveTabs(tabPositions, offset);
  24187. this._toggleGhostTab(isPrevSwipeHandled)
  24188. },
  24189. _moveTabs: function(positions, offset) {
  24190. offset = offset || 0;
  24191. var $tabs = this._allTabElements();
  24192. $tabs.each(function(index) {
  24193. translator.move($(this), {left: positions[index] + offset})
  24194. })
  24195. },
  24196. _applyOffsetBoundaries: function(offset) {
  24197. offset = offset || 0;
  24198. var maxOffset = offset > 0 ? this._maxRightOffset : this._maxLeftOffset;
  24199. return offset * maxOffset
  24200. },
  24201. _animateRollback: function() {
  24202. var that = this,
  24203. $tabs = this._itemElements(),
  24204. positions = this._calculateTabPositions("prepend");
  24205. if (this._isGhostTabVisible()) {
  24206. this._swapGhostWithTab($tabs.eq(this._previousIndex()));
  24207. animation.moveTo(this._$ghostTab, positions[this._indexBoundary()], function() {
  24208. that._toggleGhostTab(false)
  24209. })
  24210. }
  24211. $tabs.each(function(index) {
  24212. animation.moveTo($(this), positions[index])
  24213. })
  24214. },
  24215. _animateComplete: function(newIndex, currentIndex) {
  24216. var that = this,
  24217. $tabs = this._itemElements(),
  24218. isPrevSwipeHandled = this._isGhostTabVisible();
  24219. $tabs.eq(currentIndex).removeClass(PIVOT_TAB_SELECTED_CLASS);
  24220. var animations = isPrevSwipeHandled ? this._animateIndexDecreasing(newIndex) : this._animateIndexIncreasing(newIndex);
  24221. $tabs.eq(newIndex).addClass(PIVOT_TAB_SELECTED_CLASS)
  24222. },
  24223. _animateIndexDecreasing: function(newIndex) {
  24224. var $tabs = this._itemElements(),
  24225. positions = this._calculateTabPositions("append", newIndex),
  24226. animations = [];
  24227. $tabs.each(function(index) {
  24228. animations.push(animation.moveTo($(this), positions[index]))
  24229. });
  24230. animations.push(animation.slideDisappear(this._$ghostTab, positions[this._indexBoundary()]));
  24231. return $.when.apply($, animations)
  24232. },
  24233. _animateIndexIncreasing: function(newIndex) {
  24234. var that = this,
  24235. $tabs = this._itemElements(),
  24236. positions = this._calculateTabPositions("prepend", newIndex),
  24237. previousIndex = this._previousIndex(newIndex),
  24238. $prevTab = $tabs.eq(previousIndex),
  24239. prevTabPosition = translator.locate($prevTab).left,
  24240. rtl = this.option("rtlEnabled"),
  24241. bound = rtl ? this._elementWidth() - this._itemWidths()[previousIndex] : 0,
  24242. isNextSwipeHandled = (prevTabPosition - bound) * this._getRTLSignCorrection() < 0,
  24243. animations = [];
  24244. if (!isNextSwipeHandled)
  24245. this._moveTabs(this._calculateTabPositions("append", previousIndex));
  24246. this._updateGhostTabContent(previousIndex);
  24247. this._swapGhostWithTab($tabs.eq(previousIndex));
  24248. $tabs.each(function(index) {
  24249. var $tab = $(this),
  24250. newPosition = positions[index];
  24251. animations.push(index === previousIndex ? animation.slideAppear($tab, newPosition) : animation.moveTo($tab, newPosition))
  24252. });
  24253. animations.push(animation.moveTo(this._$ghostTab, positions[this._indexBoundary()], function() {
  24254. that._toggleGhostTab(false)
  24255. }));
  24256. return $.when.apply($, animations)
  24257. },
  24258. _swapGhostWithTab: function($tab) {
  24259. var $ghostTab = this._$ghostTab,
  24260. lastTabPosition = translator.locate($tab).left,
  24261. lastTabOpacity = $tab.css("opacity");
  24262. translator.move($tab, {left: translator.locate($ghostTab).left});
  24263. $tab.css("opacity", $ghostTab.css("opacity"));
  24264. translator.move($ghostTab, {left: lastTabPosition});
  24265. $ghostTab.css("opacity", lastTabOpacity)
  24266. },
  24267. _calculateTabPositions: function(ghostPosition, index) {
  24268. index = index === undefined ? this.option("selectedIndex") : index;
  24269. var mark = index + ghostPosition;
  24270. if (this._calculetedPositionsMark !== mark) {
  24271. this._calculetedPositions = this._calculateTabPositionsImpl(index, ghostPosition);
  24272. this._calculetedPositionsMark = mark
  24273. }
  24274. return this._calculetedPositions
  24275. },
  24276. _calculateTabPositionsImpl: function(currentIndex, ghostPosition) {
  24277. var prevIndex = this._normalizeIndex(currentIndex - 1),
  24278. $tabs = this._itemElements(),
  24279. widths = this._itemWidths();
  24280. var rtl = this.option("rtlEnabled"),
  24281. signCorrection = this._getRTLSignCorrection(),
  24282. tabsContainerWidth = this._elementWidth(),
  24283. nextPosition = rtl ? tabsContainerWidth : 0,
  24284. positions = [];
  24285. var calculateTabPosition = function(currentIndex, width) {
  24286. var rtlOffset = rtl * width;
  24287. positions.splice(currentIndex, 0, nextPosition - rtlOffset);
  24288. nextPosition += width * signCorrection
  24289. };
  24290. $.each(widths.slice(currentIndex), calculateTabPosition);
  24291. $.each(widths.slice(0, currentIndex), calculateTabPosition);
  24292. switch (ghostPosition) {
  24293. case"replace":
  24294. var lastTabPosition = positions[prevIndex];
  24295. positions.splice(prevIndex, 1, rtl ? tabsContainerWidth : -widths[prevIndex]);
  24296. positions.push(lastTabPosition);
  24297. break;
  24298. case"prepend":
  24299. positions.push(rtl ? tabsContainerWidth : -widths[prevIndex]);
  24300. break;
  24301. case"append":
  24302. positions.push(nextPosition - widths[currentIndex] * rtl);
  24303. break
  24304. }
  24305. return positions
  24306. },
  24307. _allTabElements: function() {
  24308. return this._itemContainer().find("." + PIVOT_TAB_CLASS + ", ." + PIVOT_GHOST_TAB_CLASS)
  24309. },
  24310. _initSwipeHandlers: function() {
  24311. this._element().on(events.addNamespace("dxswipestart", this.NAME), {itemSizeFunc: $.proxy(this._elementWidth, this)}, $.proxy(this._swipeStartHandler, this)).on(events.addNamespace("dxswipe", this.NAME), $.proxy(this._swipeUpdateHandler, this)).on(events.addNamespace("dxswipeend", this.NAME), $.proxy(this._swipeEndHandler, this))
  24312. },
  24313. _swipeStartHandler: function(e) {
  24314. this._prepareAnimation();
  24315. this._prepareAction();
  24316. e.maxLeftOffset = 1;
  24317. e.maxRightOffset = 1;
  24318. if (DX.designMode || this.option("disabled") || this._indexBoundary() <= 1)
  24319. e.cancel = true;
  24320. else
  24321. this._swipeGestureRunning = true
  24322. },
  24323. _prepareAnimation: function() {
  24324. this._stopAnimation()
  24325. },
  24326. _stopAnimation: function() {
  24327. animation.complete(this._allTabElements())
  24328. },
  24329. _swipeUpdateHandler: function(e) {
  24330. var offset = e.offset;
  24331. this._updateTabsPositions(offset);
  24332. this._updatePositionAction({offset: offset})
  24333. },
  24334. _swipeEndHandler: function(e) {
  24335. var targetOffset = e.targetOffset * this._getRTLSignCorrection();
  24336. if (targetOffset === 0) {
  24337. this._animateRollback();
  24338. this._rollbackAction()
  24339. }
  24340. else {
  24341. var newIndex = this._normalizeIndex(this.option("selectedIndex") - targetOffset);
  24342. this.option("selectedIndex", newIndex)
  24343. }
  24344. this._swipeGestureRunning = false
  24345. },
  24346. _previousIndex: function(atIndex) {
  24347. atIndex = atIndex === undefined ? this.option("selectedIndex") : atIndex;
  24348. return this._normalizeIndex(atIndex - 1)
  24349. },
  24350. _normalizeIndex: function(index) {
  24351. var boundary = this._indexBoundary();
  24352. if (index < 0)
  24353. index = boundary + index;
  24354. if (index >= boundary)
  24355. index = index - boundary;
  24356. return index
  24357. },
  24358. _indexBoundary: function() {
  24359. return this.option("items").length
  24360. },
  24361. _renderSelectedIndex: function(current) {
  24362. this._calculateMaxOffsets(current);
  24363. this._updateTabsPositions();
  24364. this._itemElements().eq(current).addClass(PIVOT_TAB_SELECTED_CLASS)
  24365. },
  24366. _updateSelectedIndex: function(current) {
  24367. this._calculateMaxOffsets(current)
  24368. },
  24369. _calculateMaxOffsets: function(index) {
  24370. var $tabs = this._itemElements(),
  24371. currentTabWidth = this._itemWidths()[index],
  24372. prevTabWidth = this._itemWidths()[this._previousIndex(index)],
  24373. rtl = this.option("rtlEnabled");
  24374. this._maxLeftOffset = rtl ? prevTabWidth : currentTabWidth;
  24375. this._maxRightOffset = rtl ? currentTabWidth : prevTabWidth
  24376. },
  24377. _itemRenderDefault: function(item, index, $itemElement) {
  24378. var $itemText = $("<span>").text(item.title);
  24379. $itemElement.html($itemText)
  24380. },
  24381. _getRTLSignCorrection: function() {
  24382. return this.option("rtlEnabled") ? -1 : 1
  24383. },
  24384. _visibilityChanged: function(visible) {
  24385. if (visible)
  24386. this._dimensionChanged()
  24387. },
  24388. _clean: function() {
  24389. animation.stop(this._allTabElements());
  24390. this._clearElementWidthCache();
  24391. this._cleanPositionCache();
  24392. this.callBase()
  24393. },
  24394. _cleanPositionCache: function() {
  24395. delete this._itemWidthsCache;
  24396. delete this._calculetedPositionsMark
  24397. },
  24398. _optionChanged: function(name, value, prevValue) {
  24399. switch (name) {
  24400. case"selectedIndex":
  24401. if (!this._swipeGestureRunning)
  24402. this._prepareAnimation();
  24403. if (this._itemElements().length)
  24404. this._animateComplete(value, prevValue);
  24405. this.callBase.apply(this, arguments);
  24406. break;
  24407. case"items":
  24408. case"rtlEnabled":
  24409. this._cleanPositionCache();
  24410. this.callBase.apply(this, arguments);
  24411. break;
  24412. case"prepareAction":
  24413. case"updatePositionAction":
  24414. case"rollbackAction":
  24415. this._initActions();
  24416. break;
  24417. default:
  24418. this.callBase.apply(this, arguments)
  24419. }
  24420. },
  24421. prepare: function() {
  24422. this._prepareAnimation()
  24423. },
  24424. updatePosition: function(offset) {
  24425. this._updateTabsPositions(offset)
  24426. },
  24427. rollback: function() {
  24428. this._animateRollback()
  24429. }
  24430. }));
  24431. ui.dxPivotTabs.__internals = {animation: animation}
  24432. })(jQuery, DevExpress);
  24433. /*! Module widgets-mobile, file ui.pivot.js */
  24434. (function($, DX, undefined) {
  24435. var ui = DX.ui,
  24436. events = ui.events,
  24437. fx = DX.fx,
  24438. translator = DX.translator;
  24439. var PIVOT_CLASS = "dx-pivot",
  24440. PIVOT_WRAPPER_CLASS = "dx-pivot-wrapper",
  24441. PIVOT_TABS_CONTAINER_CLASS = "dx-pivottabs-container",
  24442. PIVOT_ITEM_CONTAINER_CLASS = "dx-pivot-itemcontainer",
  24443. PIVOT_ITEM_WRAPPER_CLASS = "dx-pivot-itemwrapper",
  24444. PIVOT_ITEM_CLASS = "dx-pivot-item",
  24445. PIVOT_ITEM_HIDDEN_CLASS = "dx-pivot-item-hidden",
  24446. PIVOT_ITEM_DATA_KEY = "dxPivotItemData",
  24447. PIVOT_RETURN_BACK_DURATION = 200,
  24448. PIVOT_SLIDE_AWAY_DURATION = 50,
  24449. PIVOT_SLIDE_BACK_DURATION = 250,
  24450. PIVOT_SLIDE_BACK_EASING = "cubic-bezier(.10, 1, 0, 1)";
  24451. var animation = {
  24452. returnBack: function($element) {
  24453. fx.animate($element, {
  24454. type: "slide",
  24455. to: {left: 0},
  24456. duration: PIVOT_RETURN_BACK_DURATION
  24457. })
  24458. },
  24459. slideAway: function($element, position, completeAction) {
  24460. fx.animate($element, {
  24461. type: "slide",
  24462. to: {left: position},
  24463. duration: PIVOT_SLIDE_AWAY_DURATION,
  24464. complete: completeAction
  24465. })
  24466. },
  24467. slideBack: function($element) {
  24468. fx.animate($element, {
  24469. type: "slide",
  24470. to: {left: 0},
  24471. easing: PIVOT_SLIDE_BACK_EASING,
  24472. duration: PIVOT_SLIDE_BACK_DURATION
  24473. })
  24474. },
  24475. complete: function($element) {
  24476. fx.stop($element, true)
  24477. },
  24478. stop: function($element) {
  24479. fx.stop($element)
  24480. }
  24481. };
  24482. DX.registerComponent("dxPivot", ui.CollectionContainerWidget.inherit({
  24483. _setDefaultOptions: function() {
  24484. this.callBase();
  24485. this.option({selectedIndex: 0})
  24486. },
  24487. _itemClass: function() {
  24488. return PIVOT_ITEM_CLASS
  24489. },
  24490. _itemDataKey: function() {
  24491. return PIVOT_ITEM_DATA_KEY
  24492. },
  24493. _itemContainer: function() {
  24494. return this._$itemWrapper
  24495. },
  24496. _elementWidth: function() {
  24497. if (!this._elementWidthCache)
  24498. this._elementWidthCache = this._element().width();
  24499. return this._elementWidthCache
  24500. },
  24501. _clearElementWidthCache: function() {
  24502. delete this._elementWidthCache
  24503. },
  24504. _init: function() {
  24505. this.callBase();
  24506. this._initWrapper();
  24507. this._initTabs();
  24508. this._initItemContainer();
  24509. this._clearItemsCache();
  24510. this._initSwipeHandlers()
  24511. },
  24512. _dimensionChanged: function() {
  24513. this._clearElementWidthCache()
  24514. },
  24515. _initWrapper: function() {
  24516. this._$wrapper = $("<div>").addClass(PIVOT_WRAPPER_CLASS).appendTo(this._element())
  24517. },
  24518. _initItemContainer: function() {
  24519. var $itemContainer = $("<div>").addClass(PIVOT_ITEM_CONTAINER_CLASS);
  24520. this._$wrapper.append($itemContainer);
  24521. this._$itemWrapper = $("<div>").addClass(PIVOT_ITEM_WRAPPER_CLASS);
  24522. $itemContainer.append(this._$itemWrapper)
  24523. },
  24524. _clearItemsCache: function() {
  24525. this._itemsCache = []
  24526. },
  24527. _initTabs: function() {
  24528. var that = this,
  24529. $tabsContainer = $("<div>").addClass(PIVOT_TABS_CONTAINER_CLASS);
  24530. this._$wrapper.append($tabsContainer);
  24531. $tabsContainer.dxPivotTabs({
  24532. items: this.option("items"),
  24533. selectedIndex: this.option("selectedIndex"),
  24534. prepareAction: function() {
  24535. that._prepareAnimation()
  24536. },
  24537. updatePositionAction: function(args) {
  24538. that._updateContentPosition(args.offset)
  24539. },
  24540. rollbackAction: function() {
  24541. that._animateRollback()
  24542. },
  24543. itemSelectAction: function(args) {
  24544. that.option("selectedIndex", args.selectedIndex)
  24545. }
  24546. });
  24547. this._tabs = $tabsContainer.dxPivotTabs("instance")
  24548. },
  24549. _render: function() {
  24550. this._element().addClass(PIVOT_CLASS);
  24551. this.callBase()
  24552. },
  24553. _renderCurrentContent: function(currentIndex, previousIndex) {
  24554. var itemsCache = this._itemsCache;
  24555. itemsCache[previousIndex] = this._selectedItemElement();
  24556. itemsCache[previousIndex].addClass(PIVOT_ITEM_HIDDEN_CLASS);
  24557. if (itemsCache[currentIndex])
  24558. itemsCache[currentIndex].removeClass(PIVOT_ITEM_HIDDEN_CLASS);
  24559. else
  24560. this._renderContent();
  24561. this._fireSelectItemEvent(currentIndex, previousIndex)
  24562. },
  24563. _updateContentPosition: function(offset) {
  24564. translator.move(this._$itemWrapper, {left: this._calculatePixelOffset(offset)})
  24565. },
  24566. _animateRollback: function() {
  24567. animation.returnBack(this._$itemWrapper)
  24568. },
  24569. _animateComplete: function(newIndex, currentIndex) {
  24570. var $itemWrapper = this._$itemWrapper,
  24571. rtlSignCorrection = this._getRTLSignCorrection(),
  24572. intermediatePosition = this._elementWidth() * (this._isPrevSwipeHandled() ? 1 : -1) * rtlSignCorrection;
  24573. animation.slideAway($itemWrapper, intermediatePosition, $.proxy(function() {
  24574. translator.move($itemWrapper, {left: -intermediatePosition});
  24575. this._renderCurrentContent(newIndex, currentIndex)
  24576. }, this));
  24577. animation.slideBack($itemWrapper)
  24578. },
  24579. _calculatePixelOffset: function(offset) {
  24580. offset = offset || 0;
  24581. return offset * this._elementWidth()
  24582. },
  24583. _isPrevSwipeHandled: function() {
  24584. var wrapperOffset = translator.locate(this._$itemWrapper).left,
  24585. rtl = this.option("rtlEnabled");
  24586. return rtl ^ wrapperOffset > 0 && wrapperOffset !== 0
  24587. },
  24588. _initSwipeHandlers: function() {
  24589. this._element().on(events.addNamespace("dxswipestart", this.NAME), {itemSizeFunc: $.proxy(this._elementWidth, this)}, $.proxy(this._swipeStartHandler, this)).on(events.addNamespace("dxswipe", this.NAME), $.proxy(this._swipeUpdateHandler, this)).on(events.addNamespace("dxswipeend", this.NAME), $.proxy(this._swipeEndHandler, this))
  24590. },
  24591. _swipeStartHandler: function(e) {
  24592. this._prepareAnimation();
  24593. this._tabs.prepare();
  24594. if (DX.designMode || this.option("disabled") || this._indexBoundary() <= 1)
  24595. e.cancel = true;
  24596. else
  24597. this._swipeGestureRunning = true;
  24598. e.maxLeftOffset = 1;
  24599. e.maxRightOffset = 1
  24600. },
  24601. _prepareAnimation: function() {
  24602. this._stopAnimation()
  24603. },
  24604. _stopAnimation: function() {
  24605. animation.complete(this._$itemWrapper)
  24606. },
  24607. _swipeUpdateHandler: function(e) {
  24608. var offset = e.offset;
  24609. this._updateContentPosition(offset);
  24610. this._tabs.updatePosition(offset)
  24611. },
  24612. _swipeEndHandler: function(e) {
  24613. var targetOffset = e.targetOffset * this._getRTLSignCorrection();
  24614. if (targetOffset === 0) {
  24615. this._animateRollback();
  24616. this._tabs.rollback()
  24617. }
  24618. else {
  24619. var newIndex = this._normalizeIndex(this.option("selectedIndex") - targetOffset);
  24620. this.option("selectedIndex", newIndex)
  24621. }
  24622. this._swipeGestureRunning = false
  24623. },
  24624. _renderSelectedIndex: $.noop,
  24625. _normalizeIndex: function(index) {
  24626. var boundary = this._indexBoundary();
  24627. if (index < 0)
  24628. index = boundary + index;
  24629. if (index >= boundary)
  24630. index = index - boundary;
  24631. return index
  24632. },
  24633. _indexBoundary: function() {
  24634. return this.option("items").length
  24635. },
  24636. _renderContentImpl: function() {
  24637. var items = this.option("items"),
  24638. selectedIndex = this.option("selectedIndex");
  24639. if (items.length)
  24640. this._renderItems([items[selectedIndex]])
  24641. },
  24642. _selectedItemElement: function() {
  24643. return this._$itemWrapper.children(":not(." + PIVOT_ITEM_HIDDEN_CLASS + ")")
  24644. },
  24645. _getRTLSignCorrection: function() {
  24646. return this.option("rtlEnabled") ? -1 : 1
  24647. },
  24648. _clean: function() {
  24649. animation.stop(this._$itemWrapper);
  24650. this.callBase()
  24651. },
  24652. _refresh: function() {
  24653. this._tabs._refresh();
  24654. this.callBase()
  24655. },
  24656. _optionChanged: function(name, value, prevValue) {
  24657. switch (name) {
  24658. case"disabled":
  24659. this._tabs.option("disabled", value);
  24660. this.callBase.apply(this, arguments);
  24661. break;
  24662. case"selectedIndex":
  24663. if (!this._swipeGestureRunning)
  24664. this._prepareAnimation();
  24665. this._animateComplete(value, prevValue);
  24666. this._tabs.option("selectedIndex", value);
  24667. break;
  24668. case"items":
  24669. this._tabs.option("items", value);
  24670. this._clearItemsCache();
  24671. this.callBase.apply(this, arguments);
  24672. break;
  24673. case"rtlEnabled":
  24674. this._tabs.option("rtlEnabled", value);
  24675. this._clearItemsCache();
  24676. this.callBase.apply(this, arguments);
  24677. break;
  24678. default:
  24679. this.callBase.apply(this, arguments)
  24680. }
  24681. }
  24682. }));
  24683. ui.dxPivot.__internals = {animation: animation}
  24684. })(jQuery, DevExpress);
  24685. /*! Module widgets-mobile, file ui.tileView.js */
  24686. (function($, DX, undefined) {
  24687. var ui = DX.ui,
  24688. utils = DX.utils;
  24689. var TILEVIEW_CLASS = "dx-tileview",
  24690. TILEVIEW_CONTAINER_CLASS = "dx-tileview-wrapper",
  24691. TILEVIEW_ITEM_CLASS = "dx-tile",
  24692. TILEVIEW_ITEM_SELECTOR = "." + TILEVIEW_ITEM_CLASS,
  24693. TILEVIEW_ITEM_DATA_KEY = "dxTileData";
  24694. DX.registerComponent("dxTileView", ui.CollectionContainerWidget.inherit({
  24695. _activeStateUnit: TILEVIEW_ITEM_SELECTOR,
  24696. _deprecatedOptions: {listHeight: {
  24697. since: "14.1",
  24698. message: "Use the 'height' option instead"
  24699. }},
  24700. _optionAliases: {listHeight: "height"},
  24701. _setDefaultOptions: function() {
  24702. this.callBase();
  24703. this.option({
  24704. hoverStateEnabled: true,
  24705. items: null,
  24706. showScrollbar: false,
  24707. height: 500,
  24708. baseItemWidth: 100,
  24709. baseItemHeight: 100,
  24710. itemMargin: 20,
  24711. indicateLoading: true
  24712. })
  24713. },
  24714. _itemClass: function() {
  24715. return TILEVIEW_ITEM_CLASS
  24716. },
  24717. _itemDataKey: function() {
  24718. return TILEVIEW_ITEM_DATA_KEY
  24719. },
  24720. _itemContainer: function() {
  24721. return this._$container
  24722. },
  24723. _init: function() {
  24724. this.callBase();
  24725. this._initScrollView()
  24726. },
  24727. _handleDataSourceLoadingChanged: function(isLoading) {
  24728. var scrollView = this._scrollView;
  24729. if (!scrollView)
  24730. return;
  24731. if (isLoading && this.option("indicateLoading"))
  24732. scrollView.startLoading();
  24733. else
  24734. scrollView.finishLoading()
  24735. },
  24736. _hideLoadingIfLoadIndicationOff: function() {
  24737. if (!this.option("indicateLoading"))
  24738. this._handleDataSourceLoadingChanged(false)
  24739. },
  24740. _initScrollView: function() {
  24741. this._scrollView = this._element().dxScrollView({
  24742. direction: "horizontal",
  24743. scrollByContent: true
  24744. }).dxScrollView("instance");
  24745. this._$container = this._scrollView.content();
  24746. this._$container.addClass(TILEVIEW_CONTAINER_CLASS);
  24747. this._scrollView.option("updateAction", $.proxy(this._renderGeometry, this))
  24748. },
  24749. _render: function() {
  24750. this.callBase();
  24751. this._element().addClass(TILEVIEW_CLASS);
  24752. this.cellsPerColumn = 1;
  24753. this._updateScrollView();
  24754. this._fireContentReadyAction()
  24755. },
  24756. _renderContent: function() {
  24757. this._renderContentImpl()
  24758. },
  24759. _updateScrollView: function() {
  24760. this._scrollView.option({
  24761. rtlEnabled: this.option("rtlEnabled"),
  24762. showScrollbar: this.option("showScrollbar"),
  24763. disabled: this.option("disabled")
  24764. });
  24765. this._scrollView.update();
  24766. this._indicateLoadingIfAlreadyStarted()
  24767. },
  24768. _indicateLoadingIfAlreadyStarted: function() {
  24769. if (this._dataSource && this._dataSource.isLoading())
  24770. this._handleDataSourceLoadingChanged(true)
  24771. },
  24772. _renderGeometry: function() {
  24773. var items = this.option("items") || [],
  24774. maxItemHeight = Math.max.apply(Math, $.map(items || [], function(item) {
  24775. return Math.round(item.heightRatio || 1)
  24776. }));
  24777. this.cellsPerColumn = Math.floor(this._element().height() / (this.option("baseItemHeight") + this.option("itemMargin")));
  24778. this.cellsPerColumn = Math.max(this.cellsPerColumn, maxItemHeight);
  24779. this.cells = [];
  24780. this.cells.push(new Array(this.cellsPerColumn));
  24781. this._arrangeItems(items);
  24782. this._$container.width(this.cells.length * this.option("baseItemWidth") + (this.cells.length + 1) * this.option("itemMargin"))
  24783. },
  24784. _arrangeItems: function(items) {
  24785. var that = this,
  24786. offsetCorrection = this.option("rtlEnabled") ? this._$container.width() : 0;
  24787. $.each(items, function(index, item) {
  24788. var currentItem = {};
  24789. currentItem.widthRatio = item.widthRatio || 1;
  24790. currentItem.heightRatio = item.heightRatio || 1;
  24791. currentItem.text = item.text || "";
  24792. currentItem.widthRatio = currentItem.widthRatio <= 0 ? 0 : Math.round(currentItem.widthRatio);
  24793. currentItem.heightRatio = currentItem.heightRatio <= 0 ? 0 : Math.round(currentItem.heightRatio);
  24794. var $item = that._itemElements().eq(index),
  24795. itemPosition = that._getItemPosition(currentItem);
  24796. if (itemPosition.x === -1)
  24797. itemPosition.x = that.cells.push(new Array(that.cellsPerColumn)) - 1;
  24798. that._occupyCells(currentItem, itemPosition);
  24799. that._arrangeItem($item, currentItem, itemPosition, offsetCorrection)
  24800. })
  24801. },
  24802. _getItemPosition: function(item) {
  24803. var position = {
  24804. x: -1,
  24805. y: 0
  24806. };
  24807. for (var col = 0; col < this.cells.length; col++) {
  24808. for (var row = 0; row < this.cellsPerColumn; row++)
  24809. if (this._itemFit(col, row, item)) {
  24810. position.x = col;
  24811. position.y = row;
  24812. break
  24813. }
  24814. if (position.x > -1)
  24815. break
  24816. }
  24817. return position
  24818. },
  24819. _itemFit: function(column, row, item) {
  24820. var result = true;
  24821. if (row + item.heightRatio > this.cellsPerColumn)
  24822. return false;
  24823. for (var columnIndex = column; columnIndex < column + item.widthRatio; columnIndex++)
  24824. for (var rowIndex = row; rowIndex < row + item.heightRatio; rowIndex++)
  24825. if (this.cells.length - 1 < columnIndex)
  24826. this.cells.push(new Array(this.cellsPerColumn));
  24827. else if (this.cells[columnIndex][rowIndex]) {
  24828. result = false;
  24829. break
  24830. }
  24831. return result
  24832. },
  24833. _occupyCells: function(item, itemPosition) {
  24834. for (var i = itemPosition.x; i < itemPosition.x + item.widthRatio; i++)
  24835. for (var j = itemPosition.y; j < itemPosition.y + item.heightRatio; j++)
  24836. this.cells[i][j] = true
  24837. },
  24838. _arrangeItem: function($item, item, itemPosition, offsetCorrection) {
  24839. var baseItemHeight = this.option("baseItemHeight"),
  24840. baseItemWidth = this.option("baseItemWidth"),
  24841. itemMargin = this.option("itemMargin"),
  24842. leftOffset;
  24843. if (!offsetCorrection)
  24844. leftOffset = itemPosition.x * baseItemWidth + (itemPosition.x + 1) * itemMargin;
  24845. else {
  24846. var startOffsetPosition = itemPosition.x * baseItemWidth,
  24847. itemBasePartWidth = baseItemWidth + itemMargin,
  24848. itemWidth = itemBasePartWidth * item.widthRatio,
  24849. subitemMarginsWidth = itemPosition.x * itemMargin;
  24850. leftOffset = offsetCorrection - (startOffsetPosition + itemWidth + subitemMarginsWidth)
  24851. }
  24852. $item.css({
  24853. height: item.heightRatio * baseItemHeight + (item.heightRatio - 1) * itemMargin,
  24854. width: item.widthRatio * baseItemWidth + (item.widthRatio - 1) * itemMargin,
  24855. top: itemPosition.y * baseItemHeight + (itemPosition.y + 1) * itemMargin,
  24856. left: leftOffset,
  24857. display: item.widthRatio <= 0 || item.heightRatio <= 0 ? "none" : ""
  24858. })
  24859. },
  24860. _optionChanged: function(name, value) {
  24861. switch (name) {
  24862. case"showScrollbar":
  24863. this._initScrollView();
  24864. break;
  24865. case"disabled":
  24866. this._scrollView.option("disabled", value);
  24867. break;
  24868. case"baseItemWidth":
  24869. case"baseItemHeight":
  24870. case"itemMargin":
  24871. this._renderGeometry();
  24872. break;
  24873. case"height":
  24874. this.callBase.apply(this, arguments);
  24875. this._renderGeometry();
  24876. this._scrollView.update();
  24877. break;
  24878. case"indicateLoading":
  24879. this._hideLoadingIfLoadIndicationOff();
  24880. break;
  24881. default:
  24882. this.callBase.apply(this, arguments)
  24883. }
  24884. },
  24885. scrollPosition: function() {
  24886. return this._scrollView.scrollOffset().left
  24887. }
  24888. }))
  24889. })(jQuery, DevExpress);
  24890. /*! Module widgets-mobile, file ui.actionSheet.js */
  24891. (function($, DX, undefined) {
  24892. var ui = DX.ui;
  24893. var ACTION_SHEET_CLASS = "dx-action-sheet",
  24894. ACTION_SHEET_CONTAINER_CLASS = "dx-action-sheet-container",
  24895. ACTION_SHEET_POPUP_WRAPPER_CLASS = "dx-action-sheet-popup-wrapper",
  24896. ACTION_SHEET_POPOVER_WRAPPER_CLASS = "dx-action-sheet-popover-wrapper",
  24897. ACTION_SHEET_CANCEL_BUTTON_CLASS = "dx-action-sheet-cancel",
  24898. ACTION_SHEET_ITEM_CLASS = "dx-action-sheet-item",
  24899. ACTION_SHEET_ITEM_DATA_KEY = "dxActionSheetItemData",
  24900. ACTION_SHEET_WITHOUT_TITLE_CLASS = "dx-action-sheet-without-title";
  24901. DX.registerComponent("dxActionSheet", ui.CollectionContainerWidget.inherit({
  24902. _setDefaultOptions: function() {
  24903. this.callBase();
  24904. this.option({
  24905. usePopover: false,
  24906. target: null,
  24907. title: "",
  24908. showTitle: true,
  24909. showCancelButton: true,
  24910. cancelText: Globalize.localize("Cancel"),
  24911. cancelClickAction: null,
  24912. visible: false,
  24913. noDataText: ""
  24914. })
  24915. },
  24916. _defaultOptionsRules: function() {
  24917. return this.callBase().slice(0).concat([{
  24918. device: [{
  24919. platform: "ios",
  24920. tablet: true
  24921. }, {
  24922. platform: "ios7",
  24923. tablet: true
  24924. }],
  24925. options: {usePopover: true}
  24926. }])
  24927. },
  24928. _itemContainer: function() {
  24929. return this._$itemContainer
  24930. },
  24931. _itemClass: function() {
  24932. return ACTION_SHEET_ITEM_CLASS
  24933. },
  24934. _itemDataKey: function() {
  24935. return ACTION_SHEET_ITEM_DATA_KEY
  24936. },
  24937. _toggleVisibility: $.noop,
  24938. _renderDimensions: $.noop,
  24939. _render: function() {
  24940. this._element().addClass(ACTION_SHEET_CLASS);
  24941. this._createItemContainer();
  24942. this._renderPopup()
  24943. },
  24944. _createItemContainer: function() {
  24945. this._$itemContainer = $("<div>").addClass(ACTION_SHEET_CONTAINER_CLASS);
  24946. this._renderDisabled()
  24947. },
  24948. _renderDisabled: function() {
  24949. this._$itemContainer.toggleClass("dx-state-disabled", this.option("disabled"))
  24950. },
  24951. _renderPopup: function() {
  24952. this._$popup = $("<div>").appendTo(this._element());
  24953. this._popup = this._isPopoverMode() ? this._createPopover() : this._createPopup();
  24954. this._renderPopupTitle();
  24955. this._mapPopupOption("visible")
  24956. },
  24957. _mapPopupOption: function(optionName) {
  24958. this._popup.option(optionName, this.option(optionName))
  24959. },
  24960. _isPopoverMode: function() {
  24961. return this.option("usePopover") && this.option("target")
  24962. },
  24963. _renderPopupTitle: function() {
  24964. this._mapPopupOption("showTitle");
  24965. this._popup._wrapper().toggleClass(ACTION_SHEET_WITHOUT_TITLE_CLASS, !this.option("showTitle"))
  24966. },
  24967. _clean: function() {
  24968. if (this._$popup)
  24969. this._$popup.remove();
  24970. this.callBase()
  24971. },
  24972. _createPopover: function() {
  24973. var popover = this._$popup.dxPopover({
  24974. _templates: this.option("_templates"),
  24975. rtlEnabled: this.option("rtlEnabled"),
  24976. showTitle: true,
  24977. title: this.option("title"),
  24978. width: this.option("width") || 200,
  24979. height: this.option("height") || "auto",
  24980. target: this.option("target"),
  24981. hiddenAction: $.proxy(this.hide, this),
  24982. contentReadyAction: $.proxy(this._popupContentReadyAction, this)
  24983. }).dxPopover("instance");
  24984. popover._wrapper().addClass(ACTION_SHEET_POPOVER_WRAPPER_CLASS);
  24985. return popover
  24986. },
  24987. _createPopup: function() {
  24988. var popup = this._$popup.dxPopup({
  24989. _templates: this.option("_templates"),
  24990. rtlEnabled: this.option("rtlEnabled"),
  24991. dragEnabled: false,
  24992. title: this.option("title"),
  24993. width: this.option("width") || "100%",
  24994. height: this.option("height") || "auto",
  24995. contentReadyAction: $.proxy(this._popupContentReadyAction, this),
  24996. position: {
  24997. my: "bottom",
  24998. at: "bottom",
  24999. of: window
  25000. },
  25001. animation: {
  25002. show: {
  25003. type: "slide",
  25004. duration: 400,
  25005. from: {position: {
  25006. my: "top",
  25007. at: "bottom",
  25008. of: window
  25009. }},
  25010. to: {position: {
  25011. my: "bottom",
  25012. at: "bottom",
  25013. of: window
  25014. }}
  25015. },
  25016. hide: {
  25017. type: "slide",
  25018. duration: 400,
  25019. from: {position: {
  25020. my: "bottom",
  25021. at: "bottom",
  25022. of: window
  25023. }},
  25024. to: {position: {
  25025. my: "top",
  25026. at: "bottom",
  25027. of: window
  25028. }}
  25029. }
  25030. }
  25031. }).dxPopup("instance");
  25032. popup.optionChanged.add($.proxy(function(name, value) {
  25033. if (name !== "visible")
  25034. return;
  25035. this.option("visible", value)
  25036. }, this));
  25037. popup._wrapper().addClass(ACTION_SHEET_POPUP_WRAPPER_CLASS);
  25038. return popup
  25039. },
  25040. _popupContentReadyAction: function() {
  25041. this._popup.content().append(this._$itemContainer);
  25042. this._attachClickEvent();
  25043. this._attachHoldEvent();
  25044. this._renderContent();
  25045. this._renderCancelButton()
  25046. },
  25047. _renderCancelButton: function() {
  25048. if (this._isPopoverMode())
  25049. return;
  25050. if (this._$cancelButton)
  25051. this._$cancelButton.remove();
  25052. if (this.option("showCancelButton")) {
  25053. var cancelClickAction = new DX.Action($.proxy(this.hide, this), {beforeExecute: this.option("cancelClickAction")});
  25054. this._$cancelButton = $("<div>").addClass(ACTION_SHEET_CANCEL_BUTTON_CLASS).appendTo(this._popup.content()).dxButton({
  25055. text: this.option("cancelText"),
  25056. clickAction: function(e) {
  25057. cancelClickAction.execute(e)
  25058. }
  25059. })
  25060. }
  25061. },
  25062. _handleItemClick: function(e) {
  25063. this.callBase(e);
  25064. if (!$(e.target).is(".dx-state-disabled, .dx-state-disabled *"))
  25065. this.hide()
  25066. },
  25067. _handleItemHold: function(e) {
  25068. this.callBase(e);
  25069. if (!$(e.target).is(".dx-state-disabled, .dx-state-disabled *"))
  25070. this.hide()
  25071. },
  25072. _itemRenderDefault: function(item, index, itemElement) {
  25073. itemElement.dxButton(item)
  25074. },
  25075. _optionChanged: function(name, value) {
  25076. switch (name) {
  25077. case"width":
  25078. case"height":
  25079. case"visible":
  25080. case"title":
  25081. this._mapPopupOption(name);
  25082. break;
  25083. case"disabled":
  25084. this._renderDisabled();
  25085. break;
  25086. case"showTitle":
  25087. this._renderPopupTitle();
  25088. break;
  25089. case"showCancelButton":
  25090. case"cancelClickAction":
  25091. case"cancelText":
  25092. this._renderCancelButton();
  25093. break;
  25094. case"target":
  25095. case"usePopover":
  25096. case"items":
  25097. this._invalidate();
  25098. break;
  25099. default:
  25100. this.callBase.apply(this, arguments)
  25101. }
  25102. },
  25103. toggle: function(showing) {
  25104. var that = this,
  25105. d = $.Deferred();
  25106. that._popup.toggle(showing).done(function() {
  25107. that.option("visible", showing);
  25108. d.resolveWith(that)
  25109. });
  25110. return d.promise()
  25111. },
  25112. show: function() {
  25113. return this.toggle(true)
  25114. },
  25115. hide: function() {
  25116. return this.toggle(false)
  25117. }
  25118. }))
  25119. })(jQuery, DevExpress);
  25120. /*! Module widgets-mobile, file ui.dropDownMenu.js */
  25121. (function($, DX, undefined) {
  25122. var ui = DX.ui,
  25123. events = ui.events;
  25124. var DROP_DOWN_MENU_CLASS = "dx-dropdownmenu",
  25125. DROP_DOWN_MENU_POPUP_CLASS = "dx-dropdownmenu-popup",
  25126. DROP_DOWN_MENU_POPUP_WRAPPER_CLASS = DROP_DOWN_MENU_POPUP_CLASS + "-wrapper",
  25127. DROP_DOWN_MENU_LIST_CLASS = "dx-dropdownmenu-list",
  25128. DROP_DOWN_MENU_BUTTON_CLASS = "dx-dropdownmenu-button";
  25129. DX.registerComponent("dxDropDownMenu", ui.Widget.inherit({
  25130. _setDefaultOptions: function() {
  25131. this.callBase();
  25132. this.option({
  25133. items: [],
  25134. itemClickAction: null,
  25135. dataSource: null,
  25136. itemTemplate: "item",
  25137. itemRender: null,
  25138. buttonText: "",
  25139. buttonIcon: "overflow",
  25140. buttonIconSrc: null,
  25141. buttonClickAction: null,
  25142. usePopover: false,
  25143. hoverStateEnabled: true
  25144. })
  25145. },
  25146. _defaultOptionsRules: function() {
  25147. return this.callBase().slice(0).concat([{
  25148. device: [{platform: "ios"}, {platform: "ios7"}],
  25149. options: {usePopover: true}
  25150. }])
  25151. },
  25152. _init: function() {
  25153. this.callBase();
  25154. this._initDataSource();
  25155. this._initItemClickAction()
  25156. },
  25157. _initItemClickAction: function() {
  25158. this._itemClickAction = this._createActionByOption("itemClickAction")
  25159. },
  25160. _render: function() {
  25161. this._element().addClass(DROP_DOWN_MENU_CLASS);
  25162. this._renderButton();
  25163. this._renderClick();
  25164. this.callBase()
  25165. },
  25166. _clean: function() {
  25167. this._popup._element().remove()
  25168. },
  25169. _renderContentImpl: function() {
  25170. this._renderPopup()
  25171. },
  25172. _renderButton: function() {
  25173. var buttonIconSrc = this.option("buttonIconSrc"),
  25174. buttonIcon = this.option("buttonIcon");
  25175. this._button = this._element().addClass(DROP_DOWN_MENU_BUTTON_CLASS).dxButton({
  25176. text: this.option("buttonText"),
  25177. icon: buttonIcon,
  25178. iconSrc: buttonIconSrc,
  25179. clickAction: this.option("buttonClickAction")
  25180. }).dxButton("instance")
  25181. },
  25182. _renderClick: function() {
  25183. var action = this._createAction(this._handleButtonClick),
  25184. eventName = events.addNamespace("dxclick", this.NAME);
  25185. this._element().off(eventName).on(eventName, function(e) {
  25186. action({jQueryEvent: e})
  25187. })
  25188. },
  25189. _handleButtonClick: function(e) {
  25190. e.component._popup.toggle()
  25191. },
  25192. _renderList: function(instance) {
  25193. var $content = instance.content(),
  25194. that = this;
  25195. that._list = $content.addClass(DROP_DOWN_MENU_LIST_CLASS).dxList({
  25196. _templates: this.option("_templates"),
  25197. autoPagingEnabled: false,
  25198. indicateLoading: false,
  25199. noDataText: "",
  25200. itemRender: that.option("itemRender"),
  25201. itemTemplate: that._getTemplateByOption("itemTemplate"),
  25202. itemClickAction: function(e) {
  25203. that._popup.hide();
  25204. that._itemClickAction(e)
  25205. }
  25206. }).data("dxList");
  25207. that._setListDataSource();
  25208. that._attachListClick();
  25209. var listMaxHeight = $(window).height() * 0.5;
  25210. if ($content.height() > listMaxHeight)
  25211. $content.height(listMaxHeight)
  25212. },
  25213. _toggleVisibility: function(visible) {
  25214. this.callBase(visible);
  25215. this._button.option("visible", visible)
  25216. },
  25217. _attachListClick: function() {
  25218. var action = this._createAction(this._handleListClick);
  25219. this._list._element().off("." + this.NAME).on(events.addNamespace("dxclick", this.NAME), function(e) {
  25220. action({jQueryEvent: e})
  25221. })
  25222. },
  25223. _handleListClick: function(e) {
  25224. e.component._popup.hide()
  25225. },
  25226. _renderPopup: function() {
  25227. var $popup = this._$popup = $("<div>").appendTo(this._element());
  25228. var popupOptions = {
  25229. contentReadyAction: $.proxy(this._popupContentReadyHandler, this),
  25230. deferRendering: false
  25231. };
  25232. this._popup = this._createPopover($popup, popupOptions);
  25233. this._popup._wrapper().addClass(DROP_DOWN_MENU_POPUP_WRAPPER_CLASS);
  25234. this._popup._wrapper().toggleClass(DROP_DOWN_MENU_POPUP_CLASS, !this.option("usePopover"))
  25235. },
  25236. _popupContentReadyHandler: function() {
  25237. var popup = this._$popup.dxPopover("instance");
  25238. this._renderList(popup)
  25239. },
  25240. _createPopover: function($element, popupOptions) {
  25241. return $element.dxPopover($.extend(popupOptions, {
  25242. target: this._element(),
  25243. rtlEnabled: this.option("rtlEnabled")
  25244. })).dxPopover("instance")
  25245. },
  25246. _setListDataSource: function() {
  25247. if (this._list)
  25248. this._list.option("dataSource", this._dataSource || this.option("items"))
  25249. },
  25250. _optionChanged: function(name, value) {
  25251. if (/^button/.test(name)) {
  25252. this._renderButton();
  25253. return
  25254. }
  25255. switch (name) {
  25256. case"items":
  25257. case"dataSource":
  25258. this._refreshDataSource();
  25259. this._setListDataSource();
  25260. break;
  25261. case"itemRender":
  25262. case"itemTemplate":
  25263. if (this._list)
  25264. this._list.option(name, value);
  25265. break;
  25266. case"itemClickAction":
  25267. this._initItemClickAction();
  25268. break;
  25269. case"usePopover":
  25270. this._invalidate();
  25271. break;
  25272. default:
  25273. this.callBase.apply(this, arguments)
  25274. }
  25275. }
  25276. }).include(ui.DataHelperMixin))
  25277. })(jQuery, DevExpress);
  25278. /*! Module widgets-mobile, file ui.panorama.js */
  25279. (function($, DX, undefined) {
  25280. var ui = DX.ui,
  25281. events = ui.events,
  25282. fx = DX.fx,
  25283. translator = DX.translator,
  25284. utils = DX.utils;
  25285. var PANORAMA_CLASS = "dx-panorama",
  25286. PANORAMA_WRAPPER_CLASS = "dx-panorama-wrapper",
  25287. PANORAMA_TITLE_CLASS = "dx-panorama-title",
  25288. PANORAMA_GHOST_TITLE_CLASS = "dx-panorama-ghosttitle",
  25289. PANORAMA_ITEMS_CONTAINER_CLASS = "dx-panorama-itemscontainer",
  25290. PANORAMA_ITEM_CLASS = "dx-panorama-item",
  25291. PANORAMA_GHOST_ITEM_CLASS = "dx-panorama-ghostitem",
  25292. PANORAMA_ITEM_HEADER_CLASS = "dx-panorama-item-header",
  25293. PANORAMA_ITEM_DATA_KEY = "dxPanoramaItemData",
  25294. PANORAMA_ITEM_MARGIN_SCALE = .02,
  25295. PANORAMA_TITLE_MARGIN_SCALE = .02,
  25296. PANORAMA_BACKGROUND_MOVE_DURATION = 300,
  25297. PANORAMA_BACKGROUND_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)",
  25298. PANORAMA_TITLE_MOVE_DURATION = 300,
  25299. PANORAMA_TITLE_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)",
  25300. PANORAMA_ITEM_MOVE_DURATION = 300,
  25301. PANORAMA_ITEM_MOVE_EASING = "cubic-bezier(.40, .80, .60, 1)";
  25302. var moveBackground = function($element, position) {
  25303. $element.css("background-position", position + "px 0%")
  25304. };
  25305. var position = function($element) {
  25306. return translator.locate($element).left
  25307. };
  25308. var move = function($element, position) {
  25309. translator.move($element, {left: position})
  25310. };
  25311. var animation = {
  25312. backgroundMove: function($element, position, completeAction) {
  25313. return fx.animate($element, {
  25314. to: {"background-position": position + "px 0%"},
  25315. duration: PANORAMA_BACKGROUND_MOVE_DURATION,
  25316. easing: PANORAMA_BACKGROUND_MOVE_EASING,
  25317. complete: completeAction
  25318. })
  25319. },
  25320. titleMove: function($title, position, completeAction) {
  25321. return fx.animate($title, {
  25322. type: "slide",
  25323. to: {left: position},
  25324. duration: PANORAMA_TITLE_MOVE_DURATION,
  25325. easing: PANORAMA_TITLE_MOVE_EASING,
  25326. complete: completeAction
  25327. })
  25328. },
  25329. itemMove: function($item, position, completeAction) {
  25330. return fx.animate($item, {
  25331. type: "slide",
  25332. to: {left: position},
  25333. duration: PANORAMA_ITEM_MOVE_DURATION,
  25334. easing: PANORAMA_ITEM_MOVE_EASING,
  25335. complete: completeAction
  25336. })
  25337. }
  25338. };
  25339. var endAnimation = function(elements) {
  25340. if (!elements)
  25341. return;
  25342. $.each(elements, function(_, element) {
  25343. fx.stop(element, true)
  25344. })
  25345. };
  25346. var PanoramaItemsRenderStrategy = DX.Class.inherit({
  25347. ctor: function(panorama) {
  25348. this._panorama = panorama
  25349. },
  25350. init: $.noop,
  25351. render: $.noop,
  25352. allItemElements: function() {
  25353. return this._panorama._itemElements()
  25354. },
  25355. updatePositions: DX.abstract,
  25356. animateRollback: DX.abstract,
  25357. detectBoundsTransition: DX.abstract,
  25358. animateComplete: DX.abstract,
  25359. _getRTLSignCorrection: function() {
  25360. return this._panorama._getRTLSignCorrection()
  25361. },
  25362. _isRTLEnabled: function() {
  25363. return this._panorama.option("rtlEnabled")
  25364. },
  25365. _itemMargin: function() {
  25366. return this._containerWidth() * PANORAMA_ITEM_MARGIN_SCALE
  25367. },
  25368. _containerWidth: function() {
  25369. return this._panorama._elementWidth()
  25370. },
  25371. _itemWidth: function() {
  25372. return this._panorama._itemWidth()
  25373. },
  25374. _indexBoundary: function() {
  25375. return this._panorama._indexBoundary()
  25376. },
  25377. _normalizeIndex: function(index) {
  25378. return this._panorama._normalizeIndex(index)
  25379. },
  25380. _startNextPosition: function() {
  25381. if (this._isRTLEnabled())
  25382. return this._containerWidth() - (this._itemMargin() + this._itemWidth());
  25383. else
  25384. return this._itemMargin()
  25385. },
  25386. _startPrevPosition: function() {
  25387. if (this._isRTLEnabled())
  25388. return this._containerWidth();
  25389. else
  25390. return -this._itemWidth()
  25391. }
  25392. });
  25393. var PanoramaOneAndLessItemsRenderStrategy = PanoramaItemsRenderStrategy.inherit({
  25394. updatePositions: function() {
  25395. var $items = this._panorama._itemElements(),
  25396. startPosition = this._startNextPosition();
  25397. $items.each(function() {
  25398. move($(this), startPosition)
  25399. })
  25400. },
  25401. animateRollback: $.noop,
  25402. detectBoundsTransition: $.noop,
  25403. animateComplete: $.noop
  25404. });
  25405. var PanoramaTwoItemsRenderStrategy = PanoramaItemsRenderStrategy.inherit({
  25406. init: function() {
  25407. this._initGhostItem()
  25408. },
  25409. render: function() {
  25410. this._renderGhostItem()
  25411. },
  25412. _initGhostItem: function() {
  25413. this._$ghostItem = $("<div>").addClass(PANORAMA_GHOST_ITEM_CLASS)
  25414. },
  25415. _renderGhostItem: function() {
  25416. this._panorama._itemContainer().append(this._$ghostItem);
  25417. this._toggleGhostItem(false)
  25418. },
  25419. _toggleGhostItem: function(visible) {
  25420. var $ghostItem = this._$ghostItem;
  25421. if (visible)
  25422. $ghostItem.css("opacity", 1);
  25423. else
  25424. $ghostItem.css("opacity", 0)
  25425. },
  25426. _updateGhostItemContent: function(index) {
  25427. if (index !== false && index !== this._prevGhostIndex) {
  25428. this._$ghostItem.html(this._panorama._itemElements().eq(index).html());
  25429. this._prevGhostIndex = index
  25430. }
  25431. },
  25432. _isGhostItemVisible: function() {
  25433. return this._$ghostItem.css("opacity") == 1
  25434. },
  25435. _swapGhostWithItem: function($item) {
  25436. var $ghostItem = this._$ghostItem,
  25437. lastItemPosition = position($item);
  25438. move($item, position($ghostItem));
  25439. move($ghostItem, lastItemPosition)
  25440. },
  25441. allItemElements: function() {
  25442. return this._panorama._itemContainer().find("." + PANORAMA_ITEM_CLASS + ", ." + PANORAMA_GHOST_ITEM_CLASS)
  25443. },
  25444. updatePositions: function(offset) {
  25445. var $items = this.allItemElements(),
  25446. selectedIndex = this._panorama.option("selectedIndex"),
  25447. adjustedOffset = offset * this._getRTLSignCorrection(),
  25448. isGhostReplaceLast = adjustedOffset > 0 && selectedIndex === 0 || adjustedOffset < 0 && selectedIndex === 1,
  25449. isGhostReplaceFirst = adjustedOffset < 0 && selectedIndex === 0 || adjustedOffset > 0 && selectedIndex === 1,
  25450. ghostPosition = isGhostReplaceLast && "replaceLast" || isGhostReplaceFirst && "replaceFirst",
  25451. ghostContentIndex = isGhostReplaceLast && 1 || isGhostReplaceFirst && 0,
  25452. positions = this._calculateItemPositions(selectedIndex, ghostPosition);
  25453. this._updateGhostItemContent(ghostContentIndex);
  25454. this._toggleGhostItem(isGhostReplaceLast || isGhostReplaceFirst);
  25455. $items.each(function(index) {
  25456. move($(this), positions[index] + offset)
  25457. })
  25458. },
  25459. animateRollback: function(currentIndex) {
  25460. var that = this,
  25461. $items = this._panorama._itemElements(),
  25462. startPosition = this._startNextPosition(),
  25463. signCorrection = this._getRTLSignCorrection(),
  25464. offset = (position($items.eq(currentIndex)) - startPosition) * signCorrection,
  25465. ghostOffset = (position(this._$ghostItem) - startPosition) * signCorrection,
  25466. positions = this._calculateItemPositions(currentIndex, ghostOffset > 0 ? "prepend" : "append"),
  25467. isLastReplasedByGhost = currentIndex === 0 && offset > 0 && ghostOffset > 0 || currentIndex === 1 && ghostOffset < 0;
  25468. if (isLastReplasedByGhost)
  25469. this._swapGhostWithItem($items.eq(1));
  25470. else
  25471. this._swapGhostWithItem($items.eq(0));
  25472. $items.each(function(index) {
  25473. animation.itemMove($(this), positions[index])
  25474. });
  25475. animation.itemMove(this._$ghostItem, positions[2], function() {
  25476. that._toggleGhostItem(false)
  25477. })
  25478. },
  25479. detectBoundsTransition: function(newIndex, currentIndex) {
  25480. var ghostLocation = position(this._$ghostItem),
  25481. startPosition = this._startNextPosition(),
  25482. rtl = this._isRTLEnabled();
  25483. if (newIndex === 0 && rtl ^ ghostLocation < startPosition)
  25484. return "left";
  25485. if (currentIndex === 0 && rtl ^ ghostLocation > startPosition)
  25486. return "right"
  25487. },
  25488. animateComplete: function(boundCross, newIndex, currentIndex) {
  25489. var that = this,
  25490. ghostPosition = !boundCross ^ !(currentIndex === 0) ? "prepend" : "append",
  25491. $items = this._panorama._itemElements(),
  25492. positions = this._calculateItemPositions(newIndex, ghostPosition),
  25493. animations = [];
  25494. $items.each(function(index) {
  25495. animations.push(animation.itemMove($(this), positions[index]))
  25496. });
  25497. animations.push(animation.itemMove(this._$ghostItem, positions[2], function() {
  25498. that._toggleGhostItem(false)
  25499. }));
  25500. return $.when.apply($, animations)
  25501. },
  25502. _calculateItemPositions: function(atIndex, ghostPosition) {
  25503. var positions = [],
  25504. $items = this._panorama._itemElements(),
  25505. itemMargin = this._itemMargin(),
  25506. itemWidth = this._itemWidth(),
  25507. itemPositionOffset = (itemWidth + itemMargin) * this._getRTLSignCorrection(),
  25508. normalFlow = atIndex === 0,
  25509. prevPosition = this._startPrevPosition(),
  25510. nextPosition = this._startNextPosition();
  25511. positions.push(nextPosition);
  25512. nextPosition += itemPositionOffset;
  25513. if (normalFlow)
  25514. positions.push(nextPosition);
  25515. else
  25516. positions.splice(0, 0, nextPosition);
  25517. nextPosition += itemPositionOffset;
  25518. switch (ghostPosition) {
  25519. case"replaceFirst":
  25520. positions.push(positions[0]);
  25521. if (normalFlow)
  25522. positions[0] = nextPosition;
  25523. else
  25524. positions[0] = prevPosition;
  25525. break;
  25526. case"replaceLast":
  25527. if (normalFlow)
  25528. positions.splice(1, 0, prevPosition);
  25529. else
  25530. positions.splice(1, 0, nextPosition);
  25531. break;
  25532. case"prepend":
  25533. positions.push(prevPosition);
  25534. break;
  25535. case"append":
  25536. positions.push(nextPosition);
  25537. break
  25538. }
  25539. return positions
  25540. }
  25541. });
  25542. var PanoramaThreeAndMoreItemsRenderStrategy = PanoramaItemsRenderStrategy.inherit({
  25543. updatePositions: function(offset) {
  25544. var $items = this._panorama._itemElements(),
  25545. movingBack = offset * this._getRTLSignCorrection() < 0,
  25546. positions = this._calculateItemPositions(this._panorama.option("selectedIndex"), movingBack);
  25547. $items.each(function(index) {
  25548. move($(this), positions[index] + offset)
  25549. })
  25550. },
  25551. animateRollback: function(selectedIndex) {
  25552. var $items = this._panorama._itemElements(),
  25553. positions = this._calculateItemPositions(selectedIndex),
  25554. animatingItems = [selectedIndex, this._normalizeIndex(selectedIndex + 1)];
  25555. if (this._isRTLEnabled() ^ position($items.eq(selectedIndex)) > this._startNextPosition())
  25556. animatingItems.push(this._normalizeIndex(selectedIndex - 1));
  25557. $items.each(function(index) {
  25558. var $item = $(this);
  25559. if ($.inArray(index, animatingItems) !== -1)
  25560. animation.itemMove($item, positions[index]);
  25561. else
  25562. move($item, positions[index])
  25563. })
  25564. },
  25565. detectBoundsTransition: function(newIndex, currentIndex) {
  25566. var lastIndex = this._indexBoundary() - 1;
  25567. if (currentIndex === lastIndex && newIndex === 0)
  25568. return "left";
  25569. if (currentIndex === 0 && newIndex === lastIndex)
  25570. return "right"
  25571. },
  25572. animateComplete: function(boundCross, newIndex, currentIndex) {
  25573. var animations = [],
  25574. $items = this._panorama._itemElements(),
  25575. positions = this._calculateItemPositions(newIndex);
  25576. var transitionBack = this._normalizeIndex(currentIndex - 1) === newIndex,
  25577. cyclingItemIndex = $items.length === 3 && transitionBack ? this._normalizeIndex(currentIndex + 1) : null,
  25578. cyclingItemPosition = positions[this._indexBoundary()];
  25579. var animatingItems = [newIndex, currentIndex],
  25580. backAnimatedItemIndex = transitionBack ? currentIndex : newIndex;
  25581. if (!transitionBack)
  25582. animatingItems.push(this._normalizeIndex(backAnimatedItemIndex + 1));
  25583. $items.each(function(index) {
  25584. var $item = $(this);
  25585. if ($.inArray(index, animatingItems) === -1) {
  25586. move($item, positions[index]);
  25587. return
  25588. }
  25589. animations.push(index !== cyclingItemIndex ? animation.itemMove($item, positions[index]) : animation.itemMove($item, cyclingItemPosition, function() {
  25590. move($item, positions[index])
  25591. }))
  25592. });
  25593. return $.when.apply($, animations)
  25594. },
  25595. _calculateItemPositions: function(atIndex, movingBack) {
  25596. var previousIndex = this._normalizeIndex(atIndex - 1),
  25597. $items = this._panorama._itemElements(),
  25598. itemMargin = this._itemMargin(),
  25599. itemWidth = this._itemWidth(),
  25600. itemPositionOffset = (itemWidth + itemMargin) * this._getRTLSignCorrection(),
  25601. positions = [],
  25602. prevPosition = this._startPrevPosition(),
  25603. nextPosition = this._startNextPosition();
  25604. for (var i = atIndex; i !== previousIndex; i = this._normalizeIndex(i + 1)) {
  25605. positions[i] = nextPosition;
  25606. nextPosition += itemPositionOffset
  25607. }
  25608. if (movingBack) {
  25609. positions[previousIndex] = nextPosition;
  25610. nextPosition += itemPositionOffset
  25611. }
  25612. else
  25613. positions[previousIndex] = prevPosition;
  25614. positions.push(nextPosition);
  25615. return positions
  25616. }
  25617. });
  25618. DX.registerComponent("dxPanorama", ui.CollectionContainerWidget.inherit({
  25619. _setDefaultOptions: function() {
  25620. this.callBase();
  25621. this.option({
  25622. selectedIndex: 0,
  25623. title: "panorama",
  25624. backgroundImage: {
  25625. url: null,
  25626. width: 0,
  25627. height: 0
  25628. }
  25629. })
  25630. },
  25631. _itemClass: function() {
  25632. return PANORAMA_ITEM_CLASS
  25633. },
  25634. _itemDataKey: function() {
  25635. return PANORAMA_ITEM_DATA_KEY
  25636. },
  25637. _itemContainer: function() {
  25638. return this._$itemsContainer
  25639. },
  25640. _selectionByClickEnabled: function() {
  25641. return false
  25642. },
  25643. _itemWidth: function() {
  25644. if (!this._itemWidthCache)
  25645. this._itemWidthCache = this._itemElements().eq(0).outerWidth();
  25646. return this._itemWidthCache
  25647. },
  25648. _clearItemWidthCache: function() {
  25649. delete this._itemWidthCache
  25650. },
  25651. _elementWidth: function() {
  25652. if (!this._elementWidthCache)
  25653. this._elementWidthCache = this._element().width();
  25654. return this._elementWidthCache
  25655. },
  25656. _clearElementWidthCache: function() {
  25657. delete this._elementWidthCache
  25658. },
  25659. _titleWidth: function() {
  25660. if (!this._titleWidthCache)
  25661. this._titleWidthCache = this._$title.outerWidth();
  25662. return this._titleWidthCache
  25663. },
  25664. _clearTitleWidthCache: function() {
  25665. delete this._titleWidthCache
  25666. },
  25667. _init: function() {
  25668. this.callBase();
  25669. this._initItemsRenderStrategy();
  25670. this._initWrapper();
  25671. this._initTitle();
  25672. this._initItemsContainer();
  25673. this._initSwipeHandlers()
  25674. },
  25675. _dimensionChanged: function() {
  25676. this._clearItemWidthCache();
  25677. this._clearElementWidthCache();
  25678. this._clearTitleWidthCache();
  25679. this._updatePositions()
  25680. },
  25681. _initWrapper: function() {
  25682. this._$wrapper = $("<div>").addClass(PANORAMA_WRAPPER_CLASS).appendTo(this._element())
  25683. },
  25684. _initItemsRenderStrategy: function() {
  25685. var itemsRenderStrategy;
  25686. switch (this.option("items").length) {
  25687. case 0:
  25688. case 1:
  25689. itemsRenderStrategy = PanoramaOneAndLessItemsRenderStrategy;
  25690. break;
  25691. case 2:
  25692. itemsRenderStrategy = PanoramaTwoItemsRenderStrategy;
  25693. break;
  25694. default:
  25695. itemsRenderStrategy = PanoramaThreeAndMoreItemsRenderStrategy
  25696. }
  25697. this._itemsRenderStrategy = new itemsRenderStrategy(this);
  25698. this._itemsRenderStrategy.init()
  25699. },
  25700. _initBackgroundImage: function() {
  25701. var bgUrl = this.option("backgroundImage.url");
  25702. if (bgUrl)
  25703. this._element().css("background-image", "url(" + bgUrl + ")")
  25704. },
  25705. _initTitle: function() {
  25706. this._$title = $("<div>").addClass(PANORAMA_TITLE_CLASS);
  25707. this._$ghostTitle = $("<div>").addClass(PANORAMA_GHOST_TITLE_CLASS);
  25708. this._$wrapper.append(this._$title);
  25709. this._$wrapper.append(this._$ghostTitle);
  25710. this._updateTitle()
  25711. },
  25712. _updateTitle: function() {
  25713. var title = this.option("title");
  25714. this._$title.text(title);
  25715. this._$ghostTitle.text(title);
  25716. this._toggleGhostTitle(false)
  25717. },
  25718. _toggleGhostTitle: function(visible) {
  25719. var $ghostTitle = this._$ghostTitle;
  25720. if (visible)
  25721. $ghostTitle.css("opacity", 1);
  25722. else
  25723. $ghostTitle.css("opacity", 0)
  25724. },
  25725. _getRTLSignCorrection: function() {
  25726. return this.option("rtlEnabled") ? -1 : 1
  25727. },
  25728. _initItemsContainer: function() {
  25729. this._$itemsContainer = $("<div>").addClass(PANORAMA_ITEMS_CONTAINER_CLASS);
  25730. this._$wrapper.append(this._$itemsContainer)
  25731. },
  25732. _render: function() {
  25733. this._element().addClass(PANORAMA_CLASS);
  25734. this.callBase();
  25735. this._initBackgroundImage();
  25736. this._itemsRenderStrategy.render()
  25737. },
  25738. _updatePositions: function(offset) {
  25739. offset = offset || 0;
  25740. this._updateBackgroundPosition(offset * this._calculateBackgroundStep());
  25741. this._updateTitlePosition(offset * this._calculateTitleStep());
  25742. this._itemsRenderStrategy.updatePositions(offset * this._elementWidth())
  25743. },
  25744. _updateBackgroundPosition: function(offset) {
  25745. moveBackground(this._element(), this._calculateBackgroundPosition(this.option("selectedIndex")) + offset)
  25746. },
  25747. _updateTitlePosition: function(offset) {
  25748. move(this._$title, this._calculateTitlePosition(this.option("selectedIndex")) + offset)
  25749. },
  25750. _animateRollback: function(currentIndex) {
  25751. this._animateBackgroundMove(currentIndex);
  25752. this._animateTitleMove(currentIndex);
  25753. this._itemsRenderStrategy.animateRollback(currentIndex)
  25754. },
  25755. _animateBackgroundMove: function(toIndex) {
  25756. return animation.backgroundMove(this._element(), this._calculateBackgroundPosition(toIndex))
  25757. },
  25758. _animateTitleMove: function(toIndex) {
  25759. return animation.titleMove(this._$title, this._calculateTitlePosition(toIndex))
  25760. },
  25761. _animateComplete: function(newIndex, currentIndex) {
  25762. var that = this,
  25763. boundCross = this._itemsRenderStrategy.detectBoundsTransition(newIndex, currentIndex);
  25764. var backgroundAnimation = this._performBackgroundAnimation(boundCross, newIndex);
  25765. var titleAnimation = this._performTitleAnimation(boundCross, newIndex);
  25766. var itemsAnimation = this._itemsRenderStrategy.animateComplete(boundCross, newIndex, currentIndex);
  25767. $.when(backgroundAnimation, titleAnimation, itemsAnimation).done(function() {
  25768. that._indexChangeOnAnimation = true;
  25769. that.option("selectedIndex", newIndex);
  25770. that._indexChangeOnAnimation = false
  25771. })
  25772. },
  25773. _performBackgroundAnimation: function(boundCross, newIndex) {
  25774. if (boundCross)
  25775. return this._animateBackgroundBoundsTransition(boundCross, newIndex);
  25776. return this._animateBackgroundMove(newIndex)
  25777. },
  25778. _animateBackgroundBoundsTransition: function(bound, newIndex) {
  25779. var that = this,
  25780. isLeft = bound === "left",
  25781. afterAnimationPosition = this._calculateBackgroundPosition(newIndex),
  25782. animationEndPositionShift = isLeft ^ this.option("rtlEnabled") ? -this._calculateBackgroundScaledWidth() : this._calculateBackgroundScaledWidth(),
  25783. animationEndPosition = afterAnimationPosition + animationEndPositionShift;
  25784. return animation.backgroundMove(this._element(), animationEndPosition, function() {
  25785. moveBackground(that._element(), afterAnimationPosition)
  25786. })
  25787. },
  25788. _performTitleAnimation: function(boundCross, newIndex) {
  25789. if (boundCross)
  25790. return this._animateTitleBoundsTransition(boundCross, newIndex);
  25791. return this._animateTitleMove(newIndex)
  25792. },
  25793. _animateTitleBoundsTransition: function(bound, newIndex) {
  25794. var that = this,
  25795. $ghostTitle = this._$ghostTitle,
  25796. ghostWidth = this._titleWidth(),
  25797. panoramaWidth = this._elementWidth(),
  25798. isLeft = bound === "left",
  25799. rtl = this.option("rtlEnabled"),
  25800. ghostTitleStartPosition = isLeft ^ rtl ? panoramaWidth : -ghostWidth,
  25801. ghostTitleEndPosition = isLeft ^ rtl ? -(panoramaWidth + ghostWidth) : panoramaWidth;
  25802. move($ghostTitle, ghostTitleStartPosition);
  25803. this._toggleGhostTitle(true);
  25804. this._swapGhostWithTitle();
  25805. var ghostAnimation = animation.titleMove($ghostTitle, ghostTitleEndPosition, function() {
  25806. that._toggleGhostTitle(false)
  25807. });
  25808. var titleAnimation = animation.titleMove(this._$title, this._calculateTitlePosition(newIndex));
  25809. return $.when(ghostAnimation, titleAnimation)
  25810. },
  25811. _swapGhostWithTitle: function() {
  25812. var $ghostTitle = this._$ghostTitle,
  25813. $title = this._$title,
  25814. lastTitlePosition = position($title);
  25815. move($title, position($ghostTitle));
  25816. move($ghostTitle, lastTitlePosition)
  25817. },
  25818. _calculateTitlePosition: function(atIndex) {
  25819. var panoramaWidth = this._elementWidth(),
  25820. titleWidth = this._titleWidth(),
  25821. titleMargin = panoramaWidth * PANORAMA_TITLE_MARGIN_SCALE,
  25822. titleStartPosition = this.option("rtlEnabled") ? panoramaWidth - titleMargin - titleWidth : titleMargin,
  25823. titleStep = atIndex * this._calculateTitleStep() * this._getRTLSignCorrection();
  25824. return titleStartPosition - titleStep
  25825. },
  25826. _calculateTitleStep: function() {
  25827. var panoramaWidth = this._elementWidth(),
  25828. titleWidth = this._titleWidth(),
  25829. indexBoundary = this._indexBoundary() || 1;
  25830. return Math.max((titleWidth - panoramaWidth) / indexBoundary, titleWidth / indexBoundary)
  25831. },
  25832. _calculateBackgroundPosition: function(atIndex) {
  25833. var panoramaWidth = this._elementWidth(),
  25834. backgroundScaledWidth = this._calculateBackgroundScaledWidth(),
  25835. backgroundStartPosition = this.option("rtlEnabled") ? panoramaWidth - backgroundScaledWidth : 0,
  25836. backgroundOffset = atIndex * this._calculateBackgroundStep() * this._getRTLSignCorrection();
  25837. return backgroundStartPosition - backgroundOffset
  25838. },
  25839. _calculateBackgroundStep: function() {
  25840. var itemWidth = this._itemWidth(),
  25841. backgroundScaledWidth = this._calculateBackgroundScaledWidth();
  25842. return Math.max((backgroundScaledWidth - itemWidth) / (this._indexBoundary() || 1), 0)
  25843. },
  25844. _calculateBackgroundScaledWidth: function() {
  25845. return this._element().height() * this.option("backgroundImage.width") / (this.option("backgroundImage.height") || 1)
  25846. },
  25847. _initSwipeHandlers: function() {
  25848. this._element().on(events.addNamespace("dxswipestart", this.NAME), {itemSizeFunc: $.proxy(this._elementWidth, this)}, $.proxy(this._swipeStartHandler, this)).on(events.addNamespace("dxswipe", this.NAME), $.proxy(this._swipeUpdateHandler, this)).on(events.addNamespace("dxswipeend", this.NAME), $.proxy(this._swipeEndHandler, this))
  25849. },
  25850. _swipeStartHandler: function(e) {
  25851. this._stopAnimations();
  25852. e.maxLeftOffset = 1;
  25853. e.maxRightOffset = 1;
  25854. if (DX.designMode || this.option("disabled") || this._indexBoundary() <= 1)
  25855. e.cancel = true
  25856. },
  25857. _stopAnimations: function() {
  25858. endAnimation([this._element(), this._$ghostTitle, this._$title]);
  25859. endAnimation(this._itemsRenderStrategy.allItemElements())
  25860. },
  25861. _swipeUpdateHandler: function(e) {
  25862. this._updatePositions(e.offset)
  25863. },
  25864. _swipeEndHandler: function(e) {
  25865. var currentIndex = this.option("selectedIndex"),
  25866. targetOffset = e.targetOffset * this._getRTLSignCorrection();
  25867. if (targetOffset === 0)
  25868. this._animateRollback(currentIndex);
  25869. else
  25870. this._animateComplete(this._normalizeIndex(currentIndex - targetOffset), currentIndex)
  25871. },
  25872. _renderSelectedIndex: function(current, previous) {
  25873. if (!this._indexChangeOnAnimation)
  25874. this._updatePositions()
  25875. },
  25876. _normalizeIndex: function(index) {
  25877. var boundary = this._indexBoundary();
  25878. if (index < 0)
  25879. index = boundary + index;
  25880. if (index >= boundary)
  25881. index = index - boundary;
  25882. return index
  25883. },
  25884. _indexBoundary: function() {
  25885. return this.option("items").length
  25886. },
  25887. _visibilityChanged: function(visible) {
  25888. if (visible)
  25889. this._dimensionChanged()
  25890. },
  25891. _optionChanged: function(name, value, prevValue) {
  25892. switch (name) {
  25893. case"width":
  25894. this.callBase.apply(this, arguments);
  25895. this._dimensionChanged();
  25896. break;
  25897. case"backgroundImage":
  25898. this._invalidate();
  25899. break;
  25900. case"title":
  25901. this._updateTitle();
  25902. break;
  25903. case"items":
  25904. this._initItemsRenderStrategy();
  25905. this.callBase.apply(this, arguments);
  25906. break;
  25907. default:
  25908. this.callBase.apply(this, arguments)
  25909. }
  25910. },
  25911. _itemRenderDefault: function(item, index, $itemElement) {
  25912. this.callBase(item, index, $itemElement);
  25913. if (!item.header)
  25914. return;
  25915. var $itemHeader = $("<div>").addClass(PANORAMA_ITEM_HEADER_CLASS).text(item.header);
  25916. $itemElement.prepend($itemHeader)
  25917. }
  25918. }));
  25919. ui.dxPanorama.__internals = {animation: animation}
  25920. })(jQuery, DevExpress);
  25921. /*! Module widgets-mobile, file ui.slideout.js */
  25922. (function($, DX, undefined) {
  25923. var ui = DX.ui,
  25924. events = ui.events,
  25925. fx = DX.fx,
  25926. utils = DX.utils,
  25927. translator = DX.translator;
  25928. var SLIDEOUT_CLASS = "dx-slideout",
  25929. SLIDEOUT_WRAPPER_CLASS = "dx-slideout-wrapper",
  25930. SLIDEOUT_ITEM_CONTAINER_CLASS = "dx-slideout-item-container",
  25931. SLIDEOUT_MENU = "dx-slideout-menu",
  25932. SLIDEOUT_SHIELD = "dx-slideout-shield",
  25933. SLIDEOUT_ITEM_CLASS = "dx-slideout-item",
  25934. SLIDEOUT_ITEM_DATA_KEY = "dxSlideoutItemData",
  25935. INVISIBLE_STATE_CLASS = "dx-state-invisible",
  25936. CONTENT_OFFSET = 45,
  25937. ANIMATION_DURATION = 400;
  25938. DX.registerComponent("dxSlideOut", ui.CollectionContainerWidget.inherit({
  25939. _setDefaultOptions: function() {
  25940. this.callBase();
  25941. this.option({
  25942. activeStateEnabled: false,
  25943. menuItemRender: null,
  25944. menuItemTemplate: "menuItem",
  25945. swipeEnabled: true,
  25946. menuVisible: false,
  25947. menuGrouped: false,
  25948. menuGroupTemplate: "group",
  25949. menuGroupRender: null
  25950. })
  25951. },
  25952. _itemClass: function() {
  25953. return SLIDEOUT_ITEM_CLASS
  25954. },
  25955. _itemDataKey: function() {
  25956. return SLIDEOUT_ITEM_DATA_KEY
  25957. },
  25958. _init: function() {
  25959. this.callBase();
  25960. this._deferredAnimate = undefined
  25961. },
  25962. _render: function() {
  25963. this._renderWrapper();
  25964. this._renderItemsContainer();
  25965. this._renderShield();
  25966. this._renderList();
  25967. this._initSwipeHandlers();
  25968. this._element().addClass(SLIDEOUT_CLASS);
  25969. this.callBase();
  25970. this._renderPosition(this.option("menuVisible"), false)
  25971. },
  25972. _renderWrapper: function() {
  25973. this._wrapper = $("<div>").addClass(SLIDEOUT_WRAPPER_CLASS);
  25974. this._element().append(this._wrapper)
  25975. },
  25976. _renderShield: function() {
  25977. this._$shield = $("<div>").addClass(SLIDEOUT_SHIELD);
  25978. this._$shield.appendTo(this._$container);
  25979. this._$shield.on("dxclick", $.proxy(this.hideMenu, this));
  25980. this._toggleShieldVisibility()
  25981. },
  25982. _dimensionChanged: function() {
  25983. this._renderPosition(this.option("menuVisible"), false);
  25984. this._clearListWidthCache()
  25985. },
  25986. _renderItemsContainer: function() {
  25987. this._$container = $("<div>").addClass(SLIDEOUT_ITEM_CONTAINER_CLASS).appendTo(this._wrapper);
  25988. this._$container.on("MSPointerDown", function(e){})
  25989. },
  25990. _selectedItemElement: function(index) {
  25991. return this._itemElements().eq(0)
  25992. },
  25993. _renderContentImpl: function(template) {
  25994. var items = this.option("items"),
  25995. selectedIndex = this.option("selectedIndex");
  25996. if (items.length && selectedIndex > -1) {
  25997. var selectedItem = this._$list.dxList("instance").getItemByIndex(selectedIndex);
  25998. this._renderItems([selectedItem])
  25999. }
  26000. },
  26001. _renderList: function() {
  26002. this._$list = $("<div>").addClass(SLIDEOUT_MENU).prependTo(this._wrapper);
  26003. this._renderItemClickAction();
  26004. var list = this._$list.dxList().dxList("instance");
  26005. this._$list.dxList({
  26006. _templates: this.option("_templates"),
  26007. itemTemplateProperty: "menuTemplate",
  26008. height: "100%",
  26009. indicateLoading: false,
  26010. itemClickAction: $.proxy(this._handleListItemClick, this),
  26011. items: this.option("items"),
  26012. dataSource: this.option("dataSource"),
  26013. itemRender: this.option("menuItemRender"),
  26014. itemTemplate: this._getTemplateByOption("menuItemTemplate"),
  26015. grouped: this.option("menuGrouped"),
  26016. groupTemplate: this.option("menuGroupTemplate"),
  26017. groupRender: this.option("menuGroupRender")
  26018. })
  26019. },
  26020. _handleListItemClick: function(e) {
  26021. var selectedIndex = this._$list.find(".dx-list-item").index(e.itemElement);
  26022. this.option("selectedIndex", selectedIndex);
  26023. this._itemClickAction(e)
  26024. },
  26025. _handleItemClick: $.noop,
  26026. _renderItemClickAction: function() {
  26027. this._itemClickAction = this._createActionByOption("itemClickAction")
  26028. },
  26029. _renderItem: function(index, item, container) {
  26030. this._$container.find("." + SLIDEOUT_ITEM_CLASS).remove();
  26031. this.callBase(index, item, this._$container)
  26032. },
  26033. _renderSelectedIndex: function() {
  26034. this._renderContent()
  26035. },
  26036. _initSwipeHandlers: function() {
  26037. this._$container.dxSwipeable({
  26038. elastic: false,
  26039. itemSizeFunc: $.proxy(this._getListWidth, this),
  26040. startAction: $.proxy(this.option("swipeEnabled") ? this._handleSwipeStart : function(e) {
  26041. e.jQueryEvent.cancel = true
  26042. }, this),
  26043. updateAction: $.proxy(this._handleSwipeUpdate, this),
  26044. endAction: $.proxy(this._handleSwipeEnd, this)
  26045. })
  26046. },
  26047. _handleSwipeStart: function(e) {
  26048. this._$shield.addClass(INVISIBLE_STATE_CLASS);
  26049. fx.stop(this._$container);
  26050. var menuVisible = this.option("menuVisible"),
  26051. rtl = this.option("rtlEnabled");
  26052. e.jQueryEvent.maxLeftOffset = rtl ? !menuVisible : menuVisible;
  26053. e.jQueryEvent.maxRightOffset = rtl ? menuVisible : !menuVisible
  26054. },
  26055. _handleSwipeUpdate: function(e) {
  26056. var offset = this.option("menuVisible") ? e.jQueryEvent.offset + 1 * this._getRTLSignCorrection() : e.jQueryEvent.offset;
  26057. offset *= this._getRTLSignCorrection();
  26058. this._renderPosition(offset, false)
  26059. },
  26060. _handleSwipeEnd: function(e) {
  26061. var targetOffset = e.jQueryEvent.targetOffset * this._getRTLSignCorrection() + this.option("menuVisible"),
  26062. menuVisible = targetOffset !== 0;
  26063. if (this.option("menuVisible") === menuVisible)
  26064. this._renderPosition(this.option("menuVisible"), true);
  26065. else
  26066. this.option("menuVisible", targetOffset !== 0)
  26067. },
  26068. _handleMenuButtonClick: function() {
  26069. this.option("menuVisible", !this.option("menuVisible"))
  26070. },
  26071. _toggleMenuVisibility: function(visible, animate) {
  26072. this.option("menuVisible", visible)
  26073. },
  26074. _renderPosition: function(offset, animate) {
  26075. var pos = this._calculatePixelOffset(offset) * this._getRTLSignCorrection();
  26076. if (animate) {
  26077. this._$shield.addClass(INVISIBLE_STATE_CLASS);
  26078. fx.animate(this._$container, {
  26079. type: "slide",
  26080. to: {left: pos},
  26081. duration: ANIMATION_DURATION,
  26082. complete: $.proxy(this._handleAnimationComplete, this)
  26083. })
  26084. }
  26085. else
  26086. translator.move(this._$container, {left: pos})
  26087. },
  26088. _calculatePixelOffset: function(offset) {
  26089. var offset = offset || 0,
  26090. maxOffset = this._getListWidth();
  26091. return offset * maxOffset
  26092. },
  26093. _getListWidth: function() {
  26094. if (!this._listWidth) {
  26095. var listWidth = this._$list.width(),
  26096. elementWidth = this._element().width() - CONTENT_OFFSET;
  26097. this._listWidth = Math.min(elementWidth, listWidth)
  26098. }
  26099. return this._listWidth
  26100. },
  26101. _clearListWidthCache: function() {
  26102. delete this._listWidth
  26103. },
  26104. _getRTLSignCorrection: function() {
  26105. return this.option("rtlEnabled") ? -1 : 1
  26106. },
  26107. _changeMenuOption: function(name, value) {
  26108. this._$list.dxList("instance").option(name, value);
  26109. this._clearListWidthCache()
  26110. },
  26111. _visibilityChanged: function(visible) {
  26112. if (visible)
  26113. this._dimensionChanged()
  26114. },
  26115. _optionChanged: function(name, value, prevValue) {
  26116. switch (name) {
  26117. case"menuVisible":
  26118. this._renderPosition(value, true);
  26119. break;
  26120. case"swipeEnabled":
  26121. this._initSwipeHandlers();
  26122. break;
  26123. case"menuItemRender":
  26124. this._changeMenuOption("itemRender", value);
  26125. break;
  26126. case"menuItemTemplate":
  26127. this._changeMenuOption("itemTemplate", value);
  26128. break;
  26129. case"items":
  26130. case"dataSource":
  26131. this._changeMenuOption(name, value);
  26132. break;
  26133. case"menuGrouped":
  26134. this._changeMenuOption("grouped", value);
  26135. break;
  26136. case"menuGroupRender":
  26137. this._changeMenuOption("groupRender", value);
  26138. break;
  26139. case"menuGroupTemplate":
  26140. this._changeMenuOption("groupTemplate", value);
  26141. break;
  26142. case"itemClickAction":
  26143. this._renderItemClickAction();
  26144. break;
  26145. case"rtlEnabled":
  26146. this.callBase.apply(this, arguments);
  26147. this._renderPosition(this.option("menuVisible"), false);
  26148. break;
  26149. default:
  26150. this.callBase(name, value, prevValue)
  26151. }
  26152. },
  26153. _toggleShieldVisibility: function() {
  26154. this._$shield.toggleClass(INVISIBLE_STATE_CLASS, !this.option("menuVisible"))
  26155. },
  26156. _handleAnimationComplete: function() {
  26157. this._toggleShieldVisibility();
  26158. if (this._deferredAnimate)
  26159. this._deferredAnimate.resolveWith(this)
  26160. },
  26161. showMenu: function() {
  26162. return this.toggleMenuVisibility(true)
  26163. },
  26164. hideMenu: function() {
  26165. return this.toggleMenuVisibility(false)
  26166. },
  26167. toggleMenuVisibility: function(showing) {
  26168. showing = showing === undefined ? !this.option("menuVisible") : showing;
  26169. this._deferredAnimate = $.Deferred();
  26170. this.option("menuVisible", showing);
  26171. return this._deferredAnimate.promise()
  26172. }
  26173. }))
  26174. })(jQuery, DevExpress);
  26175. DevExpress.MOD_WIDGETS_MOBILE = true
  26176. }
  26177. if (!DevExpress.MOD_WIDGETS_WEB) {
  26178. if (!DevExpress.MOD_WIDGETS_BASE)
  26179. throw Error('Required module is not referenced: widgets-base');
  26180. /*! Module widgets-web, file ui.pager.js */
  26181. (function($, DX, undefined) {
  26182. var ui = DX.ui,
  26183. utils = DX.utils,
  26184. events = ui.events,
  26185. Class = DX.Class;
  26186. var PAGES_LIMITER = 4,
  26187. PAGER_CLASS = 'dx-pager',
  26188. PAGER_PAGE_CLASS = 'dx-page',
  26189. PAGER_PAGES_CLASS = 'dx-pages',
  26190. PAGER_SELECTION_CLASS = 'dx-selection',
  26191. PAGER_PAGE_SEPARATOR_CLASS = 'dx-separator',
  26192. PAGER_PAGE_SIZES_CLASS = 'dx-page-sizes',
  26193. PAGER_PAGE_SIZE_CLASS = 'dx-page-size';
  26194. var Page = Class.inherit({
  26195. ctor: function(value, index) {
  26196. var that = this;
  26197. that.index = index;
  26198. that.element = $('<div />').text(value).addClass(PAGER_PAGE_CLASS)
  26199. },
  26200. value: function(value) {
  26201. var that = this;
  26202. if (utils.isDefined(value))
  26203. that.element.text(value);
  26204. else {
  26205. var text = that.element.text();
  26206. if (utils.isNumber(text))
  26207. return parseInt(text);
  26208. else
  26209. return text
  26210. }
  26211. },
  26212. select: function(value) {
  26213. this.element.toggleClass(PAGER_SELECTION_CLASS, value)
  26214. },
  26215. render: function(rootElement, rtlEnabled) {
  26216. rtlEnabled ? this.element.prependTo(rootElement) : this.element.appendTo(rootElement)
  26217. }
  26218. });
  26219. DX.registerComponent("dxPager", DX.DOMComponent.inherit({
  26220. NAMESPACE: ui,
  26221. _setDefaultOptions: function() {
  26222. this.callBase();
  26223. this.option({
  26224. visible: true,
  26225. pageIndex: 1,
  26226. maxPagesCount: 10,
  26227. pagesCount: 10,
  26228. pageSize: 5,
  26229. showPageSizes: true,
  26230. pageSizes: [5, 10],
  26231. hasKnownLastPage: true,
  26232. pageIndexChanged: $.noop,
  26233. pageSizeChanged: $.noop
  26234. })
  26235. },
  26236. _toggleVisibility: function(value) {
  26237. var $element = this._element();
  26238. if ($element)
  26239. $element.css("display", value ? "" : "none")
  26240. },
  26241. _getPages: function(currentPage, count) {
  26242. var pages = [],
  26243. showMoreButton = !this.option("hasKnownLastPage"),
  26244. firstValue,
  26245. i;
  26246. this._testPagesCount = count;
  26247. this._testShowMoreButton = showMoreButton;
  26248. if (count > 1 || showMoreButton)
  26249. if (count <= this.option("maxPagesCount")) {
  26250. for (i = 1; i <= count; i++)
  26251. pages.push(new Page(i, i - 1));
  26252. if (showMoreButton)
  26253. pages.push(new Page('>', i - 1))
  26254. }
  26255. else {
  26256. pages.push(new Page(1, 0));
  26257. firstValue = currentPage ? currentPage.value() - currentPage.index : 1;
  26258. for (i = 1; i <= PAGES_LIMITER; i++)
  26259. pages.push(new Page(firstValue + i, i));
  26260. pages.push(new Page(count, PAGES_LIMITER + 1));
  26261. if (showMoreButton)
  26262. pages.push(new Page('>', PAGES_LIMITER + 1))
  26263. }
  26264. return pages
  26265. },
  26266. _getPageByValue: function(value) {
  26267. var that = this,
  26268. page,
  26269. i;
  26270. for (i = 0; i < that._pages.length; i++) {
  26271. page = that._pages[i];
  26272. if (page.value() === value)
  26273. return page
  26274. }
  26275. },
  26276. _processSelectedPage: function(maxPagesCount, pageIndex, pagesCount) {
  26277. var that = this,
  26278. isPageIndexValid = false,
  26279. selectedPageIndex;
  26280. if (that._pages) {
  26281. $.each(that._pages, function(key, page) {
  26282. if (pageIndex === page.value())
  26283. isPageIndexValid = true
  26284. });
  26285. if (!isPageIndexValid)
  26286. that.selectedPage = null
  26287. }
  26288. if (utils.isDefined(that.selectedPage)) {
  26289. if (pageIndex === pagesCount && pagesCount > maxPagesCount && that.selectedPage.index !== PAGES_LIMITER + 1)
  26290. that.selectedPage.index = PAGES_LIMITER + 1
  26291. }
  26292. else if (pageIndex > PAGES_LIMITER && pageIndex < pagesCount) {
  26293. selectedPageIndex = pagesCount - PAGES_LIMITER < pageIndex ? PAGES_LIMITER - (pagesCount - pageIndex) + 1 : 2;
  26294. that.selectedPage = new Page(pageIndex, selectedPageIndex)
  26295. }
  26296. },
  26297. _selectPageByValue: function(value) {
  26298. var that = this,
  26299. i,
  26300. page = that._getPageByValue(value),
  26301. pages = that._pages,
  26302. pagesLength = pages.length,
  26303. prevPage,
  26304. nextPage,
  26305. morePage;
  26306. if (!utils.isDefined(page))
  26307. return;
  26308. prevPage = that._pages[page.index - 1];
  26309. nextPage = that._pages[page.index + 1];
  26310. if (nextPage && nextPage.value() === '>') {
  26311. morePage = nextPage;
  26312. nextPage = undefined;
  26313. pagesLength--;
  26314. pages.pop()
  26315. }
  26316. if (that.selectedPage)
  26317. that.selectedPage.select(false);
  26318. page.select(true);
  26319. that.selectedPage = page;
  26320. if (nextPage && nextPage.value() - value > 1)
  26321. if (page.index !== 0) {
  26322. prevPage.value(value + 1);
  26323. that._pages.splice(page.index, 1);
  26324. that._pages.splice(page.index - 1, 0, page);
  26325. that._pages[page.index].index = page.index;
  26326. page.index = page.index - 1;
  26327. for (i = page.index - 1; i > 0; i--)
  26328. that._pages[i].value(that._pages[i + 1].value() - 1)
  26329. }
  26330. else
  26331. for (i = 0; i < pagesLength - 1; i++)
  26332. that._pages[i].value(i + 1);
  26333. if (prevPage && value - prevPage.value() > 1)
  26334. if (page.index !== pagesLength - 1) {
  26335. nextPage.value(value - 1);
  26336. that._pages.splice(page.index, 1);
  26337. that._pages.splice(page.index + 1, 0, page);
  26338. that._pages[page.index].index = page.index;
  26339. page.index = page.index + 1;
  26340. for (i = page.index + 1; i < pagesLength - 1; i++)
  26341. that._pages[i].value(that._pages[i - 1].value() + 1)
  26342. }
  26343. else
  26344. for (i = 1; i <= pagesLength - 2; i++)
  26345. that._pages[pagesLength - 1 - i].value(that._pages[pagesLength - 1].value() - i);
  26346. if (morePage)
  26347. pages.push(morePage)
  26348. },
  26349. _renderPagesChooser: function() {
  26350. var that = this,
  26351. page,
  26352. pageIndexChanged = that.option("pageIndexChanged"),
  26353. i,
  26354. $element = that._element();
  26355. if (!$element)
  26356. return;
  26357. that._clickPagesIndexAction = that._createAction(function(args) {
  26358. var e = args.jQueryEvent,
  26359. pageNumber = $(e.target).text(),
  26360. pageIndex = pageNumber === '>' ? that.option("pagesCount") + 1 : Number(pageNumber);
  26361. that._testPageIndex = pageIndex;
  26362. that.option("pageIndex", pageIndex);
  26363. pageIndexChanged(pageIndex)
  26364. });
  26365. if (utils.isDefined(that.pagesChooserElement))
  26366. that.pagesChooserElement.empty();
  26367. else
  26368. that.pagesChooserElement = $('<div />').addClass(PAGER_PAGES_CLASS).on(events.addNamespace("dxclick", that.Name + "Pages"), '.' + PAGER_PAGE_CLASS, function(e) {
  26369. that._clickPagesIndexAction({jQueryEvent: e})
  26370. });
  26371. if (that._pages.length === 0) {
  26372. that.selectedPage = null;
  26373. return
  26374. }
  26375. for (i = 0; i < that._pages.length; i++) {
  26376. page = that._pages[i];
  26377. page.render(that.pagesChooserElement, that.option('rtlEnabled'));
  26378. if (that._pages[i + 1] && that._pages[i + 1].value() - page.value() > 1) {
  26379. var $separator = $('<div>. . .</div>').addClass(PAGER_PAGE_SEPARATOR_CLASS).attr('style', '-webkit-user-select: none');
  26380. that.option('rtlEnabled') ? $separator.prependTo(that.pagesChooserElement) : $separator.appendTo(that.pagesChooserElement)
  26381. }
  26382. }
  26383. if (!utils.isDefined(that.pagesChooserElement[0].parentElement))
  26384. that.pagesChooserElement.appendTo($element)
  26385. },
  26386. _renderPagesSizeChooser: function() {
  26387. var that = this,
  26388. i,
  26389. pageSizeElement,
  26390. currentPageSize = that.option("pageSize"),
  26391. pageSizes = that.option("pageSizes"),
  26392. showPageSizes = that.option("showPageSizes"),
  26393. pageSizeValue,
  26394. pagesSizesLength = pageSizes && pageSizes.length,
  26395. $element = that._element();
  26396. if (!$element)
  26397. return;
  26398. that._clickPagesSizeAction = that._createAction(function(args) {
  26399. var e = args.jQueryEvent;
  26400. pageSizeValue = parseInt($(e.target).text());
  26401. that._testPageSizeIndex = pageSizeValue;
  26402. that.option("pageSize", pageSizeValue)
  26403. });
  26404. if (utils.isDefined(that.pagesSizeChooserElement))
  26405. that.pagesSizeChooserElement.empty();
  26406. else
  26407. that.pagesSizeChooserElement = $('<div />').addClass(PAGER_PAGE_SIZES_CLASS).on(events.addNamespace("dxclick", that.Name + "PageSize"), '.' + PAGER_PAGE_SIZE_CLASS, function(e) {
  26408. that._clickPagesSizeAction({jQueryEvent: e})
  26409. });
  26410. if (!showPageSizes || !pagesSizesLength)
  26411. return;
  26412. that._testCurrentPageSize = currentPageSize;
  26413. for (i = 0; i < pagesSizesLength; i++) {
  26414. pageSizeElement = $('<div />').text(pageSizes[i]).addClass(PAGER_PAGE_SIZE_CLASS);
  26415. if (currentPageSize === pageSizes[i])
  26416. pageSizeElement.addClass(PAGER_SELECTION_CLASS);
  26417. that.option('rtlEnabled') ? that.pagesSizeChooserElement.prepend(pageSizeElement) : that.pagesSizeChooserElement.append(pageSizeElement)
  26418. }
  26419. if (!utils.isDefined(that.pagesSizeChooserElement[0].parentElement))
  26420. that.pagesSizeChooserElement.appendTo($element)
  26421. },
  26422. _render: function() {
  26423. this._update();
  26424. this._element().addClass(PAGER_CLASS);
  26425. this._toggleVisibility(this.option("visible"));
  26426. this._renderPagesSizeChooser();
  26427. this._renderPagesChooser()
  26428. },
  26429. _update: function() {
  26430. var pagesCount = this.option("pagesCount"),
  26431. pageIndex = this.option("pageIndex");
  26432. this._processSelectedPage(this.option("maxPagesCount"), pageIndex, pagesCount);
  26433. this._pages = this._getPages(this.selectedPage, pagesCount);
  26434. this._selectPageByValue(pageIndex)
  26435. },
  26436. _optionChanged: function(name, value) {
  26437. switch (name) {
  26438. case"visible":
  26439. this._toggleVisibility(value);
  26440. break;
  26441. case"pageIndex":
  26442. case"maxPagesCount":
  26443. case"pagesCount":
  26444. case"hasKnownLastPage":
  26445. this._update();
  26446. this._renderPagesChooser();
  26447. break;
  26448. case"pageSize":
  26449. var pageSizeChanged = this.option("pageSizeChanged");
  26450. if (pageSizeChanged)
  26451. pageSizeChanged(value);
  26452. case"pageSizes":
  26453. this._renderPagesSizeChooser();
  26454. break;
  26455. default:
  26456. this._invalidate()
  26457. }
  26458. },
  26459. getHeight: function() {
  26460. return this.option("visible") ? this._element().outerHeight() : 0
  26461. }
  26462. }));
  26463. ui.dxPager.__internals = {
  26464. PAGER_CLASS: PAGER_CLASS,
  26465. PAGER_PAGE_CLASS: PAGER_PAGE_CLASS,
  26466. PAGER_PAGES_CLASS: PAGER_PAGES_CLASS,
  26467. PAGER_SELECTION_CLASS: PAGER_SELECTION_CLASS,
  26468. PAGER_PAGE_SEPARATOR_CLASS: PAGER_PAGE_SEPARATOR_CLASS,
  26469. PAGER_PAGE_SIZES_CLASS: PAGER_PAGE_SIZES_CLASS,
  26470. PAGER_PAGE_SIZE_CLASS: PAGER_PAGE_SIZE_CLASS
  26471. }
  26472. })(jQuery, DevExpress);
  26473. /*! Module widgets-web, file ui.colorPicker.js */
  26474. (function($, DX, undefined) {
  26475. var ui = DX.ui,
  26476. events = ui.events,
  26477. utils = DX.utils;
  26478. var COLOR_PICKER_CLASS = "dx-color-picker",
  26479. COLOR_PICKER_INPUT_CONTAINER_CLASS = "dx-color-picker-input-container",
  26480. COLOR_PICKER_INPUT_CLASS = "dx-color-picker-input",
  26481. COLOR_PICKER_COLOR_RESULT_PREVIEW = "dx-color-picker-color-result-preview",
  26482. COLOR_PICKER_OVERLAY_CLASS = "dx-color-picker-overlay",
  26483. COLOR_PICKER_OVERLAY_WITHOUT_ALPHA_CHANNEL_CLASS = "dx-color-picker-without-alpha-channel",
  26484. COLOR_PICKER_CONTAINER_CLASS = "dx-color-picker-container",
  26485. COLOR_PICKER_ROW_CLASS = "dx-color-picker-container-row",
  26486. COLOR_PICKER_CELL_CLASS = "dx-color-picker-container-cell",
  26487. COLOR_PICKER_PALETTE_CLASS = "dx-color-picker-palette",
  26488. COLOR_PICKER_PALETTE_GRADIENT_CLASS = "dx-color-picker-palette-gradient",
  26489. COLOR_PICKER_PALETTE_GRADIENT_WHITE_CLASS = "dx-white",
  26490. COLOR_PICKER_PALETTE_GRADIENT_BLACK_CLASS = "dx-black",
  26491. COLOR_PICKER_HUE_SCALE_CLASS = "dx-color-picker-hue-scale",
  26492. COLOR_PICKER_HUE_SCALE_HANDLE_CLASS = "dx-color-picker-hue-scale-handle",
  26493. COLOR_PICKER_HUE_SCALE_WRAPPER_CLASS = "dx-hue-scale-wrapper",
  26494. COLOR_PICKER_CONTROLS_CONTAINER_CLASS = "dx-color-picker-controls-container",
  26495. COLOR_PICKER_BUTTONS_CONTAINER_CLASS = "dx-color-picker-buttons-container",
  26496. COLOR_PICKER_APPLY_BUTTON_CLASS = "dx-color-picker-apply-button",
  26497. COLOR_PICKER_CANCEL_BUTTON_CLASS = "dx-color-picker-cancel-button",
  26498. COLOR_PICKER_COLOR_CHOOSER_CLASS = "dx-color-picker-color-chooser",
  26499. COLOR_PICKER_RED_LABEL_CLASS = "dx-color-picker-red-label",
  26500. COLOR_PICKER_GREEN_LABEL_CLASS = "dx-color-picker-green-label",
  26501. COLOR_PICKER_BLUE_LABEL_CLASS = "dx-color-picker-blue-label",
  26502. COLOR_PICKER_HEX_LABEL_CLASS = "dx-color-picker-hex-label",
  26503. COLOR_PICKER_RED_INPUT_CLASS = "dx-color-picker-red-input",
  26504. COLOR_PICKER_GREEN_INPUT_CLASS = "dx-color-picker-green-input",
  26505. COLOR_PICKER_BLUE_INPUT_CLASS = "dx-color-picker-blue-input",
  26506. COLOR_PICKER_HEX_INPUT_CLASS = "dx-color-picker-hex-input",
  26507. COLOR_PICKER_ALPHA_CHANNEL_SCALE_WRAPPER_CLASS = "dx-color-picker-alpha-scale-wrapper",
  26508. COLOR_PICKER_ALPHA_CHANNEL_SCALE_CLASS = "dx-color-picker-alpha-scale",
  26509. COLOR_PICKER_ALPHA_CHANNEL_INPUT_CLASS = "dx-color-picker-alpha-input",
  26510. COLOR_PICKER_ALPHA_CHANNEL_LABEL_CLASS = "dx-color-picker-alpha-label",
  26511. COLOR_PICKER_ALPHA_CHANNEL_HANDLE_CLASS = "dx-color-picker-alpha-handle",
  26512. COLOR_PICKER_ALPHA_CHANNEL_CELL_CLASS = "dx-alpha-channel-cell",
  26513. COLOR_PICKER_ALPHA_CHANNEL_BORDER_CLASS = "dx-alpha-channel-border",
  26514. COLOR_PICKER_COLOR_PREVIEW_CONTAINER_CLASS = "dx-color-picker-color-preview-container",
  26515. COLOR_PICKER_COLOR_PREVIEW_CONTAINER_INNER_CLASS = "dx-color-picker-color-preview-container-inner",
  26516. COLOR_PICKER_COLOR_PREVIEW = "dx-color-preview",
  26517. COLOR_PICKER_CURRENT_COLOR_PREVIEW = "dx-current-color",
  26518. COLOR_PICKER_NEW_COLOR_PREVIEW = "dx-new-color";
  26519. $.fn.colorPickerDrag = function(options) {
  26520. return this.each(function(i, el) {
  26521. var getCoordinatesFork = function() {
  26522. var Xmax,
  26523. Xmin,
  26524. Ymax,
  26525. Ymin;
  26526. var deltaX = parentWidth - halfOfElWidth,
  26527. deltaY = parentHeight - halfOfElHeight;
  26528. if (options.enableStripHalfOfWidth) {
  26529. Xmin = 0;
  26530. Xmax = parentWidth
  26531. }
  26532. else {
  26533. Xmin = halfOfElWidth;
  26534. Xmax = deltaX
  26535. }
  26536. if (options.enableStripHalfOfHeight) {
  26537. Ymin = 0;
  26538. Ymax = parentHeight
  26539. }
  26540. else {
  26541. Ymin = halfOfElHeight;
  26542. Ymax = deltaY
  26543. }
  26544. return {
  26545. x: {
  26546. min: Xmin,
  26547. max: Xmax
  26548. },
  26549. y: {
  26550. min: Ymin,
  26551. max: Ymax
  26552. }
  26553. }
  26554. };
  26555. var $base = $(el),
  26556. $parent = $base.parent(),
  26557. parentWidth = $parent.outerWidth(),
  26558. parentHeight = $parent.outerHeight(),
  26559. elHeight = $base.height(),
  26560. elWidth = $base.width(),
  26561. motionEnabled = false,
  26562. halfOfElHeight = elHeight / 2,
  26563. halfOfElWidth = elWidth / 2,
  26564. coordinates = getCoordinatesFork();
  26565. var defaultOptions = {
  26566. enableVerticalMotion: true,
  26567. enableHorizontalMotion: true,
  26568. moveByClick: true,
  26569. enableStripHalfOfWidth: false,
  26570. enableStripHalfOfHeight: false,
  26571. verticalMotionCallback: $.noop,
  26572. horizontalMotionCallback: $.noop,
  26573. _coordinatesUpdater: $.noop
  26574. };
  26575. options = $.extend(true, defaultOptions, options);
  26576. var moveElement = function(event) {
  26577. var x = options._coordinatesUpdater(event).x,
  26578. y = options._coordinatesUpdater(event).y;
  26579. changeElementPosition(x, y)
  26580. };
  26581. var changeElementPosition = function(x, y) {
  26582. if (options.enableVerticalMotion) {
  26583. if (y < coordinates.y.min)
  26584. y = coordinates.y.min;
  26585. if (y > coordinates.y.max)
  26586. y = coordinates.y.max;
  26587. $base.css("top", y - halfOfElHeight);
  26588. options.verticalMotionCallback(y)
  26589. }
  26590. if (options.enableHorizontalMotion) {
  26591. if (x < coordinates.x.min)
  26592. x = coordinates.x.min;
  26593. if (x > coordinates.x.max)
  26594. x = coordinates.x.max;
  26595. $base.css("right", "auto");
  26596. $base.css("left", x - halfOfElWidth);
  26597. options.horizontalMotionCallback(x)
  26598. }
  26599. };
  26600. if (!options._coordinatesUpdater)
  26601. options._coordinatesUpdater = function(event) {
  26602. return {
  26603. x: event.pageX - $parent.offset().left,
  26604. y: event.pageY - $parent.offset().top
  26605. }
  26606. };
  26607. $base.on(events.addNamespace("dxpointerdown", "dxColorPicker"), function() {
  26608. motionEnabled = true
  26609. });
  26610. $("*").on(events.addNamespace("dxpointerup", "dxColorPicker"), function() {
  26611. motionEnabled = false
  26612. });
  26613. $("body").on(events.addNamespace("dxpointermove", "dxColorPicker"), function(event) {
  26614. if (motionEnabled) {
  26615. event.preventDefault();
  26616. event.stopPropagation();
  26617. moveElement(event)
  26618. }
  26619. });
  26620. if (options.moveByClick)
  26621. $parent.on(events.addNamespace("dxpointerdown", "dxColorPicker"), function(event) {
  26622. motionEnabled = true;
  26623. moveElement(event)
  26624. })
  26625. })
  26626. };
  26627. var htmlCreator = {
  26628. createElement: function(tagName, cssClass, $parent) {
  26629. var el = document.createElement(tagName),
  26630. $el = $(el);
  26631. if (DX.utils.isArray(cssClass))
  26632. cssClass = cssClass.join(" ");
  26633. if (cssClass)
  26634. $el.addClass(cssClass);
  26635. if ($parent)
  26636. return $el.appendTo($parent);
  26637. else
  26638. return $el
  26639. },
  26640. createHtmlRows: function(count) {
  26641. var $rows = [];
  26642. for (var i = 0; i < count; i++)
  26643. $rows.push(this.createElement("div", COLOR_PICKER_ROW_CLASS));
  26644. return $rows
  26645. },
  26646. createHtmlCellInsideRow: function(rowIndex, $rowParent, additionalClass) {
  26647. var $row,
  26648. $rows = $rowParent.find("." + COLOR_PICKER_ROW_CLASS);
  26649. if (DX.utils.isNumber(rowIndex))
  26650. $row = $rows.eq(rowIndex);
  26651. else if (DX.utils.isString(rowIndex))
  26652. $row = $rows[rowIndex]();
  26653. var $cell = this.createElement("div", COLOR_PICKER_CELL_CLASS, $row);
  26654. if (additionalClass)
  26655. $cell.addClass(additionalClass);
  26656. return $cell
  26657. },
  26658. createInputWithLabel: function(labelText, labelClass, inputClass) {
  26659. return this.createElement("label", labelClass).text(labelText + ":").append(this.createElement("input", inputClass))
  26660. }
  26661. };
  26662. var colorHelper = {makeCSSLinearGradient: function($el) {
  26663. var color = this._currentColor,
  26664. colorAsRgb = [color.r, color.g, color.b].join(","),
  26665. colorAsHex = color.toHex().replace("#", "");
  26666. var combineGradientString = function(colorAsRgb, colorAsHex) {
  26667. var rtlEnabled = this.option("rtlEnabled"),
  26668. startColor = "rgba(" + colorAsRgb + ", " + (rtlEnabled ? "1" : "0") + ")",
  26669. finishColor = "rgba(" + colorAsRgb + ", " + (rtlEnabled ? "0" : "1") + ")",
  26670. startColorIE = "'#" + (rtlEnabled ? "00" : "") + colorAsHex + "'",
  26671. finishColorIE = "'#" + (rtlEnabled ? "" : "00") + colorAsHex + "'";
  26672. return ["background-image: -webkit-linear-gradient(180deg, " + startColor + ", " + finishColor + ")", "background-image: -moz-linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "background-image: -ms-linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "background-image: -o-linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "background-image: linear-gradient(-90deg, " + startColor + ", " + finishColor + ")", "filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=" + startColorIE + ", endColorstr=" + finishColorIE + ")", "-ms-filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr=" + startColorIE + ", endColorstr=" + finishColorIE + ")"].join(";")
  26673. };
  26674. $el.attr("style", combineGradientString.call(this, colorAsRgb, colorAsHex))
  26675. }};
  26676. DX.registerComponent("dxColorPicker", ui.dxDropDownEditor.inherit({
  26677. _setDefaultOptions: function() {
  26678. this.callBase();
  26679. this.option({
  26680. _dragCoordinatesUpdater: null,
  26681. _standAlone: false,
  26682. value: "#000000",
  26683. editAlphaChannel: false,
  26684. applyButtonText: Globalize.localize("OK"),
  26685. cancelButtonText: Globalize.localize("Cancel")
  26686. })
  26687. },
  26688. _setCurrentColor: function(value) {
  26689. var newColor = new DX.Color(value);
  26690. if (!newColor.colorIsInvalid) {
  26691. this._currentColor = new DX.Color(value);
  26692. this._alpha = this._currentColor.a
  26693. }
  26694. else
  26695. this.option("value", this._currentColor.baseColor)
  26696. },
  26697. _initColorAndOpacity: function() {
  26698. this._setCurrentColor(this.option("value"))
  26699. },
  26700. _init: function() {
  26701. this.callBase();
  26702. this._initColorAndOpacity()
  26703. },
  26704. _render: function() {
  26705. this.callBase();
  26706. this._element().addClass(COLOR_PICKER_CLASS);
  26707. if (this.option("_standAlone")) {
  26708. this._element().addClass("dx-standalone-colorpicker");
  26709. this._element().find(".dx-dropdowneditor-button").trigger("dxclick")
  26710. }
  26711. },
  26712. _optionChanged: function(name, value) {
  26713. switch (name) {
  26714. case"value":
  26715. this._input().val(value);
  26716. this._setCurrentColor(value);
  26717. this._makeTransparentBackground(this._$colorResultPreview);
  26718. this.callBase.apply(this, arguments);
  26719. break;
  26720. case"applyButtonText":
  26721. this._$applyButton.dxButton("instance").option("text", value);
  26722. break;
  26723. case"cancelButtonText":
  26724. this._$cancelButton.dxButton("instance").option("text", value);
  26725. break;
  26726. case"editAlphaChannel":
  26727. if (this._$colorPickerContainer) {
  26728. this._renderHtmlRows();
  26729. this._toggleContainerClass();
  26730. this._renderAlphaChannelElements()
  26731. }
  26732. break;
  26733. default:
  26734. this.callBase.apply(this, arguments)
  26735. }
  26736. },
  26737. _handleValueChangeEvent: function(e) {
  26738. if (this._dropDownVisible()) {
  26739. this._setCurrentColor(this._input().val());
  26740. this._refreshDropDown()
  26741. }
  26742. this.callBase(e)
  26743. },
  26744. _makeRgba: function() {
  26745. return "rgba(" + [this._currentColor.r, this._currentColor.g, this._currentColor.b, this._alpha].join(", ") + ")"
  26746. },
  26747. _makeTransparentBackground: function($el) {
  26748. if (DX.browser.msie && DX.browser.version === "8.0")
  26749. $el.css({
  26750. background: this._currentColor.toHex(),
  26751. filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=" + this._alpha * 100 + ")"
  26752. });
  26753. else
  26754. $el.css("backgroundColor", this._makeRgba())
  26755. },
  26756. _renderInput: function() {
  26757. this._$colorPickerInputContainer = $("<div/>").addClass(COLOR_PICKER_INPUT_CONTAINER_CLASS);
  26758. this._$colorResultPreview = htmlCreator.createElement("div", COLOR_PICKER_COLOR_RESULT_PREVIEW, this._$colorPickerInputContainer);
  26759. this._makeTransparentBackground(this._$colorResultPreview);
  26760. this.callBase(this._$colorPickerInputContainer);
  26761. this._input().addClass(COLOR_PICKER_INPUT_CLASS)
  26762. },
  26763. _renderValue: function(formattedValue) {
  26764. this.callBase(this.option("editAlphaChannel") ? this._makeRgba() : this.option("value"))
  26765. },
  26766. _closeOutsideDropDownHandler: function(e, ignoreContainerClicks) {
  26767. this.callBase(e, true)
  26768. },
  26769. _hideOnBlur: function() {
  26770. return false
  26771. },
  26772. _createDropDown: function() {
  26773. var that = this;
  26774. this.callBase({
  26775. height: "",
  26776. width: "",
  26777. contentReadyAction: function() {
  26778. that._createColorPickerContainer()
  26779. }
  26780. })
  26781. },
  26782. _showDropDown: function() {
  26783. if (!this._dropDownVisible()) {
  26784. this.callBase();
  26785. this._refreshDropDown()
  26786. }
  26787. },
  26788. _hideDropDown: function() {
  26789. if (this._dropDownVisible()) {
  26790. this._initColorAndOpacity();
  26791. this.callBase()
  26792. }
  26793. },
  26794. _calculateRowsCount: function() {
  26795. var rowCount = this.option("editAlphaChannel") ? 3 : 2,
  26796. $renderedRows = this._$colorPickerContainer.find("." + COLOR_PICKER_ROW_CLASS);
  26797. if (this.option("editAlphaChannel") && $renderedRows.length === 2)
  26798. rowCount = 1;
  26799. if (!this.option("editAlphaChannel") && $renderedRows.length === 3)
  26800. rowCount = 0;
  26801. return rowCount
  26802. },
  26803. _renderHtmlRows: function() {
  26804. var $renderedRows = this._$colorPickerContainer.find("." + COLOR_PICKER_ROW_CLASS),
  26805. rowCount = this._calculateRowsCount($renderedRows);
  26806. if (rowCount) {
  26807. var $rows = htmlCreator.createHtmlRows(rowCount);
  26808. if (rowCount === 1)
  26809. this._$colorPickerContainer.find("." + COLOR_PICKER_ROW_CLASS).eq(0).after($rows);
  26810. else
  26811. this._$colorPickerContainer.append($rows)
  26812. }
  26813. else
  26814. $renderedRows.eq(1).remove()
  26815. },
  26816. _toggleContainerClass: function() {
  26817. this._$colorPickerContainer.toggleClass(COLOR_PICKER_OVERLAY_WITHOUT_ALPHA_CHANNEL_CLASS, !this.option("editAlphaChannel"))
  26818. },
  26819. _renderAlphaChannelElements: function() {
  26820. if (this.option("editAlphaChannel")) {
  26821. this._renderAlphaChannelScale();
  26822. this._renderAlphaChannelInput()
  26823. }
  26824. },
  26825. _createColorPickerContainer: function() {
  26826. var $parent = this._dropDown.content();
  26827. if (this.option("_standAlone")) {
  26828. this._dropDown.hide();
  26829. $parent = this._element()
  26830. }
  26831. else
  26832. this._dropDown.content().addClass(COLOR_PICKER_OVERLAY_CLASS);
  26833. this._$colorPickerContainer = htmlCreator.createElement("div", COLOR_PICKER_CONTAINER_CLASS, $parent);
  26834. this._renderHtmlRows();
  26835. this._toggleContainerClass();
  26836. this._createPalette();
  26837. this._renderHueScale();
  26838. this._renderControlsContainer();
  26839. this._renderControls();
  26840. this._renderAlphaChannelElements();
  26841. this._renderButtons()
  26842. },
  26843. _createPalette: function() {
  26844. var $paletteCell = htmlCreator.createHtmlCellInsideRow("first", this._$colorPickerContainer, "dx-palette-cell"),
  26845. $paletteGradientWhite = htmlCreator.createElement("div", [COLOR_PICKER_PALETTE_GRADIENT_CLASS, COLOR_PICKER_PALETTE_GRADIENT_WHITE_CLASS]),
  26846. $paletteGradientBlack = htmlCreator.createElement("div", [COLOR_PICKER_PALETTE_GRADIENT_CLASS, COLOR_PICKER_PALETTE_GRADIENT_BLACK_CLASS]);
  26847. this._$palette = htmlCreator.createElement("div", COLOR_PICKER_PALETTE_CLASS, $paletteCell).css("backgroundColor", this._currentColor.getPureColor().toHex());
  26848. this._createColorChooser();
  26849. this._$palette.append([$paletteGradientWhite, $paletteGradientBlack])
  26850. },
  26851. _updateColor: function(isHex) {
  26852. var rgba,
  26853. newColor;
  26854. if (isHex)
  26855. newColor = this._validateHex("#" + this._$hexInput.val());
  26856. else {
  26857. rgba = this._validateRgb();
  26858. if (this._$alphaChannelInput) {
  26859. rgba.push(this._$alphaChannelInput.val());
  26860. newColor = "rgba(" + rgba.join(", ") + ")"
  26861. }
  26862. else
  26863. newColor = "rgb(" + rgba.join(", ") + ")"
  26864. }
  26865. this._currentColor = new DX.Color(newColor);
  26866. this._refreshDropDown()
  26867. },
  26868. _refreshDropDown: function() {
  26869. this._placeHueMarker();
  26870. this._placeColorChooser();
  26871. this._updateColorParamsAndColorPreview();
  26872. this._$palette.css("backgroundColor", this._currentColor.getPureColor().toHex());
  26873. if (this._$alphaChannelHandle) {
  26874. this._updateColorTransparence(this._currentColor.a);
  26875. this._placeAlphaChannelHandle()
  26876. }
  26877. },
  26878. _validateHex: function(hex) {
  26879. return this._currentColor.isValidHex(hex) ? hex : this._currentColor.toHex()
  26880. },
  26881. _validateRgb: function() {
  26882. var r = Number(this._$rgbInputs[0].val()),
  26883. g = Number(this._$rgbInputs[1].val()),
  26884. b = Number(this._$rgbInputs[2].val());
  26885. if (!this._currentColor.isValidRGB(r, g, b)) {
  26886. r = this._currentColor.r;
  26887. g = this._currentColor.g;
  26888. b = this._currentColor.b
  26889. }
  26890. return [r, g, b]
  26891. },
  26892. _placeHueMarker: function() {
  26893. var hueScaleHeight = this._$hueScale.parent().outerHeight(),
  26894. handleHeight = this._$hueScaleHandle.height();
  26895. var top = hueScaleHeight - hueScaleHeight * this._currentColor.hsv.h / 360 - handleHeight / 2;
  26896. if (hueScaleHeight < top + handleHeight)
  26897. top = hueScaleHeight - handleHeight;
  26898. if (top < 0)
  26899. top = 0;
  26900. this._$hueScaleHandle.css("top", Math.round(top))
  26901. },
  26902. _updateColorSaturation: function(value) {
  26903. var hue = this._currentColor.hsv.h,
  26904. saturation = Math.round(value * 100 / this._$palette.width()),
  26905. value = this._currentColor.hsv.v;
  26906. this._updateColorFromHsv(hue, saturation, value)
  26907. },
  26908. _updateColorValue: function(value) {
  26909. var hue = this._currentColor.hsv.h,
  26910. saturation = this._currentColor.hsv.s,
  26911. value = 100 - Math.round(value * 100 / this._$palette.height());
  26912. this._updateColorFromHsv(hue, saturation, value)
  26913. },
  26914. _updateColorHue: function(value) {
  26915. var hue = 360 - Math.round((value + this._$hueScaleHandle.outerHeight() / 2) * 360 / this._$hueScale.height()),
  26916. saturation = this._currentColor.hsv.s,
  26917. value = this._currentColor.hsv.v;
  26918. hue = hue < 0 ? 0 : hue;
  26919. this._updateColorFromHsv(hue, saturation, value);
  26920. this._$palette.css("backgroundColor", this._currentColor.getPureColor().toHex())
  26921. },
  26922. _updateColorTransparence: function(transparence) {
  26923. this._$alphaChannelInput.val(transparence);
  26924. this._alpha = transparence;
  26925. this._makeTransparentBackground(this._$newColor)
  26926. },
  26927. _calculateColorTransparenceByScaleWidth: function(value) {
  26928. var handleHalfWidth = this._$alphaChannelHandle.width() / 2,
  26929. alphaScaleWidth = this._$alphaChannelScale.width(),
  26930. rtlEnabled = this.option("rtlEnabled"),
  26931. transparence = value / this._$alphaChannelScale.width();
  26932. transparence = rtlEnabled ? transparence : 1 - transparence;
  26933. if (handleHalfWidth === value)
  26934. transparence = rtlEnabled ? 0 : 1;
  26935. else if (value >= alphaScaleWidth - handleHalfWidth)
  26936. transparence = rtlEnabled ? 1 : 0;
  26937. else if (transparence < 1)
  26938. transparence = transparence.toFixed(2);
  26939. this._updateColorTransparence(transparence)
  26940. },
  26941. _updateColorFromHsv: function(hue, saturation, value) {
  26942. this._currentColor = new DX.Color("hsv(" + [hue, saturation, value].join(",") + ")");
  26943. this._updateColorParamsAndColorPreview()
  26944. },
  26945. _updateColorParamsAndColorPreview: function() {
  26946. this._$hexInput.val(this._currentColor.toHex().replace("#", ""));
  26947. this._$rgbInputs[0].val(this._currentColor.r);
  26948. this._$rgbInputs[1].val(this._currentColor.g);
  26949. this._$rgbInputs[2].val(this._currentColor.b);
  26950. this._makeTransparentBackground(this._$newColor);
  26951. if (this.option("editAlphaChannel"))
  26952. colorHelper.makeCSSLinearGradient.call(this, this._$alphaChannelScale)
  26953. },
  26954. _createColorChooser: function() {
  26955. this._$colorChooser = htmlCreator.createElement("div", COLOR_PICKER_COLOR_CHOOSER_CLASS, this._$palette).colorPickerDrag({
  26956. verticalMotionCallback: $.proxy(this._updateColorValue, this),
  26957. horizontalMotionCallback: $.proxy(this._updateColorSaturation, this),
  26958. enableStripHalfOfWidth: true,
  26959. enableStripHalfOfHeight: true,
  26960. _coordinatesUpdater: this.option("_dragCoordinatesUpdater")
  26961. });
  26962. this._placeColorChooser()
  26963. },
  26964. _placeColorChooser: function() {
  26965. var paletteHeight = this._$palette.height(),
  26966. colorChooserPosition = {
  26967. x: Math.round(this._$palette.width() * this._currentColor.hsv.s / 100 - this._$colorChooser.width() / 2),
  26968. y: Math.round(paletteHeight - paletteHeight * this._currentColor.hsv.v / 100 - this._$colorChooser.height() / 2)
  26969. };
  26970. this._$colorChooser.css({
  26971. left: colorChooserPosition.x,
  26972. top: colorChooserPosition.y
  26973. })
  26974. },
  26975. _renderHueScale: function() {
  26976. var $hueScaleCell = htmlCreator.createHtmlCellInsideRow("first", this._$colorPickerContainer, "dx-hue-scale-cell");
  26977. this._$hueScale = htmlCreator.createElement("div", COLOR_PICKER_HUE_SCALE_CLASS, $hueScaleCell);
  26978. this._$hueScale.wrap("<div class=\"" + COLOR_PICKER_HUE_SCALE_WRAPPER_CLASS + "\"/>");
  26979. this._renderHueScaleHandle()
  26980. },
  26981. _renderHueScaleHandle: function() {
  26982. this._$hueScaleHandle = htmlCreator.createElement("div", COLOR_PICKER_HUE_SCALE_HANDLE_CLASS, this._$hueScale.closest("." + COLOR_PICKER_HUE_SCALE_WRAPPER_CLASS)).colorPickerDrag({
  26983. enableHorizontalMotion: false,
  26984. verticalMotionCallback: $.proxy(this._updateColorHue, this),
  26985. _coordinatesUpdater: this.option("_dragCoordinatesUpdater")
  26986. });
  26987. this._placeHueMarker()
  26988. },
  26989. _renderControlsContainer: function() {
  26990. var $controlsContainerCell = htmlCreator.createHtmlCellInsideRow("first", this._$colorPickerContainer);
  26991. this._$controlsContainer = htmlCreator.createElement("div", COLOR_PICKER_CONTROLS_CONTAINER_CLASS, $controlsContainerCell)
  26992. },
  26993. _renderControls: function() {
  26994. this._renderColorsPreview();
  26995. this._renderRgbInputs();
  26996. this._renderHexInput()
  26997. },
  26998. _renderButtons: function() {
  26999. var $buttonContainerCell = htmlCreator.createHtmlCellInsideRow("last", this._$colorPickerContainer, "dx-buttons-cell");
  27000. this._$buttonContainer = htmlCreator.createElement("div", COLOR_PICKER_BUTTONS_CONTAINER_CLASS, $buttonContainerCell);
  27001. this._renderApplyButton();
  27002. this._renderCancelButton()
  27003. },
  27004. _renderApplyButton: function() {
  27005. this._$applyButton = htmlCreator.createElement("div", COLOR_PICKER_APPLY_BUTTON_CLASS, this._$buttonContainer).dxButton({
  27006. text: this.option("applyButtonText"),
  27007. clickAction: $.proxy(this._applyColor, this)
  27008. })
  27009. },
  27010. _applyColor: function() {
  27011. var colorValue = this.option("editAlphaChannel") ? this._makeRgba() : this._currentColor.toHex();
  27012. this._input().val(colorValue);
  27013. this._makeTransparentBackground(this._$colorResultPreview);
  27014. this._makeTransparentBackground(this._$currentColor);
  27015. this.option("value", colorValue);
  27016. this._hideDropDown()
  27017. },
  27018. _cancelChanges: function() {
  27019. if (!this.option("_standAlone"))
  27020. this._hideDropDown();
  27021. else {
  27022. this._initColorAndOpacity();
  27023. this._refreshDropDown()
  27024. }
  27025. },
  27026. _renderCancelButton: function() {
  27027. this._$cancelButton = htmlCreator.createElement("div", COLOR_PICKER_CANCEL_BUTTON_CLASS, this._$buttonContainer).dxButton({
  27028. text: this.option("cancelButtonText"),
  27029. clickAction: $.proxy(this._cancelChanges, this)
  27030. })
  27031. },
  27032. _renderRgbInputs: function() {
  27033. this._$rgbInputsWithLabels = [htmlCreator.createInputWithLabel("R", COLOR_PICKER_RED_LABEL_CLASS, COLOR_PICKER_RED_INPUT_CLASS), htmlCreator.createInputWithLabel("G", COLOR_PICKER_GREEN_LABEL_CLASS, COLOR_PICKER_GREEN_INPUT_CLASS), htmlCreator.createInputWithLabel("B", COLOR_PICKER_BLUE_LABEL_CLASS, COLOR_PICKER_BLUE_INPUT_CLASS)];
  27034. this._$rgbInputs = [this._$rgbInputsWithLabels[0].find("input").val(this._currentColor.r).on("change", $.proxy(this._updateColor, this, false)), this._$rgbInputsWithLabels[1].find("input").val(this._currentColor.g).on("change", $.proxy(this._updateColor, this, false)), this._$rgbInputsWithLabels[2].find("input").val(this._currentColor.b).on("change", $.proxy(this._updateColor, this, false))];
  27035. this._$controlsContainer.append(this._$rgbInputsWithLabels)
  27036. },
  27037. _renderHexInput: function() {
  27038. var $hexInputWithLabel = htmlCreator.createInputWithLabel("#", COLOR_PICKER_HEX_LABEL_CLASS, COLOR_PICKER_HEX_INPUT_CLASS).appendTo(this._$controlsContainer);
  27039. this._$hexInput = $hexInputWithLabel.find("input").val(this._currentColor.toHex().replace("#", "")).on("change", $.proxy(this._updateColor, this, true))
  27040. },
  27041. _renderColorsPreview: function() {
  27042. var $colorsPreviewContainer = htmlCreator.createElement("div", COLOR_PICKER_COLOR_PREVIEW_CONTAINER_CLASS, this._$controlsContainer),
  27043. $colorsPreviewContainerInner = htmlCreator.createElement("div", COLOR_PICKER_COLOR_PREVIEW_CONTAINER_INNER_CLASS, $colorsPreviewContainer);
  27044. this._$currentColor = htmlCreator.createElement("div", [COLOR_PICKER_COLOR_PREVIEW, COLOR_PICKER_CURRENT_COLOR_PREVIEW]);
  27045. this._$newColor = htmlCreator.createElement("div", [COLOR_PICKER_COLOR_PREVIEW, COLOR_PICKER_NEW_COLOR_PREVIEW]);
  27046. this._makeTransparentBackground(this._$currentColor);
  27047. this._makeTransparentBackground(this._$newColor);
  27048. $colorsPreviewContainerInner.append([this._$currentColor, this._$newColor])
  27049. },
  27050. _renderAlphaChannelScale: function() {
  27051. var $alphaChannelScaleCell = htmlCreator.createHtmlCellInsideRow(1, this._$colorPickerContainer, COLOR_PICKER_ALPHA_CHANNEL_CELL_CLASS),
  27052. $alphaChannelBorder = htmlCreator.createElement("div", COLOR_PICKER_ALPHA_CHANNEL_BORDER_CLASS, $alphaChannelScaleCell),
  27053. $alphaChannelScaleWrapper = htmlCreator.createElement("div", COLOR_PICKER_ALPHA_CHANNEL_SCALE_WRAPPER_CLASS, $alphaChannelBorder);
  27054. this._$alphaChannelScale = htmlCreator.createElement("div", COLOR_PICKER_ALPHA_CHANNEL_SCALE_CLASS, $alphaChannelScaleWrapper);
  27055. colorHelper.makeCSSLinearGradient.call(this, this._$alphaChannelScale);
  27056. this._renderAlphaChannelHandle($alphaChannelScaleCell)
  27057. },
  27058. _renderAlphaChannelInput: function() {
  27059. var that = this,
  27060. $alphaChannelInputCell = htmlCreator.createHtmlCellInsideRow(1, this._$colorPickerContainer),
  27061. $alphaChannelInputWithLabel = htmlCreator.createInputWithLabel("Alpha", COLOR_PICKER_ALPHA_CHANNEL_LABEL_CLASS, COLOR_PICKER_ALPHA_CHANNEL_INPUT_CLASS).appendTo($alphaChannelInputCell);
  27062. this._$alphaChannelInput = $alphaChannelInputWithLabel.find("input").val(this._alpha).on("change", function() {
  27063. var value = Number($(this).val());
  27064. value = that._currentColor.isValidAlpha(value) ? value : that._alpha;
  27065. that._updateColorTransparence(value);
  27066. that._placeAlphaChannelHandle()
  27067. })
  27068. },
  27069. _renderAlphaChannelHandle: function($parent) {
  27070. this._$alphaChannelHandle = htmlCreator.createElement("div", COLOR_PICKER_ALPHA_CHANNEL_HANDLE_CLASS, $parent).colorPickerDrag({
  27071. enableVerticalMotion: false,
  27072. horizontalMotionCallback: $.proxy(this._calculateColorTransparenceByScaleWidth, this),
  27073. _coordinatesUpdater: this.option("_dragCoordinatesUpdater")
  27074. });
  27075. this._placeAlphaChannelHandle()
  27076. },
  27077. _placeAlphaChannelHandle: function() {
  27078. var alphaChannelScaleWidth = this._$alphaChannelScale.closest("." + COLOR_PICKER_ALPHA_CHANNEL_CELL_CLASS).outerWidth(),
  27079. handleWidth = this._$alphaChannelHandle.width();
  27080. var left = alphaChannelScaleWidth - alphaChannelScaleWidth * this._alpha - handleWidth / 2;
  27081. if (left < 0)
  27082. left = 0;
  27083. if (alphaChannelScaleWidth < left + handleWidth)
  27084. left = alphaChannelScaleWidth - handleWidth;
  27085. this._$alphaChannelHandle.css(this.option("rtlEnabled") ? "right" : "left", left)
  27086. }
  27087. }))
  27088. })(jQuery, DevExpress);
  27089. /*! Module widgets-web, file ui.menuBase.js */
  27090. (function($, DX, undefined) {
  27091. var ui = DX.ui,
  27092. utils = DX.utils,
  27093. events = ui.events;
  27094. var DX_MENU_CLASS = 'dx-menu',
  27095. DX_MENU_ITEM_CLASS = DX_MENU_CLASS + '-item',
  27096. DX_MENU_ITEM_HOVERED_CLASS = 'dx-state-hover',
  27097. DX_MENU_ITEM_CAPTION_CLASS = DX_MENU_ITEM_CLASS + '-text',
  27098. DX_MENU_ITEM_POPOUT_CLASS = DX_MENU_ITEM_CLASS + '-popout',
  27099. DX_MENU_ITEM_POPOUT_CONTAINER_CLASS = DX_MENU_ITEM_POPOUT_CLASS + '-container',
  27100. DX_MENU_ITEM_DISABLED_CLASS = DX_MENU_ITEM_CLASS + '-disabled',
  27101. DX_MENU_ITEM_SELECTED_CLASS = DX_MENU_ITEM_CLASS + '-selected',
  27102. DX_MENU_ITEM_WRAPPER_CLASS = DX_MENU_ITEM_CLASS + '-wrapper',
  27103. DX_MENU_RTL_CLASS = DX_MENU_CLASS + '-rtl',
  27104. DX_ICON_CLASS = 'dx-icon';
  27105. var dxMenuBase = ui.CollectionContainerWidget.inherit({
  27106. _itemRenderDefault: function(item, index, $itemElement) {
  27107. var $itemContent,
  27108. rtlEnabled;
  27109. if (!utils.isDefined(item))
  27110. return;
  27111. if (item.visible !== undefined && !item.visible)
  27112. $itemElement.hide();
  27113. if (item.disabled)
  27114. $itemElement.addClass(DX_MENU_ITEM_DISABLED_CLASS);
  27115. rtlEnabled = !!this.option('rtlEnabled');
  27116. if (rtlEnabled)
  27117. $itemElement.addClass(DX_MENU_RTL_CLASS);
  27118. $itemContent = $('<div>').addClass('dx-menu-item-content').appendTo($itemElement);
  27119. this._renderImage(item, $itemContent);
  27120. this._renderCaption(item, $itemContent);
  27121. this._renderPopout(item, $itemContent)
  27122. },
  27123. _renderImage: function(item, $itemContent) {
  27124. var $itemImage,
  27125. $imageContainer;
  27126. if (item.icon)
  27127. $itemImage = $('<span>').addClass(DX_ICON_CLASS + "-" + item.icon).appendTo($itemContent);
  27128. else if (item.iconSrc)
  27129. $itemImage = $('<img>').attr('src', item.iconSrc).appendTo($itemContent);
  27130. if ($itemImage)
  27131. $itemImage.addClass(DX_ICON_CLASS)
  27132. },
  27133. _renderPopout: function(item, $itemContent) {
  27134. var $popOutImage,
  27135. $popOutContainer;
  27136. if (this._hasChildren(item)) {
  27137. $popOutContainer = $('<span>').addClass(DX_MENU_ITEM_POPOUT_CONTAINER_CLASS).appendTo($itemContent);
  27138. $popOutImage = $('<div>').addClass(DX_MENU_ITEM_POPOUT_CLASS).appendTo($popOutContainer)
  27139. }
  27140. },
  27141. _renderCaption: function(item, $itemContent) {
  27142. var $itemCaption;
  27143. $itemCaption = $('<span>').addClass(DX_MENU_ITEM_CAPTION_CLASS);
  27144. if ($.isPlainObject(item)) {
  27145. if (item.text)
  27146. $itemCaption.text(item.text)
  27147. }
  27148. else
  27149. $itemCaption.html(String(item));
  27150. $itemContent.append($itemCaption)
  27151. },
  27152. _renderItemHotTrack: function($item, showHotTrack) {
  27153. var $itemWrapper,
  27154. menuItem;
  27155. menuItem = $item.data(this._itemDataKey());
  27156. if (menuItem == this.option('selectedItem') && showHotTrack)
  27157. return;
  27158. if (!!this.option('hoverStateEnabled')) {
  27159. $itemWrapper = $item.parents('.' + DX_MENU_ITEM_WRAPPER_CLASS).eq(0);
  27160. if ($itemWrapper.length)
  27161. $itemWrapper.toggleClass(DX_MENU_ITEM_HOVERED_CLASS, showHotTrack)
  27162. }
  27163. },
  27164. _itemDataKey: function() {
  27165. return 'dxMenuItemDataKey'
  27166. },
  27167. _itemClass: function() {
  27168. return DX_MENU_ITEM_CLASS
  27169. },
  27170. _itemWrapperSelector: function() {
  27171. return '.' + DX_MENU_ITEM_WRAPPER_CLASS
  27172. },
  27173. _attachItemHoverEvents: function() {
  27174. var itemSelector = this._itemWrapperSelector(),
  27175. mouseEnterEventName,
  27176. mouseLeaveEventName,
  27177. itemMouseEnterAction = this._createAction($.proxy(function(e) {
  27178. this._handleItemMouseEnter(e.jQueryEvent)
  27179. }, this)),
  27180. itemMouseLeaveAction = this._createAction($.proxy(function(e) {
  27181. this._handleItemMouseLeave(e.jQueryEvent)
  27182. }, this));
  27183. mouseEnterEventName = events.addNamespace('mouseenter', this.NAME);
  27184. mouseLeaveEventName = events.addNamespace('mouseleave', this.NAME);
  27185. this._itemContainer().off(mouseEnterEventName, itemSelector).on(mouseEnterEventName, itemSelector, $.proxy(function(e) {
  27186. itemMouseEnterAction({jQueryEvent: e})
  27187. }, this));
  27188. this._itemContainer().off(mouseLeaveEventName, itemSelector).on(mouseLeaveEventName, itemSelector, $.proxy(function(e) {
  27189. itemMouseLeaveAction({jQueryEvent: e})
  27190. }, this))
  27191. },
  27192. _handleItemMouseMove: function(eventArgs) {
  27193. var that = this,
  27194. $item = that._getItemElementByEventArgs(eventArgs);
  27195. if (!that._itemX)
  27196. that._itemX = 0;
  27197. if (!that._itemY)
  27198. that._itemY = 0;
  27199. if (Math.abs(event.pageX - that._itemX) > 4 || Math.abs(event.pageY - that._itemY) > 4) {
  27200. that._itemX = event.pageX;
  27201. that._itemY = event.pageY;
  27202. that._handleItemMouseMoveCore($item)
  27203. }
  27204. },
  27205. _hasChildren: function(item) {
  27206. return item.items && item.items.length > 0
  27207. },
  27208. _addCustomCssClass: function($element) {
  27209. var cssClass = $.trim(this.option('cssClass'));
  27210. if (cssClass)
  27211. $element.addClass(cssClass)
  27212. },
  27213. _init: function() {
  27214. var items = this.option('items');
  27215. this.callBase();
  27216. this.selectedItem = this.option('selectedItem');
  27217. this.enableSelection = this.option('allowSelection');
  27218. if (utils.isDefined(this.selectedItem) && this.selectedItem != null)
  27219. return;
  27220. this.selectedItem = this._getLastSelectedItem(items);
  27221. if (this.selectedItem)
  27222. this._setOptionInternal('selectedItem', this.selectedItem)
  27223. },
  27224. _setOptionInternal: function(name, value) {
  27225. this._optionChangedInternalFlag = true;
  27226. this.option(name, value);
  27227. this._optionChangedInternalFlag = false
  27228. },
  27229. _getLastSelectedItem: function(items) {
  27230. var that = this,
  27231. selectedItem = null,
  27232. nestedSelectedItem;
  27233. $.each(items, function(_, item) {
  27234. if (item) {
  27235. if (item.selected && item.selectable)
  27236. selectedItem = item;
  27237. if (utils.isArray(item.items)) {
  27238. nestedSelectedItem = that._getLastSelectedItem(item.items);
  27239. if (nestedSelectedItem)
  27240. selectedItem = nestedSelectedItem
  27241. }
  27242. }
  27243. });
  27244. return selectedItem
  27245. },
  27246. _updateSelectedItemOnClick: function($itemElement, itemData) {
  27247. var prevSelItem = this.$selectedItemWrapper ? this.$selectedItemWrapper.children('.dx-menu-item').eq(0).data(this._itemDataKey()) : null,
  27248. actionArgs = {
  27249. selectedItem: itemData,
  27250. previousSelectedItem: prevSelItem,
  27251. itemElement: $itemElement,
  27252. itemData: itemData
  27253. },
  27254. itemSelectAction = this._createActionByOption("itemSelectAction", actionArgs);
  27255. if (this.option('allowSelectOnClick') && itemData.selectable) {
  27256. if (this.$selectedItemWrapper) {
  27257. this.$selectedItemWrapper.removeClass(DX_MENU_ITEM_SELECTED_CLASS);
  27258. if (this.$selectedItemWrapper.children('.dx-menu-item').eq(0).data(this._itemDataKey()))
  27259. this.$selectedItemWrapper.children('.dx-menu-item').eq(0).data(this._itemDataKey()).selected = false
  27260. }
  27261. this._setOptionInternal('selectedItem', null);
  27262. this.$selectedItemWrapper = $itemElement.parents('.dx-menu-item-wrapper').eq(0);
  27263. this.$selectedItemWrapper.addClass(DX_MENU_ITEM_SELECTED_CLASS);
  27264. this._setOptionInternal('selectedItem', itemData);
  27265. itemData.selected = true;
  27266. itemSelectAction(actionArgs)
  27267. }
  27268. },
  27269. _handleItemClick: function(e) {
  27270. var itemClickActionHandler = this._createAction($.proxy(this._updateOverlayVisibilityOnClick, this));
  27271. this._handleItemJQueryEvent(e, "itemClickAction", {}, {afterExecute: $.proxy(itemClickActionHandler, this)})
  27272. },
  27273. _getItemElementByEventArgs: function(eventArgs) {
  27274. return $(eventArgs.currentTarget).children(this._itemSelector()).first()
  27275. }
  27276. });
  27277. ui.dxMenuBase = dxMenuBase
  27278. })(jQuery, DevExpress);
  27279. /*! Module widgets-web, file ui.contextMenu.js */
  27280. (function($, DX, undefined) {
  27281. var ui = DX.ui,
  27282. utils = DX.utils,
  27283. events = ui.events,
  27284. fx = DX.fx,
  27285. DXMENU = 'dxContextMenu';
  27286. var DX_MENU_CLASS = 'dx-menu',
  27287. DX_MENU_ITEM_CLASS = DX_MENU_CLASS + '-item',
  27288. DX_MENU_ITEM_POPOUT_CLASS = DX_MENU_ITEM_CLASS + '-popout',
  27289. DX_MENU_ITEM_SELECTED_CLASS = DX_MENU_ITEM_CLASS + '-selected',
  27290. DX_MENU_ITEM_HOVERED_CLASS = 'dx-state-hover',
  27291. DX_MENU_PHONE_CLASS = 'dx-menu-phone-overlay',
  27292. DX_MENU_ITEMS_CONTAINER_CLASS = DX_MENU_CLASS + '-items-container',
  27293. DX_MENU_ITEM_WRAPPER_CLASS = DX_MENU_ITEM_CLASS + '-wrapper',
  27294. DX_SUBMENU_CLASS = 'dx-submenu',
  27295. DX_SUBMENU_LEVEL_ID = 'dxSubMenuLevel',
  27296. DX_CONTEXT_MENU_CLASS = 'dx-context-menu',
  27297. DX_WIDGET_CLASS = 'dx-widget',
  27298. DX_MENU_SEPARATOR_CLASS = DX_MENU_CLASS + '-separator',
  27299. DX_CONTEXT_MENU_CONTENT_DELIMITER_CLASS = DX_CONTEXT_MENU_CLASS + '-content-delimiter';
  27300. DX.registerComponent("dxContextMenu", ui.dxMenuBase.inherit({
  27301. _deprecatedOptions: {
  27302. direction: {
  27303. since: "14.1",
  27304. message: "Use the 'submenuDirection' option instead."
  27305. },
  27306. allowSelectItem: {
  27307. since: "14.1",
  27308. message: "Use the 'allowSelection' option instead."
  27309. }
  27310. },
  27311. _optionAliases: {
  27312. direction: "submenuDirection",
  27313. allowSelectItem: "allowSelection"
  27314. },
  27315. _setDefaultOptions: function() {
  27316. this.callBase();
  27317. this.option({
  27318. items: [],
  27319. showSubmenuMode: 'onHover',
  27320. cssClass: '',
  27321. invokeOnlyFromCode: false,
  27322. position: {
  27323. at: 'top left',
  27324. my: 'top left'
  27325. },
  27326. hoverStateEnabled: true,
  27327. allowSelection: true,
  27328. allowSelectItem: true,
  27329. allowSelectOnClick: true,
  27330. selectedItem: null,
  27331. itemSelectAction: null,
  27332. animation: {
  27333. show: {
  27334. type: "fade",
  27335. from: 0,
  27336. to: 1,
  27337. duration: 100
  27338. },
  27339. hide: {
  27340. type: 'fade',
  27341. from: 1,
  27342. to: 0,
  27343. duration: 100
  27344. }
  27345. },
  27346. showingAction: null,
  27347. shownAction: null,
  27348. hidingAction: null,
  27349. hiddenAction: null,
  27350. positioningAction: null,
  27351. submenuDirection: 'auto',
  27352. direction: 'auto',
  27353. visible: false,
  27354. target: window
  27355. })
  27356. },
  27357. _optionsByReference: function() {
  27358. return $.extend(this.callBase(), {
  27359. animation: true,
  27360. position: true,
  27361. selectedItem: true
  27362. })
  27363. },
  27364. _itemContainer: function() {
  27365. return this._overlay.content()
  27366. },
  27367. _clean: function() {
  27368. if (this._overlay) {
  27369. this._overlay._element().remove();
  27370. this._overlay = null
  27371. }
  27372. this._target.off(events.addNamespace('dxhold', this.NAME));
  27373. this._target.off(events.addNamespace('contextmenu', this.NAME))
  27374. },
  27375. _optionChanged: function(name, value) {
  27376. if (this._optionChangedInternalFlag)
  27377. return;
  27378. switch (name) {
  27379. case'visible':
  27380. this._toggleVisibility(value);
  27381. break;
  27382. case'disable':
  27383. break;
  27384. case'invokeOnlyFromCode':
  27385. break;
  27386. case'items':
  27387. if (this._overlay.option('visible'))
  27388. this._overlay.toggle(false);
  27389. this.selectedItem = this._getLastSelectedItem(value);
  27390. this._setOptionInternal('selectedItem', this.selectedItem);
  27391. this.callBase.apply(this, arguments);
  27392. break;
  27393. case'selectedItem':
  27394. this.selectedItem = value;
  27395. break;
  27396. default:
  27397. if (this._overlay.option('visible'))
  27398. this._overlay.toggle(false);
  27399. this.callBase.apply(this, arguments)
  27400. }
  27401. },
  27402. _toggleVisibility: function(value) {
  27403. value ? this.show() : this.hide()
  27404. },
  27405. _render: function() {
  27406. this._target = $(this.option('target'));
  27407. this.option('position');
  27408. this.callBase()
  27409. },
  27410. _renderContentImpl: function() {
  27411. this._renderContextMenuOverlay();
  27412. this._renderAdditionGraphicsElements();
  27413. this._attachItemHoverEvents();
  27414. this._attachShowContextMenuEvents();
  27415. this._addCustomCssClass(this._element());
  27416. this.callBase()
  27417. },
  27418. _renderDimensions: function(){},
  27419. _renderContextMenuOverlay: function() {
  27420. var $overlayElement,
  27421. $overlayContent,
  27422. overlayOptions = this._getOverlayOptions();
  27423. $overlayElement = $('<div>').appendTo(this._$element);
  27424. $overlayElement.dxOverlay(overlayOptions);
  27425. this._overlay = $overlayElement.dxOverlay('instance');
  27426. $overlayContent = this._overlay.content();
  27427. $overlayContent.addClass(DX_CONTEXT_MENU_CLASS).addClass(DX_WIDGET_CLASS);
  27428. this._addCustomCssClass($overlayContent);
  27429. this._addPlatformDependentClass($overlayContent);
  27430. if (this.option('visible'))
  27431. this.show()
  27432. },
  27433. _addPlatformDependentClass: function($element) {
  27434. if (DX.devices.current().phone)
  27435. $element.addClass(DX_MENU_PHONE_CLASS)
  27436. },
  27437. _renderAdditionGraphicsElements: function() {
  27438. if (this.option('showAdditionalElements')) {
  27439. this.$contentDelimiter = $('<div>').appendTo(this._itemContainer());
  27440. this.$contentDelimiter.addClass(DX_CONTEXT_MENU_CONTENT_DELIMITER_CLASS);
  27441. this.$contentDelimiter.css('position', 'absolute').css('display', 'none').css('z-index', '2000')
  27442. }
  27443. },
  27444. _attachShowContextMenuEvents: function() {
  27445. var that = this,
  27446. holdEventName = events.addNamespace('dxhold', this.NAME),
  27447. rightClickEventName = events.addNamespace('contextmenu', this.NAME),
  27448. holdAction = this._createAction($.proxy(function(e) {
  27449. if (!that.option('invokeOnlyFromCode'))
  27450. if (e.jQueryEvent.originalEvent && e.jQueryEvent.originalEvent.pointerType !== 'mouse')
  27451. that.show(e.jQueryEvent)
  27452. }, this)),
  27453. contextMenuAction = this._createAction($.proxy(function(e) {
  27454. if (!that.option('invokeOnlyFromCode'))
  27455. if (that.show(e.jQueryEvent)) {
  27456. e.jQueryEvent.preventDefault();
  27457. if (e.jQueryEvent.originalEvent)
  27458. e.jQueryEvent.originalEvent.returnValue = false
  27459. }
  27460. }, this));
  27461. this._target.off(holdEventName).on(holdEventName, $.proxy(function(e) {
  27462. holdAction({jQueryEvent: e})
  27463. }, this)).off(rightClickEventName).on(rightClickEventName, $.proxy(function(e) {
  27464. contextMenuAction({jQueryEvent: e})
  27465. }, this))
  27466. },
  27467. _renderItems: function(items) {
  27468. var FIRST_SUBMENU_LEVEL = 1;
  27469. this._renderSubMenu(items, this._itemContainer(), FIRST_SUBMENU_LEVEL)
  27470. },
  27471. _renderSubMenu: function(items, $holder, subMenuLevel) {
  27472. var that = this,
  27473. $subMenu,
  27474. $itemsContainer,
  27475. $itemWrapper,
  27476. $item;
  27477. if (items.length) {
  27478. $subMenu = $('<div>').appendTo($holder);
  27479. $subMenu.addClass(DX_SUBMENU_CLASS);
  27480. $subMenu.data(DX_SUBMENU_LEVEL_ID, subMenuLevel);
  27481. $subMenu.css('display', subMenuLevel === 1 ? 'block' : 'none');
  27482. $itemsContainer = $('<ul>').appendTo($subMenu);
  27483. $itemsContainer.addClass(DX_MENU_ITEMS_CONTAINER_CLASS);
  27484. if (subMenuLevel === 1) {
  27485. if (that.option('width'))
  27486. $itemsContainer.css('min-width', that.option('width'));
  27487. if (that.option('height'))
  27488. $itemsContainer.css('min-height', that.option('height'))
  27489. }
  27490. $.each(items, function(index, item) {
  27491. that._renderSeparator(item, index, $itemsContainer);
  27492. $itemWrapper = $('<li>').appendTo($itemsContainer);
  27493. $itemWrapper.addClass(DX_MENU_ITEM_WRAPPER_CLASS);
  27494. $item = that._renderItem(index, item, $itemWrapper);
  27495. if (that.option('allowSelection') && item === that.option('selectedItem')) {
  27496. $itemWrapper.addClass(DX_MENU_ITEM_SELECTED_CLASS);
  27497. that.$selectedItemWrapper = $itemWrapper
  27498. }
  27499. if (that._hasChildren(item))
  27500. that._renderSubMenu(item.items, $item, ++subMenuLevel)
  27501. })
  27502. }
  27503. },
  27504. _renderSeparator: function(item, index, $itemsContainer) {
  27505. var $separator;
  27506. if (item.beginGroup && index > 0) {
  27507. $separator = $('<li>').appendTo($itemsContainer);
  27508. $separator.addClass(DX_MENU_SEPARATOR_CLASS)
  27509. }
  27510. },
  27511. _showAdditionalGraphicsElements: function() {
  27512. var $subMenu = this._itemContainer().children('.dx-submenu').eq(0),
  27513. $rootItem = this.option('position').of,
  27514. positionAt = this.option('position').at,
  27515. positionMy = this.option('position').my,
  27516. position = {of: $subMenu};
  27517. if (this.$contentDelimiter) {
  27518. this.$contentDelimiter.css('display', 'block');
  27519. if (positionAt === 'left bottom' && positionMy === 'left top' || positionAt === 'right bottom' && positionMy === 'right top') {
  27520. this.$contentDelimiter.width($rootItem.width() < $subMenu.width() ? $rootItem.width() - 2 : $subMenu.width() - 2);
  27521. if (this._itemContainer().offset().top > $rootItem.offset().top) {
  27522. this.$contentDelimiter.height(2);
  27523. if (Math.round(this._itemContainer().offset().left) < Math.round($rootItem.offset().left)) {
  27524. position.offset = '-1 -1';
  27525. position.at = 'right top';
  27526. position.my = 'right top'
  27527. }
  27528. else {
  27529. position.offset = '1 -1';
  27530. position.at = 'left top';
  27531. position.my = 'left top'
  27532. }
  27533. }
  27534. else {
  27535. this.$contentDelimiter.height(3);
  27536. if (Math.round(this._itemContainer().offset().left) < Math.round($rootItem.offset().left)) {
  27537. position.offset = '-1 2';
  27538. position.at = 'right bottom';
  27539. position.my = 'right bottom'
  27540. }
  27541. else {
  27542. position.offset = '1 2';
  27543. position.at = 'left bottom';
  27544. position.my = 'left bottom'
  27545. }
  27546. }
  27547. }
  27548. else {
  27549. this.$contentDelimiter.width(2);
  27550. this.$contentDelimiter.height($rootItem.height() < $subMenu.height() ? $rootItem.height() - 2 : $subMenu.height() - 2);
  27551. if (this._itemContainer().offset().top < $rootItem.offset().top) {
  27552. position.offset = positionAt === 'right top' ? '-1 -1' : '1 -1';
  27553. position.at = positionAt === 'right top' ? 'left bottom' : 'right bottom';
  27554. position.my = position.at
  27555. }
  27556. else {
  27557. position.offset = positionAt === 'right top' ? '-1 1' : '1 1';
  27558. position.at = positionMy;
  27559. position.my = positionMy
  27560. }
  27561. }
  27562. DX.position(this.$contentDelimiter, position)
  27563. }
  27564. },
  27565. _getOverlayOptions: function() {
  27566. var that = this,
  27567. overlayAnimation = this.option('animation'),
  27568. overlayOptions = {
  27569. animation: overlayAnimation,
  27570. closeOnOutsideClick: $.proxy(that._closeOnOutsideClickHandler, that),
  27571. closeOnTargetScroll: true,
  27572. deferRendering: false,
  27573. disabled: this.option('disabled'),
  27574. position: {
  27575. at: this.option('position').at,
  27576. my: this.option('position').my,
  27577. of: this._target
  27578. },
  27579. shading: false,
  27580. showTitle: false,
  27581. height: 'auto',
  27582. width: 'auto',
  27583. rtlEnabled: this.option('rtlEnabled'),
  27584. showingAction: $.proxy(that._overlayShowingActionHandler, that),
  27585. shownAction: $.proxy(that._overlayShownActionHandler, that),
  27586. hidingAction: $.proxy(that._overlayHidingActionHandler, that),
  27587. hiddenAction: $.proxy(that._overlayHiddenActionHandler, that),
  27588. positionedAction: $.proxy(that._overlayPositionedActionHandler, that)
  27589. };
  27590. return overlayOptions
  27591. },
  27592. _removeHoverClass: function() {
  27593. var that = this,
  27594. hovered_items = that._overlay._$container.find('.dx-state-hover');
  27595. $.each(hovered_items, function(_, item) {
  27596. $(item).removeClass(DX_MENU_ITEM_HOVERED_CLASS)
  27597. })
  27598. },
  27599. _searchActiveItem: function(target) {
  27600. return $(target).closest('.dx-menu-item').get(0)
  27601. },
  27602. _closeOnOutsideClickHandler: function(e) {
  27603. var that = this,
  27604. hovered_items = that._overlay._$container.find('.dx-state-hover'),
  27605. clickedItem = undefined,
  27606. sameUL = false,
  27607. shownSubMenus = $.extend([], that._shownSubMenus),
  27608. $subMenuElements,
  27609. context;
  27610. if (e.target === document) {
  27611. this._removeHoverClass();
  27612. return true
  27613. }
  27614. clickedItem = this._searchActiveItem(e.target);
  27615. if (clickedItem !== undefined) {
  27616. $.each(hovered_items, function(_, item) {
  27617. if (clickedItem.parentElement.parentElement === item.parentElement)
  27618. sameUL = true;
  27619. if (sameUL && clickedItem.parentElement !== item)
  27620. $(item).removeClass(DX_MENU_ITEM_HOVERED_CLASS)
  27621. });
  27622. if (this.option('showSubmenuMode') === 'onclick') {
  27623. $subMenuElements = $(clickedItem).find('.dx-submenu');
  27624. if ($subMenuElements.length > 0)
  27625. $.each(shownSubMenus, function(_, $subMenu) {
  27626. context = that._searchActiveItem($subMenu.context).parentElement;
  27627. if (context.parentElement === $(clickedItem)[0].parentElement.parentElement && context !== $(clickedItem)[0].parentElement)
  27628. that._hideChildrenSubMenus($subMenu)
  27629. })
  27630. }
  27631. return false
  27632. }
  27633. else {
  27634. this._removeHoverClass();
  27635. return true
  27636. }
  27637. },
  27638. _overlayShowingActionHandler: function(arg) {
  27639. var action = this._createActionByOption('showingAction', {});
  27640. action(arg)
  27641. },
  27642. _overlayShownActionHandler: function(arg) {
  27643. var action = this._createActionByOption('shownAction', {});
  27644. action(arg)
  27645. },
  27646. _overlayHidingActionHandler: function(arg) {
  27647. var action = this._createActionByOption('hidingAction', {});
  27648. action(arg);
  27649. this._hideAllShownSubMenus()
  27650. },
  27651. _overlayHiddenActionHandler: function(arg) {
  27652. var action = this._createActionByOption('hiddenAction', {});
  27653. action(arg);
  27654. this._setOptionInternal('visible', false)
  27655. },
  27656. _overlayPositionedActionHandler: function() {
  27657. this._showAdditionalGraphicsElements()
  27658. },
  27659. _handleItemMouseEnter: function(eventArgs) {
  27660. var that = this,
  27661. mouseMoveEventName = events.addNamespace('mousemove', that.NAME),
  27662. $itemElement = that._getItemElementByEventArgs(eventArgs),
  27663. $subMenuElement = $itemElement.children('.dx-submenu'),
  27664. showSubmenuMode = that.option('showSubmenuMode'),
  27665. shownSubMenus = $.extend([], that._shownSubMenus),
  27666. itemElement,
  27667. itemWrapper,
  27668. $itemWrapper = $itemElement.parents('.' + DX_MENU_ITEM_WRAPPER_CLASS).eq(0),
  27669. hovered_items,
  27670. sameOverlay;
  27671. $.each(shownSubMenus, function(_, $subMenu) {
  27672. itemElement = that._getItemElementByEventArgs(eventArgs);
  27673. itemWrapper = $($subMenu.context);
  27674. sameOverlay = false;
  27675. if ($subMenu.context.parentElement === itemElement[0].parentElement.parentElement && $subMenu.context !== itemElement[0].parentElement) {
  27676. hovered_items = that._overlay._$container.find('.dx-state-hover');
  27677. $.each(hovered_items, function(_, item) {
  27678. if (item.parentElement === itemWrapper.context.parentElement)
  27679. sameOverlay = true;
  27680. if (sameOverlay && item.parentElement !== itemWrapper.context.parentElement)
  27681. $(item).removeClass(DX_MENU_ITEM_HOVERED_CLASS)
  27682. });
  27683. that._hideChildrenSubMenus($subMenu);
  27684. itemWrapper.removeClass(DX_MENU_ITEM_HOVERED_CLASS)
  27685. }
  27686. });
  27687. if ($itemElement.data(this._itemDataKey()).disabled)
  27688. return;
  27689. that._renderItemHotTrack($itemElement, true);
  27690. if (this.option('showSubmenuMode') !== 'onclick')
  27691. if ($subMenuElement.length > 0) {
  27692. that._showSubMenuGroup($subMenuElement, $itemElement);
  27693. $itemWrapper.addClass(DX_MENU_ITEM_HOVERED_CLASS);
  27694. if (showSubmenuMode && showSubmenuMode.toLowerCase() === 'onhoverstay')
  27695. $itemElement.off(mouseMoveEventName).on(mouseMoveEventName, function(e) {
  27696. that._handleItemMouseMove(e)
  27697. })
  27698. }
  27699. },
  27700. _handleItemMouseLeave: function(eventArgs) {
  27701. var that = this,
  27702. $itemElement = that._getItemElementByEventArgs(eventArgs),
  27703. $subMenuElement = $itemElement.children('.dx-submenu');
  27704. if ($itemElement.data(this._itemDataKey()).disabled)
  27705. return;
  27706. if (!$subMenuElement.is(':visible'))
  27707. that._renderItemHotTrack($itemElement, false)
  27708. },
  27709. _handleItemMouseMoveCore: function($item) {
  27710. var $subMenuElement = $item.children('.dx-submenu');
  27711. this._showSubMenuGroup($subMenuElement, $item)
  27712. },
  27713. _hideSubMenuGroup: function($subMenu) {
  27714. var that = this;
  27715. if (this._isSubMenuVisible($subMenu))
  27716. that._hideSubMenuCore($subMenu)
  27717. },
  27718. _showSubMenuGroup: function($subMenu, $itemElement, forceRestartTimer) {
  27719. var that = this;
  27720. if (forceRestartTimer || !this._isSubMenuVisible($subMenu))
  27721. that._showSubMenuCore($subMenu, that._getSubMenuPosition($itemElement))
  27722. },
  27723. _getSubMenuPosition: function($rootItem) {
  27724. var isVerticalMenu,
  27725. submenuDirection,
  27726. rtlEnabled,
  27727. position,
  27728. $rootItemWrapper;
  27729. rtlEnabled = !!this.option('rtlEnabled');
  27730. submenuDirection = this.option('submenuDirection').toLowerCase();
  27731. $rootItemWrapper = $rootItem.parent('.dx-menu-item-wrapper');
  27732. position = {
  27733. collision: 'flip',
  27734. of: $rootItemWrapper,
  27735. offset: {
  27736. h: 0,
  27737. v: -1
  27738. }
  27739. };
  27740. switch (submenuDirection) {
  27741. case'left':
  27742. position.at = 'left top';
  27743. position.my = 'right top';
  27744. break;
  27745. case'right':
  27746. position.at = 'right top';
  27747. position.my = 'left top';
  27748. break;
  27749. default:
  27750. if (rtlEnabled) {
  27751. position.at = 'left top';
  27752. position.my = 'right top'
  27753. }
  27754. else {
  27755. position.at = 'right top';
  27756. position.my = 'left top'
  27757. }
  27758. break
  27759. }
  27760. return position
  27761. },
  27762. _isSubMenuVisible: function($subMenu) {
  27763. return $subMenu.css('display') !== 'none'
  27764. },
  27765. _animate: function($container, options) {
  27766. fx.animate($container, options)
  27767. },
  27768. _stopAnimate: function($container) {
  27769. fx.stop($container, true)
  27770. },
  27771. _showSubMenuCore: function($subMenu, position) {
  27772. var animation = this.option('animation') ? this.option('animation').show : {};
  27773. if (this._overlay && this._overlay.option('visible')) {
  27774. if (!utils.isDefined(this._shownSubMenus))
  27775. this._shownSubMenus = [];
  27776. if ($.inArray($subMenu, this._shownSubMenus))
  27777. this._shownSubMenus.push($subMenu);
  27778. $subMenu.css('display', 'block');
  27779. DevExpress.position($subMenu, position);
  27780. this._stopAnimate($subMenu);
  27781. this._animate($subMenu, animation)
  27782. }
  27783. },
  27784. _hideSubMenuCore: function($subMenu) {
  27785. var index = $.inArray($subMenu, this._shownSubMenus),
  27786. animation = this.option('animation') ? this.option('animation').hide : {};
  27787. if (index >= 0)
  27788. this._shownSubMenus.splice(index, 1);
  27789. this._stopAnimate($subMenu);
  27790. this._animate($subMenu, animation.hide);
  27791. $subMenu.css('display', 'none')
  27792. },
  27793. _updateOverlayVisibilityOnClick: function(actionArgs) {
  27794. var $itemElement,
  27795. $subMenuElement;
  27796. if (actionArgs.args.length && actionArgs.args[0]) {
  27797. actionArgs.args[0].jQueryEvent.stopPropagation();
  27798. $itemElement = actionArgs.args[0].itemElement;
  27799. $subMenuElement = $itemElement.children('.dx-submenu');
  27800. if ($itemElement.context === $subMenuElement.context && $subMenuElement.is(":visible"))
  27801. return;
  27802. if (!$itemElement.data(this._itemDataKey()) || $itemElement.data(this._itemDataKey()).disabled)
  27803. return;
  27804. this._updateSelectedItemOnClick($itemElement, actionArgs.args[0].itemData);
  27805. if ($subMenuElement.length === 0) {
  27806. var $prevSubMenu = $($itemElement.parents('.dx-submenu')[0]);
  27807. this._hideChildrenSubMenus($prevSubMenu);
  27808. if (!actionArgs.canceled && this._overlay && this._overlay.option('visible'))
  27809. this.option('visible', false)
  27810. }
  27811. else {
  27812. if (this._shownSubMenus && this._shownSubMenus.length > 0)
  27813. if (this._shownSubMenus[0].is($subMenuElement) || this._shownSubMenus[0].has($subMenuElement).length === 1)
  27814. this._hideChildrenSubMenus($subMenuElement);
  27815. else
  27816. this._hideAllShownSubMenus();
  27817. this._showSubMenuGroup($subMenuElement, $itemElement)
  27818. }
  27819. }
  27820. },
  27821. _hideChildrenSubMenus: function($curSubMenu) {
  27822. var that = this,
  27823. shownSubMenus = $.extend([], that._shownSubMenus);
  27824. $.each(shownSubMenus, function(_, $subMenu) {
  27825. if ($curSubMenu.is($subMenu) || $curSubMenu.has($subMenu).length)
  27826. that._hideSubMenuCore($subMenu)
  27827. })
  27828. },
  27829. _hideAllShownSubMenus: function() {
  27830. var that = this,
  27831. shownSubMenus = $.extend([], that._shownSubMenus);
  27832. $.each(shownSubMenus, function(_, $subMenu) {
  27833. that._hideSubMenuCore($subMenu)
  27834. })
  27835. },
  27836. show: function(jqueryEvent) {
  27837. var position = this.option('position'),
  27838. actionArgs,
  27839. positioningAction;
  27840. if (jqueryEvent && jqueryEvent.preventDefault)
  27841. position = {
  27842. at: 'top left',
  27843. my: 'top left',
  27844. of: jqueryEvent
  27845. };
  27846. if (!position.of)
  27847. position.of = this._target;
  27848. actionArgs = {
  27849. position: position,
  27850. jQueryEvent: jqueryEvent
  27851. };
  27852. positioningAction = this._createActionByOption('positioningAction', actionArgs);
  27853. positioningAction(actionArgs);
  27854. if (!actionArgs.canceled && this._overlay) {
  27855. if (position) {
  27856. this._overlay.option('position', null);
  27857. this._overlay.option('position', position)
  27858. }
  27859. this._overlay.toggle(true);
  27860. this._setOptionInternal('visible', true)
  27861. }
  27862. return this.option('visible')
  27863. },
  27864. hide: function() {
  27865. if (this._overlay) {
  27866. this._overlay.toggle(false);
  27867. this._setOptionInternal('visible', false)
  27868. }
  27869. }
  27870. }))
  27871. })(jQuery, DevExpress);
  27872. /*! Module widgets-web, file ui.menu.js */
  27873. (function($, DX, undefined) {
  27874. var ui = DX.ui,
  27875. utils = DX.utils,
  27876. events = ui.events,
  27877. fx = DX.fx,
  27878. DIV = '<div />',
  27879. UL = '<ul />',
  27880. DXMENU = 'dxMenu',
  27881. DURATION = 50;
  27882. var DX_MENU_CLASS = 'dx-menu',
  27883. DX_MENU_VERTICAL_CLASS = DX_MENU_CLASS + '-vertical',
  27884. DX_MENU_HORIZONTAL_CLASS = DX_MENU_CLASS + '-horizontal',
  27885. DX_MENU_ITEM_CLASS = DX_MENU_CLASS + '-item',
  27886. DX_MENU_ITEM_SELECTED_CLASS = DX_MENU_ITEM_CLASS + '-selected',
  27887. DX_MENU_ITEMS_CONTAINER_CLASS = DX_MENU_CLASS + '-items-container',
  27888. DX_MENU_ITEM_WITH_SUBMENU_CLASS = DX_MENU_ITEM_CLASS + '-with-submenu',
  27889. DX_MENU_ITEM_WRAPPER_CLASS = DX_MENU_ITEM_CLASS + '-wrapper',
  27890. DX_CONTEXT_MENU_CLASS = 'dx-context-menu',
  27891. DX_MENU_SEPARATOR_CLASS = DX_MENU_CLASS + '-separator',
  27892. DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS = DX_CONTEXT_MENU_CLASS + '-container-border';
  27893. DX.registerComponent("dxMenu", ui.dxMenuBase.inherit({
  27894. _deprecatedOptions: {
  27895. firstSubMenuDirection: {
  27896. since: "14.1",
  27897. message: "Use the 'submenuDirection' option instead."
  27898. },
  27899. showPopupMode: {
  27900. since: "14.1",
  27901. message: "Use the 'showFirstSubmenuMode' option instead."
  27902. },
  27903. allowSelectItem: {
  27904. since: "14.1",
  27905. message: "Use the 'allowSelection' option instead."
  27906. }
  27907. },
  27908. _optionAliases: {
  27909. firstSubMenuDirection: "submenuDirection",
  27910. showPopupMode: "showFirstSubmenuMode",
  27911. allowSelectItem: "allowSelection"
  27912. },
  27913. _setDefaultOptions: function() {
  27914. this.callBase();
  27915. this.option({
  27916. orientation: 'horizontal',
  27917. submenuDirection: 'auto',
  27918. firstSubMenuDirection: 'auto',
  27919. showFirstSubmenuMode: 'onclick',
  27920. showPopupMode: 'onclick',
  27921. showSubmenuMode: 'auto',
  27922. items: [],
  27923. hoverStateEnabled: true,
  27924. allowSelection: true,
  27925. allowSelectItem: true,
  27926. allowSelectOnClick: true,
  27927. selectedItem: null,
  27928. cssClass: '',
  27929. animation: {
  27930. show: {
  27931. type: "fade",
  27932. from: 0,
  27933. to: 1,
  27934. duration: 100
  27935. },
  27936. hide: {
  27937. type: 'fade',
  27938. from: 1,
  27939. to: 0,
  27940. duration: 100
  27941. }
  27942. },
  27943. submenuShowingAction: null,
  27944. submenuShownAction: null,
  27945. submenuHidingAction: null,
  27946. submenuHiddenAction: null,
  27947. itemSelectAction: null
  27948. })
  27949. },
  27950. _optionsByReference: function() {
  27951. return $.extend(this.callBase(), {
  27952. animation: true,
  27953. selectedItem: true
  27954. })
  27955. },
  27956. _render: function() {
  27957. this.callBase();
  27958. this._element().addClass(DX_MENU_CLASS);
  27959. this._addCustomCssClass(this._element());
  27960. this._attachItemHoverEvents()
  27961. },
  27962. _renderItems: function(items) {
  27963. var that = this,
  27964. isVerticalMenu,
  27965. $rootGroup,
  27966. $itemsContainer,
  27967. $itemWrapper,
  27968. $item,
  27969. $popupMenu,
  27970. $separator;
  27971. if (items.length) {
  27972. isVerticalMenu = that.option('orientation') === 'vertical';
  27973. $rootGroup = $('<div>').appendTo(that._$element);
  27974. $rootGroup.addClass(isVerticalMenu ? DX_MENU_VERTICAL_CLASS : DX_MENU_HORIZONTAL_CLASS);
  27975. $itemsContainer = $('<ul>').appendTo($rootGroup);
  27976. $itemsContainer.addClass(DX_MENU_ITEMS_CONTAINER_CLASS);
  27977. $itemsContainer.css('min-height', this._getValueHeight($rootGroup));
  27978. $.each(items, function(index, item) {
  27979. that._renderSeparator(item, index, $itemsContainer);
  27980. $itemWrapper = $('<li>').appendTo($itemsContainer);
  27981. $itemWrapper.addClass(DX_MENU_ITEM_WRAPPER_CLASS);
  27982. $item = that._renderItem(index, item, $itemWrapper);
  27983. that._renderSelectedItem(item, $itemWrapper);
  27984. that._renderChildrenItems(item, $item)
  27985. })
  27986. }
  27987. },
  27988. _renderSeparator: function(item, index, $itemsContainer) {
  27989. var $separator;
  27990. if (item.beginGroup && index > 0) {
  27991. $separator = $('<li>').appendTo($itemsContainer);
  27992. $separator.addClass(DX_MENU_SEPARATOR_CLASS)
  27993. }
  27994. },
  27995. _renderSelectedItem: function(item, $itemWrapper) {
  27996. if (this.option('allowSelection'))
  27997. if (item === this.option("selectedItem")) {
  27998. $itemWrapper.addClass(DX_MENU_ITEM_SELECTED_CLASS);
  27999. this.$selectedItemWrapper = $itemWrapper
  28000. }
  28001. },
  28002. _renderChildrenItems: function(item, $item) {
  28003. if (this._hasChildren(item)) {
  28004. this._createPopupMenu(item.items, $item, this.option("selectedItem")).appendTo($item);
  28005. this._renderBorderElement($item)
  28006. }
  28007. },
  28008. _renderBorderElement: function($item) {
  28009. var $border = $('<div>').appendTo($item);
  28010. $border.addClass(DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS);
  28011. $border.css('display', 'none')
  28012. },
  28013. _getValueHeight: function($root) {
  28014. var $div = $("<div>").html("Jj").css({
  28015. width: "auto",
  28016. position: "fixed",
  28017. top: "-3000px",
  28018. left: "-3000px"
  28019. }).appendTo($root),
  28020. height = $div.height();
  28021. $div.remove();
  28022. return height
  28023. },
  28024. _handleItemMouseEnter: function(eventArg) {
  28025. var that = this,
  28026. DX_MENU_HOVERSTAY_TIMEOUT = 300,
  28027. mouseMoveEventName,
  28028. $item,
  28029. popupMenu,
  28030. showFirstSubmenuMode,
  28031. isHoverStayMode;
  28032. $item = that._getItemElementByEventArgs(eventArg);
  28033. if ($item.data(this._itemDataKey()).disabled)
  28034. return;
  28035. that._renderItemHotTrack($item, true);
  28036. popupMenu = that._getPopupMenuByRootElement($item);
  28037. showFirstSubmenuMode = that.option('showFirstSubmenuMode').toLowerCase();
  28038. if (showFirstSubmenuMode !== 'onclick' && popupMenu) {
  28039. clearTimeout(that._hidePopupMenuTimer);
  28040. clearTimeout(that._showPopupMenuTimer);
  28041. isHoverStayMode = that.option('showFirstSubmenuMode') !== 'onhover';
  28042. if (isHoverStayMode && that.visiblePopupMenu == popupMenu && !popupMenu._overlay.option('visible')) {
  28043. mouseMoveEventName = events.addNamespace('mousemove', that.NAME);
  28044. $item.off(mouseMoveEventName).on(mouseMoveEventName, $.proxy(that._handleItemMouseMove, that));
  28045. that._showPopupMenuTimer = setTimeout(function() {
  28046. that._showPopupMenu(popupMenu, $item)
  28047. }, DX_MENU_HOVERSTAY_TIMEOUT)
  28048. }
  28049. else
  28050. that._showPopupMenu(popupMenu, $item)
  28051. }
  28052. },
  28053. _handleItemMouseLeave: function(eventArg) {
  28054. var that = this,
  28055. DX_MENU_HOVER_TIMEOUT = 50,
  28056. DX_MENU_HOVERSTAY_TIMEOUT = 300,
  28057. $item,
  28058. popupMenu,
  28059. showFirstSubmenuMode,
  28060. timeout;
  28061. showFirstSubmenuMode = that.option('showFirstSubmenuMode').toLowerCase();
  28062. timeout = that.option('showFirstSubmenuMode') !== 'onhover' ? DX_MENU_HOVERSTAY_TIMEOUT : DX_MENU_HOVER_TIMEOUT;
  28063. $item = that._getItemElementByEventArgs(eventArg);
  28064. if ($item.data(this._itemDataKey()).disabled)
  28065. return;
  28066. that._renderItemHotTrack($item, false);
  28067. if (showFirstSubmenuMode !== 'onclick') {
  28068. clearTimeout(that._showPopupMenuTimer);
  28069. clearTimeout(that._hidePopupMenuTimer);
  28070. that._hidePopupMenuTimer = setTimeout(function() {
  28071. popupMenu = that._getPopupMenuByRootElement($item);
  28072. that._hidePopupMenu(popupMenu);
  28073. if (that.visiblePopupMenu == popupMenu)
  28074. that.visiblePopupMenu = null
  28075. }, timeout)
  28076. }
  28077. },
  28078. _handleItemMouseMoveCore: function($item) {
  28079. var that = this,
  28080. DX_MENU_HOVERSTAY_TIMEOUT = 300,
  28081. popupMenu;
  28082. if (that._showPopupMenuTimer) {
  28083. clearTimeout(that._hidePopupMenuTimer);
  28084. clearTimeout(that._showPopupMenuTimer);
  28085. popupMenu = that._getPopupMenuByRootElement($item),
  28086. that._showPopupMenuTimer = setTimeout(function() {
  28087. that._showPopupMenu(popupMenu, $item)
  28088. }, DX_MENU_HOVERSTAY_TIMEOUT)
  28089. }
  28090. },
  28091. _updateOverlayVisibilityOnClick: function(actionArgs) {
  28092. var that = this,
  28093. $item,
  28094. popupMenu;
  28095. if (actionArgs.args.length && actionArgs.args[0]) {
  28096. actionArgs.args[0].jQueryEvent.stopPropagation();
  28097. $item = actionArgs.args[0].itemElement;
  28098. if ($item.data(this._itemDataKey()).disabled)
  28099. return;
  28100. popupMenu = that._getPopupMenuByRootElement($item);
  28101. this._updateSelectedItemOnClick($item, actionArgs.args[0].itemData);
  28102. if (popupMenu)
  28103. if (popupMenu._overlay.option('visible')) {
  28104. if (that.option('showFirstSubmenuMode') === 'onclick')
  28105. that._hidePopupMenu(popupMenu)
  28106. }
  28107. else
  28108. that._showPopupMenu(popupMenu, $item)
  28109. }
  28110. },
  28111. _createPopupMenu: function(items, $rootItem, nestedSelectedItem) {
  28112. var that = this,
  28113. popupMenu,
  28114. $popupMenuContainer = $('<div>'),
  28115. $popupMenuTarget = $('<div>'),
  28116. $popupMenuOverlayContent,
  28117. popupMenuMouseEnterName,
  28118. popupMenuMouseLeaveName;
  28119. popupMenuMouseEnterName = events.addNamespace('mouseenter', that.NAME + '_popupMenu');
  28120. popupMenuMouseLeaveName = events.addNamespace('mouseleave', that.NAME + '_popupMenu');
  28121. $popupMenuContainer.dxContextMenu({
  28122. _templates: this.option("_templates"),
  28123. target: $popupMenuTarget,
  28124. items: items,
  28125. position: that._getPopupMenuPosition($rootItem),
  28126. showAdditionalElements: true,
  28127. selectedItem: nestedSelectedItem,
  28128. cssClass: this.option('cssClass'),
  28129. animation: this.option('animation'),
  28130. rtlEnabled: this.option('rtlEnabled'),
  28131. disabled: this.option('disabled'),
  28132. showSubmenuMode: this.option('showSubmenuMode') === 'auto' ? this.option('showFirstSubmenuMode') : this.option('showSubmenuMode'),
  28133. itemSelectAction: $.proxy(this._nestedItemSelectActionHandler, this),
  28134. itemClickAction: $.proxy(this._nestedItemClickActionHandler, this),
  28135. showingAction: $.proxy(this._contextMenuShowingActionHandler, this, $rootItem, popupMenu),
  28136. shownAction: $.proxy(this._contextMenuShownActionHandler, this, $rootItem, popupMenu),
  28137. hidingAction: $.proxy(this._contextMenuHidingActionHandler, this, $rootItem, popupMenu),
  28138. hiddenAction: $.proxy(this._contextMenuHiddenActionHandler, this, $rootItem, popupMenu)
  28139. });
  28140. $popupMenuContainer.addClass(DX_CONTEXT_MENU_CLASS);
  28141. popupMenu = $popupMenuContainer.dxContextMenu('instance');
  28142. $popupMenuOverlayContent = popupMenu._overlay.content();
  28143. $popupMenuOverlayContent.off(popupMenuMouseEnterName).on(popupMenuMouseEnterName, null, $.proxy(this._handlePopupMenuMouseEnter, this, $rootItem));
  28144. $popupMenuOverlayContent.off(popupMenuMouseLeaveName).on(popupMenuMouseLeaveName, null, $.proxy(this._handlePopupMenuMouseLeave, this, $rootItem));
  28145. return $popupMenuContainer
  28146. },
  28147. _getPopupMenuPosition: function($rootItem) {
  28148. var isVerticalMenu,
  28149. submenuDirection,
  28150. rtlEnabled,
  28151. popupMenuPosition;
  28152. rtlEnabled = !!this.option('rtlEnabled');
  28153. isVerticalMenu = this.option('orientation').toLowerCase() == 'vertical';
  28154. submenuDirection = this.option('submenuDirection').toLowerCase();
  28155. popupMenuPosition = {
  28156. collision: 'flip',
  28157. of: $rootItem
  28158. };
  28159. switch (submenuDirection) {
  28160. case'leftOrTop':
  28161. popupMenuPosition.at = isVerticalMenu ? 'left top' : 'left top';
  28162. popupMenuPosition.my = isVerticalMenu ? 'right top' : 'left bottom';
  28163. break;
  28164. case'rightOrBottom':
  28165. popupMenuPosition.at = isVerticalMenu ? 'right top' : 'left bottom';
  28166. popupMenuPosition.my = isVerticalMenu ? 'left top' : 'left top';
  28167. break;
  28168. case'auto':
  28169. default:
  28170. if (isVerticalMenu) {
  28171. popupMenuPosition.at = rtlEnabled ? 'left top' : 'right top';
  28172. popupMenuPosition.my = rtlEnabled ? 'right top' : 'left top'
  28173. }
  28174. else {
  28175. popupMenuPosition.at = rtlEnabled ? 'right bottom' : 'left bottom';
  28176. popupMenuPosition.my = rtlEnabled ? 'right top' : 'left top'
  28177. }
  28178. break
  28179. }
  28180. return popupMenuPosition
  28181. },
  28182. _nestedItemSelectActionHandler: function(arg) {
  28183. this._updateSelectedItemOnClick(arg.itemElement, arg.itemData)
  28184. },
  28185. _nestedItemClickActionHandler: function(arg) {
  28186. var action = this._createActionByOption('itemClickAction', {});
  28187. action(arg)
  28188. },
  28189. _contextMenuShowingActionHandler: function($rootItem, popupMenu) {
  28190. var action,
  28191. $borderElt,
  28192. animation;
  28193. action = this._createActionByOption('submenuShowingAction', {});
  28194. action({
  28195. rootItem: $rootItem,
  28196. popupMenu: popupMenu
  28197. });
  28198. $borderElt = $rootItem.children('.' + DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS);
  28199. if (this._options.width !== undefined)
  28200. if (this._options.rtlEnabled)
  28201. $borderElt.width(this._$element.width() - $rootItem.position().right);
  28202. else
  28203. $borderElt.width(this._$element.width() - $rootItem.position().left);
  28204. $borderElt.css('display', 'block');
  28205. DX.fx.stop($borderElt, true);
  28206. animation = this.option('animation') ? this.option('animation').show : {};
  28207. DX.fx.animate($borderElt, animation);
  28208. $rootItem.addClass(DX_MENU_ITEM_WITH_SUBMENU_CLASS)
  28209. },
  28210. _contextMenuShownActionHandler: function($rootItem, popupMenu) {
  28211. var action = this._createActionByOption('submenuShownAction', {});
  28212. action({
  28213. rootItem: $rootItem,
  28214. popupMenu: popupMenu
  28215. })
  28216. },
  28217. _contextMenuHidingActionHandler: function($rootItem, popupMenu) {
  28218. var action,
  28219. $borderElt,
  28220. animation;
  28221. action = this._createActionByOption('submenuHidingAction', {});
  28222. action({
  28223. rootItem: $rootItem,
  28224. popupMenu: popupMenu
  28225. });
  28226. $borderElt = $rootItem.children('.' + DX_CONTEXT_MENU_CONTAINER_BORDER_CLASS);
  28227. animation = this.option('animation') ? this.option('animation').hide : {};
  28228. DX.fx.animate($borderElt, animation);
  28229. $borderElt.css('display', 'none');
  28230. $rootItem.removeClass(DX_MENU_ITEM_WITH_SUBMENU_CLASS)
  28231. },
  28232. _contextMenuHiddenActionHandler: function($rootItem, popupMenu) {
  28233. var action = this._createActionByOption('submenuHiddenAction', {});
  28234. action({
  28235. rootItem: $rootItem,
  28236. popupMenu: popupMenu
  28237. })
  28238. },
  28239. _handlePopupMenuMouseEnter: function($rootItem) {
  28240. this._hoveredPopupMenuContainer = $rootItem
  28241. },
  28242. _handlePopupMenuMouseLeave: function($rootItem) {
  28243. var that = this,
  28244. popupMenu,
  28245. HOVER_TIMEOUT = 50;
  28246. setTimeout(function() {
  28247. if (!that._hoveredPopupMenuContainer || !that._hoveredPopupMenuContainer.is(that._hoveredRootItem)) {
  28248. popupMenu = that._getPopupMenuByRootElement($rootItem);
  28249. if (popupMenu)
  28250. popupMenu.hide()
  28251. }
  28252. that._hoveredPopupMenuContainer = null
  28253. }, HOVER_TIMEOUT)
  28254. },
  28255. _showPopupMenu: function(popupMenu, $popupMenuContainer) {
  28256. if (utils.isDefined(this.visiblePopupMenu) && this.visiblePopupMenu !== popupMenu)
  28257. this.visiblePopupMenu.hide();
  28258. this._renderItemHotTrack($popupMenuContainer, false);
  28259. popupMenu.show();
  28260. this.visiblePopupMenu = popupMenu;
  28261. this._hoveredRootItem = $popupMenuContainer
  28262. },
  28263. _hidePopupMenu: function(popupMenu) {
  28264. if (!this._hoveredRootItem || !this._hoveredRootItem.is(this._hoveredPopupMenuContainer))
  28265. if (popupMenu)
  28266. popupMenu.hide();
  28267. this._hoveredRootItem = null
  28268. },
  28269. _optionChanged: function(name, value) {
  28270. if (this._optionChangedInternalFlag)
  28271. return;
  28272. if (this.visiblePopupMenu)
  28273. this.visiblePopupMenu.hide();
  28274. switch (name) {
  28275. case'items':
  28276. this.selectedItem = this._getLastSelectedItem(value);
  28277. this._setOptionInternal('selectedItem', this.selectedItem);
  28278. this.callBase.apply(this, arguments);
  28279. break;
  28280. case'selectedItem':
  28281. this.selectedItem = value;
  28282. break;
  28283. default:
  28284. this.callBase.apply(this, arguments)
  28285. }
  28286. },
  28287. _getPopupMenuByRootElement: function($rootItem) {
  28288. var popupMenu = null,
  28289. $popupMenu;
  28290. if ($rootItem) {
  28291. $popupMenu = $rootItem.children('.dx-context-menu');
  28292. if ($popupMenu.length > 0)
  28293. popupMenu = $popupMenu.dxContextMenu('instance')
  28294. }
  28295. return popupMenu
  28296. },
  28297. _containNode: function(hierarchy, node) {
  28298. var that = this,
  28299. nestedResult = false,
  28300. result = false;
  28301. $.each(hierarchy, function(_, curNode) {
  28302. if (curNode == node)
  28303. result = true;
  28304. if (curNode.items) {
  28305. nestedResult = that._containNode(curNode.items, node);
  28306. nestedResult ? result = nestedResult : result
  28307. }
  28308. });
  28309. return result
  28310. }
  28311. }));
  28312. ui.dxMenu.__internals = {MENU_AMIMATION_DURATION: DURATION}
  28313. })(jQuery, DevExpress);
  28314. /*! Module widgets-web, file ui.dataGrid.js */
  28315. (function($, DX) {
  28316. var ui = DX.ui,
  28317. utils = DX.utils;
  28318. var DATAGRID_ROW_SELECTOR = ".dx-row";
  28319. var ModuleItem = DX.Class.inherit({
  28320. ctor: function(component) {
  28321. var that = this;
  28322. that.component = component;
  28323. that.disposing = component.disposing;
  28324. that._actions = {};
  28325. $.each(this.callbackNames() || [], function(index, name) {
  28326. var flags = that.callbackFlags(name);
  28327. that[this] = $.Callbacks(flags)
  28328. })
  28329. },
  28330. callbackNames: function(){},
  28331. callbackFlags: function(name){},
  28332. publicMethods: function(){},
  28333. init: function(){},
  28334. option: function() {
  28335. return this.component.option.apply(this.component, arguments)
  28336. },
  28337. optionChanged: function(name, value, prevValue){},
  28338. getController: function(name) {
  28339. return this.component._controllers[name]
  28340. },
  28341. getView: function(name) {
  28342. return this.component._views[name]
  28343. },
  28344. createAction: function(actionName, config) {
  28345. var action;
  28346. if (utils.isFunction(actionName)) {
  28347. action = this.component._createAction($.proxy(actionName, this), config);
  28348. return function(e) {
  28349. action({jQueryEvent: e})
  28350. }
  28351. }
  28352. else
  28353. this._actions[actionName] = this.option(actionName) ? this.component._createActionByOption(actionName, config) : null
  28354. },
  28355. executeAction: function(actionName, options) {
  28356. var action = this._actions[actionName];
  28357. return action && action(options)
  28358. },
  28359. dispose: function() {
  28360. var that = this;
  28361. $.each(that.callbackNames() || [], function() {
  28362. that[this].empty()
  28363. })
  28364. }
  28365. });
  28366. var Controller = ModuleItem;
  28367. var ViewController = Controller;
  28368. var View = ViewController.inherit({
  28369. _element: function() {
  28370. return this._$element
  28371. },
  28372. _renderCore: function(options){},
  28373. _afterRender: function($root){},
  28374. _parentElement: function() {
  28375. return this._$parent
  28376. },
  28377. ctor: function(component) {
  28378. this.callBase(component);
  28379. this.renderCompleted = $.Callbacks();
  28380. this.resizeCompleted = $.Callbacks()
  28381. },
  28382. isVisible: function() {
  28383. return true
  28384. },
  28385. getTemplate: function(name) {
  28386. return this.component._getTemplate(name)
  28387. },
  28388. render: function($parent, options) {
  28389. var $element = this._$element,
  28390. isVisible = this.isVisible();
  28391. this._$parent = $parent;
  28392. if (!$element)
  28393. $element = this._$element = $('<div />').appendTo($parent);
  28394. $element.toggle(isVisible);
  28395. if (isVisible) {
  28396. this._renderCore(options);
  28397. this._afterRender($parent);
  28398. this.renderCompleted.fire()
  28399. }
  28400. },
  28401. resize: function() {
  28402. this.isResizing = true;
  28403. this.resizeCompleted.fire();
  28404. this.isResizing = false
  28405. },
  28406. focus: function() {
  28407. this._element().focus()
  28408. }
  28409. });
  28410. var processModules = function(that, modules) {
  28411. var controllerTypes = {},
  28412. viewTypes = {};
  28413. that._controllers = {};
  28414. that._views = {};
  28415. $.each(modules, function() {
  28416. var controllers = this.controllers,
  28417. moduleName = this.name,
  28418. views = this.views;
  28419. controllers && $.each(controllers, function(name, type) {
  28420. if (controllerTypes[name])
  28421. throw'Module "' + moduleName + '". Controller "' + name + '" is already registered';
  28422. else if (!(type && type.subclassOf && type.subclassOf(Controller))) {
  28423. type.subclassOf(Controller);
  28424. throw'Module "' + moduleName + '". Controller "' + name + '" must be inheritor of DevExpress.ui.dataGrid.Controller';
  28425. }
  28426. controllerTypes[name] = type
  28427. });
  28428. views && $.each(views, function(name, type) {
  28429. if (viewTypes[name])
  28430. throw'Module "' + moduleName + '". View "' + name + '" is already registered';
  28431. else if (!(type && type.subclassOf && type.subclassOf(View)))
  28432. throw'Module "' + moduleName + '". View "' + name + '" must be inheritor of DevExpress.ui.dataGrid.View';
  28433. viewTypes[name] = type
  28434. })
  28435. });
  28436. $.each(modules, function() {
  28437. var extenders = this.extenders;
  28438. if (extenders) {
  28439. extenders.controllers && $.each(extenders.controllers, function(name, extender) {
  28440. if (controllerTypes[name])
  28441. controllerTypes[name] = controllerTypes[name].inherit(extender)
  28442. });
  28443. extenders.views && $.each(extenders.views, function(name, extender) {
  28444. if (viewTypes[name])
  28445. viewTypes[name] = viewTypes[name].inherit(extender)
  28446. })
  28447. }
  28448. });
  28449. var registerPublicMethods = function(that, name, moduleItem) {
  28450. var publicMethods = moduleItem.publicMethods();
  28451. if (publicMethods)
  28452. $.each(publicMethods, function(index, methodName) {
  28453. if (moduleItem[methodName])
  28454. if (!that[methodName])
  28455. that[methodName] = function() {
  28456. return moduleItem[methodName].apply(moduleItem, arguments)
  28457. };
  28458. else
  28459. throw'Public method "' + methodName + '" is already registered';
  28460. else
  28461. throw'Public method "' + name + '.' + methodName + '" is not exists';
  28462. })
  28463. };
  28464. $.each(controllerTypes, function(name, controllerType) {
  28465. var controller = new controllerType(that);
  28466. controller.name = name;
  28467. registerPublicMethods(that, name, controller);
  28468. that._controllers[name] = controller
  28469. });
  28470. $.each(viewTypes, function(name, viewType) {
  28471. var view = new viewType(that);
  28472. view.name = name;
  28473. registerPublicMethods(that, name, view);
  28474. that._views[name] = view
  28475. })
  28476. };
  28477. var dataGrid = ui.dataGrid = {
  28478. __internals: {},
  28479. modules: [],
  28480. View: View,
  28481. ViewController: ViewController,
  28482. Controller: Controller,
  28483. registerModule: function(name, module) {
  28484. var modules = this.modules,
  28485. i;
  28486. for (i = 0; i < modules.length; i++)
  28487. if (modules[i].name === name)
  28488. return;
  28489. module.name = name;
  28490. modules.push(module)
  28491. },
  28492. unregisterModule: function(name) {
  28493. this.modules = $.grep(this.modules, function(module) {
  28494. return module.name !== name
  28495. })
  28496. },
  28497. processModules: processModules
  28498. };
  28499. DX.registerComponent("dxDataGrid", ui.Widget.inherit(function() {
  28500. return {
  28501. _activeStateUnit: DATAGRID_ROW_SELECTOR,
  28502. _deprecatedOptions: {"editing.texts.recoverRow": {
  28503. since: "14.1",
  28504. message: "Use the 'undeleteRow' option instead."
  28505. }},
  28506. _optionAliases: {"editing.texts.recoverRow": "editing.texts.undeleteRow"},
  28507. _setDefaultOptions: function() {
  28508. var that = this;
  28509. that.callBase();
  28510. $.each(dataGrid.modules, function() {
  28511. if ($.isFunction(this.defaultOptions))
  28512. that.option(this.defaultOptions())
  28513. })
  28514. },
  28515. _defaultOptionsRules: function() {
  28516. return this.callBase().slice(0).concat([{
  28517. device: [{platform: "ios"}, {platform: "ios7"}],
  28518. options: {showRowLines: true}
  28519. }, {
  28520. device: function() {
  28521. return DevExpress.browser.webkit
  28522. },
  28523. options: {loadPanel: {animation: {show: {
  28524. easing: 'cubic-bezier(1, 0, 1, 0)',
  28525. duration: 500,
  28526. from: {opacity: 0},
  28527. to: {opacity: 1}
  28528. }}}}
  28529. }, {
  28530. device: function() {
  28531. return DX.devices.real().ios
  28532. },
  28533. options: {loadingTimeout: 30}
  28534. }])
  28535. },
  28536. _init: function() {
  28537. var that = this;
  28538. that.callBase();
  28539. processModules(that, dataGrid.modules);
  28540. $.each(that._controllers, function() {
  28541. this.init()
  28542. });
  28543. $.each(that._views, function() {
  28544. this.init()
  28545. });
  28546. that._gridView = that._views['gridView']
  28547. },
  28548. _clean: $.noop,
  28549. _optionChanged: function(name, value, prevValue) {
  28550. var that = this;
  28551. that.callBase(name, value, prevValue);
  28552. $.each(that._controllers, function() {
  28553. this.optionChanged(name, value, prevValue)
  28554. });
  28555. $.each(that._views, function() {
  28556. this.optionChanged(name, value, prevValue)
  28557. })
  28558. },
  28559. _dimensionChanged: function() {
  28560. this.resize()
  28561. },
  28562. _visibilityChanged: function() {
  28563. this.resize()
  28564. },
  28565. _renderContentImpl: function() {
  28566. var that = this;
  28567. that._gridView.render(that._element())
  28568. },
  28569. _renderContent: function() {
  28570. this._renderContentImpl()
  28571. },
  28572. _getTemplate: function(templateName) {
  28573. var template,
  28574. templateClass,
  28575. $template;
  28576. if (!this.option("_templates")[templateName]) {
  28577. $template = $(templateName);
  28578. if ($template.length === 1) {
  28579. templateClass = this._templateProvider.getTemplateClass();
  28580. this.option("_templates")[templateName] = new templateClass($template)
  28581. }
  28582. }
  28583. return this.callBase(templateName)
  28584. },
  28585. _dispose: function() {
  28586. var that = this;
  28587. that.callBase();
  28588. $.each(that._controllers, function() {
  28589. this.dispose()
  28590. });
  28591. $.each(that._views, function() {
  28592. this.dispose()
  28593. })
  28594. },
  28595. beginUpdate: function() {
  28596. var that = this;
  28597. that.callBase();
  28598. if (that._controllers)
  28599. $.each(that._controllers, function() {
  28600. this.beginUpdate && this.beginUpdate()
  28601. });
  28602. if (that._views)
  28603. $.each(that._views, function() {
  28604. this.beginUpdate && this.beginUpdate()
  28605. })
  28606. },
  28607. endUpdate: function() {
  28608. var that = this;
  28609. if (that._controllers)
  28610. $.each(that._controllers, function() {
  28611. this.endUpdate && this.endUpdate()
  28612. });
  28613. if (that._views)
  28614. $.each(that._views, function() {
  28615. this.endUpdate && this.endUpdate()
  28616. });
  28617. that.callBase()
  28618. },
  28619. getController: function(name) {
  28620. return this._controllers[name]
  28621. },
  28622. getView: function(name) {
  28623. return this._views[name]
  28624. },
  28625. resize: function() {
  28626. this._gridView.resize()
  28627. }
  28628. }
  28629. }()))
  28630. })(jQuery, DevExpress);
  28631. /*! Module widgets-web, file ui.dataGrid.groupingHelperBase.js */
  28632. (function($, DX) {
  28633. var normalizeSortingInfo = DX.data.utils.normalizeSortingInfo;
  28634. DX.ui.dataGrid.GroupingHelperBase = DX.Class.inherit(function() {
  28635. var findGroupInfoByKey = function(groupsInfo, key) {
  28636. var i;
  28637. for (i = 0; i < groupsInfo.length; i++)
  28638. if (DX.data.utils.keysEqual(null, groupsInfo[i].key, key))
  28639. return groupsInfo[i]
  28640. };
  28641. var getGroupInfoIndexByOffset = function(groupsInfo, offset) {
  28642. var index;
  28643. for (index = 0; index < groupsInfo.length; index++)
  28644. if (groupsInfo[index].offset > offset)
  28645. break;
  28646. return index
  28647. };
  28648. var updateGroupInfoOffsets = function(groupsInfo) {
  28649. var groupInfo,
  28650. index,
  28651. newIndex;
  28652. for (index = 0; index < groupsInfo.length; index++) {
  28653. groupInfo = groupsInfo[index];
  28654. if (groupInfo.data && groupInfo.data.offset !== groupInfo.offset) {
  28655. groupsInfo.splice(index, 1);
  28656. groupInfo.offset = groupInfo.data.offset;
  28657. newIndex = getGroupInfoIndexByOffset(groupsInfo, groupInfo.offset);
  28658. groupsInfo.splice(newIndex, 0, groupInfo);
  28659. if (newIndex > index)
  28660. index--
  28661. }
  28662. }
  28663. };
  28664. var cleanGroupsInfo = function(groupsInfo, groupIndex, groupsCount) {
  28665. var i;
  28666. for (i = 0; i < groupsInfo.length; i++)
  28667. if (groupIndex + 1 >= groupsCount)
  28668. groupsInfo[i].children = [];
  28669. else
  28670. cleanGroupsInfo(groupsInfo[i].children, groupIndex + 1, groupsCount)
  28671. };
  28672. return {
  28673. ctor: function(dataSource) {
  28674. this._dataSource = dataSource;
  28675. this.reset()
  28676. },
  28677. reset: function() {
  28678. this._groupsInfo = [];
  28679. this._totalCountCorrection = 0
  28680. },
  28681. totalItemsCount: function() {
  28682. var that = this,
  28683. totalCount = that._dataSource.totalCount();
  28684. return totalCount > 0 ? totalCount + that._totalCountCorrection : 0
  28685. },
  28686. itemsCount: function() {
  28687. return this._itemsCount || 0
  28688. },
  28689. mergeLoadedData: function(datas, groupDataOptions) {
  28690. var data = this.mergeLoadedDataCore(datas, groupDataOptions);
  28691. this._itemsCount = this.calculateItemsCount(data);
  28692. return data
  28693. },
  28694. updateTotalItemsCount: function(totalCountCorrection) {
  28695. this._totalCountCorrection = totalCountCorrection || 0
  28696. },
  28697. _isGroupItemCountable: function(item) {
  28698. return !this._isVirtualPaging() || !item.isContinuation
  28699. },
  28700. _isVirtualPaging: function() {
  28701. var dataSource = this._dataSource,
  28702. dataSourceOptions = dataSource && dataSource._options,
  28703. scrollingMode = dataSourceOptions && dataSourceOptions.scrolling && dataSourceOptions.scrolling.mode;
  28704. return scrollingMode === 'virtual' || scrollingMode === 'infinite'
  28705. },
  28706. updateItemsCount: function(data, groupsCount) {
  28707. function calculateItemsCount(that, items, groupsCount) {
  28708. var i,
  28709. result = 0;
  28710. if (items)
  28711. if (!groupsCount)
  28712. result = items.length;
  28713. else
  28714. for (i = 0; i < items.length; i++) {
  28715. if (that._isGroupItemCountable(items[i]))
  28716. result++;
  28717. result += calculateItemsCount(that, items[i].items, groupsCount - 1)
  28718. }
  28719. return result
  28720. }
  28721. this._itemsCount = calculateItemsCount(this, data, groupsCount)
  28722. },
  28723. foreachGroups: function(callback, childrenAtFirst) {
  28724. var that = this;
  28725. function foreachGroupsCore(groupsInfo, callback, childrenAtFirst, parents) {
  28726. var i,
  28727. callbackResult,
  28728. callbackResults = [];
  28729. function executeCallback(callback, data, parents, callbackResults) {
  28730. var callbackResult = data && callback(data, parents);
  28731. callbackResults.push(callbackResult);
  28732. return callbackResult
  28733. }
  28734. for (i = 0; i < groupsInfo.length; i++) {
  28735. parents.push(groupsInfo[i].data);
  28736. if (!childrenAtFirst && executeCallback(callback, groupsInfo[i].data, parents, callbackResults) === false)
  28737. return false;
  28738. if (!groupsInfo[i].data || groupsInfo[i].data.isExpanded) {
  28739. callbackResult = foreachGroupsCore(groupsInfo[i].children, callback, childrenAtFirst, parents);
  28740. callbackResults.push(callbackResult);
  28741. if (callbackResult === false)
  28742. return false
  28743. }
  28744. if (childrenAtFirst && executeCallback(callback, groupsInfo[i].data, parents, callbackResults) === false)
  28745. return false;
  28746. parents.pop()
  28747. }
  28748. return $.when.apply($, callbackResults).always(function() {
  28749. updateGroupInfoOffsets(groupsInfo)
  28750. })
  28751. }
  28752. return foreachGroupsCore(that._groupsInfo, callback, childrenAtFirst, [])
  28753. },
  28754. findGroupInfo: function(path) {
  28755. var that = this,
  28756. i,
  28757. pathIndex,
  28758. groupInfo,
  28759. groupsInfo = that._groupsInfo;
  28760. for (pathIndex = 0; groupsInfo && pathIndex < path.length; pathIndex++) {
  28761. groupInfo = findGroupInfoByKey(groupsInfo, path[pathIndex]);
  28762. groupsInfo = groupInfo && groupInfo.children
  28763. }
  28764. return groupInfo && groupInfo.data
  28765. },
  28766. addGroupInfo: function(groupInfoData) {
  28767. var that = this,
  28768. index,
  28769. groupInfo,
  28770. path = groupInfoData.path,
  28771. pathIndex,
  28772. groupsInfo = that._groupsInfo;
  28773. for (pathIndex = 0; pathIndex < path.length; pathIndex++) {
  28774. groupInfo = findGroupInfoByKey(groupsInfo, path[pathIndex]);
  28775. if (!groupInfo) {
  28776. groupInfo = {
  28777. key: path[pathIndex],
  28778. offset: groupInfoData.offset,
  28779. children: []
  28780. };
  28781. index = getGroupInfoIndexByOffset(groupsInfo, groupInfoData.offset);
  28782. groupsInfo.splice(index, 0, groupInfo)
  28783. }
  28784. if (pathIndex === path.length - 1) {
  28785. groupInfo.data = groupInfoData;
  28786. updateGroupInfoOffsets(groupsInfo)
  28787. }
  28788. groupsInfo = groupInfo.children
  28789. }
  28790. },
  28791. allowCollapseAll: function() {
  28792. return true
  28793. },
  28794. collapseAll: function(groupIndex) {
  28795. if (!this.allowCollapseAll()) {
  28796. DX.utils.logger.error("The collapseAll method cannot be called when using a remote data source");
  28797. return false
  28798. }
  28799. return this._collapseExpandAll(groupIndex, false)
  28800. },
  28801. expandAll: function(groupIndex) {
  28802. return this._collapseExpandAll(groupIndex, true)
  28803. },
  28804. _collapseExpandAll: function(groupIndex, isExpand) {
  28805. var that = this,
  28806. dataSource = that._dataSource,
  28807. group = dataSource.group(),
  28808. groups = normalizeSortingInfo(group || []),
  28809. i;
  28810. if (groups.length) {
  28811. for (i = 0; i < groups.length; i++)
  28812. if (groupIndex === undefined || groupIndex === i)
  28813. groups[i].isExpanded = isExpand;
  28814. else if (group && group[i])
  28815. groups[i].isExpanded = group[i].isExpanded;
  28816. dataSource.group(groups);
  28817. that.foreachGroups(function(groupInfo, parents) {
  28818. if (groupIndex === undefined || groupIndex === parents.length - 1)
  28819. groupInfo.isExpanded = isExpand
  28820. });
  28821. that.updateItemsCount()
  28822. }
  28823. return true
  28824. },
  28825. processLoadOptions: function(storeLoadOptions) {
  28826. this._group = storeLoadOptions.group
  28827. },
  28828. refresh: function(storeLoadOptions) {
  28829. var that = this,
  28830. groupIndex,
  28831. oldGroups = normalizeSortingInfo(that._group || []),
  28832. groups = normalizeSortingInfo(storeLoadOptions.group || []),
  28833. groupsCount = Math.min(oldGroups.length, groups.length);
  28834. that._group = storeLoadOptions.group;
  28835. for (groupIndex = 0; groupIndex < groupsCount; groupIndex++)
  28836. if (oldGroups[groupIndex].selector !== groups[groupIndex].selector) {
  28837. groupsCount = groupIndex;
  28838. break
  28839. }
  28840. if (!groupsCount)
  28841. that.reset();
  28842. else
  28843. cleanGroupsInfo(that._groupsInfo, 0, groupsCount)
  28844. }
  28845. }
  28846. }())
  28847. })(jQuery, DevExpress);
  28848. /*! Module widgets-web, file ui.dataGrid.groupingHelper.js */
  28849. (function($, DX) {
  28850. var utils = DX.utils,
  28851. normalizeSortingInfo = DX.data.utils.normalizeSortingInfo,
  28852. keysEqual = DX.data.utils.keysEqual;
  28853. var loadTotalCount = function(store, options) {
  28854. var d = $.Deferred(),
  28855. loadOptions = $.extend({
  28856. skip: 0,
  28857. take: 0,
  28858. requireTotalCount: true
  28859. }, options);
  28860. store.load(loadOptions).done(function(data, extra) {
  28861. if (extra && isFinite(extra.totalCount))
  28862. d.resolve(extra.totalCount);
  28863. else
  28864. store.totalCount(options).done($.proxy(d.resolve, d)).fail($.proxy(d.reject, d))
  28865. }).fail($.proxy(d.reject, d));
  28866. return d
  28867. };
  28868. DX.ui.dataGrid.GroupingHelper = DX.ui.dataGrid.GroupingHelperBase.inherit(function() {
  28869. var foreachCollapsedGroups = function(that, callback) {
  28870. return that.foreachGroups(function(groupInfo) {
  28871. if (!groupInfo.isExpanded)
  28872. return callback(groupInfo)
  28873. })
  28874. };
  28875. var correctSkipLoadOption = function(that, skip) {
  28876. var skipCorrection = 0,
  28877. resultSkip = skip || 0;
  28878. if (skip) {
  28879. foreachCollapsedGroups(that, function(groupInfo) {
  28880. if (groupInfo.offset - skipCorrection >= skip)
  28881. return false;
  28882. skipCorrection += groupInfo.count - 1
  28883. });
  28884. resultSkip += skipCorrection
  28885. }
  28886. return resultSkip
  28887. };
  28888. var processGroupItems = function(that, items, path, offset, skipFirstItem, take) {
  28889. var i,
  28890. item,
  28891. offsetInfo,
  28892. removeLastItemsCount = 0,
  28893. needRemoveFirstItem = false;
  28894. for (i = 0; i < items.length; i++) {
  28895. item = items[i];
  28896. if (item.items !== undefined) {
  28897. path.push(item.key);
  28898. var groupInfo = that.findGroupInfo(path);
  28899. if (groupInfo && !groupInfo.isExpanded) {
  28900. item.items = null;
  28901. offset += groupInfo.count;
  28902. take--;
  28903. if (take < 0)
  28904. removeLastItemsCount++;
  28905. if (skipFirstItem)
  28906. needRemoveFirstItem = true
  28907. }
  28908. else if (item.items) {
  28909. offsetInfo = processGroupItems(that, item.items, path, offset, skipFirstItem, take);
  28910. if (skipFirstItem)
  28911. if (offsetInfo.offset - offset > 1)
  28912. item.isContinuation = true;
  28913. else
  28914. needRemoveFirstItem = true;
  28915. offset = offsetInfo.offset;
  28916. take = offsetInfo.take;
  28917. if (take < 0)
  28918. if (item.items.length)
  28919. item.isContinuationOnNextPage = true;
  28920. else
  28921. removeLastItemsCount++
  28922. }
  28923. path.pop()
  28924. }
  28925. else {
  28926. if (skipFirstItem)
  28927. needRemoveFirstItem = true;
  28928. offset++;
  28929. take--;
  28930. if (take < 0)
  28931. removeLastItemsCount++
  28932. }
  28933. skipFirstItem = false
  28934. }
  28935. if (needRemoveFirstItem)
  28936. items.splice(0, 1);
  28937. if (removeLastItemsCount)
  28938. items.splice(-removeLastItemsCount, removeLastItemsCount);
  28939. return {
  28940. offset: offset,
  28941. take: take
  28942. }
  28943. };
  28944. var pathEquals = function(path1, path2) {
  28945. var i;
  28946. if (path1.length !== path2.length)
  28947. return false;
  28948. for (i = 0; i < path1.length; i++)
  28949. if (!keysEqual(null, path1[i], path2[i]))
  28950. return false;
  28951. return true
  28952. };
  28953. var updateGroupOffsets = function(that, items, path, offset, additionalGroupInfo) {
  28954. var i,
  28955. item,
  28956. groupsInfo = that._groupsInfo;
  28957. for (i = 0; i < items.length; i++) {
  28958. item = items[i];
  28959. if (item.items !== undefined) {
  28960. path.push(item.key);
  28961. if (additionalGroupInfo && pathEquals(additionalGroupInfo.path, path))
  28962. additionalGroupInfo.offset = offset;
  28963. var groupInfo = that.findGroupInfo(path);
  28964. if (groupInfo && !groupInfo.isExpanded) {
  28965. groupInfo.offset = offset;
  28966. offset += groupInfo.count
  28967. }
  28968. else
  28969. offset = updateGroupOffsets(that, item.items, path, offset, additionalGroupInfo);
  28970. path.pop()
  28971. }
  28972. else
  28973. offset++
  28974. }
  28975. return offset
  28976. };
  28977. var removeGroupLoadOption = function(storeLoadOptions) {
  28978. if (storeLoadOptions.group) {
  28979. storeLoadOptions.sort = normalizeSortingInfo(storeLoadOptions.group || []).concat(normalizeSortingInfo(storeLoadOptions.sort || []));
  28980. delete storeLoadOptions.group
  28981. }
  28982. };
  28983. var createGroupFilter = function(path, storeLoadOptions) {
  28984. var groups = normalizeSortingInfo(storeLoadOptions.group || []),
  28985. i,
  28986. filter = [];
  28987. for (i = 0; i < path.length; i++)
  28988. filter.push([groups[i].selector, '=', path[i]]);
  28989. if (storeLoadOptions.filter)
  28990. filter.push(storeLoadOptions.filter);
  28991. return filter
  28992. };
  28993. var createOffsetFilter = function(path, storeLoadOptions) {
  28994. var groups = normalizeSortingInfo(storeLoadOptions.group || []),
  28995. i,
  28996. j,
  28997. filterElement,
  28998. filter = [];
  28999. for (i = 0; i < path.length; i++) {
  29000. filterElement = [];
  29001. for (j = 0; j <= i; j++)
  29002. filterElement.push([groups[j].selector, i === j ? groups[j].desc ? '>' : '<' : '=', path[j]]);
  29003. if (filter.length)
  29004. filter.push('or');
  29005. filter.push(filterElement)
  29006. }
  29007. if (storeLoadOptions.filter)
  29008. filter.push(storeLoadOptions.filter);
  29009. return filter
  29010. };
  29011. return {
  29012. processLoadOptions: function(storeLoadOptions) {
  29013. var that = this,
  29014. currentTake,
  29015. loadOptions,
  29016. collapsedPaths = [],
  29017. collapsedPathsByLoads = [],
  29018. skipFirstItem = false,
  29019. take,
  29020. offset,
  29021. group = storeLoadOptions.group,
  29022. groupLoadOptions = [];
  29023. that.callBase(storeLoadOptions);
  29024. removeGroupLoadOption(storeLoadOptions);
  29025. loadOptions = $.extend({}, storeLoadOptions);
  29026. loadOptions.skip = correctSkipLoadOption(that, storeLoadOptions.skip);
  29027. if (loadOptions.skip && loadOptions.take && group) {
  29028. loadOptions.skip--;
  29029. loadOptions.take++;
  29030. skipFirstItem = true
  29031. }
  29032. if (loadOptions.take && group) {
  29033. take = loadOptions.take;
  29034. loadOptions.take++
  29035. }
  29036. offset = loadOptions.skip || 0;
  29037. if (loadOptions.take) {
  29038. foreachCollapsedGroups(that, function(groupInfo) {
  29039. if (groupInfo.offset >= loadOptions.skip + loadOptions.take)
  29040. return false;
  29041. else if (groupInfo.offset >= loadOptions.skip && groupInfo.count) {
  29042. currentTake = groupInfo.offset - loadOptions.skip;
  29043. if (currentTake > 0) {
  29044. groupLoadOptions.push($.extend({}, loadOptions, {
  29045. skip: loadOptions.skip,
  29046. take: currentTake
  29047. }));
  29048. loadOptions.take -= currentTake;
  29049. collapsedPathsByLoads.push(collapsedPaths);
  29050. collapsedPaths = []
  29051. }
  29052. loadOptions.skip = groupInfo.offset + groupInfo.count;
  29053. loadOptions.take--;
  29054. collapsedPaths.push(groupInfo.path)
  29055. }
  29056. });
  29057. if (!groupLoadOptions.length || loadOptions.take > 0)
  29058. groupLoadOptions.push(loadOptions);
  29059. if (collapsedPaths.length)
  29060. collapsedPathsByLoads.push(collapsedPaths)
  29061. }
  29062. else
  29063. groupLoadOptions.push(loadOptions);
  29064. return {
  29065. loads: groupLoadOptions,
  29066. data: {
  29067. collapsedPathsByLoads: collapsedPathsByLoads,
  29068. offset: offset,
  29069. skipFirstItem: skipFirstItem,
  29070. take: take,
  29071. group: group
  29072. }
  29073. }
  29074. },
  29075. updateTotalItemsCount: function() {
  29076. var itemsCountCorrection = 0;
  29077. foreachCollapsedGroups(this, function(groupInfo) {
  29078. if (groupInfo.count)
  29079. itemsCountCorrection -= groupInfo.count - 1
  29080. });
  29081. this.callBase(itemsCountCorrection)
  29082. },
  29083. changeGroupExpand: function(path) {
  29084. var that = this,
  29085. dataSource = that._dataSource,
  29086. basePageIndex = dataSource.basePageIndex && dataSource.basePageIndex() || dataSource.pageIndex(),
  29087. offset = correctSkipLoadOption(that, basePageIndex * dataSource.pageSize()),
  29088. groupCountQuery;
  29089. groupCountQuery = loadTotalCount(dataSource.store(), {filter: createGroupFilter(path, {
  29090. filter: dataSource.filter(),
  29091. group: dataSource.group()
  29092. })});
  29093. return $.when(groupCountQuery).done(function(count) {
  29094. var groupInfo;
  29095. count = parseInt(count.length ? count[0] : count);
  29096. groupInfo = that.findGroupInfo(path);
  29097. if (groupInfo) {
  29098. updateGroupOffsets(that, dataSource.items(), [], offset);
  29099. groupInfo.isExpanded = !groupInfo.isExpanded;
  29100. groupInfo.count = count
  29101. }
  29102. else {
  29103. groupInfo = {
  29104. offset: -1,
  29105. count: count,
  29106. path: path,
  29107. isExpanded: false
  29108. };
  29109. updateGroupOffsets(that, dataSource.items(), [], offset, groupInfo);
  29110. if (groupInfo.offset >= 0)
  29111. that.addGroupInfo(groupInfo)
  29112. }
  29113. that.updateTotalItemsCount()
  29114. }).fail($.proxy(dataSource.loadError.fire, dataSource.loadError))
  29115. },
  29116. mergeLoadedData: function(datas, groupDataOptions) {
  29117. var that = this,
  29118. data = [],
  29119. i,
  29120. pathIndex,
  29121. query,
  29122. collapsedPathsByLoads = groupDataOptions.collapsedPathsByLoads,
  29123. collapsedPaths,
  29124. groups = normalizeSortingInfo(groupDataOptions.group || []),
  29125. groupsCount = groups.length,
  29126. loadsCount = Math.max(datas.length, collapsedPathsByLoads.length);
  29127. function createCollapsedGroupItem(path) {
  29128. var result = {},
  29129. i,
  29130. item;
  29131. for (i = 0; i < path.length; i++) {
  29132. if (!item)
  29133. item = result;
  29134. else {
  29135. item.items.push({});
  29136. item = item.items[0]
  29137. }
  29138. item.key = path[i];
  29139. item.items = []
  29140. }
  29141. return result
  29142. }
  29143. function appendData(data, appendingData) {
  29144. var index = 0;
  29145. if (appendingData) {
  29146. if (data.length && appendingData.length && keysEqual(null, data[data.length - 1].key, appendingData[0].key)) {
  29147. appendData(data[data.length - 1].items, appendingData[0].items);
  29148. index = 1
  29149. }
  29150. while (index < appendingData.length) {
  29151. data.push(appendingData[index]);
  29152. index++
  29153. }
  29154. }
  29155. }
  29156. for (i = 0; i < loadsCount; i++) {
  29157. collapsedPaths = collapsedPathsByLoads[i];
  29158. if (collapsedPaths && collapsedPaths.length)
  29159. for (pathIndex = 0; pathIndex < collapsedPaths.length; pathIndex++)
  29160. appendData(data, [createCollapsedGroupItem(collapsedPaths[pathIndex])]);
  29161. if (datas[i]) {
  29162. query = DX.data.query(datas[i]);
  29163. DX.data.utils.multiLevelGroup(query, groups).enumerate().done(function(groupedData) {
  29164. appendData(data, groupedData)
  29165. })
  29166. }
  29167. }
  29168. processGroupItems(that, data, [], groupDataOptions.offset, groupDataOptions.skipFirstItem, groupDataOptions.take);
  29169. that.updateItemsCount(data, groupsCount);
  29170. return data
  29171. },
  29172. allowCollapseAll: function() {
  29173. return false
  29174. },
  29175. refresh: function(storeLoadOptions) {
  29176. var that = this,
  29177. store = that._dataSource.store();
  29178. that.callBase(storeLoadOptions);
  29179. return foreachCollapsedGroups(that, function(groupInfo) {
  29180. var groupCountQuery = loadTotalCount(store, {filter: createGroupFilter(groupInfo.path, storeLoadOptions)}),
  29181. groupOffsetQuery = loadTotalCount(store, {filter: createOffsetFilter(groupInfo.path, storeLoadOptions)});
  29182. return $.when(groupOffsetQuery, groupCountQuery).done(function(offset, count) {
  29183. offset = parseInt(offset.length ? offset[0] : offset);
  29184. count = parseInt(count.length ? count[0] : count);
  29185. groupInfo.offset = offset;
  29186. if (groupInfo.count !== count) {
  29187. groupInfo.count = count;
  29188. that.updateTotalItemsCount()
  29189. }
  29190. }).fail($.proxy(that._dataSource.loadError.fire, that._dataSource.loadError))
  29191. })
  29192. }
  29193. }
  29194. }());
  29195. $.extend(DX.ui.dataGrid.__internals, {loadTotalCount: loadTotalCount})
  29196. })(jQuery, DevExpress);
  29197. /*! Module widgets-web, file ui.dataGrid.groupingHelperWithNativeGrouping.js */
  29198. (function($, DX) {
  29199. var utils = DX.utils,
  29200. normalizeSortingInfo = DX.data.utils.normalizeSortingInfo,
  29201. keysEqual = DX.data.utils.keysEqual;
  29202. DX.ui.dataGrid.GroupingHelperWithNativeGrouping = DX.ui.dataGrid.GroupingHelperBase.inherit(function() {
  29203. var foreachExpandedGroups = function(that, callback) {
  29204. return that.foreachGroups(function(groupInfo, parents) {
  29205. if (groupInfo.isExpanded)
  29206. return callback(groupInfo, parents)
  29207. }, true)
  29208. };
  29209. var processGroupItems = function(that, items, path, groupsCount) {
  29210. var i,
  29211. item;
  29212. if (!groupsCount)
  29213. return;
  29214. for (i = 0; i < items.length; i++) {
  29215. item = items[i];
  29216. if (item.items !== undefined) {
  29217. path.push(item.key);
  29218. var groupInfo = that.findGroupInfo(path);
  29219. if (!groupInfo || !groupInfo.isExpanded)
  29220. item.items = null;
  29221. else
  29222. processGroupItems(that, item.items, path, groupsCount - 1);
  29223. path.pop()
  29224. }
  29225. }
  29226. };
  29227. var hasExpandedGroup = function(that, group) {
  29228. var hasExpandedGroup = false,
  29229. i,
  29230. groupsCount = normalizeSortingInfo(group || []).length;
  29231. for (i = 0; i < groupsCount; i++)
  29232. if (that._isGroupExpanded(i))
  29233. hasExpandedGroup = true;
  29234. return hasExpandedGroup
  29235. };
  29236. var updateGroupInfos = function(that, items, groupsCount, offset) {
  29237. updateGroupInfosCore(that, items, 0, groupsCount, [], offset)
  29238. };
  29239. var updateGroupInfosCore = function(that, items, groupIndex, groupsCount, path, offset) {
  29240. var item,
  29241. i,
  29242. groupInfo;
  29243. if (groupIndex >= groupsCount)
  29244. return;
  29245. for (i = 0; i < items.length; i++) {
  29246. item = items[i];
  29247. if (item) {
  29248. path.push(item.key);
  29249. groupInfo = that.findGroupInfo(path);
  29250. if (!groupInfo)
  29251. that.addGroupInfo({
  29252. isExpanded: that._isGroupExpanded(groupIndex),
  29253. path: path.slice(0),
  29254. offset: offset + i,
  29255. count: item.items.length
  29256. });
  29257. else {
  29258. groupInfo.count = item.items.length;
  29259. groupInfo.offset = offset + i
  29260. }
  29261. updateGroupInfosCore(that, item.items, groupIndex + 1, groupsCount, path, 0);
  29262. path.pop()
  29263. }
  29264. }
  29265. };
  29266. var isGroupExpanded = function(groups, groupIndex) {
  29267. return groups && groups.length && groups[groupIndex] && !!groups[groupIndex].isExpanded
  29268. };
  29269. var getTotalOffset = function(groupInfos, pageSize, offset) {
  29270. var groupIndex,
  29271. prevOffset = 0,
  29272. groupSize,
  29273. totalOffset = offset;
  29274. for (groupIndex = 0; groupIndex < groupInfos.length; groupIndex++) {
  29275. groupSize = groupInfos[groupIndex].offset + 1;
  29276. if (groupIndex > 0) {
  29277. groupSize += groupInfos[groupIndex - 1].childrenTotalCount;
  29278. if (pageSize)
  29279. groupSize += getContinuationGroupCount(totalOffset, pageSize, groupSize, groupIndex - 1) * groupIndex
  29280. }
  29281. totalOffset += groupSize
  29282. }
  29283. return totalOffset
  29284. };
  29285. var getContinuationGroupCount = function(groupOffset, pageSize, groupSize, groupIndex) {
  29286. groupIndex = groupIndex || 0;
  29287. if (pageSize > 1 && groupSize > 0) {
  29288. var pageOffset = groupOffset - Math.floor(groupOffset / pageSize) * pageSize || pageSize;
  29289. pageOffset += groupSize - groupIndex - 2;
  29290. if (pageOffset < 0)
  29291. pageOffset += pageSize;
  29292. return Math.floor(pageOffset / (pageSize - groupIndex - 1))
  29293. }
  29294. return 0
  29295. };
  29296. DX.ui.dataGrid.getContinuationGroupCount = getContinuationGroupCount;
  29297. return {
  29298. updateTotalItemsCount: function() {
  29299. var totalItemsCount = 0,
  29300. pageSize = this._dataSource.pageSize(),
  29301. isVirtualPaging = this._isVirtualPaging();
  29302. foreachExpandedGroups(this, function(groupInfo, parents) {
  29303. groupInfo.childrenTotalCount = 0
  29304. });
  29305. foreachExpandedGroups(this, function(groupInfo, parents) {
  29306. var totalOffset = getTotalOffset(parents, isVirtualPaging ? 0 : pageSize, totalItemsCount),
  29307. count = groupInfo.count + groupInfo.childrenTotalCount,
  29308. i;
  29309. if (!isVirtualPaging)
  29310. count += getContinuationGroupCount(totalOffset, pageSize, count, parents.length - 1);
  29311. if (parents[parents.length - 2])
  29312. parents[parents.length - 2].childrenTotalCount += count;
  29313. else
  29314. totalItemsCount += count
  29315. });
  29316. this.callBase(totalItemsCount)
  29317. },
  29318. _isGroupExpanded: function(groupIndex) {
  29319. var groups = this._dataSource.group();
  29320. return isGroupExpanded(groups, groupIndex)
  29321. },
  29322. processLoadOptions: function(storeLoadOptions, isExpandedGroupsLoaded) {
  29323. var that = this,
  29324. dataSource = this._dataSource,
  29325. isVirtualPaging = that._isVirtualPaging(),
  29326. pageSize = dataSource.pageSize(),
  29327. groups = normalizeSortingInfo(storeLoadOptions.group || []),
  29328. skips = [],
  29329. takes = [],
  29330. skipChildrenTotalCount = 0,
  29331. childrenTotalCount = 0,
  29332. loadOptions = $.extend({}, storeLoadOptions);
  29333. that.callBase(storeLoadOptions);
  29334. if (hasExpandedGroup(that, groups) && !isExpandedGroupsLoaded) {
  29335. delete loadOptions.skip;
  29336. delete loadOptions.take
  29337. }
  29338. else if (loadOptions.take) {
  29339. foreachExpandedGroups(this, function(groupInfo) {
  29340. groupInfo.childrenTotalCount = 0;
  29341. groupInfo.skipChildrenTotalCount = 0
  29342. });
  29343. foreachExpandedGroups(that, function(groupInfo, parents) {
  29344. var skip,
  29345. take,
  29346. takeCorrection = 0,
  29347. parentTakeCorrection = 0,
  29348. totalOffset = getTotalOffset(parents, isVirtualPaging ? 0 : pageSize, childrenTotalCount),
  29349. continuationGroupCount = 0,
  29350. skipContinuationGroupCount = 0,
  29351. groupInfoCount = groupInfo.count + groupInfo.childrenTotalCount,
  29352. childrenGroupInfoCount = groupInfoCount;
  29353. if (totalOffset <= loadOptions.skip + loadOptions.take && groupInfoCount) {
  29354. skip = loadOptions.skip - totalOffset;
  29355. take = loadOptions.take;
  29356. if (!isVirtualPaging) {
  29357. continuationGroupCount = getContinuationGroupCount(totalOffset, pageSize, groupInfoCount, parents.length - 1);
  29358. groupInfoCount += continuationGroupCount * parents.length;
  29359. childrenGroupInfoCount += continuationGroupCount;
  29360. if (pageSize && skip >= 0) {
  29361. takeCorrection = parents.length;
  29362. parentTakeCorrection = parents.length - 1;
  29363. skipContinuationGroupCount = Math.floor(skip / pageSize)
  29364. }
  29365. }
  29366. if (skip >= 0) {
  29367. if (totalOffset + groupInfoCount > loadOptions.skip)
  29368. skips.unshift(skip - skipContinuationGroupCount * takeCorrection - groupInfo.skipChildrenTotalCount);
  29369. if (totalOffset + groupInfoCount >= loadOptions.skip + take)
  29370. takes.unshift(take - takeCorrection - groupInfo.childrenTotalCount + groupInfo.skipChildrenTotalCount)
  29371. }
  29372. else if (totalOffset + groupInfoCount >= loadOptions.skip + take)
  29373. takes.unshift(take + skip - groupInfo.childrenTotalCount)
  29374. }
  29375. if (totalOffset <= loadOptions.skip)
  29376. if (parents[parents.length - 2])
  29377. parents[parents.length - 2].skipChildrenTotalCount += Math.min(childrenGroupInfoCount, skip + 1 - skipContinuationGroupCount * parentTakeCorrection);
  29378. else
  29379. skipChildrenTotalCount += Math.min(childrenGroupInfoCount, skip + 1);
  29380. if (totalOffset <= loadOptions.skip + take) {
  29381. groupInfoCount = Math.min(childrenGroupInfoCount, skip + take - (skipContinuationGroupCount + 1) * parentTakeCorrection);
  29382. if (parents[parents.length - 2])
  29383. parents[parents.length - 2].childrenTotalCount += groupInfoCount;
  29384. else
  29385. childrenTotalCount += groupInfoCount
  29386. }
  29387. });
  29388. loadOptions.skip -= skipChildrenTotalCount;
  29389. loadOptions.take -= childrenTotalCount - skipChildrenTotalCount
  29390. }
  29391. return {
  29392. loads: [loadOptions],
  29393. data: {
  29394. skip: loadOptions.skip,
  29395. take: loadOptions.take,
  29396. skips: skips,
  29397. takes: takes,
  29398. storeLoadOptions: storeLoadOptions
  29399. }
  29400. }
  29401. },
  29402. changeGroupExpand: function(path) {
  29403. var that = this,
  29404. groupInfo = that.findGroupInfo(path);
  29405. if (groupInfo) {
  29406. groupInfo.isExpanded = !groupInfo.isExpanded;
  29407. that.updateTotalItemsCount();
  29408. return $.Deferred().resolve()
  29409. }
  29410. return $.Deferred().reject()
  29411. },
  29412. mergeLoadedData: function(datas, groupDataOptions) {
  29413. var that = this,
  29414. data = datas[0],
  29415. group = normalizeSortingInfo(groupDataOptions.storeLoadOptions.group || []),
  29416. groupsCount = group.length,
  29417. skips,
  29418. takes,
  29419. i,
  29420. item,
  29421. items;
  29422. updateGroupInfos(that, data, groupsCount, groupDataOptions.skip || 0);
  29423. that.updateTotalItemsCount();
  29424. if (hasExpandedGroup(that, group)) {
  29425. groupDataOptions = that.processLoadOptions(groupDataOptions.storeLoadOptions, true).data;
  29426. if (groupDataOptions.skip)
  29427. data = data.slice(groupDataOptions.skip);
  29428. if (groupDataOptions.take)
  29429. data = data.slice(0, groupDataOptions.take)
  29430. }
  29431. skips = groupDataOptions.skips;
  29432. takes = groupDataOptions.takes;
  29433. items = data;
  29434. for (i = 0; items && i < groupsCount; i++) {
  29435. item = items[0];
  29436. items = item && item.items;
  29437. if (items && skips[i] !== undefined) {
  29438. item.isContinuation = true;
  29439. items = items.slice(skips[i]);
  29440. item.items = items
  29441. }
  29442. }
  29443. items = data;
  29444. for (i = 0; items && i < groupsCount; i++) {
  29445. item = items[items.length - 1];
  29446. items = item && item.items;
  29447. if (items && takes[i] !== undefined && items.length > takes[i]) {
  29448. item.isContinuationOnNextPage = true;
  29449. items = items.slice(0, takes[i]);
  29450. item.items = items
  29451. }
  29452. }
  29453. processGroupItems(that, data, [], groupsCount);
  29454. that.updateItemsCount(data, groupsCount);
  29455. return data
  29456. },
  29457. refresh: function(storeLoadOptions) {
  29458. var that = this,
  29459. oldGroups = normalizeSortingInfo(that._group || []),
  29460. groups = normalizeSortingInfo(storeLoadOptions.group || []),
  29461. groupIndex;
  29462. for (groupIndex = 0; groupIndex < oldGroups.length; groupIndex++)
  29463. if (isGroupExpanded(that._group, groupIndex) !== isGroupExpanded(storeLoadOptions.group, groupIndex)) {
  29464. that.reset();
  29465. return
  29466. }
  29467. that.callBase(storeLoadOptions);
  29468. that.foreachGroups(function(groupInfo) {
  29469. groupInfo.count = 0
  29470. });
  29471. if (groups.length)
  29472. return that._dataSource.store().load(storeLoadOptions).done(function(data) {
  29473. updateGroupInfos(that, data, groups.length, 0)
  29474. }).fail($.proxy(that._dataSource.loadError.fire, that._dataSource.loadError))
  29475. }
  29476. }
  29477. }())
  29478. })(jQuery, DevExpress);
  29479. /*! Module widgets-web, file ui.dataGrid.scrollingDataSourceWrapper.js */
  29480. (function($, DX) {
  29481. var dataGrid = DX.ui.dataGrid,
  29482. utils = DX.utils;
  29483. dataGrid.ScrollingDataSourceWrapper = DX.Class.inherit(function() {
  29484. var getPreloadPageCount = function(that) {
  29485. var scrolling = that._options.scrolling;
  29486. return scrolling && scrolling.preloadEnabled ? 2 : 1
  29487. };
  29488. var isVirtualMode = function(that) {
  29489. return that._options.scrolling && that._options.scrolling.mode === 'virtual'
  29490. };
  29491. var isAppendMode = function(that) {
  29492. return that._options.scrolling && that._options.scrolling.mode === 'infinite'
  29493. };
  29494. var getBasePageIndex = function(that) {
  29495. return that._cache[0] ? that._cache[0].pageIndex : -1
  29496. };
  29497. var updateLoading = function(that) {
  29498. var basePageIndex = getBasePageIndex(that),
  29499. pagesCount = that._cache.length;
  29500. if (isVirtualMode(that))
  29501. if (basePageIndex < 0 || that._viewportItemIndex >= 0 && (basePageIndex * that.pageSize() > that._viewportItemIndex || basePageIndex * that.pageSize() + that.itemsCount() < that._viewportItemIndex + that._viewportSize) && that._dataSource.isLoading()) {
  29502. if (!that._isLoading) {
  29503. that._isLoading = true;
  29504. that.loadingChanged.fire(true)
  29505. }
  29506. }
  29507. else if (that._isLoading) {
  29508. that._isLoading = false;
  29509. that.loadingChanged.fire(false)
  29510. }
  29511. };
  29512. return {
  29513. ctor: function(options) {
  29514. var that = this,
  29515. dataSource = new dataGrid.DataSource(options, that);
  29516. that._dataSource = dataSource;
  29517. that.loadError = dataSource.loadError;
  29518. that.changed = $.Callbacks();
  29519. that.loadingChanged = $.Callbacks();
  29520. that._isLoading = true;
  29521. that._pageIndex = dataSource.pageIndex();
  29522. that._lastPageIndex = that._pageIndex;
  29523. that._viewportSize = 0;
  29524. that._viewportItemIndex = -1;
  29525. that._userPageSize = options.pageSize;
  29526. that._items = [];
  29527. that._isLoaded = true;
  29528. dataSource.loadingChanged.add(function(isLoading) {
  29529. if (!isVirtualMode(that)) {
  29530. that._isLoading = isLoading;
  29531. that.loadingChanged.fire(isLoading)
  29532. }
  29533. });
  29534. var processChanged = function(that, changeType, isDelayChanged) {
  29535. var dataSource = that._dataSource,
  29536. items = dataSource.items();
  29537. if (changeType === 'append')
  29538. that._items.push.apply(that._items, items);
  29539. else if (changeType === 'prepend')
  29540. that._items.unshift.apply(that._items, items);
  29541. else
  29542. that._items = items;
  29543. updateLoading(that);
  29544. that._lastPageIndex = that.pageIndex();
  29545. that._isDelayChanged = isDelayChanged;
  29546. if (!isDelayChanged)
  29547. that.changed.fire(changeType && {
  29548. changeType: changeType,
  29549. items: items
  29550. })
  29551. };
  29552. var processDelayChanged = function(that) {
  29553. if (that._isDelayChanged) {
  29554. that._isDelayChanged = false;
  29555. that.changed.fire()
  29556. }
  29557. };
  29558. dataSource.changed.add(function() {
  29559. var basePageIndex,
  29560. lastCacheLength = that._cache.length,
  29561. changeType,
  29562. cacheItem;
  29563. if (isVirtualMode(that)) {
  29564. basePageIndex = getBasePageIndex(that);
  29565. if (basePageIndex >= 0)
  29566. if (basePageIndex + that._cache.length === dataSource.pageIndex());
  29567. else if (basePageIndex - 1 === dataSource.pageIndex());
  29568. else
  29569. that._cache = [];
  29570. cacheItem = {
  29571. pageIndex: dataSource.pageIndex(),
  29572. itemsCount: dataSource.itemsCount()
  29573. };
  29574. processDelayChanged(that);
  29575. if (basePageIndex === dataSource.pageIndex() + 1) {
  29576. changeType = 'prepend';
  29577. that._cache.unshift(cacheItem)
  29578. }
  29579. else {
  29580. changeType = 'append';
  29581. that._cache.push(cacheItem)
  29582. }
  29583. processChanged(that, that._cache.length > 1 ? changeType : undefined, lastCacheLength === 0);
  29584. that.load().done(function() {
  29585. processDelayChanged(that)
  29586. })
  29587. }
  29588. else
  29589. processChanged(that, isAppendMode(that) && dataSource.pageIndex() !== 0 ? 'append' : undefined)
  29590. });
  29591. $.each(dataSource, function(memberName, member) {
  29592. if (!that[memberName] && $.isFunction(member))
  29593. that[memberName] = function() {
  29594. return this._dataSource[memberName].apply(this._dataSource, arguments)
  29595. }
  29596. });
  29597. that._cache = [];
  29598. that._options = options
  29599. },
  29600. items: function() {
  29601. return this._items
  29602. },
  29603. itemsCount: function() {
  29604. var itemsCount = 0;
  29605. if (isVirtualMode(this))
  29606. $.each(this._cache, function() {
  29607. itemsCount += this.itemsCount
  29608. });
  29609. else
  29610. itemsCount = this._dataSource.itemsCount();
  29611. return itemsCount
  29612. },
  29613. virtualItemsCount: function() {
  29614. var that = this,
  29615. pageIndex,
  29616. itemsCount = 0,
  29617. i,
  29618. beginItemsCount,
  29619. endItemsCount;
  29620. if (isVirtualMode(that)) {
  29621. pageIndex = getBasePageIndex(that);
  29622. if (pageIndex < 0)
  29623. pageIndex = 0;
  29624. beginItemsCount = pageIndex * that.pageSize();
  29625. itemsCount = that._cache.length * that.pageSize();
  29626. endItemsCount = Math.max(0, that.totalItemsCount() - itemsCount - beginItemsCount);
  29627. return {
  29628. begin: beginItemsCount,
  29629. end: endItemsCount
  29630. }
  29631. }
  29632. },
  29633. setViewportItemIndex: function(itemIndex) {
  29634. var that = this,
  29635. pageSize = that.pageSize(),
  29636. dataSource = that._dataSource,
  29637. pagesCount = that.pagesCount(),
  29638. virtualMode = isVirtualMode(that),
  29639. appendMode = isAppendMode(that),
  29640. totalItemsCount = that.totalItemsCount(),
  29641. lastPageSize,
  29642. needLoad = that._viewportItemIndex < 0,
  29643. maxPageIndex,
  29644. newPageIndex;
  29645. that._viewportItemIndex = itemIndex;
  29646. if (pageSize && (virtualMode || appendMode)) {
  29647. if (that._viewportSize && itemIndex + that._viewportSize >= totalItemsCount) {
  29648. if (that.hasKnownLastPage()) {
  29649. newPageIndex = pagesCount - 1;
  29650. lastPageSize = totalItemsCount % pageSize;
  29651. if (newPageIndex > 0 && lastPageSize > 0 && lastPageSize < pageSize / 2)
  29652. newPageIndex--
  29653. }
  29654. else if (that.pageIndex() < pagesCount)
  29655. newPageIndex = pagesCount
  29656. }
  29657. else {
  29658. newPageIndex = Math.floor(itemIndex / pageSize);
  29659. maxPageIndex = pagesCount - 1;
  29660. newPageIndex = Math.max(newPageIndex, 0);
  29661. newPageIndex = Math.min(newPageIndex, maxPageIndex)
  29662. }
  29663. if (that.pageIndex() !== newPageIndex || needLoad) {
  29664. that.pageIndex(newPageIndex);
  29665. that.load()
  29666. }
  29667. }
  29668. },
  29669. setViewportSize: function(size) {
  29670. var that = this,
  29671. pageSize;
  29672. if (that._viewportSize !== size) {
  29673. that._viewportSize = size;
  29674. if ((isVirtualMode(that) || isAppendMode(that)) && !that._userPageSize) {
  29675. pageSize = Math.ceil(size / 5) * 10;
  29676. if (pageSize !== that.pageSize()) {
  29677. that.pageSize(pageSize);
  29678. that.reload()
  29679. }
  29680. }
  29681. }
  29682. },
  29683. pageIndex: function(pageIndex) {
  29684. if (isVirtualMode(this) || isAppendMode(this)) {
  29685. if (pageIndex !== undefined)
  29686. this._pageIndex = pageIndex;
  29687. return this._pageIndex
  29688. }
  29689. else
  29690. return this._dataSource.pageIndex(pageIndex)
  29691. },
  29692. basePageIndex: function() {
  29693. var basePageIndex = getBasePageIndex(this);
  29694. return basePageIndex > 0 ? basePageIndex : 0
  29695. },
  29696. load: function() {
  29697. var basePageIndex = getBasePageIndex(this),
  29698. pageIndexForLoad = -1,
  29699. dataSource = this._dataSource,
  29700. result;
  29701. var loadCore = function(that, pageIndex) {
  29702. var dataSource = that._dataSource;
  29703. if (pageIndex === that.pageIndex() || !dataSource.isLoading() && pageIndex < dataSource.pagesCount() || !dataSource.hasKnownLastPage() && pageIndex === dataSource.pagesCount()) {
  29704. dataSource.pageIndex(pageIndex);
  29705. return dataSource.load()
  29706. }
  29707. };
  29708. if (isVirtualMode(this)) {
  29709. if (basePageIndex < 0 || !this._cache[this._pageIndex - basePageIndex])
  29710. pageIndexForLoad = this._pageIndex;
  29711. if (basePageIndex >= 0 && pageIndexForLoad < 0 && this._viewportItemIndex >= 0 && basePageIndex + this._cache.length <= this._pageIndex + getPreloadPageCount(this))
  29712. pageIndexForLoad = basePageIndex + this._cache.length;
  29713. if (pageIndexForLoad >= 0)
  29714. result = loadCore(this, pageIndexForLoad);
  29715. updateLoading(this)
  29716. }
  29717. else if (isAppendMode(this)) {
  29718. if (!dataSource.isLoaded() || this.pageIndex() === dataSource.pagesCount()) {
  29719. dataSource.pageIndex(this.pageIndex());
  29720. result = dataSource.load()
  29721. }
  29722. }
  29723. else
  29724. result = dataSource.load();
  29725. if (!result && this._lastPageIndex !== this.pageIndex())
  29726. this.changed.fire({changeType: 'pageIndex'});
  29727. return result || $.Deferred().resolve()
  29728. },
  29729. isLoading: function() {
  29730. return this._isLoading
  29731. },
  29732. isLoaded: function() {
  29733. return this._dataSource.isLoaded() && this._isLoaded
  29734. },
  29735. changeGroupExpand: function(path) {
  29736. this._cache = [];
  29737. updateLoading(this);
  29738. this._dataSource.changeGroupExpand(path)
  29739. },
  29740. reload: function() {
  29741. var that = this,
  29742. dataSource = that._dataSource;
  29743. that._cache = [];
  29744. that._isLoaded = false;
  29745. updateLoading(that);
  29746. that._isLoaded = true;
  29747. if (isAppendMode(that)) {
  29748. that.pageIndex(0);
  29749. dataSource.pageIndex(0)
  29750. }
  29751. else
  29752. dataSource.pageIndex(that.pageIndex());
  29753. return dataSource.reload()
  29754. }
  29755. }
  29756. }())
  29757. })(jQuery, DevExpress);
  29758. /*! Module widgets-web, file ui.dataGrid.dataSource.js */
  29759. (function($, DX) {
  29760. var dataGrid = DX.ui.dataGrid;
  29761. dataGrid.DataSource = DX.data.DataSource.inherit(function() {
  29762. var hasGrouping = function(that) {
  29763. return !!that._storeLoadOptions.group
  29764. };
  29765. return {
  29766. ctor: function(options, dataSourceWrapper) {
  29767. var that = this;
  29768. that.callBase(options);
  29769. that._pageIndex = options.pageIndex || 0;
  29770. that._asyncLoadEnabled = !!options.asyncLoadEnabled;
  29771. that._loadingTimeout = options.loadingTimeout;
  29772. if (options.useNativeGrouping === 'auto')
  29773. options.useNativeGrouping = that.store() instanceof DX.data.ArrayStore;
  29774. that._groupingHelper = options.useNativeGrouping ? new dataGrid.GroupingHelperWithNativeGrouping(dataSourceWrapper || that) : new dataGrid.GroupingHelper(dataSourceWrapper || that);
  29775. that._hasLastPage = false;
  29776. that._currentTotalCount = 0;
  29777. that._options = options;
  29778. that.map(that._mapFunc)
  29779. },
  29780. map: function(mapFunc) {
  29781. var that = this,
  29782. i,
  29783. store = that.store();
  29784. if (mapFunc)
  29785. if (store instanceof DX.data.ArrayStore) {
  29786. for (i = 0; i < store._array.length; i++)
  29787. store._array[i] = mapFunc(store._array[i]);
  29788. delete that._mapFunc
  29789. }
  29790. else
  29791. that._mapFunc = mapFunc;
  29792. else
  29793. return that._mapFunc
  29794. },
  29795. pageSize: function(value) {
  29796. if (value === undefined)
  29797. return this._paginate ? this._pageSize : 0;
  29798. this._pageSize = value || 20
  29799. },
  29800. totalCount: function() {
  29801. return parseInt(this._currentTotalCount || this._totalCount)
  29802. },
  29803. totalItemsCount: function() {
  29804. var that = this;
  29805. return hasGrouping(that) && that._storeLoadOptions.requireTotalCount ? that._groupingHelper.totalItemsCount() : that.totalCount()
  29806. },
  29807. itemsCount: function() {
  29808. var that = this;
  29809. return hasGrouping(that) ? that._groupingHelper.itemsCount() : that.items().length
  29810. },
  29811. collapseAll: function(groupIndex) {
  29812. return this._groupingHelper.collapseAll(groupIndex)
  29813. },
  29814. expandAll: function(groupIndex) {
  29815. return this._groupingHelper.expandAll(groupIndex)
  29816. },
  29817. pagesCount: function() {
  29818. var that = this,
  29819. count = that.totalItemsCount(),
  29820. pageSize = that.pageSize();
  29821. if (pageSize && count > 0)
  29822. return Math.max(1, Math.ceil(count / pageSize));
  29823. return 1
  29824. },
  29825. _reloadCore: function() {
  29826. var that = this,
  29827. prop,
  29828. userData = that._userData;
  29829. for (prop in userData)
  29830. if (userData.hasOwnProperty(prop))
  29831. delete userData[prop];
  29832. that._isLastPage = !that._paginate;
  29833. that._currentTotalCount = 0;
  29834. that._totalCount = -1;
  29835. that._hasLastPage = that._isLastPage;
  29836. that._isLoaded = false;
  29837. return that.load()
  29838. },
  29839. reload: function() {
  29840. var that = this,
  29841. d = $.Deferred();
  29842. if (that.isLoading()) {
  29843. var loadingChangedHandler = function() {
  29844. that.loadingChanged.remove(loadingChangedHandler);
  29845. setTimeout(function() {
  29846. that.reload().done(d.resolve).fail(d.reject)
  29847. })
  29848. };
  29849. that.loadingChanged.add(loadingChangedHandler)
  29850. }
  29851. else
  29852. $.when(that._groupingHelper.refresh(that._createStoreLoadOptions())).always(function() {
  29853. that._reloadCore().done(d.resolve).fail(d.reject)
  29854. });
  29855. return d
  29856. },
  29857. hasKnownLastPage: function() {
  29858. return this._hasLastPage || this._totalCount >= 0
  29859. },
  29860. changeGroupExpand: function(path) {
  29861. var that = this,
  29862. groupingHelper = that._groupingHelper;
  29863. if (hasGrouping(that)) {
  29864. that._changeLoadingCount(1);
  29865. groupingHelper.changeGroupExpand(path).always(function() {
  29866. that._changeLoadingCount(-1)
  29867. }).done(function() {
  29868. that.load()
  29869. })
  29870. }
  29871. else
  29872. that.load()
  29873. },
  29874. _createLoadQueue: function() {
  29875. return DX.createQueue(true)
  29876. },
  29877. _scheduleChangedCallbacks: function(deferred) {
  29878. var that = this,
  29879. pageIndex = that.pageIndex();
  29880. that._lastLoadDeferred = deferred;
  29881. deferred.done(function() {
  29882. var currentTotalCount,
  29883. itemsCount = that.itemsCount();
  29884. that._isLastPage = !itemsCount || !that._paginate || that._pageSize && itemsCount < that._pageSize;
  29885. if (that.isLastPage())
  29886. that._hasLastPage = true;
  29887. if (that._totalCount >= 0) {
  29888. if (that._pageIndex >= that.pagesCount()) {
  29889. that.pageIndex(that.pagesCount() - 1);
  29890. that.load()
  29891. }
  29892. }
  29893. else {
  29894. currentTotalCount = that.pageIndex() * that.pageSize() + itemsCount;
  29895. that._currentTotalCount = Math.max(that._currentTotalCount, currentTotalCount);
  29896. if (itemsCount === 0 && that.pageIndex() >= that.pagesCount()) {
  29897. that.pageIndex(that.pagesCount() - 1);
  29898. that.load()
  29899. }
  29900. }
  29901. if (pageIndex === that.pageIndex() && !that.isLoading())
  29902. that.changed.fire()
  29903. })
  29904. },
  29905. _loadFromStore: function(storeLoadOptions, pendingDeferred) {
  29906. var that = this;
  29907. var loadTaskCore = function() {
  29908. var i,
  29909. groupOptions,
  29910. groupLoadOptions,
  29911. groupingHelper = that._groupingHelper,
  29912. loads = [],
  29913. datas = [];
  29914. if (that._disposed)
  29915. return;
  29916. if (hasGrouping(that)) {
  29917. groupOptions = groupingHelper.processLoadOptions(storeLoadOptions);
  29918. groupLoadOptions = groupOptions.loads;
  29919. for (i = 0; i < groupLoadOptions.length; i++) {
  29920. loads.push(that.store().load(groupLoadOptions[i]));
  29921. (function(index) {
  29922. loads[index].done(function(data) {
  29923. datas[index] = data
  29924. })
  29925. })(i)
  29926. }
  29927. }
  29928. else
  29929. loads.push(that.store().load(storeLoadOptions));
  29930. $.when.apply($, loads).done(function(data, extra) {
  29931. if (that._disposed)
  29932. return;
  29933. if (hasGrouping(that)) {
  29934. if (datas.length > 1)
  29935. extra = undefined;
  29936. data = groupingHelper.mergeLoadedData(datas, groupOptions.data)
  29937. }
  29938. extra = extra || {totalCount: that._totalCount >= 0 ? that._totalCount : undefined};
  29939. that._processStoreLoadResult(data, extra, storeLoadOptions, pendingDeferred)
  29940. }).fail($.proxy(pendingDeferred.reject, pendingDeferred))
  29941. };
  29942. if (that._asyncLoadEnabled)
  29943. window.setTimeout(loadTaskCore, that._loadingTimeout);
  29944. else
  29945. loadTaskCore()
  29946. }
  29947. }
  29948. }())
  29949. })(jQuery, DevExpress);
  29950. /*! Module widgets-web, file ui.dataGrid.stateStoring.js */
  29951. (function($, DX) {
  29952. var ui = DX.ui,
  29953. utils = DX.utils,
  29954. dataGrid = ui.dataGrid;
  29955. dataGrid.StateStoringController = dataGrid.ViewController.inherit(function() {
  29956. var getStorage = function(options) {
  29957. var storage = options.type === 'sessionStorage' ? sessionStorage : localStorage;
  29958. if (!storage)
  29959. throw new Error("State storing can not be provided due to the restrictions of your browser.");
  29960. return storage
  29961. };
  29962. var getUniqueStorageKey = function(options) {
  29963. return 'dx_datagrid_' + (utils.isDefined(options.storageKey) ? options.storageKey : 'storage')
  29964. };
  29965. var dateReviver = function(key, value) {
  29966. var date;
  29967. if (typeof value === 'string') {
  29968. date = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
  29969. if (date)
  29970. return new Date(Date.UTC(+date[1], +date[2] - 1, +date[3], +date[4], +date[5], +date[6]))
  29971. }
  29972. return value
  29973. };
  29974. var processLoadState = function(that, state) {
  29975. var allowedPageSizes = state.allowedPageSizes,
  29976. searchText = state.searchText,
  29977. selectedRowKeys = state.selectedRowKeys,
  29978. columnsController = that.getController('columns'),
  29979. selectionController = that.getController('selection'),
  29980. dataController = that.getController('data'),
  29981. pagerView = that.getView('pagerView');
  29982. if (columnsController) {
  29983. columnsController.setUserState(state.columns);
  29984. columnsController.columnsChanged.add(function() {
  29985. that.state({columns: columnsController.getUserState()});
  29986. that.save()
  29987. })
  29988. }
  29989. if (selectedRowKeys)
  29990. that.option('selectedRowKeys', selectedRowKeys);
  29991. if (selectionController)
  29992. selectionController.selectionChanged.add(function(keys) {
  29993. that.state({selectedRowKeys: keys});
  29994. that.save()
  29995. });
  29996. if (dataController) {
  29997. if (allowedPageSizes && that.option('pager.allowedPageSizes') === 'auto' && allowedPageSizes)
  29998. that.option('pager').allowedPageSizes = allowedPageSizes;
  29999. if (searchText)
  30000. dataController.searchByText(searchText);
  30001. dataController.changed.add(function() {
  30002. that.state({
  30003. searchText: dataController.getSearchText(),
  30004. pageIndex: dataController.pageIndex(),
  30005. pageSize: dataController.pageSize(),
  30006. allowedPageSizes: pagerView.getPageSizes()
  30007. });
  30008. that.save()
  30009. })
  30010. }
  30011. };
  30012. return {
  30013. _loadState: function() {
  30014. var options = this.option('stateStoring');
  30015. if (options.type === 'custom')
  30016. return options.customLoad && options.customLoad();
  30017. try {
  30018. return JSON.parse(getStorage(options).getItem(getUniqueStorageKey(options)), dateReviver)
  30019. }
  30020. catch(e) {
  30021. DX.utils.logger.error(e.message)
  30022. }
  30023. },
  30024. _saveState: function(state) {
  30025. var options = this.option('stateStoring');
  30026. if (options.type === 'custom') {
  30027. options.customSave && options.customSave(state);
  30028. return
  30029. }
  30030. try {
  30031. getStorage(options).setItem(getUniqueStorageKey(options), JSON.stringify(state))
  30032. }
  30033. catch(e) {}
  30034. },
  30035. publicMethods: function() {
  30036. return ['state']
  30037. },
  30038. isEnabled: function() {
  30039. var stateStoringOptions = this.option('stateStoring');
  30040. return stateStoringOptions && stateStoringOptions.enabled
  30041. },
  30042. init: function() {
  30043. var that = this;
  30044. that._state = {};
  30045. that._isLoaded = false;
  30046. that._isLoading = false
  30047. },
  30048. isLoaded: function() {
  30049. return this._isLoaded
  30050. },
  30051. isLoading: function() {
  30052. return this._isLoading
  30053. },
  30054. load: function() {
  30055. var that = this,
  30056. loadResult;
  30057. that._isLoading = true;
  30058. loadResult = that._loadState();
  30059. if (!loadResult || !$.isFunction(loadResult.done))
  30060. loadResult = $.Deferred().resolve(loadResult);
  30061. loadResult.done(function(state) {
  30062. that._isLoaded = true;
  30063. that._isLoading = false;
  30064. that._state = state || {};
  30065. processLoadState(that, that._state)
  30066. });
  30067. return loadResult
  30068. },
  30069. state: function(state) {
  30070. var that = this;
  30071. if (state === undefined)
  30072. return that._state;
  30073. else
  30074. $.extend(that._state, state)
  30075. },
  30076. save: function() {
  30077. var that = this;
  30078. clearTimeout(that._savingTimeoutID);
  30079. that._savingTimeoutID = setTimeout(function() {
  30080. that._saveState(that.state())
  30081. }, that.option('stateStoring.savingTimeout'))
  30082. },
  30083. dispose: function() {
  30084. clearTimeout(this._savingTimeoutID)
  30085. }
  30086. }
  30087. }());
  30088. dataGrid.registerModule('stateStoring', {
  30089. defaultOptions: function() {
  30090. return {stateStoring: {
  30091. enabled: false,
  30092. storageKey: null,
  30093. type: 'localStorage',
  30094. customLoad: null,
  30095. customSave: null,
  30096. savingTimeout: 2000
  30097. }}
  30098. },
  30099. controllers: {stateStoring: ui.dataGrid.StateStoringController},
  30100. extenders: {controllers: {
  30101. columns: {getVisibleColumns: function() {
  30102. var visibleColumns = this.callBase();
  30103. return this.getController('stateStoring').isLoading() ? [] : visibleColumns
  30104. }},
  30105. data: {
  30106. _refreshDataSource: function() {
  30107. var that = this,
  30108. callBase = that.callBase,
  30109. stateStoringController = that.getController('stateStoring');
  30110. if (stateStoringController.isEnabled() && !stateStoringController.isLoaded())
  30111. stateStoringController.load().done(function() {
  30112. callBase.call(that)
  30113. });
  30114. else
  30115. callBase.call(that)
  30116. },
  30117. isLoading: function() {
  30118. var that = this,
  30119. stateStoringController = that.getController('stateStoring');
  30120. return this.callBase() || stateStoringController.isLoading()
  30121. },
  30122. _dataSourceOptions: function() {
  30123. var that = this,
  30124. result = that.callBase(),
  30125. stateStoringController = that.getController('stateStoring'),
  30126. userState;
  30127. if (stateStoringController.isEnabled()) {
  30128. userState = stateStoringController.state();
  30129. if (userState.pageIndex !== undefined)
  30130. result.pageIndex = userState.pageIndex;
  30131. if (userState.pageSize !== undefined)
  30132. result.pageSize = userState.pageSize
  30133. }
  30134. return result
  30135. }
  30136. }
  30137. }}
  30138. })
  30139. })(jQuery, DevExpress);
  30140. /*! Module widgets-web, file ui.dataGrid.columnsController.js */
  30141. (function($, DX, undefined) {
  30142. var ui = DX.ui,
  30143. dataGrid = ui.dataGrid,
  30144. utils = DX.utils,
  30145. dataUtils = DX.data.utils,
  30146. normalizeSortingInfo = dataUtils.normalizeSortingInfo,
  30147. isDefined = utils.isDefined;
  30148. var USER_STATE_FIELD_NAMES = ['initialIndex', 'dataField', 'width', 'visible', 'sortOrder', 'sortIndex', 'groupIndex', 'filterValue', 'selectedFilterOperation'];
  30149. 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})$/;
  30150. dataGrid.checkChanges = function(changes, changeNames) {
  30151. var changesWithChangeNamesCount = 0,
  30152. i;
  30153. for (i = 0; i < changeNames.length; i++)
  30154. if (changes[changeNames[i]])
  30155. changesWithChangeNamesCount++;
  30156. return changes.length && changes.length === changesWithChangeNamesCount
  30157. };
  30158. var ColumnsController = dataGrid.Controller.inherit(function() {
  30159. var DEFAULT_COLUMN_OPTIONS = {visible: true},
  30160. DATATYPE_OPERATIONS = {
  30161. number: ['=', '<>', '<', '>', '<=', '>='],
  30162. date: ['=', '<>', '<', '>', '<=', '>='],
  30163. string: ['contains', 'notcontains', 'startswith', 'endswith', '=', '<>']
  30164. },
  30165. FIXED_COLUMN_OPTIONS = {
  30166. allowResizing: false,
  30167. allowGrouping: false,
  30168. allowReordering: false,
  30169. allowSorting: false,
  30170. allowHiding: false
  30171. };
  30172. var GROUP_COLUMN_WIDTH = 30;
  30173. var GROUP_LOCATION = 'group',
  30174. COLUMN_CHOOSER_LOCATION = 'columnChooser';
  30175. var convertNameToCaption = function(name) {
  30176. var captionList = [],
  30177. i,
  30178. char,
  30179. isPrevCharNewWord = false,
  30180. isNewWord = false;
  30181. for (i = 0; i < name.length; i++) {
  30182. char = name.charAt(i);
  30183. isNewWord = char === char.toUpperCase() || char in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
  30184. if (char === '_' || char === '.') {
  30185. char = ' ';
  30186. isNewWord = true
  30187. }
  30188. else if (i === 0) {
  30189. char = char.toUpperCase();
  30190. isNewWord = true
  30191. }
  30192. else if (!isPrevCharNewWord && isNewWord)
  30193. if (captionList.length > 0)
  30194. captionList.push(' ');
  30195. captionList.push(char);
  30196. isPrevCharNewWord = isNewWord
  30197. }
  30198. return captionList.join('')
  30199. };
  30200. var createColumn = function(that, columnOptions) {
  30201. var commonColumnOptions,
  30202. calculatedColumnOptions;
  30203. if (columnOptions) {
  30204. if (utils.isString(columnOptions))
  30205. columnOptions = {dataField: columnOptions};
  30206. commonColumnOptions = that.getCommonSettings();
  30207. calculatedColumnOptions = that._createCalculatedColumnOptions(columnOptions);
  30208. return $.extend(true, {}, DEFAULT_COLUMN_OPTIONS, commonColumnOptions, calculatedColumnOptions, columnOptions)
  30209. }
  30210. };
  30211. var createColumnsFromOptions = function(that, columnsOptions) {
  30212. var result = [];
  30213. if (columnsOptions)
  30214. $.each(columnsOptions, function(index, value) {
  30215. var column = createColumn(that, value);
  30216. if (column) {
  30217. if (column.initialIndex === undefined)
  30218. column.initialIndex = index;
  30219. result.push(column)
  30220. }
  30221. });
  30222. return result
  30223. };
  30224. var getValueDataType = function(value) {
  30225. var dataType = $.type(value);
  30226. if (dataType === 'string') {
  30227. if (utils.isNumber(value))
  30228. dataType = 'number';
  30229. else if (GUID_REGEX.test(value))
  30230. dataType = 'guid'
  30231. }
  30232. else if (dataType !== 'boolean' && dataType !== 'number' && dataType !== 'date')
  30233. dataType = undefined;
  30234. return dataType
  30235. };
  30236. var getAlignmentByDataType = function(dataType, isRTL) {
  30237. switch (dataType) {
  30238. case'number':
  30239. return 'right';
  30240. case'boolean':
  30241. return 'center';
  30242. case'date':
  30243. return 'left';
  30244. default:
  30245. return isRTL ? 'right' : 'left'
  30246. }
  30247. };
  30248. var getFormatByDataType = function(dataType) {
  30249. switch (dataType) {
  30250. case"date":
  30251. return "shortDate"
  30252. }
  30253. };
  30254. var getCustomizeTextByDataType = function(dataType) {
  30255. if (dataType === 'boolean')
  30256. return function(e) {
  30257. if (e.value === true)
  30258. return this.trueText || 'true';
  30259. else if (e.value === false)
  30260. return this.falseText || 'false';
  30261. else
  30262. return e.valueText || ''
  30263. }
  30264. };
  30265. var createColumnsFromDataSource = function(that, dataSource) {
  30266. var firstItems = getFirstItems(dataSource),
  30267. fieldName,
  30268. processedFields = {},
  30269. i,
  30270. initialIndex = 0,
  30271. result = [];
  30272. for (i = 0; i < firstItems.length; i++)
  30273. firstItems[i] && $.each(firstItems[i], function(fieldName) {
  30274. processedFields[fieldName] = true
  30275. });
  30276. $.each(processedFields, function(fieldName) {
  30277. if (fieldName.indexOf('__') !== 0) {
  30278. var column = createColumn(that, fieldName);
  30279. column.initialIndex = initialIndex++;
  30280. result.push(column)
  30281. }
  30282. });
  30283. return result
  30284. };
  30285. var equalSortParameters = function(sortParameters1, sortParameters2) {
  30286. var i;
  30287. if ($.isArray(sortParameters1) && $.isArray(sortParameters2)) {
  30288. if (sortParameters1.length !== sortParameters2.length)
  30289. return false;
  30290. else
  30291. for (i = 0; i < sortParameters1.length; i++)
  30292. if (sortParameters1[i].selector !== sortParameters2[i].selector || sortParameters1[i].desc !== sortParameters2[i].desc || !sortParameters1[i].isExpanded !== !sortParameters2[i].isExpanded)
  30293. return false;
  30294. return true
  30295. }
  30296. else
  30297. return (!sortParameters1 || !sortParameters1.length) === (!sortParameters2 || !sortParameters2.length)
  30298. };
  30299. var getFirstItems = function(dataSource) {
  30300. var groupsCount,
  30301. items = [];
  30302. var getFirstItemsCore = function(items, groupsCount) {
  30303. var i,
  30304. childItems;
  30305. if (!items || !groupsCount)
  30306. return items;
  30307. for (i = 0; i < items.length; i++) {
  30308. childItems = getFirstItemsCore(items[i].items, groupsCount - 1);
  30309. if (childItems && childItems.length)
  30310. return childItems
  30311. }
  30312. };
  30313. if (dataSource && dataSource.items().length > 0) {
  30314. groupsCount = normalizeSortingInfo(dataSource.group() || []).length;
  30315. items = getFirstItemsCore(dataSource.items(), groupsCount) || []
  30316. }
  30317. return items
  30318. };
  30319. var updateColumnIndexes = function(that) {
  30320. $.each(that._columns, function(index, column) {
  30321. column.index = index
  30322. })
  30323. };
  30324. var updateColumnParameterIndexes = function(that, indexParameterName, currentColumn) {
  30325. var indexedSortColumns = [],
  30326. parameterIndex = 0;
  30327. $.each(that._columns, function(index, column) {
  30328. var index = column[indexParameterName];
  30329. if (isDefined(index)) {
  30330. if (!indexedSortColumns[index])
  30331. indexedSortColumns[index] = [];
  30332. if (column === currentColumn)
  30333. indexedSortColumns[index].unshift(column);
  30334. else
  30335. indexedSortColumns[index].push(column);
  30336. delete column[indexParameterName]
  30337. }
  30338. });
  30339. $.each(indexedSortColumns, function(index, sortColumns) {
  30340. if (sortColumns)
  30341. $.each(sortColumns, function() {
  30342. this[indexParameterName] = parameterIndex++
  30343. })
  30344. });
  30345. return parameterIndex
  30346. };
  30347. var updateColumnGroupIndexes = function(that, currentColumn) {
  30348. var indexPropertyName = 'groupIndex',
  30349. groupIndex = updateColumnParameterIndexes(that, indexPropertyName, currentColumn);
  30350. $.each(that._columns, function(index, column) {
  30351. if (!isDefined(column[indexPropertyName]) && column.grouped)
  30352. column[indexPropertyName] = groupIndex++;
  30353. delete column.grouped
  30354. })
  30355. };
  30356. var updateColumnSortIndexes = function(that, currentColumn) {
  30357. $.each(that._columns, function(index, column) {
  30358. if (isDefined(column.sortIndex) && !isSortOrderValid(column.sortOrder))
  30359. delete column.sortIndex
  30360. });
  30361. var sortIndex = updateColumnParameterIndexes(that, 'sortIndex', currentColumn);
  30362. $.each(that._columns, function(index, column) {
  30363. if (!isDefined(column.sortIndex) && !isDefined(column.groupIndex) && isSortOrderValid(column.sortOrder))
  30364. column.sortIndex = sortIndex++
  30365. })
  30366. };
  30367. var parseDate = function(value) {
  30368. var parsedDate;
  30369. if (!utils.isDate(value))
  30370. if (utils.isNumber(value))
  30371. value = new Date(value);
  30372. else {
  30373. parsedDate = Date.parse(value);
  30374. if (parsedDate)
  30375. value = new Date(parsedDate)
  30376. }
  30377. return value
  30378. };
  30379. var applyColumnTypesToDataSource = function(that, dataSource) {
  30380. var i,
  30381. columns = that._columns,
  30382. firstItem = getFirstItems(dataSource)[0],
  30383. fieldName,
  30384. userMapFunc,
  30385. columnTypesMapFunc,
  30386. columnTypesWithUserMapFunc,
  30387. groupsCount,
  30388. dateFieldNames = [],
  30389. numberFieldNames = [];
  30390. if (dataSource && dataSource.map) {
  30391. for (i = 0; i < columns.length; i++) {
  30392. fieldName = columns[i].dataField;
  30393. if (fieldName)
  30394. switch (columns[i].dataType) {
  30395. case"date":
  30396. if (!firstItem || !utils.isDate(firstItem[fieldName]))
  30397. dateFieldNames.push(fieldName);
  30398. break;
  30399. case"number":
  30400. if (!firstItem || utils.isString(firstItem[fieldName]))
  30401. numberFieldNames.push(fieldName);
  30402. break
  30403. }
  30404. }
  30405. var convertValue = function(item, fieldNames, groupsCount, parseFunc) {
  30406. if (!groupsCount || !utils.isDefined(item.items))
  30407. for (var i = 0; i < fieldNames.length; i++) {
  30408. var fieldValue = item[fieldNames[i]];
  30409. if (fieldValue)
  30410. item[fieldNames[i]] = parseFunc(fieldValue)
  30411. }
  30412. else
  30413. $.each(item.items, function(index, item) {
  30414. convertValue(item, fieldNames, groupsCount - 1, parseFunc)
  30415. })
  30416. };
  30417. if (dateFieldNames.length > 0 || numberFieldNames.length > 0) {
  30418. userMapFunc = dataSource.map();
  30419. columnTypesMapFunc = function(item) {
  30420. var groupsCount;
  30421. if (item) {
  30422. groupsCount = normalizeSortingInfo(dataSource.group() || []).length;
  30423. convertValue(item, dateFieldNames, groupsCount, parseDate);
  30424. convertValue(item, numberFieldNames, groupsCount, Number)
  30425. }
  30426. return item
  30427. };
  30428. columnTypesWithUserMapFunc = function(item) {
  30429. item = userMapFunc ? userMapFunc(item) : item;
  30430. return columnTypesMapFunc(item)
  30431. };
  30432. dataSource.map(columnTypesWithUserMapFunc);
  30433. if (!dataSource.map()) {
  30434. dataSource.store().inserting.remove(that._insertingHandler);
  30435. that._insertingHandler = function(values) {
  30436. columnTypesWithUserMapFunc(values)
  30437. };
  30438. dataSource.store().inserting.add(that._insertingHandler)
  30439. }
  30440. else
  30441. $.each(dataSource.items(), function() {
  30442. columnTypesMapFunc(this)
  30443. });
  30444. return dataSource.load()
  30445. }
  30446. }
  30447. };
  30448. var getColumnIndexByVisibleIndex = function(that, visibleIndex, location) {
  30449. var columns = location === GROUP_LOCATION ? that.getGroupColumns() : location === COLUMN_CHOOSER_LOCATION ? that.getHiddenColumns() : that.getVisibleColumns(),
  30450. column = columns[visibleIndex];
  30451. return column && isDefined(column.index) ? column.index : -1
  30452. };
  30453. var moveColumnToGroup = function(that, column, groupIndex) {
  30454. var groupColumns = that.getGroupColumns(),
  30455. i;
  30456. if (groupIndex >= 0) {
  30457. for (i = 0; i < groupColumns.length; i++)
  30458. if (groupColumns[i].groupIndex >= groupIndex)
  30459. groupColumns[i].groupIndex++
  30460. }
  30461. else {
  30462. groupIndex = 0;
  30463. for (i = 0; i < groupColumns.length; i++)
  30464. groupIndex = Math.max(groupIndex, groupColumns[i].groupIndex + 1)
  30465. }
  30466. column.groupIndex = groupIndex
  30467. };
  30468. var applyUserState = function(that) {
  30469. var columnsUserState = that._columnsUserState,
  30470. columns = that._columns,
  30471. resultColumns = [],
  30472. columnsByInitialIndex = [],
  30473. column,
  30474. i;
  30475. if (columnsUserState) {
  30476. if (columns.length !== columnsUserState.length)
  30477. return;
  30478. for (i = 0; i < columns.length; i++)
  30479. columnsByInitialIndex[columns[i].initialIndex] = columns[i];
  30480. for (i = 0; i < columnsUserState.length; i++) {
  30481. column = columnsByInitialIndex[columnsUserState[i].initialIndex];
  30482. if (column && columnsUserState[i].dataField === column.dataField) {
  30483. column = $.extend({}, column);
  30484. $.each(USER_STATE_FIELD_NAMES, function(index, value) {
  30485. column[value] = columnsUserState[i][value]
  30486. });
  30487. resultColumns.push(column)
  30488. }
  30489. else
  30490. return
  30491. }
  30492. that._columns = resultColumns
  30493. }
  30494. };
  30495. var updateIndexes = function(that, column) {
  30496. updateColumnIndexes(that);
  30497. updateColumnGroupIndexes(that, column);
  30498. updateColumnSortIndexes(that, column)
  30499. };
  30500. var updateColumnChanges = function(that, changeType, optionName, column) {
  30501. var columnChanges = that._columnChanges || {
  30502. optionNames: {length: 0},
  30503. changeTypes: {length: 0},
  30504. columnIndex: column && column.initialIndex,
  30505. column: column
  30506. };
  30507. var changeTypes = columnChanges.changeTypes;
  30508. if (changeType && !changeTypes[changeType]) {
  30509. changeTypes[changeType] = true;
  30510. changeTypes.length++
  30511. }
  30512. var optionNames = columnChanges.optionNames;
  30513. if (optionName && !optionNames[optionName]) {
  30514. optionNames[optionName] = true;
  30515. optionNames.length++
  30516. }
  30517. if (column === undefined || column !== columnChanges.column) {
  30518. delete columnChanges.column;
  30519. delete columnChanges.columnIndex
  30520. }
  30521. that._columnChanges = columnChanges;
  30522. that._visibleColumns = undefined
  30523. };
  30524. var fireColumnsChanged = function(that, changeType) {
  30525. if (changeType)
  30526. updateColumnChanges(that, changeType);
  30527. if (!that._updateLockCount && that._columnChanges) {
  30528. that.columnsChanged.fire(that._columnChanges);
  30529. that._columnChanges = undefined
  30530. }
  30531. };
  30532. var columnOptionCore = function(that, column, optionName, value) {
  30533. var optionGetter = dataUtils.compileGetter(optionName),
  30534. changeType;
  30535. if (arguments.length === 3)
  30536. return optionGetter(column, {functionsAsIs: true});
  30537. if (optionGetter(column, {functionsAsIs: true}) !== value) {
  30538. if (optionName === 'groupIndex')
  30539. changeType = 'grouping';
  30540. else if (optionName === 'sortIndex' || optionName === 'sortOrder')
  30541. changeType = 'sorting';
  30542. else
  30543. changeType = 'columns';
  30544. dataUtils.compileSetter(optionName)(column, value, {functionsAsIs: true});
  30545. updateColumnChanges(that, changeType, optionName, column)
  30546. }
  30547. };
  30548. var isSortOrderValid = function(sortOrder) {
  30549. return sortOrder === 'asc' || sortOrder === 'desc'
  30550. };
  30551. return {
  30552. init: function() {
  30553. var that = this,
  30554. columns = that.option('columns');
  30555. that._columns = columns ? createColumnsFromOptions(that, columns) : [];
  30556. that._updateLockCount = that._updateLockCount || 0;
  30557. that._isColumnsFromOptions = !!columns;
  30558. if (that._isColumnsFromOptions)
  30559. applyUserState(that);
  30560. else
  30561. that._columns = that._columnsUserState || that._columns;
  30562. if (that._dataSourceApplied)
  30563. that.applyDataSource(that._dataSource, true);
  30564. else
  30565. updateIndexes(that)
  30566. },
  30567. callbackNames: function() {
  30568. return ['columnsChanged']
  30569. },
  30570. optionChanged: function(name, value, prevValue) {
  30571. switch (name) {
  30572. case'columns':
  30573. case'commonColumnSettings':
  30574. case'columnAutoWidth':
  30575. case'allowColumnResizing':
  30576. case'allowColumnReordering':
  30577. case'grouping':
  30578. case'groupPanel':
  30579. case'regenerateColumnsByVisibleItems':
  30580. case'customizeColumns':
  30581. case'editing':
  30582. case'rtlEnabled':
  30583. this._columnsUserState = this.getUserState();
  30584. this.init();
  30585. break
  30586. }
  30587. },
  30588. publicMethods: function() {
  30589. return ['addColumn', 'columnOption', 'columnCount']
  30590. },
  30591. applyDataSource: function(dataSource, forceApplying) {
  30592. var that = this,
  30593. isDataSourceLoaded = dataSource && dataSource.isLoaded(),
  30594. applyingComplete;
  30595. that._dataSource = dataSource;
  30596. if (!that._dataSourceApplied || that._dataSourceColumnsCount === 0 || forceApplying || that.option('regenerateColumnsByVisibleItems'))
  30597. if (isDataSourceLoaded) {
  30598. if (!that._isColumnsFromOptions) {
  30599. that._columns = createColumnsFromDataSource(that, dataSource);
  30600. that._dataSourceColumnsCount = that._columns.length;
  30601. applyUserState(that)
  30602. }
  30603. return that.updateColumns(dataSource)
  30604. }
  30605. },
  30606. reset: function() {
  30607. this._dataSourceApplied = false;
  30608. this._dataSourceColumnsCount = undefined
  30609. },
  30610. isInitialized: function() {
  30611. return !!this._columns.length
  30612. },
  30613. isDataSourceApplied: function() {
  30614. return this._dataSourceApplied
  30615. },
  30616. beginUpdate: function() {
  30617. this._updateLockCount++
  30618. },
  30619. endUpdate: function() {
  30620. var that = this;
  30621. that._updateLockCount--;
  30622. if (!that._updateLockCount)
  30623. fireColumnsChanged(that)
  30624. },
  30625. getCommonSettings: function() {
  30626. var commonColumnSettings = this.option('commonColumnSettings') || {},
  30627. groupingOptions = this.option('grouping') || {},
  30628. groupPanelOptions = this.option('groupPanel') || {};
  30629. return $.extend({
  30630. allowResizing: this.option('allowColumnResizing'),
  30631. allowReordering: this.option('allowColumnReordering'),
  30632. autoExpandGroup: groupingOptions.autoExpandAll,
  30633. allowCollapsing: groupingOptions.allowCollapsing,
  30634. allowGrouping: groupPanelOptions.allowColumnDragging && groupPanelOptions.visible
  30635. }, commonColumnSettings)
  30636. },
  30637. isColumnOptionUsed: function(optionName) {
  30638. for (var i = 0; i < this._columns.length; i++)
  30639. if (this._columns[i][optionName])
  30640. return true
  30641. },
  30642. getColumns: function() {
  30643. return $.extend(true, [], this._columns)
  30644. },
  30645. getGroupColumns: function() {
  30646. var result = [];
  30647. $.each(this._columns, function() {
  30648. var column = this;
  30649. if (isDefined(column.groupIndex))
  30650. result[column.groupIndex] = column
  30651. });
  30652. return result
  30653. },
  30654. getVisibleColumns: function() {
  30655. var visibleColumns = $.map(this.getGroupColumns(), function(column) {
  30656. return $.extend({}, column, {width: GROUP_COLUMN_WIDTH}, FIXED_COLUMN_OPTIONS)
  30657. });
  30658. var notGroupedColumnsCount = 0;
  30659. $.each(this._columns, function() {
  30660. var column = this;
  30661. if (column.visible && !isDefined(column.groupIndex)) {
  30662. column = $.extend(true, {}, column);
  30663. visibleColumns.push(column);
  30664. notGroupedColumnsCount++
  30665. }
  30666. });
  30667. if (!notGroupedColumnsCount && this._columns.length)
  30668. visibleColumns.push({command: 'empty'});
  30669. return visibleColumns
  30670. },
  30671. getHiddenColumns: function() {
  30672. var result = [];
  30673. $.each(this._columns, function(_, column) {
  30674. if (!column.visible)
  30675. result.push(column)
  30676. });
  30677. return result
  30678. },
  30679. allowMoveColumn: function(fromVisibleIndex, toVisibleIndex, sourceLocation, targetLocation) {
  30680. var that = this,
  30681. columnIndex = getColumnIndexByVisibleIndex(that, fromVisibleIndex, sourceLocation),
  30682. sourceColumn = that._columns[columnIndex];
  30683. if (sourceColumn && (sourceColumn.allowReordering || sourceColumn.allowGrouping || sourceColumn.allowHiding)) {
  30684. if (sourceLocation === targetLocation) {
  30685. if (sourceLocation === COLUMN_CHOOSER_LOCATION)
  30686. return false;
  30687. return fromVisibleIndex !== toVisibleIndex && fromVisibleIndex + 1 !== toVisibleIndex
  30688. }
  30689. else if (sourceLocation === GROUP_LOCATION && targetLocation !== COLUMN_CHOOSER_LOCATION || targetLocation === GROUP_LOCATION)
  30690. return sourceColumn && sourceColumn.allowGrouping;
  30691. else if (sourceLocation === COLUMN_CHOOSER_LOCATION || targetLocation === COLUMN_CHOOSER_LOCATION)
  30692. return sourceColumn && sourceColumn.allowHiding;
  30693. return true
  30694. }
  30695. return false
  30696. },
  30697. moveColumn: function(fromVisibleIndex, toVisibleIndex, sourceLocation, targetLocation) {
  30698. var that = this,
  30699. fromIndex,
  30700. toIndex,
  30701. targetGroupIndex,
  30702. isGroupMoving = sourceLocation === GROUP_LOCATION || targetLocation === GROUP_LOCATION,
  30703. column;
  30704. fromIndex = getColumnIndexByVisibleIndex(that, fromVisibleIndex, sourceLocation);
  30705. toIndex = getColumnIndexByVisibleIndex(that, toVisibleIndex, targetLocation);
  30706. if (fromIndex >= 0) {
  30707. column = that._columns[fromIndex];
  30708. targetGroupIndex = toIndex >= 0 ? that._columns[toIndex].groupIndex : -1;
  30709. if (isDefined(column.groupIndex)) {
  30710. if (targetGroupIndex > column.groupIndex)
  30711. targetGroupIndex--;
  30712. delete column.groupIndex;
  30713. delete column.sortOrder;
  30714. updateColumnGroupIndexes(that)
  30715. }
  30716. if (targetLocation === GROUP_LOCATION)
  30717. moveColumnToGroup(that, column, targetGroupIndex);
  30718. else if (toVisibleIndex >= 0) {
  30719. that._columns.splice(fromIndex, 1);
  30720. if (toIndex < 0)
  30721. that._columns.push(column);
  30722. else {
  30723. var spliceIndex = toIndex > fromIndex ? toIndex - 1 : toIndex;
  30724. that._columns.splice(spliceIndex, 0, column)
  30725. }
  30726. updateColumnIndexes(that)
  30727. }
  30728. column.visible = targetLocation !== COLUMN_CHOOSER_LOCATION;
  30729. fireColumnsChanged(that, isGroupMoving ? 'grouping' : 'columns')
  30730. }
  30731. },
  30732. changeSortOrder: function(columnIndex, sortOrder) {
  30733. var that = this,
  30734. sortingOptions = that.option('sorting'),
  30735. sortingMode = sortingOptions && sortingOptions.mode,
  30736. needResetSorting = sortingMode === 'single' || !sortOrder,
  30737. allowSorting = sortingMode === 'single' || sortingMode === 'multiple',
  30738. column = that._columns[columnIndex],
  30739. nextSortOrder = function(column) {
  30740. if (sortOrder === "ctrl") {
  30741. delete column.sortOrder;
  30742. delete column.sortIndex
  30743. }
  30744. else if (isDefined(column.groupIndex) || isDefined(column.sortIndex))
  30745. column.sortOrder = column.sortOrder === 'desc' ? 'asc' : 'desc';
  30746. else
  30747. column.sortOrder = 'asc'
  30748. },
  30749. isSortingChanged = false;
  30750. if (allowSorting && column && column.allowSorting) {
  30751. if (needResetSorting && !isDefined(column.groupIndex))
  30752. $.each(that._columns, function(index) {
  30753. if (index !== columnIndex && this.sortOrder && !isDefined(this.groupIndex)) {
  30754. delete this.sortOrder;
  30755. delete this.sortIndex;
  30756. isSortingChanged = true
  30757. }
  30758. });
  30759. if (isSortOrderValid(sortOrder)) {
  30760. if (column.sortOrder !== sortOrder) {
  30761. column.sortOrder = sortOrder;
  30762. isSortingChanged = true
  30763. }
  30764. }
  30765. else if (sortOrder === 'none') {
  30766. if (column.sortOrder) {
  30767. delete column.sortIndex;
  30768. delete column.sortOrder;
  30769. isSortingChanged = true
  30770. }
  30771. }
  30772. else {
  30773. nextSortOrder(column);
  30774. isSortingChanged = true
  30775. }
  30776. }
  30777. if (isSortingChanged) {
  30778. updateColumnSortIndexes(that);
  30779. fireColumnsChanged(that, 'sorting')
  30780. }
  30781. },
  30782. getSortDataSourceParameters: function() {
  30783. var that = this,
  30784. sortColumns = [],
  30785. sort = [];
  30786. $.each(that._columns, function() {
  30787. if ((this.dataField || this.calculateCellValue) && this.visible && isDefined(this.sortIndex) && !isDefined(this.groupIndex))
  30788. sortColumns[this.sortIndex] = this
  30789. });
  30790. $.each(sortColumns, function() {
  30791. var sortOrder = this && this.sortOrder;
  30792. if (isSortOrderValid(sortOrder))
  30793. sort.push({
  30794. selector: this.dataField || this.calculateCellValue,
  30795. desc: this.sortOrder === 'desc'
  30796. })
  30797. });
  30798. return sort.length > 0 ? sort : null
  30799. },
  30800. getGroupDataSourceParameters: function() {
  30801. var group = [];
  30802. $.each(this.getGroupColumns(), function() {
  30803. var selector = this.dataField || this.calculateCellValue;
  30804. if (selector)
  30805. group.push({
  30806. selector: selector,
  30807. desc: this.sortOrder === 'desc',
  30808. isExpanded: !!this.autoExpandGroup
  30809. })
  30810. });
  30811. return group.length > 0 ? group : null
  30812. },
  30813. refresh: function(updateNewLookupsOnly) {
  30814. var deferreds = [];
  30815. $.each(this._columns, function() {
  30816. var lookup = this.lookup;
  30817. if (lookup) {
  30818. if (updateNewLookupsOnly && lookup.valueMap)
  30819. return;
  30820. if (lookup.update)
  30821. deferreds.push(lookup.update())
  30822. }
  30823. });
  30824. return $.when.apply($, deferreds)
  30825. },
  30826. _updateColumnDataTypes: function(dataSource) {
  30827. var firstItems = getFirstItems(dataSource),
  30828. rtlEnabled = this.option("rtlEnabled");
  30829. $.each(this._columns, function(index, column) {
  30830. var i,
  30831. value,
  30832. dataType,
  30833. lookup = column.lookup;
  30834. if (column.dataField && firstItems.length)
  30835. for (i = 0; (!column.dataType || lookup && !lookup.dataType) && i < firstItems.length; i++) {
  30836. value = column.calculateCellValue(firstItems[i]);
  30837. column.dataType = getValueDataType(value);
  30838. if (lookup)
  30839. lookup.dataType = getValueDataType(lookup.calculateCellValue(value))
  30840. }
  30841. dataType = lookup ? lookup.dataType : column.dataType;
  30842. if (dataType) {
  30843. column.alignment = column.alignment || getAlignmentByDataType(dataType, rtlEnabled);
  30844. column.format = column.format || getFormatByDataType(dataType);
  30845. column.customizeText = column.customizeText || getCustomizeTextByDataType(dataType);
  30846. if (!isDefined(column.filterOperations))
  30847. column.filterOperations = !lookup && DATATYPE_OPERATIONS[dataType] || [];
  30848. column.defaultFilterOperation = column.filterOperations && column.filterOperations[0] || '=';
  30849. column.defaultSelectedFilterOperation = column.selectedFilterOperation
  30850. }
  30851. })
  30852. },
  30853. updateColumns: function(dataSource) {
  30854. var that = this,
  30855. customizeColumns = that.option('customizeColumns'),
  30856. sortParameters,
  30857. groupParameters;
  30858. that.updateSortingGrouping(dataSource);
  30859. if (!dataSource || dataSource.isLoaded()) {
  30860. sortParameters = dataSource ? dataSource.sort() || [] : that.getSortDataSourceParameters();
  30861. groupParameters = dataSource ? dataSource.group() || [] : that.getGroupDataSourceParameters();
  30862. if (customizeColumns) {
  30863. customizeColumns(that._columns);
  30864. that._columns = createColumnsFromOptions(that, that._columns)
  30865. }
  30866. updateIndexes(that);
  30867. that._updateColumnDataTypes(dataSource);
  30868. return $.when(that.refresh(true), applyColumnTypesToDataSource(that, dataSource)).always(function() {
  30869. if (dataSource) {
  30870. that._updateColumnDataTypes(dataSource);
  30871. that._dataSourceApplied = true
  30872. }
  30873. if (!equalSortParameters(sortParameters, that.getSortDataSourceParameters()))
  30874. updateColumnChanges(that, 'sorting');
  30875. else if (!equalSortParameters(groupParameters, that.getGroupDataSourceParameters()))
  30876. updateColumnChanges(that, 'grouping');
  30877. else
  30878. updateColumnChanges(that, 'columns');
  30879. fireColumnsChanged(that)
  30880. })
  30881. }
  30882. },
  30883. updateSortingGrouping: function(dataSource) {
  30884. var that = this,
  30885. sortParameters,
  30886. groupParameters,
  30887. columnsGroupParameters,
  30888. columnsSortParameters,
  30889. updateSortGroupParameterIndexes = function(columns, sortParameters, indexParameterName) {
  30890. var i;
  30891. $.each(columns, function(index, column) {
  30892. if (column.dataField) {
  30893. delete column[indexParameterName];
  30894. if (sortParameters && sortParameters.length)
  30895. for (i = 0; i < sortParameters.length; i++)
  30896. if (sortParameters[i].selector === column.dataField) {
  30897. column.sortOrder = column.sortOrder || (sortParameters[i].desc ? 'desc' : 'asc');
  30898. column[indexParameterName] = i;
  30899. break
  30900. }
  30901. }
  30902. })
  30903. };
  30904. if (dataSource) {
  30905. sortParameters = normalizeSortingInfo(dataSource.sort() || []);
  30906. groupParameters = normalizeSortingInfo(dataSource.group() || []);
  30907. columnsGroupParameters = that.getGroupDataSourceParameters();
  30908. columnsSortParameters = that.getSortDataSourceParameters();
  30909. if (!that._columns.length) {
  30910. $.each(groupParameters, function(index, group) {
  30911. that._columns.push(group.selector)
  30912. });
  30913. $.each(sortParameters, function(index, sort) {
  30914. that._columns.push(sort.selector)
  30915. });
  30916. that._columns = createColumnsFromOptions(that, that._columns)
  30917. }
  30918. if (!columnsGroupParameters && !equalSortParameters(groupParameters, columnsGroupParameters)) {
  30919. that.__groupingUpdated = true;
  30920. updateSortGroupParameterIndexes(that._columns, groupParameters, 'groupIndex')
  30921. }
  30922. if (!columnsSortParameters && !equalSortParameters(sortParameters, columnsSortParameters)) {
  30923. that.__sortingUpdated = true;
  30924. updateSortGroupParameterIndexes(that._columns, sortParameters, 'sortIndex')
  30925. }
  30926. }
  30927. },
  30928. columnCount: function() {
  30929. return this._columns.length
  30930. },
  30931. columnOption: function(identificator, option, value) {
  30932. var that = this,
  30933. i,
  30934. columns = that._columns,
  30935. column;
  30936. for (i = 0; i < columns.length; i++)
  30937. if (columns[i].initialIndex === identificator || columns[i].dataField === identificator || columns[i].caption === identificator) {
  30938. column = columns[i];
  30939. break
  30940. }
  30941. if (column) {
  30942. if (arguments.length === 1)
  30943. return $.extend({}, column);
  30944. if (utils.isString(option))
  30945. if (arguments.length === 2)
  30946. return columnOptionCore(that, column, option);
  30947. else
  30948. columnOptionCore(that, column, option, value);
  30949. else if (utils.isObject(option))
  30950. $.each(option, function(optionName, value) {
  30951. columnOptionCore(that, column, optionName, value)
  30952. });
  30953. updateIndexes(that, column);
  30954. fireColumnsChanged(that)
  30955. }
  30956. },
  30957. getVisibleIndex: function(initialIndex) {
  30958. var i,
  30959. visibleColumns = this.getVisibleColumns();
  30960. for (i = 0; i < visibleColumns.length; i++)
  30961. if (visibleColumns[i].initialIndex === initialIndex)
  30962. return i;
  30963. return -1
  30964. },
  30965. addColumn: function(options) {
  30966. var that = this;
  30967. that._columns.push(createColumn(that, options));
  30968. that.updateColumns()
  30969. },
  30970. getUserState: function() {
  30971. var columns = this._columns,
  30972. result = [],
  30973. i;
  30974. for (i = 0; i < columns.length; i++) {
  30975. result[i] = {};
  30976. $.each(USER_STATE_FIELD_NAMES, function(index, value) {
  30977. if (columns[i][value] !== undefined)
  30978. result[i][value] = columns[i][value]
  30979. })
  30980. }
  30981. return result
  30982. },
  30983. setUserState: function(state) {
  30984. this._columnsUserState = state;
  30985. this.init()
  30986. },
  30987. _createCalculatedColumnOptions: function(columnOptions) {
  30988. var calculatedColumnOptions = {};
  30989. if (columnOptions.dataField) {
  30990. calculatedColumnOptions = {
  30991. caption: convertNameToCaption(columnOptions.dataField),
  30992. calculateCellValue: dataUtils.compileGetter(columnOptions.dataField),
  30993. validate: function(value) {
  30994. if (typeof value === 'string')
  30995. return !value || !this.parseValue || this.parseValue(value) !== undefined;
  30996. return true
  30997. },
  30998. parseValue: function(text) {
  30999. var column = this,
  31000. result,
  31001. parsedValue;
  31002. if (column.dataType === 'number') {
  31003. if (utils.isString(text)) {
  31004. parsedValue = Globalize.parseFloat(text);
  31005. if (utils.isNumber(parsedValue))
  31006. result = parsedValue
  31007. }
  31008. else if (utils.isDefined(text))
  31009. result = Number(text)
  31010. }
  31011. else if (column.dataType === 'boolean') {
  31012. if (text === column.trueText)
  31013. result = true;
  31014. else if (text === column.falseText)
  31015. result = false
  31016. }
  31017. else if (column.dataType === 'date') {
  31018. parsedValue = Globalize.parseDate(text);
  31019. if (parsedValue)
  31020. result = parsedValue
  31021. }
  31022. else if (column.dataType === 'guid') {
  31023. if (GUID_REGEX.test(text))
  31024. result = text
  31025. }
  31026. else
  31027. result = text;
  31028. return result
  31029. }
  31030. };
  31031. if (columnOptions.lookup)
  31032. calculatedColumnOptions.lookup = {
  31033. calculateCellValue: function(value) {
  31034. return this.valueMap && this.valueMap[value]
  31035. },
  31036. updateValueMap: function() {
  31037. var calculateValue,
  31038. calculateDisplayValue,
  31039. item,
  31040. i;
  31041. this.valueMap = {};
  31042. if (this.items) {
  31043. calculateValue = dataUtils.compileGetter(this.valueExpr);
  31044. calculateDisplayValue = dataUtils.compileGetter(this.displayExpr);
  31045. for (i = 0; i < this.items.length; i++) {
  31046. item = this.items[i];
  31047. this.valueMap[calculateValue(item)] = calculateDisplayValue(item)
  31048. }
  31049. }
  31050. },
  31051. update: function() {
  31052. var that = this,
  31053. dataSource = that.dataSource;
  31054. if (dataSource)
  31055. if (utils.isObject(dataSource) || utils.isArray(dataSource)) {
  31056. dataSource = new DX.data.DataSource($.extend(true, {
  31057. paginate: false,
  31058. _preferSync: true
  31059. }, dataUtils.normalizeDataSourceOptions(dataSource)));
  31060. return dataSource.load().done(function(data) {
  31061. that.items = data;
  31062. that.updateValueMap && that.updateValueMap()
  31063. })
  31064. }
  31065. else
  31066. DX.utils.logger.error("Unexpected type of data source is provided for a lookup column. For the list of supported types, see http://js.devexpress.com/Documentation/ApiReference/UI_Widgets/dxDataGrid/Configuration/columns/lookup#dataSource");
  31067. else
  31068. that.updateValueMap && that.updateValueMap()
  31069. }
  31070. }
  31071. }
  31072. else
  31073. $.extend(true, calculatedColumnOptions, {calculateCellValue: function() {
  31074. return null
  31075. }});
  31076. calculatedColumnOptions.resizedCallbacks = $.Callbacks();
  31077. if (columnOptions.resized)
  31078. calculatedColumnOptions.resizedCallbacks.add($.proxy(columnOptions.resized, columnOptions));
  31079. return calculatedColumnOptions
  31080. }
  31081. }
  31082. }());
  31083. ui.dataGrid.ColumnsController = ColumnsController;
  31084. dataGrid.registerModule('columns', {
  31085. defaultOptions: function() {
  31086. return {
  31087. commonColumnSettings: {
  31088. allowFiltering: true,
  31089. allowHiding: true,
  31090. allowSorting: true,
  31091. allowEditing: true,
  31092. encodeHtml: true,
  31093. trueText: Globalize.localize("dxDataGrid-trueText"),
  31094. falseText: Globalize.localize("dxDataGrid-falseText")
  31095. },
  31096. grouping: {
  31097. autoExpandAll: true,
  31098. allowCollapsing: true,
  31099. groupContinuesMessage: Globalize.localize("dxDataGrid-groupContinuesMessage"),
  31100. groupContinuedMessage: Globalize.localize("dxDataGrid-groupContinuedMessage")
  31101. },
  31102. allowColumnReordering: false,
  31103. allowColumnResizing: false,
  31104. columns: undefined,
  31105. regenerateColumnsByVisibleItems: false,
  31106. sorting: {
  31107. mode: 'single',
  31108. ascendingText: Globalize.localize("dxDataGrid-sortingAscendingText"),
  31109. descendingText: Globalize.localize("dxDataGrid-sortingDescendingText"),
  31110. clearText: Globalize.localize("dxDataGrid-sortingClearText")
  31111. },
  31112. customizeColumns: null
  31113. }
  31114. },
  31115. controllers: {columns: ColumnsController}
  31116. })
  31117. })(jQuery, DevExpress);
  31118. /*! Module widgets-web, file ui.dataGrid.selection.js */
  31119. (function($, DX) {
  31120. var dataGrid = DX.ui.dataGrid,
  31121. events = DX.ui.events,
  31122. utils = DX.utils;
  31123. var DATAGRID_EDITOR_CELL_CLASS = "dx-editor-cell",
  31124. DATAGRID_ROW_SELECTION_CLASS = "dx-selection",
  31125. DATAGRID_SELECT_CHECKBOX_CLASS = "dx-select-checkbox",
  31126. LONG_TAP_TIME = 500,
  31127. MAX_EQUAL_KEYS_LEVEL = 3;
  31128. $.extend(dataGrid.__internals, {DATAGRID_ROW_SELECTION_CLASS: DATAGRID_ROW_SELECTION_CLASS});
  31129. var SHOW_CHECKBOXES_MODE = 'selection.showCheckBoxesInMultipleMode';
  31130. dataGrid.equalKeys = function(key1, key2, level) {
  31131. var propertyName,
  31132. i;
  31133. level = level || 0;
  31134. if (level < MAX_EQUAL_KEYS_LEVEL)
  31135. if (utils.isObject(key1) && utils.isObject(key2)) {
  31136. for (propertyName in key1)
  31137. if (key1.hasOwnProperty(propertyName) && !dataGrid.equalKeys(key1[propertyName], key2[propertyName], level + 1))
  31138. return false;
  31139. for (propertyName in key2)
  31140. if (!(propertyName in key1))
  31141. return false;
  31142. return true
  31143. }
  31144. else if (utils.isArray(key1) && utils.isArray(key2)) {
  31145. if (key1.length !== key2.length)
  31146. return false;
  31147. for (i = 0; i < key1.length; i++)
  31148. if (!dataGrid.equalKeys(key1[i], key2[i], level + 1))
  31149. return false;
  31150. return true
  31151. }
  31152. else if (utils.isDate(key1) && utils.isDate(key2))
  31153. return key1.getTime() === key2.getTime();
  31154. else
  31155. return key1 === key2;
  31156. return true
  31157. };
  31158. dataGrid.SelectionController = dataGrid.Controller.inherit(function() {
  31159. var SELECTION_MODE = 'selection.mode';
  31160. var isSelectable = function(selectionMode) {
  31161. return selectionMode === 'single' || selectionMode === 'multiple'
  31162. };
  31163. var indexOfSelectedItemKey = function(that, key, isSelectAll) {
  31164. var index,
  31165. selectedItemKeys = isSelectAll ? that._unselectedItemKeys : that._selectedItemKeys;
  31166. if (utils.isObject(key)) {
  31167. for (index = 0; index < selectedItemKeys.length; index++)
  31168. if (equalKeys(selectedItemKeys[index], key))
  31169. return index;
  31170. return -1
  31171. }
  31172. else
  31173. return $.inArray(key, selectedItemKeys)
  31174. };
  31175. var addSelectedItem = function(that, itemData) {
  31176. var key = that.getController('data').keyOf(itemData),
  31177. keyIndex;
  31178. if (indexOfSelectedItemKey(that, key) === -1) {
  31179. that._selectedItemKeys.push(key);
  31180. that._addedItemKeys.push(key);
  31181. that._selectedItems.push(itemData)
  31182. }
  31183. if (that._isSelectAll) {
  31184. keyIndex = indexOfSelectedItemKey(that, key, true);
  31185. that._unselectedItemKeys.splice(keyIndex, 1)
  31186. }
  31187. };
  31188. var removeSelectedItem = function(that, key) {
  31189. var keyIndex = indexOfSelectedItemKey(that, key);
  31190. if (keyIndex >= 0) {
  31191. that._selectedItemKeys.splice(keyIndex, 1);
  31192. that._removedItemKeys.push(key);
  31193. that._selectedItems.splice(keyIndex, 1);
  31194. if (that._isSelectAll && indexOfSelectedItemKey(that, key, true) === -1)
  31195. that._unselectedItemKeys.push(key)
  31196. }
  31197. };
  31198. var clearSelectedItems = function(that) {
  31199. setSelectedItems(that, [], [])
  31200. };
  31201. var setSelectedItems = function(that, keys, items, isSelectAll) {
  31202. var i,
  31203. oldSelectedItemKeys = that._selectedItemKeys;
  31204. that._selectedItemKeys = keys;
  31205. that._selectedItems = items;
  31206. that._unselectedItemKeys = [];
  31207. that._isSelectAll = !!isSelectAll;
  31208. for (i = 0; i < oldSelectedItemKeys.length; i++)
  31209. if ($.inArray(oldSelectedItemKeys[i], keys) === -1)
  31210. that._removedItemKeys.push(oldSelectedItemKeys[i]);
  31211. for (i = 0; i < keys.length; i++)
  31212. if ($.inArray(keys[i], oldSelectedItemKeys) === -1)
  31213. that._addedItemKeys.push(keys[i])
  31214. };
  31215. var equalKeys = dataGrid.equalKeys;
  31216. var resetItemSelectionWhenShiftKeyPressed = function(that) {
  31217. delete that._shiftFocusedItemIndex
  31218. };
  31219. var isDataItem = function(row) {
  31220. return row && row.rowType === "data"
  31221. };
  31222. var changeItemSelectionWhenShiftKeyPressed = function(that, itemIndex, items) {
  31223. var isSelectedItemsChanged = false,
  31224. itemIndexStep,
  31225. index,
  31226. dataController = that.getController('data'),
  31227. isFocusedItemSelected = items[that._focusedItemIndex] && that.isSelectedItem(dataController.keyOf(items[that._focusedItemIndex].data));
  31228. var addRemoveSelectedItem = function(that, data, isRemove) {
  31229. if (isRemove)
  31230. removeSelectedItem(that, dataController.keyOf(data));
  31231. else
  31232. addSelectedItem(that, data)
  31233. };
  31234. if (!utils.isDefined(that._shiftFocusedItemIndex))
  31235. that._shiftFocusedItemIndex = that._focusedItemIndex;
  31236. if (that._shiftFocusedItemIndex !== that._focusedItemIndex) {
  31237. itemIndexStep = that._focusedItemIndex < that._shiftFocusedItemIndex ? 1 : -1;
  31238. for (index = that._focusedItemIndex; index !== that._shiftFocusedItemIndex; index += itemIndexStep)
  31239. if (isDataItem(items[index])) {
  31240. addRemoveSelectedItem(that, items[index].data, true);
  31241. isSelectedItemsChanged = true
  31242. }
  31243. }
  31244. if (itemIndex !== that._shiftFocusedItemIndex) {
  31245. itemIndexStep = itemIndex < that._shiftFocusedItemIndex ? 1 : -1;
  31246. for (index = itemIndex; index !== that._shiftFocusedItemIndex; index += itemIndexStep)
  31247. if (isDataItem(items[index])) {
  31248. addRemoveSelectedItem(that, items[index].data, false);
  31249. isSelectedItemsChanged = true
  31250. }
  31251. }
  31252. if (isDataItem(items[that._focusedItemIndex]) && !isFocusedItemSelected) {
  31253. addRemoveSelectedItem(that, items[that._focusedItemIndex].data, false);
  31254. isSelectedItemsChanged = true
  31255. }
  31256. return isSelectedItemsChanged
  31257. };
  31258. var createSelectedItemsFilterCriteria = function(dataSource, selectedItemKeys, isSelectAll) {
  31259. var keyCriteria,
  31260. i,
  31261. key = dataSource && dataSource.key(),
  31262. criteria = [];
  31263. if (dataSource)
  31264. if (key)
  31265. $.each(selectedItemKeys, function(index, keyValue) {
  31266. if (criteria.length > 0)
  31267. criteria.push(isSelectAll ? 'and' : 'or');
  31268. if ($.isArray(key)) {
  31269. keyCriteria = [];
  31270. for (i = 0; i < key.length; i++) {
  31271. if (i > 0)
  31272. keyCriteria.push(isSelectAll ? 'or' : 'and');
  31273. keyCriteria.push([key[i], isSelectAll ? '<>' : '=', keyValue[key[i]]])
  31274. }
  31275. criteria.push(keyCriteria)
  31276. }
  31277. else
  31278. criteria.push([key, isSelectAll ? '<>' : '=', keyValue])
  31279. });
  31280. else
  31281. criteria = function(item) {
  31282. var i;
  31283. for (i = 0; i < selectedItemKeys.length; i++)
  31284. if (equalKeys(selectedItemKeys[i], item))
  31285. return !isSelectAll;
  31286. return isSelectAll
  31287. };
  31288. if (criteria.length > 0 || $.isFunction(criteria))
  31289. return criteria
  31290. };
  31291. var updateSelectedItems = function(that) {
  31292. var changedItemIndexes = [],
  31293. dataController = that.getController('data'),
  31294. addedItemKeys,
  31295. removedItemKeys;
  31296. if (dataController) {
  31297. $.each(dataController.items(), function(index, row) {
  31298. var key = dataController.keyOf(row.data);
  31299. if (isDataItem(row) && row.isSelected !== that.isSelectedItem(key))
  31300. changedItemIndexes.push(index)
  31301. });
  31302. if (that.option(SHOW_CHECKBOXES_MODE) === 'onClick')
  31303. if (that._selectedItemKeys.length > 1)
  31304. that.startSelectionWithCheckboxes();
  31305. else if (that._selectedItemKeys.length === 0 && changedItemIndexes.length)
  31306. that.stopSelectionWithCheckboxes();
  31307. if (changedItemIndexes.length)
  31308. dataController.updateItems({
  31309. changeType: 'updateSelection',
  31310. itemIndexes: changedItemIndexes
  31311. });
  31312. addedItemKeys = that._addedItemKeys;
  31313. removedItemKeys = that._removedItemKeys;
  31314. if (addedItemKeys.length || removedItemKeys.length) {
  31315. that._selectedItemsInternalChange = true;
  31316. that.option("selectedRowKeys", that._selectedItemKeys.slice(0));
  31317. that._selectedItemsInternalChange = false;
  31318. that.selectionChanged.fire(that._selectedItemKeys);
  31319. that.executeAction("selectionChanged", {
  31320. selectedRowsData: that._selectedItems,
  31321. selectedRowKeys: that._selectedItemKeys,
  31322. currentSelectedRowKeys: addedItemKeys,
  31323. currentDeselectedRowKeys: removedItemKeys
  31324. })
  31325. }
  31326. that._addedItemKeys = [];
  31327. that._removedItemKeys = []
  31328. }
  31329. };
  31330. return {
  31331. init: function() {
  31332. var that = this;
  31333. that._isSelectionWithCheckboxes = false;
  31334. that._focusedItemIndex = -1;
  31335. that._selectedItemKeys = [];
  31336. that._unselectedItemKeys = [];
  31337. that._selectedItems = [];
  31338. that._addedItemKeys = [];
  31339. that._removedItemKeys = [];
  31340. that._isSelectAll = false;
  31341. that.createAction("selectionChanged")
  31342. },
  31343. callbackNames: function() {
  31344. return ['selectionChanged']
  31345. },
  31346. optionChanged: function(name, value, prevValue) {
  31347. switch (name) {
  31348. case"selection":
  31349. this.init();
  31350. this.getController('columns').updateColumns();
  31351. break;
  31352. case"selectedRowKeys":
  31353. if (utils.isArray(value) && !this._selectedItemsInternalChange)
  31354. this.selectRows(value);
  31355. break;
  31356. case"selectionChanged":
  31357. this.createAction("selectionChanged");
  31358. break
  31359. }
  31360. },
  31361. publicMethods: function() {
  31362. return ['selectRows', 'selectRowsByIndexes', 'getSelectedRowKeys', 'getSelectedRowsData', 'clearSelection', 'selectAll', 'startSelectionWithCheckboxes', 'stopSelectionWithCheckboxes']
  31363. },
  31364. isSelectedItem: function(key) {
  31365. var index = indexOfSelectedItemKey(this, key);
  31366. return index !== -1
  31367. },
  31368. isSelectColumnVisible: function() {
  31369. var showCheckboxesMode = this.option(SHOW_CHECKBOXES_MODE);
  31370. return this.option(SELECTION_MODE) === 'multiple' && (showCheckboxesMode === 'always' || showCheckboxesMode === 'onClick' || this._isSelectionWithCheckboxes)
  31371. },
  31372. isSelectAll: function() {
  31373. return this._isSelectAll && !this._unselectedItemKeys.length
  31374. },
  31375. selectAll: function() {
  31376. if (this.option(SHOW_CHECKBOXES_MODE) === 'onClick')
  31377. this.startSelectionWithCheckboxes();
  31378. return this.selectedItemKeys([], true)
  31379. },
  31380. clearSelection: function() {
  31381. this.selectedItemKeys([])
  31382. },
  31383. refresh: function() {
  31384. var that = this,
  31385. result;
  31386. if (that.isSelectAll())
  31387. result = that.selectAll();
  31388. else
  31389. result = that.selectedItemKeys(that.option("selectedRowKeys") || []);
  31390. return result.done(function(selectedRows) {
  31391. updateSelectedItems(that)
  31392. })
  31393. },
  31394. selectedItemKeys: function(value, isSelectAll) {
  31395. var that = this,
  31396. keys,
  31397. criteria,
  31398. isFunctionCriteria,
  31399. deferred,
  31400. dataController = that.getController('data'),
  31401. dataSource = dataController.dataSource(),
  31402. store = dataSource && dataSource.store(),
  31403. dataSourceFilter,
  31404. filter;
  31405. if (utils.isDefined(value)) {
  31406. if (store) {
  31407. keys = $.isArray(value) ? $.extend(true, [], value) : [value];
  31408. that._isSelectAll = isSelectAll;
  31409. if (keys.length || isSelectAll) {
  31410. criteria = createSelectedItemsFilterCriteria(dataSource, keys, isSelectAll);
  31411. isFunctionCriteria = $.isFunction(criteria);
  31412. if (criteria || isSelectAll) {
  31413. dataSourceFilter = dataSource.filter();
  31414. if (criteria && !isFunctionCriteria && dataSourceFilter) {
  31415. filter = [];
  31416. filter.push(criteria);
  31417. filter.push(dataSourceFilter)
  31418. }
  31419. else if (dataSourceFilter)
  31420. filter = dataSourceFilter;
  31421. else if (criteria && !isFunctionCriteria)
  31422. filter = criteria;
  31423. deferred = $.Deferred();
  31424. dataController.setSelectionLoading(true);
  31425. store.load({filter: filter}).done(function(items) {
  31426. new DX.data.ArrayStore(items).load({filter: criteria}).done(function(items) {
  31427. deferred.resolve(items)
  31428. })
  31429. }).fail($.proxy(deferred.reject, deferred)).always(function() {
  31430. dataController.setSelectionLoading(false)
  31431. })
  31432. }
  31433. }
  31434. }
  31435. deferred = deferred || $.Deferred().resolve([]);
  31436. deferred.done(function(items) {
  31437. var i,
  31438. key,
  31439. keys = [];
  31440. if (store && items.length > 0)
  31441. for (i = 0; i < items.length; i++) {
  31442. key = store.keyOf(items[i]);
  31443. keys.push(key)
  31444. }
  31445. setSelectedItems(that, keys, items, isSelectAll);
  31446. updateSelectedItems(that)
  31447. });
  31448. return deferred
  31449. }
  31450. else
  31451. return that._selectedItemKeys
  31452. },
  31453. getSelectedRowKeys: function() {
  31454. return this.selectedItemKeys()
  31455. },
  31456. selectRows: function(keys) {
  31457. return this.selectedItemKeys(keys)
  31458. },
  31459. selectRowsByIndexes: function(indexes) {
  31460. var items = this.getController('data').items(),
  31461. i,
  31462. keys = [];
  31463. if (!utils.isArray(indexes))
  31464. indexes = Array.prototype.slice.call(arguments, 0);
  31465. $.each(indexes, function() {
  31466. var item = items[this];
  31467. if (item && item.rowType === 'data')
  31468. keys.push(item.key)
  31469. });
  31470. return this.selectRows(keys)
  31471. },
  31472. getSelectedRowsData: function() {
  31473. return this._selectedItems
  31474. },
  31475. changeItemSelection: function(itemIndex, keys) {
  31476. var that = this,
  31477. dataController = that.getController('data'),
  31478. items = dataController.items(),
  31479. item = items[itemIndex],
  31480. itemData = item && item.data,
  31481. selectionMode = that.option(SELECTION_MODE),
  31482. isSelectedItemsChanged,
  31483. isSelected,
  31484. itemKey;
  31485. if (isSelectable(selectionMode) && isDataItem(item)) {
  31486. itemKey = dataController.keyOf(itemData);
  31487. keys = keys || {};
  31488. if (that.isSelectionWithCheckboxes())
  31489. keys.control = true;
  31490. if (keys.shift && selectionMode === 'multiple' && that._focusedItemIndex >= 0)
  31491. isSelectedItemsChanged = changeItemSelectionWhenShiftKeyPressed(that, itemIndex, items);
  31492. else if (keys.control) {
  31493. resetItemSelectionWhenShiftKeyPressed(that);
  31494. isSelected = that.isSelectedItem(itemKey);
  31495. if (selectionMode === 'single')
  31496. clearSelectedItems(that);
  31497. if (isSelected)
  31498. removeSelectedItem(that, itemKey);
  31499. else
  31500. addSelectedItem(that, itemData);
  31501. isSelectedItemsChanged = true
  31502. }
  31503. else {
  31504. resetItemSelectionWhenShiftKeyPressed(that);
  31505. if (that._selectedItemKeys.length !== 1 || !equalKeys(that._selectedItemKeys[0], itemKey)) {
  31506. setSelectedItems(that, [itemKey], [itemData]);
  31507. isSelectedItemsChanged = true
  31508. }
  31509. }
  31510. if (isSelectedItemsChanged) {
  31511. that._focusedItemIndex = itemIndex;
  31512. updateSelectedItems(that);
  31513. return true
  31514. }
  31515. }
  31516. return false
  31517. },
  31518. focusedItemIndex: function(itemIndex) {
  31519. var that = this;
  31520. if (utils.isDefined(itemIndex))
  31521. that._focusedItemIndex = itemIndex;
  31522. else
  31523. return that._focusedItemIndex
  31524. },
  31525. isSelectionWithCheckboxes: function() {
  31526. var selectionMode = this.option(SELECTION_MODE),
  31527. showCheckboxesMode = this.option(SHOW_CHECKBOXES_MODE);
  31528. return selectionMode === 'multiple' && (showCheckboxesMode === 'always' || this._isSelectionWithCheckboxes)
  31529. },
  31530. startSelectionWithCheckboxes: function() {
  31531. var that = this,
  31532. isSelectColumnVisible = that.isSelectColumnVisible();
  31533. if (that.option(SELECTION_MODE) === 'multiple' && !that.isSelectionWithCheckboxes()) {
  31534. that._isSelectionWithCheckboxes = true;
  31535. if (isSelectColumnVisible !== that.isSelectColumnVisible())
  31536. that.getController('columns').updateColumns();
  31537. else if (that.option(SHOW_CHECKBOXES_MODE) === 'onClick')
  31538. updateSelectedItems(that);
  31539. return true
  31540. }
  31541. return false
  31542. },
  31543. stopSelectionWithCheckboxes: function() {
  31544. var that = this,
  31545. isSelectColumnVisible = that.isSelectColumnVisible();
  31546. if (that._isSelectionWithCheckboxes) {
  31547. that._isSelectionWithCheckboxes = false;
  31548. if (isSelectColumnVisible !== that.isSelectColumnVisible())
  31549. that.getController('columns').updateColumns();
  31550. return true
  31551. }
  31552. return false
  31553. }
  31554. }
  31555. }());
  31556. dataGrid.registerModule('selection', {
  31557. defaultOptions: function() {
  31558. return {
  31559. selection: {
  31560. mode: 'none',
  31561. showCheckBoxesInMultipleMode: 'onClick',
  31562. allowSelectAll: true
  31563. },
  31564. selectionChanged: null,
  31565. selectedRowKeys: []
  31566. }
  31567. },
  31568. controllers: {selection: dataGrid.SelectionController},
  31569. extenders: {
  31570. controllers: {
  31571. data: {
  31572. setDataSource: function(dataSource) {
  31573. this.callBase(dataSource);
  31574. this.getController('selection').refresh()
  31575. },
  31576. setSelectionLoading: function(isLoading) {
  31577. this._isSelectionLoading = isLoading;
  31578. this._fireLoadingChanged()
  31579. },
  31580. isLoading: function() {
  31581. var isLoading = this.callBase();
  31582. return isLoading || !!this._isSelectionLoading
  31583. },
  31584. pageIndex: function(value) {
  31585. var that = this,
  31586. dataSource = that._dataSource;
  31587. if (dataSource && value && dataSource.pageIndex() !== value)
  31588. that.getController('selection').focusedItemIndex(-1);
  31589. return that.callBase(value)
  31590. },
  31591. _processDataItem: function() {
  31592. var that = this,
  31593. selectionController = that.getController('selection'),
  31594. hasSelectColumn = selectionController.isSelectColumnVisible(),
  31595. dataItem = this.callBase.apply(this, arguments);
  31596. dataItem.isSelected = selectionController.isSelectedItem(dataItem.key);
  31597. if (hasSelectColumn && dataItem.values)
  31598. dataItem.values[0] = dataItem.isSelected;
  31599. return dataItem
  31600. },
  31601. refresh: function() {
  31602. this.callBase.apply(this, arguments);
  31603. this.getController('selection').refresh()
  31604. }
  31605. },
  31606. columns: {getVisibleColumns: function() {
  31607. var that = this,
  31608. selectionController = that.getController('selection'),
  31609. columns = that.callBase();
  31610. columns = $.grep(columns, function(column) {
  31611. return column.command !== 'select'
  31612. });
  31613. if (selectionController.isSelectColumnVisible() && columns.length)
  31614. columns.unshift({
  31615. visible: true,
  31616. command: 'select',
  31617. dataType: 'boolean',
  31618. alignment: 'center',
  31619. width: 70
  31620. });
  31621. return columns
  31622. }}
  31623. },
  31624. views: {
  31625. columnHeadersView: {
  31626. _renderCore: function(options) {
  31627. var that = this;
  31628. that.getController('selection').selectionChanged.remove(that._selectionChangedHandler);
  31629. that.callBase(options)
  31630. },
  31631. _renderHeaderContent: function(rootElement, column, columnIndex) {
  31632. var that = this,
  31633. groupElement,
  31634. selectionController = that.getController('selection');
  31635. var getSelectAllValue = function(selectionController) {
  31636. if (selectionController.isSelectAll() || selectionController.getSelectedRowKeys().length === 0)
  31637. return selectionController.isSelectAll()
  31638. };
  31639. if (column.command === 'select') {
  31640. rootElement.addClass(DATAGRID_EDITOR_CELL_CLASS);
  31641. groupElement = $('<div />').appendTo(rootElement);
  31642. that.getController('editorFactory').createEditor(groupElement, $.extend({}, column, {
  31643. parentType: "headerRow",
  31644. value: getSelectAllValue(selectionController),
  31645. setValue: function(value, e) {
  31646. if (e.jQueryEvent && getSelectAllValue(selectionController) !== value) {
  31647. if (e.previousValue === undefined || e.previousValue) {
  31648. selectionController.clearSelection();
  31649. e.component.option('value', false)
  31650. }
  31651. if (e.previousValue === false)
  31652. if (that.option("selection.allowSelectAll"))
  31653. selectionController.selectAll();
  31654. else
  31655. e.component.option('value', false);
  31656. e.jQueryEvent.preventDefault()
  31657. }
  31658. }
  31659. }));
  31660. rootElement.on('dxclick', that.createAction(function(e) {
  31661. var event = e.jQueryEvent;
  31662. if (!$(event.target).closest('.dx-checkbox').length)
  31663. $(event.currentTarget).children().trigger('dxclick');
  31664. event.preventDefault()
  31665. }));
  31666. that._selectionChangedHandler = function() {
  31667. groupElement.dxCheckBox('instance').option('value', getSelectAllValue(selectionController))
  31668. };
  31669. selectionController.selectionChanged.add(that._selectionChangedHandler)
  31670. }
  31671. else
  31672. that.callBase(rootElement, column, columnIndex)
  31673. }
  31674. },
  31675. rowsView: {
  31676. _getDefaultTemplate: function(column) {
  31677. var that = this,
  31678. groupElement;
  31679. if (column.command === 'select')
  31680. return function(container, options) {
  31681. container.addClass(DATAGRID_EDITOR_CELL_CLASS);
  31682. container.on('dxclick', that.createAction(function(e) {
  31683. var selectionController = that.getController('selection'),
  31684. event = e.jQueryEvent,
  31685. rowIndex = that.getRowIndex($(event.currentTarget).closest('.dx-row'));
  31686. if (rowIndex >= 0) {
  31687. selectionController.startSelectionWithCheckboxes();
  31688. selectionController.changeItemSelection(rowIndex, {shift: event.shiftKey})
  31689. }
  31690. }));
  31691. groupElement = $('<div />').addClass(DATAGRID_SELECT_CHECKBOX_CLASS).appendTo(container);
  31692. that.getController('editorFactory').createEditor(groupElement, $.extend({}, column, {
  31693. parentType: "dataRow",
  31694. value: options.value
  31695. }))
  31696. };
  31697. else
  31698. return that.callBase(column)
  31699. },
  31700. _update: function(change) {
  31701. var that = this;
  31702. if (change.changeType === 'updateSelection') {
  31703. if (that._tableElement.length > 0)
  31704. $.each(change.itemIndexes || [], function(_, index) {
  31705. var $row,
  31706. isSelected;
  31707. if (change.items[index]) {
  31708. $row = that._getRowElements().eq(index);
  31709. isSelected = !!change.items[index].isSelected;
  31710. $row.toggleClass(DATAGRID_ROW_SELECTION_CLASS, isSelected);
  31711. $row.find('.dx-checkbox').dxCheckBox('option', 'value', isSelected)
  31712. }
  31713. });
  31714. that._updateCheckboxesClass()
  31715. }
  31716. else
  31717. that.callBase(change)
  31718. },
  31719. _createTable: function() {
  31720. var that = this,
  31721. $table = that.callBase();
  31722. return $table.on(events.addNamespace('dxpointerdown', "dxDataGridRowsView"), that.createAction(function(e) {
  31723. that._isTouchEvent = events.isTouchEvent(e.jQueryEvent)
  31724. })).on(events.addNamespace('dxhold', "dxDataGridRowsView"), {timeout: that.option("selection.longTapTime") || LONG_TAP_TIME}, that.createAction(function(e) {
  31725. var selectionController = that.getController('selection'),
  31726. event = e.jQueryEvent;
  31727. if (that.option(SHOW_CHECKBOXES_MODE) === 'onLongTap')
  31728. if (selectionController.isSelectionWithCheckboxes())
  31729. selectionController.stopSelectionWithCheckboxes();
  31730. else
  31731. selectionController.startSelectionWithCheckboxes();
  31732. if (that.option(SHOW_CHECKBOXES_MODE) === 'onClick')
  31733. $(event.target).closest('.dx-row').find(DATAGRID_SELECT_CHECKBOX_CLASS).parent().trigger('dxclick')
  31734. })).on('mousedown selectstart', that.createAction(function(e) {
  31735. var event = e.jQueryEvent;
  31736. if (event.shiftKey)
  31737. event.preventDefault()
  31738. }))
  31739. },
  31740. _createRow: function(rowOptions) {
  31741. var $row = this.callBase(rowOptions);
  31742. rowOptions && $row.toggleClass(DATAGRID_ROW_SELECTION_CLASS, !!rowOptions.isSelected);
  31743. return $row
  31744. },
  31745. _rowClick: function(rowIndex, event) {
  31746. var that = this;
  31747. that.getController('selection').changeItemSelection(rowIndex, {
  31748. control: event.ctrlKey,
  31749. shift: event.shiftKey
  31750. });
  31751. that.callBase(rowIndex, event)
  31752. },
  31753. _renderCore: function(change) {
  31754. this.callBase(change);
  31755. this._updateCheckboxesClass()
  31756. },
  31757. _updateCheckboxesClass: function() {
  31758. var selectionController = this.getController('selection');
  31759. this._element().toggleClass('dx-select-checkboxes-hidden', selectionController.isSelectColumnVisible() && !selectionController.isSelectionWithCheckboxes())
  31760. }
  31761. }
  31762. }
  31763. }
  31764. })
  31765. })(jQuery, DevExpress);
  31766. /*! Module widgets-web, file ui.dataGrid.editorFactory.js */
  31767. (function($, DX) {
  31768. var dataGrid = DX.ui.dataGrid,
  31769. addNamespace = DX.ui.events.addNamespace;
  31770. var FILTERING_TIMEOUT = 700,
  31771. DATAGRID_CHECKBOX_SIZE_CLASS = "dx-datagrid-checkbox-size",
  31772. DATAGRID_MODULE_NAMESPACE = 'dxDataGridEditorFactory',
  31773. DATAGRID_UPDATE_FOCUS_EVENTS = addNamespace('focusin dxpointerdown dxclick', DATAGRID_MODULE_NAMESPACE),
  31774. ENTER_KEY = 13,
  31775. TAB_KEY = 9,
  31776. DATAGRID_FOCUS_OVERLAY_CLASS = 'dx-datagrid-focus-overlay',
  31777. DATAGRID_FOCUSED_ELEMENT_CLASS = 'dx-focused',
  31778. DATAGRID_CONTENT_CLASS = 'dx-datagrid-content';
  31779. dataGrid.EditorFactoryController = dataGrid.Controller.inherit(function() {
  31780. var createCalendarPicker = function($container, options) {
  31781. $container.dxDateBox({
  31782. value: options.value,
  31783. useCalendar: true,
  31784. customOverlayCssClass: 'dx-datagrid',
  31785. formatString: DX.utils.isString(options.format) && DX.DateTimeFormat[options.format.toLowerCase()] || options.format,
  31786. formatWidthCalculator: null,
  31787. rtlEnabled: options.rtlEnabled,
  31788. disabled: options.disabled
  31789. });
  31790. $container.dxDateBox('instance').optionChanged.add(function(optionName, value) {
  31791. if (optionName === 'value')
  31792. options.setValue(value)
  31793. })
  31794. };
  31795. var createTextBox = function($container, options) {
  31796. var toString = function(value) {
  31797. return DX.utils.isDefined(value) ? value.toString() : ''
  31798. },
  31799. isFilterRow = options.parentType === 'filterRow',
  31800. isSearchPanel = options.parentType === 'searchPanel';
  31801. $container.dxTextBox({
  31802. placeholder: options.placeholder,
  31803. width: options.width,
  31804. value: toString(options.value),
  31805. valueChangeAction: function(e) {
  31806. var updateValue = function(e, isTimeout) {
  31807. var parsedValue;
  31808. if (!options.validate || options.validate(e.value)) {
  31809. parsedValue = options.parseValue ? options.parseValue(e.value) : e.value;
  31810. options.setValue(parsedValue !== undefined ? parsedValue : null, e)
  31811. }
  31812. else if (!isTimeout)
  31813. e.component.option('value', toString(e.previousValue))
  31814. };
  31815. window.clearTimeout($container._valueChangeTimeoutID);
  31816. if (e.jQueryEvent && e.jQueryEvent.type === "keyup")
  31817. $container._valueChangeTimeoutID = window.setTimeout(function() {
  31818. updateValue(e, true)
  31819. }, FILTERING_TIMEOUT);
  31820. else if (e.jQueryEvent && e.jQueryEvent.type === 'keydown') {
  31821. if (e.jQueryEvent.which === ENTER_KEY || e.jQueryEvent.which === TAB_KEY)
  31822. updateValue(e)
  31823. }
  31824. else
  31825. updateValue(e)
  31826. },
  31827. mode: isSearchPanel ? 'search' : 'text',
  31828. valueChangeEvent: 'change keydown' + (isFilterRow ? ' keyup' : '') + (isSearchPanel ? ' keyup search' : ''),
  31829. rtlEnabled: options.rtlEnabled,
  31830. disabled: options.disabled
  31831. })
  31832. };
  31833. var createBooleanEditor = function($container, options) {
  31834. if (options.parentType === 'filterRow')
  31835. createSelectBox($container, $.extend({lookup: {
  31836. displayExpr: function(data) {
  31837. if (data === true)
  31838. return options.trueText || 'true';
  31839. else if (data === false)
  31840. return options.falseText || 'false'
  31841. },
  31842. items: [true, false],
  31843. rtlEnabled: options.rtlEnabled,
  31844. disabled: options.disabled
  31845. }}, options));
  31846. else
  31847. createCheckBox($container, options)
  31848. };
  31849. var createSelectBox = function($container, options) {
  31850. var lookup = options.lookup,
  31851. items,
  31852. displayGetter,
  31853. isFilterRow = options.parentType === 'filterRow';
  31854. if (lookup) {
  31855. items = lookup.items;
  31856. displayGetter = DX.data.utils.compileGetter(lookup.displayExpr);
  31857. if (isFilterRow && items) {
  31858. items = items.slice(0);
  31859. items.unshift(null)
  31860. }
  31861. $container.dxSelectBox({
  31862. value: options.value || null,
  31863. valueExpr: options.lookup.valueExpr,
  31864. showClearButton: lookup.allowClearing && !isFilterRow,
  31865. displayExpr: function(data) {
  31866. if (data === null)
  31867. return options.showAllText;
  31868. return displayGetter(data)
  31869. },
  31870. items: items,
  31871. valueChangeAction: function(e) {
  31872. options.setValue(e.value, e)
  31873. },
  31874. rtlEnabled: options.rtlEnabled,
  31875. disabled: options.disabled
  31876. })
  31877. }
  31878. };
  31879. var createCheckBox = function($container, options) {
  31880. $container.addClass(DATAGRID_CHECKBOX_SIZE_CLASS).dxCheckBox({
  31881. value: options.value,
  31882. valueChangeAction: function(e) {
  31883. options.setValue && options.setValue(e.value, e)
  31884. },
  31885. rtlEnabled: options.rtlEnabled
  31886. })
  31887. };
  31888. return {
  31889. _updateFocusCore: function() {
  31890. var $focus = this._$focusedElement,
  31891. $dataGridElement = this.component && this.component._element();
  31892. if ($dataGridElement) {
  31893. $focus = $dataGridElement.find('[tabindex]:focus, input:focus');
  31894. if ($focus.length) {
  31895. $focus = $focus.closest('.dx-editor-cell > *, .dx-row > td');
  31896. if ($focus.length) {
  31897. this.focus($focus);
  31898. return
  31899. }
  31900. }
  31901. }
  31902. this.loseFocus()
  31903. },
  31904. _updateFocus: function(e) {
  31905. var that = this,
  31906. isFocusOverlay = e.jQueryEvent && $(e.jQueryEvent.target).hasClass(DATAGRID_FOCUS_OVERLAY_CLASS);
  31907. that._isFocusOverlay = that._isFocusOverlay || isFocusOverlay;
  31908. clearTimeout(that._updateFocusTimeoutID);
  31909. that._updateFocusTimeoutID = setTimeout(function() {
  31910. delete that._updateFocusTimeoutID;
  31911. if (!that._isFocusOverlay)
  31912. that._updateFocusCore();
  31913. that._isFocusOverlay = false
  31914. })
  31915. },
  31916. callbackNames: function() {
  31917. return ["focused"]
  31918. },
  31919. focus: function($element) {
  31920. var that = this;
  31921. if ($element === undefined)
  31922. return that._$focusedElement;
  31923. else if ($element)
  31924. setTimeout(function() {
  31925. var $focusOverlay = that._$focusOverlay = that._$focusOverlay || $('<div>').addClass(DATAGRID_FOCUS_OVERLAY_CLASS);
  31926. var align = !parseInt($element.css('border-left-width')) && parseInt($element.css('border-right-width')) ? "right bottom" : "left top";
  31927. $focusOverlay.show();
  31928. $focusOverlay.css('visibility', 'hidden');
  31929. $focusOverlay.appendTo($element.closest('.' + DATAGRID_CONTENT_CLASS));
  31930. $focusOverlay.outerWidth($element.outerWidth() + 1);
  31931. $focusOverlay.outerHeight($element.outerHeight() + 1);
  31932. DX.position($focusOverlay, {
  31933. my: align,
  31934. at: align,
  31935. of: $element
  31936. });
  31937. $focusOverlay.css('visibility', 'visible');
  31938. that._$focusedElement && that._$focusedElement.removeClass(DATAGRID_FOCUSED_ELEMENT_CLASS);
  31939. $element.addClass(DATAGRID_FOCUSED_ELEMENT_CLASS);
  31940. that._$focusedElement = $element;
  31941. that.focused.fire($element)
  31942. })
  31943. },
  31944. loseFocus: function() {
  31945. this._$focusedElement && this._$focusedElement.removeClass(DATAGRID_FOCUSED_ELEMENT_CLASS);
  31946. this._$focusedElement = null;
  31947. this._$focusOverlay && this._$focusOverlay.hide()
  31948. },
  31949. init: function() {
  31950. var that = this,
  31951. $container = that.component && that.component._element();
  31952. $(document).on(DATAGRID_UPDATE_FOCUS_EVENTS, this.createAction($.proxy(this._updateFocus, this)));
  31953. $container && $container.on('dxclick', '.' + DATAGRID_FOCUS_OVERLAY_CLASS, function(e) {
  31954. var $focusOverlay = $(e.target),
  31955. element;
  31956. $focusOverlay.hide();
  31957. element = document.elementFromPoint(e.pageX, e.pageY);
  31958. $focusOverlay.show();
  31959. $(element).trigger('dxclick');
  31960. that._$focusedElement && that._$focusedElement.find('input').focus()
  31961. })
  31962. },
  31963. dispose: function() {
  31964. $(document).off(DATAGRID_UPDATE_FOCUS_EVENTS)
  31965. },
  31966. createEditor: function($container, options) {
  31967. var editorPreparing = this.option('editorPreparing'),
  31968. editorPrepared = this.option('editorPrepared');
  31969. options.rtlEnabled = this.option('rtlEnabled');
  31970. options.disabled = this.option("disabled");
  31971. options.cancel = false;
  31972. editorPreparing && editorPreparing($container, options);
  31973. if (options.cancel)
  31974. return;
  31975. if (options.lookup)
  31976. createSelectBox($container, options);
  31977. else
  31978. switch (options.dataType) {
  31979. case'date':
  31980. createCalendarPicker($container, options);
  31981. break;
  31982. case'boolean':
  31983. createBooleanEditor($container, options);
  31984. break;
  31985. default:
  31986. createTextBox($container, options);
  31987. break
  31988. }
  31989. editorPrepared && editorPrepared($container, options)
  31990. }
  31991. }
  31992. }());
  31993. $.extend(dataGrid.__internals, {DATAGRID_FOCUSED_ELEMENT_CLASS: DATAGRID_FOCUSED_ELEMENT_CLASS});
  31994. dataGrid.registerModule('editorFactory', {
  31995. defaultOptions: function() {
  31996. return {}
  31997. },
  31998. controllers: {editorFactory: dataGrid.EditorFactoryController}
  31999. })
  32000. })(jQuery, DevExpress);
  32001. /*! Module widgets-web, file ui.dataGrid.columnChooserModule.js */
  32002. (function($, DX) {
  32003. var ui = DX.ui,
  32004. utils = DX.utils,
  32005. dataGrid = ui.dataGrid;
  32006. var DATAGRID_COLUMN_CHOOSER_CLASS = 'dx-datagrid-column-chooser',
  32007. DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS = 'dx-datagrid-column-chooser-button',
  32008. DATAGRID_COLUMN_CHOOSER_ICON_NAME = 'column-chooser',
  32009. DATAGRID_COLUMN_CHOOSER_ITEM_CLASS = "dx-column-chooser-item",
  32010. DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS = "dx-column-chooser-message",
  32011. DATAGRID_HEADERS_ACTION_CLASS = "dx-datagrid-action-cursor";
  32012. dataGrid.ColumnChooserView = dataGrid.View.inherit({
  32013. _updateItems: function() {
  32014. var hiddenColumns = this._columnsController.getHiddenColumns(),
  32015. columnChooserOptions = this.option("columnChooser"),
  32016. $content = this._popupContainer.content();
  32017. $content.dxScrollable(dataGrid.createScrollableOptions(this));
  32018. this._renderColumnChooserItems($content, hiddenColumns);
  32019. if (!hiddenColumns.length)
  32020. $('<span />').addClass(DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS).text(columnChooserOptions ? columnChooserOptions.emptyPanelText : "").appendTo($content.dxScrollable("instance").content())
  32021. },
  32022. _initializePopupContainer: function() {
  32023. var that = this,
  32024. $element = this._element().addClass(DATAGRID_COLUMN_CHOOSER_CLASS),
  32025. columnChooserOptions = this.option("columnChooser"),
  32026. theme = DevExpress.ui.themes.current(),
  32027. isGenericTheme = theme && theme.indexOf("generic") > -1;
  32028. if (!utils.isDefined(this._popupContainer)) {
  32029. this._popupContainer = $element.dxPopup({
  32030. visible: false,
  32031. shading: false,
  32032. closeButton: isGenericTheme,
  32033. cancelButton: !isGenericTheme,
  32034. width: columnChooserOptions.width,
  32035. height: columnChooserOptions.height,
  32036. title: columnChooserOptions.title,
  32037. targetContainer: this._element().parent(),
  32038. rtlEnabled: this.option('rtlEnabled')
  32039. }).data('dxPopup');
  32040. this._popupContainer.optionChanged.add(function(optionName) {
  32041. if (optionName === "visible")
  32042. that.renderCompleted.fire()
  32043. })
  32044. }
  32045. },
  32046. _renderCore: function() {
  32047. if (this.option("columnChooser.enabled"))
  32048. this._initializePopupContainer();
  32049. if (this._popupContainer)
  32050. this._updateItems()
  32051. },
  32052. _renderColumnChooserItems: function($container, hiddenColumns) {
  32053. var dxScrollable = $container.dxScrollable("instance"),
  32054. $scrollableContainer = dxScrollable.content(),
  32055. $item;
  32056. $scrollableContainer.empty();
  32057. $.each(hiddenColumns, function(index, hiddenColumn) {
  32058. $item = $('<div />').addClass(hiddenColumn.cssClass).addClass(DATAGRID_COLUMN_CHOOSER_ITEM_CLASS).toggleClass(DATAGRID_HEADERS_ACTION_CLASS, hiddenColumn.allowHiding).text(hiddenColumn.caption).appendTo($scrollableContainer)
  32059. });
  32060. dxScrollable.update()
  32061. },
  32062. init: function() {
  32063. var that = this;
  32064. that._columnsController = that.getController('columns');
  32065. that._columnsController.columnsChanged.add(function(e) {
  32066. if (!dataGrid.checkChanges(e.optionNames, ['width']))
  32067. that.render()
  32068. })
  32069. },
  32070. renderShowColumnChooserButton: function(rootElement) {
  32071. var that = this,
  32072. columnChooserOptions = that.option("columnChooser") || {},
  32073. $showColumnChooserButton = rootElement.find("." + DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS);
  32074. if (columnChooserOptions.enabled)
  32075. if (!$showColumnChooserButton.length)
  32076. $('<div />').addClass(DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS).appendTo(rootElement).dxButton({
  32077. icon: DATAGRID_COLUMN_CHOOSER_ICON_NAME,
  32078. clickAction: function(e) {
  32079. that._popupContainer.toggle(!that._popupContainer.option('visible'))
  32080. }
  32081. });
  32082. else
  32083. $showColumnChooserButton.show();
  32084. else
  32085. $showColumnChooserButton.hide()
  32086. },
  32087. getColumnElements: function() {
  32088. var $content = this._popupContainer && this._popupContainer.content();
  32089. return $content && $content.find('.' + DATAGRID_COLUMN_CHOOSER_ITEM_CLASS)
  32090. },
  32091. getName: function() {
  32092. return 'columnChooser'
  32093. },
  32094. getColumns: function() {
  32095. return this._columnsController.getHiddenColumns()
  32096. },
  32097. allowDragging: function(column) {
  32098. var popupContainer = this._popupContainer;
  32099. return popupContainer && popupContainer.option("visible") && column && column.allowHiding
  32100. },
  32101. getBoundingRect: function() {
  32102. var that = this,
  32103. container = that._popupContainer && that._popupContainer._container(),
  32104. offset;
  32105. if (container && container.is(':visible')) {
  32106. offset = container.offset();
  32107. return {
  32108. left: offset.left,
  32109. top: offset.top,
  32110. right: offset.left + container.outerWidth(),
  32111. bottom: offset.top + container.outerHeight()
  32112. }
  32113. }
  32114. return null
  32115. },
  32116. showColumnChooser: function() {
  32117. this._isPopupContainerShown = true;
  32118. if (!this._popupContainer) {
  32119. this._initializePopupContainer();
  32120. this.render()
  32121. }
  32122. this._popupContainer.show()
  32123. },
  32124. hideColumnChooser: function() {
  32125. if (this._popupContainer) {
  32126. this._popupContainer.hide();
  32127. this._isPopupContainerShown = false
  32128. }
  32129. },
  32130. publicMethods: function() {
  32131. return ['showColumnChooser', 'hideColumnChooser']
  32132. }
  32133. });
  32134. $.extend(dataGrid.__internals, {
  32135. DATAGRID_COLUMN_CHOOSER_CLASS: DATAGRID_COLUMN_CHOOSER_CLASS,
  32136. DATAGRID_COLUMN_CHOOSER_ITEM_CLASS: DATAGRID_COLUMN_CHOOSER_ITEM_CLASS,
  32137. DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS: DATAGRID_COLUMN_CHOOSER_BUTTON_CLASS,
  32138. DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS: DATAGRID_COLUMN_CHOOSER_MESSAGE_CLASS
  32139. });
  32140. dataGrid.registerModule('columnChooser', {
  32141. defaultOptions: function() {
  32142. return {columnChooser: {
  32143. enabled: false,
  32144. width: 250,
  32145. height: 260,
  32146. title: Globalize.localize("dxDataGrid-columnChooserTitle"),
  32147. emptyPanelText: Globalize.localize("dxDataGrid-columnChooserEmptyText")
  32148. }}
  32149. },
  32150. views: {columnChooserView: dataGrid.ColumnChooserView},
  32151. extenders: {views: {headerPanel: {
  32152. _renderShowColumnChooserButton: function() {
  32153. this.getView('columnChooserView').renderShowColumnChooserButton(this._element())
  32154. },
  32155. _renderCore: function() {
  32156. this.callBase();
  32157. this._renderShowColumnChooserButton()
  32158. },
  32159. optionChanged: function(name, value, prevValue) {
  32160. this.callBase(name, value, prevValue);
  32161. switch (name) {
  32162. case'columnChooser':
  32163. this._renderShowColumnChooserButton();
  32164. break
  32165. }
  32166. },
  32167. isVisible: function() {
  32168. var that = this,
  32169. columnChooserOptions = that.getView('columnChooserView').option('columnChooser');
  32170. return that.callBase() || columnChooserOptions && columnChooserOptions.enabled
  32171. }
  32172. }}}
  32173. })
  32174. })(jQuery, DevExpress);
  32175. /*! Module widgets-web, file ui.dataGrid.editing.js */
  32176. (function($, DX) {
  32177. var dataGrid = DX.ui.dataGrid,
  32178. events = DX.ui.events,
  32179. addNamespace = events.addNamespace,
  32180. utils = DX.utils;
  32181. var DATAGRID_LINK_CLASS = "dx-link",
  32182. DATAGRID_EDITOR_CELL_CLASS = "dx-editor-cell",
  32183. DATAGRID_ROW_SELECTED = "dx-selection",
  32184. DATAGRID_EDIT_ROW = "dx-edit-row",
  32185. DATAGRID_EDIT_BUTTON_CLASS = "dx-edit-button",
  32186. DATAGRID_INSERT_INDEX = "__DX_INSERT_INDEX__",
  32187. DATAGRID_ROW_REMOVED = "dx-row-removed",
  32188. DATAGRID_ROW_INSERTED = "dx-row-inserted",
  32189. DATAGRID_ROW_MODIFIED = "dx-row-modified",
  32190. DATAGRID_CELL_MODIFIED = "dx-cell-modified",
  32191. DATAGRID_CELL_HIGHLIGHT_OUTLINE = "dx-highlight-outline",
  32192. DATAGRID_EDITING_NAMESPACE = "dxDataGridEditing",
  32193. DATAGRID_FOCUS_OVERLAY_CLASS = "dx-datagrid-focus-overlay",
  32194. DATAGRID_EDIT_MODE_BATCH = "batch",
  32195. DATAGRID_EDIT_MODE_ROW = "row";
  32196. $.extend(dataGrid.__internals, {
  32197. DATAGRID_LINK_CLASS: DATAGRID_LINK_CLASS,
  32198. DATAGRID_EDITOR_CELL_CLASS: DATAGRID_EDITOR_CELL_CLASS,
  32199. DATAGRID_EDIT_ROW: DATAGRID_EDIT_ROW,
  32200. DATAGRID_EDIT_BUTTON_CLASS: DATAGRID_EDIT_BUTTON_CLASS
  32201. });
  32202. var getEditMode = function(that) {
  32203. var editing = that.option('editing.editMode');
  32204. if (editing === DATAGRID_EDIT_MODE_BATCH)
  32205. return editing;
  32206. return DATAGRID_EDIT_MODE_ROW
  32207. };
  32208. var getEditIndex = function(key, editDataArray) {
  32209. var index = -1;
  32210. $.each(editDataArray, function(i, editData) {
  32211. if (key && key[DATAGRID_INSERT_INDEX] && key === editData.key || dataGrid.equalKeys(key, editData.key)) {
  32212. index = i;
  32213. return false
  32214. }
  32215. });
  32216. return index
  32217. };
  32218. dataGrid.EditingController = dataGrid.ViewController.inherit(function() {
  32219. var getDataController = function(that) {
  32220. return that.getController('data')
  32221. };
  32222. var getDefaultEditor = function(that) {
  32223. return function(container, options) {
  32224. var $editor = $('<div/>').appendTo(container);
  32225. that.getController('editorFactory').createEditor($editor, $.extend({}, options.column, {
  32226. value: options.value,
  32227. setValue: options.setValue,
  32228. parentType: 'dataRow',
  32229. width: null
  32230. }))
  32231. }
  32232. };
  32233. return {
  32234. init: function() {
  32235. var that = this;
  32236. that._insertIndex = 1;
  32237. that._editRowIndex = -1;
  32238. that._editData = [];
  32239. that._editColumnIndex = -1;
  32240. that._columnsController = that.getController("columns");
  32241. if (!that._saveEditorHandler) {
  32242. that._saveEditorHandler = that.createAction(function(e) {
  32243. var event = e.jQueryEvent,
  32244. visibleColumns,
  32245. isEditorPopup,
  32246. isFocusOverlay,
  32247. $targetCell,
  32248. allowEditing,
  32249. isDataRow;
  32250. if (getEditMode(that) === DATAGRID_EDIT_MODE_BATCH && that.isEditing() && !that._editCellInProgress) {
  32251. isEditorPopup = $(event.target).closest('.dx-overlay-wrapper').length;
  32252. isFocusOverlay = $(event.target).hasClass(DATAGRID_FOCUS_OVERLAY_CLASS);
  32253. isDataRow = $(event.target).closest('.dx-data-row').length;
  32254. visibleColumns = that._columnsController.getVisibleColumns();
  32255. $targetCell = $(event.target).closest('td');
  32256. allowEditing = $targetCell.length && visibleColumns[$targetCell[0].cellIndex].allowEditing;
  32257. if ((!isDataRow || isDataRow && !allowEditing) && !isEditorPopup && !isFocusOverlay)
  32258. that.closeEditCell()
  32259. }
  32260. });
  32261. $(document).on('dxclick', that._saveEditorHandler)
  32262. }
  32263. that._updateEditButtons()
  32264. },
  32265. getEditMode: function() {
  32266. return getEditMode(this)
  32267. },
  32268. hasChanges: function() {
  32269. return this._editData.length
  32270. },
  32271. dispose: function() {
  32272. this.callBase();
  32273. $(document).off('dxclick', this._saveEditorHandler)
  32274. },
  32275. optionChanged: function(name, value, prevValue){},
  32276. publicMethods: function() {
  32277. return ['insertRow', 'editRow', 'editCell', 'closeEditCell', 'removeRow', 'saveEditData', 'recoverRow', 'undeleteRow', 'cancelEditData']
  32278. },
  32279. refresh: function() {
  32280. if (getEditMode(this) === DATAGRID_EDIT_MODE_BATCH) {
  32281. this._editRowIndex = -1;
  32282. this._editColumnIndex = -1
  32283. }
  32284. else
  32285. this.init()
  32286. },
  32287. isEditing: function() {
  32288. return this._editRowIndex > -1
  32289. },
  32290. isEditRow: function(rowIndex) {
  32291. return this._editRowIndex === rowIndex && this._editColumnIndex === -1
  32292. },
  32293. isEditCell: function(rowIndex, columnIndex) {
  32294. return this._editRowIndex === rowIndex && this._editColumnIndex === columnIndex
  32295. },
  32296. processItems: function(items) {
  32297. var that = this,
  32298. editData = that._editData,
  32299. i,
  32300. key;
  32301. that.update();
  32302. for (i = 0; i < editData.length; i++) {
  32303. key = editData[i].key;
  32304. if (key && key[DATAGRID_INSERT_INDEX] && key.pageIndex === that._pageIndex)
  32305. items.splice(key.rowIndex, 0, key)
  32306. }
  32307. return items
  32308. },
  32309. processDataItem: function(item, columns, generateDataValues) {
  32310. var that = this,
  32311. editIndex,
  32312. data,
  32313. key = item.data[DATAGRID_INSERT_INDEX] ? item.data : item.key;
  32314. editIndex = getEditIndex(key, that._editData);
  32315. if (editIndex >= 0) {
  32316. data = that._editData[editIndex].data;
  32317. if (key && key[DATAGRID_INSERT_INDEX]) {
  32318. item.inserted = true;
  32319. item.key = key;
  32320. item.data = data
  32321. }
  32322. else if (data) {
  32323. item.modified = true;
  32324. item.data = $.extend(true, {}, item.data, data);
  32325. item.modifiedValues = generateDataValues(data, columns)
  32326. }
  32327. else
  32328. item.removed = true
  32329. }
  32330. },
  32331. insertRow: function() {
  32332. var that = this,
  32333. dataController = getDataController(that),
  32334. rowsView = that.getView('rowsView'),
  32335. initNewRow = that.option("initNewRow"),
  32336. param = {data: {}},
  32337. insertKey = {
  32338. pageIndex: dataController.pageIndex(),
  32339. rowIndex: rowsView ? rowsView.getTopVisibleItemIndex() : 0
  32340. };
  32341. that.refresh();
  32342. if (getEditMode(that) === DATAGRID_EDIT_MODE_ROW)
  32343. that._editRowIndex = insertKey.rowIndex;
  32344. initNewRow && initNewRow(param);
  32345. insertKey[DATAGRID_INSERT_INDEX] = that._insertIndex++;
  32346. that._editData.push({
  32347. key: insertKey,
  32348. data: param.data
  32349. });
  32350. dataController.updateItems()
  32351. },
  32352. editRow: function(rowIndex) {
  32353. var that = this,
  32354. dataController = getDataController(that),
  32355. item = dataController.items()[rowIndex],
  32356. editingStart = that.option("editingStart"),
  32357. params = {
  32358. data: item.data,
  32359. key: item.key,
  32360. cancel: false
  32361. };
  32362. if (!item.inserted)
  32363. params.key = item.key;
  32364. editingStart && editingStart(params);
  32365. if (params.cancel)
  32366. return;
  32367. that.init();
  32368. that._editRowIndex = rowIndex;
  32369. that._pageIndex = dataController.pageIndex();
  32370. dataController.updateItems()
  32371. },
  32372. editCell: function (rowIndex, columnIndex) {
  32373. if (rowIndex < 0) return false // hcLee 2015 07 15
  32374. var that = this,
  32375. rowsView = that.getView("rowsView"),
  32376. dataController = getDataController(that),
  32377. item = dataController.items()[rowIndex],
  32378. editingStart = that.option("editingStart"),
  32379. params = {
  32380. data: item.data,
  32381. cancel: false,
  32382. column: that._columnsController.getVisibleColumns()[columnIndex]
  32383. };
  32384. if (item && item.rowType === 'data' && !item.removed && getEditMode(that) === DATAGRID_EDIT_MODE_BATCH) {
  32385. if (!item.inserted)
  32386. params.key = item.key;
  32387. editingStart && editingStart(params);
  32388. if (params.cancel)
  32389. return;
  32390. that._editRowIndex = rowIndex;
  32391. that._editColumnIndex = columnIndex;
  32392. that._pageIndex = dataController.pageIndex();
  32393. that._editCellInProgress = true;
  32394. dataController.updateItems();
  32395. setTimeout(function() {
  32396. that._editCellInProgress = false;
  32397. rowsView._focusEditor()
  32398. });
  32399. return true
  32400. }
  32401. return false
  32402. },
  32403. removeRow: function(rowIndex) {
  32404. var that = this,
  32405. editingOptions = that.option("editing"),
  32406. editingTexts = editingOptions && editingOptions.texts,
  32407. confirmDeleteTitle = editingTexts && editingTexts.confirmDeleteTitle,
  32408. isBatchMode = editingOptions && editingOptions.editMode === DATAGRID_EDIT_MODE_BATCH,
  32409. confirmDeleteMessage = editingTexts && editingTexts.confirmDeleteMessage,
  32410. dataController = getDataController(that),
  32411. removeByKey,
  32412. item = dataController.items()[rowIndex],
  32413. key = item && item.key;
  32414. if (item) {
  32415. removeByKey = function(key) {
  32416. that.refresh();
  32417. var editIndex = getEditIndex(key, that._editData);
  32418. if (editIndex >= 0)
  32419. if (key && key[DATAGRID_INSERT_INDEX])
  32420. that._editData.splice(editIndex, 1);
  32421. else
  32422. that._editData[editIndex].data = null;
  32423. else
  32424. that._editData.push({
  32425. key: key,
  32426. oldData: item.data
  32427. });
  32428. if (isBatchMode)
  32429. dataController.updateItems();
  32430. else
  32431. that.saveEditData()
  32432. };
  32433. if (isBatchMode || !confirmDeleteMessage)
  32434. removeByKey(key);
  32435. else
  32436. DX.ui.dialog.confirm(confirmDeleteMessage, confirmDeleteTitle).done(function(confirmResult) {
  32437. if (confirmResult)
  32438. removeByKey(key)
  32439. })
  32440. }
  32441. },
  32442. recoverRow: function(rowIndex) {
  32443. DX.utils.logger.warn("'recoverRow' method is deprecated since 14.1. Use the 'undeleteRow' method instead.");
  32444. return this.undeleteRow(rowIndex)
  32445. },
  32446. undeleteRow: function(rowIndex) {
  32447. var that = this,
  32448. dataController = getDataController(that),
  32449. item = dataController.items()[rowIndex],
  32450. key = item && item.key;
  32451. if (item) {
  32452. var editIndex = getEditIndex(key, that._editData);
  32453. if (editIndex >= 0) {
  32454. that._editData.splice(editIndex, 1);
  32455. dataController.updateItems()
  32456. }
  32457. }
  32458. },
  32459. saveEditData: function() {
  32460. var that = this;
  32461. that._editRowIndex = -1;
  32462. that._editColumnIndex = -1;
  32463. that._saveEditData()
  32464. },
  32465. _saveEditData: function() {
  32466. var that = this,
  32467. dataController = getDataController(that),
  32468. store = dataController.store(),
  32469. item,
  32470. key,
  32471. rowInserting = that.option("rowInserting"),
  32472. rowInserted = that.option("rowInserted"),
  32473. rowUpdating = that.option("rowUpdating"),
  32474. rowUpdated = that.option("rowUpdated"),
  32475. rowRemoving = that.option("rowRemoving"),
  32476. rowRemoved = that.option("rowRemoved"),
  32477. processedKeys = [],
  32478. deferreds = [],
  32479. editData = $.extend({}, that._editData);
  32480. var removeEditData = function(that, keys) {
  32481. $.each(keys, function(index, key) {
  32482. var editIndex = getEditIndex(key, that._editData);
  32483. if (editIndex >= 0)
  32484. that._editData.splice(editIndex, 1)
  32485. })
  32486. };
  32487. if (that._editData.length) {
  32488. $.each(that._editData, function(_, editData) {
  32489. var data = editData.data,
  32490. oldData = editData.oldData,
  32491. key = editData.key,
  32492. deferred,
  32493. params;
  32494. if (!data) {
  32495. params = {
  32496. data: oldData,
  32497. key: key,
  32498. cancel: false
  32499. };
  32500. rowRemoving && rowRemoving(params);
  32501. if (params.cancel)
  32502. return;
  32503. deferred = store.remove(key)
  32504. }
  32505. else if (key && key[DATAGRID_INSERT_INDEX]) {
  32506. params = {
  32507. data: data,
  32508. cancel: false
  32509. };
  32510. rowInserting && rowInserting(params);
  32511. if (params.cancel)
  32512. return;
  32513. deferred = store.insert(data)
  32514. }
  32515. else {
  32516. params = {
  32517. newData: $.extend({}, oldData, data),
  32518. oldData: oldData,
  32519. key: key,
  32520. cancel: false
  32521. };
  32522. rowUpdating && rowUpdating(params);
  32523. if (params.cancel)
  32524. return;
  32525. deferred = store.update(key, data)
  32526. }
  32527. deferred.done($.proxy(processedKeys.push, processedKeys, key));
  32528. deferreds.push(deferred)
  32529. });
  32530. if (deferreds.length)
  32531. $.when.apply($, deferreds).always(function(e) {
  32532. var isError = e && e.name === "Error";
  32533. if (!isError)
  32534. removeEditData(that, processedKeys);
  32535. $.when(dataController.refresh()).always(function() {
  32536. $.each(editData, function(_, itemData) {
  32537. var data = itemData.data,
  32538. key = itemData.key,
  32539. params = {
  32540. key: key,
  32541. data: data
  32542. };
  32543. if (isError)
  32544. params.error = e;
  32545. if (!data)
  32546. rowRemoved && rowRemoved($.extend({}, params, {data: itemData.oldData}));
  32547. else if (key && key[DATAGRID_INSERT_INDEX])
  32548. rowInserted && rowInserted(params);
  32549. else
  32550. rowUpdated && rowUpdated(params)
  32551. })
  32552. });
  32553. if (isError)
  32554. dataController.dataErrorOccurred.fire(e)
  32555. })
  32556. }
  32557. else
  32558. dataController.updateItems()
  32559. },
  32560. _updateEditButtons: function() {
  32561. var that = this,
  32562. saveChangesButton = that._saveChangesButton,
  32563. cancelChangesButton = that._cancelChangesButton,
  32564. hasChanges = that.hasChanges();
  32565. if (saveChangesButton)
  32566. saveChangesButton.option('disabled', !hasChanges);
  32567. if (cancelChangesButton)
  32568. cancelChangesButton.option('disabled', !hasChanges)
  32569. },
  32570. cancelEditData: function() {
  32571. var that = this,
  32572. dataController = getDataController(that);
  32573. that.init();
  32574. dataController.updateItems()
  32575. },
  32576. closeEditCell: function() {
  32577. var that = this,
  32578. dataController = getDataController(that);
  32579. setTimeout(function() {
  32580. that._editRowIndex = -1;
  32581. that._editColumnIndex = -1;
  32582. dataController.updateItems()
  32583. })
  32584. },
  32585. update: function() {
  32586. var that = this,
  32587. dataController = getDataController(that);
  32588. if (that._pageIndex !== dataController.pageIndex()) {
  32589. that.refresh();
  32590. that._pageIndex = dataController.pageIndex()
  32591. }
  32592. that._updateEditButtons()
  32593. },
  32594. updateFieldValue: function(options) {
  32595. var that = this,
  32596. rowKey = options.key,
  32597. dataField = options.column.dataField,
  32598. value = options.column.serializeValue ? options.column.serializeValue(options.value) : options.value,
  32599. editDataIndex;
  32600. if (rowKey !== undefined) {
  32601. editDataIndex = getEditIndex(rowKey, that._editData);
  32602. if (editDataIndex < 0) {
  32603. editDataIndex = that._editData.length;
  32604. that._editData.push({
  32605. data: {},
  32606. key: rowKey,
  32607. oldData: options.data
  32608. })
  32609. }
  32610. if (that._editData[editDataIndex])
  32611. that._editData[editDataIndex].data[dataField] = value;
  32612. that._updateEditButtons()
  32613. }
  32614. },
  32615. getColumnTemplate: function(options) {
  32616. var that = this,
  32617. column = options.column,
  32618. template,
  32619. isRowMode,
  32620. editingOptions,
  32621. editingTexts;
  32622. if (column.allowEditing && column.dataField && !column.command && that._editRowIndex === options.rowIndex && (that._editColumnIndex < 0 || that._editColumnIndex === options.columnIndex) && options.rowType === 'data') {
  32623. options.setValue = function(value) {
  32624. options.value = value;
  32625. that.updateFieldValue(options)
  32626. };
  32627. template = column.editCellTemplate || getDefaultEditor(that)
  32628. }
  32629. else if (column.command === 'edit')
  32630. template = function(container, options) {
  32631. var createLink = function(container, text, methodName, options) {
  32632. var $link = $('<a />').addClass(DATAGRID_LINK_CLASS).text(text).on(addNamespace('dxclick', DATAGRID_EDITING_NAMESPACE), that.createAction(function() {
  32633. setTimeout(function() {
  32634. that[methodName](options.rowIndex)
  32635. })
  32636. }));
  32637. options.rtlEnabled ? container.prepend($link, "&nbsp;") : container.append($link, "&nbsp;")
  32638. };
  32639. isRowMode = getEditMode(that) === DATAGRID_EDIT_MODE_ROW;
  32640. container.css('text-align', 'center');
  32641. options.rtlEnabled = that.option('rtlEnabled');
  32642. editingOptions = that.option("editing") || {};
  32643. editingTexts = editingOptions.texts || {};
  32644. if (that._editRowIndex === options.rowIndex && isRowMode) {
  32645. createLink(container, editingTexts.saveRowChanges, 'saveEditData', options);
  32646. createLink(container, editingTexts.cancelRowChanges, 'cancelEditData', options)
  32647. }
  32648. else {
  32649. if (editingOptions.editEnabled && isRowMode)
  32650. createLink(container, editingTexts.editRow, 'editRow', options);
  32651. if (editingOptions.removeEnabled)
  32652. if (options.row.removed)
  32653. createLink(container, editingTexts.undeleteRow, 'undeleteRow', options);
  32654. else
  32655. createLink(container, editingTexts.deleteRow, 'removeRow', options)
  32656. }
  32657. };
  32658. return template
  32659. },
  32660. renderEditButtons: function(rootElement) {
  32661. var that = this,
  32662. insertButton = rootElement.find('.' + DATAGRID_EDIT_BUTTON_CLASS),
  32663. editingOptions = that.option("editing") || {};
  32664. var createEditButton = function(rootElement, className, methodName) {
  32665. return $('<div />').addClass(DATAGRID_EDIT_BUTTON_CLASS).addClass("dx-datagrid-" + className + "-button").appendTo(rootElement).dxButton({
  32666. icon: "edit-button-" + className,
  32667. clickAction: $.proxy(that, methodName)
  32668. }).dxButton('instance')
  32669. };
  32670. if (insertButton.length)
  32671. insertButton.remove();
  32672. if ((editingOptions.editEnabled || editingOptions.insertEnabled || editingOptions.removeEnabled) && getEditMode(that) === DATAGRID_EDIT_MODE_BATCH) {
  32673. that._cancelChangesButton = createEditButton(rootElement, "cancel", 'cancelEditData');
  32674. that._saveChangesButton = createEditButton(rootElement, "save", 'saveEditData');
  32675. that._updateEditButtons()
  32676. }
  32677. if (editingOptions.insertEnabled)
  32678. createEditButton(rootElement, "addrow", 'insertRow')
  32679. }
  32680. }
  32681. }());
  32682. dataGrid.registerModule('editing', {
  32683. defaultOptions: function() {
  32684. return {editing: {
  32685. editMode: 'row',
  32686. insertEnabled: false,
  32687. editEnabled: false,
  32688. removeEnabled: false,
  32689. texts: {
  32690. editRow: Globalize.localize("dxDataGrid-editingEditRow"),
  32691. saveRowChanges: Globalize.localize("dxDataGrid-editingSaveRowChanges"),
  32692. cancelRowChanges: Globalize.localize("dxDataGrid-editingCancelRowChanges"),
  32693. deleteRow: Globalize.localize("dxDataGrid-editingDeleteRow"),
  32694. recoverRow: Globalize.localize("dxDataGrid-editingUndeleteRow"),
  32695. undeleteRow: Globalize.localize("dxDataGrid-editingUndeleteRow"),
  32696. confirmDeleteMessage: Globalize.localize("dxDataGrid-editingConfirmDeleteMessage"),
  32697. confirmDeleteTitle: Globalize.localize("dxDataGrid-editingConfirmDeleteTitle")
  32698. }
  32699. }}
  32700. },
  32701. controllers: {editing: dataGrid.EditingController},
  32702. extenders: {
  32703. controllers: {
  32704. data: {
  32705. init: function() {
  32706. this._editingController = this.getController('editing');
  32707. this.callBase()
  32708. },
  32709. reload: function() {
  32710. this._editingController.refresh();
  32711. return this.callBase()
  32712. },
  32713. _processItems: function(items) {
  32714. items = this._editingController.processItems(items);
  32715. return this.callBase(items)
  32716. },
  32717. _processDataItem: function(dataItem, columns) {
  32718. this._editingController.processDataItem(dataItem, columns, this._generateDataValues);
  32719. return this.callBase(dataItem, columns)
  32720. }
  32721. },
  32722. columns: {getVisibleColumns: function() {
  32723. var that = this,
  32724. editing = that.option('editing'),
  32725. columns = that.callBase();
  32726. columns = $.grep(columns, function(column) {
  32727. return column.command !== 'edit'
  32728. });
  32729. if (editing && ((editing.editEnabled || editing.insertEnabled) && getEditMode(that) === DATAGRID_EDIT_MODE_ROW || editing.removeEnabled) && columns.length)
  32730. columns.push({
  32731. visible: true,
  32732. command: 'edit',
  32733. width: 100
  32734. });
  32735. return columns
  32736. }}
  32737. },
  32738. views: {
  32739. rowsView: {
  32740. _getColumnTemplate: function(options) {
  32741. var that = this,
  32742. template = that.getController('editing').getColumnTemplate(options);
  32743. return template || that.callBase(options)
  32744. },
  32745. _createRow: function(options) {
  32746. var $row = this.callBase(options),
  32747. editingController,
  32748. isEditRow,
  32749. isRowRemoved,
  32750. isRowInserted,
  32751. isRowModified;
  32752. if (options) {
  32753. editingController = this.getController('editing');
  32754. isEditRow = editingController.isEditRow(options.rowIndex);
  32755. isRowRemoved = !!options.removed;
  32756. isRowInserted = !!options.inserted;
  32757. isRowModified = !!options.modified;
  32758. if (getEditMode(this) === DATAGRID_EDIT_MODE_BATCH)
  32759. $row.toggleClass(DATAGRID_ROW_REMOVED, isRowRemoved);
  32760. else
  32761. $row.toggleClass(DATAGRID_EDIT_ROW, isEditRow);
  32762. $row.toggleClass(DATAGRID_ROW_INSERTED, isRowInserted);
  32763. $row.toggleClass(DATAGRID_ROW_MODIFIED, isRowModified);
  32764. if (isEditRow || isRowInserted || isRowRemoved || isRowModified)
  32765. $row.removeClass(DATAGRID_ROW_SELECTED)
  32766. }
  32767. return $row
  32768. },
  32769. _rowClick: function(rowIndex, event) {
  32770. var that = this,
  32771. editingController = that.getController('editing'),
  32772. editing = that.option('editing'),
  32773. $targetCell = $(event.target).closest('td'),
  32774. cellIndex = $targetCell.length ? $targetCell[0].cellIndex : -1,
  32775. column = that._columnsController.getVisibleColumns()[cellIndex],
  32776. isEditCell = cellIndex >= 0 && editing && editing.editEnabled && column && column.allowEditing && editingController.editCell(rowIndex, cellIndex);
  32777. if (!isEditCell && !editingController.isEditRow(rowIndex))
  32778. that.callBase(rowIndex, event)
  32779. },
  32780. _cellPrepared: function($cell, parameters) {
  32781. var modifiedValues = parameters.row && (parameters.row.inserted ? parameters.row.values : parameters.row.modifiedValues),
  32782. columnIndex = parameters.columnIndex,
  32783. alignment = parameters.column.alignment,
  32784. editingController = this.getController('editing'),
  32785. $contents;
  32786. parameters.isEditing = editingController.isEditCell(parameters.rowIndex, columnIndex) || editingController.isEditRow(parameters.rowIndex) && parameters.column.allowEditing;
  32787. if (parameters.isEditing) {
  32788. $cell.addClass(DATAGRID_EDITOR_CELL_CLASS);
  32789. if (alignment)
  32790. $cell.find('input').first().css('text-align', alignment)
  32791. }
  32792. if (modifiedValues && parameters.column && parameters.column.allowEditing && modifiedValues[columnIndex] !== undefined)
  32793. if (!parameters.isEditing) {
  32794. $cell.addClass(DATAGRID_CELL_MODIFIED);
  32795. $contents = $cell.contents();
  32796. $("<div>").addClass(DATAGRID_CELL_HIGHLIGHT_OUTLINE).append(!$contents.length || $contents.length === 1 && !$contents.eq(0).text().length ? "&nbsp;" : $contents).appendTo($cell)
  32797. }
  32798. this.callBase.apply(this, arguments)
  32799. },
  32800. _update: function(change) {
  32801. this.callBase(change);
  32802. if (change.changeType === 'updateSelection')
  32803. this._element().find('.' + DATAGRID_EDIT_ROW).removeClass(DATAGRID_ROW_SELECTED)
  32804. },
  32805. _focusEditor: function() {
  32806. this._tableElement.find('input').first().focus()
  32807. }
  32808. },
  32809. headerPanel: {
  32810. _renderCore: function() {
  32811. this.callBase();
  32812. this.getController('editing').renderEditButtons(this._element())
  32813. },
  32814. isVisible: function() {
  32815. var that = this,
  32816. editingOptions = that.getController('editing').option('editing');
  32817. return that.callBase() || editingOptions && (editingOptions.insertEnabled || (editingOptions.editEnabled || editingOptions.removeEnabled) && editingOptions.editMode === DATAGRID_EDIT_MODE_BATCH)
  32818. }
  32819. }
  32820. }
  32821. }
  32822. });
  32823. $.extend(dataGrid.__internals, {
  32824. DATAGRID_CELL_MODIFIED: DATAGRID_CELL_MODIFIED,
  32825. DATAGRID_ROW_REMOVED: DATAGRID_ROW_REMOVED,
  32826. DATAGRID_ROW_INSERTED: DATAGRID_ROW_INSERTED,
  32827. DATAGRID_ROW_MODIFIED: DATAGRID_ROW_MODIFIED,
  32828. DATAGRID_CELL_HIGHLIGHT_OUTLINE: DATAGRID_CELL_HIGHLIGHT_OUTLINE,
  32829. DATAGRID_FOCUS_OVERLAY_CLASS: DATAGRID_FOCUS_OVERLAY_CLASS
  32830. })
  32831. })(jQuery, DevExpress);
  32832. /*! Module widgets-web, file ui.dataGrid.dataController.js */
  32833. (function($, DX) {
  32834. var ui = DX.ui,
  32835. dataGrid = ui.dataGrid,
  32836. utils = DX.utils;
  32837. dataGrid.DataController = dataGrid.Controller.inherit({}).include(ui.DataHelperMixin).inherit(function() {
  32838. var processGroupItems = function(that, items, groupsCount) {
  32839. var scrollingMode = that.option('scrolling.mode'),
  32840. collectedItems = [],
  32841. collectItemsCore = function(items, collectedItems, groupIndex, groupsCount, path, collectContinuationItems) {
  32842. var i,
  32843. isExpanded,
  32844. item;
  32845. if (groupIndex >= groupsCount)
  32846. collectedItems.push.apply(collectedItems, items);
  32847. else
  32848. for (i = 0; i < items.length; i++) {
  32849. item = items[i];
  32850. if (item.items !== undefined) {
  32851. path.push(item.key);
  32852. isExpanded = !!item.items;
  32853. if (collectContinuationItems || !item.isContinuation)
  32854. collectedItems.push({
  32855. rowType: 'group',
  32856. groupIndex: groupIndex,
  32857. data: item,
  32858. isExpanded: isExpanded,
  32859. values: path.slice(0)
  32860. });
  32861. if (isExpanded)
  32862. collectItemsCore(item.items, collectedItems, groupIndex + 1, groupsCount, path, collectContinuationItems);
  32863. path.pop()
  32864. }
  32865. else
  32866. collectedItems.push(item)
  32867. }
  32868. };
  32869. collectItemsCore(items, collectedItems, 0, groupsCount, [], scrollingMode !== 'virtual' && scrollingMode !== 'infinite');
  32870. return collectedItems
  32871. };
  32872. return {
  32873. init: function() {
  32874. var that = this;
  32875. that._items = [];
  32876. that._columnsController = that.getController('columns');
  32877. that._columnsChangedHandler = function(e) {
  32878. var changeTypes = e.changeTypes,
  32879. optionNames = e.optionNames;
  32880. var updateItemsHandler = function() {
  32881. that._columnsController.columnsChanged.remove(updateItemsHandler);
  32882. that.updateItems()
  32883. };
  32884. if (changeTypes.sorting || changeTypes.grouping) {
  32885. if (that._dataSource) {
  32886. that._dataSource.group(that._columnsController.getGroupDataSourceParameters());
  32887. that._dataSource.sort(that._columnsController.getSortDataSourceParameters());
  32888. that.reload()
  32889. }
  32890. }
  32891. else if (changeTypes.columns) {
  32892. if (optionNames.filterValue || optionNames.selectedFilterOperation)
  32893. if (!e.column || utils.isDefined(e.column.filterValue) || !optionNames.selectedFilterOperation || optionNames.filterValue)
  32894. that._applyFilter();
  32895. if (!that._needApplyFilter && !dataGrid.checkChanges(optionNames, ['width', 'filterValue', 'selectedFilterOperation']))
  32896. that._columnsController.columnsChanged.add(updateItemsHandler)
  32897. }
  32898. };
  32899. that._gridDataSourceChangedHandler = function(e) {
  32900. var dataSource = that._dataSource;
  32901. if (dataSource && !that._isDataSourceApplying) {
  32902. that._isDataSourceApplying = true;
  32903. $.when(that._columnsController.applyDataSource(dataSource)).done(function() {
  32904. that._isDataSourceApplying = false;
  32905. var additionalFilter = that._calculateAdditionalFilter(),
  32906. needApplyFilter = that._needApplyFilter;
  32907. that._needApplyFilter = false;
  32908. if (needApplyFilter && additionalFilter && additionalFilter.length)
  32909. that._applyFilter();
  32910. else
  32911. that.updateItems(e)
  32912. });
  32913. that._needApplyFilter = !that._columnsController.isDataSourceApplied()
  32914. }
  32915. };
  32916. that._columnsController.columnsChanged.add(that._columnsChangedHandler);
  32917. that._loadingChangedHandler = function(isLoading) {
  32918. that._isLoading = isLoading;
  32919. that._fireLoadingChanged()
  32920. };
  32921. that._loadErrorHandler = function(e) {
  32922. that.dataErrorOccurred.fire(e)
  32923. };
  32924. that._viewportSize = 20;
  32925. that._isLoading = false;
  32926. that._isCustomLoading = false;
  32927. that._refreshDataSource();
  32928. that.createAction('dataErrorOccurred', {excludeValidators: ['gesture']});
  32929. that.dataErrorOccurred.add(function(e) {
  32930. return that.executeAction('dataErrorOccurred', e)
  32931. })
  32932. },
  32933. callbackNames: function() {
  32934. return ['changed', 'loadingChanged', 'dataErrorOccurred']
  32935. },
  32936. callbackFlags: function(name) {
  32937. if (name === 'dataErrorOccurred')
  32938. return 'stopOnFalse'
  32939. },
  32940. publicMethods: function() {
  32941. return ['beginCustomLoading', 'endCustomLoading', 'refresh', 'filter', 'clearFilter', 'keyOf', 'byKey', 'getDataByKeys', 'collapseAll', 'expandAll', 'pageIndex', 'pageSize', 'pageCount', 'totalCount', '_disposeDataSource']
  32942. },
  32943. optionChanged: function(name, value, prevValue) {
  32944. var that = this;
  32945. switch (name) {
  32946. case'dataSource':
  32947. case'grouping':
  32948. case'scrolling':
  32949. case'rtlEnabled':
  32950. case'paging':
  32951. case'columns':
  32952. that._columnsController.reset();
  32953. that._refreshDataSource();
  32954. break;
  32955. case'dataErrorOccurred':
  32956. that.createAction('dataErrorOccurred');
  32957. break
  32958. }
  32959. },
  32960. _dataSourceType: function() {
  32961. var scrolling = this.option('scrolling');
  32962. if (scrolling && (scrolling.mode === 'virtual' || scrolling.mode === 'infinite'))
  32963. return dataGrid.ScrollingDataSourceWrapper;
  32964. else
  32965. return dataGrid.DataSource
  32966. },
  32967. _dataSourceOptions: function() {
  32968. var that = this,
  32969. paging = that.option('paging'),
  32970. scrolling = that.option('scrolling'),
  32971. virtualMode = !!(scrolling && scrolling.mode === 'virtual'),
  32972. appendMode = !!(scrolling && scrolling.mode === 'infinite');
  32973. return {
  32974. paginate: paging && paging.enabled || virtualMode || appendMode,
  32975. loadingTimeout: that.option('loadingTimeout'),
  32976. asyncLoadEnabled: true,
  32977. pageIndex: paging && paging.pageIndex,
  32978. pageSize: paging && paging.pageSize,
  32979. requireTotalCount: !appendMode,
  32980. useNativeGrouping: 'auto',
  32981. scrolling: scrolling
  32982. }
  32983. },
  32984. _initDataSource: function() {
  32985. var columnsController = this._columnsController,
  32986. sort,
  32987. group,
  32988. dataSource;
  32989. if (this.option("dataSource") instanceof DX.data.DataSource) {
  32990. DX.utils.logger.error("The dataSource option cannot take the DevExpress.data.DataSource instance directly. Assign a DataSource configuration object (see http://js.devexpress.com/Documentation/ApiReference/Data_Library/DataSource/Configuration) or a simple array instead.");
  32991. return
  32992. }
  32993. this.callBase();
  32994. dataSource = this._dataSource;
  32995. if (dataSource) {
  32996. columnsController.updateSortingGrouping(dataSource);
  32997. sort = columnsController.getSortDataSourceParameters();
  32998. if (sort)
  32999. dataSource.sort(sort);
  33000. group = columnsController.getGroupDataSourceParameters();
  33001. if (group)
  33002. dataSource.group(group);
  33003. this.setDataSource(dataSource)
  33004. }
  33005. },
  33006. _processItems: function(items) {
  33007. var that = this,
  33008. visibleColumns = that._columnsController.getVisibleColumns(),
  33009. groupColumns = that._columnsController.getGroupColumns(),
  33010. result = [],
  33011. dataIndex = 0;
  33012. if (items.length > 0 && that._columnsController.isInitialized()) {
  33013. if (groupColumns.length > 0)
  33014. items = processGroupItems(that, items, groupColumns.length);
  33015. $.each(items, function(index, item) {
  33016. if (utils.isDefined(item)) {
  33017. if (utils.isDefined(item.groupIndex))
  33018. dataIndex = 0;
  33019. else {
  33020. item = that._generateDataItem(item);
  33021. item = that._processDataItem(item, visibleColumns);
  33022. item.dataIndex = dataIndex++
  33023. }
  33024. result.push(item)
  33025. }
  33026. })
  33027. }
  33028. return result
  33029. },
  33030. _generateDataItem: function(data) {
  33031. return {
  33032. rowType: 'data',
  33033. data: data,
  33034. key: this.keyOf(data)
  33035. }
  33036. },
  33037. _processDataItem: function(dataItem, visibleColumns) {
  33038. dataItem.values = this._generateDataValues(dataItem.data, visibleColumns);
  33039. return dataItem
  33040. },
  33041. _generateDataValues: function(data, columns) {
  33042. var values = [];
  33043. $.each(columns, function() {
  33044. var value = null;
  33045. if (utils.isDefined(this.groupIndex))
  33046. value = null;
  33047. else if (this.calculateCellValue)
  33048. value = this.calculateCellValue(data);
  33049. else if (this.dataField)
  33050. value = data[this.dataField];
  33051. values.push(value)
  33052. });
  33053. return values
  33054. },
  33055. _updateItemsCore: function(change) {
  33056. var that = this,
  33057. items,
  33058. dataSource = that._dataSource,
  33059. changes = [],
  33060. changeType = change.changeType;
  33061. if (dataSource) {
  33062. items = change.items || dataSource.items();
  33063. items = that._processItems(items.slice(0));
  33064. change.items = items;
  33065. change.changeType = changeType || 'refresh';
  33066. switch (changeType) {
  33067. case'prepend':
  33068. that._items.unshift.apply(that._items, items);
  33069. break;
  33070. case'append':
  33071. that._items.push.apply(that._items, items);
  33072. break;
  33073. default:
  33074. that._items = items;
  33075. break
  33076. }
  33077. }
  33078. },
  33079. updateItems: function(change) {
  33080. var that = this;
  33081. change = change || {};
  33082. if (that._dataSource && that._columnsController.isDataSourceApplied()) {
  33083. that._updateItemsCore(change);
  33084. that.changed.fire(change)
  33085. }
  33086. },
  33087. changeGroupExpand: function(path) {
  33088. this._dataSource && this._dataSource.changeGroupExpand(path)
  33089. },
  33090. getGroupPathByRowIndex: function(rowIndex) {
  33091. var item = this.items()[rowIndex];
  33092. if (item && item.rowType === 'group')
  33093. return item.values
  33094. },
  33095. isLoading: function() {
  33096. return this._isLoading || this._isCustomLoading
  33097. },
  33098. _fireLoadingChanged: function(messageText) {
  33099. this.loadingChanged.fire(this.isLoading(), messageText)
  33100. },
  33101. _calculateAdditionalFilter: function() {
  33102. return null
  33103. },
  33104. _applyFilter: function() {
  33105. var that = this,
  33106. dataSource = that._dataSource,
  33107. additionalFilter,
  33108. filter = that._filter;
  33109. if (dataSource) {
  33110. additionalFilter = that._calculateAdditionalFilter();
  33111. if (additionalFilter)
  33112. if (filter)
  33113. filter = [additionalFilter, 'and', filter];
  33114. else
  33115. filter = additionalFilter;
  33116. dataSource.filter(filter && filter.length ? filter : null);
  33117. dataSource.pageIndex(0);
  33118. return that.reload()
  33119. }
  33120. },
  33121. filter: function(filterExpr) {
  33122. this._filter = arguments.length > 1 ? Array.prototype.slice.call(arguments, 0) : filterExpr;
  33123. this._applyFilter()
  33124. },
  33125. clearFilter: function() {
  33126. this._filter = null;
  33127. this._applyFilter()
  33128. },
  33129. setDataSource: function(dataSource) {
  33130. var that = this;
  33131. if (that._dataSource) {
  33132. that._dataSource.changed.remove(that._gridDataSourceChangedHandler);
  33133. that._dataSource.loadingChanged.remove(that._loadingChangedHandler);
  33134. that._dataSource.loadError.remove(that._loadErrorHandler)
  33135. }
  33136. that._dataSource = dataSource;
  33137. if (dataSource) {
  33138. that._isLoading = !dataSource.isLoaded();
  33139. that._filter = dataSource.filter();
  33140. dataSource.changed.add(that._gridDataSourceChangedHandler);
  33141. dataSource.loadingChanged.add(that._loadingChangedHandler);
  33142. dataSource.loadError.add(that._loadErrorHandler);
  33143. that._needApplyFilter = true;
  33144. if (dataSource.isLoaded())
  33145. that._gridDataSourceChangedHandler()
  33146. }
  33147. },
  33148. items: function() {
  33149. return this._items
  33150. },
  33151. virtualItemsCount: function() {
  33152. var dataSource = this._dataSource;
  33153. return dataSource && dataSource.virtualItemsCount && dataSource.virtualItemsCount()
  33154. },
  33155. setViewportSize: function(size) {
  33156. var dataSource = this._dataSource;
  33157. return dataSource && dataSource.setViewportSize && dataSource.setViewportSize(size)
  33158. },
  33159. setViewportItemIndex: function(itemIndex) {
  33160. var dataSource = this._dataSource;
  33161. dataSource && dataSource.setViewportItemIndex && dataSource.setViewportItemIndex(itemIndex)
  33162. },
  33163. collapseAll: function(groupIndex) {
  33164. var dataSource = this._dataSource;
  33165. if (dataSource && dataSource.collapseAll(groupIndex)) {
  33166. dataSource.pageIndex(0);
  33167. dataSource.reload()
  33168. }
  33169. },
  33170. expandAll: function(groupIndex) {
  33171. var dataSource = this._dataSource;
  33172. if (dataSource && dataSource.expandAll(groupIndex)) {
  33173. dataSource.pageIndex(0);
  33174. dataSource.reload()
  33175. }
  33176. },
  33177. totalItemsCount: function() {
  33178. return this._dataSource ? this._dataSource.totalItemsCount() : 0
  33179. },
  33180. hasKnownLastPage: function() {
  33181. return this._dataSource ? this._dataSource.hasKnownLastPage() : true
  33182. },
  33183. isLoaded: function() {
  33184. return this._dataSource ? this._dataSource.isLoaded() : false
  33185. },
  33186. totalCount: function() {
  33187. return this._dataSource ? this._dataSource.totalCount() : 0
  33188. },
  33189. pageCount: function() {
  33190. return this._dataSource ? this._dataSource.pagesCount() : 1
  33191. },
  33192. dataSource: function() {
  33193. return this._dataSource
  33194. },
  33195. store: function() {
  33196. var dataSource = this._dataSource;
  33197. return dataSource && dataSource.store()
  33198. },
  33199. keyOf: function(data) {
  33200. var store = this.store();
  33201. return store && store.keyOf(data)
  33202. },
  33203. byKey: function(key) {
  33204. var store = this.store(),
  33205. result;
  33206. if (!store)
  33207. return;
  33208. $.each(this._items, function(_, item) {
  33209. if (item.key === key) {
  33210. result = $.Deferred().resolve(item.data);
  33211. return false
  33212. }
  33213. });
  33214. return result || store.byKey(key)
  33215. },
  33216. getDataByKeys: function(rowKeys) {
  33217. var that = this,
  33218. result = $.Deferred(),
  33219. deferreds = [],
  33220. data = [];
  33221. $.each(rowKeys, function(index, key) {
  33222. deferreds.push(that.byKey(key).done(function(keyData) {
  33223. data[index] = keyData
  33224. }))
  33225. });
  33226. $.when.apply($, deferreds).always(function() {
  33227. result.resolve(data)
  33228. });
  33229. return result
  33230. },
  33231. pageIndex: function(value) {
  33232. var that = this,
  33233. dataSource = that._dataSource;
  33234. if (dataSource) {
  33235. if (value !== undefined)
  33236. if (dataSource.pageIndex() !== value) {
  33237. dataSource.pageIndex(value);
  33238. return dataSource.load()
  33239. }
  33240. return dataSource.pageIndex()
  33241. }
  33242. return 0
  33243. },
  33244. pageSize: function(value) {
  33245. var that = this,
  33246. dataSource = that._dataSource;
  33247. if (value === undefined)
  33248. return dataSource ? dataSource.pageSize() : 0;
  33249. if (dataSource) {
  33250. dataSource.pageIndex(0);
  33251. dataSource.pageSize(value);
  33252. return dataSource.reload()
  33253. }
  33254. },
  33255. beginCustomLoading: function(messageText) {
  33256. this._isCustomLoading = true;
  33257. this._fireLoadingChanged(messageText)
  33258. },
  33259. endCustomLoading: function() {
  33260. this._isCustomLoading = false;
  33261. this._fireLoadingChanged()
  33262. },
  33263. refresh: function() {
  33264. var that = this,
  33265. d = $.Deferred();
  33266. $.when(this._columnsController.refresh()).always(function() {
  33267. $.when(that.reload()).done(d.resolve).fail(d.reject)
  33268. });
  33269. return d
  33270. },
  33271. reload: function() {
  33272. var dataSource = this._dataSource;
  33273. return dataSource && dataSource.reload()
  33274. },
  33275. dispose: function() {
  33276. var that = this,
  33277. dataSource = that._dataSource;
  33278. that.callBase();
  33279. if (dataSource) {
  33280. dataSource.changed.remove(that._gridDataSourceChangedHandler);
  33281. dataSource.loadingChanged.remove(that._loadingChangedHandler)
  33282. }
  33283. }
  33284. }
  33285. }());
  33286. dataGrid.registerModule('data', {
  33287. defaultOptions: function() {
  33288. return {
  33289. dataSource: null,
  33290. dataErrorOccurred: null
  33291. }
  33292. },
  33293. controllers: {data: ui.dataGrid.DataController}
  33294. })
  33295. })(jQuery, DevExpress);
  33296. /*! Module widgets-web, file ui.dataGrid.columnsView.js */
  33297. (function($, DX, undefined) {
  33298. var ui = DX.ui,
  33299. utils = DX.utils,
  33300. dataGrid = ui.dataGrid;
  33301. var DATAGRID_SORT_CLASS = "dx-sort",
  33302. DATAGRID_SORTUP_CLASS = "dx-sort-up",
  33303. DATAGRID_SORTDOWN_CLASS = "dx-sort-down",
  33304. DATAGRID_SORT_ALIGNMENT_CLASS = "dx-sort-alignment-",
  33305. DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",
  33306. DATAGRID_TABLE_CONTENT_CLASS = "dx-datagrid-table-content",
  33307. DATAGRID_ROW_CLASS = "dx-row",
  33308. DATAGRID_GROUP_ROW_CLASS = "dx-group-row",
  33309. DATAGRID_TABLE_CLASS = "dx-datagrid-table";
  33310. dataGrid.ColumnsView = dataGrid.View.inherit({
  33311. _applySorting: function(rootElement, column, showColumnLines) {
  33312. var $span,
  33313. columnAlignment;
  33314. function getAlignment(columnAlignment) {
  33315. return columnAlignment === 'right' ? 'left' : 'right'
  33316. }
  33317. rootElement.find('.' + DATAGRID_SORT_CLASS).remove();
  33318. if (utils.isDefined(column.sortOrder)) {
  33319. if (column.alignment === 'center') {
  33320. var align = this.option('rtlEnabled') ? 'right' : 'left';
  33321. $('<span />').addClass(DATAGRID_SORT_CLASS).css('float', align).prependTo(rootElement)
  33322. }
  33323. columnAlignment = column.alignment || 'left';
  33324. $span = $('<span />').addClass(DATAGRID_SORT_CLASS).css('float', showColumnLines ? getAlignment(column.alignment) : columnAlignment).toggleClass(DATAGRID_SORTUP_CLASS, column.sortOrder === 'asc').toggleClass(DATAGRID_SORTDOWN_CLASS, column.sortOrder === 'desc');
  33325. if (this.option("showColumnLines"))
  33326. $span.prependTo(rootElement);
  33327. else
  33328. $span.addClass(DATAGRID_SORT_ALIGNMENT_CLASS + columnAlignment).appendTo(rootElement)
  33329. }
  33330. },
  33331. _updateSortIndicatorPositions: function(rootElement) {
  33332. if (!rootElement)
  33333. return;
  33334. var sortIndicators = rootElement.find('.' + DATAGRID_SORT_CLASS);
  33335. $.each(sortIndicators, function() {
  33336. var $sortIndicator = $(this),
  33337. $sortIndicatorContainer = $sortIndicator.parent(),
  33338. $textContent = $sortIndicatorContainer.find('.' + DATAGRID_CELL_CONTENT_CLASS);
  33339. $sortIndicator.height($textContent.height() || $sortIndicatorContainer.height())
  33340. })
  33341. },
  33342. _createRow: function() {
  33343. return $("<tr />").addClass(DATAGRID_ROW_CLASS)
  33344. },
  33345. _createTable: function() {
  33346. return $('<table />').toggleClass(DATAGRID_TABLE_CLASS, !this.option('columnAutoWidth'))
  33347. },
  33348. init: function() {
  33349. var that = this;
  33350. that._columnsController = that.getController('columns')
  33351. },
  33352. getColumnWidths: function() {
  33353. var that = this,
  33354. cells,
  33355. result = [],
  33356. width,
  33357. clientRect;
  33358. if (that._tableElement) {
  33359. cells = that._tableElement.find('tr').filter(':not(.' + DATAGRID_GROUP_ROW_CLASS + ')').first().find('td');
  33360. $.each(cells, function(index, item) {
  33361. if (item.getBoundingClientRect) {
  33362. clientRect = item.getBoundingClientRect();
  33363. width = Math.floor(clientRect.right - clientRect.left)
  33364. }
  33365. else
  33366. width = $(item).outerWidth(true);
  33367. result.push(width)
  33368. })
  33369. }
  33370. return result
  33371. },
  33372. setColumnWidths: function(widths) {
  33373. this._setColumnWidthsCore(this._tableElement, widths)
  33374. },
  33375. _setColumnWidthsCore: function(tableElements, widths) {
  33376. var colgroupElement,
  33377. i,
  33378. columnIndex;
  33379. if (!tableElements)
  33380. return;
  33381. for (i = 0; i < tableElements.length; i++) {
  33382. tableElements.eq(i).addClass(DATAGRID_TABLE_CLASS);
  33383. if (widths) {
  33384. this._columnWidths = widths;
  33385. colgroupElement = tableElements.eq(i).find('colgroup').first();
  33386. colgroupElement.empty();
  33387. for (columnIndex = 0; columnIndex < widths.length; columnIndex++)
  33388. $('<col />').width(widths[columnIndex] || 'auto').appendTo(colgroupElement)
  33389. }
  33390. }
  33391. },
  33392. resetColumnWidths: function() {
  33393. var that = this,
  33394. tableElement,
  33395. visibleColumns = that._columnsController.getVisibleColumns(),
  33396. i,
  33397. widths = [],
  33398. $elementWithFocus,
  33399. elementWithFocus,
  33400. selectionStart,
  33401. selectionEnd;
  33402. for (i = 0; i < visibleColumns.length; i++)
  33403. widths.push(visibleColumns[i].width);
  33404. that.setColumnWidths(widths);
  33405. if (that._tableElement) {
  33406. $elementWithFocus = that._tableElement.find(':focus');
  33407. elementWithFocus = $elementWithFocus.get(0);
  33408. if (elementWithFocus) {
  33409. selectionStart = elementWithFocus.selectionStart;
  33410. selectionEnd = elementWithFocus.selectionEnd
  33411. }
  33412. tableElement = that._createTable();
  33413. tableElement.append(that._tableElement.children());
  33414. tableElement.toggleClass(DATAGRID_TABLE_CONTENT_CLASS, that._tableElement.hasClass(DATAGRID_TABLE_CONTENT_CLASS));
  33415. tableElement.attr('style', that._tableElement.attr('style'));
  33416. that._tableElement.replaceWith(tableElement);
  33417. that._tableElement = tableElement;
  33418. if (elementWithFocus && elementWithFocus.setSelectionRange)
  33419. elementWithFocus.setSelectionRange(selectionStart, selectionEnd);
  33420. $elementWithFocus.focus()
  33421. }
  33422. },
  33423. getColumnElements: function(){},
  33424. getColumns: function(){},
  33425. getCell: function(columnIndex, rowIndex) {
  33426. var row;
  33427. if (this._tableElement && this._tableElement.length === 1) {
  33428. row = this._tableElement[0].rows[rowIndex];
  33429. return row ? $(row.cells[columnIndex]) : null
  33430. }
  33431. },
  33432. getRowsCount: function() {
  33433. if (this._tableElement && this._tableElement.length === 1)
  33434. return this._tableElement[0].rows.length;
  33435. return 0
  33436. },
  33437. getBoundingRect: function(){},
  33438. getName: function(){}
  33439. });
  33440. $.extend(dataGrid.__internals, {
  33441. DATAGRID_SORT_CLASS: DATAGRID_SORT_CLASS,
  33442. DATAGRID_SORTUP_CLASS: DATAGRID_SORTUP_CLASS,
  33443. DATAGRID_SORTDOWN_CLASS: DATAGRID_SORTDOWN_CLASS,
  33444. DATAGRID_SORT_ALIGNMENT_CLASS: DATAGRID_SORT_ALIGNMENT_CLASS,
  33445. DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,
  33446. DATAGRID_ROW_CLASS: DATAGRID_ROW_CLASS,
  33447. DATAGRID_GROUP_ROW_CLASS: DATAGRID_GROUP_ROW_CLASS,
  33448. DATAGRID_TABLE_CLASS: DATAGRID_TABLE_CLASS
  33449. })
  33450. })(jQuery, DevExpress);
  33451. /*! Module widgets-web, file ui.dataGrid.columnHeadersView.js */
  33452. (function($, DX) {
  33453. var ui = DX.ui,
  33454. events = ui.events,
  33455. utils = DX.utils,
  33456. dataGrid = ui.dataGrid;
  33457. var DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",
  33458. DATAGRID_HEADERS_ACTION_CLASS = "dx-datagrid-action-cursor",
  33459. DATAGRID_HEADERS_CONTAINER_CLASS = "dx-datagrid-headers-container",
  33460. DATAGRID_HEADERS_CLASS = "dx-datagrid-headers",
  33461. DATAGRID_HEADER_ROW_CLASS = "dx-header-row",
  33462. DATAGRID_NOWRAP_CLASS = "dx-datagrid-nowrap",
  33463. DATAGRID_GROUP_SPACE_CLASS = "dx-datagrid-group-space",
  33464. DATAGRID_CONTENT_CLASS = "dx-datagrid-content",
  33465. DATAGRID_COLUMN_LINES_CLASS = "dx-column-lines",
  33466. DATAGRID_CONTEXT_MENU_SORT_ASC_ICON = "context-menu-sort-asc",
  33467. DATAGRID_CONTEXT_MENU_SORT_DESC_ICON = "context-menu-sort-desc",
  33468. DATAGRID_CONTEXT_MENU_SORT_NONE_ICON = "context-menu-sort-none",
  33469. DATAGRID_SORT_CLASS = "dx-sort",
  33470. COLUMN_HEADERS_VIEW_NAMESPACE = 'dxDataGridColumnHeadersView';
  33471. dataGrid.ColumnHeadersView = dataGrid.ColumnsView.inherit({
  33472. _renderHeaderContent: function($cell, column, columnIndex) {
  33473. var that = this,
  33474. $group = $('<div />'),
  33475. headerCellTemplate = column.headerCellTemplate;
  33476. if (column.command === "empty" || column.command === "edit")
  33477. $cell.html('&nbsp;');
  33478. else if (!utils.isDefined(column.groupIndex)) {
  33479. that._applySorting($cell, column, that.option('showColumnLines'));
  33480. var $content = $('<div />').addClass(DATAGRID_CELL_CONTENT_CLASS);
  33481. if (that.option("showColumnLines"))
  33482. $content.appendTo($cell);
  33483. else
  33484. $content.css("float", column.alignment || 'left').prependTo($cell);
  33485. var templateOptions = {
  33486. column: column,
  33487. columnIndex: columnIndex
  33488. };
  33489. if ($.isFunction(headerCellTemplate))
  33490. headerCellTemplate($content, templateOptions);
  33491. else if (utils.isString(headerCellTemplate)) {
  33492. headerCellTemplate = that.getTemplate(headerCellTemplate);
  33493. if (headerCellTemplate)
  33494. headerCellTemplate.render($content, templateOptions)
  33495. }
  33496. else
  33497. $content.text(column.caption)
  33498. }
  33499. else
  33500. $cell.addClass(DATAGRID_GROUP_SPACE_CLASS)
  33501. },
  33502. _renderHeader: function(rootElement, column, columnIndex) {
  33503. var that = this,
  33504. sorting = that.option('sorting'),
  33505. sortingMode = sorting && sorting.mode,
  33506. cellElement;
  33507. cellElement = $('<td />').css('text-align', column.alignment || 'left').toggleClass(column.cssClass, !utils.isDefined(column.groupIndex));
  33508. that._renderHeaderContent(cellElement, column, columnIndex);
  33509. if (((sortingMode === 'single' || sortingMode === 'multiple') && column.allowSorting || column.allowReordering || column.allowHiding) && !utils.isDefined(column.groupIndex))
  33510. cellElement.addClass(DATAGRID_HEADERS_ACTION_CLASS);
  33511. cellElement.appendTo(rootElement)
  33512. },
  33513. _renderCore: function() {
  33514. var that = this,
  33515. $container = that._element(),
  33516. columns = that._columnsController.getVisibleColumns(),
  33517. scrollLeft = that._scrollLeft,
  33518. columnsLength = columns.length,
  33519. i,
  33520. $row;
  33521. that._tableElement = that._createTable().attr('style', '-webkit-user-select: none').append(dataGrid.createColGroup(columns));
  33522. if (that.option('showColumnHeaders')) {
  33523. $row = that._createRow().addClass(DATAGRID_HEADER_ROW_CLASS).toggleClass(DATAGRID_COLUMN_LINES_CLASS, that.option('showColumnLines'));
  33524. $row.on(events.addNamespace("dxclick", COLUMN_HEADERS_VIEW_NAMESPACE), 'td', that.createAction(function(e) {
  33525. var keyName = null,
  33526. event = e.jQueryEvent;
  33527. event.stopPropagation();
  33528. setTimeout(function() {
  33529. var column = columns[event.currentTarget.cellIndex];
  33530. if (event.shiftKey)
  33531. keyName = "shift";
  33532. else if (event.ctrlKey)
  33533. keyName = "ctrl";
  33534. if (column && !utils.isDefined(column.groupIndex))
  33535. that._columnsController.changeSortOrder(column.index, keyName)
  33536. })
  33537. }));
  33538. for (i = 0; i < columnsLength; i++)
  33539. that._renderHeader($row, columns[i], i);
  33540. that._tableElement.append($row)
  33541. }
  33542. $container.addClass(DATAGRID_HEADERS_CLASS).addClass(DATAGRID_CONTENT_CLASS).toggleClass(DATAGRID_NOWRAP_CLASS, !!that.option("columnAutoWidth") || !that.option("wordWrapEnabled")).empty();
  33543. $('<div/>').addClass(DATAGRID_HEADERS_CONTAINER_CLASS).append(that._tableElement).appendTo($container);
  33544. that._scrollLeft = 0;
  33545. that.scrollOffset(scrollLeft)
  33546. },
  33547. setColumnWidths: function(widths) {
  33548. var that = this,
  33549. scrollLeft = that._scrollLeft;
  33550. that.callBase(widths);
  33551. that._scrollLeft = 0;
  33552. that.scrollOffset(scrollLeft)
  33553. },
  33554. _afterRender: function($root) {
  33555. var that = this;
  33556. if (!$root)
  33557. that.setColumnWidths(that._columnWidths && that._columnWidths.length === that._columnsController.getVisibleColumns().length ? that._columnWidths : null);
  33558. that._updateSortIndicatorPositions(that._element());
  33559. that.processSizeChanged()
  33560. },
  33561. _updateSortIndicatorPositions: function(element) {
  33562. var that = this,
  33563. columns = that.getColumnElements();
  33564. that.callBase(element);
  33565. if (!that.option('showColumnLines') && columns) {
  33566. var i;
  33567. for (i = 0; i < columns.length; i++) {
  33568. var $cell = $(columns[i]);
  33569. that._setColumnTextWidth($cell, $cell.outerWidth())
  33570. }
  33571. }
  33572. },
  33573. _updateSortIndicators: function() {
  33574. var that = this,
  33575. columns = that._columnsController.getVisibleColumns(),
  33576. $element = that._element(),
  33577. $cells = $element.find('.' + DATAGRID_HEADER_ROW_CLASS + ' > td'),
  33578. i;
  33579. for (i = 0; i < columns.length; i++)
  33580. if (!utils.isDefined(columns[i].groupIndex))
  33581. that._applySorting($cells.eq(i), columns[i], that.option('showColumnLines'));
  33582. that._updateSortIndicatorPositions($element)
  33583. },
  33584. _processColumnsChanged: function(e) {
  33585. var visibleColumnIndex;
  33586. if (dataGrid.checkChanges(e.changeTypes, ['sorting'])) {
  33587. this._updateSortIndicators();
  33588. return
  33589. }
  33590. if (dataGrid.checkChanges(e.optionNames, ['width'])) {
  33591. visibleColumnIndex = this._columnsController.getVisibleIndex(e.columnIndex);
  33592. if (visibleColumnIndex !== -1) {
  33593. this._tableElement.find('col').eq(visibleColumnIndex).css('width', e.column.width);
  33594. this._updateSortIndicatorPositions(this._element());
  33595. if (!this.option('showColumnLines'))
  33596. this._setColumnTextWidth($(this._tableElement.find('.' + DATAGRID_HEADER_ROW_CLASS + ' td')[visibleColumnIndex]), e.column.width)
  33597. }
  33598. if (this._columnWidths)
  33599. this._columnWidths[visibleColumnIndex] = e.column.width;
  33600. return
  33601. }
  33602. this.render()
  33603. },
  33604. _setColumnTextWidth: function($column, columnWidth) {
  33605. var $sortElement = $column.find("." + DATAGRID_SORT_CLASS),
  33606. indicatorOuterWidth = $sortElement.outerWidth(),
  33607. columnPaddings = $column.outerWidth() - $column.width(),
  33608. columnContentIndent = indicatorOuterWidth + columnPaddings;
  33609. $column.find("." + DATAGRID_CELL_CONTENT_CLASS).css("max-width", columnWidth - columnContentIndent)
  33610. },
  33611. _isElementVisible: function(elementOptions) {
  33612. return elementOptions && elementOptions.visible
  33613. },
  33614. processSizeChanged: function() {
  33615. var that = this,
  33616. $element = that._element();
  33617. if (!utils.isDefined(that._headersHeight) || that._headersHeight !== $element.height()) {
  33618. that._headersHeight = $element.height();
  33619. that.sizeChanged.fire()
  33620. }
  33621. },
  33622. getHeaderElement: function(index) {
  33623. var columnElements = this.getColumnElements();
  33624. return columnElements && columnElements.eq(index)
  33625. },
  33626. getColumnElements: function() {
  33627. var that = this,
  33628. columnElements;
  33629. if (that._tableElement) {
  33630. columnElements = that._tableElement.find('.' + DATAGRID_HEADER_ROW_CLASS).find('td');
  33631. if (columnElements.length)
  33632. return columnElements
  33633. }
  33634. return null
  33635. },
  33636. allowDragging: function(column, draggingPanels) {
  33637. var i,
  33638. result = false,
  33639. columns = this.getColumns(),
  33640. draggableColumnCount = 0,
  33641. allowDrag = function(column) {
  33642. return column.allowReordering || column.allowGrouping || column.allowHiding
  33643. };
  33644. for (i = 0; i < columns.length; i++)
  33645. if (allowDrag(columns[i]))
  33646. draggableColumnCount++;
  33647. if (draggableColumnCount <= 1)
  33648. return false;
  33649. else if (!draggingPanels)
  33650. return (this.option("allowColumnReordering") || this._columnsController.isColumnOptionUsed("allowReordering")) && column && column.allowReordering;
  33651. for (i = 0; i < draggingPanels.length; i++)
  33652. if (draggingPanels[i].allowDragging(column))
  33653. return true;
  33654. return false
  33655. },
  33656. getColumns: function() {
  33657. return this._columnsController.getVisibleColumns()
  33658. },
  33659. getBoundingRect: function() {
  33660. var that = this,
  33661. offset;
  33662. if (that._tableElement.length > 0 && that._tableElement[0].rows.length > 0 && that._tableElement[0].rows[0].cells.length > 0) {
  33663. offset = that._tableElement.offset();
  33664. return {top: offset.top}
  33665. }
  33666. return null
  33667. },
  33668. getName: function() {
  33669. return 'headers'
  33670. },
  33671. getHeadersLength: function() {
  33672. var that = this;
  33673. if (that._tableElement.length > 0 && that._tableElement[0].rows.length > 0)
  33674. return that._tableElement[0].rows[0].cells.length;
  33675. return 0
  33676. },
  33677. tableElement: function() {
  33678. return this._tableElement
  33679. },
  33680. init: function() {
  33681. var that = this,
  33682. dataController = that.getController('data');
  33683. that.callBase();
  33684. that._columnsController.columnsChanged.add(function(e) {
  33685. var dataControllerChangedHandler = function() {
  33686. dataController.changed.remove(dataControllerChangedHandler);
  33687. that._processColumnsChanged(e)
  33688. };
  33689. if (e.changeTypes.grouping)
  33690. dataController.changed.add(dataControllerChangedHandler);
  33691. else
  33692. that._processColumnsChanged(e)
  33693. });
  33694. that._scrollerWidth = 0;
  33695. that.sizeChanged = $.Callbacks()
  33696. },
  33697. isVisible: function() {
  33698. return this.option('showColumnHeaders')
  33699. },
  33700. scrollOffset: function(pos) {
  33701. var that = this,
  33702. $element = that._element(),
  33703. $scrollContainer = $element && $element.find('.' + DATAGRID_HEADERS_CONTAINER_CLASS);
  33704. if (pos === undefined)
  33705. return $scrollContainer && $scrollContainer.scrollLeft();
  33706. else if (that._scrollLeft !== pos) {
  33707. that._scrollLeft = pos;
  33708. $scrollContainer && $scrollContainer.scrollLeft(pos)
  33709. }
  33710. },
  33711. setScrollerSpacing: function(width) {
  33712. var that = this,
  33713. $element = that._element(),
  33714. rtlEnabled = that.option("rtlEnabled");
  33715. that._scrollerWidth = width;
  33716. $element && $element.css(rtlEnabled ? {paddingLeft: width} : {paddingRight: width})
  33717. },
  33718. optionChanged: function(name, value, prevValue) {
  33719. var that = this;
  33720. switch (name) {
  33721. case'showColumnHeaders':
  33722. case'wordWrapEnabled':
  33723. case'showColumnLines':
  33724. that.render();
  33725. break
  33726. }
  33727. },
  33728. resize: function() {
  33729. this.callBase();
  33730. this._updateSortIndicatorPositions(this._element())
  33731. },
  33732. getHeight: function() {
  33733. var that = this,
  33734. $element = that._element();
  33735. return $element ? $element.height() : 0
  33736. },
  33737. getContextMenuItems: function($targetElement) {
  33738. var that = this,
  33739. $cell,
  33740. column,
  33741. itemClickAction,
  33742. sortingOptions;
  33743. if ($targetElement.closest("." + DATAGRID_HEADER_ROW_CLASS).length) {
  33744. $cell = $targetElement.closest("td");
  33745. column = $cell.length && that.getColumns()[$cell[0].cellIndex];
  33746. sortingOptions = that.option("sorting");
  33747. if (sortingOptions && sortingOptions.mode !== "none" && column && column.allowSorting) {
  33748. itemClickAction = function(params) {
  33749. setTimeout(function() {
  33750. that._columnsController.changeSortOrder(column.index, params.itemData.value)
  33751. })
  33752. };
  33753. return [{
  33754. text: sortingOptions.ascendingText,
  33755. value: "asc",
  33756. icon: DATAGRID_CONTEXT_MENU_SORT_ASC_ICON,
  33757. itemClickAction: itemClickAction
  33758. }, {
  33759. text: sortingOptions.descendingText,
  33760. value: "desc",
  33761. icon: DATAGRID_CONTEXT_MENU_SORT_DESC_ICON,
  33762. itemClickAction: itemClickAction
  33763. }, {
  33764. text: sortingOptions.clearText,
  33765. value: "none",
  33766. icon: DATAGRID_CONTEXT_MENU_SORT_NONE_ICON,
  33767. itemClickAction: itemClickAction
  33768. }]
  33769. }
  33770. }
  33771. return []
  33772. }
  33773. });
  33774. $.extend(dataGrid.__internals, {
  33775. DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,
  33776. DATAGRID_HEADERS_ACTION_CLASS: DATAGRID_HEADERS_ACTION_CLASS,
  33777. DATAGRID_HEADERS_CONTAINER_CLASS: DATAGRID_HEADERS_CONTAINER_CLASS,
  33778. DATAGRID_HEADERS_CLASS: DATAGRID_HEADERS_CLASS,
  33779. DATAGRID_HEADER_ROW_CLASS: DATAGRID_HEADER_ROW_CLASS,
  33780. DATAGRID_NOWRAP_CLASS: DATAGRID_NOWRAP_CLASS
  33781. });
  33782. dataGrid.registerModule('columnHeaders', {
  33783. defaultOptions: function() {
  33784. return {showColumnHeaders: true}
  33785. },
  33786. views: {columnHeadersView: dataGrid.ColumnHeadersView}
  33787. })
  33788. })(jQuery, DevExpress);
  33789. /*! Module widgets-web, file ui.dataGrid.filterRow.js */
  33790. (function($, DX) {
  33791. var ui = DX.ui,
  33792. events = ui.events,
  33793. utils = DX.utils,
  33794. dataGrid = ui.dataGrid;
  33795. var OPERATION_ICONS = {
  33796. '=': 'filter-operation-equals',
  33797. '<>': 'filter-operation-not-equals',
  33798. '<': 'filter-operation-less',
  33799. '<=': 'filter-operation-less-equal',
  33800. '>': 'filter-operation-greater',
  33801. '>=': 'filter-operation-greater-equal',
  33802. 'default': 'filter-operation-default',
  33803. notcontains: 'filter-operation-not-contains',
  33804. contains: 'filter-operation-contains',
  33805. startswith: 'filter-operation-starts-with',
  33806. endswith: 'filter-operation-ends-with'
  33807. };
  33808. var DATAGRID_FILTER_ROW_CLASS = "dx-datagrid-filter-row",
  33809. DATAGRID_MENU_CLASS = "dx-menu",
  33810. DATAGRID_MENU_IMAGE_CLASS = 'dx-menu-image',
  33811. DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",
  33812. DATAGRID_GROUP_SPACE_CLASS = "dx-datagrid-group-space",
  33813. DATAGRID_EDITOR_WITH_MENU_CLASS = "dx-editor-with-menu",
  33814. DATAGRID_EDITOR_CONTAINER_CLASS = "dx-editor-container",
  33815. DATAGRID_COLUMN_LINES_CLASS = "dx-column-lines",
  33816. DATAGRID_EDITOR_CELL_CLASS = "dx-editor-cell";
  33817. var ColumnHeadersViewFilterRowExtender = {
  33818. _processColumnsChanged: function(e) {
  33819. var that = this,
  33820. visibleIndex,
  33821. textBox,
  33822. column,
  33823. $menu;
  33824. if (dataGrid.checkChanges(e.optionNames, ['filterValue']))
  33825. return;
  33826. if (dataGrid.checkChanges(e.optionNames, ['selectedFilterOperation'])) {
  33827. visibleIndex = that.getController('columns').getVisibleIndex(e.columnIndex);
  33828. column = e.column;
  33829. if (visibleIndex >= 0) {
  33830. $menu = that._element().find('.' + DATAGRID_FILTER_ROW_CLASS).children().eq(visibleIndex).find('.' + DATAGRID_MENU_CLASS);
  33831. if ($menu.length) {
  33832. that._updateFilterOperationChooser($menu, column);
  33833. textBox = $menu.prev().children().data('dxTextBox');
  33834. if (textBox)
  33835. textBox.option('value', column.filterValue)
  33836. }
  33837. }
  33838. }
  33839. else
  33840. that.callBase(e)
  33841. },
  33842. isFilterRowVisible: function() {
  33843. return this._isElementVisible(this.option('filterRow'))
  33844. },
  33845. isVisible: function() {
  33846. return this.callBase() || this.isFilterRowVisible()
  33847. },
  33848. _renderCore: function() {
  33849. this.callBase();
  33850. var that = this,
  33851. columns = that._columnsController.getVisibleColumns(),
  33852. i,
  33853. rowElement;
  33854. if (that.isFilterRowVisible()) {
  33855. rowElement = that._createRow().appendTo(that._tableElement);
  33856. rowElement.addClass(DATAGRID_FILTER_ROW_CLASS).toggleClass(DATAGRID_COLUMN_LINES_CLASS, that.option('showColumnLines'));
  33857. for (i = 0; i < columns.length; i++)
  33858. that._renderFilterRowCell(rowElement, columns[i])
  33859. }
  33860. },
  33861. _updateFilterOperationChooser: function($menu, column) {
  33862. var that = this;
  33863. $menu.dxMenu({
  33864. highlightActiveItem: true,
  33865. cssClass: 'dx-datagrid dx-widget',
  33866. showFirstSubmenuMode: 'onhover',
  33867. items: [{
  33868. disabled: column.filterOperations && column.filterOperations.length === 0,
  33869. icon: OPERATION_ICONS[column.selectedFilterOperation || "default"],
  33870. items: that._getFilterOperationMenuItems(column)
  33871. }],
  33872. itemClickAction: function(properties) {
  33873. var selectedFilterOperation = properties.itemData.name;
  33874. if (properties.itemData.items)
  33875. return;
  33876. if (selectedFilterOperation)
  33877. that._columnsController.columnOption(column.initialIndex, 'selectedFilterOperation', selectedFilterOperation);
  33878. else
  33879. that._columnsController.columnOption(column.initialIndex, {
  33880. selectedFilterOperation: column.defaultSelectedFilterOperation || null,
  33881. filterValue: null
  33882. })
  33883. },
  33884. rtlEnabled: that.option('rtlEnabled')
  33885. })
  33886. },
  33887. _renderFilterOperationChooser: function($container, column) {
  33888. var that = this,
  33889. $menu;
  33890. if (that.option("filterRow.showOperationChooser")) {
  33891. $container.addClass(DATAGRID_EDITOR_WITH_MENU_CLASS);
  33892. $menu = $('<div />').appendTo($container);
  33893. that._updateFilterOperationChooser($menu, column)
  33894. }
  33895. },
  33896. _getFilterOperationMenuItems: function(column) {
  33897. var that = this,
  33898. result = [{}],
  33899. filterRowOptions = that.option("filterRow"),
  33900. operationDescriptions = filterRowOptions && filterRowOptions.operationDescriptions || {};
  33901. if (column.filterOperations && column.filterOperations.length) {
  33902. result = $.map(column.filterOperations, function(value) {
  33903. return {
  33904. name: value,
  33905. selectable: true,
  33906. selected: (column.selectedFilterOperation || column.defaultFilterOperation) === value,
  33907. text: operationDescriptions[value],
  33908. icon: OPERATION_ICONS[value]
  33909. }
  33910. });
  33911. result.push({
  33912. name: null,
  33913. text: filterRowOptions && filterRowOptions.resetOperationText,
  33914. allowSelectOnclick: false,
  33915. icon: OPERATION_ICONS['default']
  33916. })
  33917. }
  33918. return result
  33919. },
  33920. _renderFilterRowCell: function(rootElement, column) {
  33921. var that = this,
  33922. $cell = $('<td />').toggleClass(column.cssClass, !utils.isDefined(column.groupIndex)).appendTo(rootElement),
  33923. columnsController = that._columnsController,
  33924. $container,
  33925. $editorContainer,
  33926. $editor;
  33927. var updateFilterValue = function(that, column, value) {
  33928. var filterOptions,
  33929. filterText = value;
  33930. if (value === '')
  33931. value = undefined;
  33932. if (!utils.isDefined(column.filterValue) && !utils.isDefined(value))
  33933. return;
  33934. column.filterValue = value;
  33935. columnsController.columnOption(column.initialIndex, 'filterValue', value)
  33936. };
  33937. if (column.command === 'empty')
  33938. $cell.html('&nbsp;');
  33939. else if (utils.isDefined(column.groupIndex))
  33940. $cell.addClass(DATAGRID_GROUP_SPACE_CLASS);
  33941. else if (column.allowFiltering) {
  33942. $cell.addClass(DATAGRID_EDITOR_CELL_CLASS);
  33943. $container = $('<div />').appendTo($cell);
  33944. $editorContainer = $('<div />').addClass(DATAGRID_EDITOR_CONTAINER_CLASS).appendTo($container);
  33945. $editor = $('<div />').appendTo($editorContainer);
  33946. that.getController('editorFactory').createEditor($editor, $.extend({}, column, {
  33947. value: columnsController.isDataSourceApplied() ? column.filterValue : undefined,
  33948. setValue: function(value) {
  33949. updateFilterValue(that, column, value)
  33950. },
  33951. parentType: "filterRow",
  33952. showAllText: that.option('filterRow.showAllText'),
  33953. width: null
  33954. }));
  33955. if (column.alignment)
  33956. $cell.find('input').first().css('text-align', column.alignment);
  33957. if (column.filterOperations && column.filterOperations.length)
  33958. that._renderFilterOperationChooser($container, column)
  33959. }
  33960. },
  33961. optionChanged: function(name, value, prevValue) {
  33962. var that = this;
  33963. switch (name) {
  33964. case'filterRow':
  33965. case'showColumnLines':
  33966. case'disabled':
  33967. that.render();
  33968. break;
  33969. default:
  33970. that.callBase(name);
  33971. break
  33972. }
  33973. }
  33974. };
  33975. var DataControllerFilterRowExtender = {_calculateAdditionalFilter: function() {
  33976. var that = this,
  33977. filter = that.callBase(),
  33978. i,
  33979. filters = [],
  33980. resultFilter = [],
  33981. columns = that._columnsController.getVisibleColumns();
  33982. $.each(columns, function() {
  33983. var filterOptions,
  33984. filter;
  33985. if (this.allowFiltering && this.calculateFilterExpression && utils.isDefined(this.filterValue)) {
  33986. filter = this.calculateFilterExpression(this.filterValue, this.selectedFilterOperation || this.defaultFilterOperation);
  33987. if (filter)
  33988. filters.push(filter)
  33989. }
  33990. });
  33991. if (filters.length) {
  33992. if (filter && filter.length)
  33993. filters.unshift(filter);
  33994. for (i = 0; i < filters.length; i++) {
  33995. if (i > 0)
  33996. resultFilter.push('and');
  33997. resultFilter.push(filters[i])
  33998. }
  33999. }
  34000. else
  34001. resultFilter = filter;
  34002. return resultFilter && resultFilter.length ? resultFilter : null
  34003. }};
  34004. var ColumnsControllerFilterRowExtender = {_createCalculatedColumnOptions: function(columnOptions) {
  34005. var calculatedColumnOptions = this.callBase(columnOptions);
  34006. if (columnOptions.dataField)
  34007. $.extend(calculatedColumnOptions, {
  34008. calculateFilterExpression: function(value, selectedFilterOperation) {
  34009. var column = this,
  34010. dataField = column.dataField,
  34011. filter = null;
  34012. if (utils.isDefined(value))
  34013. if (column.dataType === 'string' && !column.lookup)
  34014. filter = [dataField, selectedFilterOperation || 'contains', value];
  34015. else if (column.dataType === 'date') {
  34016. if (utils.isDate(value)) {
  34017. var dateStart = new Date(value.getFullYear(), value.getMonth(), value.getDate()),
  34018. dateEnd = new Date(value.getFullYear(), value.getMonth(), value.getDate() + 1);
  34019. switch (selectedFilterOperation) {
  34020. case'<':
  34021. return [dataField, '<', dateStart];
  34022. case'<=':
  34023. return [dataField, '<', dateEnd];
  34024. case'>':
  34025. return [dataField, '>=', dateEnd];
  34026. case'>=':
  34027. return [dataField, '>=', dateStart];
  34028. case'<>':
  34029. return [[dataField, '<', dateStart], 'or', [dataField, '>=', dateEnd]];
  34030. default:
  34031. return [[dataField, '>=', dateStart], 'and', [dataField, '<', dateEnd]]
  34032. }
  34033. }
  34034. }
  34035. else
  34036. filter = [dataField, selectedFilterOperation || '=', value];
  34037. return filter
  34038. },
  34039. allowFiltering: true
  34040. });
  34041. else
  34042. $.extend(calculatedColumnOptions, {allowFiltering: !!columnOptions.calculateFilterExpression});
  34043. return calculatedColumnOptions
  34044. }};
  34045. dataGrid.registerModule('filterRow', {
  34046. defaultOptions: function() {
  34047. return {filterRow: {
  34048. visible: false,
  34049. showOperationChooser: true,
  34050. showAllText: Globalize.localize("dxDataGrid-filterRowShowAllText"),
  34051. resetOperationText: Globalize.localize("dxDataGrid-filterRowResetOperationText"),
  34052. operationDescriptions: {
  34053. '=': Globalize.localize("dxDataGrid-filterRowOperationEquals"),
  34054. '<>': Globalize.localize("dxDataGrid-filterRowOperationNotEquals"),
  34055. '<': Globalize.localize("dxDataGrid-filterRowOperationLess"),
  34056. '<=': Globalize.localize("dxDataGrid-filterRowOperationLessOrEquals"),
  34057. '>': Globalize.localize("dxDataGrid-filterRowOperationGreater"),
  34058. '>=': Globalize.localize("dxDataGrid-filterRowOperationGreaterOrEquals"),
  34059. startswith: Globalize.localize("dxDataGrid-filterRowOperationStartsWith"),
  34060. contains: Globalize.localize("dxDataGrid-filterRowOperationContains"),
  34061. notcontains: Globalize.localize("dxDataGrid-filterRowOperationNotContains"),
  34062. endswith: Globalize.localize("dxDataGrid-filterRowOperationEndsWith")
  34063. }
  34064. }}
  34065. },
  34066. extenders: {
  34067. controllers: {
  34068. data: DataControllerFilterRowExtender,
  34069. columns: ColumnsControllerFilterRowExtender
  34070. },
  34071. views: {columnHeadersView: ColumnHeadersViewFilterRowExtender}
  34072. }
  34073. });
  34074. $.extend(dataGrid.__internals, {
  34075. DATAGRID_FILTER_ROW_CLASS: DATAGRID_FILTER_ROW_CLASS,
  34076. DATAGRID_MENU_CLASS: DATAGRID_MENU_CLASS,
  34077. DATAGRID_MENU_IMAGE_CLASS: DATAGRID_MENU_IMAGE_CLASS,
  34078. DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,
  34079. DATAGRID_EDITOR_WITH_MENU_CLASS: DATAGRID_EDITOR_WITH_MENU_CLASS,
  34080. DATAGRID_EDITOR_CONTAINER_CLASS: DATAGRID_EDITOR_CONTAINER_CLASS
  34081. });
  34082. dataGrid.ColumnHeadersViewFilterRowExtender = ColumnHeadersViewFilterRowExtender;
  34083. dataGrid.DataControllerFilterRowExtender = DataControllerFilterRowExtender
  34084. })(jQuery, DevExpress);
  34085. /*! Module widgets-web, file ui.dataGrid.headerPanel.js */
  34086. (function($, DX) {
  34087. var ui = DX.ui,
  34088. events = ui.events,
  34089. dataGrid = ui.dataGrid;
  34090. var DATAGRID_HEADER_PANEL_CLASS = "dx-datagrid-header-panel",
  34091. DATAGRID_GROUP_PANEL_CLASS = "dx-datagrid-group-panel",
  34092. DATAGRID_GROUP_PANEL_MESSAGE_CLASS = "dx-group-panel-message",
  34093. DATAGRID_GROUP_PANEL_ITEM_CLASS = "dx-group-panel-item",
  34094. DATAGRID_HEADERS_ACTION_CLASS = "dx-datagrid-action-cursor";
  34095. dataGrid.HeaderPanel = dataGrid.ColumnsView.inherit({
  34096. _renderGroupPanel: function() {
  34097. var that = this,
  34098. $element = that._element(),
  34099. groupPanelOptions = that.option("groupPanel"),
  34100. $groupPanel,
  34101. groupColumns = that.getController('columns').getGroupColumns();
  34102. $groupPanel = $element.find('.' + DATAGRID_GROUP_PANEL_CLASS);
  34103. if (groupPanelOptions && groupPanelOptions.visible) {
  34104. if (!$groupPanel.length)
  34105. $groupPanel = $('<div />').addClass(DATAGRID_GROUP_PANEL_CLASS).prependTo($element);
  34106. else
  34107. $groupPanel.show();
  34108. that._renderGroupPanelItems($groupPanel, groupColumns);
  34109. if (groupPanelOptions.allowColumnDragging && !groupColumns.length)
  34110. $('<div />').addClass(DATAGRID_GROUP_PANEL_MESSAGE_CLASS).text(groupPanelOptions.emptyPanelText).appendTo($groupPanel)
  34111. }
  34112. else
  34113. $groupPanel.hide()
  34114. },
  34115. _renderGroupPanelItems: function($groupPanel, groupColumns) {
  34116. var that = this,
  34117. $item;
  34118. $groupPanel.empty();
  34119. $.each(groupColumns, function(index, groupColumn) {
  34120. $item = $('<div />').addClass(groupColumn.cssClass).addClass(DATAGRID_GROUP_PANEL_ITEM_CLASS).toggleClass(DATAGRID_HEADERS_ACTION_CLASS, groupColumn.allowSorting || groupColumn.allowReordering).appendTo($groupPanel).text(groupColumn.caption).on(events.addNamespace("dxclick", "dxDataGridHeaderPanel"), that.createAction(function(e) {
  34121. setTimeout(function() {
  34122. that.getController('columns').changeSortOrder(groupColumn.index)
  34123. })
  34124. }));
  34125. that._applySorting($item, {
  34126. alignment: 'left',
  34127. sortOrder: groupColumn.sortOrder === 'desc' ? 'desc' : 'asc'
  34128. }, true)
  34129. });
  34130. that._updateSortIndicatorPositions($groupPanel)
  34131. },
  34132. _renderCore: function() {
  34133. var that = this;
  34134. that._element().addClass(DATAGRID_HEADER_PANEL_CLASS);
  34135. that._renderGroupPanel()
  34136. },
  34137. getHeaderPanel: function() {
  34138. return this._element()
  34139. },
  34140. allowDragging: function(column) {
  34141. var groupPanelOptions = this.option("groupPanel");
  34142. return groupPanelOptions && groupPanelOptions.visible && groupPanelOptions.allowColumnDragging && column && column.allowGrouping
  34143. },
  34144. getColumnElements: function() {
  34145. var $element = this._element();
  34146. return $element && $element.find('.' + DATAGRID_GROUP_PANEL_ITEM_CLASS)
  34147. },
  34148. getColumns: function() {
  34149. return this.getController('columns').getGroupColumns()
  34150. },
  34151. getBoundingRect: function() {
  34152. var that = this,
  34153. $element = that._element(),
  34154. offset;
  34155. if ($element && $element.find('.' + DATAGRID_GROUP_PANEL_CLASS).length) {
  34156. offset = $element.offset();
  34157. return {
  34158. top: offset.top,
  34159. bottom: offset.top + $element.height()
  34160. }
  34161. }
  34162. return null
  34163. },
  34164. getName: function() {
  34165. return 'group'
  34166. },
  34167. init: function() {
  34168. var that = this;
  34169. that.callBase();
  34170. that.getController('columns').columnsChanged.add(function(e) {
  34171. if (!dataGrid.checkChanges(e.optionNames, ['width']))
  34172. that.render()
  34173. })
  34174. },
  34175. isVisible: function() {
  34176. var groupPanelOptions = this.option('groupPanel');
  34177. return groupPanelOptions && groupPanelOptions.visible
  34178. },
  34179. getHeight: function() {
  34180. var $element = this._element();
  34181. return $element ? $element.outerHeight(true) : 0
  34182. },
  34183. optionChanged: function(name, value, prevValue) {
  34184. var that = this;
  34185. switch (name) {
  34186. case'searchPanel':
  34187. that._renderSearchPanel();
  34188. break;
  34189. case'groupPanel':
  34190. that._renderGroupPanel();
  34191. break;
  34192. case'disabled':
  34193. that.render();
  34194. break
  34195. }
  34196. },
  34197. resize: function() {
  34198. var that = this,
  34199. $element = that._element(),
  34200. $groupPanel = $element && $element.find('.' + DATAGRID_GROUP_PANEL_CLASS),
  34201. groupPanelOptions = that.option('groupPanel');
  34202. that.callBase();
  34203. that._updateSortIndicatorPositions($groupPanel)
  34204. }
  34205. });
  34206. $.extend(dataGrid.__internals, {
  34207. DATAGRID_HEADER_PANEL_CLASS: DATAGRID_HEADER_PANEL_CLASS,
  34208. DATAGRID_GROUP_PANEL_CLASS: DATAGRID_GROUP_PANEL_CLASS,
  34209. DATAGRID_GROUP_PANEL_MESSAGE_CLASS: DATAGRID_GROUP_PANEL_MESSAGE_CLASS,
  34210. DATAGRID_GROUP_PANEL_ITEM_CLASS: DATAGRID_GROUP_PANEL_ITEM_CLASS,
  34211. DATAGRID_HEADERS_ACTION_CLASS: DATAGRID_HEADERS_ACTION_CLASS
  34212. });
  34213. dataGrid.registerModule('headerPanel', {
  34214. defaultOptions: function() {
  34215. return {groupPanel: {
  34216. visible: false,
  34217. emptyPanelText: Globalize.localize("dxDataGrid-groupPanelEmptyText"),
  34218. allowColumnDragging: true
  34219. }}
  34220. },
  34221. views: {headerPanel: dataGrid.HeaderPanel}
  34222. })
  34223. })(jQuery, DevExpress);
  34224. /*! Module widgets-web, file ui.dataGrid.search.js */
  34225. (function($, DX) {
  34226. var ui = DX.ui,
  34227. events = ui.events,
  34228. utils = DX.utils,
  34229. dataGrid = ui.dataGrid;
  34230. var DATAGRID_SEARCH_PANEL_CLASS = "dx-datagrid-search-panel",
  34231. MARGIN_RIGHT = 10;
  34232. dataGrid.registerModule('search', {
  34233. defaultOptions: function() {
  34234. return {searchPanel: {
  34235. visible: false,
  34236. width: 160,
  34237. placeholder: Globalize.localize("dxDataGrid-searchPanelPlaceholder"),
  34238. highlightSearchText: true
  34239. }}
  34240. },
  34241. extenders: {
  34242. controllers: {data: function() {
  34243. var calculateSearchFilter = function(that, text) {
  34244. var i,
  34245. column,
  34246. columns = that._columnsController.getColumns(),
  34247. filter,
  34248. filterValue,
  34249. lookup,
  34250. searchFilter = [];
  34251. if (!text)
  34252. return null;
  34253. for (i = 0; i < columns.length; i++) {
  34254. filter = null;
  34255. column = columns[i];
  34256. if (column.allowFiltering && column.calculateFilterExpression) {
  34257. lookup = column.lookup;
  34258. if (lookup && lookup.items) {
  34259. filterValue = column.parseValue.call(lookup, text);
  34260. DX.data.query(lookup.items).filter(column.calculateFilterExpression.call({
  34261. dataField: lookup.displayExpr,
  34262. dataType: lookup.dataType
  34263. }, filterValue)).enumerate().done(function(items) {
  34264. var i,
  34265. valueGetter = DX.data.utils.compileGetter(lookup.valueExpr),
  34266. value;
  34267. for (i = 0; i < items.length; i++) {
  34268. if (searchFilter.length > 0)
  34269. searchFilter.push('or');
  34270. value = valueGetter(items[i]);
  34271. searchFilter.push(column.calculateFilterExpression(value))
  34272. }
  34273. })
  34274. }
  34275. else {
  34276. filterValue = column.parseValue ? column.parseValue(text) : text;
  34277. if (filterValue !== undefined) {
  34278. filter = column.calculateFilterExpression(filterValue);
  34279. if (filter) {
  34280. if (searchFilter.length > 0)
  34281. searchFilter.push('or');
  34282. searchFilter.push(filter)
  34283. }
  34284. }
  34285. }
  34286. }
  34287. }
  34288. return searchFilter
  34289. };
  34290. return {
  34291. publicMethods: function() {
  34292. return this.callBase().concat(['searchByText'])
  34293. },
  34294. _calculateAdditionalFilter: function() {
  34295. var that = this,
  34296. filter = that.callBase(),
  34297. searchFilter = calculateSearchFilter(that, that._searchText);
  34298. if (searchFilter)
  34299. if (filter)
  34300. filter = [filter, 'and', searchFilter];
  34301. else
  34302. filter = searchFilter;
  34303. return filter
  34304. },
  34305. searchByText: function(text) {
  34306. var that = this;
  34307. if (that._searchText !== text) {
  34308. that._searchText = text;
  34309. that._applyFilter()
  34310. }
  34311. },
  34312. getSearchText: function() {
  34313. return this._searchText || ''
  34314. }
  34315. }
  34316. }()},
  34317. views: {headerPanel: function() {
  34318. var getSearchPanelOptions = function(that) {
  34319. return that.option('searchPanel')
  34320. };
  34321. return {
  34322. _renderSearchPanel: function() {
  34323. var that = this,
  34324. $element = that._element(),
  34325. dataController = that.getController('data'),
  34326. searchPanelOptions = getSearchPanelOptions(that);
  34327. if (searchPanelOptions && searchPanelOptions.visible) {
  34328. if (!that._$searchPanel)
  34329. that._$searchPanel = $('<div/>').addClass(DATAGRID_SEARCH_PANEL_CLASS).prependTo($element);
  34330. else
  34331. that._$searchPanel.show();
  34332. that.getController('editorFactory').createEditor(that._$searchPanel, {
  34333. width: searchPanelOptions.width,
  34334. placeholder: searchPanelOptions.placeholder,
  34335. parentType: "searchPanel",
  34336. value: dataController.getSearchText(),
  34337. setValue: function(value) {
  34338. dataController.searchByText(value)
  34339. }
  34340. });
  34341. that.resize()
  34342. }
  34343. else
  34344. that._$searchPanel && that._$searchPanel.hide()
  34345. },
  34346. _renderCore: function() {
  34347. this.callBase();
  34348. this._renderSearchPanel()
  34349. },
  34350. focus: function() {
  34351. var textBox = this._$searchPanel.dxTextBox("instance");
  34352. if (textBox)
  34353. textBox.focus()
  34354. },
  34355. isVisible: function() {
  34356. var searchPanelOptions = getSearchPanelOptions(this);
  34357. return this.callBase() || searchPanelOptions && searchPanelOptions.visible
  34358. }
  34359. }
  34360. }()}
  34361. }
  34362. });
  34363. dataGrid.__internals = $.extend({}, dataGrid.__internals, {DATAGRID_SEARCH_PANEL_CLASS: DATAGRID_SEARCH_PANEL_CLASS})
  34364. })(jQuery, DevExpress);
  34365. /*! Module widgets-web, file ui.dataGrid.rowsView.js */
  34366. (function($, DX) {
  34367. var ui = DX.ui,
  34368. utils = DX.utils,
  34369. dataGrid = ui.dataGrid;
  34370. var DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",
  34371. DATAGRID_GROUP_ROW_CLASS = "dx-group-row",
  34372. DATAGRID_SEARCH_TEXT_CLASS = "dx-datagrid-search-text",
  34373. DATAGRID_ROWS_VIEW_CLASS = "dx-datagrid-rowsview",
  34374. DATAGRID_TABLE_CONTENT_CLASS = "dx-datagrid-table-content",
  34375. DATAGRID_TABLE_CLASS = "dx-datagrid-table",
  34376. DATAGRID_ROW_CLASS = "dx-row",
  34377. DATAGRID_DATA_ROW_CLASS = "dx-data-row",
  34378. DATAGRID_FREESPACE_CLASS = "dx-freespace-row",
  34379. DATAGRID_BOTTOM_LOAD_PANEL_CLASS = "dx-datagrid-bottom-load-panel",
  34380. DATAGRID_NODATA_TEXT_CLASS = "dx-datagrid-nodata",
  34381. DATAGRID_GROUP_SPACE_CLASS = "dx-datagrid-group-space",
  34382. DATAGRID_GROUP_OPENED_CLASS = "dx-datagrid-group-opened",
  34383. DATAGRID_GROUP_CLOSED_CLASS = "dx-datagrid-group-closed",
  34384. DATAGRID_CONTENT_CLASS = "dx-datagrid-content",
  34385. DATAGRID_NOWRAP_CLASS = "dx-datagrid-nowrap",
  34386. DATAGRID_ROW_LINES_CLASS = "dx-row-lines",
  34387. DATAGRID_COLUMN_LINES_CLASS = "dx-column-lines",
  34388. DATAGRID_ROW_ALTERNATION_CLASS = 'dx-row-alt',
  34389. DATAGRID_EDITOR_CELL_CLASS = "dx-editor-cell",
  34390. PIXELS_LIMIT = 250000,
  34391. DATAGRID_LOADPANEL_HIDE_TIMEOUT = 200;
  34392. var formatValue = function(value, options) {
  34393. var formatObject = {
  34394. value: value,
  34395. valueText: DX.formatHelper.format(value, options.format, options.precision) || ''
  34396. };
  34397. return options.customizeText ? options.customizeText.call(options, formatObject) : formatObject.valueText
  34398. };
  34399. var appendElementTemplate = {render: function(container, element) {
  34400. container.append(element)
  34401. }};
  34402. var createScrollableOptions = function(that) {
  34403. var useNativeScrolling = that.option("scrolling.useNativeScrolling");
  34404. var options = {
  34405. direction: "both",
  34406. rtlEnabled: that.option("rtlEnabled") || DX.rtlEnabled,
  34407. disabled: that.option("disabled"),
  34408. bounceEnabled: false,
  34409. useKeyboard: false
  34410. };
  34411. if (useNativeScrolling === undefined)
  34412. useNativeScrolling = true;
  34413. if (useNativeScrolling !== 'auto') {
  34414. options.useNative = !!useNativeScrolling;
  34415. options.useSimulatedScrollbar = !useNativeScrolling
  34416. }
  34417. return options
  34418. };
  34419. dataGrid.createScrollableOptions = createScrollableOptions;
  34420. dataGrid.RowsView = dataGrid.ColumnsView.inherit({
  34421. _getDefaultTemplate: function(column) {
  34422. var that = this;
  34423. switch (column.command) {
  34424. case"group":
  34425. return function(container, options) {
  34426. if (!utils.isDefined(options.value) || options.data && options.data.isContinuation)
  34427. container.addClass(DATAGRID_GROUP_SPACE_CLASS);
  34428. else
  34429. container.addClass(options.value ? DATAGRID_GROUP_OPENED_CLASS : DATAGRID_GROUP_CLOSED_CLASS).on('dxclick', that.createAction(function() {
  34430. that._dataController.changeGroupExpand(options.values)
  34431. }))
  34432. };
  34433. case"empty":
  34434. return function(container) {
  34435. container.html('&nbsp;')
  34436. };
  34437. default:
  34438. return function(container, options) {
  34439. var isDataTextEmpty = !options.text && options.rowType === "data",
  34440. text = isDataTextEmpty ? "&nbsp;" : options.text;
  34441. if (column.encodeHtml && !isDataTextEmpty)
  34442. container.text(text);
  34443. else
  34444. container.html(text)
  34445. }
  34446. }
  34447. },
  34448. _getDefaultGroupTemplate: function() {
  34449. var that = this;
  34450. return function(container, options) {
  34451. var data = options.data,
  34452. text = options.column.caption + ": " + options.text;
  34453. if (data)
  34454. if (options.groupContinuedMessage && options.groupContinuesMessage)
  34455. text += ' (' + options.groupContinuedMessage + '. ' + options.groupContinuesMessage + ')';
  34456. else if (options.groupContinuesMessage)
  34457. text += ' (' + options.groupContinuesMessage + ')';
  34458. else if (options.groupContinuedMessage)
  34459. text += ' (' + options.groupContinuedMessage + ')';
  34460. container.css('text-align', that.option('rtlEnabled') ? 'right' : 'left').text(text)
  34461. }
  34462. },
  34463. _update: function(change){},
  34464. _createRow: function(rowOptions) {
  34465. var $row = this.callBase(),
  34466. isGroup,
  34467. isDataRow;
  34468. if (rowOptions) {
  34469. isGroup = rowOptions.rowType === 'group';
  34470. isDataRow = rowOptions.rowType === 'data';
  34471. $row.toggleClass(DATAGRID_DATA_ROW_CLASS, isDataRow).toggleClass(DATAGRID_ROW_ALTERNATION_CLASS, isDataRow && rowOptions.dataIndex % 2 === 1 && this.option('rowAlternationEnabled')).toggleClass(DATAGRID_ROW_LINES_CLASS, isDataRow && this.option('showRowLines')).toggleClass(DATAGRID_COLUMN_LINES_CLASS, this.option('showColumnLines')).toggleClass(DATAGRID_GROUP_ROW_CLASS, isGroup)
  34472. }
  34473. return $row
  34474. },
  34475. _highlightSearchText: function(cellElement, isEquals) {
  34476. var that = this,
  34477. $parent,
  34478. searchHTML,
  34479. searchText = that._dataController.getSearchText();
  34480. if (searchText && that.option("searchPanel.highlightSearchText")) {
  34481. searchHTML = $('<div>').text(searchText).html();
  34482. $parent = cellElement.parent();
  34483. if (!$parent.length)
  34484. $parent = $('<div>').append(cellElement);
  34485. $.each($parent.find(":dxicontains('" + searchText + "')"), function(index, element) {
  34486. $.each($(element).contents(), function(index, content) {
  34487. if (content.nodeType !== 3)
  34488. return;
  34489. var highlightSearchTextInTextNode = function($content, searchText) {
  34490. var $searchTextSpan = $('<span />').addClass(DATAGRID_SEARCH_TEXT_CLASS),
  34491. text = $content.text(),
  34492. index = text.toLowerCase().indexOf(searchText.toLowerCase());
  34493. if (index >= 0) {
  34494. if ($content[0].textContent)
  34495. $content[0].textContent = text.substr(0, index);
  34496. else
  34497. $content[0].nodeValue = text.substr(0, index);
  34498. $content.after($searchTextSpan.text(text.substr(index, searchText.length)));
  34499. $content = $(document.createTextNode(text.substr(index + searchText.length))).insertAfter($searchTextSpan);
  34500. return highlightSearchTextInTextNode($content, searchText)
  34501. }
  34502. };
  34503. if (isEquals) {
  34504. if ($(content).text().toLowerCase() === searchText.toLowerCase())
  34505. $(this).replaceWith($('<span />').addClass(DATAGRID_SEARCH_TEXT_CLASS).text($(content).text()))
  34506. }
  34507. else
  34508. highlightSearchTextInTextNode($(content), searchText)
  34509. })
  34510. })
  34511. }
  34512. },
  34513. _renderTemplate: function(container, template, options) {
  34514. var that = this;
  34515. if ($.isFunction(template)) {
  34516. template(container, options);
  34517. return true
  34518. }
  34519. else if (utils.isString(template)) {
  34520. if (!that._templatesCache[template])
  34521. that._templatesCache[template] = that.getTemplate(template);
  34522. template = that._templatesCache[template];
  34523. if (template)
  34524. if (template.allowRenderToDetachedContainer) {
  34525. template.render(container, options);
  34526. return true
  34527. }
  34528. else
  34529. that._delayedTemplates.push({
  34530. template: template,
  34531. container: container,
  34532. options: options
  34533. })
  34534. }
  34535. return false
  34536. },
  34537. _getColumnTemplate: function(options) {
  34538. var that = this,
  34539. column = options.column,
  34540. template;
  34541. if (column.groupIndex !== undefined)
  34542. template = column.groupCellTemplate || that._getDefaultGroupTemplate();
  34543. else
  34544. template = column.cellTemplate || that._getDefaultTemplate(column);
  34545. return template
  34546. },
  34547. _updateCell: function($cell, parameters) {
  34548. var that = this,
  34549. column = parameters.column,
  34550. isEquals = column.dataType !== "string";
  34551. if (column.allowFiltering)
  34552. that._highlightSearchText($cell, isEquals);
  34553. if (parameters.rowType === "data" && column.groupIndex === undefined)
  34554. that._cellPrepared($cell, parameters)
  34555. },
  34556. _createCell: function(value, item, rowIndex, column, columnIndex) {
  34557. var that = this,
  34558. template,
  34559. groupingOptions = that.option('grouping'),
  34560. scrollingMode = this.option('scrolling.mode'),
  34561. data = item && item.data,
  34562. displayValue = column.lookup ? column.lookup.calculateCellValue(value) : value,
  34563. $cell = $('<td />').addClass(column.cssClass),
  34564. parameters = {
  34565. value: value,
  34566. displayValue: displayValue,
  34567. row: item,
  34568. key: item && item.key,
  34569. data: data,
  34570. rowType: item && item.rowType,
  34571. values: item && item.values,
  34572. text: formatValue(displayValue, column),
  34573. rowIndex: rowIndex,
  34574. columnIndex: columnIndex,
  34575. column: column,
  34576. resized: column.resizedCallbacks
  34577. };
  34578. if (utils.isDefined(column.groupIndex) && scrollingMode !== 'virtual' && scrollingMode !== 'infinite') {
  34579. parameters.groupContinuesMessage = data && data.isContinuationOnNextPage && groupingOptions && groupingOptions.groupContinuesMessage;
  34580. parameters.groupContinuedMessage = data && data.isContinuation && groupingOptions && groupingOptions.groupContinuedMessage
  34581. }
  34582. template = that._getColumnTemplate(parameters);
  34583. if (that._renderTemplate($cell, template, parameters))
  34584. that._updateCell($cell, parameters);
  34585. return $cell
  34586. },
  34587. _cellPrepared: function($cell, options) {
  34588. var that = this,
  34589. cellPrepared = that.option("cellPrepared"),
  34590. alignment = options.column.alignment,
  34591. extendOptions = function(event) {
  34592. return {
  34593. cellElement: $(event.target).closest('td'),
  34594. jQueryEvent: event,
  34595. eventType: event.type
  34596. }
  34597. };
  34598. if (alignment)
  34599. $cell[0].style.textAlign = alignment;
  34600. if (that.option("cellClick"))
  34601. $cell.on("dxclick", function(e) {
  34602. that.executeAction("cellClick", $.extend({}, options, extendOptions(e)))
  34603. });
  34604. if (that.option("cellHoverChanged")) {
  34605. $cell.on("mouseover", function(e) {
  34606. that.executeAction("cellHoverChanged", $.extend({}, options, extendOptions(e)))
  34607. });
  34608. $cell.on("mouseout", function(e) {
  34609. that.executeAction("cellHoverChanged", $.extend({}, options, extendOptions(e)))
  34610. })
  34611. }
  34612. if (utils.isFunction(cellPrepared))
  34613. cellPrepared($cell, options)
  34614. },
  34615. _rowPrepared: function($row, options) {
  34616. var that = this,
  34617. rowPrepared = that.option("rowPrepared");
  34618. if (utils.isFunction(rowPrepared))
  34619. rowPrepared($row, options)
  34620. },
  34621. _renderScrollable: function($table) {
  34622. var that = this,
  34623. $element = that._element();
  34624. if (!utils.isDefined(that._tableElement)) {
  34625. that._tableElement = $table;
  34626. if (!$element.children().length)
  34627. $element.append('<div />');
  34628. that._renderLoadPanel($element);
  34629. that._renderScrollableCore($element);
  34630. that._subscribeToWindowScrollEvents($element)
  34631. }
  34632. },
  34633. _renderScrollableCore: function($element) {
  34634. var that = this,
  34635. dxScrollableOptions = createScrollableOptions(that);
  34636. var scrollHandler = function(e) {
  34637. var $content = that._findContentElement();
  34638. if (that._hasHeight && that._rowHeight) {
  34639. that._scrollTop = e.scrollOffset.top;
  34640. that._dataController.setViewportItemIndex(that._scrollTop / that._rowHeight)
  34641. }
  34642. that.scrollOffsetChanged.fire(e.scrollOffset)
  34643. };
  34644. dxScrollableOptions.scrollAction = scrollHandler;
  34645. dxScrollableOptions.stopAction = scrollHandler;
  34646. $element.dxScrollable(dxScrollableOptions);
  34647. that._scrollable = $element.data('dxScrollable');
  34648. that._scrollableContainer = that._scrollable._$container
  34649. },
  34650. _renderLoadPanel: function($element) {
  34651. var that = this,
  34652. loadPanelOptions;
  34653. if ($element.dxLoadPanel) {
  34654. loadPanelOptions = that.option("loadPanel");
  34655. if (loadPanelOptions && loadPanelOptions.enabled) {
  34656. loadPanelOptions = $.extend({
  34657. shading: false,
  34658. message: loadPanelOptions.text,
  34659. position: {of: $element},
  34660. targetContainer: $element
  34661. }, loadPanelOptions);
  34662. if (that._loadPanel)
  34663. that._loadPanel.option(loadPanelOptions);
  34664. else
  34665. that._loadPanel = $('<div />').appendTo($element.parent()).dxLoadPanel(loadPanelOptions).dxLoadPanel('instance')
  34666. }
  34667. else {
  34668. that._loadPanel && that._loadPanel._element().remove();
  34669. that._loadPanel = null
  34670. }
  34671. }
  34672. },
  34673. _subscribeToWindowScrollEvents: function($element) {
  34674. var that = this,
  34675. disposing = that.disposing,
  34676. $componentContainer = that.component._element(),
  34677. $scrollElement;
  34678. if (!$componentContainer)
  34679. return;
  34680. if (!that._windowScrollEvents) {
  34681. that._windowScrollEvents = true;
  34682. var createWindowScrollHandler = function($scrollElement, oldHandler) {
  34683. var handler = function(e) {
  34684. var contentOffset,
  34685. scrollTop = $scrollElement.scrollTop();
  34686. if (!that._hasHeight && that._rowHeight) {
  34687. scrollTop -= $element.offset().top;
  34688. scrollTop = scrollTop > 0 ? scrollTop : 0;
  34689. that._scrollTop = scrollTop;
  34690. that._dataController.setViewportItemIndex(scrollTop / that._rowHeight)
  34691. }
  34692. };
  34693. if (oldHandler)
  34694. return function(e) {
  34695. handler(e);
  34696. oldHandler(e)
  34697. };
  34698. return handler
  34699. };
  34700. var subscribeToScrollEvents = function($scrollElement) {
  34701. var dxScrollable = $scrollElement.data("dxScrollable"),
  34702. scrollHandler,
  34703. oldScrollHandler;
  34704. if (dxScrollable) {
  34705. oldScrollHandler = dxScrollable.option('scrollAction');
  34706. scrollHandler = createWindowScrollHandler($scrollElement, oldScrollHandler);
  34707. dxScrollable.option('scrollAction', scrollHandler);
  34708. disposing && disposing.add(function() {
  34709. if (dxScrollable.option('scrollAction') === scrollHandler)
  34710. dxScrollable.option('scrollAction', oldScrollHandler)
  34711. })
  34712. }
  34713. else if ($scrollElement.is(document) || $scrollElement.css("overflow-y") === "auto") {
  34714. if ($scrollElement.is(document))
  34715. $scrollElement = $(window);
  34716. scrollHandler = createWindowScrollHandler($scrollElement);
  34717. $scrollElement.on('scroll', scrollHandler);
  34718. disposing && disposing.add(function() {
  34719. $scrollElement.off('scroll', scrollHandler)
  34720. })
  34721. }
  34722. };
  34723. for ($scrollElement = that.component._element().parent(); $scrollElement.length; $scrollElement = $scrollElement.parent())
  34724. subscribeToScrollEvents($scrollElement)
  34725. }
  34726. },
  34727. _renderContent: function(contentElement, tableElement) {
  34728. var that = this,
  34729. contentElement,
  34730. contentHeight,
  34731. virtualItemsCount = that._dataController.virtualItemsCount();
  34732. that._tableElement = tableElement;
  34733. contentElement.addClass(DATAGRID_CONTENT_CLASS);
  34734. if (virtualItemsCount) {
  34735. tableElement.addClass(DATAGRID_TABLE_CONTENT_CLASS);
  34736. if (!contentElement.children().length)
  34737. contentElement.append(tableElement);
  34738. else
  34739. contentElement.children().first().replaceWith(tableElement);
  34740. if (contentElement.children().length === 1) {
  34741. contentElement.append(that._createTable());
  34742. that._contentHeight = 0
  34743. }
  34744. }
  34745. else
  34746. contentElement.replaceWith($('<div>').addClass(DATAGRID_CONTENT_CLASS).append(tableElement));
  34747. return contentElement
  34748. },
  34749. _updateContentPosition: function() {
  34750. var that = this,
  34751. contentElement,
  34752. contentHeight,
  34753. rowHeight = that._rowHeight || 20,
  34754. virtualItemsCount = that._dataController.virtualItemsCount();
  34755. if (virtualItemsCount) {
  34756. contentElement = that._findContentElement();
  34757. DX.translator.move(contentElement.children().first(), {top: Math.floor(virtualItemsCount.begin * rowHeight)});
  34758. contentHeight = (virtualItemsCount.begin + virtualItemsCount.end) * rowHeight + contentElement.children().first().outerHeight();
  34759. if (that._contentHeight !== contentHeight || contentHeight === 0) {
  34760. that._contentHeight = contentHeight;
  34761. that._updateContainerHeight(contentElement.children().eq(1), contentHeight)
  34762. }
  34763. }
  34764. },
  34765. setColumnWidths: function(widths) {
  34766. this._setColumnWidthsCore(this._findContentElement().children(), widths)
  34767. },
  34768. _updateContent: function(tableElement, changeType) {
  34769. var that = this,
  34770. contentElement = that._findContentElement(),
  34771. rowHeight = that._rowHeight || 20,
  34772. contentTable,
  34773. virtualItemsCount = that._dataController.virtualItemsCount();
  34774. that.setColumnWidths();
  34775. if (changeType === 'append' || changeType === 'prepend') {
  34776. contentTable = contentElement.children().first();
  34777. tableElement.find('tr')[changeType === 'append' ? 'appendTo' : 'prependTo'](contentTable)
  34778. }
  34779. else
  34780. that._renderContent(contentElement, tableElement);
  34781. that._updateBottomLoading()
  34782. },
  34783. _renderFreeSpaceRow: function(tableElement, columns) {
  34784. var that = this,
  34785. i,
  34786. freeSpaceRowElement = that._createRow().hide(),
  34787. column;
  34788. freeSpaceRowElement.addClass(DATAGRID_FREESPACE_CLASS).toggleClass(DATAGRID_COLUMN_LINES_CLASS, that.option('showColumnLines'));
  34789. for (i = 0; i < columns.length; i++) {
  34790. column = {
  34791. command: utils.isDefined(columns[i].groupIndex) ? 'group' : '',
  34792. cssClass: utils.isDefined(columns[i].cssClass) ? columns[i].cssClass : ''
  34793. };
  34794. freeSpaceRowElement.append(that._createCell(null, null, null, column))
  34795. }
  34796. that._appendRow(tableElement, freeSpaceRowElement);
  34797. that._freeSpaceRowElement = freeSpaceRowElement
  34798. },
  34799. _updateRowHeight: function() {
  34800. var that = this,
  34801. tableHeight,
  34802. $element = that._element(),
  34803. itemsCount = that._dataController.items().length,
  34804. lastRowHight = that._rowHeight,
  34805. viewportHeight;
  34806. if ($element && itemsCount > 0 && (!lastRowHight || that.option('scrolling.mode') === 'infinite')) {
  34807. tableHeight = that._tableElement.outerHeight();
  34808. if (that._freeSpaceRowElement && that._freeSpaceRowElement.is(':visible'))
  34809. tableHeight -= that._freeSpaceRowElement.outerHeight();
  34810. that._rowHeight = tableHeight / itemsCount;
  34811. if (!lastRowHight && that._rowHeight) {
  34812. that._updateContentPosition();
  34813. viewportHeight = that._hasHeight ? $element.outerHeight() : $(window).outerHeight();
  34814. that._dataController.setViewportSize(Math.round(viewportHeight / that._rowHeight))
  34815. }
  34816. }
  34817. },
  34818. _updateContainerHeight: function(container, height) {
  34819. var that = this,
  34820. columns = that._columnsController.getVisibleColumns(),
  34821. html = container.find('colgroup').prop('outerHTML') || dataGrid.createColGroup(columns).prop('outerHTML'),
  34822. freeSpaceCellsHtml = '',
  34823. i,
  34824. columnLinesClass = that.option('showColumnLines') ? DATAGRID_COLUMN_LINES_CLASS : '',
  34825. createFreeSpaceRowHtml = function(height) {
  34826. return '<tr style="height:' + height + 'px;" class="' + DATAGRID_FREESPACE_CLASS + ' ' + DATAGRID_ROW_CLASS + ' ' + columnLinesClass + '" >' + freeSpaceCellsHtml + '</tr>'
  34827. };
  34828. for (i = 0; i < columns.length; i++)
  34829. freeSpaceCellsHtml += utils.isDefined(columns[i].groupIndex) ? '<td class="' + DATAGRID_GROUP_SPACE_CLASS + '"/>' : '<td />';
  34830. while (height > PIXELS_LIMIT) {
  34831. html += createFreeSpaceRowHtml(PIXELS_LIMIT);
  34832. height -= PIXELS_LIMIT
  34833. }
  34834. html += createFreeSpaceRowHtml(height);
  34835. container.addClass(DATAGRID_TABLE_CLASS);
  34836. container.html(html)
  34837. },
  34838. _findContentElement: function() {
  34839. var $element = this._element(),
  34840. $scrollableContent;
  34841. if ($element) {
  34842. $scrollableContent = $element.find('.dx-scrollable-content');
  34843. if (!$scrollableContent)
  34844. $scrollableContent = $element;
  34845. return $scrollableContent.children().first()
  34846. }
  34847. },
  34848. _findBottomLoadPanel: function() {
  34849. var $bottomLoadPanel = this._element().find('.' + DATAGRID_BOTTOM_LOAD_PANEL_CLASS);
  34850. if ($bottomLoadPanel.length)
  34851. return $bottomLoadPanel
  34852. },
  34853. _getRowElements: function() {
  34854. return this._element().find('.dx-row:not(.' + DATAGRID_FREESPACE_CLASS + ')')
  34855. },
  34856. _updateBottomLoading: function() {
  34857. var that = this,
  34858. scrollingOptions = that.option("scrolling"),
  34859. virtualMode = scrollingOptions && scrollingOptions.mode === 'virtual',
  34860. appendMode = scrollingOptions && scrollingOptions.mode === 'infinite',
  34861. showBottomLoading = !that._dataController.hasKnownLastPage() && that._dataController.isLoaded() && (virtualMode || appendMode),
  34862. bottomLoadPanelElement = that._findBottomLoadPanel();
  34863. if (showBottomLoading) {
  34864. bottomLoadPanelElement = bottomLoadPanelElement || $('<div />').addClass(DATAGRID_BOTTOM_LOAD_PANEL_CLASS).append($('<div />').dxLoadIndicator());
  34865. bottomLoadPanelElement.appendTo(that._findContentElement());
  34866. bottomLoadPanelElement.show()
  34867. }
  34868. else if (bottomLoadPanelElement)
  34869. bottomLoadPanelElement.hide()
  34870. },
  34871. _appendRow: function(tableElement, rowElement) {
  34872. var that = this;
  34873. if (that.option("rowTemplate") && that._delayedTemplates.length && rowElement)
  34874. that._delayedTemplates.push({
  34875. container: tableElement,
  34876. template: appendElementTemplate,
  34877. options: rowElement
  34878. });
  34879. else
  34880. tableElement.append(rowElement)
  34881. },
  34882. _updateNoDataText: function() {
  34883. var noDataElement = this._element().find('.' + DATAGRID_NODATA_TEXT_CLASS),
  34884. isVisible = !this._dataController.items().length,
  34885. isLoading = this._dataController.isLoading(),
  34886. rtlEnabled = this.option("rtlEnabled"),
  34887. noDataElementCSSConfig = {};
  34888. if (!noDataElement.length)
  34889. noDataElement = $('<span>').addClass(DATAGRID_NODATA_TEXT_CLASS).hide().appendTo(this._element());
  34890. noDataElement.text(this.option("noDataText"));
  34891. noDataElementCSSConfig = {
  34892. marginTop: -Math.floor(noDataElement.height() / 2),
  34893. marginRight: rtlEnabled ? -Math.floor(noDataElement.width() / 2) : 0,
  34894. marginLeft: rtlEnabled ? 0 : -Math.floor(noDataElement.width() / 2)
  34895. };
  34896. noDataElement.css(noDataElementCSSConfig);
  34897. if (isVisible && !isLoading)
  34898. noDataElement.show();
  34899. else
  34900. noDataElement.hide()
  34901. },
  34902. _createTable: function() {
  34903. var that = this;
  34904. return that.callBase().on("dxclick", '.dx-row', that.createAction(function(args) {
  34905. var e = args.jQueryEvent;
  34906. if (!$(e.target).closest('.' + DATAGRID_EDITOR_CELL_CLASS).length && !$(e.target).closest('a').length) {
  34907. that._rowClick(that.getRowIndex(e.currentTarget), e);
  34908. e.preventDefault()
  34909. }
  34910. }))
  34911. },
  34912. _rowClick: function(rowIndex, event) {
  34913. var item = this._dataController.items()[rowIndex] || {};
  34914. this.executeAction("rowClick", $.extend({
  34915. rowIndex: rowIndex,
  34916. columns: this._columnsController.getVisibleColumns(),
  34917. jQueryEvent: event,
  34918. rowElement: $(event.target).closest(".dx-row"),
  34919. evaluate: function(expr) {
  34920. var getter = DX.data.utils.compileGetter(expr);
  34921. return getter(item.data)
  34922. }
  34923. }, item))
  34924. },
  34925. _renderTable: function(items) {
  34926. var that = this,
  34927. itemsLength = items.length,
  34928. item,
  34929. $row,
  34930. $groupCell,
  34931. values,
  34932. columnsLength,
  34933. i,
  34934. j,
  34935. groupEmptyCellsCount,
  34936. $cells = [],
  34937. columnsCountBeforeGroups = 0,
  34938. columns = that._columnsController.getVisibleColumns(),
  34939. rowTemplate = that.option("rowTemplate"),
  34940. scrollingMode = that.option("scrolling.mode"),
  34941. $table = that._createTable();
  34942. $table.append(dataGrid.createColGroup(columns));
  34943. for (i = 0; i < columns.length; i++)
  34944. if (columns[i].groupIndex !== undefined) {
  34945. columnsCountBeforeGroups = i;
  34946. break
  34947. }
  34948. for (i = 0; i < itemsLength; i++) {
  34949. item = items[i];
  34950. item.rowIndex = i;
  34951. $cells = [];
  34952. if (item.groupIndex !== undefined) {
  34953. $row = that._createRow(item);
  34954. groupEmptyCellsCount = item.groupIndex + columnsCountBeforeGroups;
  34955. for (j = 0; j < groupEmptyCellsCount; j++)
  34956. $cells.push(that._createCell(null, item, i, {command: 'group'}));
  34957. if (columns[groupEmptyCellsCount].allowCollapsing && scrollingMode !== "infinite")
  34958. $cells.push(that._createCell(!!item.isExpanded, item, i, {command: 'group'}));
  34959. else
  34960. $cells.push(that._createCell(null, item, i, {command: 'group'}));
  34961. $groupCell = that._createCell(item.values[item.groupIndex], item, i, columns[groupEmptyCellsCount]);
  34962. $groupCell.attr('colspan', columns.length - groupEmptyCellsCount - 1);
  34963. $cells.push($groupCell)
  34964. }
  34965. else if (rowTemplate)
  34966. that._renderTemplate($table, rowTemplate, $.extend({columns: columns}, item));
  34967. else {
  34968. values = item.values;
  34969. columnsLength = columns.length;
  34970. $row = that._createRow(item);
  34971. for (j = 0; j < columnsLength; j++)
  34972. $cells.push(that._createCell(values[j], item, i, utils.isDefined(columns[j].groupIndex) ? {command: 'group'} : columns[j], j))
  34973. }
  34974. if ($cells.length)
  34975. $row.append($cells);
  34976. if ($row)
  34977. that._rowPrepared($row, $.extend({columns: columns}, item));
  34978. that._appendRow($table, $row)
  34979. }
  34980. if (rowTemplate)
  34981. that._highlightSearchText($table);
  34982. that._renderFreeSpaceRow($table, columns);
  34983. return $table
  34984. },
  34985. _renderCore: function(change) {
  34986. var that = this,
  34987. items = change && change.items || that._dataController.items(),
  34988. changeType = change && change.changeType,
  34989. $element = that._element(),
  34990. $root = $element.parent();
  34991. $element.addClass(DATAGRID_ROWS_VIEW_CLASS).toggleClass(DATAGRID_NOWRAP_CLASS, !that.option("wordWrapEnabled"));
  34992. var $table = that._renderTable(items);
  34993. that._renderScrollable($table);
  34994. that._updateContent($table, changeType);
  34995. if (!$root || $root.parent().length)
  34996. that.renderDelayedTemplates();
  34997. that._updateContentPosition();
  34998. that._lastColumnWidths = null
  34999. },
  35000. getRowIndex: function($row) {
  35001. return this._getRowElements().index($row)
  35002. },
  35003. getRow: function(index) {
  35004. var rows = this._getRowElements();
  35005. if (rows.length > index)
  35006. return $(rows[index])
  35007. },
  35008. getCell: function(columnIndex, rowIndex) {
  35009. var rows = this._getRowElements(),
  35010. cells;
  35011. if (rows.length > 0 && rowIndex >= 0) {
  35012. rowIndex = rowIndex < rows.length ? rowIndex : rows.length - 1;
  35013. cells = rows[rowIndex].cells;
  35014. if (cells && cells.length > 0)
  35015. return $(cells[cells.length > columnIndex ? columnIndex : cells.length - 1])
  35016. }
  35017. },
  35018. getTableFromCell: function($cell) {
  35019. return $cell.closest("." + DATAGRID_ROWS_VIEW_CLASS + " ." + DATAGRID_TABLE_CLASS)
  35020. },
  35021. updateFreeSpaceRowHeight: function() {
  35022. var that = this,
  35023. elementHeight,
  35024. contentElement = that._findContentElement(),
  35025. contentHeight = 0,
  35026. freespaceRowCount,
  35027. scrollingMode,
  35028. resultHeight;
  35029. if (that._freeSpaceRowElement && contentElement) {
  35030. that._freeSpaceRowElement.hide();
  35031. elementHeight = that._element().height();
  35032. contentHeight = contentElement.outerHeight();
  35033. resultHeight = elementHeight - contentHeight - that.getScrollbarWidth(true);
  35034. if (that._dataController.items().length > 0)
  35035. if (resultHeight > 0) {
  35036. that._freeSpaceRowElement.height(resultHeight);
  35037. that._freeSpaceRowElement.show()
  35038. }
  35039. else if (!that._hasHeight) {
  35040. freespaceRowCount = that._dataController.pageSize() - that._dataController.items().length;
  35041. scrollingMode = that.option('scrolling.mode');
  35042. if (freespaceRowCount > 0 && that._dataController.pageCount() > 1 && scrollingMode !== 'virtual' && scrollingMode !== 'infinite') {
  35043. that._freeSpaceRowElement.height(freespaceRowCount * that._rowHeight);
  35044. that._freeSpaceRowElement.show()
  35045. }
  35046. }
  35047. }
  35048. },
  35049. ctor: function(component) {
  35050. this.callBase(component);
  35051. this.scrollOffsetChanged = $.Callbacks()
  35052. },
  35053. init: function() {
  35054. var that = this,
  35055. visibleColumnIndex;
  35056. that.callBase();
  35057. that._editorFactoryController = that.getController("editorFactory");
  35058. that._editorFactoryController && that._editorFactoryController.focused.add(function($element) {
  35059. that._scrollable && that._scrollable.scrollToElement($element)
  35060. });
  35061. that._dataController = that.getController('data');
  35062. that._columnsController.columnsChanged.add(function(e) {
  35063. var editorFactory,
  35064. column,
  35065. $tables;
  35066. if (dataGrid.checkChanges(e.optionNames, ['width'])) {
  35067. column = e.column,
  35068. visibleColumnIndex = that._columnsController.getVisibleIndex(e.columnIndex);
  35069. if (visibleColumnIndex !== -1) {
  35070. $tables = that._findContentElement().children();
  35071. $.each($tables, function(key, table) {
  35072. $(table).find('col').eq(visibleColumnIndex).css('width', column.width)
  35073. });
  35074. if (e.column.resizedCallbacks)
  35075. e.column.resizedCallbacks.fire(column.width);
  35076. editorFactory = that.getController('editorFactory');
  35077. editorFactory && editorFactory.focus(editorFactory.focus())
  35078. }
  35079. }
  35080. });
  35081. that._rowHeight = 0;
  35082. that._scrollTop = 0;
  35083. that._hasHeight = false;
  35084. that._dataController.changed.add(function(change) {
  35085. switch (change.changeType) {
  35086. case'refresh':
  35087. case'prepend':
  35088. case'append':
  35089. that.render(null, change);
  35090. break;
  35091. default:
  35092. that._update(change);
  35093. break
  35094. }
  35095. });
  35096. that._dataController.loadingChanged.add(function(isLoading, messageText) {
  35097. that.setLoading(isLoading, messageText)
  35098. });
  35099. that._delayedTemplates = [];
  35100. that._templatesCache = {};
  35101. that.createAction("rowClick", {validatingTargetName: "rowElement"});
  35102. that.createAction("cellClick", {validatingTargetName: "cellElement"});
  35103. that.createAction("cellHoverChanged", {excludeValidators: ['gesture']})
  35104. },
  35105. publicMethods: function() {
  35106. return ['isScrollbarVisible', 'getTopVisibleRowData']
  35107. },
  35108. renderDelayedTemplates: function() {
  35109. var templateParameters,
  35110. delayedTemplates = this._delayedTemplates;
  35111. while (delayedTemplates.length) {
  35112. templateParameters = delayedTemplates.shift();
  35113. templateParameters.template.render(templateParameters.container, templateParameters.options);
  35114. if (templateParameters.options.column)
  35115. this._updateCell(templateParameters.container, templateParameters.options)
  35116. }
  35117. },
  35118. getScrollbarWidth: function(isHorizontal) {
  35119. var scrollableContainer = this._scrollableContainer && this._scrollableContainer.get(0),
  35120. scrollbarWidth = 0;
  35121. if (scrollableContainer)
  35122. if (!isHorizontal)
  35123. scrollbarWidth = scrollableContainer.offsetWidth - scrollableContainer.clientWidth;
  35124. else
  35125. scrollbarWidth = scrollableContainer.offsetHeight - scrollableContainer.clientHeight;
  35126. return scrollbarWidth
  35127. },
  35128. resize: function() {
  35129. var that = this,
  35130. lastColumnWidths = that._lastColumnWidths || [],
  35131. columnWidths = that.getColumnWidths(),
  35132. columns = that._columnsController.getVisibleColumns(),
  35133. dxScrollable,
  35134. i;
  35135. for (i = 0; i < columns.length; i++)
  35136. if (columns[i].resizedCallbacks && !utils.isDefined(columns[i].groupIndex) && lastColumnWidths[i] !== columnWidths[i])
  35137. columns[i].resizedCallbacks.fire(columnWidths[i]);
  35138. that._lastColumnWidths = columnWidths;
  35139. that._updateRowHeight();
  35140. that._updateNoDataText();
  35141. that.updateFreeSpaceRowHeight();
  35142. dxScrollable = that._element().data('dxScrollable');
  35143. if (dxScrollable)
  35144. dxScrollable.update();
  35145. that.callBase()
  35146. },
  35147. scrollToPage: function(pageIndex) {
  35148. var that = this,
  35149. scrollingMode = that.option('scrolling.mode'),
  35150. dataController = that._dataController,
  35151. pageSize = dataController ? dataController.pageSize() : 0,
  35152. scrollPosition;
  35153. if (scrollingMode === 'virtual' || scrollingMode === 'infinite')
  35154. scrollPosition = pageIndex * that._rowHeight * pageSize;
  35155. else
  35156. scrollPosition = 0;
  35157. that.scrollTo({
  35158. y: scrollPosition,
  35159. x: 0
  35160. })
  35161. },
  35162. scrollTo: function(location) {
  35163. var $element = this._element(),
  35164. dxScrollable = $element && $element.data('dxScrollable');
  35165. if (dxScrollable)
  35166. dxScrollable.scrollTo(location)
  35167. },
  35168. height: function(height) {
  35169. var that = this,
  35170. $element = this._element();
  35171. if (utils.isDefined(height)) {
  35172. that._hasHeight = height !== 'auto';
  35173. if ($element)
  35174. $element.height(height);
  35175. that._freeSpaceRowElement && that._freeSpaceRowElement.hide()
  35176. }
  35177. else
  35178. return $element ? $element.height() : 0
  35179. },
  35180. setLoading: function(isLoading, messageText) {
  35181. var that = this,
  35182. loadPanel = that._loadPanel,
  35183. dataController = that._dataController,
  35184. hasBottomLoadPanel = !!that._findBottomLoadPanel() && dataController.isLoaded(),
  35185. loadPanelOptions = that.option("loadPanel") || {},
  35186. animation = dataController.isLoaded() ? loadPanelOptions.animation : null,
  35187. visible = hasBottomLoadPanel ? false : isLoading,
  35188. visibilityOptions;
  35189. if (loadPanel) {
  35190. visibilityOptions = {
  35191. message: messageText || loadPanelOptions.text,
  35192. animation: animation,
  35193. visible: visible
  35194. };
  35195. clearTimeout(that._hideLoadingTimeoutID);
  35196. if (loadPanel.option('visible') && !visible)
  35197. that._hideLoadingTimeoutID = setTimeout(function() {
  35198. loadPanel.option(visibilityOptions)
  35199. }, DATAGRID_LOADPANEL_HIDE_TIMEOUT);
  35200. else
  35201. loadPanel.option(visibilityOptions);
  35202. that._updateNoDataText()
  35203. }
  35204. },
  35205. isScrollbarVisible: function() {
  35206. var $element = this._element();
  35207. return $element ? this._findContentElement().outerHeight() - $element.height() > 0 : false
  35208. },
  35209. setRowsOpacity: function(columnIndex, value) {
  35210. var that = this,
  35211. $rows = that._getRowElements().not('.' + DATAGRID_GROUP_ROW_CLASS) || [];
  35212. $.each($rows, function(_, row) {
  35213. $(row).children().eq(columnIndex).css({opacity: value})
  35214. })
  35215. },
  35216. getTopVisibleItemIndex: function() {
  35217. var that = this,
  35218. itemIndex,
  35219. prevOffsetTop = 0,
  35220. offsetTop = 0,
  35221. rowElements = that._getRowElements(),
  35222. scrollPosition = that._scrollTop,
  35223. contentElementOffsetTop = that._findContentElement().offset().top,
  35224. items = that._dataController.items();
  35225. for (itemIndex = 0; itemIndex < items.length; itemIndex++) {
  35226. prevOffsetTop = offsetTop;
  35227. offsetTop = rowElements.eq(itemIndex).offset().top - contentElementOffsetTop;
  35228. if (offsetTop > scrollPosition) {
  35229. if (scrollPosition * 2 < offsetTop + prevOffsetTop && itemIndex)
  35230. itemIndex--;
  35231. break
  35232. }
  35233. }
  35234. if (itemIndex && itemIndex === items.length)
  35235. itemIndex--;
  35236. return itemIndex
  35237. },
  35238. getTopVisibleRowData: function() {
  35239. var itemIndex = this.getTopVisibleItemIndex(),
  35240. items = this._dataController.items();
  35241. if (items[itemIndex])
  35242. return items[itemIndex].data
  35243. },
  35244. optionChanged: function(name, value, prevValue) {
  35245. var that = this;
  35246. switch (name) {
  35247. case'wordWrapEnabled':
  35248. case'hoverStateEnabled':
  35249. case'showColumnLines':
  35250. case'showRowLines':
  35251. case'rowAlternationEnabled':
  35252. case'rowTemplate':
  35253. case'cellPrepared':
  35254. case'rowPrepared':
  35255. that.render();
  35256. that.component.resize();
  35257. break;
  35258. case'scrolling':
  35259. case'rtlEnabled':
  35260. that._rowHeight = null;
  35261. that._tableElement = null;
  35262. break;
  35263. case"disabled":
  35264. case'loadPanel':
  35265. that._tableElement = null;
  35266. that.render();
  35267. that.component.resize();
  35268. break;
  35269. case'noDataText':
  35270. that._updateNoDataText();
  35271. break;
  35272. case'cellHoverChanged':
  35273. that.createAction("cellHoverChanged", {excludeValidators: ['gesture']});
  35274. that.render();
  35275. that.component.resize();
  35276. break;
  35277. case"rowClick":
  35278. that.createAction("rowClick", {validatingTargetName: "rowElement"});
  35279. break;
  35280. case"cellClick":
  35281. that.createAction("cellClick", {validatingTargetName: "cellElement"});
  35282. break
  35283. }
  35284. },
  35285. dispose: function() {
  35286. clearTimeout(this._hideLoadingTimeoutID)
  35287. }
  35288. });
  35289. dataGrid.formatValue = formatValue;
  35290. $.extend(dataGrid.__internals, {
  35291. DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,
  35292. DATAGRID_GROUP_ROW_CLASS: DATAGRID_GROUP_ROW_CLASS,
  35293. DATAGRID_SEARCH_TEXT_CLASS: DATAGRID_SEARCH_TEXT_CLASS,
  35294. DATAGRID_ROWS_VIEW_CLASS: DATAGRID_ROWS_VIEW_CLASS,
  35295. DATAGRID_TABLE_CLASS: DATAGRID_TABLE_CLASS,
  35296. DATAGRID_FREESPACE_CLASS: DATAGRID_FREESPACE_CLASS,
  35297. DATAGRID_BOTTOM_LOAD_PANEL_CLASS: DATAGRID_BOTTOM_LOAD_PANEL_CLASS,
  35298. DATAGRID_NODATA_TEXT_CLASS: DATAGRID_NODATA_TEXT_CLASS,
  35299. DATAGRID_GROUP_SPACE_CLASS: DATAGRID_GROUP_SPACE_CLASS,
  35300. DATAGRID_GROUP_OPENED_CLASS: DATAGRID_GROUP_OPENED_CLASS,
  35301. DATAGRID_GROUP_CLOSED_CLASS: DATAGRID_GROUP_CLOSED_CLASS,
  35302. DATAGRID_NOWRAP_CLASS: DATAGRID_NOWRAP_CLASS,
  35303. DATAGRID_ROW_LINES_CLASS: DATAGRID_ROW_LINES_CLASS,
  35304. DATAGRID_COLUMN_LINES_CLASS: DATAGRID_COLUMN_LINES_CLASS,
  35305. DATAGRID_ROW_ALTERNATION_CLASS: DATAGRID_ROW_ALTERNATION_CLASS
  35306. });
  35307. dataGrid.registerModule('rows', {
  35308. defaultOptions: function() {
  35309. return {
  35310. hoverStateEnabled: false,
  35311. cellHoverChanged: null,
  35312. scrolling: {
  35313. mode: 'standard',
  35314. preloadEnabled: false,
  35315. useNativeScrolling: 'auto'
  35316. },
  35317. loadPanel: {
  35318. enabled: true,
  35319. text: Globalize.localize("Loading"),
  35320. width: 200,
  35321. height: 70,
  35322. showIndicator: true,
  35323. indicatorSrc: "",
  35324. showPane: true
  35325. },
  35326. rowClick: null,
  35327. cellClick: null,
  35328. rowTemplate: null,
  35329. columnAutoWidth: false,
  35330. noDataText: Globalize.localize("dxDataGrid-noDataText"),
  35331. wordWrapEnabled: false,
  35332. showColumnLines: true,
  35333. showRowLines: false,
  35334. rowAlternationEnabled: false,
  35335. cellPrepared: null,
  35336. rowPrepared: null,
  35337. activeStateEnabled: false
  35338. }
  35339. },
  35340. views: {rowsView: dataGrid.RowsView},
  35341. extenders: {controllers: {data: {
  35342. _applyFilter: function() {
  35343. var that = this,
  35344. result = that.callBase();
  35345. if (result && result.done)
  35346. result.done(function() {
  35347. that.getView('rowsView').scrollToPage(0)
  35348. });
  35349. return result
  35350. },
  35351. pageIndex: function(value) {
  35352. var that = this,
  35353. result = that.callBase(value);
  35354. if (result && result.done)
  35355. result.done(function() {
  35356. that.getView('rowsView').scrollToPage(that.pageIndex())
  35357. });
  35358. return result
  35359. },
  35360. pageSize: function(value) {
  35361. var that = this,
  35362. result = that.callBase(value);
  35363. if (result && result.done)
  35364. result.done(function() {
  35365. that.getView('rowsView').scrollToPage(that.pageIndex())
  35366. });
  35367. return result
  35368. },
  35369. _refreshDataSource: function() {
  35370. var that = this;
  35371. var changedHandler = function() {
  35372. that.changed.remove(changedHandler);
  35373. that.getView('rowsView').scrollToPage(0)
  35374. };
  35375. that.changed.add(changedHandler);
  35376. that.callBase()
  35377. }
  35378. }}}
  35379. })
  35380. })(jQuery, DevExpress);
  35381. /*! Module widgets-web, file ui.dataGrid.pager.js */
  35382. (function($, DX) {
  35383. var ui = DX.ui,
  35384. events = ui.events,
  35385. utils = DX.utils,
  35386. dataGrid = ui.dataGrid;
  35387. var DATAGRID_PAGER_CLASS = "dx-datagrid-pager";
  35388. var MAX_PAGES_COUNT = 10;
  35389. dataGrid.PagerView = dataGrid.View.inherit({
  35390. init: function() {
  35391. var that = this,
  35392. dataController = that.getController('data');
  35393. that._isVisible = false;
  35394. dataController.changed.add(function() {
  35395. that.render()
  35396. })
  35397. },
  35398. _getPager: function() {
  35399. var $element = this._element();
  35400. return $element && $element.data('dxPager')
  35401. },
  35402. _renderCore: function() {
  35403. var that = this,
  35404. $element = that._element().addClass(DATAGRID_PAGER_CLASS),
  35405. pagerOptions = that.option('pager'),
  35406. dataController = that.getController('data'),
  35407. rtlEnabled = that.option('rtlEnabled');
  35408. $element.dxPager({
  35409. maxPagesCount: MAX_PAGES_COUNT,
  35410. pageIndex: dataController.pageIndex() + 1,
  35411. pagesCount: dataController.pageCount(),
  35412. pageSize: dataController.pageSize(),
  35413. showPageSizes: pagerOptions && pagerOptions.showPageSizeSelector,
  35414. pageSizes: that.getPageSizes(),
  35415. rtlEnabled: rtlEnabled,
  35416. hasKnownLastPage: dataController.hasKnownLastPage(),
  35417. pageIndexChanged: function(pageIndex) {
  35418. window.setTimeout(function() {
  35419. dataController.pageIndex(pageIndex - 1)
  35420. })
  35421. },
  35422. pageSizeChanged: function(pageSize) {
  35423. window.setTimeout(function() {
  35424. dataController.pageSize(pageSize)
  35425. })
  35426. }
  35427. })
  35428. },
  35429. getPageSizes: function() {
  35430. var that = this,
  35431. dataController = that.getController('data'),
  35432. pagerOptions = that.option('pager'),
  35433. allowedPageSizes = pagerOptions && pagerOptions.allowedPageSizes,
  35434. pageSize = dataController.pageSize();
  35435. if (!utils.isDefined(that._pageSizes) || $.inArray(pageSize, that._pageSizes) === -1) {
  35436. that._pageSizes = [];
  35437. if (pagerOptions)
  35438. if ($.isArray(allowedPageSizes))
  35439. that._pageSizes = allowedPageSizes;
  35440. else if (allowedPageSizes && pageSize > 1)
  35441. that._pageSizes = [Math.floor(pageSize / 2), pageSize, pageSize * 2]
  35442. }
  35443. return that._pageSizes
  35444. },
  35445. isVisible: function() {
  35446. var that = this,
  35447. dataController = that.getController('data'),
  35448. pagerOptions = that.option('pager'),
  35449. pagerVisible = pagerOptions && pagerOptions.visible,
  35450. scrolling = that.option('scrolling');
  35451. if (that._isVisible)
  35452. return true;
  35453. if (pagerVisible === 'auto')
  35454. if (scrolling && (scrolling.mode === 'virtual' || scrolling.mode === 'infinite'))
  35455. pagerVisible = false;
  35456. else
  35457. pagerVisible = dataController.pageCount() > 1 || dataController.isLoaded() && !dataController.hasKnownLastPage();
  35458. that._isVisible = pagerVisible;
  35459. return pagerVisible
  35460. },
  35461. getHeight: function() {
  35462. var pager = this._getPager();
  35463. return pager && this.isVisible() ? pager.getHeight() : 0
  35464. },
  35465. optionChanged: function(name, value, prevValue) {
  35466. var that = this;
  35467. switch (name) {
  35468. case'paging':
  35469. case'pager':
  35470. that._pageSizes = null;
  35471. case'scrolling':
  35472. that._isVisible = false;
  35473. that.render();
  35474. if (name === 'pager')
  35475. that.component && that.component.resize();
  35476. break
  35477. }
  35478. }
  35479. });
  35480. dataGrid.registerModule('pager', {
  35481. defaultOptions: function() {
  35482. return {
  35483. paging: {
  35484. enabled: true,
  35485. pageSize: undefined,
  35486. pageIndex: undefined
  35487. },
  35488. pager: {
  35489. visible: 'auto',
  35490. showPageSizeSelector: false,
  35491. allowedPageSizes: 'auto'
  35492. }
  35493. }
  35494. },
  35495. views: {pagerView: dataGrid.PagerView}
  35496. })
  35497. })(jQuery, DevExpress);
  35498. /*! Module widgets-web, file ui.dataGrid.gridView.js */
  35499. (function($, DX) {
  35500. var dataGrid = DX.ui.dataGrid,
  35501. utils = DX.utils;
  35502. var DATAGRID_CLASS = "dx-datagrid",
  35503. EMPTY_GRID_ROWS_HEIGHT = 100,
  35504. LOADPANEL_MARGIN = 50,
  35505. VIEW_NAMES = ['columnsSeparatorView', 'blockSeparatorView', 'trackerView', 'headerPanel', 'columnHeadersView', 'rowsView', 'columnChooserView', 'pagerView', 'draggingHeaderView', 'contextMenuView', 'errorView'];
  35506. var mergeArraysByMaxValue = function(values1, values2) {
  35507. var result = [],
  35508. i;
  35509. if (values1 && values2 && values1.length && values1.length === values2.length)
  35510. for (i = 0; i < values1.length; i++)
  35511. result.push(values1[i] > values2[i] ? values1[i] : values2[i]);
  35512. return result
  35513. };
  35514. var isPercentWidth = function(width) {
  35515. return utils.isString(width) && width.slice(-1) === '%'
  35516. };
  35517. dataGrid.createColGroup = function(columns) {
  35518. var colgroupElement = $('<colgroup />'),
  35519. columnsLength = columns.length,
  35520. i;
  35521. for (i = 0; i < columnsLength; i++)
  35522. $('<col />').width(columns[i].width).appendTo(colgroupElement);
  35523. return colgroupElement
  35524. };
  35525. dataGrid.GridView = dataGrid.View.inherit({
  35526. _initResizeHandlers: function() {
  35527. var that = this;
  35528. if (!that._refreshSizesHandler) {
  35529. that._refreshSizesHandler = function(e) {
  35530. if (!e || e.changeType === 'refresh' || e.changeType === 'append')
  35531. that.resize()
  35532. };
  35533. that._dataController.changed.add(that._refreshSizesHandler);
  35534. that._columnHeadersView.sizeChanged.add(that._refreshSizesHandler)
  35535. }
  35536. },
  35537. _synchronizeColumns: function() {
  35538. var that = this,
  35539. rowsColumnWidths = that._rowsView.getColumnWidths(),
  35540. headerColumnWidths = that._columnHeadersView.getColumnWidths(),
  35541. unusedIndexes = {length: 0},
  35542. hasAutoWidth = false,
  35543. hasPercentWidth = false,
  35544. $element = that.component._element(),
  35545. width = that.option('width'),
  35546. resultWidths = headerColumnWidths ? mergeArraysByMaxValue(rowsColumnWidths, headerColumnWidths) : rowsColumnWidths;
  35547. $.each(that._columnsController.getVisibleColumns(), function(index) {
  35548. if (!this.width || this.width === 'auto')
  35549. hasAutoWidth = true;
  35550. if (isPercentWidth(this.width))
  35551. hasPercentWidth = true;
  35552. if (this.width && this.width !== 'auto') {
  35553. resultWidths[index] = this.width;
  35554. unusedIndexes[index] = true;
  35555. unusedIndexes.length++
  35556. }
  35557. });
  35558. if ($element && that._maxWidth) {
  35559. delete that._maxWidth;
  35560. $element.css('max-width', '')
  35561. }
  35562. if (!hasAutoWidth && resultWidths.length) {
  35563. var totalWidth = that._getTotalWidth(resultWidths, that._groupElement.width() - that._rowsView.getScrollbarWidth());
  35564. if (totalWidth < that._groupElement.width() - that._rowsView.getScrollbarWidth()) {
  35565. resultWidths[resultWidths.length - 1] = 'auto';
  35566. if ((!width || width === 'auto') && !hasPercentWidth) {
  35567. that._maxWidth = totalWidth;
  35568. $element.css('max-width', that._maxWidth)
  35569. }
  35570. }
  35571. }
  35572. if (that.option('columnAutoWidth') && resultWidths.length > 0)
  35573. that._processStretch(resultWidths, that._groupElement.width() - that._rowsView.getScrollbarWidth(), unusedIndexes);
  35574. that._rowsView.setColumnWidths(resultWidths);
  35575. that._columnHeadersView.setColumnWidths(resultWidths)
  35576. },
  35577. _processStretch: function(resultSizes, groupSize, unusedIndexes) {
  35578. var tableSize = this._getTotalWidth(resultSizes, groupSize),
  35579. diff,
  35580. diffElement,
  35581. onePixelElementsCount,
  35582. i;
  35583. diff = groupSize - tableSize;
  35584. diffElement = Math.floor(diff / (resultSizes.length - unusedIndexes.length));
  35585. onePixelElementsCount = diff - diffElement * (resultSizes.length - unusedIndexes.length);
  35586. if (diff >= 0)
  35587. for (i = 0; i < resultSizes.length; i++) {
  35588. if (unusedIndexes[i])
  35589. continue;
  35590. resultSizes[i] += diffElement;
  35591. if (i < onePixelElementsCount)
  35592. resultSizes[i]++
  35593. }
  35594. },
  35595. _getTotalWidth: function(widths, groupWidth) {
  35596. var result = 0,
  35597. width,
  35598. i;
  35599. for (i = 0; i < widths.length; i++) {
  35600. width = widths[i];
  35601. if (width)
  35602. result += isPercentWidth(width) ? parseInt(width) * groupWidth / 100 : parseInt(width)
  35603. }
  35604. return Math.round(result)
  35605. },
  35606. getView: function(name) {
  35607. return this.component._views[name]
  35608. },
  35609. getViews: function() {
  35610. return this.component._views
  35611. },
  35612. resize: function() {
  35613. var that = this,
  35614. dataController = that._dataController,
  35615. rootElementHeight = that._rootElement.height(),
  35616. loadPanelOptions = that.option('loadPanel'),
  35617. height = that.option('height'),
  35618. rowsViewHeight,
  35619. $testDiv;
  35620. if (height && that._hasHeight ^ height !== 'auto') {
  35621. $testDiv = $('<div>').height(height).appendTo(that._rootElement);
  35622. that._hasHeight = !!$testDiv.height();
  35623. $testDiv.remove()
  35624. }
  35625. if (that._hasHeight && rootElementHeight > 0 && that.option('scrolling'))
  35626. that._rowsView.height(rootElementHeight - that._headerPanel.getHeight() - that._columnHeadersView.getHeight() - that._pagerView.getHeight());
  35627. else if (!that._hasHeight && dataController.items().length === 0)
  35628. rowsViewHeight = loadPanelOptions && loadPanelOptions.visible ? loadPanelOptions.height + LOADPANEL_MARGIN : EMPTY_GRID_ROWS_HEIGHT;
  35629. else
  35630. rowsViewHeight = 'auto';
  35631. that._rowsView.height(rowsViewHeight);
  35632. that._rowsView.resetColumnWidths();
  35633. that._columnHeadersView.resetColumnWidths();
  35634. that._columnHeadersView.setScrollerSpacing(that._rowsView.getScrollbarWidth());
  35635. that._synchronizeColumns();
  35636. $.each(VIEW_NAMES, function(index, viewName) {
  35637. var view = that.getView(viewName);
  35638. if (view)
  35639. view.resize()
  35640. })
  35641. },
  35642. optionChanged: function(name, value, prevValue) {
  35643. switch (name) {
  35644. case"width":
  35645. case"height":
  35646. this.resize()
  35647. }
  35648. },
  35649. init: function() {
  35650. var that = this;
  35651. that._dataController = that.getController('data');
  35652. that._columnsController = that.getController('columns');
  35653. that._columnHeadersView = that.getView('columnHeadersView');
  35654. that._headerPanel = that.getView('headerPanel');
  35655. that._rowsView = that.getView('rowsView');
  35656. that._pagerView = that.getView('pagerView');
  35657. that._rowsView.scrollOffsetChanged.add(function(e) {
  35658. that._columnHeadersView.scrollOffset(e.left)
  35659. });
  35660. that._dataController.changed.add(function() {
  35661. that.component._fireContentReadyAction()
  35662. });
  35663. that._options = {}
  35664. },
  35665. element: function() {
  35666. return this._groupElement
  35667. },
  35668. render: function(rootElement) {
  35669. var that = this,
  35670. isFirstRender,
  35671. isLoading,
  35672. groupElement = that._groupElement || $('<div />').addClass(DATAGRID_CLASS);
  35673. that._rootElement = rootElement || that._rootElement;
  35674. isFirstRender = !that._groupElement;
  35675. that._groupElement = groupElement;
  35676. $.each(VIEW_NAMES, function(index, viewName) {
  35677. var view = that.getView(viewName);
  35678. if (view)
  35679. view.render(groupElement)
  35680. });
  35681. if (isFirstRender) {
  35682. that._hasHeight = !!that._rootElement.height();
  35683. that._groupElement = groupElement;
  35684. groupElement.appendTo(that._rootElement);
  35685. that._rowsView.renderDelayedTemplates()
  35686. }
  35687. that._initResizeHandlers();
  35688. that.resize();
  35689. isLoading = that._dataController.isLoading();
  35690. if (!isLoading)
  35691. that.component._fireContentReadyAction();
  35692. that._rowsView.setLoading(isLoading)
  35693. }
  35694. });
  35695. dataGrid.registerModule("gridView", {views: {gridView: dataGrid.GridView}});
  35696. $.extend(dataGrid.__internals, {
  35697. viewNames: VIEW_NAMES,
  35698. DATAGRID_CLASS: DATAGRID_CLASS
  35699. })
  35700. })(jQuery, DevExpress);
  35701. /*! Module widgets-web, file ui.dataGrid.columnsResizingReorderingModule.js */
  35702. (function($, DX) {
  35703. var ui = DX.ui,
  35704. events = ui.events,
  35705. addNamespace = events.addNamespace,
  35706. utils = DX.utils,
  35707. dataGrid = ui.dataGrid,
  35708. fx = DX.fx;
  35709. var DATAGRID_COLUMNS_SEPARATOR_CLASS = "dx-datagrid-columns-separator",
  35710. DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT = "dx-datagrid-columns-separator-transparent",
  35711. DATAGRID_DRAGGING_HEADER_CLASS = "dx-datagrid-drag-header",
  35712. DATAGRID_CELL_CONTENT_CLASS = "dx-datagrid-text-content",
  35713. DATAGTID_HEADERS_ACTION_CLASS = "dx-datagrid-action-cursor",
  35714. DATAGRID_TRACKER_CLASS = "dx-datagrid-tracker",
  35715. DATAGRID_BLOCK_SEPARATOR_CLASS = "dx-block-separator",
  35716. DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS = 'dx-datagrid-drop-highlight',
  35717. DATAGRID_HEADER_ROW_CLASS = "dx-header-row",
  35718. WIDGET_CLASS = "dx-widget",
  35719. DATAGRID_MODULE_NAMESPACE = "dxDataGridResizingReordering",
  35720. COLUMNS_SEPARATOR_TOUCH_TRACKER_WIDTH = 10,
  35721. DRAGGING_DELTA = 5;
  35722. var allowResizing = function(that) {
  35723. return that.option("allowColumnResizing") || that.getController("columns").isColumnOptionUsed("allowResizing")
  35724. };
  35725. var allowReordering = function(that) {
  35726. return that.option("allowColumnReordering") || that.getController("columns").isColumnOptionUsed("allowReordering")
  35727. };
  35728. dataGrid.getPointsByColumns = function(items, pointCreated, isVertical) {
  35729. var cellsLength = items.length,
  35730. cancel = false,
  35731. i,
  35732. point,
  35733. item,
  35734. offset,
  35735. result = [],
  35736. rtlEnabled,
  35737. columnIndex = 0;
  35738. for (i = 0; i <= cellsLength; i++) {
  35739. if (i < cellsLength) {
  35740. item = items.eq(columnIndex);
  35741. offset = item.offset();
  35742. rtlEnabled = item.css('direction') === 'rtl'
  35743. }
  35744. point = {
  35745. index: i,
  35746. x: offset ? offset.left + (!isVertical && rtlEnabled ^ i === cellsLength ? item.outerWidth() : 0) : 0,
  35747. y: offset ? offset.top + (isVertical && i === cellsLength ? item.outerHeight() : 0) : 0,
  35748. columnIndex: columnIndex
  35749. };
  35750. if (pointCreated)
  35751. cancel = pointCreated(point);
  35752. if (!cancel)
  35753. result.push(point);
  35754. columnIndex++
  35755. }
  35756. return result
  35757. };
  35758. dataGrid.TrackerView = dataGrid.View.inherit({
  35759. _renderCore: function(options) {
  35760. this.callBase();
  35761. this._element().addClass(DATAGRID_TRACKER_CLASS);
  35762. this.hide()
  35763. },
  35764. init: function() {
  35765. var that = this,
  35766. $element;
  35767. that.callBase();
  35768. that.getController("tablePosition").positionChanged.add(function(position) {
  35769. $element = that._element();
  35770. if ($element && $element.hasClass(DATAGRID_TRACKER_CLASS)) {
  35771. $element.css({top: position.top});
  35772. $element.height(position.height)
  35773. }
  35774. })
  35775. },
  35776. isVisible: function() {
  35777. return allowResizing(this)
  35778. },
  35779. show: function() {
  35780. this._element().show()
  35781. },
  35782. hide: function() {
  35783. this._element().hide()
  35784. },
  35785. setHeight: function(value) {
  35786. this._element().height(value)
  35787. }
  35788. });
  35789. dataGrid.ColumnsSeparatorView = dataGrid.View.inherit({
  35790. _isShown: true,
  35791. _renderCore: function(options) {
  35792. this.callBase(options);
  35793. this._element().addClass(DATAGRID_COLUMNS_SEPARATOR_CLASS);
  35794. this._isShown = true;
  35795. this.hide()
  35796. },
  35797. _subscribeToEvent: function() {
  35798. var that = this,
  35799. $element;
  35800. that.getController("tablePosition").positionChanged.add(function(position) {
  35801. $element = that._element();
  35802. if ($element) {
  35803. $element.css({top: position.top});
  35804. $element.height(position.height)
  35805. }
  35806. })
  35807. },
  35808. isVisible: function() {
  35809. return this.option('showColumnHeaders') && (allowReordering(this) || allowResizing(this))
  35810. },
  35811. init: function() {
  35812. this.callBase();
  35813. this._isTransparent = allowResizing(this);
  35814. if (this.isVisible())
  35815. this._subscribeToEvent()
  35816. },
  35817. show: function(targetLocation) {
  35818. var that = this,
  35819. $element = this._element(),
  35820. startAnimate = function(toOptions) {
  35821. fx.stop($element, true);
  35822. fx.animate($element, {
  35823. type: "slide",
  35824. from: {
  35825. width: 0,
  35826. display: toOptions.display
  35827. },
  35828. to: toOptions,
  35829. duration: 300,
  35830. easing: "swing"
  35831. })
  35832. };
  35833. if ($element && !that._isShown)
  35834. if (targetLocation === "group")
  35835. startAnimate({
  35836. width: "50px",
  35837. display: "inline-block"
  35838. });
  35839. else if (targetLocation === "columnChooser")
  35840. startAnimate({
  35841. width: "100%",
  35842. display: "block"
  35843. });
  35844. else if (that._isTransparent)
  35845. $element.removeClass(DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT);
  35846. else
  35847. $element.show();
  35848. that._isShown = true
  35849. },
  35850. hide: function() {
  35851. var $element = this._element();
  35852. if ($element && this._isShown)
  35853. if (this._isTransparent)
  35854. $element.addClass(DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT);
  35855. else
  35856. $element.hide();
  35857. this._isShown = false
  35858. },
  35859. height: function(value) {
  35860. var $element = this._element();
  35861. if ($element)
  35862. if (utils.isDefined(value))
  35863. $element.height(value);
  35864. else
  35865. return $element.height()
  35866. },
  35867. width: function(value) {
  35868. var $element = this._element();
  35869. if ($element)
  35870. if (utils.isDefined(value))
  35871. $element.width(value);
  35872. else
  35873. return $element.width()
  35874. },
  35875. moveByX: function(outerX) {
  35876. var $element = this._element();
  35877. if ($element) {
  35878. $element.css("left", outerX - this._parentElement().offset().left);
  35879. this._testPosx = outerX
  35880. }
  35881. },
  35882. changeCursor: function(cursorName) {
  35883. cursorName = utils.isDefined(cursorName) ? cursorName : "";
  35884. var $element = this._element();
  35885. if ($element) {
  35886. $element.css('cursor', cursorName);
  35887. this._testCursorName = cursorName
  35888. }
  35889. }
  35890. });
  35891. dataGrid.BlockSeparatorView = dataGrid.ColumnsSeparatorView.inherit({
  35892. _subscribeToEvent: function(){},
  35893. _renderCore: function(options) {
  35894. this._isTransparent = false;
  35895. this.callBase(options);
  35896. this._element().addClass(DATAGRID_BLOCK_SEPARATOR_CLASS).html('&nbsp;')
  35897. },
  35898. hide: function() {
  35899. var that = this,
  35900. $parent = this._parentElement();
  35901. that.callBase();
  35902. if ($parent && !$parent.children('.' + DATAGRID_BLOCK_SEPARATOR_CLASS).length)
  35903. $parent.prepend(that._element())
  35904. },
  35905. isVisible: function() {
  35906. var groupPanelOptions = this.option("groupPanel"),
  35907. columnChooserOptions = this.option('columnChooser');
  35908. return groupPanelOptions && groupPanelOptions.visible || columnChooserOptions && columnChooserOptions.enabled
  35909. }
  35910. });
  35911. dataGrid.DraggingHeaderView = dataGrid.View.inherit({
  35912. _isDragging: false,
  35913. _getDropOptions: function() {
  35914. var that = this;
  35915. if (that._dragOptions)
  35916. return {
  35917. sourceColumnIndex: that._dragOptions.columnIndex,
  35918. sourceColumnElement: that._dragOptions.columnElement,
  35919. sourceLocation: that._dragOptions.sourceLocation,
  35920. targetColumnIndex: that._dropColumnIndex,
  35921. targetLocation: that._dropLocation
  35922. }
  35923. },
  35924. _dropHeader: function(args) {
  35925. var e = args.jQueryEvent,
  35926. that = e.data.that,
  35927. controller = that._controller;
  35928. that._element().hide();
  35929. if (controller && that._isDragging)
  35930. controller.drop(that._getDropOptions());
  35931. that._element().appendTo(that._parentElement());
  35932. that._dragOptions = null;
  35933. that._isDragging = false;
  35934. document.onselectstart = that._onSelectStart || null
  35935. },
  35936. _getDraggingPanelByPos: function(pos) {
  35937. var that = this,
  35938. result;
  35939. $.each(that._dragOptions.draggingPanels, function(index, draggingPanel) {
  35940. if (draggingPanel) {
  35941. var boundingRect = draggingPanel.getBoundingRect();
  35942. if (boundingRect && (boundingRect.bottom === undefined || pos.y < boundingRect.bottom) && (boundingRect.top === undefined || pos.y > boundingRect.top) && (boundingRect.left === undefined || pos.x > boundingRect.left) && (boundingRect.right === undefined || pos.x < boundingRect.right)) {
  35943. result = draggingPanel;
  35944. return false
  35945. }
  35946. }
  35947. });
  35948. return result
  35949. },
  35950. _pointCreated: function(point, columns, location, sourceColumn) {
  35951. var targetColumn = columns[point.columnIndex],
  35952. prevColumn = columns[point.columnIndex - 1];
  35953. switch (location) {
  35954. case"columnChooser":
  35955. return true;
  35956. case"headers":
  35957. return sourceColumn && !sourceColumn.allowReordering || (!targetColumn || !targetColumn.allowReordering) && (!prevColumn || !prevColumn.allowReordering);
  35958. default:
  35959. return columns.length === 0
  35960. }
  35961. },
  35962. _moveHeader: function(args) {
  35963. var e = args.jQueryEvent,
  35964. that = e.data.that,
  35965. columnElements,
  35966. pointsByColumns,
  35967. newLeft,
  35968. newTop,
  35969. moveDeltaX,
  35970. moveDeltaY,
  35971. eventData = events.eventData(e),
  35972. targetDraggingPanel,
  35973. controller = that._controller,
  35974. i,
  35975. params,
  35976. dragOptions = that._dragOptions,
  35977. isVerticalOrientation,
  35978. centerPosition,
  35979. axisName,
  35980. rtlEnabled;
  35981. if (that._isDragging) {
  35982. moveDeltaX = Math.abs(eventData.x - dragOptions.columnElement.offset().left - dragOptions.deltaX);
  35983. moveDeltaY = Math.abs(eventData.y - dragOptions.columnElement.offset().top - dragOptions.deltaY);
  35984. if (that._element().is(':visible') || moveDeltaX > DRAGGING_DELTA || moveDeltaY > DRAGGING_DELTA) {
  35985. that._element().show();
  35986. newLeft = eventData.x - dragOptions.deltaX;
  35987. newTop = eventData.y - dragOptions.deltaY;
  35988. that._element().offset({
  35989. left: newLeft,
  35990. top: newTop
  35991. });
  35992. targetDraggingPanel = that._getDraggingPanelByPos(eventData);
  35993. if (targetDraggingPanel) {
  35994. rtlEnabled = that.option('rtlEnabled');
  35995. isVerticalOrientation = targetDraggingPanel.getName() === 'columnChooser';
  35996. axisName = isVerticalOrientation ? 'y' : 'x';
  35997. columnElements = targetDraggingPanel.getColumnElements() || [];
  35998. pointsByColumns = dataGrid.getPointsByColumns(columnElements, function(point) {
  35999. return that._pointCreated(point, targetDraggingPanel.getColumns(), targetDraggingPanel.getName(), dragOptions.sourceColumn)
  36000. }, axisName === 'y');
  36001. that._dropLocation = targetDraggingPanel.getName();
  36002. if (pointsByColumns.length > 0)
  36003. for (i = 0; i < pointsByColumns.length; i++) {
  36004. centerPosition = pointsByColumns[i + 1] && (pointsByColumns[i][axisName] + pointsByColumns[i + 1][axisName]) / 2;
  36005. if (centerPosition === undefined || (rtlEnabled && axisName === 'x' ? eventData[axisName] > centerPosition : eventData[axisName] < centerPosition)) {
  36006. that._dropColumnIndex = pointsByColumns[i].columnIndex;
  36007. params = that._getDropOptions();
  36008. if (columnElements[i])
  36009. params.targetColumnElement = columnElements.eq(i);
  36010. else {
  36011. params.targetColumnElement = columnElements.last();
  36012. params.isLast = true
  36013. }
  36014. params.posX = pointsByColumns[i].x;
  36015. controller.dock(params);
  36016. break
  36017. }
  36018. }
  36019. else {
  36020. that._dropColumnIndex = -1;
  36021. params = that._getDropOptions();
  36022. controller.dock(params)
  36023. }
  36024. }
  36025. }
  36026. e.preventDefault()
  36027. }
  36028. },
  36029. _subscribeToEvents: function(rootElement) {
  36030. var that = this;
  36031. that._moveHeaderAction = this.createAction(this._moveHeader, {excludeValidators: ['gesture']});
  36032. that._dropHeaderAction = this.createAction(this._dropHeader, {excludeValidators: ['gesture']});
  36033. $(document).on(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), {
  36034. that: that,
  36035. rootElement: rootElement
  36036. }, that._moveHeaderAction);
  36037. that._element().on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), {that: that}, that._dropHeaderAction);
  36038. $(document).on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), {that: that}, that._dropHeaderAction)
  36039. },
  36040. _renderCore: function() {
  36041. this._element().addClass(DATAGRID_DRAGGING_HEADER_CLASS + ' ' + DATAGRID_CELL_CONTENT_CLASS + ' ' + WIDGET_CLASS).css('display', 'none')
  36042. },
  36043. _afterRender: function($parent) {
  36044. this._unsubscribeFromEvents();
  36045. this._subscribeToEvents($parent)
  36046. },
  36047. _unsubscribeFromEvents: function() {
  36048. if (this._dropHeaderAction) {
  36049. this._element().off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._dropHeaderAction);
  36050. $(document).off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._dropHeaderAction)
  36051. }
  36052. if (this._moveHeaderAction)
  36053. $(document).off(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), this._moveHeaderAction)
  36054. },
  36055. dispose: function() {
  36056. this._dragOptions = null;
  36057. this._unsubscribeFromEvents();
  36058. this._element().parent().find('.' + DATAGRID_DRAGGING_HEADER_CLASS).remove()
  36059. },
  36060. isVisible: function() {
  36061. var columnsController = this.getController("columns"),
  36062. commonColumnSettings = columnsController.getCommonSettings();
  36063. return this.option('showColumnHeaders') && (allowReordering(this) || commonColumnSettings.allowGrouping || commonColumnSettings.allowHiding)
  36064. },
  36065. init: function() {
  36066. this.callBase();
  36067. this._controller = this.getController("draggingHeader")
  36068. },
  36069. drag: function(options) {
  36070. var that = this,
  36071. columnElement = options.columnElement;
  36072. that._dragOptions = options;
  36073. that._isDragging = true;
  36074. that._dropColumnIndex = options.columnIndex;
  36075. that._dropLocation = options.sourceLocation;
  36076. that._onSelectStart = document.onselectstart;
  36077. document.onselectstart = function() {
  36078. return false
  36079. };
  36080. that._element().css({
  36081. textAlign: columnElement && columnElement.css('text-align'),
  36082. height: columnElement && columnElement.height(),
  36083. width: columnElement && columnElement.width(),
  36084. whiteSpace: columnElement && columnElement.css('white-space')
  36085. }).addClass(DATAGTID_HEADERS_ACTION_CLASS).text(options.sourceColumn.caption);
  36086. that._element().appendTo($(document.body))
  36087. }
  36088. });
  36089. dataGrid.ColumnsResizerViewController = dataGrid.ViewController.inherit({
  36090. _pointCreated: function(point, cellsLength, columns) {
  36091. var currentColumn,
  36092. nextColumn;
  36093. if (point.index > 0 && point.index < cellsLength) {
  36094. point.columnIndex -= 1;
  36095. currentColumn = columns[point.columnIndex] || {};
  36096. nextColumn = columns[point.columnIndex + 1] || {};
  36097. return !(currentColumn.allowResizing && nextColumn.allowResizing)
  36098. }
  36099. return true
  36100. },
  36101. _getTargetPoint: function(pointsByColumns, currentX, deltaX) {
  36102. if (pointsByColumns)
  36103. for (var i = 0; i < pointsByColumns.length; i++)
  36104. if (pointsByColumns[i].x - deltaX <= currentX && currentX <= pointsByColumns[i].x + deltaX)
  36105. return pointsByColumns[i];
  36106. return null
  36107. },
  36108. _moveSeparator: function(args) {
  36109. var e = args.jQueryEvent,
  36110. that = e.data,
  36111. pointsByColumns = that._pointsByColumns,
  36112. columnsSeparatorWidth = that._columnsSeparatorView.width(),
  36113. columnsSeparatorOffset = that._columnsSeparatorView._element().offset(),
  36114. deltaX = columnsSeparatorWidth / 2,
  36115. parentOffsetLeft = that._$parentContainer.offset().left,
  36116. eventData = events.eventData(e);
  36117. if (that._isResizing) {
  36118. if (parentOffsetLeft <= eventData.x && eventData.x <= parentOffsetLeft + that._$parentContainer.width())
  36119. if (that._updateColumnsWidthIfNeeded(that._targetPoint.columnIndex, eventData.x)) {
  36120. that._columnsSeparatorView.moveByX(that._targetPoint.x + (eventData.x - that._resizingInfo.startPosX));
  36121. that._tablePositionController.update();
  36122. e.preventDefault()
  36123. }
  36124. }
  36125. else {
  36126. that._targetPoint = that._getTargetPoint(pointsByColumns, eventData.x, columnsSeparatorWidth);
  36127. that._isReadyResizing = false;
  36128. that._columnsSeparatorView.changeCursor();
  36129. if (that._targetPoint && columnsSeparatorOffset.top <= eventData.y && columnsSeparatorOffset.top + that._columnsSeparatorView.height() >= eventData.y) {
  36130. that._columnsSeparatorView.changeCursor('col-resize');
  36131. that._columnsSeparatorView.moveByX(that._targetPoint.x - deltaX);
  36132. that._isReadyResizing = true;
  36133. e.preventDefault()
  36134. }
  36135. }
  36136. },
  36137. _endResizing: function(args) {
  36138. var e = args.jQueryEvent,
  36139. that = e.data;
  36140. if (that._isResizing) {
  36141. that._updatePointsByColumns();
  36142. that._resizingInfo = null;
  36143. that._columnsSeparatorView.hide();
  36144. that._columnsSeparatorView.changeCursor();
  36145. that._trackerView.hide();
  36146. that._isReadyResizing = false;
  36147. that._isResizing = false
  36148. }
  36149. },
  36150. _setupResizingInfo: function(posX) {
  36151. var that = this,
  36152. currentHeader = that._columnHeadersView.getHeaderElement(that._targetPoint.columnIndex),
  36153. nextHeader = that._columnHeadersView.getHeaderElement(that._targetPoint.columnIndex + 1);
  36154. that._resizingInfo = {
  36155. startPosX: posX,
  36156. currentColumnWidth: currentHeader && currentHeader.length > 0 ? currentHeader.outerWidth() : 0,
  36157. nextColumnWidth: nextHeader && nextHeader.length > 0 ? nextHeader.outerWidth() : 0
  36158. }
  36159. },
  36160. _startResizing: function(args) {
  36161. var e = args.jQueryEvent,
  36162. that = e.data,
  36163. eventData = events.eventData(e);
  36164. if (events.isTouchEvent(e)) {
  36165. that._targetPoint = that._getTargetPoint(that._pointsByColumns, eventData.x, COLUMNS_SEPARATOR_TOUCH_TRACKER_WIDTH);
  36166. if (that._targetPoint) {
  36167. that._columnsSeparatorView.moveByX(that._targetPoint.x - that._columnsSeparatorView.width() / 2);
  36168. that._isReadyResizing = true
  36169. }
  36170. }
  36171. if (that._isReadyResizing) {
  36172. if (that._targetPoint)
  36173. that._testColumnIndex = that._targetPoint.columnIndex;
  36174. that._setupResizingInfo(eventData.x);
  36175. that._columnsSeparatorView.show();
  36176. that._trackerView.show();
  36177. that._isResizing = true;
  36178. e.preventDefault()
  36179. }
  36180. },
  36181. _generatePointsByColumns: function() {
  36182. var that = this,
  36183. columns = that._columnsController ? that._columnsController.getVisibleColumns() : [],
  36184. cells = that._columnHeadersView.getColumnElements(),
  36185. pointsByColumns = [];
  36186. if (cells && cells.length > 0)
  36187. pointsByColumns = dataGrid.getPointsByColumns(cells, function(point) {
  36188. return that._pointCreated(point, cells.length, columns)
  36189. });
  36190. that._pointsByColumns = pointsByColumns
  36191. },
  36192. _unsubscribeFromEvents: function() {
  36193. this._moveSeparatorHandler && this._$parentContainer.off(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), this._moveSeparatorHandler);
  36194. this._startResizingHandler && this._columnsSeparatorView._element().off(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE), this._startResizingHandler);
  36195. if (this._endResizingHandler) {
  36196. this._columnsSeparatorView._element().off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._endResizingHandler);
  36197. $(document).off(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this._endResizingHandler)
  36198. }
  36199. },
  36200. _subscribeToEvents: function() {
  36201. this._moveSeparatorHandler = this.createAction(this._moveSeparator, {excludeValidators: ['gesture']});
  36202. this._startResizingHandler = this.createAction(this._startResizing);
  36203. this._endResizingHandler = this.createAction(this._endResizing, {excludeValidators: ['gesture']});
  36204. this._$parentContainer.on(addNamespace('dxpointermove', DATAGRID_MODULE_NAMESPACE), this, this._moveSeparatorHandler);
  36205. this._$parentContainer.on(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE), this, this._startResizingHandler);
  36206. this._columnsSeparatorView._element().on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this, this._endResizingHandler);
  36207. $(document).on(addNamespace('dxpointerup', DATAGRID_MODULE_NAMESPACE), this, this._endResizingHandler)
  36208. },
  36209. _updateColumnsWidthIfNeeded: function(columnIndex, posX) {
  36210. var deltaX,
  36211. isUpdated = false,
  36212. nextCellWidth,
  36213. visibleColumns = this._columnsController.getVisibleColumns(),
  36214. columnsSeparatorWidth = this._columnsSeparatorView.width(),
  36215. cellWidth;
  36216. deltaX = posX - this._resizingInfo.startPosX;
  36217. if (this.option("rtlEnabled"))
  36218. deltaX = -deltaX;
  36219. cellWidth = this._resizingInfo.currentColumnWidth + deltaX;
  36220. nextCellWidth = this._resizingInfo.nextColumnWidth - deltaX;
  36221. isUpdated = !(cellWidth <= columnsSeparatorWidth || nextCellWidth <= columnsSeparatorWidth);
  36222. if (isUpdated) {
  36223. visibleColumns[columnIndex] && this._columnsController.columnOption(visibleColumns[columnIndex].initialIndex, 'width', Math.floor(cellWidth));
  36224. visibleColumns[columnIndex + 1] && this._columnsController.columnOption(visibleColumns[columnIndex + 1].initialIndex, 'width', Math.floor(nextCellWidth))
  36225. }
  36226. return isUpdated
  36227. },
  36228. _updatePointsByColumns: function() {
  36229. var i,
  36230. point,
  36231. rtlEnabled = this.option("rtlEnabled"),
  36232. headerElement;
  36233. for (i = 0; i < this._pointsByColumns.length; i++) {
  36234. point = this._pointsByColumns[i];
  36235. headerElement = this._columnHeadersView.getHeaderElement(point.columnIndex + 1);
  36236. if (headerElement && headerElement.length > 0)
  36237. point.x = headerElement.offset().left + (rtlEnabled ? headerElement.outerWidth() : 0)
  36238. }
  36239. },
  36240. init: function() {
  36241. var that = this,
  36242. gridView,
  36243. previousScrollbarVisibility,
  36244. generatePointsByColumnsScrollHandler = function(offset) {
  36245. if (that._scrollLeft !== offset.left) {
  36246. that._scrollLeft = offset.left;
  36247. that._generatePointsByColumns()
  36248. }
  36249. },
  36250. generatePointsByColumnsHandler = function() {
  36251. that._generatePointsByColumns()
  36252. };
  36253. that.callBase();
  36254. if (allowResizing(that)) {
  36255. that._columnsSeparatorView = that.getView("columnsSeparatorView");
  36256. that._columnHeadersView = that.getView("columnHeadersView");
  36257. that._trackerView = that.getView("trackerView");
  36258. that._rowsView = that.getView("rowsView");
  36259. that._columnsController = that.getController("columns");
  36260. that._tablePositionController = that.getController("tablePosition");
  36261. that._$parentContainer = that._columnsSeparatorView.component._element();
  36262. that._columnHeadersView.renderCompleted.add(generatePointsByColumnsHandler);
  36263. that._columnHeadersView.resizeCompleted.add(generatePointsByColumnsHandler);
  36264. that._columnsSeparatorView.renderCompleted.add(function() {
  36265. that._unsubscribeFromEvents();
  36266. that._subscribeToEvents()
  36267. });
  36268. that._rowsView.renderCompleted.add(function() {
  36269. that._rowsView.scrollOffsetChanged.remove(generatePointsByColumnsScrollHandler);
  36270. that._rowsView.scrollOffsetChanged.add(generatePointsByColumnsScrollHandler)
  36271. });
  36272. gridView = that.getView("gridView");
  36273. previousScrollbarVisibility = that._rowsView.getScrollbarWidth() !== 0;
  36274. that.getController("tablePosition").positionChanged.add(function() {
  36275. if (that._isResizing && !that._rowsView.isResizing) {
  36276. var scrollbarVisibility = that._rowsView.getScrollbarWidth() !== 0;
  36277. if (previousScrollbarVisibility !== scrollbarVisibility) {
  36278. previousScrollbarVisibility = scrollbarVisibility;
  36279. gridView.resize()
  36280. }
  36281. else {
  36282. that._rowsView.updateFreeSpaceRowHeight();
  36283. that._columnHeadersView.processSizeChanged()
  36284. }
  36285. }
  36286. })
  36287. }
  36288. },
  36289. dispose: function() {
  36290. this._unsubscribeFromEvents()
  36291. }
  36292. });
  36293. dataGrid.TablePositionViewController = dataGrid.ViewController.inherit({
  36294. update: function() {
  36295. var $element = this._columnHeadersView._element(),
  36296. columnsHeadersHeight = this._columnHeadersView ? this._columnHeadersView.getHeight() : 0,
  36297. rowsHeight = this._rowsView ? this._rowsView.height() - this._rowsView.getScrollbarWidth(true) : 0;
  36298. this.positionChanged.fire({
  36299. height: columnsHeadersHeight + rowsHeight,
  36300. top: $element && $element.length > 0 ? Math.floor($element[0].offsetTop) : 0
  36301. })
  36302. },
  36303. init: function() {
  36304. var that = this;
  36305. that.callBase();
  36306. that._columnHeadersView = this.getView("columnHeadersView");
  36307. that._rowsView = this.getView("rowsView");
  36308. that._pagerView = this.getView("pagerView");
  36309. that._rowsView.resizeCompleted.add(function() {
  36310. that.update()
  36311. })
  36312. },
  36313. ctor: function(component) {
  36314. this.callBase(component);
  36315. this.positionChanged = $.Callbacks()
  36316. }
  36317. });
  36318. dataGrid.DraggingHeaderViewController = dataGrid.ViewController.inherit({
  36319. _subscribeToEvent: function(draggingHeader, draggingPanels) {
  36320. var that = this;
  36321. $.each(draggingPanels, function(_, draggingPanel) {
  36322. if (draggingPanel) {
  36323. var columnElements = draggingPanel.getColumnElements() || [],
  36324. nameDraggingPanel = draggingPanel.getName(),
  36325. columns = draggingPanel.getColumns() || [];
  36326. $.each(columnElements, function(index, columnElement) {
  36327. $(columnElement).off(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE));
  36328. if (draggingPanel.allowDragging(columns[index], draggingPanels))
  36329. $(columnElement).on(addNamespace('dxpointerdown', DATAGRID_MODULE_NAMESPACE), that.createAction(function(args) {
  36330. var e = args.jQueryEvent,
  36331. eventData = events.eventData(e);
  36332. e.preventDefault();
  36333. draggingHeader.drag({
  36334. deltaX: eventData.x - $(e.currentTarget).offset().left,
  36335. deltaY: eventData.y - $(e.currentTarget).offset().top,
  36336. sourceColumn: columns[index],
  36337. columnIndex: index,
  36338. columnElement: $(columnElement),
  36339. sourceLocation: draggingPanel.getName(),
  36340. draggingPanels: draggingPanels
  36341. })
  36342. }))
  36343. })
  36344. }
  36345. })
  36346. },
  36347. _getSeparator: function(targetLocation) {
  36348. return targetLocation === "headers" ? this._columnsSeparatorView : this._blockSeparatorView
  36349. },
  36350. hideSeparators: function() {
  36351. var blockSeparator = this._blockSeparatorView,
  36352. columnsSeparator = this._columnsSeparatorView;
  36353. this._animationColumnIndex = null;
  36354. blockSeparator && blockSeparator.hide();
  36355. columnsSeparator && columnsSeparator.hide()
  36356. },
  36357. init: function() {
  36358. var that = this,
  36359. subscribeToEvent;
  36360. that.callBase();
  36361. that._columnsController = that.getController("columns");
  36362. that._columnHeadersView = that.getView("columnHeadersView");
  36363. that._columnsSeparatorView = that.getView("columnsSeparatorView");
  36364. that._draggingHeaderView = that.getView("draggingHeaderView");
  36365. that._rowsView = that.getView('rowsView');
  36366. that._blockSeparatorView = that.getView("blockSeparatorView");
  36367. that._headerPanelView = that.getView("headerPanel");
  36368. that._columnChooserView = that.getView("columnChooserView");
  36369. subscribeToEvent = function() {
  36370. if (that._draggingHeaderView)
  36371. that._subscribeToEvent(that._draggingHeaderView, [that._columnChooserView, that._columnHeadersView, that._headerPanelView])
  36372. };
  36373. that._columnHeadersView.renderCompleted.add(subscribeToEvent);
  36374. that._headerPanelView.renderCompleted.add(subscribeToEvent);
  36375. that._columnChooserView.renderCompleted.add(subscribeToEvent)
  36376. },
  36377. allowDrop: function(parameters) {
  36378. return this._columnsController.allowMoveColumn(parameters.sourceColumnIndex, parameters.targetColumnIndex, parameters.sourceLocation, parameters.targetLocation)
  36379. },
  36380. allowDragColumn: function(columns, index, namePanel) {
  36381. var column = columns[index],
  36382. i,
  36383. draggableColumnCount = 0;
  36384. var allowDragFromHeaders = function(column) {
  36385. return column.allowReordering || column.allowGrouping || column.allowHiding
  36386. };
  36387. if (!column)
  36388. return false;
  36389. switch (namePanel) {
  36390. case"headers":
  36391. for (i = 0; i < columns.length; i++)
  36392. if (allowDragFromHeaders(columns[i]))
  36393. draggableColumnCount++;
  36394. return draggableColumnCount > 1 && allowDragFromHeaders(column);
  36395. case"group":
  36396. return column.allowGrouping;
  36397. case"columnChooser":
  36398. return column.allowHiding
  36399. }
  36400. },
  36401. dock: function(parameters) {
  36402. var that = this,
  36403. targetColumnIndex = parameters.targetColumnIndex,
  36404. sourceLocation = parameters.sourceLocation,
  36405. sourceColumnIndex = parameters.sourceColumnIndex,
  36406. sourceColumnElement = parameters.sourceColumnElement,
  36407. targetLocation = parameters.targetLocation,
  36408. separator = that._getSeparator(targetLocation),
  36409. hasTargetColumnIndex = targetColumnIndex >= 0;
  36410. var showSeparator = function() {
  36411. if (that._animationColumnIndex !== targetColumnIndex) {
  36412. that.hideSeparators();
  36413. separator._element()[parameters.isLast ? 'insertAfter' : 'insertBefore'](parameters.targetColumnElement);
  36414. that._animationColumnIndex = targetColumnIndex;
  36415. separator.show(targetLocation)
  36416. }
  36417. };
  36418. that._columnHeadersView._element().find('.' + DATAGRID_HEADER_ROW_CLASS).first().toggleClass(DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS, sourceLocation !== 'headers' && targetLocation === 'headers' && !hasTargetColumnIndex);
  36419. if (separator) {
  36420. if (sourceColumnElement) {
  36421. sourceColumnElement.css({opacity: 0.5});
  36422. if (sourceLocation === 'headers')
  36423. that._rowsView.setRowsOpacity(sourceColumnIndex, 0.5)
  36424. }
  36425. if (that.allowDrop(parameters) && hasTargetColumnIndex)
  36426. if (targetLocation === 'group' || targetLocation === 'columnChooser')
  36427. showSeparator();
  36428. else {
  36429. that.hideSeparators();
  36430. separator.moveByX(parameters.posX - separator.width());
  36431. separator.show()
  36432. }
  36433. else
  36434. that.hideSeparators()
  36435. }
  36436. },
  36437. drop: function(parameters) {
  36438. var sourceColumnElement = parameters.sourceColumnElement;
  36439. if (sourceColumnElement) {
  36440. sourceColumnElement.css({opacity: ''});
  36441. this._rowsView.setRowsOpacity(parameters.sourceColumnIndex, '');
  36442. this._columnHeadersView._element().find('.' + DATAGRID_HEADER_ROW_CLASS).first().removeClass(DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS)
  36443. }
  36444. if (this.allowDrop(parameters)) {
  36445. var separator = this._getSeparator(parameters.targetLocation);
  36446. if (separator)
  36447. separator.hide();
  36448. this._columnsController.moveColumn(parameters.sourceColumnIndex, parameters.targetColumnIndex, parameters.sourceLocation, parameters.targetLocation)
  36449. }
  36450. }
  36451. });
  36452. dataGrid.__internals = $.extend({}, dataGrid.__internals, {
  36453. DATAGRID_COLUMNS_SEPARATOR_CLASS: DATAGRID_COLUMNS_SEPARATOR_CLASS,
  36454. DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT: DATAGRID_COLUMNS_SEPARATOR_TRANSPARENT,
  36455. DATAGRID_DRAGGING_HEADER_CLASS: DATAGRID_DRAGGING_HEADER_CLASS,
  36456. DATAGRID_CELL_CONTENT_CLASS: DATAGRID_CELL_CONTENT_CLASS,
  36457. DATAGTID_HEADERS_ACTION_CLASS: DATAGTID_HEADERS_ACTION_CLASS,
  36458. DATAGRID_TRACKER_CLASS: DATAGRID_TRACKER_CLASS,
  36459. DATAGRID_MODULE_NAMESPACE: DATAGRID_MODULE_NAMESPACE,
  36460. DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS: DATAGRID_HEADERS_DROP_HIGHLIGHT_CLASS,
  36461. WIDGET_CLASS: WIDGET_CLASS
  36462. });
  36463. dataGrid.registerModule("columnsResizingReordering", {
  36464. views: {
  36465. columnsSeparatorView: dataGrid.ColumnsSeparatorView,
  36466. blockSeparatorView: dataGrid.BlockSeparatorView,
  36467. draggingHeaderView: dataGrid.DraggingHeaderView,
  36468. trackerView: dataGrid.TrackerView
  36469. },
  36470. controllers: {
  36471. draggingHeader: dataGrid.DraggingHeaderViewController,
  36472. tablePosition: dataGrid.TablePositionViewController,
  36473. columnsResizer: dataGrid.ColumnsResizerViewController
  36474. }
  36475. })
  36476. })(jQuery, DevExpress);
  36477. /*! Module widgets-web, file ui.dataGrid.contextMenuView.js */
  36478. (function($, DX) {
  36479. var ui = DX.ui,
  36480. utils = DX.utils,
  36481. dataGrid = ui.dataGrid;
  36482. var DATAGRID_CLASS = "dx-datagrid",
  36483. DATAGRID_CONTEXT_MENU = "dx-context-menu";
  36484. dataGrid.ContextMenuView = dataGrid.View.inherit({
  36485. viewNames: function() {
  36486. return ["columnHeadersView"]
  36487. },
  36488. _renderCore: function() {
  36489. var that = this;
  36490. that._element().addClass(DATAGRID_CONTEXT_MENU).dxContextMenu({
  36491. positioningAction: function(actionArgs) {
  36492. var event = actionArgs.jQueryEvent,
  36493. $targetElement = $(event.target),
  36494. contextMenuInstance = actionArgs.component,
  36495. items = [];
  36496. $.each(that.viewNames(), function(index, viewName) {
  36497. var view = that.getView(viewName),
  36498. menuItems = view.getContextMenuItems($targetElement);
  36499. if (menuItems.length) {
  36500. items = menuItems;
  36501. return false
  36502. }
  36503. });
  36504. if (items.length)
  36505. contextMenuInstance.option('items', items);
  36506. else
  36507. actionArgs.canceled = true
  36508. },
  36509. itemClickAction: function(params) {
  36510. params.itemData.itemClickAction && params.itemData.itemClickAction(params)
  36511. },
  36512. rtlEnabled: that.option('rtlEnabled'),
  36513. cssClass: DATAGRID_CLASS,
  36514. target: that.component._element()
  36515. })
  36516. }
  36517. });
  36518. dataGrid.registerModule("contextMenu", {views: {contextMenuView: dataGrid.ContextMenuView}})
  36519. })(jQuery, DevExpress);
  36520. /*! Module widgets-web, file ui.dataGrid.keyboardNavigation.js */
  36521. (function($, DX) {
  36522. var ui = DX.ui,
  36523. utils = DX.utils,
  36524. events = ui.events,
  36525. dataGrid = ui.dataGrid;
  36526. var DATAGRID_ROW_CLASS = "dx-row",
  36527. DATAGRID_GROUP_ROW_CLASS = "dx-group-row",
  36528. DATAGRID_EDITING_MODE_BATCH = "batch",
  36529. DATAGRID_ROWS_VIEW_CLASS = "dx-datagrid-rowsview",
  36530. DATAGRID_VIEWS = ["rowsView"];
  36531. dataGrid.KeyboardNavigationController = dataGrid.ViewController.inherit({
  36532. _focusView: function(view, viewIndex) {
  36533. view.focus();
  36534. this._focusedViews.viewIndex = viewIndex;
  36535. this._focusedView = view
  36536. },
  36537. _initFocusedViews: function() {
  36538. var that = this,
  36539. $cell,
  36540. $input,
  36541. clickHandler = that.createAction(function(e) {
  36542. var event = e.jQueryEvent,
  36543. $cell = $(event.currentTarget);
  36544. if (!that._editingController.isEditing())
  36545. if (that._isCellValid($cell)) {
  36546. $cell.focus();
  36547. that._focusView(event.data.view, event.data.viewIndex);
  36548. that._updateFocusedCellPosition($cell)
  36549. }
  36550. else
  36551. that._resetFocusedCell(that)
  36552. });
  36553. that._focusedViews = [];
  36554. $.each(DATAGRID_VIEWS, function(key, viewName) {
  36555. var view = that.getView(viewName);
  36556. if (view.isVisible())
  36557. that._focusedViews.push(view)
  36558. });
  36559. $.each(that._focusedViews, function(index, view) {
  36560. if (view)
  36561. view.renderCompleted.add(function() {
  36562. var $element = view._element();
  36563. $element.off(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), clickHandler);
  36564. $element.on(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), "." + DATAGRID_ROW_CLASS + " td", {
  36565. viewIndex: index,
  36566. view: view
  36567. }, clickHandler);
  36568. that._initKeyDownProcessor(that, $element, that._keyDownHandler);
  36569. if (that._focusedView && that._focusedView.name === view.name && that._isKeyDown) {
  36570. $cell = that._getFocusedCell();
  36571. if ($cell && $cell.length > 0) {
  36572. that._focusView(view, index);
  36573. if (that.getController('editorFactory').focus())
  36574. that._focus($cell);
  36575. setTimeout(function() {
  36576. if (that._editingController.isEditing()) {
  36577. $input = $cell.find('input').first();
  36578. that._testFocusedInput = $input;
  36579. $input.focus()
  36580. }
  36581. else {
  36582. $cell.attr("tabindex", 0);
  36583. $cell.focus()
  36584. }
  36585. })
  36586. }
  36587. }
  36588. })
  36589. })
  36590. },
  36591. _initKeyDownProcessor: function(context, element, handler) {
  36592. if (this._keyDownProcessor) {
  36593. this._keyDownProcessor.dispose();
  36594. this._keyDownProcessor = null
  36595. }
  36596. this._keyDownProcessor = new ui.HierarchicalKeyDownProcessor({
  36597. element: element,
  36598. context: context,
  36599. handler: handler
  36600. })
  36601. },
  36602. _focusCell: function($cell) {
  36603. var that = this;
  36604. if ($cell) {
  36605. that.getController('editorFactory').focus($cell);
  36606. that._updateFocusedCellPosition($cell)
  36607. }
  36608. },
  36609. _focusGroupRow: function($row) {
  36610. if ($row) {
  36611. this.getController('editorFactory').focus($row);
  36612. this._focusedCellPosition.rowIndex = this._focusedView.getRowIndex($row)
  36613. }
  36614. },
  36615. _getFocusedCell: function() {
  36616. if (this._focusedView && this._focusedCellPosition)
  36617. return this._focusedView.getCell(this._focusedCellPosition.columnIndex, this._focusedCellPosition.rowIndex)
  36618. },
  36619. _updateFocusedCellPosition: function($cell) {
  36620. var that = this;
  36621. if ($cell.length > 0)
  36622. this._focusedCellPosition = {
  36623. columnIndex: $cell[0].cellIndex,
  36624. rowIndex: $cell.parent().length > 0 && that._focusedView ? that._focusedView.getRowIndex($cell.parent()) : null
  36625. }
  36626. },
  36627. _isCellValid: function($cell) {
  36628. var visibleColumns = this._columnsController.getVisibleColumns(),
  36629. columnIndex = $cell[0].cellIndex;
  36630. return visibleColumns.length > columnIndex && !(visibleColumns[columnIndex].command || utils.isDefined(visibleColumns[columnIndex].groupIndex))
  36631. },
  36632. _isGroupRow: function($row) {
  36633. return $row && $row.hasClass(DATAGRID_GROUP_ROW_CLASS)
  36634. },
  36635. _focus: function($cell) {
  36636. var $row = $cell && $cell.parent();
  36637. if (this._isGroupRow($row))
  36638. this._focusGroupRow($row);
  36639. else
  36640. this._focusCell($cell)
  36641. },
  36642. _keyDownHandler: function(e) {
  36643. var editingOptions = this.option("editing"),
  36644. isEditing = this._editingController.isEditing(),
  36645. pageIndex = this._dataController.pageIndex(),
  36646. pagesCount = this._dataController.pageCount(),
  36647. rowIndex = this._focusedCellPosition ? this._focusedCellPosition.rowIndex : null,
  36648. $row = this._focusedView && this._focusedView.getRow(rowIndex),
  36649. $cell;
  36650. this._isKeyDown = true;
  36651. switch (e.key) {
  36652. case"leftArrow":
  36653. case"rightArrow":
  36654. if (!isEditing && !this._isGroupRow($row)) {
  36655. $cell = this._getNextCell(e.key);
  36656. if ($cell && this._isCellValid($cell))
  36657. this._focusCell($cell);
  36658. e.originalEvent.preventDefault()
  36659. }
  36660. break;
  36661. case"upArrow":
  36662. case"downArrow":
  36663. if (!isEditing) {
  36664. if (rowIndex === 0 || rowIndex === this._focusedView.getRowsCount() - 1);
  36665. $cell = this._getNextCell(e.key);
  36666. if ($cell && this._isCellValid($cell))
  36667. this._focus($cell);
  36668. e.originalEvent.preventDefault()
  36669. }
  36670. break;
  36671. case"pageUp":
  36672. if (pageIndex > 0) {
  36673. this._dataController.pageIndex(pageIndex - 1);
  36674. e.originalEvent.preventDefault()
  36675. }
  36676. break;
  36677. case"pageDown":
  36678. if (pageIndex < pagesCount - 1) {
  36679. this._dataController.pageIndex(pageIndex + 1);
  36680. e.originalEvent.preventDefault()
  36681. }
  36682. break;
  36683. case"space":
  36684. if (this.option("selection") && this.option("selection").mode !== "none" && !isEditing)
  36685. this._selectionController.changeItemSelection(rowIndex, {
  36686. shift: e.shift,
  36687. control: e.ctrl
  36688. });
  36689. break;
  36690. case"A":
  36691. if (e.ctrl && this.option("selection.mode") === "multiple" && this.option("selection.allowSelectAll")) {
  36692. this._selectionController.selectAll();
  36693. e.originalEvent.preventDefault()
  36694. }
  36695. break;
  36696. case"tab":
  36697. if (isEditing && this._editingController.getEditMode() === DATAGRID_EDITING_MODE_BATCH && e.originalEvent.target) {
  36698. this._updateFocusedCellPosition($(e.originalEvent.target).closest('td'));
  36699. $cell = this._getNextCell("rightArrow");
  36700. this._focusCell($cell);
  36701. this._editingController.editCell(this._focusedCellPosition.rowIndex, this._focusedCellPosition.columnIndex);
  36702. e.originalEvent.preventDefault()
  36703. }
  36704. break;
  36705. case"enter":
  36706. if (this._isGroupRow($row)) {
  36707. if (this.option("grouping") && this.option("grouping").allowCollapsing) {
  36708. var path = this._dataController.getGroupPathByRowIndex(rowIndex);
  36709. if (path)
  36710. this._dataController.changeGroupExpand(path)
  36711. }
  36712. }
  36713. else if (editingOptions.editEnabled)
  36714. if (isEditing) {
  36715. this._updateFocusedCellPosition($(e.originalEvent.target).closest('td'));
  36716. if (this._editingController.getEditMode() === DATAGRID_EDITING_MODE_BATCH)
  36717. this._editingController.closeEditCell();
  36718. else
  36719. setTimeout($.proxy(this._editingController.saveEditData, this._editingController))
  36720. }
  36721. else if (this._editingController.getEditMode() === DATAGRID_EDITING_MODE_BATCH)
  36722. this._editingController.editCell(rowIndex, this._focusedCellPosition.columnIndex);
  36723. else
  36724. this._editingController.editRow(rowIndex);
  36725. break;
  36726. case"escape":
  36727. if (editingOptions.editEnabled)
  36728. if (isEditing) {
  36729. this._updateFocusedCellPosition($(e.originalEvent.target).closest('td'));
  36730. if (this._editingController.getEditMode() === DATAGRID_EDITING_MODE_BATCH)
  36731. this._editingController.closeEditCell();
  36732. else
  36733. this._editingController.cancelEditData();
  36734. e.originalEvent.preventDefault()
  36735. }
  36736. break;
  36737. case"F":
  36738. if (e.ctrl && this.option("searchPanel") && this.option("searchPanel").visible) {
  36739. this._testHeaderPanelFocused = true;
  36740. this._headerPanel.focus();
  36741. e.originalEvent.preventDefault()
  36742. }
  36743. break
  36744. }
  36745. },
  36746. _getNextCell: function(keyCode) {
  36747. if (this._focusedView && this._focusedCellPosition) {
  36748. var columnIndex = this._focusedCellPosition.columnIndex,
  36749. visibleColumnsCount = this.getController("columns").getVisibleColumns().length,
  36750. rowIndex = this._focusedCellPosition.rowIndex;
  36751. switch (keyCode) {
  36752. case"rightArrow":
  36753. columnIndex = columnIndex < visibleColumnsCount - 1 ? columnIndex + 1 : columnIndex;
  36754. break;
  36755. case"leftArrow":
  36756. columnIndex = columnIndex > 0 ? columnIndex - 1 : columnIndex;
  36757. break;
  36758. case"upArrow":
  36759. rowIndex = rowIndex > 0 ? rowIndex - 1 : rowIndex;
  36760. break;
  36761. case"downArrow":
  36762. rowIndex = rowIndex < this._dataController.items().length - 1 ? rowIndex + 1 : rowIndex;
  36763. break
  36764. }
  36765. return this._focusedView.getCell(columnIndex, rowIndex)
  36766. }
  36767. return null
  36768. },
  36769. _resetFocusedCell: function(that) {
  36770. var $cell = that._getFocusedCell();
  36771. $cell && $cell.attr("tabindex", null);
  36772. that._focusedCellPosition = null;
  36773. that._isKeyDown = false
  36774. },
  36775. init: function() {
  36776. var that = this;
  36777. if (that.option("useKeyboard")) {
  36778. that._dataController = that.getController("data");
  36779. that._selectionController = that.getController("selection");
  36780. that._editingController = that.getController("editing");
  36781. that._headerPanel = that.getView("headerPanel");
  36782. that._pagerView = that.getView("pagerView");
  36783. that._columnsController = that.getController("columns");
  36784. that._focusedCellPosition = {
  36785. columnIndex: 0,
  36786. rowIndex: 0
  36787. };
  36788. that._dataController.changed.add(function(change) {
  36789. if (that._focusedCellPosition && change && change.changeType === 'prepend')
  36790. that._focusedCellPosition.rowIndex += change.items.length
  36791. });
  36792. that._initFocusedViews();
  36793. that._documentClickHandler = that.createAction(function(e) {
  36794. if (!$(e.jQueryEvent.target).closest("." + DATAGRID_ROWS_VIEW_CLASS).length)
  36795. that._resetFocusedCell(that)
  36796. });
  36797. $(document).on(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), that._documentClickHandler)
  36798. }
  36799. },
  36800. dispose: function() {
  36801. this.callBase();
  36802. this._focusedView = null;
  36803. this._focusedViews = null;
  36804. this._keyDownProcessor && this._keyDownProcessor.dispose();
  36805. $(document).off(events.addNamespace("dxpointerdown", "dxDataGridKeyboardNavigation"), this._documentClickHandler)
  36806. }
  36807. });
  36808. $.extend(dataGrid.__internals, {
  36809. DATAGRID_GROUP_ROW_CLASS: DATAGRID_GROUP_ROW_CLASS,
  36810. DATAGRID_ROW_CLASS: DATAGRID_ROW_CLASS
  36811. });
  36812. dataGrid.registerModule("keyboardNavigation", {
  36813. defaultOptions: function() {
  36814. return {useKeyboard: true}
  36815. },
  36816. controllers: {keyboardNavigation: dataGrid.KeyboardNavigationController}
  36817. })
  36818. })(jQuery, DevExpress);
  36819. /*! Module widgets-web, file ui.dataGrid.errorHandling.js */
  36820. (function($, DX) {
  36821. var ui = DX.ui,
  36822. utils = DX.utils,
  36823. dataGrid = ui.dataGrid;
  36824. dataGrid.ErrorView = dataGrid.View.inherit({
  36825. _renderCore: function() {
  36826. this.toast({
  36827. type: 'error',
  36828. displayTime: 1000000,
  36829. position: {
  36830. my: 'center',
  36831. at: 'center'
  36832. },
  36833. contentReadyAction: function(e) {
  36834. this.content().on('dxclick', function() {
  36835. e.component.hide()
  36836. })
  36837. }
  36838. })
  36839. },
  36840. toast: function(options) {
  36841. return this._element().dxToast(options || 'instance')
  36842. },
  36843. isVisible: function() {
  36844. return this.option('dataErrorVisible')
  36845. },
  36846. init: function() {
  36847. var that = this,
  36848. dataController = that.getController('data');
  36849. dataController.dataErrorOccurred.add(function(error) {
  36850. var message = error && error.message || error;
  36851. if (that.isVisible()) {
  36852. that.toast({message: message});
  36853. that.toast().show()
  36854. }
  36855. })
  36856. }
  36857. });
  36858. dataGrid.registerModule('errorHandling', {views: {errorView: dataGrid.ErrorView}})
  36859. })(jQuery, DevExpress);
  36860. DevExpress.MOD_WIDGETS_WEB = true
  36861. }
  36862. if (!DevExpress.MOD_FRAMEWORK) {
  36863. if (!window.DevExpress)
  36864. throw Error('Required module is not referenced: core');
  36865. /*! Module framework, file framework.js */
  36866. (function($, DX, undefined) {
  36867. var mergeWithReplace = function(destination, source, needReplaceFn) {
  36868. var result = [];
  36869. for (var i = 0, destinationLength = destination.length; i < destinationLength; i++)
  36870. if (!needReplaceFn(destination[i], source))
  36871. result.push(destination[i]);
  36872. result.push.apply(result, source);
  36873. return result
  36874. };
  36875. var getMergeCommands = function() {
  36876. return function(destination, source) {
  36877. return mergeWithReplace(destination, source, function(destObject, source) {
  36878. return $.grep(source, function(srcObject) {
  36879. var match = destObject.option("id") === srcObject.option("id") && srcObject.option("id") || destObject.option("behavior") === srcObject.option("behavior") && destObject.option("behavior");
  36880. if (match)
  36881. destObject._element().remove();
  36882. return match
  36883. }).length
  36884. })
  36885. }
  36886. };
  36887. var resolvePropertyValue = function(command, containerOptions, propertyName) {
  36888. var defaultOption = containerOptions ? containerOptions[propertyName] : undefined;
  36889. return command.option(propertyName) || defaultOption
  36890. };
  36891. var resolveTextValue = function(command, containerOptions) {
  36892. var hasIcon = !!command.option("icon") || command.option("iconSrc"),
  36893. titleValue = resolvePropertyValue(command, containerOptions, "title");
  36894. return containerOptions.showText || !hasIcon ? titleValue : ""
  36895. };
  36896. var resolveIconValue = function(command, containerOptions, propertyName) {
  36897. var hasText = !!command.option("title"),
  36898. iconValue = resolvePropertyValue(command, containerOptions, propertyName);
  36899. return containerOptions.showIcon || !hasText ? iconValue : undefined
  36900. };
  36901. var resolveTypeValue = function(command, containerOptions) {
  36902. return resolvePropertyValue(command, containerOptions, "type")
  36903. };
  36904. DX.framework = {utils: {
  36905. mergeCommands: getMergeCommands(),
  36906. commandToContainer: {
  36907. resolveTypeValue: resolveTypeValue,
  36908. resolveIconValue: resolveIconValue,
  36909. resolveTextValue: resolveTextValue,
  36910. resolvePropertyValue: resolvePropertyValue
  36911. }
  36912. }}
  36913. })(jQuery, DevExpress);
  36914. /*! Module framework, file framework.routing.js */
  36915. (function($, DX) {
  36916. var JSON_URI_PREFIX = encodeURIComponent("json:");
  36917. var Class = DX.Class;
  36918. DX.framework.Route = Class.inherit({
  36919. _trimSeparators: function(str) {
  36920. return str.replace(/^[\/.]+|\/+$/g, "")
  36921. },
  36922. _escapeRe: function(str) {
  36923. return str.replace(/\W/g, "\\$1")
  36924. },
  36925. _checkConstraint: function(param, constraint) {
  36926. param = String(param);
  36927. if (typeof constraint === "string")
  36928. constraint = new RegExp(constraint);
  36929. var match = constraint.exec(param);
  36930. if (!match || match[0] !== param)
  36931. return false;
  36932. return true
  36933. },
  36934. _ensureReady: function() {
  36935. var that = this;
  36936. if (this._patternRe)
  36937. return false;
  36938. this._pattern = this._trimSeparators(this._pattern);
  36939. this._patternRe = "";
  36940. this._params = [];
  36941. this._segments = [];
  36942. this._separators = [];
  36943. this._pattern.replace(/[^\/]+/g, function(segment, index) {
  36944. that._segments.push(segment);
  36945. if (index)
  36946. that._separators.push(that._pattern.substr(index - 1, 1))
  36947. });
  36948. $.each(this._segments, function(index) {
  36949. var isStatic = true,
  36950. segment = this,
  36951. separator = index ? that._separators[index - 1] : "";
  36952. if (segment.charAt(0) === ":") {
  36953. isStatic = false;
  36954. segment = segment.substr(1);
  36955. that._params.push(segment);
  36956. that._patternRe += "(?:" + separator + "([^/]*))";
  36957. if (segment in that._defaults)
  36958. that._patternRe += "?"
  36959. }
  36960. else
  36961. that._patternRe += separator + that._escapeRe(segment)
  36962. });
  36963. this._patternRe = new RegExp("^" + this._patternRe + "$")
  36964. },
  36965. ctor: function(pattern, defaults, constraints) {
  36966. this._pattern = pattern || "";
  36967. this._defaults = defaults || {};
  36968. this._constraints = constraints || {}
  36969. },
  36970. parse: function(uri) {
  36971. var that = this;
  36972. this._ensureReady();
  36973. var matches = this._patternRe.exec(uri);
  36974. if (!matches)
  36975. return false;
  36976. var result = $.extend({}, this._defaults);
  36977. $.each(this._params, function(i) {
  36978. var index = i + 1;
  36979. if (matches.length >= index && matches[index])
  36980. result[this] = that.parseSegment(matches[index])
  36981. });
  36982. $.each(this._constraints, function(key) {
  36983. if (!that._checkConstraint(result[key], that._constraints[key])) {
  36984. result = false;
  36985. return false
  36986. }
  36987. });
  36988. return result
  36989. },
  36990. format: function(routeValues) {
  36991. var that = this,
  36992. query = "";
  36993. this._ensureReady();
  36994. var mergeValues = $.extend({}, this._defaults),
  36995. useStatic = 0,
  36996. ret = [],
  36997. dels = [],
  36998. unusedRouteValues = {};
  36999. $.each(routeValues, function(paramName, paramValue) {
  37000. routeValues[paramName] = that.formatSegment(paramValue);
  37001. if (!(paramName in mergeValues))
  37002. unusedRouteValues[paramName] = true
  37003. });
  37004. $.each(this._segments, function(index, segment) {
  37005. ret[index] = index ? that._separators[index - 1] : '';
  37006. if (segment.charAt(0) === ':') {
  37007. var paramName = segment.substr(1);
  37008. if (!(paramName in routeValues) && !(paramName in that._defaults)) {
  37009. ret = null;
  37010. return false
  37011. }
  37012. if (paramName in that._constraints && !that._checkConstraint(routeValues[paramName], that._constraints[paramName])) {
  37013. ret = null;
  37014. return false
  37015. }
  37016. if (paramName in routeValues) {
  37017. if (routeValues[paramName] !== undefined) {
  37018. mergeValues[paramName] = routeValues[paramName];
  37019. ret[index] += routeValues[paramName];
  37020. useStatic = index
  37021. }
  37022. delete unusedRouteValues[paramName]
  37023. }
  37024. else if (paramName in mergeValues) {
  37025. ret[index] += mergeValues[paramName];
  37026. dels.push(index)
  37027. }
  37028. }
  37029. else {
  37030. ret[index] += segment;
  37031. useStatic = index
  37032. }
  37033. });
  37034. $.each(mergeValues, function(key, value) {
  37035. if (!!value && $.inArray(":" + key, that._segments) === -1 && routeValues[key] !== value) {
  37036. ret = null;
  37037. return false
  37038. }
  37039. });
  37040. var unusedCount = 0;
  37041. if (!$.isEmptyObject(unusedRouteValues)) {
  37042. query = "?";
  37043. $.each(unusedRouteValues, function(key) {
  37044. query += key + "=" + routeValues[key] + "&";
  37045. unusedCount++
  37046. });
  37047. query = query.substr(0, query.length - 1)
  37048. }
  37049. if (ret === null)
  37050. return false;
  37051. if (dels.length)
  37052. $.map(dels, function(i) {
  37053. if (i >= useStatic)
  37054. ret[i] = ''
  37055. });
  37056. var path = ret.join('');
  37057. path = path.replace(/\/+$/, "");
  37058. return {
  37059. uri: path + query,
  37060. unusedCount: unusedCount
  37061. }
  37062. },
  37063. formatSegment: function(value) {
  37064. if ($.isArray(value) || $.isPlainObject(value))
  37065. return JSON_URI_PREFIX + encodeURIComponent(JSON.stringify(value));
  37066. return encodeURIComponent(value)
  37067. },
  37068. parseSegment: function(value) {
  37069. if (value.substr(0, JSON_URI_PREFIX.length) === JSON_URI_PREFIX)
  37070. try {
  37071. return $.parseJSON(decodeURIComponent(value.substr(JSON_URI_PREFIX.length)))
  37072. }
  37073. catch(x) {}
  37074. return decodeURIComponent(value)
  37075. }
  37076. });
  37077. DX.framework.MvcRouter = DX.Class.inherit({
  37078. ctor: function() {
  37079. this._registry = []
  37080. },
  37081. _trimSeparators: function(str) {
  37082. return str.replace(/^[\/.]+|\/+$/g, "")
  37083. },
  37084. _createRoute: function(pattern, defaults, constraints) {
  37085. return new DX.framework.Route(pattern, defaults, constraints)
  37086. },
  37087. register: function(pattern, defaults, constraints) {
  37088. this._registry.push(this._createRoute(pattern, defaults, constraints))
  37089. },
  37090. _parseQuery: function(query) {
  37091. var result = {},
  37092. values = query.split("&");
  37093. $.each(values, function(index, value) {
  37094. var keyValuePair = value.split("=");
  37095. result[keyValuePair[0]] = decodeURIComponent(keyValuePair[1])
  37096. });
  37097. return result
  37098. },
  37099. parse: function(uri) {
  37100. var that = this,
  37101. ret;
  37102. uri = this._trimSeparators(uri);
  37103. var parts = uri.split("?", 2),
  37104. path = parts[0],
  37105. query = parts[1];
  37106. $.each(this._registry, function() {
  37107. var result = this.parse(path);
  37108. if (result !== false) {
  37109. ret = result;
  37110. if (query)
  37111. ret = $.extend(ret, that._parseQuery(query));
  37112. return false
  37113. }
  37114. });
  37115. return ret ? ret : false
  37116. },
  37117. format: function(obj) {
  37118. var ret = false,
  37119. minUnusedCount = 99999;
  37120. obj = obj || {};
  37121. $.each(this._registry, function() {
  37122. var toFormat = $.extend(true, {}, obj);
  37123. var result = this.format(toFormat);
  37124. if (result !== false)
  37125. if (minUnusedCount > result.unusedCount) {
  37126. minUnusedCount = result.unusedCount;
  37127. ret = result.uri
  37128. }
  37129. });
  37130. return ret
  37131. }
  37132. });
  37133. DX.framework.Route.__internals = {JSON_URI_PREFIX: JSON_URI_PREFIX}
  37134. })(jQuery, DevExpress);
  37135. /*! Module framework, file framework.command.js */
  37136. (function($, DX) {
  37137. var ui = DX.ui;
  37138. DX.framework.dxCommand = DX.DOMComponent.inherit({
  37139. ctor: function(element, options) {
  37140. if ($.isPlainObject(element)) {
  37141. options = element;
  37142. element = $("<div />")
  37143. }
  37144. this.beforeExecute = $.Callbacks();
  37145. this.afterExecute = $.Callbacks();
  37146. this.callBase(element, options)
  37147. },
  37148. _setDefaultOptions: function() {
  37149. this.callBase();
  37150. this.option({
  37151. action: null,
  37152. id: null,
  37153. title: "",
  37154. icon: "",
  37155. iconSrc: "",
  37156. visible: true,
  37157. disabled: false
  37158. })
  37159. },
  37160. execute: function() {
  37161. var isDisabled = this._options.disabled;
  37162. if ($.isFunction(isDisabled))
  37163. isDisabled = !!isDisabled.apply(this, arguments);
  37164. if (isDisabled)
  37165. throw new Error(DX.utils.stringFormat("Cannot execute command: {0}", this._options.id));
  37166. this.beforeExecute.fire(arguments);
  37167. this._createActionByOption("action", {excludeValidators: ["gesture"]}).apply(this, arguments);
  37168. this.afterExecute.fire(arguments)
  37169. },
  37170. _render: function() {
  37171. this.callBase();
  37172. this._element().addClass("dx-command")
  37173. },
  37174. _renderDisabledState: $.noop,
  37175. _dispose: function() {
  37176. this.callBase();
  37177. this._element().removeData(this.NAME);
  37178. this.beforeExecute.empty();
  37179. this.afterExecute.empty()
  37180. }
  37181. });
  37182. DX.registerComponent("dxCommand", DX.framework.dxCommand)
  37183. })(jQuery, DevExpress);
  37184. /*! Module framework, file framework.commandMapping.js */
  37185. (function($, DX) {
  37186. DX.framework.CommandMapping = DX.Class.inherit({
  37187. ctor: function() {
  37188. this._commandMappings = {};
  37189. this._containerDefaults = {}
  37190. },
  37191. setDefaults: function(containerId, defaults) {
  37192. this._containerDefaults[containerId] = defaults;
  37193. return this
  37194. },
  37195. mapCommands: function(containerId, commandMappings) {
  37196. var that = this;
  37197. $.each(commandMappings, function(index, commandMapping) {
  37198. if (typeof commandMapping === "string")
  37199. commandMapping = {id: commandMapping};
  37200. var commandId = commandMapping.id;
  37201. var mappings = that._commandMappings[containerId] || {};
  37202. mappings[commandId] = $.extend({
  37203. showIcon: true,
  37204. showText: true
  37205. }, that._containerDefaults[containerId] || {}, commandMapping);
  37206. that._commandMappings[containerId] = mappings
  37207. });
  37208. this._initExistingCommands();
  37209. return this
  37210. },
  37211. unmapCommands: function(containerId, commandIds) {
  37212. var that = this;
  37213. $.each(commandIds, function(index, commandId) {
  37214. var mappings = that._commandMappings[containerId] || {};
  37215. if (mappings)
  37216. delete mappings[commandId]
  37217. });
  37218. this._initExistingCommands()
  37219. },
  37220. getCommandMappingForContainer: function(commandId, containerId) {
  37221. return (this._commandMappings[containerId] || {})[commandId]
  37222. },
  37223. checkCommandsExist: function(commands) {
  37224. var that = this,
  37225. result = $.grep(commands, function(commandName, index) {
  37226. return $.inArray(commandName, that._existingCommands) < 0 && $.inArray(commandName, commands) === index
  37227. });
  37228. if (result.length !== 0)
  37229. throw new Error("The '" + result.join("', '") + "' command" + (result.length === 1 ? " is" : "s are") + " not registred in the application's command mapping. See http://dxpr.es/1bTjfj1 for more details.");
  37230. },
  37231. load: function(config) {
  37232. if (!config)
  37233. return;
  37234. var that = this;
  37235. $.each(config, function(name, container) {
  37236. that.setDefaults(name, container.defaults);
  37237. that.mapCommands(name, container.commands)
  37238. });
  37239. return this
  37240. },
  37241. _initExistingCommands: function() {
  37242. var that = this;
  37243. this._existingCommands = [];
  37244. $.each(that._commandMappings, function(name, _commands) {
  37245. $.each(_commands, function(index, command) {
  37246. if ($.inArray(command.id, that._existingCommands) < 0)
  37247. that._existingCommands.push(command.id)
  37248. })
  37249. })
  37250. }
  37251. });
  37252. DX.framework.CommandMapping.defaultMapping = {
  37253. "global-navigation": {
  37254. defaults: {
  37255. showIcon: true,
  37256. showText: true
  37257. },
  37258. commands: []
  37259. },
  37260. "ios-header-toolbar": {
  37261. defaults: {
  37262. showIcon: false,
  37263. showText: true,
  37264. location: "after"
  37265. },
  37266. commands: ["edit", "save", {
  37267. id: "back",
  37268. location: "before"
  37269. }, {
  37270. id: "cancel",
  37271. location: "before"
  37272. }, {
  37273. id: "create",
  37274. showIcon: true,
  37275. showText: false
  37276. }]
  37277. },
  37278. "ios-action-sheet": {
  37279. defaults: {
  37280. showIcon: false,
  37281. showText: true
  37282. },
  37283. commands: []
  37284. },
  37285. "ios-view-footer": {
  37286. defaults: {
  37287. showIcon: false,
  37288. showText: true
  37289. },
  37290. commands: [{
  37291. id: "delete",
  37292. type: "danger"
  37293. }]
  37294. },
  37295. "android-header-toolbar": {
  37296. defaults: {
  37297. showIcon: true,
  37298. showText: false,
  37299. location: "after"
  37300. },
  37301. commands: [{
  37302. id: "back",
  37303. showIcon: false,
  37304. location: "before"
  37305. }, "create", "edit", "save", {
  37306. id: "cancel",
  37307. showText: true,
  37308. location: "menu"
  37309. }, {
  37310. id: "delete",
  37311. showText: true,
  37312. location: "menu"
  37313. }]
  37314. },
  37315. "android-simple-toolbar": {
  37316. defaults: {
  37317. showIcon: true,
  37318. showText: false,
  37319. location: "after"
  37320. },
  37321. commands: [{
  37322. id: "back",
  37323. showIcon: false,
  37324. location: "before"
  37325. }, {id: "create"}, {
  37326. id: "save",
  37327. showText: true,
  37328. location: "before"
  37329. }, {
  37330. id: "edit",
  37331. showText: true,
  37332. location: "menu"
  37333. }, {
  37334. id: "cancel",
  37335. showText: true,
  37336. location: "menu"
  37337. }, {
  37338. id: "delete",
  37339. showText: true,
  37340. location: "menu"
  37341. }]
  37342. },
  37343. "android-footer-toolbar": {
  37344. defaults: {location: "after"},
  37345. commands: [{
  37346. id: "create",
  37347. showText: false,
  37348. location: "center"
  37349. }, {
  37350. id: "edit",
  37351. showText: false,
  37352. location: "before"
  37353. }, {
  37354. id: "delete",
  37355. location: "menu"
  37356. }, {
  37357. id: "save",
  37358. showIcon: false,
  37359. location: "before"
  37360. }]
  37361. },
  37362. "tizen-header-toolbar": {
  37363. defaults: {
  37364. showIcon: true,
  37365. showText: false,
  37366. location: "after"
  37367. },
  37368. commands: [{
  37369. id: "back",
  37370. showIcon: false,
  37371. location: "before"
  37372. }, "create", "edit", "save", {
  37373. id: "cancel",
  37374. showText: true,
  37375. location: "menu"
  37376. }, {
  37377. id: "delete",
  37378. showText: true,
  37379. location: "menu"
  37380. }]
  37381. },
  37382. "tizen-footer-toolbar": {
  37383. defaults: {location: "after"},
  37384. commands: [{
  37385. id: "create",
  37386. showText: false
  37387. }, {
  37388. id: "edit",
  37389. showText: false,
  37390. location: "before"
  37391. }, {
  37392. id: "delete",
  37393. location: "menu"
  37394. }, {
  37395. id: "save",
  37396. showIcon: false,
  37397. location: "before"
  37398. }]
  37399. },
  37400. "tizen-simple-toolbar": {
  37401. defaults: {
  37402. showIcon: true,
  37403. showText: false,
  37404. location: "after"
  37405. },
  37406. commands: [{
  37407. id: "back",
  37408. showIcon: false,
  37409. location: "before"
  37410. }, {id: "create"}, {
  37411. id: "save",
  37412. showText: true,
  37413. location: "before"
  37414. }, {
  37415. id: "edit",
  37416. showText: true,
  37417. location: "menu"
  37418. }, {
  37419. id: "cancel",
  37420. showText: true,
  37421. location: "menu"
  37422. }, {
  37423. id: "delete",
  37424. showText: true,
  37425. location: "menu"
  37426. }]
  37427. },
  37428. "generic-header-toolbar": {
  37429. defaults: {
  37430. showIcon: false,
  37431. showText: true,
  37432. location: "after"
  37433. },
  37434. commands: ["edit", "save", {
  37435. id: "back",
  37436. location: "before"
  37437. }, {
  37438. id: "cancel",
  37439. location: "before"
  37440. }, {
  37441. id: "create",
  37442. showIcon: true,
  37443. showText: false
  37444. }]
  37445. },
  37446. "generic-view-footer": {
  37447. defaults: {
  37448. showIcon: false,
  37449. showText: true
  37450. },
  37451. commands: [{
  37452. id: "delete",
  37453. type: "danger"
  37454. }]
  37455. },
  37456. "win8-appbar": {
  37457. defaults: {location: "after"},
  37458. commands: ["edit", "cancel", "save", "delete", {
  37459. id: "create",
  37460. location: "before"
  37461. }, {
  37462. id: "refresh",
  37463. location: "before"
  37464. }]
  37465. },
  37466. "win8-toolbar": {
  37467. defaults: {
  37468. showText: false,
  37469. location: "before"
  37470. },
  37471. commands: [{id: "previousPage"}]
  37472. },
  37473. "win8-phone-appbar": {
  37474. defaults: {location: "center"},
  37475. commands: ["create", "edit", "cancel", "save", "refresh", {
  37476. id: "delete",
  37477. location: "menu"
  37478. }]
  37479. },
  37480. "win8-split-toolbar": {
  37481. defaults: {
  37482. showIcon: true,
  37483. showText: false,
  37484. location: "after"
  37485. },
  37486. commands: [{
  37487. id: "back",
  37488. showIcon: false,
  37489. location: "before"
  37490. }, {id: "create"}, {
  37491. id: "save",
  37492. showText: true,
  37493. location: "before"
  37494. }, {
  37495. id: "edit",
  37496. showText: true,
  37497. location: "menu"
  37498. }, {
  37499. id: "cancel",
  37500. showText: true,
  37501. location: "menu"
  37502. }, {
  37503. id: "delete",
  37504. showText: true,
  37505. location: "menu"
  37506. }]
  37507. },
  37508. "win8-master-detail-toolbar": {
  37509. defaults: {
  37510. showText: false,
  37511. location: "before"
  37512. },
  37513. commands: ["back"]
  37514. },
  37515. "desktop-toolbar": {
  37516. defaults: {
  37517. showIcon: false,
  37518. showText: true,
  37519. location: "after"
  37520. },
  37521. commands: ["cancel", "create", "edit", "save", {
  37522. id: "delete",
  37523. type: "danger"
  37524. }]
  37525. }
  37526. }
  37527. })(jQuery, DevExpress);
  37528. /*! Module framework, file framework.viewCache.js */
  37529. (function($, DX, undefined) {
  37530. var Class = DX.Class;
  37531. DX.framework.ViewCache = Class.inherit({
  37532. ctor: function(options) {
  37533. this._cache = {};
  37534. this.viewRemoved = $.Callbacks()
  37535. },
  37536. setView: function(key, viewInfo) {
  37537. this._cache[key] = viewInfo
  37538. },
  37539. getView: function(key) {
  37540. return this._cache[key]
  37541. },
  37542. removeView: function(key) {
  37543. var result = this._cache[key];
  37544. if (result) {
  37545. delete this._cache[key];
  37546. this.viewRemoved.fire({viewInfo: result})
  37547. }
  37548. return result
  37549. },
  37550. clear: function() {
  37551. var that = this;
  37552. $.each(this._cache, function(key) {
  37553. that.removeView(key)
  37554. })
  37555. },
  37556. hasView: function(key) {
  37557. return key in this._cache
  37558. }
  37559. });
  37560. DX.framework.NullViewCache = DX.framework.ViewCache.inherit({setView: function(key, viewInfo) {
  37561. this.callBase(key, viewInfo);
  37562. this.removeView(key)
  37563. }});
  37564. DX.framework.ConditionalViewCacheDecorator = Class.inherit({
  37565. ctor: function(options) {
  37566. this._filter = options.filter;
  37567. this._viewCache = options.viewCache;
  37568. this.viewRemoved = this._viewCache.viewRemoved
  37569. },
  37570. setView: function(key, viewInfo) {
  37571. this._viewCache.setView(key, viewInfo);
  37572. if (!this._filter(key, viewInfo))
  37573. this._viewCache.removeView(key)
  37574. },
  37575. getView: function(key) {
  37576. return this._viewCache.getView(key)
  37577. },
  37578. removeView: function(key) {
  37579. return this._viewCache.removeView(key)
  37580. },
  37581. clear: function() {
  37582. return this._viewCache.clear()
  37583. },
  37584. hasView: function(key) {
  37585. return this._viewCache.hasView(key)
  37586. }
  37587. });
  37588. var DEFAULT_VIEW_CACHE_CAPACITY = 10;
  37589. DX.framework.CapacityViewCacheDecorator = Class.inherit({
  37590. ctor: function(options) {
  37591. this._keys = [];
  37592. this._size = options.size || DEFAULT_VIEW_CACHE_CAPACITY;
  37593. this._viewCache = options.viewCache;
  37594. this.viewRemoved = this._viewCache.viewRemoved
  37595. },
  37596. setView: function(key, viewInfo) {
  37597. if (!this.hasView(key)) {
  37598. if (this._keys.length == this._size)
  37599. this.removeView(this._keys[0]);
  37600. this._keys.push(key)
  37601. }
  37602. this._viewCache.setView(key, viewInfo)
  37603. },
  37604. getView: function(key) {
  37605. var index = $.inArray(key, this._keys);
  37606. if (index < 0)
  37607. return null;
  37608. this._keys.push(key);
  37609. this._keys.splice(index, 1);
  37610. return this._viewCache.getView(key)
  37611. },
  37612. removeView: function(key) {
  37613. var index = $.inArray(key, this._keys);
  37614. if (index > -1)
  37615. this._keys.splice(index, 1);
  37616. return this._viewCache.removeView(key)
  37617. },
  37618. clear: function() {
  37619. this._keys = [];
  37620. return this._viewCache.clear()
  37621. },
  37622. hasView: function(key) {
  37623. return this._viewCache.hasView(key)
  37624. }
  37625. });
  37626. DX.framework.HistoryDependentViewCacheDecorator = Class.inherit({
  37627. ctor: function(options) {
  37628. this._viewCache = options.viewCache || new DX.framework.ViewCache;
  37629. this._navigationManager = options.navigationManager;
  37630. this._navigationManager.itemRemoved.add($.proxy(this._onNavigationItemRemoved, this));
  37631. this.viewRemoved = this._viewCache.viewRemoved
  37632. },
  37633. _onNavigationItemRemoved: function(item) {
  37634. this.removeView(item.key)
  37635. },
  37636. setView: function(key, viewInfo) {
  37637. this._viewCache.setView(key, viewInfo)
  37638. },
  37639. getView: function(key) {
  37640. return this._viewCache.getView(key)
  37641. },
  37642. removeView: function(key) {
  37643. return this._viewCache.removeView(key)
  37644. },
  37645. clear: function() {
  37646. return this._viewCache.clear()
  37647. },
  37648. hasView: function(key) {
  37649. return this._viewCache.hasView(key)
  37650. }
  37651. })
  37652. })(jQuery, DevExpress);
  37653. /*! Module framework, file framework.stateManager.js */
  37654. (function($, DX, undefined) {
  37655. var Class = DX.Class;
  37656. DX.framework.MemoryKeyValueStorage = Class.inherit({
  37657. ctor: function() {
  37658. this.storage = {}
  37659. },
  37660. getItem: function(key) {
  37661. return this.storage[key]
  37662. },
  37663. setItem: function(key, value) {
  37664. this.storage[key] = value
  37665. },
  37666. removeItem: function(key) {
  37667. delete this.storage[key]
  37668. }
  37669. });
  37670. DX.framework.StateManager = Class.inherit({
  37671. ctor: function(options) {
  37672. options = options || {};
  37673. this.storage = options.storage || new DX.framework.MemoryKeyValueStorage;
  37674. this.stateSources = options.stateSources || []
  37675. },
  37676. addStateSource: function(stateSource) {
  37677. this.stateSources.push(stateSource)
  37678. },
  37679. removeStateSource: function(stateSource) {
  37680. var index = $.inArray(stateSource, this.stateSources);
  37681. if (index > -1) {
  37682. this.stateSources.splice(index, 1);
  37683. stateSource.removeState(this.storage)
  37684. }
  37685. },
  37686. saveState: function() {
  37687. var that = this;
  37688. $.each(this.stateSources, function(index, stateSource) {
  37689. stateSource.saveState(that.storage)
  37690. })
  37691. },
  37692. restoreState: function() {
  37693. var that = this;
  37694. $.each(this.stateSources, function(index, stateSource) {
  37695. stateSource.restoreState(that.storage)
  37696. })
  37697. },
  37698. clearState: function() {
  37699. var that = this;
  37700. $.each(this.stateSources, function(index, stateSource) {
  37701. stateSource.removeState(that.storage)
  37702. })
  37703. }
  37704. })
  37705. })(jQuery, DevExpress);
  37706. /*! Module framework, file framework.browserAdapters.js */
  37707. (function($, DX, undefined) {
  37708. var Class = DX.Class;
  37709. var ROOT_PAGE_URL = "__root__",
  37710. BUGGY_ANDROID_BUFFER_PAGE_URL = "__buffer__";
  37711. DX.framework.DefaultBrowserAdapter = Class.inherit({
  37712. ctor: function(options) {
  37713. options = options || {};
  37714. this._window = options.window || window;
  37715. this.popState = $.Callbacks();
  37716. $(this._window).on("hashchange", $.proxy(this._onHashChange, this));
  37717. this._tasks = DX.createQueue();
  37718. this.canWorkInPureBrowser = true
  37719. },
  37720. replaceState: function(uri) {
  37721. var that = this;
  37722. return this._addTask(function() {
  37723. uri = that._normalizeUri(uri);
  37724. that._window.history.replaceState(null, null, "#" + uri);
  37725. that._currentTask.resolve()
  37726. })
  37727. },
  37728. pushState: function(uri) {
  37729. var that = this;
  37730. return this._addTask(function() {
  37731. uri = that._normalizeUri(uri);
  37732. that._window.history.pushState(null, null, "#" + uri);
  37733. that._currentTask.resolve()
  37734. })
  37735. },
  37736. createRootPage: function() {
  37737. return this.replaceState(ROOT_PAGE_URL)
  37738. },
  37739. _onHashChange: function() {
  37740. if (this._currentTask)
  37741. this._currentTask.resolve();
  37742. this.popState.fire()
  37743. },
  37744. back: function() {
  37745. var that = this;
  37746. return this._addTask(function() {
  37747. that._window.history.back()
  37748. })
  37749. },
  37750. getHash: function() {
  37751. return this._normalizeUri(this._window.location.hash)
  37752. },
  37753. isRootPage: function() {
  37754. return this.getHash() === ROOT_PAGE_URL
  37755. },
  37756. _normalizeUri: function(uri) {
  37757. return (uri || "").replace(/^#+/, "")
  37758. },
  37759. _addTask: function(task) {
  37760. var that = this,
  37761. d = $.Deferred();
  37762. this._tasks.add(function() {
  37763. that._currentTask = d;
  37764. task();
  37765. return d
  37766. });
  37767. return d.promise()
  37768. }
  37769. });
  37770. DX.framework.OldBrowserAdapter = DX.framework.DefaultBrowserAdapter.inherit({
  37771. ctor: function() {
  37772. this._innerEventCount = 0;
  37773. this.callBase.apply(this, arguments);
  37774. this._skipNextEvent = false
  37775. },
  37776. replaceState: function(uri) {
  37777. var that = this;
  37778. uri = that._normalizeUri(uri);
  37779. if (that.getHash() !== uri) {
  37780. that._addTask(function() {
  37781. that._skipNextEvent = true;
  37782. that._window.history.back()
  37783. });
  37784. return that._addTask(function() {
  37785. that._skipNextEvent = true;
  37786. that._window.location.hash = uri
  37787. })
  37788. }
  37789. return $.Deferred().resolve().promise()
  37790. },
  37791. pushState: function(uri) {
  37792. var that = this;
  37793. uri = this._normalizeUri(uri);
  37794. if (this.getHash() !== uri)
  37795. return that._addTask(function() {
  37796. that._skipNextEvent = true;
  37797. that._window.location.hash = uri
  37798. });
  37799. return $.Deferred().resolve().promise()
  37800. },
  37801. createRootPage: function() {
  37802. return this.pushState(ROOT_PAGE_URL)
  37803. },
  37804. _onHashChange: function() {
  37805. var currentTask = this._currentTask;
  37806. this._currentTask = null;
  37807. if (this._skipNextEvent)
  37808. this._skipNextEvent = false;
  37809. else
  37810. this.popState.fire();
  37811. if (currentTask)
  37812. currentTask.resolve()
  37813. }
  37814. });
  37815. DX.framework.BuggyAndroidBrowserAdapter = DX.framework.OldBrowserAdapter.inherit({createRootPage: function() {
  37816. this.pushState(BUGGY_ANDROID_BUFFER_PAGE_URL);
  37817. return this.callBase()
  37818. }});
  37819. DX.framework.HistorylessBrowserAdapter = DX.framework.DefaultBrowserAdapter.inherit({
  37820. ctor: function(options) {
  37821. options = options || {};
  37822. this._window = options.window || window;
  37823. this.popState = $.Callbacks();
  37824. $(this._window).on("dxback", $.proxy(this._onHashChange, this));
  37825. this._currentHash = this._window.location.hash
  37826. },
  37827. replaceState: function(uri) {
  37828. this._currentHash = this._normalizeUri(uri);
  37829. return $.Deferred().resolve().promise()
  37830. },
  37831. pushState: function(uri) {
  37832. return this.replaceState(uri)
  37833. },
  37834. createRootPage: function() {
  37835. return this.replaceState(ROOT_PAGE_URL)
  37836. },
  37837. getHash: function() {
  37838. return this._normalizeUri(this._currentHash)
  37839. },
  37840. back: function() {
  37841. return this.replaceState(ROOT_PAGE_URL)
  37842. },
  37843. _onHashChange: function() {
  37844. var promise = this.back();
  37845. this.popState.fire();
  37846. return promise
  37847. }
  37848. });
  37849. DX.framework.BuggyCordovaWP81BrowserAdapter = DX.framework.DefaultBrowserAdapter.inherit({ctor: function(options) {
  37850. this.callBase(options);
  37851. this.canWorkInPureBrowser = false
  37852. }})
  37853. })(jQuery, DevExpress);
  37854. /*! Module framework, file framework.navigationDevices.js */
  37855. (function($, DX, undefined) {
  37856. var Class = DX.Class;
  37857. var SESSION_KEY = "dxPhoneJSApplication";
  37858. DX.framework.HistoryBasedNavigationDevice = Class.inherit({
  37859. ctor: function(options) {
  37860. options = options || {};
  37861. this._browserAdapter = options.browserAdapter || this._createBrowserAdapter(options);
  37862. this.uriChanged = $.Callbacks();
  37863. this._browserAdapter.popState.add($.proxy(this._onPopState, this))
  37864. },
  37865. init: $.noop,
  37866. getUri: function() {
  37867. return this._browserAdapter.getHash()
  37868. },
  37869. setUri: function(uri, replaceCurrent) {
  37870. if (replaceCurrent)
  37871. return this._browserAdapter.replaceState(uri);
  37872. return this._browserAdapter.pushState(uri)
  37873. },
  37874. back: function() {
  37875. return this._browserAdapter.back()
  37876. },
  37877. _onPopState: function() {
  37878. this.uriChanged.fire(this.getUri())
  37879. },
  37880. _isBuggyAndroid2: function() {
  37881. var realDevice = DX.devices.real();
  37882. var version = realDevice.version;
  37883. return realDevice.platform === "android" && version.length > 1 && (version[0] === 2 && version[1] < 4 || version[0] < 2)
  37884. },
  37885. _isBuggyAndroid4: function() {
  37886. var realDevice = DX.devices.real();
  37887. var version = realDevice.version;
  37888. return realDevice.platform === "android" && version.length > 1 && version[0] === 4 && version[1] === 0
  37889. },
  37890. _isWindowsPhone8: function() {
  37891. var realDevice = DX.devices.real();
  37892. return realDevice.platform === "win8" && realDevice.phone
  37893. },
  37894. _createBrowserAdapter: function(options) {
  37895. var sourceWindow = options.window || window,
  37896. supportPushReplace = sourceWindow.history.replaceState && sourceWindow.history.pushState,
  37897. result;
  37898. if (this._isWindowsPhone8())
  37899. result = new DX.framework.BuggyCordovaWP81BrowserAdapter(options);
  37900. else if (sourceWindow !== sourceWindow.top)
  37901. result = new DX.framework.HistorylessBrowserAdapter(options);
  37902. else if (this._isBuggyAndroid4())
  37903. result = new DX.framework.BuggyAndroidBrowserAdapter(options);
  37904. else if (this._isBuggyAndroid2() || !supportPushReplace)
  37905. result = new DX.framework.OldBrowserAdapter(options);
  37906. else
  37907. result = new DX.framework.DefaultBrowserAdapter(options);
  37908. return result
  37909. }
  37910. });
  37911. DX.framework.StackBasedNavigationDevice = DX.framework.HistoryBasedNavigationDevice.inherit({
  37912. ctor: function(options) {
  37913. this.callBase(options);
  37914. this.backInitiated = $.Callbacks();
  37915. this._deferredNavigate = null;
  37916. $(window).on("unload", this._saveBrowserState)
  37917. },
  37918. init: function() {
  37919. var that = this;
  37920. if (that._browserAdapter.canWorkInPureBrowser)
  37921. return that._initRootPage().done(function() {
  37922. if (that._browserAdapter.isRootPage())
  37923. that._browserAdapter.pushState("")
  37924. });
  37925. else
  37926. return $.Deferred().resolve().promise()
  37927. },
  37928. setUri: function(uri) {
  37929. return this.callBase(uri, !this._browserAdapter.isRootPage())
  37930. },
  37931. _saveBrowserState: function() {
  37932. if (window.sessionStorage)
  37933. sessionStorage.setItem(SESSION_KEY, true)
  37934. },
  37935. _initRootPage: function() {
  37936. var hash = this.getUri();
  37937. if (!window.sessionStorage || sessionStorage.getItem(SESSION_KEY))
  37938. return $.Deferred().resolve().promise();
  37939. sessionStorage.removeItem(SESSION_KEY);
  37940. this._browserAdapter.createRootPage();
  37941. return this._browserAdapter.pushState(hash)
  37942. },
  37943. _onPopState: function() {
  37944. var navigationPending = this._deferredNavigate && this._deferredNavigate.state() === "pending";
  37945. if (this._browserAdapter.isRootPage())
  37946. if (navigationPending)
  37947. this._deferredNavigate.resolve();
  37948. else
  37949. this.backInitiated.fire();
  37950. else {
  37951. if (!navigationPending)
  37952. this._deferredNavigate = $.Deferred().done($.proxy(this.callBase, this));
  37953. this.back()
  37954. }
  37955. }
  37956. })
  37957. })(jQuery, DevExpress);
  37958. /*! Module framework, file framework.navigationManager.js */
  37959. (function($, DX, undefined) {
  37960. var Class = DX.Class;
  37961. var NAVIGATION_TARGETS = {
  37962. current: "current",
  37963. blank: "blank",
  37964. back: "back"
  37965. },
  37966. STORAGE_HISTORY_KEY = "__history";
  37967. DX.framework.HistoryBasedNavigationManager = Class.inherit({
  37968. ctor: function(options) {
  37969. options = options || {};
  37970. this._currentItem = undefined;
  37971. this._previousItem = undefined;
  37972. this.navigating = $.Callbacks();
  37973. this.navigated = $.Callbacks();
  37974. this.navigationCanceled = $.Callbacks();
  37975. this.navigatingBack = $.Callbacks();
  37976. this.itemRemoved = $.Callbacks();
  37977. this._createNavigationDevice(options)
  37978. },
  37979. _createNavigationDevice: function(options) {
  37980. this._navigationDevice = options.navigationDevice || new DX.framework.HistoryBasedNavigationDevice;
  37981. this._navigationDevice.uriChanged.add($.proxy(this._uriChangedHandler, this))
  37982. },
  37983. _uriChangedHandler: function(uri) {
  37984. while (DX.hideTopOverlayCallback.fire());
  37985. this.navigate(uri, {target: "none"})
  37986. },
  37987. _cancelNavigation: function(args) {
  37988. this.navigationCanceled.fire(args)
  37989. },
  37990. _getDefaultOptions: function() {
  37991. return {
  37992. direction: "none",
  37993. target: NAVIGATION_TARGETS.blank
  37994. }
  37995. },
  37996. _updateHistory: function(uri, options) {
  37997. this._previousItem = this._currentItem;
  37998. this._currentItem = {
  37999. uri: uri,
  38000. key: uri
  38001. };
  38002. if (options.target !== "none")
  38003. this._navigationDevice.setUri(uri, options.target === "current")
  38004. },
  38005. navigate: function(uri, options) {
  38006. options = options || {};
  38007. var that = this,
  38008. currentItem = that._currentItem || {},
  38009. targetItem = options.item || {},
  38010. currentUri = currentItem.uri,
  38011. currentKey = currentItem.key,
  38012. targetKey = targetItem.key,
  38013. args;
  38014. if (uri === undefined)
  38015. uri = that._navigationDevice.getUri();
  38016. if (/^_back$/.test(uri)) {
  38017. that.back();
  38018. return
  38019. }
  38020. options = $.extend(that._getDefaultOptions(), options || {});
  38021. args = {
  38022. currentUri: currentUri,
  38023. uri: uri,
  38024. cancel: false,
  38025. navigateWhen: [],
  38026. options: options
  38027. };
  38028. that.navigating.fire(args);
  38029. uri = args.uri;
  38030. if (args.cancel || currentUri === uri && (targetKey === undefined || targetKey === currentKey) && !that._forceNavigate)
  38031. that._cancelNavigation(args);
  38032. else {
  38033. that._forceNavigate = false;
  38034. $.when.apply($, args.navigateWhen).done(function() {
  38035. DX.utils.executeAsync(function() {
  38036. that._updateHistory(uri, options);
  38037. that.navigated.fire({
  38038. uri: uri,
  38039. previousUri: currentUri,
  38040. options: options,
  38041. item: that._currentItem
  38042. })
  38043. })
  38044. })
  38045. }
  38046. },
  38047. back: function() {
  38048. return this._navigationDevice.back()
  38049. },
  38050. previousItem: function() {
  38051. return this._previousItem
  38052. },
  38053. currentItem: function() {
  38054. return this._currentItem
  38055. },
  38056. rootUri: function() {
  38057. return this._currentItem && this._currentItem.uri
  38058. },
  38059. canBack: function() {
  38060. return true
  38061. },
  38062. saveState: $.noop,
  38063. restoreState: $.noop,
  38064. removeState: $.noop
  38065. });
  38066. DX.framework.StackBasedNavigationManager = DX.framework.HistoryBasedNavigationManager.inherit({
  38067. ctor: function(options) {
  38068. options = options || {};
  38069. this.callBase(options);
  38070. this._createNavigationStacks(options);
  38071. DX.hardwareBackButton.add($.proxy(this._deviceBackInitiated, this));
  38072. this._stateStorageKey = options.stateStorageKey || STORAGE_HISTORY_KEY
  38073. },
  38074. init: function() {
  38075. return this._navigationDevice.init()
  38076. },
  38077. _createNavigationDevice: function(options) {
  38078. if (!options.navigationDevice)
  38079. options.navigationDevice = new DX.framework.StackBasedNavigationDevice;
  38080. this.callBase(options);
  38081. this._navigationDevice.backInitiated.add($.proxy(this._deviceBackInitiated, this))
  38082. },
  38083. _uriChangedHandler: function(uri) {
  38084. this.navigate(uri)
  38085. },
  38086. _createNavigationStacks: function(options) {
  38087. this.navigationStacks = {};
  38088. this._keepPositionInStack = options.keepPositionInStack;
  38089. this.currentStack = new DX.framework.NavigationStack
  38090. },
  38091. _deviceBackInitiated: function() {
  38092. if (!DX.hideTopOverlayCallback.fire())
  38093. this.back({isHardwareButton: true});
  38094. else
  38095. this._restoreDevicePreviousUri()
  38096. },
  38097. _restoreDevicePreviousUri: function() {
  38098. var currentUri = this._currentItem && this._currentItem.uri;
  38099. this._navigationDevice.setUri(currentUri)
  38100. },
  38101. _cancelNavigation: function(args) {
  38102. this._restoreDevicePreviousUri();
  38103. this.callBase(args)
  38104. },
  38105. _getDefaultOptions: function() {
  38106. return {target: NAVIGATION_TARGETS.blank}
  38107. },
  38108. _createNavigationStack: function() {
  38109. var result = new DX.framework.NavigationStack;
  38110. result.itemsRemoved.add($.proxy(this._removeItems, this));
  38111. return result
  38112. },
  38113. _setCurrentStack: function(stackKey) {
  38114. if (!(stackKey in this.navigationStacks))
  38115. this.navigationStacks[stackKey] = this._createNavigationStack();
  38116. this.currentStack = this.navigationStacks[stackKey];
  38117. this.currentStackKey = stackKey
  38118. },
  38119. _updateHistory: function(uri, options) {
  38120. var isRoot = options.root,
  38121. forceIsRoot = isRoot,
  38122. forceToRoot = false,
  38123. stackKey = options.stack || (isRoot ? uri : this.currentStackKey || uri),
  38124. previousStack = this.currentStack,
  38125. keepPositionInStack = options.keepPositionInStack !== undefined ? options.keepPositionInStack : this._keepPositionInStack;
  38126. this._setCurrentStack(stackKey);
  38127. if (isRoot || !this.currentStack.items.length) {
  38128. forceToRoot = this.currentStack === previousStack;
  38129. forceIsRoot = true
  38130. }
  38131. if (isRoot && this.currentStack.items.length) {
  38132. if (!keepPositionInStack || forceToRoot) {
  38133. this.currentStack.currentIndex = 0;
  38134. if (this.currentItem().uri !== uri)
  38135. this.currentStack.navigate(uri, true)
  38136. }
  38137. }
  38138. else {
  38139. var prevIndex = this.currentStack.currentIndex,
  38140. prevItem = this.currentItem() || {};
  38141. switch (options.target) {
  38142. case NAVIGATION_TARGETS.blank:
  38143. this.currentStack.navigate(uri);
  38144. break;
  38145. case NAVIGATION_TARGETS.current:
  38146. this.currentStack.navigate(uri, true);
  38147. break;
  38148. case NAVIGATION_TARGETS.back:
  38149. if (this.currentStack.currentIndex > 0)
  38150. this.currentStack.back(uri);
  38151. else
  38152. this.currentStack.navigate(uri, true);
  38153. break;
  38154. default:
  38155. throw Error(DX.utils.stringFormat("Unknown navigation target: \"{0}\". Use the DevExpress.framework.StackBasedNavigationManager.NAVIGATION_TARGETS enumerable values", options.target));
  38156. }
  38157. if (options.direction === undefined) {
  38158. var indexDelta = this.currentStack.currentIndex - prevIndex;
  38159. if (indexDelta < 0)
  38160. options.direction = this.currentStack.currentItem().backDirection || "backward";
  38161. else if (indexDelta > 0 && this.currentStack.currentIndex > 0)
  38162. options.direction = "forward";
  38163. else
  38164. options.direction = "none"
  38165. }
  38166. prevItem.backDirection = options.direction === "forward" ? "backward" : "none"
  38167. }
  38168. options.root = forceIsRoot;
  38169. this._currentItem = this.currentStack.currentItem();
  38170. this._restoreDevicePreviousUri()
  38171. },
  38172. _removeItems: function(items) {
  38173. var that = this;
  38174. $.each(items, function(index, item) {
  38175. that.itemRemoved.fire(item)
  38176. })
  38177. },
  38178. back: function(options) {
  38179. options = options || {};
  38180. var navigatingBackArgs = $.extend({cancel: false}, options);
  38181. this.navigatingBack.fire(navigatingBackArgs);
  38182. if (navigatingBackArgs.cancel) {
  38183. this._restoreDevicePreviousUri();
  38184. return
  38185. }
  38186. var item = this.previousItem(navigatingBackArgs.stack);
  38187. if (item)
  38188. this.navigate(item.uri, {
  38189. stack: navigatingBackArgs.stack,
  38190. target: NAVIGATION_TARGETS.back,
  38191. item: item
  38192. });
  38193. else
  38194. this.callBase()
  38195. },
  38196. rootUri: function() {
  38197. return this.currentStack.items.length ? this.currentStack.items[0].uri : this.callBase()
  38198. },
  38199. canBack: function(stackKey) {
  38200. var stack = stackKey ? this.navigationStacks[stackKey] : this.currentStack;
  38201. return stack.canBack()
  38202. },
  38203. saveState: function(storage) {
  38204. if (this.currentStack.items.length) {
  38205. var state = {
  38206. items: this.currentStack.items,
  38207. currentIndex: this.currentStack.currentIndex,
  38208. currentStackKey: this.currentStack.items[0].uri
  38209. };
  38210. var json = JSON.stringify(state);
  38211. storage.setItem(this._stateStorageKey, json)
  38212. }
  38213. else
  38214. this.removeState(storage)
  38215. },
  38216. restoreState: function(storage) {
  38217. if (this.disableRestoreState)
  38218. return;
  38219. var json = storage.getItem(this._stateStorageKey);
  38220. if (json)
  38221. try {
  38222. var state = JSON.parse(json),
  38223. stack = this._createNavigationStack();
  38224. if (!state.items[0].uri)
  38225. throw Error("Error while application state restoring. State has been cleared. Refresh the page");
  38226. stack.items = state.items;
  38227. stack.currentIndex = state.currentIndex;
  38228. this.navigationStacks[stack.items[0].uri] = stack;
  38229. this.currentStackKey = state.currentStackKey;
  38230. this.currentStack = this.navigationStacks[this.currentStackKey];
  38231. this._currentItem = this.currentStack.currentItem();
  38232. this._navigationDevice.setUri(this.currentItem().uri);
  38233. this._forceNavigate = true
  38234. }
  38235. catch(e) {
  38236. this.removeState(storage);
  38237. throw e;
  38238. }
  38239. },
  38240. removeState: function(storage) {
  38241. storage.removeItem(this._stateStorageKey)
  38242. },
  38243. currentIndex: function() {
  38244. return this.currentStack.currentIndex
  38245. },
  38246. previousItem: function(stackKey) {
  38247. var stack = stackKey ? this.navigationStacks[stackKey] : this.currentStack;
  38248. return stack.previousItem()
  38249. },
  38250. getItemByIndex: function(index) {
  38251. return this.currentStack.items[index]
  38252. },
  38253. clearHistory: function() {
  38254. this.currentStack.clear()
  38255. }
  38256. });
  38257. DX.framework.NavigationStack = Class.inherit({
  38258. ctor: function(options) {
  38259. options = options || {};
  38260. this.itemsRemoved = $.Callbacks();
  38261. this.clear()
  38262. },
  38263. currentItem: function() {
  38264. return this.items[this.currentIndex]
  38265. },
  38266. previousItem: function() {
  38267. return this.items.length > 1 ? this.items[this.currentIndex - 1] : undefined
  38268. },
  38269. canBack: function() {
  38270. return this.currentIndex > 0
  38271. },
  38272. clear: function() {
  38273. this._deleteItems(this.items);
  38274. this.items = [];
  38275. this.currentIndex = -1
  38276. },
  38277. back: function(uri) {
  38278. this.currentIndex--;
  38279. if (this.currentIndex < 0)
  38280. throw Error("Unable to go back");
  38281. var currentItem = this.currentItem();
  38282. if (currentItem.uri !== uri)
  38283. this._updateItem(this.currentIndex, uri)
  38284. },
  38285. forward: function() {
  38286. this.currentIndex++;
  38287. if (this.currentIndex >= this.items.length)
  38288. throw Error("Unable to go forward");
  38289. },
  38290. navigate: function(uri, replaceCurrent) {
  38291. if (this.currentIndex < this.items.length && this.currentIndex > -1 && this.items[this.currentIndex].uri === uri)
  38292. return;
  38293. if (replaceCurrent && this.currentIndex > -1)
  38294. this.currentIndex--;
  38295. if (this.currentIndex + 1 < this.items.length && this.items[this.currentIndex + 1].uri === uri)
  38296. this.currentIndex++;
  38297. else {
  38298. var toDelete = this.items.splice(this.currentIndex + 1, this.items.length - this.currentIndex - 1);
  38299. this.items.push({});
  38300. this.currentIndex++;
  38301. this._updateItem(this.currentIndex, uri);
  38302. this._deleteItems(toDelete)
  38303. }
  38304. return this.currentItem()
  38305. },
  38306. _updateItem: function(index, uri) {
  38307. var item = this.items[index];
  38308. item.uri = uri;
  38309. item.key = this.items[0].uri + "_" + index + "_" + uri
  38310. },
  38311. _deleteItems: function(items) {
  38312. if (items)
  38313. this.itemsRemoved.fire(items)
  38314. }
  38315. });
  38316. DX.framework.HistoryBasedNavigationManager.NAVIGATION_TARGETS = NAVIGATION_TARGETS
  38317. })(jQuery, DevExpress);
  38318. /*! Module framework, file framework.actionExecutors.js */
  38319. (function($, DX, undefined) {
  38320. DX.framework.createActionExecutors = function(app) {
  38321. return {
  38322. routing: {execute: function(e) {
  38323. var action = e.action,
  38324. routeValues,
  38325. options,
  38326. uri;
  38327. if ($.isPlainObject(action)) {
  38328. routeValues = action.routeValues;
  38329. if (routeValues && $.isPlainObject(routeValues))
  38330. options = action.options;
  38331. else
  38332. routeValues = action;
  38333. uri = app.router.format(routeValues);
  38334. app.navigate(uri, options);
  38335. e.handled = true
  38336. }
  38337. }},
  38338. hash: {execute: function(e) {
  38339. if (typeof e.action !== "string" || e.action.charAt(0) !== "#")
  38340. return;
  38341. var uriTemplate = e.action.substr(1),
  38342. args = e.args[0],
  38343. uri = uriTemplate;
  38344. var defaultEvaluate = function(expr) {
  38345. var getter = DX.data.utils.compileGetter(expr),
  38346. model = e.args[0].model;
  38347. return getter(model)
  38348. };
  38349. var evaluate = args.evaluate || defaultEvaluate;
  38350. uri = uriTemplate.replace(/\{([^}]+)\}/g, function(entry, expr) {
  38351. expr = $.trim(expr);
  38352. if (expr.indexOf(",") > -1)
  38353. expr = $.map(expr.split(","), $.trim);
  38354. var value = evaluate(expr);
  38355. if (value === undefined)
  38356. value = "";
  38357. value = DX.framework.Route.prototype.formatSegment(value);
  38358. return value
  38359. });
  38360. var navigateOptions = (e.component || {}).NAME === "dxCommand" ? e.component.option() : {};
  38361. app.navigate(uri, navigateOptions);
  38362. e.handled = true
  38363. }}
  38364. }
  38365. }
  38366. })(jQuery, DevExpress);
  38367. /*! Module framework, file framework.application.js */
  38368. (function($, DX) {
  38369. var Class = DX.Class,
  38370. BACK_COMMAND_TITLE,
  38371. INIT_IN_PROGRESS = "InProgress",
  38372. INIT_COMPLETE = "Inited",
  38373. frameworkNS = DX.framework;
  38374. DX.framework.Application = Class.inherit({
  38375. ctor: function(options) {
  38376. options = options || {};
  38377. this._options = options;
  38378. this.namespace = options.namespace || options.ns || window;
  38379. this._applicationMode = options.mode ? options.mode : "mobileApp";
  38380. this.components = [];
  38381. BACK_COMMAND_TITLE = DX.localization.localizeString("@Back");
  38382. this.router = options.router || new DX.framework.MvcRouter;
  38383. var navigationManagers = {
  38384. mobileApp: DX.framework.StackBasedNavigationManager,
  38385. webSite: DX.framework.HistoryBasedNavigationManager
  38386. };
  38387. this.navigationManager = options.navigationManager || new navigationManagers[this._applicationMode]({keepPositionInStack: options.navigateToRootViewMode === "keepHistory"});
  38388. this.navigationManager.navigating.add($.proxy(this._onNavigating, this));
  38389. this.navigationManager.navigatingBack.add($.proxy(this._onNavigatingBack, this));
  38390. this.navigationManager.navigated.add($.proxy(this._onNavigated, this));
  38391. this.navigationManager.navigationCanceled.add($.proxy(this._onNavigationCanceled, this));
  38392. this.stateManager = options.stateManager || new DX.framework.StateManager({storage: options.stateStorage || sessionStorage});
  38393. this.stateManager.addStateSource(this.navigationManager);
  38394. this.viewCache = this._createViewCache(options);
  38395. this.commandMapping = this._createCommandMapping(options.commandMapping);
  38396. this.createNavigation(options.navigation);
  38397. this.beforeViewSetup = $.Callbacks();
  38398. this.afterViewSetup = $.Callbacks();
  38399. this.viewShowing = $.Callbacks();
  38400. this.viewShown = $.Callbacks();
  38401. this.viewHidden = $.Callbacks();
  38402. this.viewDisposing = $.Callbacks();
  38403. this.viewDisposed = $.Callbacks();
  38404. this.navigating = $.Callbacks();
  38405. this.navigatingBack = $.Callbacks();
  38406. this.initialized = $.Callbacks();
  38407. this._isNavigating = false;
  38408. this._viewLinksHash = {};
  38409. DX.registerActionExecutor(DX.framework.createActionExecutors(this));
  38410. DX.overlayTargetContainer(".dx-viewport");
  38411. this.components.push(this.router);
  38412. this.components.push(this.navigationManager)
  38413. },
  38414. _createViewCache: function(options) {
  38415. var result;
  38416. if (options.viewCache)
  38417. result = options.viewCache;
  38418. else if (options.disableViewCache)
  38419. result = new DX.framework.NullViewCache;
  38420. else
  38421. result = new DX.framework.CapacityViewCacheDecorator({
  38422. size: options.viewCacheSize,
  38423. viewCache: new DX.framework.ViewCache
  38424. });
  38425. result.viewRemoved.add($.proxy(function(e) {
  38426. this._releaseViewLink(e.viewInfo)
  38427. }, this));
  38428. return result
  38429. },
  38430. _createCommandMapping: function(commandMapping) {
  38431. var result = commandMapping;
  38432. if (!(commandMapping instanceof DX.framework.CommandMapping)) {
  38433. result = new DX.framework.CommandMapping;
  38434. result.load(DX.framework.CommandMapping.defaultMapping || {}).load(commandMapping || {})
  38435. }
  38436. return result
  38437. },
  38438. createNavigation: function(navigationConfig) {
  38439. this.navigation = this._createNavigationCommands(navigationConfig);
  38440. this._mapNavigationCommands(this.navigation, this.commandMapping)
  38441. },
  38442. _createNavigationCommands: function(commandConfig) {
  38443. if (!commandConfig)
  38444. return [];
  38445. var that = this,
  38446. generatedIdCount = 0;
  38447. return $.map(commandConfig, function(item) {
  38448. var command;
  38449. if (item instanceof frameworkNS.dxCommand)
  38450. command = item;
  38451. else
  38452. command = new frameworkNS.dxCommand($.extend({root: true}, item));
  38453. if (!command.option("id"))
  38454. command.option("id", "navigation_" + generatedIdCount++);
  38455. return command
  38456. })
  38457. },
  38458. _mapNavigationCommands: function(navigationCommands, commandMapping) {
  38459. var navigationCommandIds = $.map(navigationCommands, function(command) {
  38460. return command.option("id")
  38461. });
  38462. commandMapping.mapCommands("global-navigation", navigationCommandIds)
  38463. },
  38464. _callComponentMethod: function(methodName, args) {
  38465. var tasks = [];
  38466. $.each(this.components, function(index, component) {
  38467. if (component[methodName] && $.isFunction(component[methodName])) {
  38468. var result = component[methodName](args);
  38469. if (result && result.done)
  38470. tasks.push(result)
  38471. }
  38472. });
  38473. return $.when.apply($, tasks)
  38474. },
  38475. init: function() {
  38476. var that = this;
  38477. that._initState = INIT_IN_PROGRESS;
  38478. return that._callComponentMethod("init").done(function() {
  38479. that._initState = INIT_COMPLETE;
  38480. that._processEvent("initialized")
  38481. })
  38482. },
  38483. _onNavigatingBack: function(args) {
  38484. this._processEvent("navigatingBack", args)
  38485. },
  38486. _onNavigating: function(args) {
  38487. var that = this;
  38488. if (that._isNavigating) {
  38489. that._pendingNavigationArgs = args;
  38490. args.cancel = true;
  38491. return
  38492. }
  38493. else {
  38494. that._isNavigating = true;
  38495. delete that._pendingNavigationArgs
  38496. }
  38497. var routeData = this.router.parse(args.uri);
  38498. if (!routeData)
  38499. throw new Error(DX.utils.stringFormat("Routing rule is not found for the \"{0}\" url", args.uri));
  38500. var uri = this.router.format(routeData);
  38501. if (args.uri !== uri && uri) {
  38502. args.cancel = true;
  38503. DX.utils.executeAsync(function() {
  38504. that.navigate(uri, args.options)
  38505. })
  38506. }
  38507. else
  38508. that._processEvent("navigating", args)
  38509. },
  38510. _onNavigated: function(args) {
  38511. var that = this,
  38512. direction = args.options.direction,
  38513. deferred = $.Deferred(),
  38514. viewInfo = that._acquireViewInfo(args.item, args.options);
  38515. if (!that._isViewReadyToShow(viewInfo))
  38516. that._setViewLoadingState(viewInfo, direction).done(function() {
  38517. DX.utils.executeAsync(function() {
  38518. that._createViewModel(viewInfo);
  38519. that._createViewCommands(viewInfo);
  38520. deferred.resolve()
  38521. })
  38522. }).fail(function() {
  38523. that._isNavigating = false;
  38524. deferred.reject()
  38525. });
  38526. else
  38527. deferred.resolve();
  38528. deferred.done(function() {
  38529. that._highlightCurrentNavigationCommand(viewInfo);
  38530. that._showView(viewInfo, direction).always(function() {
  38531. that._isNavigating = false;
  38532. var pendingArgs = that._pendingNavigationArgs;
  38533. if (pendingArgs)
  38534. DX.utils.executeAsync(function() {
  38535. that.navigate(pendingArgs.uri, pendingArgs.options)
  38536. })
  38537. })
  38538. })
  38539. },
  38540. _isViewReadyToShow: function(viewInfo) {
  38541. return !!viewInfo.model
  38542. },
  38543. _onNavigationCanceled: function(args) {
  38544. var that = this;
  38545. if (!that._pendingNavigationArgs || that._pendingNavigationArgs.uri !== args.uri) {
  38546. var currentItem = that.navigationManager.currentItem();
  38547. if (currentItem)
  38548. DX.utils.executeAsync(function() {
  38549. var viewInfo = that._acquireViewInfo(currentItem, args.options);
  38550. that._highlightCurrentNavigationCommand(viewInfo)
  38551. });
  38552. that._isNavigating = false
  38553. }
  38554. },
  38555. _disposeRemovedViews: function() {
  38556. var that = this,
  38557. args;
  38558. $.each(that._viewLinksHash, function(key, link) {
  38559. if (!link.linkCount) {
  38560. args = {viewInfo: link.viewInfo};
  38561. that._processEvent("viewDisposing", args, args.viewInfo.model);
  38562. that._disposeView(link.viewInfo);
  38563. that._processEvent("viewDisposed", args, args.viewInfo.model);
  38564. delete that._viewLinksHash[key]
  38565. }
  38566. })
  38567. },
  38568. _onViewHidden: function(viewInfo) {
  38569. var args = {viewInfo: viewInfo};
  38570. this._processEvent("viewHidden", args, args.viewInfo.model)
  38571. },
  38572. _disposeView: function(viewInfo) {
  38573. var commands = viewInfo.commands || [];
  38574. $.each(commands, function(index, command) {
  38575. command._dispose()
  38576. })
  38577. },
  38578. _acquireViewInfo: function(navigationItem, navigateOptions) {
  38579. var viewInfo = this.viewCache.getView(navigationItem.key);
  38580. if (!viewInfo) {
  38581. viewInfo = this._createViewInfo(navigationItem, navigateOptions);
  38582. this._obtainViewLink(viewInfo);
  38583. this.viewCache.setView(navigationItem.key, viewInfo)
  38584. }
  38585. return viewInfo
  38586. },
  38587. _processEvent: function(eventName, args, model) {
  38588. this._callComponentMethod(eventName, args);
  38589. if (this[eventName] && this[eventName].fire)
  38590. this[eventName].fire(args);
  38591. var modelMethod = (model || {})[eventName];
  38592. if (modelMethod)
  38593. modelMethod.call(model, args)
  38594. },
  38595. _createViewInfo: function(navigationItem, navigateOptions) {
  38596. var uri = navigationItem.uri,
  38597. routeData = this.router.parse(uri);
  38598. var viewInfo = {
  38599. viewName: routeData.view,
  38600. routeData: routeData,
  38601. uri: uri,
  38602. key: navigationItem.key,
  38603. canBack: this.canBack(),
  38604. navigateOptions: navigateOptions,
  38605. previousViewInfo: this._getPreviousViewInfo(navigateOptions)
  38606. };
  38607. return viewInfo
  38608. },
  38609. _createViewModel: function(viewInfo) {
  38610. this._processEvent("beforeViewSetup", {viewInfo: viewInfo});
  38611. viewInfo.model = viewInfo.model || this._callViewCodeBehind(viewInfo);
  38612. this._processEvent("afterViewSetup", {viewInfo: viewInfo})
  38613. },
  38614. _createViewCommands: function(viewInfo) {
  38615. viewInfo.commands = viewInfo.model.commands || [];
  38616. if (viewInfo.canBack && this._applicationMode !== "webSite")
  38617. this._appendBackCommand(viewInfo)
  38618. },
  38619. _callViewCodeBehind: function(viewInfo) {
  38620. var setupFunc = $.noop,
  38621. routeData = viewInfo.routeData;
  38622. if (routeData.view in this.namespace)
  38623. setupFunc = this.namespace[routeData.view];
  38624. return setupFunc.call(this.namespace, routeData, viewInfo) || {}
  38625. },
  38626. _appendBackCommand: function(viewInfo) {
  38627. var commands = viewInfo.commands,
  38628. that = this,
  38629. stackKey = this.navigationManager.currentStackKey,
  38630. backTitle = BACK_COMMAND_TITLE;
  38631. if (that._options.useViewTitleAsBackText)
  38632. backTitle = ((viewInfo.previousViewInfo || {}).model || {}).title || backTitle;
  38633. var toMergeTo = [new DX.framework.dxCommand({
  38634. id: "back",
  38635. title: backTitle,
  38636. behavior: "back",
  38637. action: function() {
  38638. that.back({stack: stackKey})
  38639. },
  38640. icon: "arrowleft",
  38641. type: "back"
  38642. })];
  38643. var result = DX.framework.utils.mergeCommands(toMergeTo, commands);
  38644. commands.length = 0;
  38645. commands.push.apply(commands, result)
  38646. },
  38647. _showView: function(viewInfo, direction) {
  38648. var that = this;
  38649. var eventArgs = {
  38650. viewInfo: viewInfo,
  38651. direction: direction
  38652. };
  38653. that._processEvent("viewShowing", eventArgs, viewInfo.model);
  38654. return that._showViewImpl(eventArgs.viewInfo, eventArgs.direction).done(function() {
  38655. DX.utils.executeAsync(function() {
  38656. that._processEvent("viewShown", eventArgs, viewInfo.model);
  38657. that._disposeRemovedViews()
  38658. })
  38659. })
  38660. },
  38661. _highlightCurrentNavigationCommand: function(viewInfo) {
  38662. var that = this,
  38663. selectedCommand,
  38664. currentUri = viewInfo.uri,
  38665. currentNavigationItemId = viewInfo.model && viewInfo.model.currentNavigationItemId;
  38666. if (currentNavigationItemId !== undefined)
  38667. $.each(this.navigation, function(index, command) {
  38668. if (command.option("id") === currentNavigationItemId) {
  38669. selectedCommand = command;
  38670. return false
  38671. }
  38672. });
  38673. if (!selectedCommand)
  38674. $.each(this.navigation, function(index, command) {
  38675. var commandUri = command.option("action");
  38676. if (DX.utils.isString(commandUri)) {
  38677. commandUri = commandUri.replace(/^#+/, "");
  38678. if (commandUri === that.navigationManager.rootUri()) {
  38679. selectedCommand = command;
  38680. return false
  38681. }
  38682. }
  38683. });
  38684. $.each(this.navigation, function(index, command) {
  38685. if (command === selectedCommand && command.option("highlighted"))
  38686. command.optionChanged.fireWith(command, ["highlighted", true, true]);
  38687. command.option("highlighted", command === selectedCommand)
  38688. })
  38689. },
  38690. _setViewLoadingState: DX.abstract,
  38691. _showViewImpl: DX.abstract,
  38692. _obtainViewLink: function(viewInfo) {
  38693. var key = viewInfo.key;
  38694. if (!this._viewLinksHash[key])
  38695. this._viewLinksHash[key] = {
  38696. viewInfo: viewInfo,
  38697. linkCount: 1
  38698. };
  38699. else
  38700. this._viewLinksHash[key].linkCount++
  38701. },
  38702. _releaseViewLink: function(viewInfo) {
  38703. if (this._viewLinksHash[viewInfo.key] === undefined)
  38704. DX.utils.logger.warn("A view with the '" + viewInfo.key + "' key doesn't exist");
  38705. if (this._viewLinksHash[viewInfo.key].linkCount === 0)
  38706. DX.utils.logger.warn("A view with the '" + viewInfo.key + "' key has already been released");
  38707. this._viewLinksHash[viewInfo.key].linkCount--
  38708. },
  38709. navigate: function(uri, options) {
  38710. var that = this;
  38711. if ($.isPlainObject(uri)) {
  38712. uri = that.router.format(uri);
  38713. if (uri === false)
  38714. throw new Error("The passed object cannot be formatted into a uri string by router. An appropriate route should be registered.");
  38715. }
  38716. if (!that._initState)
  38717. that.init().done(function() {
  38718. that.restoreState();
  38719. that.navigate(uri, options)
  38720. });
  38721. else if (that._initState === INIT_COMPLETE)
  38722. that.navigationManager.navigate(uri, options);
  38723. else
  38724. throw new Error("Unable to navigate. Application is being initialized. Consider using the 'HtmlApplication.navigating' event to alter the navigation logic.");
  38725. },
  38726. canBack: function(stackKey) {
  38727. return this.navigationManager.canBack(stackKey)
  38728. },
  38729. _getPreviousViewInfo: function(navigateOptions) {
  38730. var previousNavigationItem = this.navigationManager.previousItem(navigateOptions.stack),
  38731. result;
  38732. if (previousNavigationItem)
  38733. result = this.viewCache.getView(previousNavigationItem.key);
  38734. return result
  38735. },
  38736. back: function(options) {
  38737. this.navigationManager.back(options)
  38738. },
  38739. saveState: function() {
  38740. this.stateManager.saveState()
  38741. },
  38742. restoreState: function() {
  38743. this.stateManager.restoreState()
  38744. },
  38745. clearState: function() {
  38746. this.stateManager.clearState()
  38747. }
  38748. })
  38749. })(jQuery, DevExpress);
  38750. /*! Module framework, file framework.html.js */
  38751. (function($, DX, undefined) {
  38752. DX.framework.html = {
  38753. layoutControllers: [],
  38754. layoutSets: {}
  38755. }
  38756. })(jQuery, DevExpress);
  38757. /*! Module framework, file framework.widgetCommandAdapters.js */
  38758. (function($, DX) {
  38759. var commandToContainer = DX.framework.utils.commandToContainer,
  38760. DX_COMMAND_TO_WIDGET_ADAPTER = "dxCommandToWidgetAdapter";
  38761. var WidgetItemWrapperBase = DX.Class.inherit({
  38762. ctor: function(command, containerOptions) {
  38763. this.command = command;
  38764. this.containerOptions = containerOptions;
  38765. this._createWidgetItem(command, containerOptions);
  38766. this._commandChangedHandler = $.proxy(this._onCommandChanged, this);
  38767. command.optionChanged.add(this._commandChangedHandler)
  38768. },
  38769. _createWidgetItem: function(command, containerOptions) {
  38770. this.widgetItem = $.extend({
  38771. command: command,
  38772. containerOptions: containerOptions
  38773. }, containerOptions, command.option());
  38774. this._updateItem()
  38775. },
  38776. _onCommandChanged: function(optionName, newValue, oldValue) {
  38777. this.widgetItem[optionName] = newValue;
  38778. this._updateItem(optionName, newValue, oldValue)
  38779. },
  38780. _updateItem: function(optionName, newValue, oldValue){},
  38781. dispose: function() {
  38782. if (this.command)
  38783. this.command.optionChanged.remove(this._commandChangedHandler);
  38784. delete this.command;
  38785. delete this.containerOptions;
  38786. delete this.widgetItem;
  38787. delete this.updateItemHandler
  38788. }
  38789. });
  38790. var WidgetAdapterBase = DX.Class.inherit({
  38791. ctor: function($widgetElement) {
  38792. this.$widgetElement = $widgetElement;
  38793. this.$widgetElement.data(DX_COMMAND_TO_WIDGET_ADAPTER, this);
  38794. this.widget = this._getWidgetByElement($widgetElement);
  38795. this._widgetDisposingHandler = $.proxy(this._onWidgetDisposing, this);
  38796. this.widget.disposing.add(this._widgetDisposingHandler);
  38797. this.itemWrappers = []
  38798. },
  38799. addCommand: function(command, containerOptions) {
  38800. var itemWrapper = this._createItemWrapper(command, containerOptions);
  38801. this.itemWrappers.push(itemWrapper);
  38802. this._addItemToWidget(itemWrapper);
  38803. this.refresh();
  38804. this._commandChangedHandler = $.proxy(this._onCommandChanged, this);
  38805. itemWrapper.command.optionChanged.add(this._commandChangedHandler)
  38806. },
  38807. beginUpdate: function() {
  38808. this.widget.beginUpdate()
  38809. },
  38810. endUpdate: function() {
  38811. this.widget.endUpdate()
  38812. },
  38813. _onWidgetDisposing: function() {
  38814. this.dispose(true)
  38815. },
  38816. _onCommandChanged: function(optionName, newValue, oldValue) {
  38817. if (name !== "highlighted")
  38818. this.refresh()
  38819. },
  38820. _addItemToWidget: function(itemWrapper) {
  38821. var items = this.widget.option("items");
  38822. items.push(itemWrapper.widgetItem)
  38823. },
  38824. refresh: function() {
  38825. var items = this.widget.option("items");
  38826. this.widget.option("items", items)
  38827. },
  38828. clear: function(widgetDisposing) {
  38829. var that = this;
  38830. $.each(that.itemWrappers, function(index, itemWrapper) {
  38831. itemWrapper.command.optionChanged.remove(that._commandChangedHandler);
  38832. itemWrapper.dispose()
  38833. });
  38834. this.itemWrappers.length = 0;
  38835. if (!widgetDisposing)
  38836. this._clearWidgetItems()
  38837. },
  38838. _clearWidgetItems: function() {
  38839. this.widget.option("items", [])
  38840. },
  38841. dispose: function(widgetDisposing) {
  38842. this.clear(widgetDisposing);
  38843. if (this.widget) {
  38844. this.widget.disposing.remove(this._widgetDisposingHandler);
  38845. this.$widgetElement.removeData(DX_COMMAND_TO_WIDGET_ADAPTER);
  38846. delete this.widget;
  38847. delete this.$widgetElement
  38848. }
  38849. }
  38850. });
  38851. var CommandToWidgetAdapter = DX.Class.inherit({
  38852. ctor: function(createAdapter) {
  38853. this.createAdapter = createAdapter
  38854. },
  38855. _getWidgetAdapter: function($container) {
  38856. var widgetAdapter = $container.data(DX_COMMAND_TO_WIDGET_ADAPTER);
  38857. if (!widgetAdapter)
  38858. widgetAdapter = this.createAdapter($container);
  38859. return widgetAdapter
  38860. },
  38861. addCommand: function($container, command, containerOptions) {
  38862. var widgetAdapter = this._getWidgetAdapter($container);
  38863. widgetAdapter.addCommand(command, containerOptions)
  38864. },
  38865. clearContainer: function($container) {
  38866. var widgetAdapter = this._getWidgetAdapter($container);
  38867. widgetAdapter.clear()
  38868. },
  38869. beginUpdate: function($container) {
  38870. var widgetAdapter = this._getWidgetAdapter($container);
  38871. widgetAdapter.beginUpdate()
  38872. },
  38873. endUpdate: function($container) {
  38874. var widgetAdapter = this._getWidgetAdapter($container);
  38875. widgetAdapter.endUpdate()
  38876. }
  38877. });
  38878. var dxToolbarItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function() {
  38879. var widgetItem = this.widgetItem,
  38880. command = this.command,
  38881. containerOptions = this.containerOptions,
  38882. location = commandToContainer.resolvePropertyValue(command, containerOptions, "location"),
  38883. optionsTarget;
  38884. widgetItem.location = location;
  38885. if (location === "menu")
  38886. optionsTarget = widgetItem;
  38887. else {
  38888. optionsTarget = $.extend({}, widgetItem);
  38889. widgetItem.options = optionsTarget;
  38890. widgetItem.widget = "button"
  38891. }
  38892. optionsTarget.text = commandToContainer.resolveTextValue(command, containerOptions);
  38893. optionsTarget.disabled = command.option("disabled");
  38894. optionsTarget.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon");
  38895. optionsTarget.iconSrc = commandToContainer.resolveIconValue(command, containerOptions, "iconSrc");
  38896. optionsTarget.type = commandToContainer.resolveTypeValue(command, containerOptions)
  38897. }});
  38898. var dxToolbarAdapter = WidgetAdapterBase.inherit({
  38899. ctor: function($widgetElement) {
  38900. this.callBase($widgetElement);
  38901. this.widget.option("itemClickAction", $.proxy(this._onToolbarItemClick, this))
  38902. },
  38903. _onToolbarItemClick: function(e) {
  38904. if (e.itemData.command)
  38905. e.itemData.command.execute(e)
  38906. },
  38907. _getWidgetByElement: function($element) {
  38908. return $element.dxToolbar("instance")
  38909. },
  38910. _createItemWrapper: function(command, containerOptions) {
  38911. return new dxToolbarItemWrapper(command, containerOptions)
  38912. },
  38913. addCommand: function(command, containerOptions) {
  38914. this.callBase(command, containerOptions);
  38915. this.widget.option("visible", true)
  38916. }
  38917. });
  38918. var dxActionSheetItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function() {
  38919. var widgetItem = this.widgetItem,
  38920. command = this.command,
  38921. containerOptions = this.containerOptions;
  38922. widgetItem.text = commandToContainer.resolveTextValue(command, containerOptions);
  38923. widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon");
  38924. widgetItem.iconSrc = commandToContainer.resolveIconValue(command, containerOptions, "iconSrc")
  38925. }});
  38926. var dxActionSheetAdapter = WidgetAdapterBase.inherit({
  38927. _createItemWrapper: function(command, containerOptions) {
  38928. return new dxActionSheetItemWrapper(command, containerOptions)
  38929. },
  38930. _getWidgetByElement: function($element) {
  38931. return $element.dxActionSheet("instance")
  38932. }
  38933. });
  38934. var dxListItemWrapper = WidgetItemWrapperBase.inherit({
  38935. _createWidgetItem: function(command, containerOptions) {
  38936. this.callBase(command, containerOptions);
  38937. this.widgetItem.clickAction = $.proxy(this._itemClick, this)
  38938. },
  38939. _updateItem: function() {
  38940. var widgetItem = this.widgetItem,
  38941. command = this.command,
  38942. containerOptions = this.containerOptions;
  38943. widgetItem.title = commandToContainer.resolveTextValue(command, containerOptions);
  38944. widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon");
  38945. widgetItem.iconSrc = commandToContainer.resolveIconValue(command, containerOptions, "iconSrc")
  38946. },
  38947. _itemClick: function(e) {
  38948. if (!this.widgetItem.disabled)
  38949. this.command.execute(e)
  38950. }
  38951. });
  38952. var dxListAdapter = WidgetAdapterBase.inherit({
  38953. _createItemWrapper: function(command, containerOptions) {
  38954. return new dxListItemWrapper(command, containerOptions)
  38955. },
  38956. _getWidgetByElement: function($element) {
  38957. return $element.dxList("instance")
  38958. }
  38959. });
  38960. var dxNavBarItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function(optionName, newValue, oldValue) {
  38961. var command = this.command,
  38962. containerOptions = this.containerOptions;
  38963. if (optionName !== "highlighted") {
  38964. this.widgetItem.text = commandToContainer.resolveTextValue(command, containerOptions);
  38965. this.widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon");
  38966. this.widgetItem.iconSrc = commandToContainer.resolveIconValue(command, containerOptions, "iconSrc")
  38967. }
  38968. }});
  38969. var dxNavBarAdapter = WidgetAdapterBase.inherit({
  38970. ctor: function($widgetElement) {
  38971. this.callBase($widgetElement);
  38972. this.widget.option("itemClickAction", $.proxy(this._onNavBarItemClick, this))
  38973. },
  38974. _onNavBarItemClick: function(e) {
  38975. var items = this.widget.option("items");
  38976. for (var i = items.length; --i; )
  38977. items[i].command.option("highlighted", false);
  38978. e.itemData.command.execute(e)
  38979. },
  38980. _getWidgetByElement: function($element) {
  38981. return $element.dxNavBar("instance")
  38982. },
  38983. _createItemWrapper: function(command, containerOptions) {
  38984. return new dxNavBarItemWrapper(command, containerOptions)
  38985. },
  38986. addCommand: function(command, containerOptions) {
  38987. this.callBase(command, containerOptions);
  38988. this._updateSelectedIndex()
  38989. },
  38990. _onCommandChanged: function(name, newValue, oldValue) {
  38991. if (name !== "highlighted" || newValue)
  38992. this._updateSelectedIndex();
  38993. this.callBase(name, newValue, oldValue)
  38994. },
  38995. _updateSelectedIndex: function() {
  38996. var items = this.widget.option("items");
  38997. for (var i = 0, itemsCount = items.length; i < itemsCount; i++)
  38998. if (items[i].highlighted) {
  38999. this.widget.option("selectedIndex", i);
  39000. break
  39001. }
  39002. }
  39003. });
  39004. var dxPivotItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function(optionName, newValue, oldValue) {
  39005. if (optionName === "title")
  39006. this.widgetItem.title = commandToContainer.resolveTextValue(this.command, this.containerOptions)
  39007. }});
  39008. var dxPivotAdapter = WidgetAdapterBase.inherit({
  39009. ctor: function($widgetElement) {
  39010. this.callBase($widgetElement);
  39011. this._highlighting = false;
  39012. this.widget.option("itemSelectAction", $.proxy(this._onPivotItemSelect, this))
  39013. },
  39014. _onPivotItemSelect: function(e) {
  39015. if (e.itemData && e.itemData.command)
  39016. e.itemData.command.execute(e)
  39017. },
  39018. _getWidgetByElement: function($element) {
  39019. return $element.dxPivot("instance")
  39020. },
  39021. _createItemWrapper: function(command, containerOptions) {
  39022. return new dxToolbarItemWrapper(command, containerOptions)
  39023. },
  39024. addCommand: function(command, containerOptions) {
  39025. this.callBase(command, containerOptions);
  39026. this._updateSelectedIndex()
  39027. },
  39028. _onCommandChanged: function(optionName, newValue, oldValue) {
  39029. if (optionName === "visible")
  39030. this._rerenderPivot();
  39031. else if (optionName !== "highlighted" || newValue)
  39032. this._updateSelectedIndex()
  39033. },
  39034. _addItemToWidget: function(itemWrapper) {
  39035. if (itemWrapper.command.option("visible"))
  39036. this.callBase(itemWrapper)
  39037. },
  39038. _updateSelectedIndex: function() {
  39039. var pivot = this.widget,
  39040. items = pivot.option("items") || [];
  39041. DX.fx.off = true;
  39042. for (var i = 0, itemsCount = items.length; i < itemsCount; i++)
  39043. if (items[i].highlighted) {
  39044. if (this._highlighting && pivot.option("selectedIndex") === i)
  39045. this._highlighting = false;
  39046. pivot.option("selectedIndex", i);
  39047. break
  39048. }
  39049. DX.fx.off = false
  39050. },
  39051. _rerenderPivot: function() {
  39052. var that = this;
  39053. that.widget.option("items", []);
  39054. $.each(that.itemWrappers, function(index, itemWrapper) {
  39055. if (itemWrapper.command.option("visible"))
  39056. that._addItemToWidget(itemWrapper)
  39057. });
  39058. that.refresh();
  39059. that._updateSelectedIndex()
  39060. }
  39061. });
  39062. var dxSlideOutItemWrapper = WidgetItemWrapperBase.inherit({_updateItem: function(optionName, newValue, oldValue) {
  39063. var widgetItem = this.widgetItem,
  39064. command = this.command,
  39065. containerOptions = this.containerOptions;
  39066. if (name !== "highlighted") {
  39067. widgetItem.title = commandToContainer.resolveTextValue(command, containerOptions);
  39068. widgetItem.icon = commandToContainer.resolveIconValue(command, containerOptions, "icon");
  39069. widgetItem.iconSrc = commandToContainer.resolveIconValue(command, containerOptions, "iconSrc")
  39070. }
  39071. }});
  39072. var dxSlideOutAdapter = WidgetAdapterBase.inherit({
  39073. ctor: function($widgetElement) {
  39074. this.callBase($widgetElement);
  39075. this.widget.option("itemClickAction", $.proxy(this._onSlideOutItemClick, this))
  39076. },
  39077. _onSlideOutItemClick: function(e) {
  39078. e.itemData.command.execute(e)
  39079. },
  39080. _getWidgetByElement: function($element) {
  39081. return $element.dxSlideOut("instance")
  39082. },
  39083. _createItemWrapper: function(command, containerOptions) {
  39084. return new dxSlideOutItemWrapper(command, containerOptions)
  39085. },
  39086. _updateSelectedIndex: function() {
  39087. var items = this.widget.option("items") || [];
  39088. for (var i = 0, itemsCount = items.length; i < itemsCount; i++)
  39089. if (items[i].highlighted) {
  39090. this.widget.option("selectedIndex", i);
  39091. break
  39092. }
  39093. },
  39094. addCommand: function(command, containerOptions) {
  39095. this.callBase(command, containerOptions);
  39096. this._updateSelectedIndex()
  39097. },
  39098. _onCommandChanged: function(name, newValue, oldValue) {
  39099. if (name !== "highlighted" || newValue)
  39100. this._updateSelectedIndex();
  39101. this.callBase(name, newValue, oldValue)
  39102. }
  39103. });
  39104. var adapters = DX.framework.html.commandToDXWidgetAdapters = {};
  39105. adapters.dxToolbar = new CommandToWidgetAdapter(function($widgetElement) {
  39106. return new dxToolbarAdapter($widgetElement)
  39107. });
  39108. adapters.dxActionSheet = new CommandToWidgetAdapter(function($widgetElement) {
  39109. return new dxActionSheetAdapter($widgetElement)
  39110. });
  39111. adapters.dxList = new CommandToWidgetAdapter(function($widgetElement) {
  39112. return new dxListAdapter($widgetElement)
  39113. });
  39114. adapters.dxNavBar = new CommandToWidgetAdapter(function($widgetElement) {
  39115. return new dxNavBarAdapter($widgetElement)
  39116. });
  39117. adapters.dxPivot = new CommandToWidgetAdapter(function($widgetElement) {
  39118. return new dxPivotAdapter($widgetElement)
  39119. });
  39120. adapters.dxSlideOut = new CommandToWidgetAdapter(function($widgetElement) {
  39121. return new dxSlideOutAdapter($widgetElement)
  39122. });
  39123. DX.framework.html.WidgetItemWrapperBase = WidgetItemWrapperBase;
  39124. DX.framework.html.WidgetAdapterBase = WidgetAdapterBase
  39125. })(jQuery, DevExpress);
  39126. /*! Module framework, file framework.commandManager.js */
  39127. (function($, DX, undefined) {
  39128. var Class = DX.Class,
  39129. ui = DevExpress.ui;
  39130. DX.framework.dxCommandContainer = DX.DOMComponent.inherit({
  39131. ctor: function(element, options) {
  39132. if ($.isPlainObject(element)) {
  39133. options = element;
  39134. element = $("<div />")
  39135. }
  39136. this.callBase(element, options)
  39137. },
  39138. _setDefaultOptions: function() {
  39139. this.callBase();
  39140. this.option({id: null})
  39141. },
  39142. _render: function() {
  39143. this.callBase();
  39144. this._element().addClass("dx-command-container")
  39145. }
  39146. });
  39147. DX.registerComponent("dxCommandContainer", DX.framework.dxCommandContainer);
  39148. DX.framework.html.CommandManager = Class.inherit({
  39149. ctor: function(options) {
  39150. options = options || {};
  39151. this.defaultWidgetAdapter = options.defaultWidgetAdapter || this._getDefaultWidgetAdapter();
  39152. this.commandMapping = options.commandMapping || new DX.framework.CommandMapping
  39153. },
  39154. _getDefaultWidgetAdapter: function() {
  39155. return {
  39156. addCommand: this._defaultAddCommand,
  39157. clearContainer: $.noop
  39158. }
  39159. },
  39160. _getContainerAdapter: function($container) {
  39161. var componentNames = $container.data("dxComponents"),
  39162. adapters = DX.framework.html.commandToDXWidgetAdapters;
  39163. if (componentNames)
  39164. for (var index in componentNames) {
  39165. var widgetName = componentNames[index];
  39166. if (widgetName in adapters)
  39167. return adapters[widgetName]
  39168. }
  39169. return this.defaultWidgetAdapter
  39170. },
  39171. findCommands: function($view) {
  39172. var result = $.map($view.addBack().find(".dx-command"), function(element) {
  39173. return $(element).dxCommand("instance")
  39174. });
  39175. return result
  39176. },
  39177. findCommandContainers: function($markup) {
  39178. var result = $.map($markup.find(".dx-command-container"), function(element) {
  39179. return $(element).dxCommandContainer("instance")
  39180. });
  39181. return result
  39182. },
  39183. _checkCommandId: function(id, command) {
  39184. if (id === null)
  39185. throw new Error("The command's 'id' option should be specified.\r\nProcessed markup: " + command._element().get(0).outerHTML);
  39186. },
  39187. renderCommandsToContainers: function(commands, containers) {
  39188. var that = this,
  39189. commandHash = {},
  39190. commandIds = [];
  39191. $.each(commands, function(i, command) {
  39192. var id = command.option("id");
  39193. that._checkCommandId(id, command);
  39194. commandIds.push(id);
  39195. commandHash[id] = command
  39196. });
  39197. that.commandMapping.checkCommandsExist(commandIds);
  39198. $.each(containers, function(k, container) {
  39199. var commandInfos = [];
  39200. $.each(commandHash, function(id, command) {
  39201. var commandId = id;
  39202. var commandOptions = that.commandMapping.getCommandMappingForContainer(commandId, container.option("id"));
  39203. if (commandOptions)
  39204. commandInfos.push({
  39205. command: command,
  39206. options: commandOptions
  39207. })
  39208. });
  39209. if (commandInfos.length)
  39210. that._attachCommandsToContainer(container._element(), commandInfos)
  39211. })
  39212. },
  39213. clearContainer: function(container) {
  39214. var $container = container._element(),
  39215. adapter = this._getContainerAdapter($container);
  39216. adapter.clearContainer($container)
  39217. },
  39218. _arrangeCommandsToContainers: function(commands, containers) {
  39219. DX.utils.logger.warn("The _arrangeCommandsToContainers function is deprecated. Use renderCommandsToContainers instead");
  39220. this.renderCommandsToContainers(commands, containers)
  39221. },
  39222. _attachCommandsToContainer: function($container, commandInfos) {
  39223. var adapter = this._getContainerAdapter($container);
  39224. if (adapter.beginUpdate)
  39225. adapter.beginUpdate($container);
  39226. $.each(commandInfos, function(index, commandInfo) {
  39227. adapter.addCommand($container, commandInfo.command, commandInfo.options)
  39228. });
  39229. if (adapter.endUpdate)
  39230. adapter.endUpdate($container);
  39231. return true
  39232. },
  39233. _defaultAddCommand: function($container, command, options) {
  39234. var $source = command._element();
  39235. if ($source) {
  39236. $container.append($source);
  39237. $source.on("dxclick", function() {
  39238. command.execute()
  39239. })
  39240. }
  39241. }
  39242. })
  39243. })(jQuery, DevExpress);
  39244. /*! Module framework, file framework.layoutController.js */
  39245. (function($, DX, undefined) {
  39246. var Class = DX.Class;
  39247. var HIDDEN_BAG_ID = "__hidden-bag";
  39248. var TRANSITION_SELECTOR = ".dx-transition:not(.dx-transition .dx-transition)";
  39249. var transitionSelector = function(transitionName) {
  39250. return ".dx-transition-" + transitionName
  39251. };
  39252. DX.framework.html.DefaultLayoutController = Class.inherit({
  39253. ctor: function(options) {
  39254. options = options || {};
  39255. this.name = options.layoutTemplateName || options.name || "";
  39256. this._disableViewLoadingState = options.disableViewLoadingState;
  39257. this._layoutModel = options.layoutModel || {};
  39258. this._defaultPaneName = options.defaultPaneName || "content";
  39259. this.viewReleased = $.Callbacks();
  39260. this.viewRendered = $.Callbacks()
  39261. },
  39262. init: function(options) {
  39263. options = options || {};
  39264. this._visibleViews = {};
  39265. this._$viewPort = options.$viewPort || $("body");
  39266. this._$hiddenBag = options.$hiddenBag || $(document.getElementById(HIDDEN_BAG_ID)) || $("<div/>").hide().appendTo("body");
  39267. this._commandManager = options.commandManager;
  39268. this._viewEngine = options.viewEngine;
  39269. this._prepareTemplates();
  39270. this.DEFAULT_LOADING_TITLE = DX.localization.localizeString("@Loading");
  39271. if (options.templateContext) {
  39272. this._templateContextChanged = options.templateContext.optionChanged;
  39273. this._proxiedTemplateContextChangedHandler = $.proxy(this._templateContextChangedHandler, this)
  39274. }
  39275. },
  39276. activate: function() {
  39277. var $rootElement = this._getRootElement();
  39278. this._justActivated = true;
  39279. $rootElement.show();
  39280. this._moveToViewPort($rootElement);
  39281. this._attachRefreshViewRequiredHandler()
  39282. },
  39283. deactivate: function() {
  39284. this._releaseVisibleViews();
  39285. this._moveToHiddenBag(this._getRootElement());
  39286. this._detachRefreshViewRequiredHandler()
  39287. },
  39288. _releaseVisibleViews: function() {
  39289. var that = this;
  39290. $.each(this._visibleViews, function(index, viewInfo) {
  39291. that._hideView(viewInfo);
  39292. that._releaseView(viewInfo)
  39293. });
  39294. this._visibleViews = {}
  39295. },
  39296. _templateContextChangedHandler: function() {
  39297. $.each(this._visibleViews, $.proxy(function(index, viewInfo) {
  39298. this.showView(viewInfo)
  39299. }, this))
  39300. },
  39301. _attachRefreshViewRequiredHandler: function() {
  39302. if (this._templateContextChanged)
  39303. this._templateContextChanged.add(this._proxiedTemplateContextChangedHandler)
  39304. },
  39305. _detachRefreshViewRequiredHandler: function() {
  39306. if (this._templateContextChanged)
  39307. this._templateContextChanged.remove(this._proxiedTemplateContextChangedHandler)
  39308. },
  39309. _getPreviousViewInfo: function(viewInfo) {
  39310. return this._visibleViews[this._getViewPaneName(viewInfo.viewTemplateInfo)]
  39311. },
  39312. _prepareTemplates: function() {
  39313. var that = this;
  39314. var $layoutTemplate = that._viewEngine.findLayoutTemplate(this._getLayoutTemplateName()).removeClass("dx-hidden");
  39315. that._$layoutTemplate = $layoutTemplate;
  39316. that._$mainLayout = that._createEmptyLayout().show();
  39317. that._viewEngine._applyTemplate(that._$mainLayout, that._layoutModel);
  39318. that._$navigationWidget = that._createNavigationWidget();
  39319. that._loadingStateViewInfo = that._createLoadingStateViewInfo($layoutTemplate)
  39320. },
  39321. renderNavigation: function(navigationCommands) {
  39322. this._clearNavigationWidget();
  39323. this._renderNavigationImpl(navigationCommands)
  39324. },
  39325. _renderNavigationImpl: function(navigationCommands) {
  39326. this._renderCommands(this._$mainLayout, navigationCommands)
  39327. },
  39328. _createNavigationWidget: function() {
  39329. var result;
  39330. this._$mainLayout.find(".dx-command-container").each(function() {
  39331. var container = $(this).dxCommandContainer("instance");
  39332. if (container.option("id") === "global-navigation")
  39333. result = $(this)
  39334. });
  39335. return result
  39336. },
  39337. _clearNavigationWidget: function() {
  39338. if (this._$navigationWidget)
  39339. this._commandManager.clearContainer(this._$navigationWidget.dxCommandContainer("instance"))
  39340. },
  39341. _getRootElement: function() {
  39342. return this._$mainLayout
  39343. },
  39344. _getViewFrame: function(viewInfo) {
  39345. return this._$mainLayout
  39346. },
  39347. _getLayoutTemplateName: function() {
  39348. return this.name
  39349. },
  39350. _applyModelToTransitionElements: function($markup, model) {
  39351. var that = this;
  39352. this._getTransitionElements($markup).each(function(i, item) {
  39353. that._viewEngine._applyTemplate($(item).children(), model)
  39354. })
  39355. },
  39356. _createLoadingStateViewInfo: function($layoutTemplate) {
  39357. var $loadingStateView = $layoutTemplate.clone().addClass("dx-loading-state-view").appendTo(this._$hiddenBag),
  39358. model = {title: ko.observable()};
  39359. this._viewEngine._createComponents($loadingStateView);
  39360. this._applyModelToTransitionElements($loadingStateView, model);
  39361. var result = {
  39362. model: model,
  39363. renderResult: {
  39364. $markup: $loadingStateView,
  39365. $viewItems: $()
  39366. },
  39367. isLoadingStateView: true
  39368. };
  39369. this._appendViewToLayout(result);
  39370. return result
  39371. },
  39372. _createViewLayoutTemplate: function() {
  39373. var that = this;
  39374. var $viewLayoutTemplate = that._$layoutTemplate.clone().appendTo(that._$hiddenBag);
  39375. that._viewEngine._createComponents($viewLayoutTemplate);
  39376. return $viewLayoutTemplate
  39377. },
  39378. _createEmptyLayout: function() {
  39379. var that = this;
  39380. var $result = that._$layoutTemplate.clone().appendTo(that._$hiddenBag);
  39381. that._viewEngine._createComponents($result);
  39382. that._removeTransitionContent($result);
  39383. return $result
  39384. },
  39385. _removeTransitionContent: function($markup) {
  39386. var $transitionElements = this._getTransitionElements($markup);
  39387. $transitionElements.children().remove()
  39388. },
  39389. _getTransitionElements: function($markup) {
  39390. return $markup.find(TRANSITION_SELECTOR).addBack(TRANSITION_SELECTOR)
  39391. },
  39392. setViewLoadingState: function(viewInfo, direction) {
  39393. var that = this;
  39394. if (that._disableViewLoadingState)
  39395. return $.Deferred().resolve().promise();
  39396. var loadingStateViewInfo = $.extend({}, viewInfo, that._loadingStateViewInfo);
  39397. that._loadingStateViewInfo.model.title((viewInfo.viewTemplateInfo || {}).title || this.DEFAULT_LOADING_TITLE);
  39398. return that._showViewImpl(loadingStateViewInfo, direction)
  39399. },
  39400. showView: function(viewInfo, direction) {
  39401. var that = this;
  39402. var previousViewInfo = that._getPreviousViewInfo(viewInfo);
  39403. if (previousViewInfo && previousViewInfo.isLoadingStateView)
  39404. direction = "none";
  39405. that._ensureViewRendered(viewInfo);
  39406. return this._showViewImpl(viewInfo, direction).done(function() {
  39407. that._onViewShown(viewInfo)
  39408. })
  39409. },
  39410. disposeView: function(viewInfo) {
  39411. this._clearRenderResult(viewInfo)
  39412. },
  39413. _clearRenderResult: function(viewInfo) {
  39414. if (viewInfo.renderResult) {
  39415. viewInfo.renderResult.$markup.remove();
  39416. viewInfo.renderResult.$viewItems.remove();
  39417. delete viewInfo.renderResult
  39418. }
  39419. },
  39420. _prepareViewTemplate: function($viewTemplate, viewInfo) {
  39421. this._viewEngine._createComponents($viewTemplate)
  39422. },
  39423. _renderViewImpl: function($viewTemplate, viewInfo) {
  39424. var that = this,
  39425. $layout = this._createViewLayoutTemplate(),
  39426. $viewItems = $viewTemplate.children(),
  39427. isSimplifiedMarkup = true,
  39428. outOfContentItems = $();
  39429. this._applyModelToTransitionElements($layout, viewInfo.model);
  39430. this._viewEngine._applyLayoutCore($viewTemplate, $layout);
  39431. $viewItems.each(function(i, item) {
  39432. var $item = $(item);
  39433. that._viewEngine._applyTemplate($item, viewInfo.model);
  39434. if ($item.is(".dx-command,.dx-content,script"))
  39435. isSimplifiedMarkup = false;
  39436. else
  39437. outOfContentItems = outOfContentItems.add($item)
  39438. });
  39439. if (outOfContentItems.length && !isSimplifiedMarkup)
  39440. throw new Error("All the dxView element children should be either of the dxCommand or dxContent type.\r\nProcessed markup: " + outOfContentItems[0].outerHTML);
  39441. viewInfo.renderResult = viewInfo.renderResult || {};
  39442. viewInfo.renderResult.$viewItems = $viewItems;
  39443. viewInfo.renderResult.$markup = $layout
  39444. },
  39445. _renderCommands: function($markup, commands) {
  39446. var commandContainers = this._findCommandContainers($markup);
  39447. this._commandManager.renderCommandsToContainers(commands, commandContainers)
  39448. },
  39449. _applyViewCommands: function(viewInfo) {
  39450. var $viewItems = viewInfo.renderResult.$viewItems,
  39451. $markup = viewInfo.renderResult.$markup,
  39452. viewCommands = this._commandManager.findCommands($viewItems);
  39453. viewInfo.commands = DX.framework.utils.mergeCommands(viewInfo.commands || [], viewCommands);
  39454. this._renderCommands($markup, viewInfo.commands)
  39455. },
  39456. _findCommandContainers: function($markup) {
  39457. return this._viewEngine._createComponents($markup, ["dxCommandContainer"])
  39458. },
  39459. _ensureViewRendered: function(viewInfo) {
  39460. var viewTemplateInstance = viewInfo.$viewTemplate ? viewInfo.$viewTemplate.dxView("instance") : this._viewEngine.findViewComponent(viewInfo.viewName),
  39461. currentViewId = viewTemplateInstance.getId(),
  39462. $cachedMarkup = viewInfo.renderResult && viewInfo.renderResult.markupCache[currentViewId];
  39463. if ($cachedMarkup)
  39464. viewInfo.renderResult.$markup = $cachedMarkup;
  39465. else {
  39466. this._renderView(viewInfo);
  39467. viewInfo.renderResult.markupCache = viewInfo.renderResult.markupCache || {};
  39468. viewInfo.renderResult.markupCache[currentViewId] = viewInfo.renderResult.$markup
  39469. }
  39470. },
  39471. _renderView: function(viewInfo) {
  39472. var $viewTemplate = viewInfo.$viewTemplate || this._viewEngine.findViewTemplate(viewInfo.viewName);
  39473. this._prepareViewTemplate($viewTemplate, viewInfo);
  39474. this._renderViewImpl($viewTemplate, viewInfo);
  39475. this._applyViewCommands(viewInfo);
  39476. this._appendViewToLayout(viewInfo);
  39477. $viewTemplate.remove();
  39478. this._onRenderComplete(viewInfo);
  39479. this.viewRendered.fire(viewInfo)
  39480. },
  39481. _appendViewToLayout: function(viewInfo) {
  39482. var that = this,
  39483. $viewFrame = that._getViewFrame(viewInfo),
  39484. $markup = viewInfo.renderResult.$markup,
  39485. $transitionContentElements = $();
  39486. $.each($markup.find(".dx-content-placeholder"), function(index, el) {
  39487. var placeholder = $(el).dxContentPlaceholder("instance");
  39488. placeholder.prepareTransition()
  39489. });
  39490. $.each(that._getTransitionElements($viewFrame), function(index, transitionElement) {
  39491. var $transition = $(transitionElement),
  39492. $viewElement = $markup.find(transitionSelector($transition.data("dx-transition-name"))).children();
  39493. that._hideViewElements($viewElement);
  39494. $transition.append($viewElement);
  39495. $transitionContentElements = $transitionContentElements.add($viewElement)
  39496. });
  39497. that._$mainLayout.append(viewInfo.renderResult.$viewItems.filter(".dx-command"));
  39498. $markup.remove();
  39499. viewInfo.renderResult.$markup = $transitionContentElements
  39500. },
  39501. _onRenderComplete: function(viewInfo){},
  39502. _onViewShown: function(viewInfo) {
  39503. $(document).trigger("dx.viewchanged")
  39504. },
  39505. _doTransition: function(viewInfo, direction) {
  39506. var that = this,
  39507. deferred = $.Deferred();
  39508. var transitions = $.map(viewInfo.renderResult.$markup, function(transitionContent) {
  39509. var $transitionContent = $(transitionContent),
  39510. $transition = $transitionContent.parent(),
  39511. transitionType = that._disableTransitions ? "none" : $transition.data("dx-transition-type");
  39512. return {
  39513. destination: $transition,
  39514. source: $transitionContent,
  39515. type: transitionType || "none",
  39516. direction: direction || "none"
  39517. }
  39518. });
  39519. that._executeTransitions(transitions).done(function() {
  39520. deferred.resolve()
  39521. });
  39522. return deferred.promise()
  39523. },
  39524. _hideView: function(viewInfo) {
  39525. if (viewInfo.renderResult)
  39526. this._hideViewElements(viewInfo.renderResult.$markup)
  39527. },
  39528. _showViewImpl: function(viewInfo, direction) {
  39529. var that = this,
  39530. deferred = $.Deferred();
  39531. if (this._justActivated) {
  39532. this._justActivated = false;
  39533. direction = "none"
  39534. }
  39535. return that._doTransition(viewInfo, direction).done(function() {
  39536. that._changeView(viewInfo)
  39537. })
  39538. },
  39539. _releaseView: function(viewInfo) {
  39540. this.viewReleased.fireWith(this, [viewInfo])
  39541. },
  39542. _getViewPortElement: function() {
  39543. return this._$viewPort
  39544. },
  39545. _getHiddenBagElement: function() {
  39546. return this._$hiddenBag
  39547. },
  39548. _changeView: function(viewInfo) {
  39549. var that = this;
  39550. var previousViewInfo = that._getPreviousViewInfo(viewInfo);
  39551. if (previousViewInfo && previousViewInfo !== viewInfo) {
  39552. that._hideView(previousViewInfo);
  39553. if (!previousViewInfo.isLoadingStateView)
  39554. this._releaseView(previousViewInfo)
  39555. }
  39556. this._visibleViews[this._getViewPaneName(viewInfo.viewTemplateInfo)] = viewInfo
  39557. },
  39558. _getViewPaneName: function(viewTemplateInfo) {
  39559. return this._defaultPaneName
  39560. },
  39561. _hideViewElements: function($elements) {
  39562. DX.utils.triggerHidingEvent($elements.filter(".dx-active-view"));
  39563. this._patchIDs($elements);
  39564. this._disableInputs($elements);
  39565. $elements.removeClass("dx-active-view").addClass("dx-inactive-view")
  39566. },
  39567. _showViewElements: function($elements) {
  39568. this._unpatchIDs($elements);
  39569. this._enableInputs($elements);
  39570. $elements.removeClass("dx-inactive-view").addClass("dx-active-view");
  39571. DX.utils.triggerShownEvent($elements.filter(".dx-active-view"))
  39572. },
  39573. _executeTransitions: function(transitions) {
  39574. var that = this;
  39575. var animatedTransitions = $.map(transitions, function(transitionOptions) {
  39576. that._showViewElements(transitionOptions.source);
  39577. if (transitionOptions.source.children().length)
  39578. return DX.framework.html.TransitionExecutor.create(transitionOptions.destination, transitionOptions)
  39579. });
  39580. var animatedDeferreds = $.map(animatedTransitions, function(transition) {
  39581. transition.options.source.addClass("dx-transition-source");
  39582. return transition.exec()
  39583. });
  39584. var result = $.when.apply($, animatedDeferreds).done(function() {
  39585. $.each(animatedTransitions, function(index, transition) {
  39586. transition.finalize();
  39587. that._hideViewElements(transition.options.source.parent().find(".dx-active-view:not(.dx-transition-source)"));
  39588. transition.options.source.removeClass("dx-transition-source")
  39589. })
  39590. });
  39591. return result
  39592. },
  39593. _patchIDs: function($markup) {
  39594. this._processIDs($markup, function(id) {
  39595. var result = id;
  39596. if (id.indexOf(HIDDEN_BAG_ID) === -1)
  39597. result = HIDDEN_BAG_ID + "-" + id;
  39598. return result
  39599. })
  39600. },
  39601. _unpatchIDs: function($markup) {
  39602. this._processIDs($markup, function(id) {
  39603. var result = id;
  39604. if (id.indexOf(HIDDEN_BAG_ID) === 0)
  39605. result = id.substr(HIDDEN_BAG_ID.length + 1);
  39606. return result
  39607. })
  39608. },
  39609. _processIDs: function($markup, process) {
  39610. var elementsWithIds = $markup.find("[id]");
  39611. $.each(elementsWithIds, function(index, element) {
  39612. var $el = $(element),
  39613. id = $el.attr("id");
  39614. $el.attr("id", process(id))
  39615. })
  39616. },
  39617. _enableInputs: function($markup) {
  39618. var $inputs = $markup.find(":input[data-disabled=true]");
  39619. $.each($inputs, function(index, input) {
  39620. $(input).removeAttr("disabled").removeAttr("data-disabled")
  39621. })
  39622. },
  39623. _disableInputs: function($markup) {
  39624. var $inputs = $markup.find(":input:not([disabled], [disabled=true])");
  39625. $.each($inputs, function(index, input) {
  39626. $(input).attr({
  39627. disabled: true,
  39628. "data-disabled": true
  39629. })
  39630. })
  39631. },
  39632. _moveToViewPort: function($items) {
  39633. $items.appendTo(this._getViewPortElement());
  39634. $items.find(".dx-visibility-change-handler").each(function() {
  39635. $(this).triggerHandler("dxshown")
  39636. })
  39637. },
  39638. _moveToHiddenBag: function($items) {
  39639. $items.appendTo(this._getHiddenBagElement())
  39640. }
  39641. });
  39642. var layoutSets = DX.framework.html.layoutSets;
  39643. layoutSets["default"] = layoutSets["default"] || [];
  39644. layoutSets["default"].push({controller: new DX.framework.html.DefaultLayoutController})
  39645. })(jQuery, DevExpress);
  39646. /*! Module framework, file framework.templateEngine.js */
  39647. (function($, DX, undefined) {
  39648. var Class = DX.Class;
  39649. DX.framework.html.KnockoutJSTemplateEngine = Class.inherit({applyTemplate: function(template, model) {
  39650. ko.applyBindings(model, $(template).get(0))
  39651. }})
  39652. })(jQuery, DevExpress);
  39653. /*! Module framework, file framework.viewEngine.js */
  39654. (function($, DX, undefined) {
  39655. var Class = DX.Class,
  39656. ui = DX.ui,
  39657. _VIEW_ROLE = "dxView",
  39658. _LAYOUT_ROLE = "dxLayout",
  39659. lastViewId = 0;
  39660. DX.framework[_VIEW_ROLE] = DX.DOMComponent.inherit({
  39661. _setDefaultOptions: function() {
  39662. this.callBase();
  39663. this.option({
  39664. name: null,
  39665. title: null,
  39666. layout: null
  39667. })
  39668. },
  39669. ctor: function() {
  39670. this.callBase.apply(this, arguments);
  39671. this._id = ++lastViewId
  39672. },
  39673. _render: function() {
  39674. this.callBase();
  39675. this._element().addClass("dx-view")
  39676. },
  39677. getId: function() {
  39678. return this._id
  39679. }
  39680. });
  39681. DX.registerComponent(_VIEW_ROLE, DX.framework.dxView);
  39682. DX.framework[_LAYOUT_ROLE] = DX.DOMComponent.inherit({
  39683. _setDefaultOptions: function() {
  39684. this.callBase();
  39685. this.option({name: null})
  39686. },
  39687. _render: function() {
  39688. this.callBase();
  39689. this._element().addClass("dx-layout")
  39690. }
  39691. });
  39692. DX.registerComponent(_LAYOUT_ROLE, DX.framework.dxLayout);
  39693. DX.framework.dxViewPlaceholder = DX.DOMComponent.inherit({
  39694. _setDefaultOptions: function() {
  39695. this.callBase();
  39696. this.option({viewName: null})
  39697. },
  39698. _render: function() {
  39699. this.callBase();
  39700. this._element().addClass("dx-view-placeholder")
  39701. }
  39702. });
  39703. DX.registerComponent("dxViewPlaceholder", DX.framework.dxViewPlaceholder);
  39704. var setupTransitionElement = function($element, transitionType, transitionName, contentCssPosition) {
  39705. if (contentCssPosition === "absolute")
  39706. $element.addClass("dx-transition-absolute");
  39707. else
  39708. $element.addClass("dx-transition-static");
  39709. $element.addClass("dx-transition").addClass("dx-transition-" + transitionName);
  39710. $element.data("dx-transition-type", transitionType);
  39711. $element.data("dx-transition-name", transitionName)
  39712. };
  39713. var setupTransitionInnerElement = function($element) {
  39714. $element.addClass("dx-transition-inner-wrapper")
  39715. };
  39716. DX.framework.dxTransition = DX.DOMComponent.inherit({
  39717. _setDefaultOptions: function() {
  39718. this.callBase();
  39719. this.option({
  39720. name: null,
  39721. type: "slide"
  39722. })
  39723. },
  39724. _render: function() {
  39725. this.callBase();
  39726. var element = this._element();
  39727. setupTransitionElement(element, this.option("type"), this.option("name"), "absolute");
  39728. element.wrapInner("<div/>");
  39729. setupTransitionInnerElement(element.children())
  39730. },
  39731. _clean: function() {
  39732. this.callBase();
  39733. this._element().empty()
  39734. }
  39735. });
  39736. DX.registerComponent("dxTransition", DX.framework.dxTransition);
  39737. DX.framework.dxContentPlaceholder = DX.DOMComponent.inherit({
  39738. _setDefaultOptions: function() {
  39739. this.callBase();
  39740. this.option({
  39741. name: null,
  39742. transition: "none",
  39743. contentCssPosition: "absolute"
  39744. })
  39745. },
  39746. _render: function() {
  39747. this.callBase();
  39748. var $element = this._element();
  39749. $element.addClass("dx-content-placeholder").addClass("dx-content-placeholder-" + this.option("name"));
  39750. setupTransitionElement($element, this.option("transition"), this.option("name"), this.option("contentCssPosition"))
  39751. },
  39752. prepareTransition: function() {
  39753. var $element = this._element();
  39754. if ($element.children(".dx-content").length === 0) {
  39755. $element.wrapInner("<div>");
  39756. $element.children().dxContent({targetPlaceholder: this.option("name")})
  39757. }
  39758. }
  39759. });
  39760. DX.registerComponent("dxContentPlaceholder", DX.framework.dxContentPlaceholder);
  39761. DX.framework.dxContent = DX.DOMComponent.inherit({
  39762. _setDefaultOptions: function() {
  39763. this.callBase();
  39764. this.option({targetPlaceholder: null})
  39765. },
  39766. _optionChanged: function(name) {
  39767. this._refresh()
  39768. },
  39769. _clean: function() {
  39770. this.callBase();
  39771. this._element().removeClass(this._currentClass)
  39772. },
  39773. _render: function() {
  39774. this.callBase();
  39775. var element = this._element();
  39776. element.addClass("dx-content");
  39777. this._currentClass = "dx-content-" + this.option("targetPlaceholder");
  39778. element.addClass(this._currentClass);
  39779. setupTransitionInnerElement(element)
  39780. }
  39781. });
  39782. DX.registerComponent("dxContent", DX.framework.dxContent);
  39783. DX.framework.html.ViewEngine = Class.inherit({
  39784. ctor: function(options) {
  39785. options = options || {};
  39786. this.$root = options.$root;
  39787. this.device = options.device || {};
  39788. this.templateEngine = options.templateEngine;
  39789. this.dataOptionsAttributeName = options.dataOptionsAttributeName || "data-options";
  39790. this._templateMap = {};
  39791. this._pendingViewContainer = null;
  39792. this.viewSelecting = $.Callbacks();
  39793. this.modelFromViewDataExtended = $.Callbacks();
  39794. this.layoutSelecting = $.Callbacks();
  39795. this._templateContext = options.templateContext
  39796. },
  39797. init: function() {
  39798. var that = this;
  39799. this._initDefaultLayout();
  39800. return this._loadExternalTemplates().done(function() {
  39801. that._loadTemplatesFromMarkupCore(that.$root.children());
  39802. that._processTemplates()
  39803. })
  39804. },
  39805. _enumerateTemplates: function(processFn) {
  39806. var that = this;
  39807. $.each(that._templateMap, function(name, templatesByRoleMap) {
  39808. $.each(templatesByRoleMap, function(role, templates) {
  39809. $.each(templates, function(index, template) {
  39810. processFn(template)
  39811. })
  39812. })
  39813. })
  39814. },
  39815. _findComponent: function(name, role) {
  39816. var components = (this._templateMap[name] || {})[role] || [],
  39817. filter = this._templateContext && this._templateContext.option() || {};
  39818. components = this._filterTemplates(filter, components);
  39819. this._checkMatchedTemplates(components);
  39820. return components[0]
  39821. },
  39822. _findTemplate: function(name, role) {
  39823. var component = this._findComponent(name, role);
  39824. if (!component)
  39825. throw new Error("Error 404: Template not found. role: " + role + ", name: " + name);
  39826. var $template = component._element(),
  39827. $result = $template.clone();
  39828. this._createComponents($result, [role]);
  39829. return $result
  39830. },
  39831. _extendModelFromViewData: function($view, model) {
  39832. DX.utils.extendFromObject(model, $view.data(_VIEW_ROLE).option());
  39833. this.modelFromViewDataExtended.fire({
  39834. view: $view,
  39835. model: model
  39836. })
  39837. },
  39838. _createComponents: function($markup, types) {
  39839. var that = this;
  39840. var result = [];
  39841. $markup.find("*").addBack().filter("[" + that.dataOptionsAttributeName + "]").each(function(index, element) {
  39842. var $element = $(element),
  39843. optionsString = $element.attr(that.dataOptionsAttributeName),
  39844. options;
  39845. try {
  39846. options = new Function("return {" + optionsString + "}")()
  39847. }
  39848. catch(ex) {
  39849. throw new Error(DX.utils.stringFormat("Unable to parse options.\nMessage: {0};\nOptions value: {1}", ex, optionsString));
  39850. }
  39851. for (var componentName in options)
  39852. if (!types || $.inArray(componentName, types) > -1)
  39853. if ($element[componentName]) {
  39854. $element[componentName](options[componentName]);
  39855. result.push($element[componentName]("instance"))
  39856. }
  39857. });
  39858. return result
  39859. },
  39860. _loadTemplatesFromMarkupCore: function($markup) {
  39861. if ($markup.find("[data-dx-role]").length)
  39862. throw Error("View templates should be updated according to the 13.1 changes. Go to http://dxpr.es/15ikrJA for more details");
  39863. var that = this;
  39864. $markup.appendTo(this.$root);
  39865. DX.localization.localizeNode($markup);
  39866. var components = that._createComponents($markup, [_VIEW_ROLE, _LAYOUT_ROLE]);
  39867. $.each(components, function(index, component) {
  39868. var $element = component._element();
  39869. $element.addClass("dx-hidden");
  39870. that._registerTemplateComponent(component);
  39871. component._element().detach()
  39872. })
  39873. },
  39874. _registerTemplateComponent: function(component) {
  39875. var role = component.NAME,
  39876. options = component.option(),
  39877. templateName = options.name,
  39878. componentsByRoleMap = this._templateMap[templateName] || {};
  39879. componentsByRoleMap[role] = componentsByRoleMap[role] || [];
  39880. componentsByRoleMap[role].push(component);
  39881. this._templateMap[templateName] = componentsByRoleMap
  39882. },
  39883. _applyPartialViews: function($render) {
  39884. var that = this;
  39885. this._createComponents($render, ["dxViewPlaceholder"]);
  39886. $.each($render.find(".dx-view-placeholder"), function() {
  39887. var $partialPlaceholder = $(this);
  39888. if ($partialPlaceholder.children().length)
  39889. return;
  39890. var viewName = $partialPlaceholder.data("dxViewPlaceholder").option("viewName"),
  39891. $view = that._findTemplate(viewName, _VIEW_ROLE);
  39892. that._applyPartialViews($view);
  39893. $partialPlaceholder.append($view);
  39894. $view.removeClass("dx-hidden")
  39895. })
  39896. },
  39897. _ajaxImpl: function() {
  39898. return $.ajax.apply($, arguments)
  39899. },
  39900. _loadTemplatesFromURL: function(url) {
  39901. var that = this,
  39902. options = this._getLoadOptions(),
  39903. deferred = $.Deferred();
  39904. this._ajaxImpl({
  39905. url: options.winPhonePrefix + url,
  39906. isLocal: options.isLocal,
  39907. dataType: "html"
  39908. }).done(function(data) {
  39909. that._loadTemplatesFromMarkupCore(DX.utils.createMarkupFromString(data));
  39910. deferred.resolve()
  39911. }).fail(function(jqXHR, textStatus, errorThrown) {
  39912. var error = new Error(DX.utils.stringFormat("Remote template cannot be loaded.\r\nUrl:{0}\r\nError:{1}.", url, errorThrown));
  39913. deferred.reject(error)
  39914. });
  39915. return deferred.promise()
  39916. },
  39917. _getLoadOptions: function() {
  39918. if (location.protocol.indexOf("wmapp") >= 0)
  39919. return {
  39920. winPhonePrefix: location.protocol + "www/",
  39921. isLocal: true
  39922. };
  39923. return {
  39924. winPhonePrefix: "",
  39925. isLocal: undefined
  39926. }
  39927. },
  39928. _loadExternalTemplates: function() {
  39929. var tasks = [],
  39930. that = this;
  39931. $("head").find("link[rel='dx-template']").each(function(index, link) {
  39932. var task = that._loadTemplatesFromURL($(link).attr("href"));
  39933. tasks.push(task)
  39934. });
  39935. return $.when.apply($, tasks)
  39936. },
  39937. _processTemplates: function() {
  39938. var that = this;
  39939. $.each(that._templateMap, function(name, templatesByRoleMap) {
  39940. $.each(templatesByRoleMap, function(role, templates) {
  39941. that._filterTemplatesByDevice(templates)
  39942. })
  39943. });
  39944. that._enumerateTemplates(function(template) {
  39945. that._applyPartialViews(template._element())
  39946. })
  39947. },
  39948. _filterTemplatesByDevice: function(components) {
  39949. var filteredComponents = this._filterTemplates(this.device, components);
  39950. $.each(components, function(index, component) {
  39951. if ($.inArray(component, filteredComponents) < 0) {
  39952. component._dispose();
  39953. component._element().remove()
  39954. }
  39955. });
  39956. components.length = 0;
  39957. components.push.apply(components, filteredComponents)
  39958. },
  39959. _filterTemplates: function(filter, components) {
  39960. return DX.utils.findBestMatches(filter, components, function(component) {
  39961. return component.option()
  39962. })
  39963. },
  39964. _checkMatchedTemplates: function(bestMatches) {
  39965. if (bestMatches.length > 1) {
  39966. var message = "Concurrent templates are found:\r\n";
  39967. $.each(bestMatches, function(index, match) {
  39968. message += match._element().attr("data-options") + "\r\n"
  39969. });
  39970. message += "Target device:\r\n";
  39971. message += JSON.stringify(this.device);
  39972. throw Error(message);
  39973. }
  39974. },
  39975. _extendModelFormViewTemplate: function($viewTemplate, model) {
  39976. this._extendModelFromViewData($viewTemplate, model)
  39977. },
  39978. _ensureTemplates: function(viewInfo) {
  39979. this._ensureViewTemplate(viewInfo)
  39980. },
  39981. _ensureViewTemplate: function(viewInfo) {
  39982. viewInfo.$viewTemplate = viewInfo.$viewTemplate || this.findViewTemplate(viewInfo.viewName);
  39983. return viewInfo.$viewTemplate
  39984. },
  39985. _wrapViewDefaultContent: function($viewTemplate) {
  39986. $viewTemplate.wrapInner("<div class=\"dx-full-height\"></div>");
  39987. $viewTemplate.children().eq(0).dxContent({targetPlaceholder: 'content'})
  39988. },
  39989. _initDefaultLayout: function() {
  39990. this._$defaultLayoutTemplate = $("<div class=\"dx-full-height\" data-options=\"dxLayout : { name: 'default' } \"> \
  39991. <div class=\"dx-full-height\" data-options=\"dxContentPlaceholder : { name: 'content' } \" ></div> \
  39992. </div>")
  39993. },
  39994. _getDefaultLayoutTemplate: function() {
  39995. var $result = this._$defaultLayoutTemplate.clone();
  39996. this._createComponents($result);
  39997. return $result
  39998. },
  39999. _applyTemplate: function($markup, model) {
  40000. var that = this;
  40001. $markup.each(function(i, element) {
  40002. that.templateEngine.applyTemplate(element, model)
  40003. })
  40004. },
  40005. _applyLayoutCore: function($view, $layout) {
  40006. if ($layout === undefined || $layout.length === 0)
  40007. $layout = this._getDefaultLayoutTemplate();
  40008. if ($view.children(".dx-content").length === 0)
  40009. this._wrapViewDefaultContent($view);
  40010. var $toMerge = $().add($layout).add($view);
  40011. var $placeholderContents = $toMerge.find(".dx-content");
  40012. $.each($placeholderContents, function() {
  40013. var $placeholderContent = $(this);
  40014. var placeholderId = $placeholderContent.data("dxContent").option("targetPlaceholder");
  40015. var $placeholder = $toMerge.find(".dx-content-placeholder-" + placeholderId);
  40016. $placeholder.empty();
  40017. $placeholder.append($placeholderContent)
  40018. });
  40019. $placeholderContents.filter(":not(.dx-content-placeholder .dx-content)").remove();
  40020. return $layout
  40021. },
  40022. findViewTemplate: function(viewName) {
  40023. var findViewEventArgs = {viewName: viewName};
  40024. this.viewSelecting.fire(findViewEventArgs);
  40025. return findViewEventArgs.view ? $(findViewEventArgs.view) : this._findTemplate(viewName, _VIEW_ROLE, true)
  40026. },
  40027. findViewComponent: function(name) {
  40028. return this._findComponent(name, "dxView")
  40029. },
  40030. findLayoutTemplate: function(layoutName) {
  40031. if (!layoutName)
  40032. return this._getDefaultLayoutTemplate();
  40033. var findLayoutEventArgs = {layoutName: layoutName};
  40034. this.layoutSelecting.fire(findLayoutEventArgs);
  40035. return findLayoutEventArgs.layout ? $(findLayoutEventArgs.layout) : this._findTemplate(layoutName, _LAYOUT_ROLE)
  40036. },
  40037. loadTemplates: function(source) {
  40038. var result;
  40039. if (typeof source === "string")
  40040. result = this._loadTemplatesFromURL(source);
  40041. else {
  40042. this._loadTemplatesFromMarkupCore(source);
  40043. result = $.Deferred().resolve().promise()
  40044. }
  40045. return result.done($.proxy(this._processTemplates, this))
  40046. }
  40047. })
  40048. })(jQuery, DevExpress);
  40049. /*! Module framework, file framework.htmlApplication.js */
  40050. (function($, DX, undefined) {
  40051. var frameworkNS = DX.framework,
  40052. htmlNS = frameworkNS.html;
  40053. var VIEW_PORT_CLASSNAME = "dx-viewport";
  40054. var HIDDEN_BAG_ID = "__hidden-bag";
  40055. var HIDDEN_BAG_CLASSNAME = "dx-hidden-bag";
  40056. htmlNS.HtmlApplication = frameworkNS.Application.inherit({
  40057. ctor: function(options) {
  40058. options = options || {};
  40059. this.callBase(options);
  40060. this._$root = $(options.rootNode || document.body);
  40061. this._initViewport(options.viewPort);
  40062. if (this._applicationMode === "mobileApp")
  40063. DX.utils.initMobileViewport(options.viewPort);
  40064. this.device = options.device || DX.devices.current();
  40065. var layoutSets = DX.framework.html.layoutSets;
  40066. this.commandManager = options.commandManager || new DX.framework.html.CommandManager({commandMapping: this.commandMapping});
  40067. $.each(options.layoutControllers || DX.framework.html.layoutControllers, function(_, layoutControllerInfo) {
  40068. var targetLayoutSet = layoutControllerInfo.navigationType;
  40069. layoutSets[targetLayoutSet] = layoutSets[targetLayoutSet] || [];
  40070. layoutSets[targetLayoutSet].push(layoutControllerInfo);
  40071. delete layoutControllerInfo.navigationType
  40072. });
  40073. if (options.navigationType)
  40074. DX.utils.logger.warn("The 'navigationType' option is deprecated, use 'layoutSet' instead");
  40075. if (options.defaultLayout)
  40076. DX.utils.logger.warn("The 'defaultLayout' option is deprecated, use 'layoutSet' instead");
  40077. var navigationType = options.navigationType || options.defaultLayout;
  40078. if (navigationType)
  40079. options.layoutSet = layoutSets[navigationType];
  40080. this._initHiddenBag();
  40081. this._initTemplateContext();
  40082. this.viewEngine = options.viewEngine || new htmlNS.ViewEngine({
  40083. $root: this._$root,
  40084. device: this.device,
  40085. templateEngine: options.templateEngine || new htmlNS.KnockoutJSTemplateEngine({navigationManager: this.navigationManager}),
  40086. templateContext: this._templateContext
  40087. });
  40088. this.components.push(this.viewEngine);
  40089. this.viewRendered = $.Callbacks();
  40090. this._layoutSet = options.layoutSet || (options.layoutControllers && options.layoutControllers.length ? options.layoutControllers : layoutSets["default"]);
  40091. this._availableLayoutControllers = [];
  40092. this.resolveLayoutController = $.Callbacks()
  40093. },
  40094. _createViewCache: function(options) {
  40095. var result = this.callBase(options);
  40096. if (!options.viewCache)
  40097. result = new DX.framework.ConditionalViewCacheDecorator({
  40098. filter: function(key, viewInfo) {
  40099. return !viewInfo.viewTemplateInfo.disableCache
  40100. },
  40101. viewCache: result
  40102. });
  40103. return result
  40104. },
  40105. _initViewport: function() {
  40106. this._$viewPort = this._getViewPort();
  40107. DX.ui.themes.attachCssClasses(this._$viewPort);
  40108. DX.devices.attachCssClasses(this._$viewPort)
  40109. },
  40110. _getViewPort: function() {
  40111. var $viewPort = $("." + VIEW_PORT_CLASSNAME);
  40112. if (!$viewPort.length)
  40113. $viewPort = $("<div>").addClass(VIEW_PORT_CLASSNAME).appendTo(this._$root);
  40114. return $viewPort
  40115. },
  40116. _initHiddenBag: function() {
  40117. this._$hiddenBag = this._getHiddenBag(this._$root, this._$viewPort)
  40118. },
  40119. _getHiddenBag: function($root, $viewPort) {
  40120. var $hiddenBag = $("#" + HIDDEN_BAG_ID);
  40121. if (!$hiddenBag.length)
  40122. $hiddenBag = $("<div/>").addClass(HIDDEN_BAG_CLASSNAME).attr("id", HIDDEN_BAG_ID).appendTo($root);
  40123. $hiddenBag.addClass(($viewPort.attr("class") || "").replace(VIEW_PORT_CLASSNAME, ""));
  40124. return $hiddenBag
  40125. },
  40126. _initTemplateContext: function() {
  40127. this._templateContext = new DX.Component({orientation: DX.devices.orientation()});
  40128. DX.devices.orientationChanged.add($.proxy(function(args) {
  40129. this._templateContext.option("orientation", args.orientation)
  40130. }, this))
  40131. },
  40132. _showViewImpl: function(viewInfo, direction) {
  40133. this._activateLayoutController(viewInfo.layoutController);
  40134. this._obtainViewLink(viewInfo);
  40135. return this._activeLayoutController.showView(viewInfo, direction)
  40136. },
  40137. _setViewLoadingState: function(viewInfo, direction) {
  40138. this._activateLayoutController(viewInfo.layoutController);
  40139. return this._activeLayoutController.setViewLoadingState(viewInfo, direction)
  40140. },
  40141. _resolveLayoutController: function(viewInfo) {
  40142. var args = {
  40143. viewInfo: viewInfo,
  40144. layoutController: null,
  40145. availableLayoutControllers: this._availableLayoutControllers
  40146. };
  40147. this._processEvent("resolveLayoutController", args, viewInfo.model);
  40148. return args.layoutController || this._resolveLayoutControllerImpl(viewInfo)
  40149. },
  40150. _resolveLayoutControllerImpl: function(viewInfo) {
  40151. var target = $.extend({
  40152. root: !viewInfo.canBack,
  40153. customResolveRequired: false,
  40154. pane: (viewInfo.viewTemplateInfo || {}).pane
  40155. }, DX.devices.current());
  40156. var matches = DX.utils.findBestMatches(target, this._availableLayoutControllers);
  40157. if (!matches.length)
  40158. throw Error("The layout controller cannot be resolved. There are no appropriate layout controllers for the current context. Make sure you have the corresponding *.js references in your main *.html file.");
  40159. if (matches.length > 1)
  40160. throw Error("The layout controller cannot be resolved. Two or more layout controllers suit the current context. Make the layout controllers registration more specific.");
  40161. return matches[0].controller
  40162. },
  40163. _activateLayoutController: function(layoutController) {
  40164. var that = this;
  40165. if (that._activeLayoutController !== layoutController) {
  40166. if (that._activeLayoutController)
  40167. that._activeLayoutController.deactivate();
  40168. layoutController.activate();
  40169. that._activeLayoutController = layoutController
  40170. }
  40171. },
  40172. init: function() {
  40173. var that = this,
  40174. result = this.callBase();
  40175. result.done(function() {
  40176. that._initLayoutControllers();
  40177. that.renderNavigation()
  40178. });
  40179. return result
  40180. },
  40181. _disposeView: function(viewInfo) {
  40182. if (viewInfo.layoutController.disposeView)
  40183. viewInfo.layoutController.disposeView(viewInfo);
  40184. this.callBase(viewInfo)
  40185. },
  40186. viewPort: function() {
  40187. return this._$viewPort
  40188. },
  40189. _createViewInfo: function(navigationItem, navigateOptions) {
  40190. var viewInfo = this.callBase.apply(this, arguments),
  40191. templateInfo = this.getViewTemplateInfo(viewInfo.viewName);
  40192. if (!templateInfo)
  40193. throw new Error("The '" + viewInfo.viewName + "' view template is not found. Make sure case is correct and the template fits the current context.");
  40194. viewInfo.viewTemplateInfo = templateInfo;
  40195. viewInfo.layoutController = this._resolveLayoutController(viewInfo);
  40196. return viewInfo
  40197. },
  40198. _createViewModel: function(viewInfo) {
  40199. this.callBase(viewInfo);
  40200. var templateInfo = viewInfo.viewTemplateInfo,
  40201. model = viewInfo.model;
  40202. for (var name in templateInfo)
  40203. if (!(name in model))
  40204. model[name] = templateInfo[name]
  40205. },
  40206. _initLayoutControllers: function() {
  40207. var that = this;
  40208. $.each(that._layoutSet, function(index, controllerInfo) {
  40209. var controller = controllerInfo.controller,
  40210. target = DX.devices.current();
  40211. if (DX.utils.findBestMatches(target, [controllerInfo]).length) {
  40212. that._availableLayoutControllers.push(controllerInfo);
  40213. if (controller.init)
  40214. controller.init({
  40215. app: that,
  40216. $viewPort: that._$viewPort,
  40217. $hiddenBag: that._$hiddenBag,
  40218. navigationManager: that.navigationManager,
  40219. viewEngine: that.viewEngine,
  40220. templateContext: that._templateContext,
  40221. commandManager: that.commandManager
  40222. });
  40223. if (controller.viewReleased)
  40224. controller.viewReleased.add(function(viewInfo) {
  40225. that._onViewReleased(viewInfo)
  40226. });
  40227. if (controller.viewRendered)
  40228. controller.viewRendered.add(function(viewInfo) {
  40229. that._processEvent("viewRendered", {viewInfo: viewInfo}, viewInfo.model)
  40230. })
  40231. }
  40232. })
  40233. },
  40234. _onViewReleased: function(viewInfo) {
  40235. this._onViewHidden(viewInfo);
  40236. this._releaseViewLink(viewInfo)
  40237. },
  40238. renderNavigation: function() {
  40239. var that = this;
  40240. $.each(that._availableLayoutControllers, function(index, controllerInfo) {
  40241. var controller = controllerInfo.controller;
  40242. if (controller.renderNavigation)
  40243. controller.renderNavigation(that.navigation)
  40244. })
  40245. },
  40246. getViewTemplate: function(viewName) {
  40247. return this.viewEngine.findViewTemplate(viewName)
  40248. },
  40249. getViewTemplateInfo: function(viewName) {
  40250. var viewComponent = this.viewEngine.findViewComponent(viewName);
  40251. return viewComponent && viewComponent.option()
  40252. },
  40253. loadTemplates: function(source) {
  40254. return this.viewEngine.loadTemplates(source)
  40255. },
  40256. templateContext: function() {
  40257. return this._templateContext
  40258. }
  40259. })
  40260. })(jQuery, DevExpress);
  40261. /*! Module framework, file framework.transitionExecutor.js */
  40262. (function($, DX) {
  40263. $.fn.extend({unwrapInner: function(selector) {
  40264. return this.each(function() {
  40265. var t = this,
  40266. c = $(t).children(selector);
  40267. c.each(function() {
  40268. var e = $(this);
  40269. e.contents().appendTo(t);
  40270. e.remove()
  40271. })
  40272. })
  40273. }});
  40274. var TRANSITION_DURATION = 400;
  40275. var TransitionExecutor = DX.Class.inherit({
  40276. ctor: function(container, options) {
  40277. this.container = container;
  40278. this.options = options
  40279. },
  40280. exec: function() {
  40281. var that = this,
  40282. options = that.options;
  40283. var $source = options.source,
  40284. $destination = options.destination;
  40285. var $sourceAbsoluteWrapper = $source,
  40286. $destinationRelativeWrapper = $destination,
  40287. $destinationAbsoluteWrapper = that._getTransitionInnerElement($destination);
  40288. this._finalize = function(){};
  40289. return that._animate($.extend({}, options, {
  40290. source: $sourceAbsoluteWrapper,
  40291. destination: $destinationAbsoluteWrapper
  40292. }))
  40293. },
  40294. finalize: function() {
  40295. if (!this._finalize)
  40296. throw Error("The \"exec\" method should be called before the \"finalize\" one");
  40297. this._finalize()
  40298. },
  40299. _getTransitionInnerElement: function($transitionElement) {
  40300. return $transitionElement.children(".dx-active-view:not(.dx-transition-source)")
  40301. },
  40302. _animate: function() {
  40303. return (new $.Deferred).resolve().promise()
  40304. }
  40305. });
  40306. var NoneTransitionExecutor = TransitionExecutor.inherit({_animate: function(options) {
  40307. var $source = options.source,
  40308. $destination = options.destination;
  40309. var containerWidth = this.container.width();
  40310. DX.fx.animate($source, {
  40311. type: "slide",
  40312. from: {left: 0},
  40313. to: {left: 0},
  40314. duration: 0
  40315. });
  40316. DX.fx.animate($destination, {
  40317. type: "slide",
  40318. from: {left: -containerWidth},
  40319. to: {left: -containerWidth},
  40320. duration: 0
  40321. });
  40322. return $.Deferred().resolve().promise()
  40323. }});
  40324. var SlideTransitionExecutor = TransitionExecutor.inherit({_animate: function(options) {
  40325. if (options.direction === "none")
  40326. return $.Deferred().resolve().promise();
  40327. var $source = options.source,
  40328. $destination = options.destination;
  40329. var directionModifier = options.direction === "backward" ? -1 : 1,
  40330. rtlModifier = DX.rtlEnabled ? -1 : 1,
  40331. containerWidth = this.container.width() * directionModifier * rtlModifier;
  40332. var promiseSource = DX.fx.animate($source, {
  40333. type: "slide",
  40334. from: {left: containerWidth},
  40335. to: {left: 0},
  40336. duration: TRANSITION_DURATION
  40337. });
  40338. var promiseDestination = DX.fx.animate($destination, {
  40339. type: "slide",
  40340. from: {left: 0},
  40341. to: {left: -containerWidth},
  40342. duration: TRANSITION_DURATION
  40343. });
  40344. return $.when(promiseDestination, promiseSource)
  40345. }});
  40346. var SlideIOS7TransitionExecutor = TransitionExecutor.inherit({_animate: function(options) {
  40347. if (options.direction === "none")
  40348. return $.Deferred().resolve().promise();
  40349. var $source = options.source,
  40350. $destination = options.destination;
  40351. var rtlModifier = DX.rtlEnabled ? -1 : 1,
  40352. containerWidth = this.container.width() * rtlModifier,
  40353. slowTransitionWidth = containerWidth / 5,
  40354. sourceLeftFrom,
  40355. sourceLeftTo,
  40356. destinationLeftFrom,
  40357. destinationLeftTo,
  40358. sourceZIndex = $source.css("z-index"),
  40359. destinationZIndex = $destination.css("z-index");
  40360. if (options.direction === "backward") {
  40361. sourceLeftFrom = -slowTransitionWidth;
  40362. sourceLeftTo = 0;
  40363. destinationLeftFrom = 0;
  40364. destinationLeftTo = containerWidth;
  40365. $source.css("z-index", 1);
  40366. $destination.css("z-index", 2)
  40367. }
  40368. else {
  40369. sourceLeftFrom = containerWidth;
  40370. sourceLeftTo = 0;
  40371. destinationLeftFrom = 0;
  40372. destinationLeftTo = -slowTransitionWidth;
  40373. $source.css("z-index", 2);
  40374. $destination.css("z-index", 1)
  40375. }
  40376. var promiseSource = DX.fx.animate($source, {
  40377. type: "slide",
  40378. from: {left: sourceLeftFrom},
  40379. to: {left: sourceLeftTo},
  40380. duration: TRANSITION_DURATION
  40381. });
  40382. var promiseDestination = DX.fx.animate($destination, {
  40383. type: "slide",
  40384. from: {left: destinationLeftFrom},
  40385. to: {left: destinationLeftTo},
  40386. duration: TRANSITION_DURATION
  40387. });
  40388. return $.when(promiseDestination, promiseSource).done(function() {
  40389. $source.css("z-index", sourceZIndex);
  40390. $destination.css("z-index", destinationZIndex)
  40391. })
  40392. }});
  40393. var OverflowTransitionExecutor = TransitionExecutor.inherit({_animate: function(options) {
  40394. var $source = options.source,
  40395. $destination = options.destination,
  40396. destinationTop = $destination.position().top,
  40397. destinationLeft = $destination.position().left,
  40398. containerWidth = this.container.width();
  40399. if (options.direction === "backward")
  40400. containerWidth = -containerWidth;
  40401. var animations = [];
  40402. if (options.direction === "forward")
  40403. animations.push(DX.fx.animate($source, {
  40404. type: "slide",
  40405. from: {
  40406. top: destinationTop,
  40407. left: containerWidth + destinationLeft,
  40408. "z-index": 1
  40409. },
  40410. to: {left: destinationLeft},
  40411. duration: TRANSITION_DURATION
  40412. }));
  40413. else {
  40414. animations.push(DX.fx.animate($source, {
  40415. type: "slide",
  40416. from: {
  40417. left: destinationLeft,
  40418. "z-index": 1
  40419. },
  40420. to: {left: destinationLeft},
  40421. duration: TRANSITION_DURATION
  40422. }));
  40423. animations.push(DX.fx.animate($destination, {
  40424. type: "slide",
  40425. from: {"z-index": 2},
  40426. to: {left: destinationLeft - containerWidth},
  40427. duration: TRANSITION_DURATION
  40428. }))
  40429. }
  40430. return $.when.apply($, animations)
  40431. }});
  40432. var FadeTransitionExecutor = TransitionExecutor.inherit({_animate: function(options) {
  40433. var $source = options.source,
  40434. $destination = options.destination,
  40435. d = new $.Deferred;
  40436. $source.css({opacity: 0});
  40437. $destination.animate({opacity: 0}, TRANSITION_DURATION);
  40438. $source.animate({opacity: 1}, TRANSITION_DURATION, function() {
  40439. d.resolve()
  40440. });
  40441. return d.promise()
  40442. }});
  40443. var transitionType = function(options) {
  40444. if (options.type === "fade")
  40445. return options.type;
  40446. if (options.direction === "none")
  40447. return "none";
  40448. return options.type
  40449. };
  40450. TransitionExecutor.create = function(container, options) {
  40451. var device = DX.devices.current();
  40452. switch (transitionType(options)) {
  40453. case"none":
  40454. return new NoneTransitionExecutor(container, options);
  40455. case"slide":
  40456. if (device.platform === "ios" && device.version[0] === 7)
  40457. return new SlideIOS7TransitionExecutor(container, options);
  40458. else
  40459. return new SlideTransitionExecutor(container, options);
  40460. case"fade":
  40461. return new FadeTransitionExecutor(container, options);
  40462. case"overflow":
  40463. return new OverflowTransitionExecutor(container, options);
  40464. default:
  40465. throw Error(DX.utils.formatString("Unknown transition type \"{0}\"", options.type));
  40466. }
  40467. };
  40468. DX.framework.html.TransitionExecutor = TransitionExecutor;
  40469. DX.framework.html.NoneTransitionExecutor = NoneTransitionExecutor;
  40470. DX.framework.html.SlideIOS7TransitionExecutor = SlideIOS7TransitionExecutor;
  40471. DX.framework.html.SlideTransitionExecutor = SlideTransitionExecutor;
  40472. DX.framework.html.OverflowTransitionExecutor = OverflowTransitionExecutor;
  40473. DX.framework.html.FadeTransitionExecutor = FadeTransitionExecutor
  40474. })(jQuery, DevExpress);
  40475. DevExpress.MOD_FRAMEWORK = true
  40476. }
  40477. if (!DevExpress.MOD_VIZ_CORE) {
  40478. if (!window.DevExpress)
  40479. throw Error('Required module is not referenced: core');
  40480. /*! Module viz-core, file namespaces.js */
  40481. (function(DevExpress) {
  40482. DevExpress.viz = {}
  40483. })(DevExpress);
  40484. /*! Module viz-core, file namespaces.js */
  40485. (function(DevExpress) {
  40486. DevExpress.viz.core = {}
  40487. })(DevExpress);
  40488. /*! Module viz-core, file errorsWarnings.js */
  40489. (function(DevExpress) {
  40490. DevExpress.viz.core.errorsWarnings = {
  40491. E2001: "Invalid data source",
  40492. E2002: "Axis type and data type are incompatible",
  40493. E2003: "\"{0}\" data source field contains data of unsupported type",
  40494. E2004: "\"{0}\" data source field is inconsistent",
  40495. E2101: "Unknown series type was specified: {0}",
  40496. E2102: "Ambiguity occurred between two value axes with the same name",
  40497. E2103: "\"{0}\" option must be a function",
  40498. E2104: "Invalid logarithm base",
  40499. E2105: "Invalid value of a \"{0}\"",
  40500. E2106: "Invalid visible range",
  40501. E2201: "Invalid type of data source field",
  40502. E2202: "Invalid scale {0} value",
  40503. E2203: "The \"{0}\" field of the \"selectedRange\" configuration object is not valid",
  40504. W2001: "{0} cannot be drawn because its container is invisible",
  40505. W2002: "The {0} data field is absent",
  40506. W2003: "Tick interval is too small",
  40507. W2101: "\"{0}\" pane does not exist; \"{1}\" pane is used instead",
  40508. W2102: "Value axis with the \"{0}\" name was created automatically",
  40509. W2103: "Chart title was hidden due to container size",
  40510. W2104: "Legend was hidden due to container size",
  40511. W2105: "Title of \"{0}\" axis was hidden due to container size",
  40512. W2106: "Labels of \"{0}\" axis were hidden due to container size",
  40513. W2301: "Invalid value range"
  40514. }
  40515. })(DevExpress);
  40516. /*! Module viz-core, file tickProvider.js */
  40517. (function($, DX, undefined) {
  40518. var utils = DX.utils,
  40519. math = Math,
  40520. mathCeil = math.ceil,
  40521. mathFloor = math.floor,
  40522. mathAbs = math.abs,
  40523. mathRound = math.round,
  40524. core = DX.viz.core;
  40525. var TICKS_COUNT_LIMIT = 2000;
  40526. core.outOfScreen = {
  40527. x: -1000,
  40528. y: -1000
  40529. };
  40530. core.tickIntervalCalculator = {
  40531. _defaultNumberMultipliers: [1, 2, 3, 5],
  40532. _defaultGridSpacingFactor: 30,
  40533. _getCommonTickInterval: function(deltaCoef, numberMultipliers) {
  40534. var factor,
  40535. result = 0,
  40536. hasResult = false,
  40537. i;
  40538. for (factor = 1; !hasResult; factor *= 10)
  40539. for (i = 0; i < numberMultipliers.length; i++) {
  40540. result = numberMultipliers[i] * factor;
  40541. if (deltaCoef <= result) {
  40542. hasResult = true;
  40543. break
  40544. }
  40545. }
  40546. return result
  40547. },
  40548. _getNumericTickInterval: function(deltaCoef, numberMultipliers) {
  40549. var factor,
  40550. result = 0,
  40551. newResult,
  40552. hasResult = false,
  40553. i;
  40554. if (deltaCoef > 1.0)
  40555. result = this._getCommonTickInterval(deltaCoef, numberMultipliers);
  40556. else if (deltaCoef > 0) {
  40557. result = 1;
  40558. for (factor = 0.1; !hasResult; factor /= 10)
  40559. for (i = numberMultipliers.length - 1; i >= 0; i--) {
  40560. newResult = numberMultipliers[i] * factor;
  40561. if (deltaCoef > newResult) {
  40562. hasResult = true;
  40563. break
  40564. }
  40565. result = newResult
  40566. }
  40567. }
  40568. return utils.adjustValue(result)
  40569. },
  40570. _getLogarithmicTickInterval: function(deltaCoef, numberMultipliers) {
  40571. var result = 0;
  40572. if (deltaCoef !== 0)
  40573. result = this._getCommonTickInterval(deltaCoef, numberMultipliers);
  40574. return utils.adjustValue(result)
  40575. },
  40576. _getDateTimeTickInterval: function(deltaCoef, numberMultipliers) {
  40577. var dateTimeMultipliers = {
  40578. millisecond: [1, 2, 5, 10, 25, 100, 250, 300, 500],
  40579. second: [1, 2, 3, 5, 10, 15, 20, 30],
  40580. minute: [1, 2, 3, 5, 10, 15, 20, 30],
  40581. hour: [1, 2, 3, 4, 6, 8, 12],
  40582. day: [1, 2, 3, 5, 7, 10, 14],
  40583. month: [1, 2, 3, 6]
  40584. },
  40585. result = {},
  40586. factor,
  40587. key,
  40588. specificMultipliers,
  40589. yearsCount,
  40590. i;
  40591. if (deltaCoef > 0 && deltaCoef < 1.0)
  40592. return {milliseconds: 1};
  40593. else if (deltaCoef === 0)
  40594. return 0;
  40595. for (key in dateTimeMultipliers)
  40596. if (dateTimeMultipliers.hasOwnProperty(key)) {
  40597. specificMultipliers = dateTimeMultipliers[key];
  40598. for (i = 0; i < specificMultipliers.length; i++)
  40599. if (deltaCoef <= utils.convertDateUnitToMilliseconds(key, specificMultipliers[i])) {
  40600. result[key + 's'] = specificMultipliers[i];
  40601. return result
  40602. }
  40603. }
  40604. for (factor = 1; ; factor *= 10)
  40605. for (i = 0; i < numberMultipliers.length; i++) {
  40606. yearsCount = factor * numberMultipliers[i];
  40607. if (deltaCoef <= utils.convertDateUnitToMilliseconds('year', yearsCount))
  40608. return {years: yearsCount}
  40609. }
  40610. return null
  40611. },
  40612. getTickInterval: function(options) {
  40613. var that = this,
  40614. gridSpacingFactor = options.gridSpacingFactor || that._defaultGridSpacingFactor,
  40615. numberMultipliers = options.numberMultipliers || that._defaultNumberMultipliers,
  40616. businessDelta = options.businessDelta,
  40617. screenDelta = options.screenDelta,
  40618. deltaCoef = screenDelta > 0 && gridSpacingFactor < screenDelta ? gridSpacingFactor * businessDelta / screenDelta : 0;
  40619. that._testNumberMultipliers = numberMultipliers;
  40620. if (options.axisType === 'logarithmic')
  40621. return that._getLogarithmicTickInterval(deltaCoef, numberMultipliers);
  40622. else
  40623. switch (options.dataType) {
  40624. case'numeric':
  40625. return that._getNumericTickInterval(deltaCoef, numberMultipliers);
  40626. break;
  40627. case'datetime':
  40628. return that._getDateTimeTickInterval(deltaCoef, numberMultipliers);
  40629. break
  40630. }
  40631. return null
  40632. }
  40633. };
  40634. core.minorTickIntervalCalculator = {
  40635. _defaultNumberMultipliers: [2, 4, 5, 8, 10],
  40636. _defaultGridSpacingFactor: 15,
  40637. _getDateTimeTickInterval: function(businessDelta, deltaCoef, numberMultipliers) {
  40638. var result,
  40639. i;
  40640. for (i = numberMultipliers.length - 1; i >= 0; i--) {
  40641. this.testResultNumberMultiplier = numberMultipliers[i];
  40642. result = mathFloor(businessDelta / numberMultipliers[i]);
  40643. if (deltaCoef <= result)
  40644. return utils.convertMillisecondsToDateUnits(result)
  40645. }
  40646. return 0
  40647. },
  40648. _getCommonTickInterval: function(businessDelta, deltaCoef, numberMultipliers) {
  40649. var result,
  40650. i;
  40651. for (i = numberMultipliers.length - 1; i >= 0; i--) {
  40652. this.testResultNumberMultiplier = numberMultipliers[i];
  40653. result = businessDelta / numberMultipliers[i];
  40654. if (deltaCoef <= result)
  40655. return utils.adjustValue(result)
  40656. }
  40657. return 0
  40658. },
  40659. getTickInterval: function(options) {
  40660. var that = this,
  40661. gridSpacingFactor = !utils.isDefined(options.gridSpacingFactor) ? that._defaultGridSpacingFactor : options.gridSpacingFactor,
  40662. numberMultipliers = options.numberMultipliers || that._defaultNumberMultipliers,
  40663. businessDelta = options.businessDelta,
  40664. deltaCoef = gridSpacingFactor * businessDelta / options.screenDelta;
  40665. if (options.axisType === 'logarithmic')
  40666. return that._getCommonTickInterval(businessDelta, deltaCoef, numberMultipliers);
  40667. else
  40668. switch (options.dataType) {
  40669. case'numeric':
  40670. return that._getCommonTickInterval(businessDelta, deltaCoef, numberMultipliers);
  40671. case'datetime':
  40672. return that._getDateTimeTickInterval(businessDelta, deltaCoef, numberMultipliers)
  40673. }
  40674. return 0
  40675. }
  40676. };
  40677. core.tickProvider = {
  40678. _appendFakeSVGElement: function(value, text, options) {
  40679. var textOptions = $.extend({}, options.textOptions, {rotate: 0});
  40680. return options.renderer.createText(text, core.outOfScreen.x + (options.translator.translate(value) || 0), core.outOfScreen.y, textOptions).append()
  40681. },
  40682. _getDistanceByAngle: function(elementHeight, rotationAngle) {
  40683. return elementHeight / mathAbs(math.sin(rotationAngle * (math.PI / 180)))
  40684. },
  40685. _areDisplayValuesValid: function(value1, value2, options) {
  40686. var that = this,
  40687. getText = that._getTextFunc(options),
  40688. rotationAngle = options.textOptions && utils.isNumber(options.textOptions.rotate) ? options.textOptions.rotate : 0,
  40689. svgElement1 = that._appendFakeSVGElement(value1, getText(value1), options),
  40690. svgElement2 = that._appendFakeSVGElement(value2, getText(value2), options),
  40691. bBox1 = svgElement1.getBBox(),
  40692. bBox2 = svgElement2.getBBox(),
  40693. result,
  40694. translator = options.translator;
  40695. if (rotationAngle !== 0)
  40696. result = that._getDistanceByAngle(bBox1.height, rotationAngle) <= mathAbs(bBox2.x - bBox1.x);
  40697. else if (options.isHorizontal)
  40698. result = !translator.getBusinessRange().invert ? bBox1.x + bBox1.width < bBox2.x : bBox2.x + bBox2.width < bBox1.x;
  40699. else
  40700. result = mathAbs(translator.translate(value1) - translator.translate(value2)) > bBox1.height;
  40701. svgElement1.remove();
  40702. svgElement2.remove();
  40703. return result
  40704. },
  40705. _removeInvalidDatesWithUnitBegining: function(dates, options) {
  40706. if (dates.length <= 1 || !options.setTicksAtUnitBeginning || !utils.isDate(options.min))
  40707. return;
  40708. if (!this._areDisplayValuesValid(dates[0], dates[1], options))
  40709. dates.splice(1, 1)
  40710. },
  40711. _getValueSize: function(values, options) {
  40712. var that = this,
  40713. value,
  40714. rotationAngle = options.textOptions ? options.textOptions.rotate : 0,
  40715. svgElement,
  40716. bBox,
  40717. result,
  40718. getText = that._getTextFunc(options),
  40719. i;
  40720. if (values.length === 0)
  40721. return 0;
  40722. options.isRotate = utils.isNumber(rotationAngle) && rotationAngle !== 0;
  40723. if (options.isRotate || !options.isHorizontal)
  40724. value = getText(values[0]);
  40725. else {
  40726. value = [];
  40727. for (i = 0; i < values.length; i++)
  40728. value.push(getText(values[i]));
  40729. value = value.join('\n')
  40730. }
  40731. svgElement = that._appendFakeSVGElement(value, value, options);
  40732. bBox = svgElement.getBBox();
  40733. if (options.isRotate)
  40734. result = that._getDistanceByAngle(bBox.height, rotationAngle);
  40735. else
  40736. result = options.isHorizontal ? bBox.width : bBox.height;
  40737. svgElement.remove();
  40738. return mathCeil(result)
  40739. },
  40740. _adjustNumericTickValue: function(value, interval, min) {
  40741. return utils.isExponential(value) ? utils.adjustValue(value) : utils.applyPrecisionByMinDelta(min, interval, value)
  40742. },
  40743. _generateStartTick: function(tickInterval, options) {
  40744. var that = this,
  40745. milliseconds = 0,
  40746. boundedRule = options.min - options.max < 0,
  40747. startTick = options.min,
  40748. isDate = utils.isDate(options.min),
  40749. currentTickInterval = isDate ? utils.convertDateTickIntervalToMilliseconds(tickInterval) : tickInterval,
  40750. nextTick;
  40751. if (options.axisType === 'logarithmic')
  40752. startTick = utils.raiseTo(mathFloor(utils.adjustValue(utils.getLog(options.min, options.base)) / currentTickInterval * currentTickInterval), options.base);
  40753. else {
  40754. startTick = mathFloor(options.min / currentTickInterval) * currentTickInterval;
  40755. startTick = isDate ? new Date(startTick) : that._adjustNumericTickValue(startTick, currentTickInterval, options.min)
  40756. }
  40757. while (boundedRule === startTick - options.min < 0 && startTick !== options.min) {
  40758. nextTick = that._nextTick(startTick, tickInterval, options);
  40759. if (nextTick !== startTick)
  40760. startTick = nextTick;
  40761. else
  40762. return nextTick
  40763. }
  40764. return startTick
  40765. },
  40766. _nextTick: function(tick, tickInterval, options) {
  40767. var nextTick,
  40768. lgPower,
  40769. that = this;
  40770. if (options.axisType === 'logarithmic') {
  40771. lgPower = utils.addInterval(utils.adjustValue(utils.getLog(tick, options.base)), tickInterval, options.min > options.max);
  40772. nextTick = utils.raiseTo(lgPower, options.base);
  40773. nextTick = that._adjustNumericTickValue(nextTick, tickInterval, math.min(options.min, options.max))
  40774. }
  40775. else {
  40776. nextTick = utils.addInterval(tick, tickInterval, options.min > options.max);
  40777. if (options.dataType === 'numeric')
  40778. nextTick = that._adjustNumericTickValue(nextTick, tickInterval, options.min);
  40779. if (options.dataType === 'datetime' && options.setTicksAtUnitBeginning)
  40780. utils.correctDateWithUnitBeginning(nextTick, tickInterval)
  40781. }
  40782. return nextTick
  40783. },
  40784. _addMinorTicks: function(majorTick1, majorTick2, ticksInfo, options, isReverse) {
  40785. var that = this,
  40786. i,
  40787. dataType = options.dataType,
  40788. businessDelta,
  40789. minorTicks = [],
  40790. interval = 0,
  40791. minorTickIntervalsCount = options.minorTickCount + 1,
  40792. intervalsCount,
  40793. tickInterval;
  40794. options.min = majorTick1;
  40795. options.max = majorTick2;
  40796. if (!utils.isDefined(options.tickInterval)) {
  40797. options.businessDelta = businessDelta = mathAbs(options.max - options.min);
  40798. options.screenDelta = businessDelta * options.deltaCoef;
  40799. if (utils.isDefined(options.minorTickCount)) {
  40800. if (!ticksInfo.majorTicks.autoArrangementStep || ticksInfo.majorTicks.autoArrangementStep <= 1) {
  40801. intervalsCount = options.minorTickCount + 1;
  40802. interval = dataType === 'datetime' ? utils.convertDateTickIntervalToMilliseconds(ticksInfo.majorTickInterval) : ticksInfo.majorTickInterval;
  40803. minorTickIntervalsCount = mathRound(businessDelta / interval * intervalsCount) || 1
  40804. }
  40805. tickInterval = dataType === 'datetime' ? utils.convertMillisecondsToDateUnits(businessDelta / minorTickIntervalsCount) : businessDelta / minorTickIntervalsCount;
  40806. if ($.isNumeric(tickInterval))
  40807. tickInterval = utils.adjustValue(tickInterval)
  40808. }
  40809. else if (utils.isDate(majorTick1))
  40810. tickInterval = core.minorTickIntervalCalculator.getTickInterval(options)
  40811. }
  40812. options = $.extend(true, {}, options, {tickInterval: tickInterval});
  40813. minorTicks = that.getTicks(options);
  40814. if (isReverse)
  40815. minorTicks.reverse();
  40816. if (minorTicks.length > 0)
  40817. if (mathCeil(mathAbs(majorTick2 - minorTicks[minorTicks.length - 1]) * options.deltaCoef) < 2)
  40818. minorTicks.pop();
  40819. for (i = 0; i < minorTicks.length; i++) {
  40820. ticksInfo.minorTicks.push(minorTicks[i]);
  40821. ticksInfo.fullTicks.push(minorTicks[i])
  40822. }
  40823. },
  40824. _addLeftBoudedTicks: function(ticksInfo, min, minorTicksOptions) {
  40825. if (utils.isDefined(min) && ticksInfo.majorTicks[0].valueOf() !== min.valueOf()) {
  40826. minorTicksOptions.addMinMax.max = true;
  40827. this._addMinorTicks(ticksInfo.majorTicks[0], min, ticksInfo, minorTicksOptions, true);
  40828. minorTicksOptions.addMinMax.max = false;
  40829. if (minorTicksOptions.showCustomBoundaryTicks) {
  40830. if (ticksInfo.minorTicks.length > 0 && ticksInfo.minorTicks[0].valueOf() === min.valueOf())
  40831. ticksInfo.minorTicks.shift(min);
  40832. ticksInfo.customBoundaryTicks.push(min);
  40833. ticksInfo.fullTicks.unshift(min)
  40834. }
  40835. }
  40836. },
  40837. _addRightBoudedTicks: function(ticksInfo, max, minorTicksOptions) {
  40838. var lastMajorTick = ticksInfo.majorTicks[ticksInfo.majorTicks.length - 1];
  40839. ticksInfo.fullTicks.push(lastMajorTick);
  40840. if (utils.isDefined(max) && lastMajorTick.valueOf() !== max.valueOf()) {
  40841. minorTicksOptions.addMinMax.min = false;
  40842. minorTicksOptions.addMinMax.max = true;
  40843. this._addMinorTicks(lastMajorTick, max, ticksInfo, minorTicksOptions);
  40844. if (minorTicksOptions.showCustomBoundaryTicks) {
  40845. if (ticksInfo.minorTicks.length > 0 && ticksInfo.minorTicks[ticksInfo.minorTicks.length - 1].valueOf() === max.valueOf())
  40846. ticksInfo.minorTicks.pop(max);
  40847. ticksInfo.customBoundaryTicks.push(max);
  40848. ticksInfo.fullTicks.push(max)
  40849. }
  40850. }
  40851. },
  40852. _correctBoundedTicks: function(min, max, ticks, addMinMax) {
  40853. addMinMax = $.extend({}, {
  40854. min: true,
  40855. max: true
  40856. }, addMinMax);
  40857. if (ticks.length > 0) {
  40858. if (!addMinMax.min && ticks[0].valueOf() === min.valueOf())
  40859. ticks.shift();
  40860. if (!addMinMax.max || ticks[ticks.length - 1].valueOf() !== max.valueOf())
  40861. ticks.pop()
  40862. }
  40863. },
  40864. _initializeMinorTicksOptions: function(min, max, screenDelta, ticksInfo, options) {
  40865. var that = this,
  40866. businessDelta,
  40867. hasMinorsCount = utils.isDefined(options.minorTickCount);
  40868. $.extend(true, options, {
  40869. addMinMax: {
  40870. min: false,
  40871. max: false
  40872. },
  40873. deltaCoef: that._getDeltaCoef(screenDelta, max, min, options.axisType, options.base)
  40874. }, options);
  40875. options.numberMultipliers = hasMinorsCount ? [options.minorTickCount + 1] : options.numberMultipliers;
  40876. options.gridSpacingFactor = hasMinorsCount ? 0 : options.gridSpacingFactor;
  40877. if (!hasMinorsCount && ticksInfo.majorTicks.length > 1) {
  40878. options.businessDelta = businessDelta = that._getBusinessDelta(options.axisType, ticksInfo.majorTicks[0], ticksInfo.majorTicks[1], options.base);
  40879. if (that.needTickIntervalCalculation(businessDelta, ticksInfo.minorTickInterval, options.incidentOccured)) {
  40880. options.screenDelta = businessDelta * options.deltaCoef;
  40881. ticksInfo.minorTickInterval = core.minorTickIntervalCalculator.getTickInterval(options);
  40882. if (utils.isNumber(min))
  40883. options.tickInterval = ticksInfo.minorTickInterval;
  40884. else
  40885. options.tickInterval = undefined
  40886. }
  40887. }
  40888. },
  40889. _getDataType: function(value) {
  40890. return utils.isDate(value) ? 'datetime' : 'numeric'
  40891. },
  40892. _getBusinessDelta: function(type, min, max, base) {
  40893. return type === 'logarithmic' ? mathRound(mathAbs(utils.getLog(min, base) - utils.getLog(max, base))) : mathAbs(min - max)
  40894. },
  40895. _getDeltaCoef: function(screenDelta, max, min, type, base) {
  40896. return screenDelta / this._getBusinessDelta(type, min, max, base)
  40897. },
  40898. _initializeMajorTicksOptions: function(min, max, screenDelta, ticksInfo, options) {
  40899. var businessDelta;
  40900. options.screenDelta = screenDelta;
  40901. $.extend(true, options, {
  40902. min: min,
  40903. max: max,
  40904. screenDelta: screenDelta,
  40905. isHorizontal: true
  40906. });
  40907. if (utils.isDefined(min) && utils.isDefined(max)) {
  40908. options.businessDelta = businessDelta = this._getBusinessDelta(options.axisType, min, max, options.base);
  40909. if (this.needTickIntervalCalculation(businessDelta, ticksInfo.majorTickInterval, options.incidentOccured)) {
  40910. options.isStartTickGenerated = true;
  40911. ticksInfo.majorTickInterval = core.tickIntervalCalculator.getTickInterval(options);
  40912. options.tickInterval = ticksInfo.majorTickInterval
  40913. }
  40914. }
  40915. },
  40916. _getTextFunc: function(options) {
  40917. return options.getText || function(value) {
  40918. return value.toString()
  40919. }
  40920. },
  40921. _generateTicks: function(options) {
  40922. var that = this,
  40923. ticks = [],
  40924. tick,
  40925. boundedRule = options.max - options.min > 0,
  40926. leftBound,
  40927. rightBound,
  40928. tickInterval,
  40929. isStartTickGenerated = options.isStartTickGenerated,
  40930. businessDelta,
  40931. useTicksAutoArrangement = options.useTicksAutoArrangement;
  40932. options.dataType = options.dataType || that._getDataType(options.min);
  40933. options.businessDelta = businessDelta = that._getBusinessDelta(options.axisType, options.min, options.max, options.base);
  40934. if (!utils.isDefined(options.min) || !utils.isDefined(options.max) || isNaN(options.min) || isNaN(options.max)) {
  40935. ticks = options.isHorizontal ? ['canvas_position_left', 'canvas_position_center', 'canvas_position_right'] : ['canvas_position_bottom', 'canvas_position_middle', 'canvas_position_top'];
  40936. useTicksAutoArrangement = false;
  40937. ticks.hideLabels = true
  40938. }
  40939. else {
  40940. tickInterval = $.isNumeric(options.min) && $.isNumeric(options.max) && !$.isNumeric(options.tickInterval) ? undefined : options.tickInterval;
  40941. if (this.needTickIntervalCalculation(businessDelta, tickInterval, options.incidentOccured)) {
  40942. isStartTickGenerated = utils.isDefined(isStartTickGenerated) ? isStartTickGenerated : true;
  40943. tickInterval = core.tickIntervalCalculator.getTickInterval(options)
  40944. }
  40945. ticks.tickInterval = tickInterval;
  40946. that.isTestStartTickGenerated = isStartTickGenerated;
  40947. that.isTestTickInterval = tickInterval;
  40948. that.testGridSpacingFactor = options.gridSpacingFactor;
  40949. if (tickInterval && tickInterval.valueOf() !== 0 && options.min.valueOf() !== options.max.valueOf()) {
  40950. tick = isStartTickGenerated ? that._generateStartTick(tickInterval, options) : options.min;
  40951. do {
  40952. ticks.push(tick);
  40953. tick = that._nextTick(tick, tickInterval, options);
  40954. if (ticks[ticks.length - 1].valueOf() === tick.valueOf())
  40955. break;
  40956. leftBound = tick - options.min > 0;
  40957. rightBound = options.max - tick > 0
  40958. } while (boundedRule === leftBound && boundedRule === rightBound);
  40959. ticks.push(tick);
  40960. that._correctBoundedTicks(options.min, options.max, ticks, options.addMinMax)
  40961. }
  40962. if (options.min.valueOf() === options.max.valueOf()) {
  40963. tick = options.min;
  40964. ticks.push(tick)
  40965. }
  40966. }
  40967. return ticks
  40968. },
  40969. _getAutoArrangementStep: function(ticks, options) {
  40970. var that = this,
  40971. requiredValuesCount,
  40972. addedSpacing = options.isHorizontal ? options.textSpacing : 0;
  40973. if (options.getCustomAutoArrangementStep)
  40974. return options.getCustomAutoArrangementStep(ticks, options);
  40975. if (options.maxDisplayValueSize > 0) {
  40976. requiredValuesCount = mathFloor((options.screenDelta + options.textSpacing) / (options.maxDisplayValueSize + addedSpacing));
  40977. return mathCeil((options.ticksCount || ticks.length) / requiredValuesCount)
  40978. }
  40979. return 1
  40980. },
  40981. _getAutoArrangementTicks: function(ticks, options, step) {
  40982. var that = this,
  40983. resultTicks = ticks,
  40984. i;
  40985. if (step > 1) {
  40986. resultTicks = [];
  40987. for (i = 0; i < ticks.length; i += step)
  40988. resultTicks.push(ticks[i]);
  40989. resultTicks.tickInterval = ticks.tickInterval * step
  40990. }
  40991. return resultTicks
  40992. },
  40993. isOverlappedTicks: function(ticks, options) {
  40994. options.maxDisplayValueSize = this._getValueSize(ticks, options);
  40995. return this._getAutoArrangementStep(ticks, options) > 1
  40996. },
  40997. getCorrectedTicks: function(ticks, ticksOptions) {
  40998. var step = Math.ceil(core.tickIntervalCalculator.getTickInterval({
  40999. screenDelta: ticksOptions.screenDelta * 4,
  41000. businessDelta: ticks.length,
  41001. gridSpacingFactor: ticksOptions.gridSpacingFactor,
  41002. numberMultipliers: ticksOptions.numberMultipliers,
  41003. dataType: "numeric"
  41004. })) || ticks.length;
  41005. return this._getAutoArrangementTicks(ticks, ticksOptions, step)
  41006. },
  41007. needTickIntervalCalculation: function(businessDelta, tickInterval, incidentOccured) {
  41008. var date;
  41009. if (utils.isDefined(tickInterval)) {
  41010. if (!utils.isNumber(tickInterval)) {
  41011. date = new Date;
  41012. tickInterval = utils.addInterval(date, tickInterval) - date;
  41013. if (!tickInterval)
  41014. return true
  41015. }
  41016. if (utils.isNumber(tickInterval))
  41017. if (tickInterval > 0 && businessDelta / tickInterval > TICKS_COUNT_LIMIT) {
  41018. if (incidentOccured)
  41019. incidentOccured('W2003')
  41020. }
  41021. else
  41022. return false
  41023. }
  41024. return true
  41025. },
  41026. getTickIntervals: function(min, max, screenDelta, majorTicksOptions, minorTicksOptions, options) {
  41027. var that = this,
  41028. i,
  41029. options = options || {},
  41030. ticksInfo = {
  41031. majorTickInterval: majorTicksOptions.tickInterval,
  41032. minorTickInterval: minorTicksOptions.tickInterval,
  41033. majorTicks: []
  41034. };
  41035. majorTicksOptions.base = minorTicksOptions.base = options.base;
  41036. majorTicksOptions.axisType = minorTicksOptions.axisType = options.axisType;
  41037. majorTicksOptions.dataType = minorTicksOptions.dataType = options.dataType;
  41038. that._initializeMajorTicksOptions(min, max, screenDelta, ticksInfo, majorTicksOptions);
  41039. if (utils.isDefined(min) && utils.isDefined(max)) {
  41040. ticksInfo.majorTicks.push(min);
  41041. ticksInfo.majorTicks.push(that._nextTick(min, ticksInfo.majorTickInterval, {
  41042. min: min,
  41043. max: max,
  41044. setTicksAtUnitBeginning: majorTicksOptions.setTicksAtUnitBeginning,
  41045. dataType: options.dataType,
  41046. axisType: options.axisType,
  41047. base: options.base
  41048. }));
  41049. that._initializeMinorTicksOptions(min, max, screenDelta, ticksInfo, minorTicksOptions)
  41050. }
  41051. return ticksInfo
  41052. },
  41053. getFullTicks: function(min, max, screenDelta, majorTicksOptions, minorTicksOptions, options) {
  41054. var that = this,
  41055. i,
  41056. options = options || {},
  41057. ticksInfo = {
  41058. customBoundaryTicks: [],
  41059. fullTicks: [],
  41060. majorTickInterval: majorTicksOptions.tickInterval,
  41061. majorTicks: [],
  41062. minorTickInterval: minorTicksOptions.tickInterval,
  41063. minorTicks: []
  41064. };
  41065. majorTicksOptions.base = minorTicksOptions.base = options.base;
  41066. majorTicksOptions.axisType = minorTicksOptions.axisType = options.axisType;
  41067. majorTicksOptions.dataType = minorTicksOptions.dataType = options.dataType || that._getDataType(min);
  41068. that._initializeMajorTicksOptions(min, max, screenDelta, ticksInfo, majorTicksOptions);
  41069. ticksInfo.majorTicks = that.getTicks(majorTicksOptions);
  41070. if (utils.isDefined(min) && utils.isDefined(max) && ticksInfo.majorTicks.length > 0) {
  41071. if (ticksInfo.majorTicks.autoArrangementStep && ticksInfo.majorTicks.autoArrangementStep > 1 && !utils.isDefined(minorTicksOptions.tickInterval) && !utils.isDefined(minorTicksOptions.minorTickCount))
  41072. minorTicksOptions.tickInterval = ticksInfo.minorTickInterval = majorTicksOptions.tickInterval;
  41073. that._initializeMinorTicksOptions(min, max, screenDelta, ticksInfo, minorTicksOptions);
  41074. that._addLeftBoudedTicks(ticksInfo, min, minorTicksOptions);
  41075. for (i = 0; i < ticksInfo.majorTicks.length - 1; i++) {
  41076. ticksInfo.fullTicks.push(ticksInfo.majorTicks[i]);
  41077. that._addMinorTicks(ticksInfo.majorTicks[i], ticksInfo.majorTicks[i + 1], ticksInfo, minorTicksOptions)
  41078. }
  41079. that._addRightBoudedTicks(ticksInfo, max, minorTicksOptions)
  41080. }
  41081. return ticksInfo
  41082. },
  41083. getTicks: function(options) {
  41084. var that = this,
  41085. step,
  41086. maxDisplayValue,
  41087. ticks = options.customTicks ? options.customTicks : that._generateTicks(options);
  41088. if (options.useTicksAutoArrangement) {
  41089. options.maxDisplayValueSize = that._getValueSize(ticks, options);
  41090. step = that._getAutoArrangementStep(ticks, options);
  41091. if (step > 1) {
  41092. if (utils.isDefined(options.tickInterval) || utils.isDefined(options.customTicks)) {
  41093. utils.isDefined(options.customTicks) && (ticks.tickInterval = options.tickInterval);
  41094. ticks = that._getAutoArrangementTicks(ticks, options, step)
  41095. }
  41096. else
  41097. ticks = that._generateTicks($.extend({}, options, {gridSpacingFactor: options.maxDisplayValueSize}));
  41098. ticks.autoArrangementStep = step
  41099. }
  41100. that._removeInvalidDatesWithUnitBegining(ticks, options)
  41101. }
  41102. return ticks
  41103. }
  41104. }
  41105. })(jQuery, DevExpress);
  41106. /*! Module viz-core, file numericTranslator.js */
  41107. (function($, DX, undefined) {
  41108. var utils = DX.utils,
  41109. isDefined = utils.isDefined,
  41110. getPower = utils.getPower,
  41111. round = Math.round;
  41112. DX.viz.core.numericTranslatorFunctions = {
  41113. translate: function(bp) {
  41114. var that = this,
  41115. canvasOptions = that._canvasOptions,
  41116. doubleError = canvasOptions.rangeDoubleError,
  41117. specialValue = that.translateSpecialCase(bp);
  41118. if (isDefined(specialValue))
  41119. return specialValue;
  41120. if (isNaN(bp) || bp.valueOf() + doubleError < canvasOptions.rangeMin || bp.valueOf() - doubleError > canvasOptions.rangeMax)
  41121. return null;
  41122. return round(that._calculateProjection((bp - canvasOptions.rangeMinVisible) * canvasOptions.ratioOfCanvasRange))
  41123. },
  41124. untranslate: function(pos) {
  41125. var canvasOptions = this._canvasOptions,
  41126. startPoint = canvasOptions.startPoint;
  41127. if (pos < startPoint || pos > canvasOptions.endPoint)
  41128. return null;
  41129. return this._calculateUnProjection((pos - startPoint) / canvasOptions.ratioOfCanvasRange)
  41130. },
  41131. getInterval: function() {
  41132. return round(this._canvasOptions.ratioOfCanvasRange * (this._businessRange.interval || Math.abs(this._canvasOptions.rangeMax - this._canvasOptions.rangeMin)))
  41133. }
  41134. }
  41135. })(jQuery, DevExpress);
  41136. /*! Module viz-core, file datetimeTranslator.js */
  41137. (function($, DX, undefined) {
  41138. var core = DX.viz.core,
  41139. numericTranslator = core.numericTranslatorFunctions;
  41140. core.datetimeTranslatorFunctions = {
  41141. translate: numericTranslator.translate,
  41142. untranslate: function(pos) {
  41143. var result = numericTranslator.untranslate.call(this, pos);
  41144. return result === null ? result : new Date(result)
  41145. },
  41146. getInterval: numericTranslator.getInterval
  41147. }
  41148. })(jQuery, DevExpress);
  41149. /*! Module viz-core, file categoryTranslator.js */
  41150. (function($, DX, undefined) {
  41151. var isDefined = DX.utils.isDefined,
  41152. round = Math.round;
  41153. function doubleRound(value) {
  41154. return round(round(value * 10) / 10)
  41155. }
  41156. DX.viz.core.categoryTranslatorFunctions = {
  41157. translate: function(category) {
  41158. var that = this,
  41159. canvasOptions = that._canvasOptions,
  41160. categoryRecord = that._categoriesToPoints[category],
  41161. stickDelta,
  41162. specialValue = that.translateSpecialCase(category);
  41163. if (isDefined(specialValue))
  41164. return specialValue;
  41165. if (!categoryRecord)
  41166. return 0;
  41167. stickDelta = that._businessRange.stick ? categoryRecord.index : categoryRecord.index + 0.5;
  41168. return round(canvasOptions.startPoint + canvasOptions.interval * stickDelta)
  41169. },
  41170. untranslate: function(pos) {
  41171. var that = this,
  41172. canvasOptions = that._canvasOptions,
  41173. startPoint = canvasOptions.startPoint,
  41174. categoriesLength = that._categories.length,
  41175. result = 0;
  41176. if (pos < startPoint || pos > canvasOptions.endPoint)
  41177. return null;
  41178. result = doubleRound((pos - startPoint) / canvasOptions.interval + (that._businessRange.stick ? 0.5 : 0) - 0.5);
  41179. if (categoriesLength === result)
  41180. result--;
  41181. if (canvasOptions.invert)
  41182. result = categoriesLength - result - 1;
  41183. return that._categories[result]
  41184. },
  41185. getInterval: function() {
  41186. return this._canvasOptions.interval
  41187. }
  41188. }
  41189. })(jQuery, DevExpress);
  41190. /*! Module viz-core, file logarithmicTranslator.js */
  41191. (function($, DX, undefined) {
  41192. var core = DX.viz.core,
  41193. numericTranslator = core.numericTranslatorFunctions,
  41194. utils = DX.utils,
  41195. raiseTo = utils.raiseTo,
  41196. getLog = utils.getLog;
  41197. core.logarithmicTranslatorFunctions = {
  41198. translate: function(bp) {
  41199. var that = this,
  41200. specialValue = that.translateSpecialCase(bp);
  41201. if (utils.isDefined(specialValue))
  41202. return specialValue;
  41203. return numericTranslator.translate.call(that, getLog(bp, that._businessRange.base))
  41204. },
  41205. untranslate: function(pos) {
  41206. var result = numericTranslator.untranslate.call(this, pos);
  41207. return result === null ? result : raiseTo(result, this._businessRange.base)
  41208. },
  41209. getInterval: numericTranslator.getInterval
  41210. }
  41211. })(jQuery, DevExpress);
  41212. /*! Module viz-core, file translator1D.js */
  41213. (function(DX, undefined) {
  41214. var _Number = Number;
  41215. function Translator1D() {
  41216. this.setDomain(arguments[0], arguments[1]).setCodomain(arguments[2], arguments[3])
  41217. }
  41218. Translator1D.prototype = {
  41219. constructor: Translator1D,
  41220. setDomain: function(domain1, domain2) {
  41221. var that = this;
  41222. that._domain1 = _Number(domain1);
  41223. that._domain2 = _Number(domain2);
  41224. that._domainDelta = that._domain2 - that._domain1;
  41225. return that
  41226. },
  41227. setCodomain: function(codomain1, codomain2) {
  41228. var that = this;
  41229. that._codomain1 = _Number(codomain1);
  41230. that._codomain2 = _Number(codomain2);
  41231. that._codomainDelta = that._codomain2 - that._codomain1;
  41232. return that
  41233. },
  41234. getDomain: function() {
  41235. return [this._domain1, this._domain2]
  41236. },
  41237. getCodomain: function() {
  41238. return [this._codomain1, this._codomain2]
  41239. },
  41240. getDomainStart: function() {
  41241. return this._domain1
  41242. },
  41243. getDomainEnd: function() {
  41244. return this._domain2
  41245. },
  41246. getCodomainStart: function() {
  41247. return this._codomain1
  41248. },
  41249. getCodomainEnd: function() {
  41250. return this._codomain2
  41251. },
  41252. getDomainRange: function() {
  41253. return this._domainDelta
  41254. },
  41255. getCodomainRange: function() {
  41256. return this._codomainDelta
  41257. },
  41258. translate: function(value) {
  41259. var ratio = (_Number(value) - this._domain1) / this._domainDelta;
  41260. return 0 <= ratio && ratio <= 1 ? this._codomain1 + ratio * this._codomainDelta : NaN
  41261. },
  41262. adjust: function(value) {
  41263. var ratio = (_Number(value) - this._domain1) / this._domainDelta,
  41264. result = NaN;
  41265. if (ratio < 0)
  41266. result = this._domain1;
  41267. else if (ratio > 1)
  41268. result = this._domain2;
  41269. else if (0 <= ratio && ratio <= 1)
  41270. result = _Number(value);
  41271. return result
  41272. }
  41273. };
  41274. DX.viz.core.Translator1D = Translator1D
  41275. })(DevExpress);
  41276. /*! Module viz-core, file translator2D.js */
  41277. (function($, DX, undefined) {
  41278. var core = DX.viz.core,
  41279. utils = DX.utils,
  41280. getLog = utils.getLog,
  41281. getPower = utils.getPower,
  41282. raiseTo = utils.raiseTo,
  41283. isDefined = utils.isDefined,
  41284. CANVAS_PROP = ["width", "height", "left", "top", "bottom", "right"],
  41285. NUMBER_EQUALITY_CORRECTION = 1,
  41286. DATETIME_EQUALITY_CORRECTION = 60000;
  41287. var validateCanvas = function(canvas) {
  41288. $.each(CANVAS_PROP, function(_, prop) {
  41289. canvas[prop] = parseInt(canvas[prop]) || 0
  41290. });
  41291. return canvas
  41292. };
  41293. var raiseToFlooredLog = function(value, base, correction) {
  41294. return raiseTo(Math.floor(getLog(value, base)) + (correction || 0), base)
  41295. };
  41296. var makeCategoriesToPoints = function(categories, invert) {
  41297. var categoriesToPoints = {},
  41298. category,
  41299. length = categories.length,
  41300. i;
  41301. for (i = 0; i < length; i++) {
  41302. category = categories[i];
  41303. categoriesToPoints[category] = {
  41304. name: category,
  41305. index: invert ? length - 1 - i : i
  41306. }
  41307. }
  41308. return categoriesToPoints
  41309. };
  41310. var validateBusinessRange = function(businessRange) {
  41311. function validate(valueSelector, baseValueSeletor) {
  41312. if (!isDefined(businessRange[valueSelector]) && isDefined(businessRange[baseValueSeletor]))
  41313. businessRange[valueSelector] = businessRange[baseValueSeletor]
  41314. }
  41315. validate("minVisible", "min");
  41316. validate("maxVisible", "max");
  41317. return businessRange
  41318. };
  41319. core.Translator2D = function(businessRange, canvas, options) {
  41320. var that = this;
  41321. that._options = $.extend(that._options || {}, options);
  41322. that._canvas = validateCanvas(canvas);
  41323. that.updateBusinessRange(businessRange)
  41324. };
  41325. $.extend(core.Translator2D.prototype, {
  41326. reinit: function() {
  41327. var that = this,
  41328. range = that._businessRange,
  41329. categories = range.categories || [],
  41330. script = {},
  41331. canvasOptions = that._prepareCanvasOptions(),
  41332. interval,
  41333. correctedCategoriesCount;
  41334. switch (range.axisType) {
  41335. case"logarithmic":
  41336. script = core.logarithmicTranslatorFunctions;
  41337. break;
  41338. case"discrete":
  41339. script = core.categoryTranslatorFunctions;
  41340. that._categories = categories;
  41341. correctedCategoriesCount = categories.length - (range.stick ? 1 : 0);
  41342. if (correctedCategoriesCount > 0)
  41343. interval = canvasOptions.canvasLength / correctedCategoriesCount;
  41344. else
  41345. interval = canvasOptions.canvasLength;
  41346. canvasOptions.interval = interval;
  41347. that._categoriesToPoints = makeCategoriesToPoints(categories, canvasOptions.invert);
  41348. break;
  41349. default:
  41350. if (range.dataType === "datetime")
  41351. script = core.datetimeTranslatorFunctions;
  41352. else
  41353. script = core.numericTranslatorFunctions
  41354. }
  41355. that.translate = script.translate;
  41356. that.untranslate = script.untranslate;
  41357. that.getInterval = script.getInterval
  41358. },
  41359. _getCanvasBounds: function(range) {
  41360. var min = range.min,
  41361. max = range.max,
  41362. minVisible = range.minVisible,
  41363. maxVisible = range.maxVisible,
  41364. newMin,
  41365. newMax,
  41366. base = range.base,
  41367. isDateTime = utils.isDate(max) || utils.isDate(min),
  41368. correction = isDateTime ? DATETIME_EQUALITY_CORRECTION : NUMBER_EQUALITY_CORRECTION;
  41369. if (isDefined(min) && isDefined(max) && min.valueOf() === max.valueOf()) {
  41370. newMin = min.valueOf() - correction;
  41371. newMax = max.valueOf() + correction;
  41372. if (isDateTime) {
  41373. min = new Date(newMin);
  41374. max = new Date(newMax)
  41375. }
  41376. else {
  41377. min = min !== 0 ? newMin : 0;
  41378. max = newMax
  41379. }
  41380. }
  41381. if (isDefined(minVisible) && isDefined(maxVisible) && minVisible.valueOf() === maxVisible.valueOf()) {
  41382. newMin = minVisible.valueOf() - correction;
  41383. newMax = maxVisible.valueOf() + correction;
  41384. if (isDateTime) {
  41385. minVisible = newMin < min.valueOf() ? min : new Date(newMin);
  41386. maxVisible = newMax > max.valueOf() ? max : new Date(newMax)
  41387. }
  41388. else {
  41389. if (minVisible !== 0)
  41390. minVisible = newMin < min ? min : newMin;
  41391. maxVisible = newMax > max ? max : newMax
  41392. }
  41393. }
  41394. if (range.axisType === 'logarithmic') {
  41395. maxVisible = getLog(maxVisible, base);
  41396. minVisible = getLog(minVisible, base);
  41397. min = getLog(min, base);
  41398. max = getLog(max, base)
  41399. }
  41400. return {
  41401. base: base,
  41402. rangeMin: min,
  41403. rangeMax: max,
  41404. rangeMinVisible: minVisible,
  41405. rangeMaxVisible: maxVisible
  41406. }
  41407. },
  41408. _prepareCanvasOptions: function() {
  41409. var that = this,
  41410. rangeMin,
  41411. rangeMax,
  41412. rangeMinVisible,
  41413. rangeMaxVisible,
  41414. businessRange = that._businessRange,
  41415. canvasOptions = that._canvasOptions = that._getCanvasBounds(businessRange),
  41416. length;
  41417. if (that._options.direction === "horizontal") {
  41418. canvasOptions.startPoint = that._canvas.left;
  41419. length = that._canvas.width;
  41420. canvasOptions.endPoint = that._canvas.width - that._canvas.right;
  41421. canvasOptions.invert = businessRange.invert
  41422. }
  41423. else {
  41424. canvasOptions.startPoint = that._canvas.top;
  41425. length = that._canvas.height;
  41426. canvasOptions.endPoint = that._canvas.height - that._canvas.bottom;
  41427. canvasOptions.invert = !businessRange.invert
  41428. }
  41429. that.canvasLength = canvasOptions.canvasLength = canvasOptions.endPoint - canvasOptions.startPoint;
  41430. canvasOptions.rangeDoubleError = Math.pow(10, getPower(canvasOptions.rangeMax - canvasOptions.rangeMin) - getPower(length) - 2);
  41431. canvasOptions.ratioOfCanvasRange = canvasOptions.canvasLength / (canvasOptions.rangeMaxVisible - canvasOptions.rangeMinVisible);
  41432. return canvasOptions
  41433. },
  41434. updateBusinessRange: function(businessRange) {
  41435. this._businessRange = validateBusinessRange(businessRange);
  41436. this.reinit()
  41437. },
  41438. getBusinessRange: function() {
  41439. return this._businessRange
  41440. },
  41441. getCanvasVisibleArea: function() {
  41442. return {
  41443. min: this._canvasOptions.startPoint,
  41444. max: this._canvasOptions.endPoint
  41445. }
  41446. },
  41447. translateSpecialCase: function(value) {
  41448. var that = this,
  41449. canvasOptions = that._canvasOptions,
  41450. startPoint = canvasOptions.startPoint,
  41451. endPoint = canvasOptions.endPoint,
  41452. range = that._businessRange,
  41453. minVisible = range.minVisible,
  41454. maxVisible = range.maxVisible,
  41455. invert,
  41456. result = null;
  41457. switch (value) {
  41458. case"canvas_position_default":
  41459. if (minVisible <= 0 && maxVisible >= 0)
  41460. result = that.translate(0);
  41461. else {
  41462. invert = range.invert ^ (minVisible <= 0 && maxVisible <= 0);
  41463. if (that._options.direction === "horizontal")
  41464. result = invert ? endPoint : startPoint;
  41465. else
  41466. result = invert ? startPoint : endPoint
  41467. }
  41468. break;
  41469. case"canvas_position_left":
  41470. case"canvas_position_top":
  41471. result = startPoint;
  41472. break;
  41473. case"canvas_position_center":
  41474. case"canvas_position_middle":
  41475. result = startPoint + canvasOptions.canvasLength / 2;
  41476. break;
  41477. case"canvas_position_right":
  41478. case"canvas_position_bottom":
  41479. result = endPoint;
  41480. break;
  41481. case"canvas_position_start":
  41482. result = range.invert ? endPoint : startPoint;
  41483. break;
  41484. case"canvas_position_end":
  41485. result = range.invert ? startPoint : endPoint;
  41486. break
  41487. }
  41488. return result
  41489. },
  41490. _calculateProjection: function(distance) {
  41491. var canvasOptions = this._canvasOptions;
  41492. return canvasOptions.invert ? canvasOptions.endPoint - distance : canvasOptions.startPoint + distance
  41493. },
  41494. _calculateUnProjection: function(distance) {
  41495. var canvasOptions = this._canvasOptions;
  41496. return canvasOptions.invert ? canvasOptions.rangeMaxVisible.valueOf() - distance : canvasOptions.rangeMinVisible.valueOf() + distance
  41497. }
  41498. })
  41499. })(jQuery, DevExpress);
  41500. /*! Module viz-core, file rectangle.js */
  41501. (function(DX, undefined) {
  41502. var isFinite = window.isFinite;
  41503. DX.viz.core.Rectangle = DX.Class.inherit({
  41504. ctor: function(options) {
  41505. var that = this;
  41506. options = options || {};
  41507. that.left = Number(options.left) || 0;
  41508. that.right = Number(options.right) || 0;
  41509. that.top = Number(options.top) || 0;
  41510. that.bottom = Number(options.bottom) || 0
  41511. },
  41512. width: function() {
  41513. return this.right - this.left
  41514. },
  41515. height: function() {
  41516. return this.bottom - this.top
  41517. },
  41518. horizontalMiddle: function() {
  41519. return (this.left + this.right) / 2
  41520. },
  41521. verticalMiddle: function() {
  41522. return (this.top + this.bottom) / 2
  41523. },
  41524. raw: function() {
  41525. var that = this;
  41526. return {
  41527. left: that.left,
  41528. top: that.top,
  41529. right: that.right,
  41530. bottom: that.bottom
  41531. }
  41532. },
  41533. clone: function() {
  41534. return new this.constructor(this.raw())
  41535. },
  41536. move: function(dx, dy) {
  41537. var result = this.clone();
  41538. if (isFinite(dx) && isFinite(dy)) {
  41539. result.left += Number(dx);
  41540. result.right += Number(dx);
  41541. result.top += Number(dy);
  41542. result.bottom += Number(dy)
  41543. }
  41544. return result
  41545. },
  41546. inflate: function(dx, dy) {
  41547. var result = this.clone();
  41548. if (isFinite(dx) && isFinite(dy)) {
  41549. result.left -= Number(dx);
  41550. result.right += Number(dx);
  41551. result.top -= Number(dy);
  41552. result.bottom += Number(dy)
  41553. }
  41554. return result
  41555. },
  41556. scale: function(factor) {
  41557. var that = this;
  41558. if (factor > 0)
  41559. return that.inflate(that.width() * (factor - 1) / 2, that.height() * (factor - 1) / 2);
  41560. return that.clone()
  41561. }
  41562. })
  41563. })(DevExpress);
  41564. /*! Module viz-core, file themes.js */
  41565. (function($, DX, undefined) {
  41566. var viz = DX.viz,
  41567. core = viz.core;
  41568. var currentThemeId = 0;
  41569. var findThemeId = function(themeName) {
  41570. var themeId,
  41571. themes = viz.themes;
  41572. for (themeId = 0; themeId < themes.length; themeId++)
  41573. if (themes[themeId].name === themeName)
  41574. return themeId;
  41575. return -1
  41576. };
  41577. core.findTheme = function(themeName) {
  41578. var themeId = findThemeId(themeName),
  41579. themes = viz.themes;
  41580. if (themeId < 0)
  41581. themeId = currentThemeId;
  41582. return themes[themeId]
  41583. };
  41584. core.currentTheme = function(themeName, colorScheme, version) {
  41585. var themeId = -1,
  41586. themes = viz.themes;
  41587. if (themeName === undefined)
  41588. return themes[currentThemeId].name;
  41589. else {
  41590. if (version && colorScheme)
  41591. themeId = findThemeId(themeName + ':' + version + '-' + colorScheme);
  41592. if (themeId < 0 && version)
  41593. themeId = findThemeId(themeName + ':' + version);
  41594. if (colorScheme && themeId < 0)
  41595. themeId = findThemeId(themeName + '-' + colorScheme);
  41596. if (themeId < 0)
  41597. themeId = findThemeId(themeName);
  41598. currentThemeId = themeId >= 0 ? themeId : 0
  41599. }
  41600. };
  41601. core.registerTheme = function(theme, basedOnThemeName) {
  41602. var baseTheme,
  41603. extendedTheme,
  41604. themes = viz.themes;
  41605. if (!theme || !theme.name || !core.findTheme(theme.name))
  41606. return;
  41607. baseTheme = core.findTheme(basedOnThemeName);
  41608. if (baseTheme) {
  41609. extendedTheme = $.extend(true, {}, baseTheme, theme);
  41610. themes.push(extendedTheme)
  41611. }
  41612. else
  41613. themes.push(theme)
  41614. }
  41615. })(jQuery, DevExpress);
  41616. /*! Module viz-core, file palette.js */
  41617. (function(DX, $, undefined) {
  41618. var _String = window.String,
  41619. _Color = DX.Color,
  41620. _isArray = DX.utils.isArray,
  41621. _isString = DX.utils.isString,
  41622. _extend = $.extend;
  41623. var palettes = {
  41624. 'default': {
  41625. simpleSet: ['#5f8b95', '#ba4d51', '#af8a53', '#955f71', '#859666', '#7e688c'],
  41626. indicatingSet: ['#a3b97c', '#e1b676', '#ec7f83'],
  41627. gradientSet: ['#5f8b95', '#ba4d51']
  41628. },
  41629. 'harmony light': {
  41630. simpleSet: ['#fcb65e', '#679ec5', '#ad79ce', '#7abd5c', '#e18e92', '#b6d623', '#b7abea', '#85dbd5'],
  41631. indicatingSet: ['#b6d623', '#fcb65e', '#e18e92'],
  41632. gradientSet: ['#7abd5c', '#fcb65e']
  41633. },
  41634. 'soft pastel': {
  41635. simpleSet: ['#60a69f', '#78b6d9', '#6682bb', '#a37182', '#eeba69', '#90ba58', '#456c68', '#7565a4'],
  41636. indicatingSet: ['#90ba58', '#eeba69', '#a37182'],
  41637. gradientSet: ['#78b6d9', '#eeba69']
  41638. },
  41639. pastel: {
  41640. simpleSet: ['#bb7862', '#70b3a1', '#bb626a', '#057d85', '#ab394b', '#dac599', '#153459', '#b1d2c6'],
  41641. indicatingSet: ['#70b3a1', '#dac599', '#bb626a'],
  41642. gradientSet: ['#bb7862', '#70b3a1']
  41643. },
  41644. bright: {
  41645. simpleSet: ['#70c92f', '#f8ca00', '#bd1550', '#e97f02', '#9d419c', '#7e4452', '#9ab57e', '#36a3a6'],
  41646. indicatingSet: ['#70c92f', '#f8ca00', '#bd1550'],
  41647. gradientSet: ['#e97f02', '#f8ca00']
  41648. },
  41649. soft: {
  41650. simpleSet: ['#cbc87b', '#9ab57e', '#e55253', '#7e4452', '#e8c267', '#565077', '#6babac', '#ad6082'],
  41651. indicatingSet: ['#9ab57e', '#e8c267', '#e55253'],
  41652. gradientSet: ['#9ab57e', '#e8c267']
  41653. },
  41654. ocean: {
  41655. simpleSet: ['#75c099', '#acc371', '#378a8a', '#5fa26a', '#064970', '#38c5d2', '#00a7c6', '#6f84bb'],
  41656. indicatingSet: ['#c8e394', '#7bc59d', '#397c8b'],
  41657. gradientSet: ['#acc371', '#38c5d2']
  41658. },
  41659. vintage: {
  41660. simpleSet: ['#dea484', '#efc59c', '#cb715e', '#eb9692', '#a85c4c', '#f2c0b5', '#c96374', '#dd956c'],
  41661. indicatingSet: ['#ffe5c6', '#f4bb9d', '#e57660'],
  41662. gradientSet: ['#efc59c', '#cb715e']
  41663. },
  41664. violet: {
  41665. simpleSet: ['#d1a1d1', '#eeacc5', '#7b5685', '#7e7cad', '#a13d73', '#5b41ab', '#e287e2', '#689cc1'],
  41666. indicatingSet: ['#d8e2f6', '#d0b2da', '#d56a8a'],
  41667. gradientSet: ['#eeacc5', '#7b5685']
  41668. }
  41669. };
  41670. var currentPaletteName = 'default';
  41671. function currentPalette(name) {
  41672. if (name === undefined)
  41673. return currentPaletteName;
  41674. else {
  41675. name = String(name).toLowerCase();
  41676. currentPaletteName = name in palettes ? name : 'default'
  41677. }
  41678. }
  41679. function getPalette(palette, parameters) {
  41680. var result;
  41681. if (_isArray(palette))
  41682. result = palette;
  41683. else {
  41684. parameters = parameters || {};
  41685. var type = parameters.type || 'simpleSet';
  41686. if (_isString(palette)) {
  41687. var name = palette.toLowerCase(),
  41688. baseContainer = palettes[name],
  41689. themedContainer = parameters.theme && palettes[name + '_' + _String(parameters.theme).toLowerCase()];
  41690. result = themedContainer && themedContainer[type] || baseContainer && baseContainer[type]
  41691. }
  41692. if (!result)
  41693. result = palettes[currentPaletteName][type]
  41694. }
  41695. return result ? result.slice(0) : null
  41696. }
  41697. function registerPalette(name, palette, theme) {
  41698. var item = {};
  41699. if (_isArray(palette))
  41700. item.simpleSet = palette.slice(0);
  41701. else if (palette) {
  41702. item.simpleSet = _isArray(palette.simpleSet) ? palette.simpleSet.slice(0) : undefined;
  41703. item.indicatingSet = _isArray(palette.indicatingSet) ? palette.indicatingSet.slice(0) : undefined;
  41704. item.gradientSet = _isArray(palette.gradientSet) ? palette.gradientSet.slice(0) : undefined
  41705. }
  41706. if (item.simpleSet || item.indicatingSet || item.gradientSet) {
  41707. var paletteName = _String(name).toLowerCase();
  41708. if (theme)
  41709. paletteName = paletteName + '_' + _String(theme).toLowerCase();
  41710. _extend(palettes[paletteName] = palettes[paletteName] || {}, item)
  41711. }
  41712. }
  41713. function RingBuf(buf) {
  41714. var ind = 0;
  41715. this.next = function() {
  41716. var res = buf[ind++];
  41717. if (ind == buf.length)
  41718. this.reset();
  41719. return res
  41720. };
  41721. this.reset = function() {
  41722. ind = 0
  41723. }
  41724. }
  41725. function Palette(palette, parameters) {
  41726. parameters = parameters || {};
  41727. this._originalPalette = getPalette(palette, parameters);
  41728. var stepHighlight = parameters ? parameters.stepHighlight || 0 : 0;
  41729. this._paletteSteps = new RingBuf([0, stepHighlight, -stepHighlight]);
  41730. this._resetPalette()
  41731. }
  41732. _extend(Palette.prototype, {
  41733. dispose: function() {
  41734. this._originalPalette = this._palette = this._paletteSteps = null;
  41735. return this
  41736. },
  41737. getNextColor: function() {
  41738. var that = this;
  41739. if (that._currentColor >= that._palette.length)
  41740. that._resetPalette();
  41741. return that._palette[that._currentColor++]
  41742. },
  41743. _resetPalette: function() {
  41744. var that = this;
  41745. that._currentColor = 0;
  41746. var step = that._paletteSteps.next(),
  41747. originalPalette = that._originalPalette;
  41748. if (step) {
  41749. var palette = that._palette = [],
  41750. i = 0,
  41751. ii = originalPalette.length;
  41752. for (; i < ii; ++i)
  41753. palette[i] = getNewColor(originalPalette[i], step)
  41754. }
  41755. else
  41756. that._palette = originalPalette.slice(0)
  41757. },
  41758. reset: function() {
  41759. this._paletteSteps.reset();
  41760. this._resetPalette();
  41761. return this
  41762. }
  41763. });
  41764. function getNewColor(currentColor, step) {
  41765. var newColor = new _Color(currentColor).alter(step),
  41766. lightness = getLightness(newColor);
  41767. if (lightness > 200 || lightness < 55)
  41768. newColor = new _Color(currentColor).alter(-step / 2);
  41769. return newColor.toHex()
  41770. }
  41771. function getLightness(color) {
  41772. return color.r * 0.3 + color.g * 0.59 + color.b * 0.11
  41773. }
  41774. function GradientPalette(source, size) {
  41775. var palette = getPalette(source, {type: 'gradientSet'});
  41776. palette = size > 0 ? createGradientColors(palette[0], palette[1], size) : [];
  41777. this.getColor = function(index) {
  41778. return palette[index] || null
  41779. };
  41780. this._DEBUG_source = source;
  41781. this._DEBUG_size = size
  41782. }
  41783. function createGradientColors(start, end, count) {
  41784. var startColor = new _Color(start),
  41785. endColor = new _Color(end);
  41786. if (count === 1)
  41787. return [startColor.blend(endColor, 0.5).toHex()];
  41788. else {
  41789. var list = [],
  41790. step = 1 / (count - 1),
  41791. i,
  41792. ii = count;
  41793. list.push(0);
  41794. for (i = 1; i < ii - 1; ++i)
  41795. list.push(step * i);
  41796. list.push(1);
  41797. for (i = 0; i < ii; ++i)
  41798. list[i] = startColor.blend(endColor, list[i]).toHex();
  41799. return list
  41800. }
  41801. }
  41802. _extend(DX.viz.core, {
  41803. registerPalette: registerPalette,
  41804. getPalette: getPalette,
  41805. Palette: Palette,
  41806. GradientPalette: GradientPalette,
  41807. currentPalette: currentPalette
  41808. });
  41809. DX.viz.core._DEBUG_palettes = palettes
  41810. })(DevExpress, jQuery);
  41811. /*! Module viz-core, file baseThemeManager.js */
  41812. (function(DX, $, undefined) {
  41813. var _isString = DX.utils.isString,
  41814. _findTheme = DX.viz.core.findTheme,
  41815. _extend = $.extend,
  41816. _each = $.each;
  41817. DX.viz.core.BaseThemeManager = DX.Class.inherit({
  41818. dispose: function() {
  41819. this._theme = this._font = null;
  41820. return this
  41821. },
  41822. setTheme: function(theme) {
  41823. theme = theme || {};
  41824. var that = this,
  41825. themeObj = _findTheme(_isString(theme) ? theme : theme.name);
  41826. that._themeName = themeObj.name;
  41827. that._font = _extend({}, themeObj.font, theme.font);
  41828. that._themeSection && _each(that._themeSection.split('.'), function(_, path) {
  41829. themeObj = _extend(true, {}, themeObj[path], that._IE8 ? themeObj[path + 'IE8'] : {})
  41830. });
  41831. that._theme = _extend(true, {}, themeObj, _isString(theme) ? {} : theme);
  41832. that._initializeTheme();
  41833. return that
  41834. },
  41835. theme: function() {
  41836. return this._theme
  41837. },
  41838. themeName: function() {
  41839. return this._themeName
  41840. },
  41841. _initializeTheme: function(){},
  41842. _initializeFont: function(font) {
  41843. _extend(font, this._font, _extend({}, font))
  41844. }
  41845. })
  41846. })(DevExpress, jQuery);
  41847. /*! Module viz-core, file textCloud.js */
  41848. (function(DX, undefined) {
  41849. var min = Math.min;
  41850. DX.viz.core.TextCloud = DX.Class.inherit(function() {
  41851. var DEFAULT_OPTIONS = {
  41852. horMargin: 8,
  41853. verMargin: 4,
  41854. tailLength: 10
  41855. };
  41856. var COEFFICIENTS_MAP = {};
  41857. COEFFICIENTS_MAP['right-bottom'] = COEFFICIENTS_MAP['rb'] = [0, -1, -1, 0, 0, 1, 1, 0];
  41858. COEFFICIENTS_MAP['bottom-right'] = COEFFICIENTS_MAP['br'] = [-1, 0, 0, -1, 1, 0, 0, 1];
  41859. COEFFICIENTS_MAP['left-bottom'] = COEFFICIENTS_MAP['lb'] = [0, -1, 1, 0, 0, 1, -1, 0];
  41860. COEFFICIENTS_MAP['bottom-left'] = COEFFICIENTS_MAP['bl'] = [1, 0, 0, -1, -1, 0, 0, 1];
  41861. COEFFICIENTS_MAP['left-top'] = COEFFICIENTS_MAP['lt'] = [0, 1, 1, 0, 0, -1, -1, 0];
  41862. COEFFICIENTS_MAP['top-left'] = COEFFICIENTS_MAP['tl'] = [1, 0, 0, 1, -1, 0, 0, -1];
  41863. COEFFICIENTS_MAP['right-top'] = COEFFICIENTS_MAP['rt'] = [0, 1, -1, 0, 0, -1, 1, 0];
  41864. COEFFICIENTS_MAP['top-right'] = COEFFICIENTS_MAP['tr'] = [-1, 0, 0, 1, 1, 0, 0, -1];
  41865. return {
  41866. setup: function(options) {
  41867. var that = this,
  41868. ops = $.extend({}, DEFAULT_OPTIONS, options),
  41869. x = ops.x,
  41870. y = ops.y,
  41871. type = COEFFICIENTS_MAP[ops.type],
  41872. cloudWidth = ops.textWidth + 2 * ops.horMargin,
  41873. cloudHeight = ops.textHeight + 2 * ops.verMargin,
  41874. tailWidth = ops.tailLength,
  41875. tailHeight = tailWidth,
  41876. cx = x,
  41877. cy = y;
  41878. if (type[0] & 1)
  41879. tailHeight = min(tailHeight, cloudHeight / 3);
  41880. else
  41881. tailWidth = min(tailWidth, cloudWidth / 3);
  41882. that._points = [x, y, x += type[0] * (cloudWidth + tailWidth), y += type[1] * (cloudHeight + tailHeight), x += type[2] * cloudWidth, y += type[3] * cloudHeight, x += type[4] * cloudWidth, y += type[5] * cloudHeight, x += type[6] * (cloudWidth - tailWidth), y += type[7] * (cloudHeight - tailHeight)];
  41883. that._cx = cx + type[0] * tailWidth + (type[0] + type[2]) * cloudWidth / 2;
  41884. that._cy = cy + type[1] * tailHeight + (type[1] + type[3]) * cloudHeight / 2;
  41885. that._cloudWidth = cloudWidth;
  41886. that._cloudHeight = cloudHeight;
  41887. that._tailLength = ops.tailLength;
  41888. return that
  41889. },
  41890. points: function() {
  41891. return this._points.slice(0)
  41892. },
  41893. cx: function() {
  41894. return this._cx
  41895. },
  41896. cy: function() {
  41897. return this._cy
  41898. },
  41899. width: function() {
  41900. return this._cloudWidth
  41901. },
  41902. height: function() {
  41903. return this._cloudHeight
  41904. },
  41905. tailLength: function() {
  41906. return this._tailLength
  41907. }
  41908. }
  41909. }())
  41910. })(DevExpress);
  41911. /*! Module viz-core, file parseUtils.js */
  41912. (function($, DX) {
  41913. var viz = DX.viz,
  41914. core = viz.core,
  41915. Class = DX.Class,
  41916. isDefined = DX.utils.isDefined;
  41917. var parseUtils = Class.inherit({
  41918. ctor: function(options) {
  41919. options = options || {};
  41920. this._incidentOccured = $.isFunction(options.incidentOccured) ? options.incidentOccured : $.noop
  41921. },
  41922. correctValueType: function(type) {
  41923. return type === 'numeric' || type === 'datetime' || type === 'string' ? type : ''
  41924. },
  41925. _parsers: {
  41926. string: function(val) {
  41927. return isDefined(val) ? '' + val : val
  41928. },
  41929. numeric: function(val) {
  41930. if (!isDefined(val))
  41931. return val;
  41932. var parsedVal = Number(val);
  41933. if (isNaN(parsedVal))
  41934. parsedVal = undefined;
  41935. return parsedVal
  41936. },
  41937. datetime: function(val) {
  41938. if (!isDefined(val))
  41939. return val;
  41940. var parsedVal,
  41941. numVal = Number(val);
  41942. if (!isNaN(numVal))
  41943. parsedVal = new Date(numVal);
  41944. else
  41945. parsedVal = new Date(val);
  41946. if (isNaN(Number(parsedVal)))
  41947. parsedVal = undefined;
  41948. return parsedVal
  41949. }
  41950. },
  41951. getParser: function(valueType, entity) {
  41952. var that = this,
  41953. parser,
  41954. message = 'valueType is unknown.';
  41955. if (entity)
  41956. message = 'The type specified as the "valueType" field of the ' + entity + ' configuration object is unknown.';
  41957. valueType = that.correctValueType(valueType);
  41958. parser = that._parsers[valueType];
  41959. if (!parser)
  41960. this._incidentOccured.call(null, message);
  41961. return parser || $.noop
  41962. }
  41963. });
  41964. core.ParseUtils = parseUtils
  41965. })(jQuery, DevExpress);
  41966. /*! Module viz-core, file utils.js */
  41967. (function($, DX) {
  41968. var core = DX.viz.core,
  41969. math = Math;
  41970. core.utils = {decreaseGaps: function(object, keys, decrease) {
  41971. var arrayGaps,
  41972. eachDecrease,
  41973. middleValue;
  41974. do {
  41975. arrayGaps = $.map(keys, function(key) {
  41976. return object[key] ? object[key] : null
  41977. });
  41978. middleValue = math.ceil(decrease / arrayGaps.length);
  41979. arrayGaps.push(middleValue);
  41980. eachDecrease = math.min.apply(null, arrayGaps);
  41981. $.each(keys, function(_, key) {
  41982. if (object[key]) {
  41983. object[key] -= eachDecrease;
  41984. decrease -= eachDecrease
  41985. }
  41986. })
  41987. } while (decrease > 0 && arrayGaps.length > 1);
  41988. return decrease
  41989. }}
  41990. })(jQuery, DevExpress);
  41991. /*! Module viz-core, file loadIndicator.js */
  41992. (function($, DX) {
  41993. var viz = DX.viz,
  41994. core = viz.core,
  41995. ANIMATION_SETTINGS = {
  41996. easing: 'linear',
  41997. duration: 150
  41998. },
  41999. INVISIBLE_POINT = {
  42000. x: -10000,
  42001. y: -10000
  42002. };
  42003. var applySettings = function(element, settings, animate, complete) {
  42004. var prevAnimation = element.animation;
  42005. if (prevAnimation) {
  42006. prevAnimation.options.complete = null;
  42007. prevAnimation.stop()
  42008. }
  42009. if (animate)
  42010. element.animate(settings, {complete: complete});
  42011. else {
  42012. element.applySettings(settings);
  42013. complete && complete()
  42014. }
  42015. };
  42016. core.LoadIndicator = DX.Class.inherit({
  42017. ctor: function(options, widgetContainer) {
  42018. var that = this;
  42019. that._$widgetContainer = $(widgetContainer);
  42020. that._$container = $('<div>', {css: {
  42021. position: 'relative',
  42022. height: 0,
  42023. padding: 0,
  42024. margin: 0,
  42025. border: 0
  42026. }}).appendTo(that._$widgetContainer);
  42027. that._updateContainer();
  42028. that.applyOptions(options);
  42029. that._endLoadingCompleteHandler = function() {
  42030. that._endLoad = false;
  42031. that._externalComplete && that._externalComplete();
  42032. that._externalComplete = null;
  42033. that._onCompleteAction && that[that._onCompleteAction]();
  42034. that._onCompleteAction = null
  42035. };
  42036. that._$container.hide()
  42037. },
  42038. _updateRenderer: function(width, height, top) {
  42039. if (this._renderer)
  42040. this._renderer.recreateCanvas(width, height);
  42041. else if (this._$container.get(0)) {
  42042. this._renderer = new viz.renderers.Renderer({
  42043. width: width,
  42044. height: height,
  42045. animation: ANIMATION_SETTINGS
  42046. });
  42047. this._renderer.draw(this._$container[0])
  42048. }
  42049. this._renderer && this._renderer.getRoot().applySettings({style: {
  42050. position: 'absolute',
  42051. top: top,
  42052. left: 0
  42053. }});
  42054. return this._renderer
  42055. },
  42056. applyOptions: function(options, width, height) {
  42057. var pane = this._pane;
  42058. if (pane && options) {
  42059. pane.rect.applySettings({fill: options.backgroundColor});
  42060. pane.text.applySettings({
  42061. font: options.font,
  42062. text: options.text
  42063. })
  42064. }
  42065. if (this.isShown && (width || height))
  42066. this._updateContainer(width, height)
  42067. },
  42068. _draw: function() {
  42069. var pane,
  42070. renderer = this._renderer;
  42071. if (renderer) {
  42072. pane = this._pane = {};
  42073. pane.rect = renderer.createRect(0, 0, 0, 0, 0, {opacity: 0}).append();
  42074. pane.text = renderer.createText('', 0, 0, {
  42075. align: 'center',
  42076. translateX: INVISIBLE_POINT.x,
  42077. translateY: INVISIBLE_POINT.y
  42078. }).append()
  42079. }
  42080. },
  42081. _updateContainer: function(width, height) {
  42082. var that = this,
  42083. $widgetContainer = that._$widgetContainer,
  42084. canvasTop;
  42085. width = width || $widgetContainer.width();
  42086. height = height || $widgetContainer.height();
  42087. if ($widgetContainer.get(0))
  42088. canvasTop = $widgetContainer.offset().top - that._$container.offset().top;
  42089. else
  42090. canvasTop = -height;
  42091. that._updateRenderer(width, height, canvasTop);
  42092. if (!that._pane)
  42093. that._draw();
  42094. else {
  42095. that._pane.rect.applySettings({
  42096. width: width,
  42097. height: height
  42098. });
  42099. that._pane.text.move(width / 2, height / 2)
  42100. }
  42101. },
  42102. dispose: function() {
  42103. this._$widgetContainer = null;
  42104. this._$container.remove().detach();
  42105. this._$container = null;
  42106. this._renderer.dispose();
  42107. this._renderer = null;
  42108. this._pane = null
  42109. },
  42110. toForeground: function() {
  42111. this._$container.appendTo(this._$widgetContainer)
  42112. },
  42113. show: function(width, height) {
  42114. if (this._endLoad) {
  42115. this._onCompleteAction = 'show';
  42116. return
  42117. }
  42118. this._$container.show();
  42119. this._updateContainer(width, height);
  42120. applySettings(this._pane.rect, {opacity: 0.85}, true);
  42121. this.isShown = true
  42122. },
  42123. endLoading: function(complete, disableAnimation) {
  42124. this._externalComplete = complete;
  42125. if (this._endLoad)
  42126. return;
  42127. if (this.isShown) {
  42128. this._endLoad = true;
  42129. applySettings(this._pane.rect, {opacity: 1}, !disableAnimation, this._endLoadingCompleteHandler)
  42130. }
  42131. else
  42132. complete && complete()
  42133. },
  42134. hide: function() {
  42135. var that = this;
  42136. if (this._endLoad) {
  42137. this._onCompleteAction = 'hide';
  42138. return
  42139. }
  42140. if (this.isShown) {
  42141. this._pane.text.move(INVISIBLE_POINT.x, INVISIBLE_POINT.y);
  42142. applySettings(that._pane.rect, {opacity: 0}, true, function() {
  42143. that._$container.hide()
  42144. });
  42145. this.isShown = false
  42146. }
  42147. }
  42148. })
  42149. })(jQuery, DevExpress);
  42150. /*! Module viz-core, file tooltip.js */
  42151. (function($, DX, undefined) {
  42152. var ARROW_WIDTH = 20,
  42153. MAX_SHADOW_SIZE = 10,
  42154. formatHelper = DX.formatHelper,
  42155. X_INTERVAL = 15,
  42156. _max = Math.max,
  42157. _round = Math.round,
  42158. _isFunction = DX.utils.isFunction,
  42159. _isDefined = DX.utils.isDefined,
  42160. _extend = $.extend,
  42161. FORMAT_PRECISION = {
  42162. argument: ['argumentFormat', 'argumentPrecision'],
  42163. percent: ['percent', 'percentPrecision'],
  42164. value: ['format', 'precision']
  42165. },
  42166. VISIBLE = {visibility: 'visible'},
  42167. HIDDEN = {visibility: 'hidden'},
  42168. LEFT = 'left',
  42169. RIGHT = 'right';
  42170. DX.viz.core.Tooltip = DX.Class.inherit({
  42171. ctor: function(options, group, renderer) {
  42172. this._state = {};
  42173. this._options = {};
  42174. this._renderer = renderer;
  42175. this._group = group;
  42176. this._cloud = renderer.createArea();
  42177. this._textGroup = renderer.createGroup();
  42178. if (!$.isEmptyObject(options))
  42179. this.update(options);
  42180. this._createTextContent()
  42181. },
  42182. dispose: function() {
  42183. this._shadow.dispose();
  42184. this._shadow = null;
  42185. this._cloud = null;
  42186. this._text = null;
  42187. this._group = null;
  42188. this._options = null;
  42189. this._renderer = null;
  42190. this._tooltipTextArray = null;
  42191. this._textGroup = null;
  42192. return this
  42193. },
  42194. update: function(options) {
  42195. options = options || {};
  42196. var that = this,
  42197. group = that._group,
  42198. shadowOptions = options.shadow || {},
  42199. shadow = that._shadow = that._shadow || that._renderer.createFilter('shadow').applySettings({
  42200. width: '200%',
  42201. height: '200%',
  42202. color: shadowOptions.color,
  42203. opacity: shadowOptions.opacity,
  42204. dx: shadowOptions.offsetX,
  42205. dy: shadowOptions.offsetY,
  42206. blur: shadowOptions.blur,
  42207. x: '-50%',
  42208. y: '-50%'
  42209. }),
  42210. borderSettings = options.border,
  42211. shapeSettings = _extend({
  42212. opacity: options.opacity,
  42213. filter: shadow.append().ref
  42214. }, borderSettings && borderSettings.visible ? {
  42215. strokeWidth: borderSettings.width,
  42216. stroke: borderSettings.color,
  42217. strokeOpacity: borderSettings.opacity,
  42218. dashStyle: borderSettings.dashStyle
  42219. } : {
  42220. strokeWidth: null,
  42221. stroke: null
  42222. }),
  42223. textSettings = _extend({}, {
  42224. align: 'center',
  42225. font: options.font
  42226. }, options.text);
  42227. that._options = options;
  42228. that.setSize(options.canvasWidth, options.canvasHeight);
  42229. that._customizeTooltip = _isFunction(options.customizeTooltip) ? options.customizeTooltip : null;
  42230. if (!that._customizeTooltip && _isFunction(options.customizeText))
  42231. that._customizeTooltip = function() {
  42232. return {text: options.customizeText.apply(this, arguments)}
  42233. };
  42234. that._cloud.applySettings(shapeSettings).append(group);
  42235. that._text && options.font && that._text.applySettings({font: {size: options.font.size}});
  42236. that._textGroup.applySettings(textSettings).append(group);
  42237. that.hide();
  42238. return that
  42239. },
  42240. formatValue: function(value, specialFormat) {
  42241. var formatObj = FORMAT_PRECISION[specialFormat || 'value'],
  42242. format = formatObj[0] in this._options ? this._options[formatObj[0]] : specialFormat;
  42243. return formatHelper.format(value, format, this._options[formatObj[1]] || 0)
  42244. },
  42245. prepare: function(formatObject, params, defaultTextValueField) {
  42246. this._state = this._state || {};
  42247. defaultTextValueField = defaultTextValueField || 'valueText';
  42248. var defaultText = formatObject[defaultTextValueField] || '';
  42249. _extend(this._state, params);
  42250. if (this._customizeTooltip) {
  42251. var customize = this._customizeTooltip.call(formatObject, formatObject);
  42252. customize = $.isPlainObject(customize) ? customize : {};
  42253. if ('text' in customize)
  42254. this._state.text = _isDefined(customize.text) ? String(customize.text) : '';
  42255. else {
  42256. if ($.isArray(defaultText)) {
  42257. this._options._justify = true;
  42258. this._createTextContent();
  42259. defaultText = defaultText.join('<br/>')
  42260. }
  42261. this._state.text = defaultText
  42262. }
  42263. this._state.color = customize.color || this._options.color
  42264. }
  42265. else {
  42266. this._state.text = defaultText;
  42267. this._state.color = this._options.color
  42268. }
  42269. if (this._options._justify)
  42270. this._state.text = this._state.text.split('<br/>');
  42271. if (this._state.visibility == VISIBLE && !!this._state.text)
  42272. this.show();
  42273. return !!this._state.text
  42274. },
  42275. enabled: function() {
  42276. return !!this._options.enabled
  42277. },
  42278. formatColorTooltip: function(that) {
  42279. return that._customizeTooltip && that._customizeTooltip.call(this, this)
  42280. },
  42281. _getData: function() {
  42282. var that = this,
  42283. x = that._state.x,
  42284. y = that._state.y,
  42285. xt = x,
  42286. yt = y,
  42287. align = 'center',
  42288. points = [],
  42289. bbox = that._state.textBBox,
  42290. options = that._options,
  42291. paddingLeftRight = options.paddingLeftRight,
  42292. paddingTopBottom = options.paddingTopBottom,
  42293. arrowLength = options.arrowLength > 0 ? options.arrowLength : 0,
  42294. horPosition = options.cloudHorizontalPosition,
  42295. verPosition = options.cloudVerticalPosition,
  42296. isHorPositionDefined = horPosition !== undefined && horPosition !== null,
  42297. isVerPositionDefined = verPosition !== undefined && verPosition !== null,
  42298. cloudWidth = bbox.width + paddingLeftRight * 2,
  42299. cloudHeight = bbox.height + paddingTopBottom * 2,
  42300. updatedText;
  42301. updatedText = that._checkWidthText(cloudWidth, cloudHeight);
  42302. if (updatedText) {
  42303. that._state.textBBox = bbox = updatedText.bbox;
  42304. cloudWidth = updatedText.cloudWidth;
  42305. cloudHeight = updatedText.cloudHeight;
  42306. paddingLeftRight = updatedText.paddingLeftRight;
  42307. paddingTopBottom = updatedText.paddingTopBottom
  42308. }
  42309. if (isHorPositionDefined ? horPosition === RIGHT : cloudWidth / 2 > x) {
  42310. points = that._setArrowLeft(cloudWidth, cloudHeight, arrowLength, x, y);
  42311. align = LEFT;
  42312. xt += paddingLeftRight
  42313. }
  42314. else if (isHorPositionDefined ? horPosition === LEFT : x + cloudWidth / 2 > that._canvasWidth) {
  42315. points = that._setArrowRight(cloudWidth, cloudHeight, arrowLength, x, y);
  42316. align = RIGHT;
  42317. xt -= paddingLeftRight
  42318. }
  42319. else
  42320. points = that._setArrowCenter(cloudWidth, cloudHeight, arrowLength, x, y);
  42321. if (isVerPositionDefined ? verPosition === 'top' : cloudHeight + arrowLength < y) {
  42322. yt -= arrowLength + cloudHeight / 2 - bbox.height / 2 + that._state.offset;
  42323. that.tooltipInverted = false
  42324. }
  42325. else {
  42326. yt += arrowLength + cloudHeight / 2 + bbox.height / 2 + that._state.offset;
  42327. that.tooltipInverted = true
  42328. }
  42329. yt = that._correctYTextContent(yt);
  42330. return {
  42331. points: points,
  42332. text: {
  42333. x: xt,
  42334. y: yt,
  42335. align: align
  42336. }
  42337. }
  42338. },
  42339. _updateTextContent: function() {
  42340. if (this._options._justify) {
  42341. this._textGroup.clear();
  42342. this._calculateTextContent();
  42343. this._locateTextContent(0, 0, 'center')
  42344. }
  42345. else
  42346. this._text.updateText(this._state.text);
  42347. this._state.textBBox = this._textGroup.getBBox()
  42348. },
  42349. _correctYTextContent: function(y) {
  42350. var bbox;
  42351. if (this._options._justify) {
  42352. this._locateTextContent(0, y, 'center');
  42353. bbox = this._textGroup.getBBox()
  42354. }
  42355. else {
  42356. this._text.applySettings({y: y});
  42357. bbox = this._text.getBBox()
  42358. }
  42359. return y - (bbox.y + bbox.height - y)
  42360. },
  42361. _adjustTextContent: function(data) {
  42362. if (this._options._justify)
  42363. this._locateTextContent(data.text.x, data.text.y, data.text.align);
  42364. else
  42365. this._text.applySettings({
  42366. x: data.text.x,
  42367. y: data.text.y,
  42368. align: data.text.align
  42369. })
  42370. },
  42371. _updateTooltip: function() {
  42372. var that = this,
  42373. box,
  42374. data,
  42375. scale;
  42376. data = that._getData();
  42377. that._cloud.applySettings({
  42378. points: data.points,
  42379. fill: that._state.color,
  42380. 'class': that._state.className
  42381. });
  42382. that._adjustTextContent(data);
  42383. box = that._group.getBBox();
  42384. if (box.y + box.height > that._canvasHeight) {
  42385. scale = (that._canvasHeight - box.y) / box.height;
  42386. that._group.applySettings({
  42387. scale: scale,
  42388. translateX: that._state.x * (1 - scale),
  42389. translateY: that._state.y * (1 - scale)
  42390. })
  42391. }
  42392. else
  42393. that._group.applySettings({
  42394. scale: 1,
  42395. translateX: 0,
  42396. translateY: 0
  42397. })
  42398. },
  42399. _createTextContent: function() {
  42400. var that = this,
  42401. options = that._options,
  42402. fontSize;
  42403. that._textGroup.clear();
  42404. that._text = null;
  42405. if (!options._justify) {
  42406. fontSize = options.font && options.font.size;
  42407. that._text = that._renderer.createText(undefined, 0, 0, {font: {size: fontSize}}).append(that._textGroup)
  42408. }
  42409. },
  42410. _getTextContentParams: function() {
  42411. var that = this,
  42412. i,
  42413. text,
  42414. textBBox,
  42415. textArray = that._state.text,
  42416. textArrayLength = textArray.length,
  42417. textParams = {
  42418. width: [],
  42419. height: []
  42420. };
  42421. that._tooltipTextArray = [];
  42422. for (i = 0; i < textArrayLength; i++) {
  42423. text = that._renderer.createText(textArray[i], 0, 0, {}).append(this._textGroup);
  42424. that._tooltipTextArray.push(text);
  42425. textBBox = text.getBBox();
  42426. textParams.width.push(textBBox.width)
  42427. }
  42428. that._lineHeight = -2 * textBBox.y - textBBox.height;
  42429. return textParams
  42430. },
  42431. _locateTextContent: function(x, y, alignment) {
  42432. var that = this,
  42433. tooltipTextArray = that._tooltipTextArray,
  42434. textWidth = that._textContentWidth,
  42435. lineSpacing = that._options.lineSpacing,
  42436. yDelta = (lineSpacing > 0 ? lineSpacing : 0) + that._lineHeight,
  42437. leftXCoord,
  42438. rightXCoord,
  42439. i,
  42440. rtl = that._options._rtl;
  42441. if (alignment === LEFT)
  42442. leftXCoord = x;
  42443. else if (alignment === RIGHT)
  42444. leftXCoord = x - textWidth;
  42445. else
  42446. leftXCoord = _round(x - textWidth / 2);
  42447. rightXCoord = leftXCoord + textWidth;
  42448. for (i = tooltipTextArray.length - 1; i >= 0; i -= 2) {
  42449. tooltipTextArray[i].applySettings({
  42450. x: !rtl ? rightXCoord : leftXCoord,
  42451. y: y,
  42452. align: !rtl ? RIGHT : LEFT
  42453. });
  42454. if (tooltipTextArray[i - 1])
  42455. tooltipTextArray[i - 1].applySettings({
  42456. x: !rtl ? leftXCoord : rightXCoord,
  42457. y: y,
  42458. align: !rtl ? LEFT : RIGHT
  42459. });
  42460. y -= yDelta
  42461. }
  42462. },
  42463. _calculateTextContent: function() {
  42464. var that = this,
  42465. textArray = that._state.text,
  42466. textArrayLength = textArray.length,
  42467. textParams,
  42468. width,
  42469. stringWidthArray = [],
  42470. i;
  42471. textParams = that._getTextContentParams();
  42472. for (i = 0; i < textArrayLength; i += 2) {
  42473. if (textParams.width[i + 1])
  42474. width = textParams.width[i] + X_INTERVAL + textParams.width[i + 1];
  42475. else
  42476. width = textParams.width[i];
  42477. stringWidthArray.push(width)
  42478. }
  42479. that._textContentWidth = _max.apply(null, stringWidthArray)
  42480. },
  42481. setSize: function(width, height) {
  42482. this._canvasWidth = _isDefined(width) ? width : this._canvasWidth;
  42483. this._canvasHeight = _isDefined(height) ? height : this._canvasHeight;
  42484. return this
  42485. },
  42486. getBBox: function() {
  42487. var that = this,
  42488. options = that._options,
  42489. paddingLeftRight = options.paddingLeftRight || 0,
  42490. paddingTopBottom = options.paddingTopBottom || 0,
  42491. borderWidth = options.border.visible && options.border.width || 0,
  42492. tooltipBBox = that._textGroup.getBBox();
  42493. return tooltipBBox.isEmpty ? tooltipBBox : {
  42494. x: tooltipBBox.x - paddingLeftRight - borderWidth / 2 - MAX_SHADOW_SIZE,
  42495. y: tooltipBBox.y - paddingTopBottom - borderWidth / 2 - MAX_SHADOW_SIZE,
  42496. height: tooltipBBox.height + 2 * paddingTopBottom + borderWidth + MAX_SHADOW_SIZE * 2,
  42497. width: tooltipBBox.width + 2 * paddingLeftRight + borderWidth + MAX_SHADOW_SIZE * 2,
  42498. isEmpty: false
  42499. }
  42500. },
  42501. show: function() {
  42502. this._state.visibility = VISIBLE;
  42503. this._updateTextContent();
  42504. this.move(this._state.x, this._state.y, this._state.offset);
  42505. this._cloud.applySettings(VISIBLE);
  42506. this._textGroup.applySettings(VISIBLE);
  42507. return this
  42508. },
  42509. hide: function() {
  42510. this._state.visibility = HIDDEN;
  42511. this._cloud.applySettings(HIDDEN);
  42512. this._textGroup.applySettings(HIDDEN);
  42513. return this
  42514. },
  42515. move: function(x, y, offset) {
  42516. this._state.x = _isDefined(x) ? x : this._state.x || 0;
  42517. this._state.y = _isDefined(y) ? y : this._state.y || 0;
  42518. this._state.offset = _isDefined(offset) ? offset : this._state.offset || 0;
  42519. this._updateTooltip();
  42520. return this
  42521. },
  42522. _setArrowCenter: function(cloudWidth, cloudHeight, arrowLength, x, y) {
  42523. var that = this,
  42524. position = that._options.cloudVerticalPosition,
  42525. isPosDefined = position !== undefined && position !== null,
  42526. verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
  42527. x0 = x,
  42528. y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
  42529. x1 = x0 + ARROW_WIDTH / 2,
  42530. y1 = verticalInvert ? y0 + arrowLength : y0 - arrowLength,
  42531. x2 = x1 + cloudWidth / 2 - ARROW_WIDTH / 2,
  42532. y2 = y1,
  42533. x3 = x2,
  42534. y3 = verticalInvert ? y2 + cloudHeight : y2 - cloudHeight,
  42535. x4 = x3 - cloudWidth,
  42536. y4 = y3,
  42537. x5 = x4,
  42538. y5 = verticalInvert ? y4 - cloudHeight : y4 + cloudHeight,
  42539. x6 = x5 + cloudWidth / 2 - ARROW_WIDTH / 2,
  42540. y6 = y5;
  42541. return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6]
  42542. },
  42543. _setArrowLeft: function(cloudWidth, cloudHeight, arrowLength, x, y) {
  42544. var that = this,
  42545. position = that._options.cloudVerticalPosition,
  42546. isPosDefined = position !== undefined && position !== null,
  42547. verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
  42548. x0 = x,
  42549. y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
  42550. x1 = x0 + ARROW_WIDTH,
  42551. y1 = verticalInvert ? y0 + arrowLength : y0 - arrowLength,
  42552. x2 = x1 + cloudWidth - ARROW_WIDTH,
  42553. y2 = y1,
  42554. x3 = x2,
  42555. y3 = verticalInvert ? y2 + cloudHeight : y2 - cloudHeight,
  42556. x4 = x3 - cloudWidth,
  42557. y4 = y3,
  42558. x5 = x4,
  42559. y5 = verticalInvert ? y4 - cloudHeight - arrowLength : y4 + cloudHeight + arrowLength;
  42560. return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5]
  42561. },
  42562. _setArrowRight: function(cloudWidth, cloudHeight, arrowLength, x, y) {
  42563. var that = this,
  42564. position = that._options.cloudVerticalPosition,
  42565. isPosDefined = position !== undefined && position !== null,
  42566. verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
  42567. x0 = x,
  42568. y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
  42569. x1 = x0,
  42570. y1 = verticalInvert ? y0 + arrowLength + cloudHeight : y0 - arrowLength - cloudHeight,
  42571. x2 = x1 - cloudWidth,
  42572. y2 = y1,
  42573. x3 = x2,
  42574. y3 = verticalInvert ? y2 - cloudHeight : y2 + cloudHeight,
  42575. x4 = x3 + cloudWidth - ARROW_WIDTH,
  42576. y4 = y3,
  42577. x5 = x4 + ARROW_WIDTH,
  42578. y5 = verticalInvert ? y4 - arrowLength : y4 + arrowLength;
  42579. return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5]
  42580. },
  42581. _checkWidthText: function(cloudWidth, cloudHeight) {
  42582. if (this._options._justify)
  42583. return;
  42584. var x = this._state.x,
  42585. text = this._state.text,
  42586. index,
  42587. paddingLeftRight = this._options.paddingLeftRight,
  42588. paddingTopBottom = this._options.paddingTopBottom,
  42589. textLength,
  42590. maxTooltipWidth,
  42591. remainLength,
  42592. newIndex,
  42593. bbox = this._state.textBBox;
  42594. if (cloudWidth < x || x + cloudWidth < this._canvasWidth || cloudWidth / 2 < x && x + cloudWidth / 2 < this._canvasWidth)
  42595. return false;
  42596. if (text.indexOf("<br/>") === -1 && text.indexOf(" ") !== -1) {
  42597. maxTooltipWidth = _max(x, this._canvasWidth - x, 2 * Math.min(x, this._canvasWidth - x));
  42598. textLength = text.length * maxTooltipWidth / bbox.width;
  42599. index = text.substr(0, ~~textLength).lastIndexOf(" ");
  42600. if (index === -1)
  42601. index = text.substr(0).indexOf(" ");
  42602. remainLength = text.substr(index + 1).length;
  42603. this._state.text = text.substr(0, index) + "<br/>";
  42604. while (textLength <= remainLength) {
  42605. newIndex = text.substr(index + 1, ~~textLength).lastIndexOf(" ");
  42606. if (newIndex === -1)
  42607. newIndex = text.substr(index + 1).indexOf(" ");
  42608. if (newIndex !== -1) {
  42609. this._state.text += text.substr(index + 1, newIndex) + "<br/>";
  42610. remainLength = text.substr(index + 1 + newIndex).length;
  42611. index += newIndex + 1
  42612. }
  42613. else
  42614. break
  42615. }
  42616. this._state.text += text.substr(index + 1);
  42617. this._text.updateText(this._state.text);
  42618. bbox = this._text.getBBox();
  42619. cloudWidth = bbox.width + paddingLeftRight * 2;
  42620. cloudHeight = bbox.height + paddingTopBottom * 2
  42621. }
  42622. if (cloudWidth > x && x + cloudWidth > this._canvasWidth && (cloudWidth / 2 > x || x + cloudWidth / 2 > this._canvasWidth)) {
  42623. paddingLeftRight = 5;
  42624. paddingTopBottom = 5;
  42625. cloudWidth = bbox.width + 2 * paddingLeftRight;
  42626. cloudHeight = bbox.height + 2 * paddingTopBottom
  42627. }
  42628. return {
  42629. bbox: bbox,
  42630. cloudWidth: cloudWidth,
  42631. cloudHeight: cloudHeight,
  42632. paddingTopBottom: paddingTopBottom,
  42633. paddingLeftRight: paddingLeftRight
  42634. }
  42635. }
  42636. })
  42637. })(jQuery, DevExpress);
  42638. /*! Module viz-core, file legend.js */
  42639. (function(DX, $, undefined) {
  42640. var DEFAULT_MARGIN = 10,
  42641. _math = Math,
  42642. _round = _math.round,
  42643. _ceil = _math.ceil,
  42644. _floor = _math.floor,
  42645. CENTER = 'center',
  42646. RIGHT = 'right',
  42647. LEFT = 'left',
  42648. TOP = 'top',
  42649. BOTTOM = 'bottom',
  42650. HORIZONTAL = 'horizontal',
  42651. VERTICAL = 'vertical',
  42652. INSIDE = 'inside',
  42653. OUTSIDE = 'outside',
  42654. NONE = 'none',
  42655. decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
  42656. DEFAULT_MARKER_HATCHING_WIDTH = 2,
  42657. DEFAULT_MARKER_HATCHING_STEP = 5;
  42658. function getPatternId(renderer, states, action, color) {
  42659. if (!states)
  42660. return;
  42661. var direction = states[action].hatching.direction,
  42662. hatching,
  42663. colorFromAction = states[action].fill;
  42664. color = colorFromAction === NONE ? color : colorFromAction;
  42665. direction = !direction || direction === NONE ? RIGHT : direction;
  42666. hatching = $.extend({}, states[action].hatching, {
  42667. direction: direction,
  42668. step: DEFAULT_MARKER_HATCHING_STEP,
  42669. width: DEFAULT_MARKER_HATCHING_WIDTH
  42670. });
  42671. return renderer.createPattern(color, hatching).append().id
  42672. }
  42673. function getMaxBBox(groups) {
  42674. var maxWidth = 0,
  42675. maxHeight = 0,
  42676. bbox;
  42677. $.each(groups, function(_, group) {
  42678. bbox = group.getBBox();
  42679. if (bbox.width > maxWidth)
  42680. maxWidth = bbox.width;
  42681. if (bbox.height > maxHeight)
  42682. maxHeight = bbox.height
  42683. });
  42684. return {
  42685. width: maxWidth,
  42686. height: maxHeight
  42687. }
  42688. }
  42689. DX.viz.core.Legend = DX.Class.inherit({
  42690. ctor: function(data, options, renderer, group) {
  42691. var that = this;
  42692. that._renderer = renderer;
  42693. that._legendGroup = group;
  42694. that._markersPatternsIds = [];
  42695. that._data = data;
  42696. that._init(options)
  42697. },
  42698. _init: function(options) {
  42699. if (!options)
  42700. return;
  42701. var debug = DX.utils.debug;
  42702. debug.assertParam(options.visible, 'Visibility was not passed');
  42703. debug.assertParam(options.markerSize, 'markerSize was not passed');
  42704. debug.assertParam(options.font.color, 'fontColor was not passed');
  42705. debug.assertParam(options.font.family, 'fontFamily was not passed');
  42706. debug.assertParam(options.font.size, 'fontSize was not passed');
  42707. debug.assertParam(options.paddingLeftRight, 'paddingLeftRight was not passed');
  42708. debug.assertParam(options.paddingTopBottom, 'paddingTopBottom was not passed');
  42709. debug.assertParam(options.columnItemSpacing, 'columnItemSpacing was not passed');
  42710. debug.assertParam(options.rowItemSpacing, 'rowItemSpacing was not passed');
  42711. debug.assertParam(options.equalColumnWidth, 'equalColumnWidth was not passed');
  42712. var that = this,
  42713. i;
  42714. that._parseMargins(options);
  42715. that._parseAlignments(options);
  42716. options.orientation = (options.orientation || '').toLowerCase();
  42717. if (options.orientation !== VERTICAL && options.orientation !== HORIZONTAL) {
  42718. if (options.horizontalAlignment === CENTER)
  42719. options.orientation = HORIZONTAL;
  42720. if (options.horizontalAlignment === RIGHT || options.horizontalAlignment === LEFT)
  42721. options.orientation = VERTICAL
  42722. }
  42723. if (!options.itemTextPosition)
  42724. options.itemTextPosition = options.orientation === HORIZONTAL ? BOTTOM : RIGHT;
  42725. else
  42726. options.itemTextPosition = options.itemTextPosition;
  42727. options.position = (options.position || '').toLowerCase();
  42728. if (options.position !== OUTSIDE && options.position !== INSIDE)
  42729. options.position = OUTSIDE;
  42730. options.hoverMode = (options.hoverMode || '').toLowerCase();
  42731. options.customizeText = $.isFunction(options.customizeText) ? options.customizeText : function() {
  42732. return this.seriesName
  42733. };
  42734. that._options = options;
  42735. !that._trackerGroup && (that._trackerGroup = that._renderer.createGroup({
  42736. 'class': 'dxc-legend-trackers',
  42737. stroke: NONE,
  42738. fill: 'grey',
  42739. opacity: 0.0001
  42740. }));
  42741. that.__initialized = true
  42742. },
  42743. _parseMargins: function(options) {
  42744. if (options.margin >= 0) {
  42745. options.margin = Number(options.margin);
  42746. options.margin = {
  42747. top: options.margin,
  42748. bottom: options.margin,
  42749. left: options.margin,
  42750. right: options.margin
  42751. }
  42752. }
  42753. else
  42754. options.margin = {
  42755. top: options.margin.top >= 0 ? Number(options.margin.top) : DEFAULT_MARGIN,
  42756. bottom: options.margin.bottom >= 0 ? Number(options.margin.bottom) : DEFAULT_MARGIN,
  42757. left: options.margin.left >= 0 ? Number(options.margin.left) : DEFAULT_MARGIN,
  42758. right: options.margin.right >= 0 ? Number(options.margin.right) : DEFAULT_MARGIN
  42759. }
  42760. },
  42761. _parseAlignments: function(options) {
  42762. options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();
  42763. if (options.horizontalAlignment !== CENTER && options.horizontalAlignment !== RIGHT && options.horizontalAlignment !== LEFT)
  42764. options.horizontalAlignment = RIGHT;
  42765. options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();
  42766. if (options.verticalAlignment !== TOP && options.verticalAlignment !== BOTTOM) {
  42767. if (options.horizontalAlignment === CENTER)
  42768. options.verticalAlignment = BOTTOM;
  42769. if (options.horizontalAlignment === RIGHT || options.horizontalAlignment === LEFT)
  42770. options.verticalAlignment = TOP
  42771. }
  42772. },
  42773. update: function(data, options) {
  42774. this._data = data;
  42775. this.boundingRect = {
  42776. width: 0,
  42777. height: 0,
  42778. x: 0,
  42779. y: 0
  42780. };
  42781. this._init(options);
  42782. return this
  42783. },
  42784. setSize: function(size) {
  42785. this._size = size;
  42786. return this
  42787. },
  42788. draw: function() {
  42789. if (!this._options)
  42790. return this;
  42791. var that = this,
  42792. renderer = that._renderer,
  42793. options = that._options,
  42794. items = that._data,
  42795. itemsLength = items.length,
  42796. seriesGroups = [],
  42797. i,
  42798. label,
  42799. marker,
  42800. singleSeriesGroup,
  42801. trackers = [],
  42802. insideLegendGroup,
  42803. markersId = new Array(itemsLength),
  42804. passedId,
  42805. border = options.border,
  42806. borderVisible = border.visible && border.width && border.color && border.color !== NONE,
  42807. markers = new Array(itemsLength);
  42808. if (!(options.visible && items && itemsLength)) {
  42809. that._disposeTrackers();
  42810. return that
  42811. }
  42812. that._cleanLegendGroups();
  42813. insideLegendGroup = that._insideLegendGroup = renderer.createGroup().append(that._legendGroup);
  42814. that._createBackground(borderVisible);
  42815. for (i = 0; i < itemsLength; i++) {
  42816. singleSeriesGroup = renderer.createGroup({'class': 'dxc-item'}).append(insideLegendGroup);
  42817. marker = that._createMarker(items[i], singleSeriesGroup, i);
  42818. passedId = items[i].id;
  42819. label = that._createLabel(items[i], passedId, singleSeriesGroup);
  42820. markersId[i] = passedId;
  42821. that._locateLabelAndMarker(label, marker);
  42822. markers[i] = marker;
  42823. trackers.push({
  42824. rect: renderer.createRect(0, 0, 0, 0, 0, {
  42825. stroke: NONE,
  42826. fill: 'grey',
  42827. opacity: 0.0001,
  42828. inh: true
  42829. }),
  42830. id: passedId
  42831. });
  42832. seriesGroups.push(singleSeriesGroup)
  42833. }
  42834. that._seriesGroups = seriesGroups;
  42835. that._trackers = trackers;
  42836. that.drawTrackers();
  42837. that._markers = markers;
  42838. that._markersId = markersId;
  42839. that._locateElements(options);
  42840. return that
  42841. },
  42842. _locateElements: function(options) {
  42843. var that = this,
  42844. border = options.border,
  42845. borderVisible = border.visible && border.width && border.color && border.color !== NONE;
  42846. that._moveInInitialValues();
  42847. that._locateRowsColumns(that._seriesGroups, that._trackers, that._data.length, that._background, options);
  42848. if (that._background)
  42849. that._adjustBackgroundSettings(that._background, borderVisible, options);
  42850. that._setBoundingRect(options)
  42851. },
  42852. _moveInInitialValues: function() {
  42853. var that = this;
  42854. that._legendGroup && that._legendGroup.move(0, 0);
  42855. that._trackerGroup && that._trackerGroup.move(0, 0);
  42856. that._background && that._background.applySettings({
  42857. x: 0,
  42858. y: 0,
  42859. width: 0,
  42860. height: 0
  42861. })
  42862. },
  42863. _applyMarkerOptions: function(marker, options) {
  42864. if (marker)
  42865. marker.applySettings(options)
  42866. },
  42867. applySelected: function(id) {
  42868. var index = this._getIndexById(id);
  42869. if (index !== null)
  42870. this._applyMarkerOptions(this._markers[index], {fill: this._markersPatternsIds[index].selectedPatternId});
  42871. return this
  42872. },
  42873. applyHover: function(id) {
  42874. var index = this._getIndexById(id);
  42875. if (index !== null)
  42876. this._applyMarkerOptions(this._markers[index], {fill: this._markersPatternsIds[index].hoverPatternId});
  42877. return this
  42878. },
  42879. resetItem: function(id) {
  42880. var index = this._getIndexById(id);
  42881. if (index !== null)
  42882. this._applyMarkerOptions(this._markers[index], {fill: this._data[index].color || this._data[index].states.normal.fill})
  42883. },
  42884. _getIndexById: function(id) {
  42885. var i,
  42886. markersId = this._markersId,
  42887. markersIdLen = markersId.length;
  42888. for (i = 0; i < markersIdLen; i++)
  42889. if (markersId[i] === id)
  42890. return i;
  42891. return null
  42892. },
  42893. drawTrackers: function() {
  42894. if (!this._options.visible || !this._insideLegendGroup)
  42895. return;
  42896. var that = this,
  42897. trackerGroup = that._trackerGroup.append(that._legendGroup);
  42898. $.each(that._trackers || [], function(i, tracker) {
  42899. var trackerRect = tracker.rect;
  42900. trackerRect.data({
  42901. itemIndex: tracker.id,
  42902. mode: that._options.hoverMode
  42903. });
  42904. trackerRect.append(trackerGroup)
  42905. });
  42906. return that
  42907. },
  42908. _disposeTrackers: function() {
  42909. var that = this;
  42910. $.each(that._trackers || [], function(_, tracker) {
  42911. tracker.rect.removeData()
  42912. });
  42913. that._trackers = null
  42914. },
  42915. _createMarker: function(data, group, markerIndex) {
  42916. var that = this,
  42917. renderer = that._renderer,
  42918. markersPatternsIds = that._markersPatternsIds,
  42919. size = that._options.markerSize,
  42920. states = data.states,
  42921. marker;
  42922. marker = renderer.createRect(0, 0, size, size, 0, {fill: data.color}).append(group);
  42923. markersPatternsIds[markerIndex] = {
  42924. hoverPatternId: getPatternId(renderer, states, 'hover', data.color),
  42925. selectedPatternId: getPatternId(renderer, states, 'selection', data.color)
  42926. };
  42927. return marker
  42928. },
  42929. _createLabel: function(data, index, group) {
  42930. var that = this,
  42931. options = that._options,
  42932. position = options.itemTextPosition,
  42933. align = position === TOP || position === BOTTOM ? CENTER : LEFT,
  42934. text,
  42935. label,
  42936. labelFormatObject = {
  42937. seriesName: data.text,
  42938. seriesNumber: index,
  42939. seriesColor: data.color
  42940. };
  42941. text = that._formatLabel.call(labelFormatObject, options);
  42942. label = that._renderer.createText(text, 0, 0, {
  42943. font: options.font,
  42944. align: align
  42945. }).append(group);
  42946. return label
  42947. },
  42948. _cleanLegendGroups: function() {
  42949. var that = this,
  42950. trackerGroup = that._trackerGroup,
  42951. legendGroup = that._legendGroup;
  42952. if (legendGroup) {
  42953. legendGroup.clear();
  42954. that._insideLegendGroup && that._insideLegendGroup.dispose();
  42955. that._insideLegendGroup = null
  42956. }
  42957. if (trackerGroup)
  42958. trackerGroup.clear()
  42959. },
  42960. _createBackground: function(borderVisible) {
  42961. var that = this,
  42962. options = that._options,
  42963. isInside = options.position === INSIDE,
  42964. color = options.backgroundColor,
  42965. fill = color || (isInside ? options.containerBackgroundColor : NONE);
  42966. if (isInside || color || borderVisible)
  42967. that._background = that._renderer.createRect(0, 0, 0, 0, 0, {
  42968. fill: fill,
  42969. 'class': 'dxc-border'
  42970. }).append(that._insideLegendGroup)
  42971. },
  42972. _formatLabel: function(options) {
  42973. return options.customizeText.call(this, this)
  42974. },
  42975. _locateLabelAndMarker: function(label, marker) {
  42976. var that = this,
  42977. defaultXMargin = 7,
  42978. defaultTopMargin = 4,
  42979. defaultBottomMargin = 2,
  42980. labelX = 0,
  42981. labelY = 0,
  42982. markerX,
  42983. markerY,
  42984. labelBox = label.getBBox(),
  42985. markerWidth = that._options.markerSize,
  42986. markerHeight = markerWidth,
  42987. approximateLabelY = markerHeight / 2 - (labelBox.y + labelBox.height / 2),
  42988. approximateLabelX = markerWidth / 2 - (labelBox.x + labelBox.width / 2);
  42989. switch (that._options.itemTextPosition) {
  42990. case LEFT:
  42991. labelY = _round(approximateLabelY);
  42992. markerX = labelBox.width + defaultXMargin;
  42993. break;
  42994. case RIGHT:
  42995. labelX = markerWidth + defaultXMargin;
  42996. labelY = _round(approximateLabelY);
  42997. break;
  42998. case TOP:
  42999. labelX = _round(approximateLabelX);
  43000. markerY = defaultTopMargin;
  43001. break;
  43002. case BOTTOM:
  43003. labelX = _round(approximateLabelX);
  43004. labelY = markerHeight + defaultBottomMargin - labelBox.y;
  43005. break
  43006. }
  43007. label.applySettings({
  43008. x: labelX,
  43009. y: labelY
  43010. });
  43011. marker.applySettings({
  43012. x: markerX,
  43013. y: markerY
  43014. })
  43015. },
  43016. _locateRowsColumns: function(groups, trackers, count, background, options) {
  43017. var that = this,
  43018. itemTextPosition = options.itemTextPosition,
  43019. size = that._size,
  43020. legendBox,
  43021. rowsColumns = that._getRowsColumns(count),
  43022. rows = rowsColumns.rows,
  43023. columns = rowsColumns.columns,
  43024. margin = options.margin,
  43025. paddingLeftRight = background ? options.paddingLeftRight : 0,
  43026. paddingTopBottom = background ? options.paddingTopBottom : 0,
  43027. placeholderWidth = size.width - margin.left - margin.right - 2 * paddingLeftRight,
  43028. placeholderHeight = size.height - margin.top - margin.bottom - 2 * paddingTopBottom,
  43029. rowsColumnsData,
  43030. condition,
  43031. maxBBox = getMaxBBox(groups);
  43032. var moveRowsColumns = function(rows, columns) {
  43033. rowsColumnsData = that._getDataRowsColumns(groups, columns, rows);
  43034. that._moveItems(rowsColumnsData, groups, itemTextPosition, trackers, options)
  43035. };
  43036. moveRowsColumns(rows, columns);
  43037. legendBox = that._insideLegendGroup ? that._insideLegendGroup.getBBox() : {};
  43038. if (rowsColumns.autoEdit)
  43039. if (rows === 1) {
  43040. if (legendBox.width > placeholderWidth && columns > 1) {
  43041. columns = _floor(placeholderWidth / (maxBBox.width + options.columnItemSpacing)) || 1;
  43042. columns = validate(columns, count);
  43043. rows = _ceil(count / columns);
  43044. moveRowsColumns(rows, columns)
  43045. }
  43046. }
  43047. else if (columns === 1)
  43048. if (legendBox.height > placeholderHeight && rows > 1) {
  43049. rows = _floor(placeholderHeight / (maxBBox.height + options.rowItemSpacing)) || 1;
  43050. rows = validate(rows, count);
  43051. columns = _ceil(count / rows);
  43052. moveRowsColumns(rows, columns)
  43053. }
  43054. that._rowsCountDrawed = rows;
  43055. that._columnsCountDrawed = columns;
  43056. function validate(rowsOrColumns, count) {
  43057. if (rowsOrColumns > count || rowsOrColumns < 1)
  43058. rowsOrColumns = count;
  43059. return rowsOrColumns
  43060. }
  43061. },
  43062. _moveItems: function(data, seriesGroups, horizontalTextPosition, trackers, options) {
  43063. var that = this,
  43064. i,
  43065. j,
  43066. rows,
  43067. cols,
  43068. number,
  43069. group,
  43070. box,
  43071. xShift = 0,
  43072. yShift = 0,
  43073. widthColumn,
  43074. xPadding = options.columnItemSpacing,
  43075. yPadding = options.rowItemSpacing,
  43076. equalColumnWidth = options.equalColumnWidth,
  43077. renderer = that._renderer,
  43078. maxWidthPerColumn = [],
  43079. maxWidthColumn = 0,
  43080. maxHeightRow = 0;
  43081. rows = data.rows;
  43082. cols = data.cols;
  43083. maxHeightRow = data.maxHeightRow;
  43084. maxWidthColumn = data.maxWidthColumn;
  43085. maxWidthPerColumn = data.maxWidthPerColumn;
  43086. for (i = 0; i < rows; i++) {
  43087. for (j = 0; j < cols; j++) {
  43088. if (rows < cols)
  43089. number = i * cols + j;
  43090. else
  43091. number = i + j * rows;
  43092. group = seriesGroups[number];
  43093. if (!group)
  43094. break;
  43095. box = group.getBBox();
  43096. widthColumn = !equalColumnWidth ? maxWidthPerColumn[j] : maxWidthColumn;
  43097. if (horizontalTextPosition === RIGHT) {
  43098. group.move(xShift - box.x, yShift);
  43099. trackers[number].rect.applySettings({
  43100. x: xShift - xPadding / 2,
  43101. y: yShift + box.y - yPadding / 2,
  43102. height: maxHeightRow + yPadding,
  43103. width: widthColumn + xPadding
  43104. })
  43105. }
  43106. else if (horizontalTextPosition === LEFT) {
  43107. group.move(box.x + widthColumn - box.width + xShift - xPadding / 2, yShift);
  43108. trackers[number].rect.applySettings({
  43109. x: box.x + widthColumn - box.width + xShift - xPadding / 2,
  43110. y: yShift + box.y - yPadding / 2,
  43111. height: maxHeightRow + yPadding,
  43112. width: widthColumn + xPadding
  43113. })
  43114. }
  43115. else {
  43116. group.move(xShift - box.x - box.width / 2 + widthColumn / 2, yShift);
  43117. trackers[number].rect.applySettings({
  43118. x: xShift - xPadding / 2,
  43119. y: yShift + box.y - yPadding / 2,
  43120. height: maxHeightRow + yPadding,
  43121. width: widthColumn + xPadding
  43122. })
  43123. }
  43124. xShift = xShift + widthColumn + xPadding
  43125. }
  43126. yShift = yShift + maxHeightRow + yPadding;
  43127. xShift = 0
  43128. }
  43129. },
  43130. _getDataRowsColumns: function(seriesGroups, cols, rows) {
  43131. var that = this,
  43132. i,
  43133. j,
  43134. options = that._options,
  43135. equalColumnWidth = options.equalColumnWidth,
  43136. series = that.series || {},
  43137. maxWidthPerColumn = [],
  43138. maxWidthColumn = 0,
  43139. maxHeightRow = 0,
  43140. group,
  43141. box;
  43142. for (i = 0; i < cols; i++)
  43143. maxWidthPerColumn[i] = 0;
  43144. for (i = 0; i < rows; i++)
  43145. for (j = 0; j < cols; j++) {
  43146. if (rows < cols)
  43147. group = seriesGroups[i * cols + j];
  43148. else
  43149. group = seriesGroups[i + j * rows];
  43150. if (!group)
  43151. break;
  43152. box = group.getBBox();
  43153. if (maxHeightRow < box.height)
  43154. maxHeightRow = box.height;
  43155. if (!equalColumnWidth) {
  43156. if (maxWidthPerColumn[j] < box.width)
  43157. maxWidthPerColumn[j] = box.width
  43158. }
  43159. else if (maxWidthColumn < box.width)
  43160. maxWidthColumn = box.width
  43161. }
  43162. return {
  43163. rows: rows,
  43164. cols: cols,
  43165. maxWidthPerColumn: maxWidthPerColumn,
  43166. maxWidthColumn: maxWidthColumn,
  43167. maxHeightRow: maxHeightRow
  43168. }
  43169. },
  43170. _getRowsColumns: function(count) {
  43171. var that = this,
  43172. options = that._options,
  43173. isHorizontal = options.orientation === HORIZONTAL,
  43174. rows = options.rowCount,
  43175. onRows = _ceil(count / rows),
  43176. columns = options.columnCount,
  43177. onColumns = _ceil(count / columns),
  43178. autoEdit;
  43179. if (columns && !rows)
  43180. rows = onColumns;
  43181. else if (!columns && rows)
  43182. columns = onRows;
  43183. else if (columns && rows) {
  43184. if (isHorizontal && columns < onRows)
  43185. columns = onRows;
  43186. else if (!isHorizontal && rows < onColumns)
  43187. rows = onColumns
  43188. }
  43189. else {
  43190. autoEdit = true;
  43191. if (isHorizontal) {
  43192. rows = 1;
  43193. columns = count
  43194. }
  43195. else {
  43196. columns = 1;
  43197. rows = count
  43198. }
  43199. }
  43200. return {
  43201. rows: rows,
  43202. columns: columns,
  43203. autoEdit: autoEdit
  43204. }
  43205. },
  43206. _adjustBackgroundSettings: function(background, borderVisible, options) {
  43207. var that = this,
  43208. border = options.border,
  43209. legendBox = that._insideLegendGroup.getBBox(),
  43210. backgroundSettings = {
  43211. x: _round(legendBox.x - options.paddingLeftRight),
  43212. y: _round(legendBox.y - options.paddingTopBottom),
  43213. width: _round(legendBox.width) + 2 * options.paddingLeftRight,
  43214. height: _round(legendBox.height) + 2 * options.paddingTopBottom,
  43215. opacity: options.backgroundOpacity
  43216. };
  43217. if (borderVisible) {
  43218. backgroundSettings.strokeWidth = border.width;
  43219. backgroundSettings.stroke = border.color;
  43220. backgroundSettings.strokeOpacity = border.opacity;
  43221. backgroundSettings.dashStyle = border.dashStyle;
  43222. backgroundSettings.rx = border.cornerRadius || 0;
  43223. backgroundSettings.ry = border.cornerRadius || 0
  43224. }
  43225. background.applySettings(backgroundSettings)
  43226. },
  43227. _setBoundingRect: function(options) {
  43228. var that = this,
  43229. box,
  43230. margin = options.margin;
  43231. if (!that._insideLegendGroup)
  43232. return;
  43233. box = that._insideLegendGroup.getBBox();
  43234. box.height += margin.top + margin.bottom;
  43235. box.width += margin.left + margin.right;
  43236. box.x -= margin.left;
  43237. box.y -= margin.top;
  43238. that.boundingRect = box
  43239. },
  43240. changeSize: function(size) {
  43241. var that = this,
  43242. options = $.extend(true, {}, that._options),
  43243. margin = options.margin;
  43244. if (size.height >= 0) {
  43245. size.height = decreaseGaps(margin, ["top", "bottom"], size.height);
  43246. if (options.border.visible)
  43247. size.height = 2 * decreaseGaps(options, ["paddingTopBottom"], size.height / 2);
  43248. if (that._rowsCountDrawed - 1)
  43249. size.height = (that._rowsCountDrawed - 1) * decreaseGaps(options, ["rowItemSpacing"], size.height / (that._rowsCountDrawed - 1))
  43250. }
  43251. if (size.width >= 0) {
  43252. size.width = decreaseGaps(margin, ["left", "right"], size.width);
  43253. if (options.border.visible)
  43254. size.width = 2 * decreaseGaps(options, ["paddingLeftRight"], size.width / 2);
  43255. if (that._columnsCountDrawed - 1)
  43256. size.width = (that._columnsCountDrawed - 1) * decreaseGaps(options, ["columnItemSpacing"], size.width / (that._columnsCountDrawed - 1))
  43257. }
  43258. if (that._insideLegendGroup)
  43259. if (size.height > 0 || size.width > 0) {
  43260. that._options._incidentOccured("W2104");
  43261. that._insideLegendGroup.remove();
  43262. that._insideLegendGroup = null;
  43263. that._trackerGroup && that._trackerGroup.clear()
  43264. }
  43265. else
  43266. that._locateElements(options)
  43267. },
  43268. getTrackerGroup: function() {
  43269. return this._trackerGroup
  43270. },
  43271. getActionCallback: function(point) {
  43272. var that = this;
  43273. if (that._options.visible)
  43274. return function(act) {
  43275. var pointType = point.type,
  43276. isSeries = pointType ? true : false,
  43277. seriesType = pointType || point.series.type;
  43278. if (isSeries || seriesType === 'pie' || seriesType === 'doughnut' || seriesType === 'donut')
  43279. that[act] && that[act](point.index)
  43280. };
  43281. else
  43282. return $.noop
  43283. },
  43284. getLayoutOptions: function() {
  43285. var options = this._options,
  43286. boundingRect = this._insideLegendGroup ? this.boundingRect : {
  43287. width: 0,
  43288. height: 0,
  43289. x: 0,
  43290. y: 0
  43291. };
  43292. if (options) {
  43293. boundingRect.verticalAlignment = options.verticalAlignment;
  43294. boundingRect.horizontalAlignment = options.horizontalAlignment;
  43295. if (options.orientation === 'horizontal')
  43296. boundingRect.cutLayoutSide = options.verticalAlignment;
  43297. else
  43298. boundingRect.cutLayoutSide = options.horizontalAlignment === 'center' ? options.verticalAlignment : options.horizontalAlignment;
  43299. return boundingRect
  43300. }
  43301. return null
  43302. },
  43303. shift: function(x, y) {
  43304. var that = this,
  43305. settings = {},
  43306. box = that.getLayoutOptions();
  43307. settings.translateX = x - box.x;
  43308. settings.translateY = y - box.y;
  43309. that._insideLegendGroup && that._insideLegendGroup.applySettings(settings);
  43310. that._trackerGroup && that._trackerGroup.applySettings(settings)
  43311. },
  43312. getPosition: function() {
  43313. return this._options.position
  43314. },
  43315. dispose: function() {
  43316. var that = this;
  43317. that._disposeTrackers();
  43318. that._legendGroup = null;
  43319. that._trackerGroup = null;
  43320. that._insideLegendGroup = null;
  43321. that._renderer = null;
  43322. that._options = null;
  43323. that._data = null;
  43324. return that
  43325. }
  43326. })
  43327. })(DevExpress, jQuery);
  43328. /*! Module viz-core, file range.js */
  43329. (function($, DX, undefined) {
  43330. var core = DX.viz.core,
  43331. utils = DX.utils,
  43332. isDefinedUtils = utils.isDefined,
  43333. isDateUtils = utils.isDate,
  43334. getLogUtils = utils.getLog,
  43335. raiseToUtils = utils.raiseTo;
  43336. var NUMBER_EQUALITY_CORRECTION = 1,
  43337. DATETIME_EQUALITY_CORRECTION = 60000;
  43338. var minSelector = 'min',
  43339. maxSelector = 'max',
  43340. minVisibleSelector = 'minVisible',
  43341. maxVisibleSelector = 'maxVisible',
  43342. minValueMarginSelector = 'minValueMargin',
  43343. maxValueMarginSelector = 'maxValueMargin',
  43344. categoriesSelector = 'categories',
  43345. keepValueMarginsSelector = 'keepValueMargins',
  43346. baseSelector = 'base',
  43347. axisTypeSelector = 'axisType';
  43348. var raiseToFlooredLog = function(value, base, correction) {
  43349. return raiseToUtils(Math.floor(getLogUtils(value, base)) + (correction || 0), base)
  43350. };
  43351. var otherLessThan = function(thisValue, otherValue) {
  43352. return otherValue < thisValue
  43353. };
  43354. var otherGreaterThan = function(thisValue, otherValue) {
  43355. return otherValue > thisValue
  43356. };
  43357. var compareAndReplace = function(thisValue, otherValue, setValue, compare) {
  43358. var otherValueDefined = isDefinedUtils(otherValue);
  43359. if (isDefinedUtils(thisValue)) {
  43360. if (otherValueDefined && compare(thisValue, otherValue))
  43361. setValue(otherValue)
  43362. }
  43363. else if (otherValueDefined)
  43364. setValue(otherValue)
  43365. };
  43366. var applyMargin = function(value, margin, rangeLength, coef, isDateTime) {
  43367. value = value.valueOf() + coef * rangeLength * margin;
  43368. return isDateTime ? new Date(value) : value
  43369. };
  43370. DX.viz.core.__NUMBER_EQUALITY_CORRECTION = NUMBER_EQUALITY_CORRECTION;
  43371. DX.viz.core.__DATETIME_EQUALITY_CORRECTION = DATETIME_EQUALITY_CORRECTION;
  43372. core.Range = function(range) {
  43373. range && $.extend(this, range)
  43374. };
  43375. $.extend(core.Range.prototype, {
  43376. dispose: function() {
  43377. this[categoriesSelector] = null
  43378. },
  43379. addRange: function(otherRange) {
  43380. var that = this,
  43381. categories = that[categoriesSelector],
  43382. categoriesValues,
  43383. otherCategories = otherRange[categoriesSelector],
  43384. i,
  43385. j,
  43386. length,
  43387. found;
  43388. var setIndentByPriority = function(prefix) {
  43389. var prioritySelector = prefix + 'Priority',
  43390. priorityRelation = (that[prioritySelector] || 0) - (otherRange[prioritySelector] || 0);
  43391. if ((that[prefix] || 0) < otherRange[prefix] && priorityRelation === 0 || priorityRelation < 0) {
  43392. that[prefix] = otherRange[prefix];
  43393. that[prioritySelector] = otherRange[prioritySelector]
  43394. }
  43395. };
  43396. var compareAndReplaceByField = function(field, compare) {
  43397. compareAndReplace(that[field], otherRange[field], function(value) {
  43398. that[field] = value
  43399. }, compare)
  43400. };
  43401. var controlValuesByVisibleBounds = function(valueField, visibleValueField, compare) {
  43402. compareAndReplace(that[valueField], that[visibleValueField], function(value) {
  43403. isDefinedUtils(that[valueField]) && (that[valueField] = value)
  43404. }, compare)
  43405. };
  43406. var checkField = function(field) {
  43407. that[field] = that[field] || otherRange[field]
  43408. };
  43409. if (utils.isDefined(otherRange["stick"]))
  43410. that["stick"] = otherRange["stick"];
  43411. checkField('invert');
  43412. checkField(axisTypeSelector);
  43413. checkField('dataType');
  43414. checkField(keepValueMarginsSelector);
  43415. if (that[axisTypeSelector] === 'logarithmic')
  43416. checkField(baseSelector);
  43417. else
  43418. that[baseSelector] = undefined;
  43419. compareAndReplaceByField(minSelector, otherLessThan);
  43420. compareAndReplaceByField(maxSelector, otherGreaterThan);
  43421. compareAndReplaceByField(minVisibleSelector, otherLessThan);
  43422. compareAndReplaceByField(maxVisibleSelector, otherGreaterThan);
  43423. compareAndReplaceByField('interval', otherLessThan);
  43424. setIndentByPriority(minValueMarginSelector);
  43425. setIndentByPriority(maxValueMarginSelector);
  43426. controlValuesByVisibleBounds(minSelector, minVisibleSelector, otherLessThan);
  43427. controlValuesByVisibleBounds(minSelector, maxVisibleSelector, otherLessThan);
  43428. controlValuesByVisibleBounds(maxSelector, maxVisibleSelector, otherGreaterThan);
  43429. controlValuesByVisibleBounds(maxSelector, minVisibleSelector, otherGreaterThan);
  43430. if (categories === undefined)
  43431. that[categoriesSelector] = otherCategories;
  43432. else {
  43433. length = categories.length;
  43434. if (otherCategories && otherCategories.length)
  43435. for (i = 0; i < otherCategories.length; i++) {
  43436. for (j = 0, found = false; j < length; j++)
  43437. if (categories[j].valueOf() === otherCategories[i].valueOf()) {
  43438. found = true;
  43439. break
  43440. }
  43441. !found && categories.push(otherCategories[i])
  43442. }
  43443. }
  43444. return this
  43445. },
  43446. isDefined: function() {
  43447. return isDefinedUtils(this[minSelector]) && isDefinedUtils(this[maxSelector]) || isDefinedUtils(this[categoriesSelector])
  43448. },
  43449. setStubData: function(dataType) {
  43450. var that = this,
  43451. year = (new Date).getYear() - 1,
  43452. isDate = dataType === 'datetime',
  43453. isCategories = that.axisType === 'discrete';
  43454. if (isCategories)
  43455. that.categories = ['0', '1', '2'];
  43456. else {
  43457. that[minSelector] = isDate ? new Date(year, 0, 1) : 0;
  43458. that[maxSelector] = isDate ? new Date(year, 11, 31) : 10
  43459. }
  43460. that.stubData = true;
  43461. return that
  43462. },
  43463. applyValueMargins: function() {
  43464. var that = this,
  43465. base = that[baseSelector],
  43466. isDateTime = isDateUtils(that[maxSelector]) || isDateUtils(that[minSelector]);
  43467. var applyMarginWithZeroCorrection = function(min, max, rangeLength) {
  43468. var minValue = that[min],
  43469. maxValue = that[max],
  43470. minMargin = that[minValueMarginSelector],
  43471. maxMargin = that[maxValueMarginSelector],
  43472. minCorrected = false,
  43473. maxCorrected = false;
  43474. if (rangeLength && !isDateTime && !that[keepValueMarginsSelector]) {
  43475. if (minValue <= 0 && maxValue <= 0 && maxMargin > maxValue / (minValue - maxValue)) {
  43476. that[max] = 0;
  43477. maxCorrected = true
  43478. }
  43479. if (minValue >= 0 && maxValue >= 0 && minMargin > minValue / (maxValue - minValue)) {
  43480. that[min] = 0;
  43481. minCorrected = true
  43482. }
  43483. }
  43484. if (isDefinedUtils(maxValue) && !maxCorrected && maxMargin)
  43485. that[max] = applyMargin(maxValue, maxMargin, rangeLength, 1, isDateTime);
  43486. if (isDefinedUtils(minValue) && !minCorrected && minMargin)
  43487. that[min] = applyMargin(minValue, minMargin, rangeLength, -1, isDateTime)
  43488. };
  43489. var correctValueByBoundaries = function(visibleSelector, valueSelector) {
  43490. that[visibleSelector] = isDefinedUtils(that[visibleSelector]) ? that[visibleSelector] : that[valueSelector]
  43491. };
  43492. var processLogarithmicMinValue = function(valueField) {
  43493. if (isDefinedUtils(that[valueField])) {
  43494. var intermediateValue = raiseToFlooredLog(that[valueField], base);
  43495. if (getLogUtils(that[valueField] / intermediateValue, base) < 0.1 && that.alwaysCorrectMin && !that[keepValueMarginsSelector])
  43496. that[valueField] = raiseToFlooredLog(that[valueField], base, -1);
  43497. else if (that.alwaysCorrectMin && !that[keepValueMarginsSelector])
  43498. that[valueField] = intermediateValue;
  43499. else if (getLogUtils(that[valueField] / intermediateValue, base) < 0.5)
  43500. that[valueField] = intermediateValue
  43501. }
  43502. };
  43503. var processLogarithmicMaxValue = function(valueField) {
  43504. if (isDefinedUtils(that[valueField])) {
  43505. var intermediateValue = raiseToFlooredLog(that[valueField], base);
  43506. if (getLogUtils(that[valueField] / intermediateValue, base) > 0.5)
  43507. that[valueField] = raiseToUtils(Math.ceil(getLogUtils(that[valueField], base)), base)
  43508. }
  43509. };
  43510. var correctLogVisibleValue = function(visibleValueSelector, valueSelector, compare) {
  43511. if (!isDefinedUtils(that[visibleValueSelector]) || compare)
  43512. that[visibleValueSelector] = that[valueSelector]
  43513. };
  43514. if (that[axisTypeSelector] === 'logarithmic' && that[minSelector] !== that[maxSelector]) {
  43515. processLogarithmicMinValue(minSelector);
  43516. processLogarithmicMaxValue(maxSelector);
  43517. if (that.isValueRange && that[minVisibleSelector] !== that[maxVisibleSelector]) {
  43518. processLogarithmicMinValue(minVisibleSelector);
  43519. processLogarithmicMaxValue(maxVisibleSelector)
  43520. }
  43521. correctLogVisibleValue(minVisibleSelector, minSelector, that[minVisibleSelector] < that[minSelector]);
  43522. correctLogVisibleValue(maxVisibleSelector, maxSelector, that[maxVisibleSelector] > that[maxSelector])
  43523. }
  43524. else {
  43525. correctValueByBoundaries(minVisibleSelector, minSelector);
  43526. correctValueByBoundaries(maxVisibleSelector, maxSelector);
  43527. applyMarginWithZeroCorrection(minSelector, maxSelector, that[maxSelector] - that[minSelector]);
  43528. applyMarginWithZeroCorrection(minVisibleSelector, maxVisibleSelector, that[maxVisibleSelector] - that[minVisibleSelector])
  43529. }
  43530. return this
  43531. },
  43532. correctValueZeroLevel: function() {
  43533. var that = this;
  43534. if (isDateUtils(that[maxSelector]) || isDateUtils(that[minSelector]))
  43535. return that;
  43536. function setZeroLevel(min, max) {
  43537. that[min] < 0 && that[max] < 0 && (that[max] = 0);
  43538. that[min] > 0 && that[max] > 0 && (that[min] = 0)
  43539. }
  43540. setZeroLevel(minSelector, maxSelector);
  43541. setZeroLevel(minVisibleSelector, maxVisibleSelector);
  43542. return that
  43543. }
  43544. })
  43545. })(jQuery, DevExpress);
  43546. /*! Module viz-core, file seriesConsts.js */
  43547. (function(DX) {
  43548. DX.viz.core.series = DX.viz.core.series || {};
  43549. DX.viz.core.series.helpers = DX.viz.core.series.helpers || {};
  43550. DX.viz.core.series.helpers.consts = {
  43551. events: {
  43552. mouseover: "mouseover",
  43553. mouseout: "mouseout",
  43554. mousemove: "mousemove",
  43555. touchstart: "touchstart",
  43556. touchmove: "touchmove",
  43557. touchend: "touchend",
  43558. mousedown: "mousedown",
  43559. mouseup: "mouseup",
  43560. click: "click",
  43561. selectSeries: "selectseries",
  43562. deselectSeries: "deselectseries",
  43563. selectPoint: "selectpoint",
  43564. deselectPoint: "deselectpoint",
  43565. showPointTooltip: "showpointtooltip",
  43566. hidePointTooltip: "hidepointtooltip"
  43567. },
  43568. states: {
  43569. hover: "hover",
  43570. normal: "normal",
  43571. selected: "selected",
  43572. normalMark: 0,
  43573. hoverMark: 1,
  43574. selectedMark: 2
  43575. },
  43576. animations: {
  43577. showDuration: {duration: 400},
  43578. hideGroup: {opacity: 0.0001},
  43579. showGroup: {opacity: 1}
  43580. }
  43581. }
  43582. })(DevExpress);
  43583. /*! Module viz-core, file seriesFamily.js */
  43584. (function($, DX, undefined) {
  43585. var utils = DX.utils,
  43586. _round = Math.round,
  43587. _abs = Math.abs,
  43588. _pow = Math.pow;
  43589. DX.viz.core.series.helpers.SeriesFamily = DX.Class.inherit(function() {
  43590. var ctor = function(options) {
  43591. var debug = DX.utils.debug;
  43592. debug.assert(options.type, "type was not passed or empty");
  43593. var that = this,
  43594. stubFunction = $.noop;
  43595. $.extend(that, options);
  43596. that.type = that.type.toLowerCase();
  43597. that.series = [];
  43598. switch (that.type) {
  43599. case"bar":
  43600. that.adjustSeriesDimensions = adjustBarSeriesDimensions;
  43601. that.adjustSeriesValues = stubFunction;
  43602. that.updateSeriesValues = updateBarSeriesValues;
  43603. break;
  43604. case"rangebar":
  43605. that.adjustSeriesDimensions = adjustBarSeriesDimensions;
  43606. that.adjustSeriesValues = stubFunction;
  43607. that.updateSeriesValues = stubFunction;
  43608. break;
  43609. case"fullstackedbar":
  43610. that.fullStacked = true;
  43611. that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
  43612. that.adjustSeriesValues = adjustStackedSeriesValues;
  43613. that.updateSeriesValues = updateStackedSeriesValues;
  43614. break;
  43615. case"stackedbar":
  43616. that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
  43617. that.adjustSeriesValues = adjustStackedSeriesValues;
  43618. that.updateSeriesValues = updateStackedSeriesValues;
  43619. break;
  43620. case"fullstackedarea":
  43621. case"fullstackedline":
  43622. that.fullStacked = true;
  43623. that.adjustSeriesDimensions = stubFunction;
  43624. that.adjustSeriesValues = adjustStackedSeriesValues;
  43625. that.updateSeriesValues = stubFunction;
  43626. break;
  43627. case"stackedarea":
  43628. case"stackedline":
  43629. that.adjustSeriesDimensions = stubFunction;
  43630. that.adjustSeriesValues = adjustStackedSeriesValues;
  43631. that.updateSeriesValues = stubFunction;
  43632. break;
  43633. case"candlestick":
  43634. case"stock":
  43635. that.adjustSeriesDimensions = adjustCandlestickSeriesDimensions;
  43636. that.adjustSeriesValues = stubFunction;
  43637. that.updateSeriesValues = stubFunction;
  43638. break;
  43639. case"bubble":
  43640. that.adjustSeriesDimensions = adjustBubbleSeriesDimensions;
  43641. that.adjustSeriesValues = stubFunction;
  43642. that.updateSeriesValues = stubFunction;
  43643. break;
  43644. default:
  43645. that.adjustSeriesDimensions = stubFunction;
  43646. that.adjustSeriesValues = stubFunction;
  43647. that.updateSeriesValues = stubFunction;
  43648. break
  43649. }
  43650. };
  43651. var dispose = function() {
  43652. this.series = null;
  43653. this.translators = null
  43654. };
  43655. var add = function(series) {
  43656. var that = this,
  43657. singleSeries,
  43658. i;
  43659. if (!$.isArray(series))
  43660. series = [series];
  43661. for (i = 0; i < series.length; i++) {
  43662. singleSeries = series[i];
  43663. if (singleSeries.type.toLowerCase() === that.type)
  43664. that.series.push(singleSeries)
  43665. }
  43666. };
  43667. var adjustBarSeriesDimensionsCore = function(series, interval, stackCount, equalBarWidth, seriesStackIndexCallback) {
  43668. var spacing,
  43669. width,
  43670. maxWidth,
  43671. middleIndex,
  43672. stackIndex,
  43673. i,
  43674. point,
  43675. points,
  43676. seriesOffset,
  43677. stackName,
  43678. argumentsKeeper = {},
  43679. stackKeepers = {},
  43680. stacksWithArgument,
  43681. count;
  43682. if (equalBarWidth) {
  43683. width = equalBarWidth.width && equalBarWidth.width < 0 ? 0 : equalBarWidth.width;
  43684. spacing = equalBarWidth.spacing && equalBarWidth.spacing < 0 ? 0 : equalBarWidth.spacing;
  43685. if (width && !spacing)
  43686. if (stackCount > 1) {
  43687. spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));
  43688. if (spacing < 1)
  43689. spacing = 1
  43690. }
  43691. else
  43692. spacing = 0;
  43693. else if (spacing && !width) {
  43694. width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);
  43695. if (width < 2)
  43696. width = 2
  43697. }
  43698. else if (!spacing && !width) {
  43699. if (stackCount > 1) {
  43700. spacing = _round(interval * 0.7 / stackCount * 0.2);
  43701. if (spacing < 1)
  43702. spacing = 1
  43703. }
  43704. else
  43705. spacing = 0;
  43706. width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);
  43707. if (width < 2)
  43708. width = 2
  43709. }
  43710. if (width * stackCount + spacing * (stackCount - 1) > interval) {
  43711. spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));
  43712. if (spacing < 1) {
  43713. spacing = 1;
  43714. maxWidth = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount)
  43715. }
  43716. }
  43717. middleIndex = stackCount / 2;
  43718. for (i = 0; i < series.length; i++) {
  43719. stackIndex = seriesStackIndexCallback(i);
  43720. points = series[i].getPoints();
  43721. seriesOffset = (stackIndex - middleIndex + 0.5) * (maxWidth || width) - (middleIndex - stackIndex - 0.5) * spacing;
  43722. $.each(points, function(_, point) {
  43723. point.correctCoordinates({
  43724. width: width,
  43725. offset: seriesOffset
  43726. })
  43727. })
  43728. }
  43729. }
  43730. else {
  43731. $.each(series, function(i, singleSeries) {
  43732. stackName = singleSeries.getStackName && singleSeries.getStackName();
  43733. stackName = stackName || i.toString();
  43734. if (!stackKeepers[stackName])
  43735. stackKeepers[stackName] = [];
  43736. stackKeepers[stackName].push(singleSeries)
  43737. });
  43738. $.each(series, function(i, singleSeries) {
  43739. $.each(singleSeries.getPoints(), function(_, point) {
  43740. var argument = point.argument;
  43741. if (!argumentsKeeper.hasOwnProperty(argument))
  43742. argumentsKeeper[argument.valueOf()] = 1
  43743. })
  43744. });
  43745. for (var argument in argumentsKeeper) {
  43746. if (!argumentsKeeper.hasOwnProperty(argument))
  43747. continue;
  43748. stacksWithArgument = [];
  43749. $.each(stackKeepers, function(stackName, seriesInStack) {
  43750. $.each(seriesInStack, function(i, singleSeries) {
  43751. point = singleSeries.getPointByArg(argument);
  43752. if (point && point.value) {
  43753. stacksWithArgument.push(stackName);
  43754. return false
  43755. }
  43756. })
  43757. });
  43758. count = stacksWithArgument.length;
  43759. spacing = _round(interval * 0.7 / count * 0.2);
  43760. if (spacing < 1)
  43761. spacing = 1;
  43762. width = _round((interval * 0.7 - spacing * (count - 1)) / count);
  43763. if (width < 2)
  43764. width = 2;
  43765. middleIndex = count / 2;
  43766. $.each(stackKeepers, function(stackName, seriesInStack) {
  43767. stackIndex = $.inArray(stackName, stacksWithArgument);
  43768. if (stackIndex === -1)
  43769. return;
  43770. seriesOffset = (stackIndex - middleIndex + 0.5) * width - (middleIndex - stackIndex - 0.5) * spacing;
  43771. $.each(seriesInStack, function(i, singleSeries) {
  43772. var point = singleSeries.getPointByArg(argument);
  43773. if (point && point.value)
  43774. point.correctCoordinates({
  43775. width: width,
  43776. offset: seriesOffset
  43777. })
  43778. })
  43779. })
  43780. }
  43781. }
  43782. };
  43783. var getVisibleSeries = function(that) {
  43784. return $.map(that.series, function(s) {
  43785. return s.isVisible() ? s : null
  43786. })
  43787. };
  43788. var adjustBarSeriesDimensions = function(translators) {
  43789. var debug = DX.utils.debug;
  43790. debug.assert(translators, "translator was not passed or empty");
  43791. var that = this,
  43792. equalBarWidth = that.equalBarWidth,
  43793. series = getVisibleSeries(that);
  43794. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, equalBarWidth, function(seriesIndex) {
  43795. return seriesIndex
  43796. })
  43797. };
  43798. var adjustStackedBarSeriesDimensions = function(translators) {
  43799. var debug = DX.utils.debug;
  43800. debug.assert(translators, "translators was not passed or empty");
  43801. var that = this,
  43802. interval,
  43803. series = getVisibleSeries(that),
  43804. stackIndexes = {},
  43805. stackCount = 0,
  43806. equalBarWidth = that.equalBarWidth;
  43807. $.each(series, function() {
  43808. var stackName = this.getStackName();
  43809. if (!stackIndexes.hasOwnProperty(stackName))
  43810. stackIndexes[stackName] = stackCount++
  43811. });
  43812. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), stackCount, equalBarWidth, function(seriesIndex) {
  43813. return stackIndexes[series[seriesIndex].getStackName()]
  43814. })
  43815. };
  43816. var adjustStackedSeriesValues = function() {
  43817. var that = this,
  43818. series = getVisibleSeries(that),
  43819. stackKeepers = {
  43820. positive: {},
  43821. negative: {}
  43822. };
  43823. $.each(series, function(_, singleSeries) {
  43824. var points = singleSeries.getPoints();
  43825. $.each(points, function(index, point) {
  43826. var value = point.initialValue,
  43827. argument = point.argument,
  43828. stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  43829. valueType = value >= 0 ? "positive" : "negative",
  43830. currentStack;
  43831. stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  43832. currentStack = stackKeepers[valueType][stackName];
  43833. if (currentStack[argument.valueOf()]) {
  43834. points[index].correctValue(currentStack[argument.valueOf()]);
  43835. currentStack[argument.valueOf()] += value
  43836. }
  43837. else {
  43838. currentStack[argument.valueOf()] = value;
  43839. points[index].resetCorrection()
  43840. }
  43841. })
  43842. });
  43843. setPercentStackedValues(series, stackKeepers, that.fullStacked)
  43844. };
  43845. var setPercentStackedValues = function(series, stackKeepers, fullStacked) {
  43846. $.each(series, function(_, singleSeries) {
  43847. var points = singleSeries.getPoints();
  43848. $.each(points, function(index, point) {
  43849. var value = point.value,
  43850. stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  43851. valueType = value >= 0 ? "positive" : "negative",
  43852. currentStack;
  43853. stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  43854. currentStack = stackKeepers[valueType][stackName];
  43855. points[index].setPercentValue(currentStack[point.argument.valueOf()], fullStacked)
  43856. })
  43857. })
  43858. };
  43859. var getMinShownBusinessValue = function(that, translators, minBarSize) {
  43860. var rotated = that.rotated,
  43861. valTranslator = rotated ? translators.x : translators.y,
  43862. canvas = valTranslator.getCanvasVisibleArea();
  43863. if (minBarSize)
  43864. return _abs(valTranslator.untranslate(canvas.min) - valTranslator.untranslate(canvas.min + minBarSize))
  43865. };
  43866. var updateStackedSeriesValues = function(translators) {
  43867. var that = this,
  43868. series = getVisibleSeries(that),
  43869. stackKeepers = {
  43870. positive: {},
  43871. negative: {}
  43872. };
  43873. $.each(series, function(_, singleSeries) {
  43874. var points = singleSeries.getPoints(),
  43875. minBarSize = singleSeries.getOptions().minBarSize;
  43876. $.each(points, function(index, point) {
  43877. var value = point.value,
  43878. minValue = point.minValue,
  43879. argument = point.argument,
  43880. updateValue,
  43881. pointSize,
  43882. minShownBusinessValue,
  43883. stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  43884. valueType = value >= 0 ? "positive" : "negative",
  43885. currentStack;
  43886. minShownBusinessValue = getMinShownBusinessValue(that, translators, minBarSize);
  43887. currentStack = stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  43888. if (currentStack[argument.valueOf()]) {
  43889. minValue = utils.isNumber(minValue) ? minValue : 0,
  43890. pointSize = _abs(minValue - value);
  43891. if (minShownBusinessValue && pointSize < minShownBusinessValue)
  43892. updateValue = minShownBusinessValue;
  43893. else
  43894. updateValue = value - minValue;
  43895. points[index].minValue = currentStack[argument.valueOf()];
  43896. points[index].value = currentStack[argument.valueOf()] + updateValue;
  43897. currentStack[argument.valueOf()] += updateValue
  43898. }
  43899. else {
  43900. pointSize = value;
  43901. if (minShownBusinessValue && pointSize < minShownBusinessValue)
  43902. updateValue = minShownBusinessValue;
  43903. else
  43904. updateValue = value;
  43905. points[index].value = updateValue;
  43906. currentStack[argument.valueOf()] = updateValue
  43907. }
  43908. })
  43909. });
  43910. if (that.fullStacked)
  43911. updateFullStackedSeriesValues(series, stackKeepers)
  43912. };
  43913. var updateFullStackedSeriesValues = function(series, stackKeepers) {
  43914. $.each(series, function(_, singleSeries) {
  43915. var stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  43916. points = singleSeries.getPoints();
  43917. $.each(points, function(index, point) {
  43918. var value = point.value,
  43919. argument = point.argument,
  43920. valueType = value >= 0 ? "positive" : "negative",
  43921. currentStack;
  43922. stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  43923. currentStack = stackKeepers[valueType][stackName];
  43924. points[index].value = points[index].value / currentStack[argument.valueOf()] || 0;
  43925. if (DX.utils.isNumber(points[index].minValue))
  43926. points[index].minValue = points[index].minValue / currentStack[argument.valueOf()] || 0
  43927. })
  43928. })
  43929. };
  43930. var updateBarSeriesValues = function(translators) {
  43931. var that = this;
  43932. $.each(that.series, function(_, singleSeries) {
  43933. var points = singleSeries.getPoints(),
  43934. minBarSize = singleSeries.getOptions().minBarSize;
  43935. $.each(points, function(index, point) {
  43936. var value = point.value,
  43937. updateValue,
  43938. pointSize,
  43939. minShownBusinessValue;
  43940. minShownBusinessValue = getMinShownBusinessValue(that, translators, minBarSize);
  43941. pointSize = _abs(value);
  43942. if (minShownBusinessValue && pointSize < minShownBusinessValue)
  43943. updateValue = value >= 0 ? minShownBusinessValue : -minShownBusinessValue;
  43944. else
  43945. updateValue = value;
  43946. points[index].value = updateValue
  43947. })
  43948. })
  43949. };
  43950. var adjustCandlestickSeriesDimensions = function(translators) {
  43951. var debug = DX.utils.debug;
  43952. debug.assert(translators, "translator was not passed or empty");
  43953. var that = this,
  43954. series = getVisibleSeries(that);
  43955. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, true, function(seriesIndex) {
  43956. return seriesIndex
  43957. })
  43958. };
  43959. var getInterval = function(that, translators) {
  43960. var argTranslator = !that.rotated ? translators.x : translators.y;
  43961. return that.interval = argTranslator.getInterval()
  43962. };
  43963. var adjustBubbleSeriesDimensions = function(translators) {
  43964. var debug = DX.utils.debug;
  43965. debug.assert(translators, "translator was not passed or empty");
  43966. var that = this,
  43967. series = getVisibleSeries(that),
  43968. points,
  43969. i,
  43970. visibleAreaX = translators.x.getCanvasVisibleArea(),
  43971. visibleAreaY = translators.y.getCanvasVisibleArea(),
  43972. min = Math.min(visibleAreaX.max - visibleAreaX.min, visibleAreaY.max - visibleAreaY.min),
  43973. minBubbleArea = _pow(that.minBubbleSize, 2),
  43974. maxBubbleArea = _pow(min * that.maxBubbleSize, 2),
  43975. equalBubbleSize = (min * that.maxBubbleSize + that.minBubbleSize) / 2,
  43976. minPointSize = Infinity,
  43977. maxPointSize = 0,
  43978. pointSize,
  43979. bubbleArea,
  43980. sizeProportion,
  43981. sizeDispersion,
  43982. areaDispersion;
  43983. for (i = 0; i < series.length; i++) {
  43984. points = series[i].getPoints();
  43985. $.each(points, function(_, point) {
  43986. maxPointSize = maxPointSize > point.size ? maxPointSize : point.size;
  43987. minPointSize = minPointSize < point.size ? minPointSize : point.size
  43988. })
  43989. }
  43990. sizeDispersion = maxPointSize - minPointSize;
  43991. areaDispersion = _abs(maxBubbleArea - minBubbleArea);
  43992. minPointSize = minPointSize < 0 ? 0 : minPointSize;
  43993. for (i = 0; i < series.length; i++) {
  43994. points = series[i].getPoints();
  43995. $.each(points, function(_, point) {
  43996. if (maxPointSize === minPointSize)
  43997. pointSize = _round(equalBubbleSize);
  43998. else {
  43999. sizeProportion = _abs(point.size - minPointSize) / sizeDispersion;
  44000. bubbleArea = areaDispersion * sizeProportion + minBubbleArea;
  44001. pointSize = _round(Math.sqrt(bubbleArea))
  44002. }
  44003. point.correctCoordinates(pointSize)
  44004. })
  44005. }
  44006. };
  44007. return {
  44008. ctor: ctor,
  44009. dispose: dispose,
  44010. add: add
  44011. }
  44012. }())
  44013. })(jQuery, DevExpress);
  44014. /*! Module viz-core, file baseSeries.js */
  44015. (function($, DX) {
  44016. var viz = DX.viz,
  44017. utils = DX.utils,
  44018. _isDefined = utils.isDefined,
  44019. _each = $.each,
  44020. _extend = $.extend,
  44021. _isEmptyObject = $.isEmptyObject,
  44022. _Event = $.Event,
  44023. _noop = $.noop,
  44024. SELECTED_STATE = 2,
  44025. HOVER_STATE = 1,
  44026. NONE_MODE = "none",
  44027. INCLUDE_POINTS = "includepoints",
  44028. EXLUDE_POINTS = "excludepoints",
  44029. ALL_SERIES_POINTS_MODE = "allseriespoints",
  44030. APPLY_SELECTED = "applySelected",
  44031. APPLY_HOVER = "applyHover",
  44032. getEmptyBusinessRange = function() {
  44033. return {
  44034. arg: {},
  44035. val: {}
  44036. }
  44037. };
  44038. viz.core.series.mixins = {
  44039. chart: {},
  44040. pieChart: {}
  44041. };
  44042. viz.core.series.Series = DX.Class.inherit({
  44043. ctor: function(renderer, options) {
  44044. this.fullState = 0;
  44045. this._renderer = renderer;
  44046. this._group = renderer.createGroup({"class": "dxc-series"});
  44047. this.updateOptions(options)
  44048. },
  44049. update: function(data, options) {
  44050. this.updateOptions(options);
  44051. this.updateData(data)
  44052. },
  44053. _createLegendState: function(styleOptions, defaultColor) {
  44054. return {
  44055. fill: styleOptions.color || defaultColor,
  44056. hatching: styleOptions.hatching
  44057. }
  44058. },
  44059. getLegendStyles: function() {
  44060. return this._styles.legendStyles
  44061. },
  44062. _createStyles: function(options) {
  44063. var mainSeriesColor = options.mainSeriesColor,
  44064. specialMainColor = this._getSpecialColor(mainSeriesColor);
  44065. this._styles = {
  44066. normal: this._parseStyle(options, mainSeriesColor, mainSeriesColor),
  44067. hover: this._parseStyle(options.hoverStyle || {}, specialMainColor, mainSeriesColor),
  44068. selection: this._parseStyle(options.selectionStyle || {}, specialMainColor, mainSeriesColor),
  44069. legendStyles: {
  44070. normal: this._createLegendState(options, mainSeriesColor),
  44071. hover: this._createLegendState(options.hoverStyle || {}, specialMainColor),
  44072. selection: this._createLegendState(options.selectionStyle || {}, specialMainColor)
  44073. }
  44074. }
  44075. },
  44076. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  44077. _each(this._points || [], function(_, point) {
  44078. point.setAdjustSeriesLabels(adjustSeriesLabels)
  44079. })
  44080. },
  44081. setClippingParams: function(id, forceClipping) {
  44082. this._paneClipRectID = id;
  44083. this._forceClipping = forceClipping
  44084. },
  44085. getTagField: function() {
  44086. return this._options.tagField || "tag"
  44087. },
  44088. getValueFields: _noop,
  44089. getArgumentField: _noop,
  44090. getPoints: function() {
  44091. return this._points
  44092. },
  44093. _createPoint: function(data, pointsArray, index) {
  44094. data.index = index;
  44095. if (this._checkData(data)) {
  44096. var point = pointsArray[index],
  44097. options = this._customizePoint(data) || this._getCreatingPointOptions();
  44098. if (point)
  44099. point.update(data, options);
  44100. else {
  44101. point = viz.core.CoreFactory.createPoint(data, options);
  44102. pointsArray.push(point)
  44103. }
  44104. this.pointsByArgument[point.argument.valueOf()] = this.pointsByArgument[point.argument.valueOf()] || point;
  44105. return true
  44106. }
  44107. },
  44108. getRangeData: function(zoomArgs, calcIntervalFunction) {
  44109. return this._visible ? _extend(true, {}, this._getRangeData(zoomArgs, calcIntervalFunction)) : getEmptyBusinessRange()
  44110. },
  44111. _deleteElementsGroup: function() {
  44112. if (this._elementsGroup) {
  44113. this._elementsGroup.detach();
  44114. this._elementsGroup = null
  44115. }
  44116. },
  44117. _deleteBordersGroup: function() {
  44118. if (this._bordersGroup) {
  44119. this._bordersGroup.detach();
  44120. this._bordersGroup = null
  44121. }
  44122. },
  44123. _saveOldAnimationMethods: function() {
  44124. this._oldClearingAnimation = this._clearingAnimation;
  44125. this._oldUpdateElement = this._updateElement
  44126. },
  44127. _deleteOldAnimationMethods: function() {
  44128. this._oldClearingAnimation = null;
  44129. this._oldUpdateElement = null
  44130. },
  44131. updateOptions: function(newOptions) {
  44132. var that = this,
  44133. widgetType = newOptions.widgetType,
  44134. oldType = that.type,
  44135. newType = newOptions.type;
  44136. that.type = newType && newType.toString().toLowerCase();
  44137. if (!that._checkType(widgetType)) {
  44138. that.dispose();
  44139. that.isUpdated = false;
  44140. return
  44141. }
  44142. if (oldType !== that.type) {
  44143. that._firstDrawing = true;
  44144. that._saveOldAnimationMethods();
  44145. that._resetType(oldType, widgetType);
  44146. that._setType(that.type, widgetType)
  44147. }
  44148. that._options = newOptions;
  44149. that._pointOptions = null;
  44150. that._deletePatterns();
  44151. that._patterns = [];
  44152. that.name = newOptions.name;
  44153. that.pane = newOptions.pane;
  44154. that.axis = newOptions.axis;
  44155. that.tag = newOptions.tag;
  44156. that._createStyles(newOptions);
  44157. that._updateOptions(newOptions);
  44158. that._visible = newOptions.visible;
  44159. that.isUpdated = true
  44160. },
  44161. _disposePoints: function(points) {
  44162. $.each(points || [], function(_, p) {
  44163. p.dispose()
  44164. })
  44165. },
  44166. _correctPointsLength: function(length, points) {
  44167. this._disposePoints(this._oldPoints);
  44168. this._oldPoints = points.splice(length, points.length)
  44169. },
  44170. _getTicksForAggregation: function(min, max, screenDelta, pointSize) {
  44171. return viz.core.tickProvider.getTicks({
  44172. min: min,
  44173. max: max,
  44174. screenDelta: screenDelta,
  44175. gridSpacingFactor: pointSize
  44176. })
  44177. },
  44178. updateDataType: function(settings) {
  44179. var that = this;
  44180. that.argumentType = settings.argumentType;
  44181. that.valueType = settings.valueType;
  44182. that.argumentAxisType = settings.argumentAxisType;
  44183. that.valueAxisType = settings.valueAxisType
  44184. },
  44185. getValueCategories: function() {
  44186. return this._options.valueCategories || []
  44187. },
  44188. getOptions: function() {
  44189. return this._options
  44190. },
  44191. getArgumentCategories: function() {
  44192. return this._options.argumentCategories || []
  44193. },
  44194. updateData: function(data) {
  44195. var that = this,
  44196. points,
  44197. lastPointIndex = 0,
  44198. options = that._options,
  44199. pointData;
  44200. that.pointsByArgument = {};
  44201. points = that._originalPoints || [];
  44202. that._rangeData = getEmptyBusinessRange();
  44203. if (data && data.length)
  44204. that._canRenderCompleteHandle = true;
  44205. that._beginUpdateData();
  44206. _each(data, function(index, dataItem) {
  44207. pointData = that._getPointData(dataItem, options);
  44208. if (that._createPoint(pointData, points, lastPointIndex)) {
  44209. that._processRange(points[lastPointIndex], lastPointIndex > 0 ? points[lastPointIndex - 1] : null);
  44210. lastPointIndex++
  44211. }
  44212. });
  44213. that._points = that._originalPoints = points;
  44214. that._correctPointsLength(lastPointIndex, points);
  44215. that._endUpdateData()
  44216. },
  44217. getTeamplatedFields: function() {
  44218. var that = this,
  44219. fields = that.getValueFields(),
  44220. teampleteFields = [];
  44221. fields.push(that.getTagField());
  44222. _each(fields, function(_, field) {
  44223. var fieldsObject = {};
  44224. fieldsObject.teamplateField = field + that.name;
  44225. fieldsObject.originalField = field;
  44226. teampleteFields.push(fieldsObject)
  44227. });
  44228. return teampleteFields
  44229. },
  44230. resamplePoints: function(translators, min, max) {
  44231. var that = this,
  44232. originalPoints = that.getAllPoints(),
  44233. argTranslator = that._options.rotated ? translators.y : translators.x,
  44234. minI,
  44235. maxI,
  44236. sizePoint,
  44237. ticks;
  44238. if (originalPoints.length) {
  44239. _each(originalPoints, function(i, point) {
  44240. minI = point.argument - min <= 0 ? i : minI;
  44241. if (!maxI)
  44242. maxI = point.argument - max > 0 ? i : null
  44243. });
  44244. minI = minI ? minI : 1;
  44245. maxI = utils.isDefined(maxI) ? maxI : originalPoints.length - 1;
  44246. min = originalPoints[minI - 1].argument;
  44247. max = originalPoints[maxI].argument;
  44248. sizePoint = that._getPointSize();
  44249. if (that.argumentAxisType !== "discrete" && that.valueAxisType !== "discrete")
  44250. ticks = that._getTicksForAggregation(min, max, argTranslator.canvasLength, sizePoint);
  44251. else
  44252. ticks = argTranslator.canvasLength / sizePoint;
  44253. that._points = that._resample(ticks, ticks.tickInterval)
  44254. }
  44255. },
  44256. _removeOldSegments: function(startIndex) {
  44257. var that = this;
  44258. _each(that._graphics.splice(startIndex, that._graphics.length) || [], function(_, elem) {
  44259. that._removeElement(elem)
  44260. });
  44261. if (that._trackers)
  44262. _each(that._trackers.splice(startIndex, that._trackers.length) || [], function(_, elem) {
  44263. elem.remove()
  44264. })
  44265. },
  44266. draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
  44267. var that = this;
  44268. if (that._oldClearingAnimation && animationEnabled && that._firstDrawing) {
  44269. var drawComplete = function() {
  44270. that._draw(translators, true, hideLayoutLabels)
  44271. };
  44272. that._oldClearingAnimation(translators, drawComplete)
  44273. }
  44274. else
  44275. that._draw(translators, animationEnabled, hideLayoutLabels, legendCallback)
  44276. },
  44277. _clearSeries: function() {
  44278. this._deleteElementsGroup();
  44279. this._deleteBordersGroup();
  44280. this._deleteTrackers();
  44281. this._graphics = [];
  44282. this._trackers = []
  44283. },
  44284. _draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
  44285. var that = this,
  44286. points = that._points || [],
  44287. segment = [],
  44288. segmentCount = 0,
  44289. firstDrawing = that._firstDrawing,
  44290. markersGroup,
  44291. labelsGroup;
  44292. that._graphics = that._graphics || [],
  44293. that._graphics = that._graphics || [];
  44294. that._prepareSeriesToDrawing();
  44295. if (!that._visible) {
  44296. animationEnabled = false;
  44297. this._group.detach();
  44298. return
  44299. }
  44300. else
  44301. that._group.append(that._options.seriesGroup);
  44302. that.translators = translators;
  44303. that._createGroups(animationEnabled, undefined, firstDrawing);
  44304. that._segments = [];
  44305. markersGroup = that._markersGroup;
  44306. labelsGroup = that._labelsGroup;
  44307. that._drawedPoints = [];
  44308. that._firstDrawing = points.length ? false : true;
  44309. _each(this._patterns || [], function(_, pattern) {
  44310. pattern.append()
  44311. });
  44312. _each(points, function(i, p) {
  44313. p.translate(translators);
  44314. if (p.hasValue()) {
  44315. that._drawPoint(p, markersGroup, labelsGroup, animationEnabled, firstDrawing);
  44316. segment.push(p)
  44317. }
  44318. else if (segment.length) {
  44319. that._drawSegment(segment, animationEnabled, segmentCount++);
  44320. segment = []
  44321. }
  44322. });
  44323. segment.length && that._drawSegment(segment, animationEnabled, segmentCount++);
  44324. that._removeOldSegments(segmentCount);
  44325. that._defaultSegments = that._generateDefaultSegments();
  44326. that._adjustLabels(firstDrawing);
  44327. hideLayoutLabels && that.hideLabels();
  44328. animationEnabled && that._animate(firstDrawing);
  44329. if (that.isSelected())
  44330. that._changeStyle(legendCallback, APPLY_SELECTED);
  44331. else if (this.isHovered())
  44332. this._changeStyle(legendCallback, APPLY_HOVER)
  44333. },
  44334. drawTrackers: function() {
  44335. var that = this,
  44336. trackers = that._trackers = that._trackers || [],
  44337. trackersGroup = that._trackersGroup = that._trackersGroup || that._renderer.createGroup(),
  44338. markerTrackerGroup = that._markerTrackerGroup = that._markerTrackerGroup || that._renderer.createGroup();
  44339. if (!that.isVisible()) {
  44340. trackersGroup.detach();
  44341. markerTrackerGroup.detach();
  44342. return
  44343. }
  44344. else {
  44345. trackersGroup.append(that._options.trackersGroup);
  44346. markerTrackerGroup.append(that._options.markerTrackerGroup)
  44347. }
  44348. _each(that._segments || [], function(i, segment) {
  44349. if (!trackers[i]) {
  44350. trackers[i] = that._drawTrackerElement(segment).append(trackersGroup);
  44351. trackers[i].data({series: that})
  44352. }
  44353. else
  44354. that._updateTrackerElement(segment, trackers[i])
  44355. });
  44356. _each(that.getVisiblePoints(), function(_, p) {
  44357. p.drawTracker(that._renderer, markerTrackerGroup)
  44358. });
  44359. that._applyTrackersClippings()
  44360. },
  44361. _checkType: function(widgetType) {
  44362. return !!viz.core.series.mixins[widgetType][this.type]
  44363. },
  44364. _resetType: function(seriesType, widgetType) {
  44365. var that = this;
  44366. if (seriesType)
  44367. _each(viz.core.series.mixins[widgetType][seriesType], function(methodName) {
  44368. delete that[methodName]
  44369. })
  44370. },
  44371. _setType: function(seriesType, widgetType) {
  44372. var that = this;
  44373. _each(viz.core.series.mixins[widgetType][seriesType], function(methodName, method) {
  44374. that[methodName] = method
  44375. })
  44376. },
  44377. _setSelectedState: function(state, mode, legendCallback) {
  44378. this.lastSelectionMode = mode = (mode || this._options.selectionMode).toLowerCase();
  44379. if (state && !this.isSelected()) {
  44380. this.fullState = this.fullState | SELECTED_STATE;
  44381. this._changeStyle(legendCallback, APPLY_SELECTED)
  44382. }
  44383. else if (!state && this.isSelected()) {
  44384. this.fullState = this.fullState & ~SELECTED_STATE;
  44385. if (this.isHovered())
  44386. this._changeStyle(legendCallback, APPLY_HOVER);
  44387. else
  44388. this._changeStyle(legendCallback, "resetItem")
  44389. }
  44390. },
  44391. _setHoverState: function(state, mode, legendCallback) {
  44392. this.lastHoverMode = mode = (mode || this._options.hoverMode).toLowerCase();
  44393. if (state && !this.isHovered()) {
  44394. this.fullState = this.fullState | HOVER_STATE;
  44395. !this.isSelected() && this._changeStyle(legendCallback, APPLY_HOVER)
  44396. }
  44397. else if (!state && this.isHovered()) {
  44398. this.fullState = this.fullState & ~HOVER_STATE;
  44399. !this.isSelected() && this._changeStyle(legendCallback, "resetItem")
  44400. }
  44401. },
  44402. setHoverState: function(mode, legendCallback) {
  44403. this._setHoverState(true, mode, legendCallback)
  44404. },
  44405. releaseHoverState: function(mode, legendCallback) {
  44406. this._setHoverState(false, mode, legendCallback)
  44407. },
  44408. setSelectedState: function(mode, legendCallback) {
  44409. this._setSelectedState(true, mode, legendCallback)
  44410. },
  44411. releaseSelectedState: function(mode, legendCallback) {
  44412. this._setSelectedState(false, mode, legendCallback)
  44413. },
  44414. isFullStackedSeries: function() {
  44415. return this.type.indexOf("fullstacked") === 0
  44416. },
  44417. isStackedSeries: function() {
  44418. return this.type.indexOf("stacked") === 0
  44419. },
  44420. isFinancialSeries: function() {
  44421. return this.type === "stock" || this.type === "candlestick"
  44422. },
  44423. _changeStyle: function(legendCallBack, legendAction) {
  44424. var style = this._calcStyle(),
  44425. pointStyle;
  44426. if (style.mode === NONE_MODE)
  44427. return;
  44428. legendCallBack && legendCallBack(legendAction);
  44429. if (style.mode === INCLUDE_POINTS || style.mode === ALL_SERIES_POINTS_MODE) {
  44430. pointStyle = style.pointStyle;
  44431. _each(this._points || [], function(_, p) {
  44432. !p.isSelected() && p.applyStyle(pointStyle)
  44433. })
  44434. }
  44435. this._applyStyle(style.series)
  44436. },
  44437. _calcStyle: function() {
  44438. var styles = this._styles,
  44439. isHoverIncludeModeAndSeriesExcludeMode = false,
  44440. result;
  44441. switch (this.fullState & 3) {
  44442. case 0:
  44443. result = {
  44444. pointStyle: "normal",
  44445. mode: INCLUDE_POINTS,
  44446. series: styles.normal
  44447. };
  44448. break;
  44449. case 1:
  44450. result = {
  44451. pointStyle: "hover",
  44452. mode: this.lastHoverMode,
  44453. series: styles.hover
  44454. };
  44455. break;
  44456. case 2:
  44457. result = {
  44458. pointStyle: "selection",
  44459. mode: this.lastSelectionMode,
  44460. series: styles.selection
  44461. };
  44462. break;
  44463. case 3:
  44464. isHoverIncludeModeAndSeriesExcludeMode = this.lastSelectionMode === EXLUDE_POINTS && (this.lastHoverMode === INCLUDE_POINTS || this.lastHoverMode === ALL_SERIES_POINTS_MODE);
  44465. result = {
  44466. pointStyle: isHoverIncludeModeAndSeriesExcludeMode ? "normal" : "selection",
  44467. mode: isHoverIncludeModeAndSeriesExcludeMode ? INCLUDE_POINTS : this.lastSelectionMode,
  44468. series: styles.selection
  44469. }
  44470. }
  44471. return result
  44472. },
  44473. _getMainAxisName: function() {
  44474. return this._options.rotated ? "X" : "Y"
  44475. },
  44476. areLabelsVisible: function() {
  44477. return !_isDefined(this._options.maxLabelCount) || this._points.length <= this._options.maxLabelCount
  44478. },
  44479. getLabelVisibility: function() {
  44480. return this.areLabelsVisible() && this._options.label && this._options.label.visible
  44481. },
  44482. _customizePoint: function(pointData) {
  44483. var that = this,
  44484. options = that._options,
  44485. customizePoint = that._options.customizePoint,
  44486. customizeObject,
  44487. pointOptions,
  44488. customLabelOptions,
  44489. customOptions,
  44490. customizeLabel = that._options.customizeLabel,
  44491. useLabelCustomOptions,
  44492. usePointCustomOptions;
  44493. if (customizeLabel && customizeLabel.call) {
  44494. customizeObject = _extend({
  44495. seriesName: that.name,
  44496. series: that
  44497. }, pointData);
  44498. customLabelOptions = customizeLabel.call(customizeObject, customizeObject);
  44499. useLabelCustomOptions = customLabelOptions && !_isEmptyObject(customLabelOptions);
  44500. customLabelOptions = useLabelCustomOptions ? _extend(true, {}, options.label, customLabelOptions) : null
  44501. }
  44502. if (customizePoint && customizePoint.call) {
  44503. customizeObject = customizeObject || _extend({
  44504. seriesName: that.name,
  44505. series: that
  44506. }, pointData);
  44507. customOptions = customizePoint.call(customizeObject, customizeObject);
  44508. usePointCustomOptions = customOptions && !_isEmptyObject(customOptions)
  44509. }
  44510. if (useLabelCustomOptions || usePointCustomOptions) {
  44511. pointOptions = that._parsePointOptions(that._preparePointOptions(customOptions), customLabelOptions || options.label);
  44512. pointOptions.styles.useLabelCustomOptions = useLabelCustomOptions;
  44513. pointOptions.styles.usePointCustomOptions = usePointCustomOptions
  44514. }
  44515. return pointOptions
  44516. },
  44517. _getLabelOptions: function(labelOptions, defaultColor) {
  44518. var opt = labelOptions || {},
  44519. labelFont = opt.font || {},
  44520. labelBorder = opt.border || {},
  44521. labelConnector = opt.connector || {},
  44522. labelAttributes = {
  44523. align: opt.alignment,
  44524. font: {
  44525. color: opt.backgroundColor === "none" && labelFont.color.toLowerCase() === "#ffffff" && opt.position !== "inside" ? defaultColor : labelFont.color,
  44526. family: labelFont.family,
  44527. weight: labelFont.weight,
  44528. size: labelFont.size,
  44529. opacity: labelFont.opacity
  44530. },
  44531. style: opt.style
  44532. },
  44533. backgroundAttr = {
  44534. fill: opt.backgroundColor || defaultColor,
  44535. strokeWidth: labelBorder.visible ? labelBorder.width || 0 : 0,
  44536. stroke: labelBorder.visible && labelBorder.width ? labelBorder.color : "none",
  44537. dashStyle: labelBorder.dashStyle
  44538. },
  44539. connectorAttr = {
  44540. stroke: labelConnector.visible && labelConnector.width ? labelConnector.color || defaultColor : "none",
  44541. strokeWidth: labelConnector.visible ? labelConnector.width || 0 : 0
  44542. };
  44543. return {
  44544. format: opt.format,
  44545. argumentFormat: opt.argumentFormat,
  44546. precision: opt.precision,
  44547. argumentPrecision: opt.argumentPrecision,
  44548. percentPrecision: opt.percentPrecision,
  44549. customizeText: $.isFunction(opt.customizeText) ? opt.customizeText : undefined,
  44550. attributes: labelAttributes,
  44551. visible: labelFont.size !== 0 ? opt.visible : false,
  44552. showForZeroValues: opt.showForZeroValues,
  44553. horizontalOffset: opt.horizontalOffset,
  44554. verticalOffset: opt.verticalOffset,
  44555. radialOffset: opt.radialOffset,
  44556. background: backgroundAttr,
  44557. position: opt.position,
  44558. connector: connectorAttr,
  44559. rotationAngle: opt.rotationAngle,
  44560. resolveLabelsOverlapping: this._options.resolveLabelsOverlapping
  44561. }
  44562. },
  44563. show: function() {
  44564. if (!this._visible) {
  44565. this._visible = true;
  44566. this.hidePointTooltip();
  44567. this._options.visibilityChanged()
  44568. }
  44569. },
  44570. hide: function() {
  44571. if (this._visible) {
  44572. this._visible = false;
  44573. this.hidePointTooltip();
  44574. this._options.visibilityChanged()
  44575. }
  44576. },
  44577. hideLabels: function() {
  44578. _each(this._points, function(_, point) {
  44579. point._label.hide()
  44580. })
  44581. },
  44582. _parsePointOptions: function(pointOptions, labelOptions) {
  44583. var options = this._options,
  44584. styles = this._createPointStyles(pointOptions),
  44585. parsedOptions;
  44586. parsedOptions = _extend(true, {}, pointOptions, {
  44587. type: options.type,
  44588. tag: this.tag,
  44589. rotated: options.rotated,
  44590. series: this,
  44591. styles: styles,
  44592. visibilityChanged: options.visibilityChanged
  44593. });
  44594. parsedOptions.label = this._getLabelOptions(labelOptions, styles.normal.fill);
  44595. return parsedOptions
  44596. },
  44597. _resample: function(ticks, ticksInterval) {
  44598. var that = this,
  44599. fusPoints = [],
  44600. arrayFusPoints,
  44601. nowIndexTicks = 0,
  44602. lastPointIndex = 0,
  44603. originalPoints = that.getAllPoints();
  44604. if (that.argumentAxisType === "discrete" || that.valueAxisType === "discrete") {
  44605. ticksInterval = originalPoints.length / ticks;
  44606. arrayFusPoints = $.map(originalPoints, function(point, index) {
  44607. if (Math.floor(nowIndexTicks) <= index) {
  44608. nowIndexTicks += ticksInterval;
  44609. return point
  44610. }
  44611. point.setInvisibility();
  44612. return null
  44613. });
  44614. return arrayFusPoints
  44615. }
  44616. that._aggregatedPoints = that._aggregatedPoints || [];
  44617. _each(originalPoints, function(_, point) {
  44618. switch (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval)) {
  44619. case true:
  44620. fusPoints.push(point);
  44621. break;
  44622. case"nextInterval":
  44623. var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
  44624. while (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === "nextInterval")
  44625. nowIndexTicks++;
  44626. fusPoints = [];
  44627. that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === true && fusPoints.push(point);
  44628. if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
  44629. lastPointIndex++
  44630. }
  44631. });
  44632. if (fusPoints.length) {
  44633. var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
  44634. if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
  44635. lastPointIndex++
  44636. }
  44637. that._correctPointsLength(lastPointIndex, that._aggregatedPoints);
  44638. that._endUpdateData();
  44639. return that._aggregatedPoints
  44640. },
  44641. _isInInterval: function(argument, ticks, nowIndexTicks, ticksInterval) {
  44642. var minTick = ticks[nowIndexTicks],
  44643. maxTick = ticks[nowIndexTicks + 1],
  44644. sumMinTickTicksInterval;
  44645. ticksInterval = $.isNumeric(ticksInterval) ? ticksInterval : utils.convertDateTickIntervalToMilliseconds(ticksInterval);
  44646. sumMinTickTicksInterval = utils.isDate(minTick) ? new Date(minTick.getTime() + ticksInterval) : minTick + ticksInterval;
  44647. if (argument >= minTick && argument < sumMinTickTicksInterval)
  44648. return true;
  44649. if (argument < minTick || maxTick === undefined)
  44650. return false;
  44651. return "nextInterval"
  44652. },
  44653. canRenderCompleteHandle: function() {
  44654. var result = this._canRenderCompleteHandle;
  44655. delete this._canRenderCompleteHandle;
  44656. return !!result
  44657. },
  44658. isHovered: function() {
  44659. return !!(this.fullState & 1)
  44660. },
  44661. isSelected: function() {
  44662. return !!(this.fullState & 2)
  44663. },
  44664. isVisible: function() {
  44665. return this._visible
  44666. },
  44667. getAllPoints: function() {
  44668. return (this._originalPoints || []).slice()
  44669. },
  44670. getPointByPos: function(pos) {
  44671. return (this._points || [])[pos]
  44672. },
  44673. getVisiblePoints: function() {
  44674. return (this._drawedPoints || []).slice()
  44675. },
  44676. setPointHoverState: function(point, legendCallback) {
  44677. point.fullState = point.fullState | HOVER_STATE;
  44678. if (!(this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) && !point.isSelected()) {
  44679. point.applyStyle("hover");
  44680. legendCallback && legendCallback("applyHover")
  44681. }
  44682. },
  44683. releasePointHoverState: function(point, legendCallback) {
  44684. point.fullState = point.fullState & ~HOVER_STATE;
  44685. if (!(this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) && !point.isSelected())
  44686. if (!(this.isHovered() && (this.lastHoverMode === ALL_SERIES_POINTS_MODE || this.lastHoverMode === INCLUDE_POINTS))) {
  44687. point.applyStyle("normal");
  44688. legendCallback && legendCallback("resetItem")
  44689. }
  44690. },
  44691. setPointSelectedState: function(point, legendCallback) {
  44692. point.fullState = point.fullState | SELECTED_STATE;
  44693. point.applyStyle("selection");
  44694. legendCallback && legendCallback("applySelected")
  44695. },
  44696. releasePointSelectedState: function(point, legendCallback) {
  44697. point.fullState = point.fullState & ~SELECTED_STATE;
  44698. if (this.isHovered() && (this.lastHoverMode === ALL_SERIES_POINTS_MODE || this.lastHoverMode === INCLUDE_POINTS) || point.isHovered()) {
  44699. point.applyStyle("hover");
  44700. legendCallback && legendCallback("applyHover")
  44701. }
  44702. else if (this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) {
  44703. point.applyStyle("selection");
  44704. legendCallback && legendCallback("applySelected")
  44705. }
  44706. else {
  44707. point.applyStyle("normal");
  44708. legendCallback && legendCallback("resetItem")
  44709. }
  44710. },
  44711. selectPoint: function(point) {
  44712. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("selectpoint"), point)
  44713. },
  44714. deselectPoint: function(point) {
  44715. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("deselectpoint"), point)
  44716. },
  44717. showPointTooltip: function(point) {
  44718. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("showpointtooltip"), point)
  44719. },
  44720. hidePointTooltip: function(point) {
  44721. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("hidepointtooltip"), point)
  44722. },
  44723. select: function() {
  44724. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("selectseries", {target: this}), this._options.selectionMode);
  44725. this._group.toForeground();
  44726. this._trackersGroup && this._trackersGroup.toBackground()
  44727. },
  44728. clearSelection: function clearSelection() {
  44729. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("deselectseries", {target: this}), this._options.selectionMode)
  44730. },
  44731. getPointByArg: function(arg) {
  44732. return this.pointsByArgument[arg.valueOf()] || null
  44733. },
  44734. _deletePoints: function() {
  44735. this._disposePoints(this._originalPoints);
  44736. this._disposePoints(this._aggregatedPoints);
  44737. this._disposePoints(this._oldPoints);
  44738. this._points = null;
  44739. this._oldPoints = null;
  44740. this._aggregatedPoints = null;
  44741. this._originalPoints = null;
  44742. this._drawedPoint = null
  44743. },
  44744. _deletePatterns: function() {
  44745. _each(this._patterns || [], function(_, pattern) {
  44746. pattern && pattern.dispose()
  44747. });
  44748. this._patterns = null
  44749. },
  44750. _deleteTrackers: function() {
  44751. var that = this;
  44752. _each(that._trackers || [], function(_, tracker) {
  44753. tracker.remove()
  44754. });
  44755. that._trackersGroup && that._trackersGroup.detach();
  44756. that._markerTrackerGroup && that._markerTrackerGroup.detach();
  44757. that._trackers = that._trackersGroup = that._markerTrackerGroup = null
  44758. },
  44759. dispose: function() {
  44760. this._deletePoints();
  44761. this._group.detach();
  44762. this._labelsGroup && this._labelsGroup.detach();
  44763. this._deletePatterns();
  44764. this._deleteTrackers();
  44765. this._group = null;
  44766. this._markersGroup = null;
  44767. this._elementsGroup = null;
  44768. this._bordersGroup = null;
  44769. this._labelsGroup = null;
  44770. this._graphics = null;
  44771. this._rangeData = null;
  44772. this._renderer = null;
  44773. this.translators = null;
  44774. this._styles = null;
  44775. this._options = null;
  44776. this._pointOptions = null;
  44777. this._drawedPoints = null;
  44778. this._aggregatedPoints = null;
  44779. this.pointsByArgument = null;
  44780. this._segments = null
  44781. },
  44782. correctPosition: _noop,
  44783. getColor: function() {
  44784. return this.getLegendStyles().normal.fill
  44785. },
  44786. getStackName: function() {
  44787. return this.type === "stackedbar" || this.type === "fullstackedbar" ? this._stackName : null
  44788. }
  44789. })
  44790. })(jQuery, DevExpress);
  44791. /*! Module viz-core, file rangeDataCalculator.js */
  44792. (function($, DX) {
  44793. var _math = Math,
  44794. _abs = _math.abs,
  44795. _min = _math.min,
  44796. _each = $.each,
  44797. _isEmptyObject = $.isEmptyObject,
  44798. _isDefined = DevExpress.utils.isDefined,
  44799. FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY = 15,
  44800. BAR_ZERO_VALUE_MARGIN_PRIORITY = 20,
  44801. SERIES_VALUE_MARGIN_PRIORITY = 20,
  44802. SERIES_LABEL_VALUE_MARGIN = 0.3,
  44803. CATEGORIES_SELECTOR = "categories",
  44804. INTERVAL_SELECTOR = "interval",
  44805. MIN_VALUE_MARGIN_SELECTOR = "minValueMargin",
  44806. MAX_VALUE_MARGIN_SELECTOR = "maxValueMargin",
  44807. MIN = "min",
  44808. MAX = "max",
  44809. MIN_VISIBLE = "minVisible",
  44810. MAX_VISIBLE = "maxVisible";
  44811. DevExpress.viz.core.series.helpers.rangeDataCalculator = function() {
  44812. var _truncateValue = function(data, minField, maxField, value) {
  44813. var min = data[minField],
  44814. max = data[maxField];
  44815. data[minField] = value < min || !_isDefined(min) ? value : data[minField];
  44816. data[maxField] = value > max || !_isDefined(max) ? value : data[maxField]
  44817. };
  44818. var _processTwoValues = function(series, point, prevPoint, highValueName, lowValueName) {
  44819. var val = point[highValueName],
  44820. minVal = point[lowValueName],
  44821. arg = point.argument,
  44822. prevVal = prevPoint && prevPoint[highValueName],
  44823. prevMinVal = prevPoint && prevPoint[lowValueName],
  44824. prevArg = prevPoint && prevPoint.argument;
  44825. point.hasValue() && _processRangeValue(series, val, minVal, prevVal, prevMinVal);
  44826. _processValue(series, "arg", arg, prevArg)
  44827. };
  44828. var _processValue = function(series, type, value, prevValue, calcInterval) {
  44829. var axis = type === "arg" ? "argument" : "value",
  44830. data = series._rangeData[type],
  44831. minInterval = data[INTERVAL_SELECTOR],
  44832. interval;
  44833. if (series[axis + "AxisType"] === "discrete") {
  44834. data[CATEGORIES_SELECTOR] = data[CATEGORIES_SELECTOR] || [];
  44835. data[CATEGORIES_SELECTOR].push(value)
  44836. }
  44837. else {
  44838. _truncateValue(data, "min", "max", value);
  44839. if (type === "arg") {
  44840. interval = (_isDefined(prevValue) ? _abs(calcInterval ? calcInterval(value, prevValue) : value - prevValue) : interval) || minInterval;
  44841. data[INTERVAL_SELECTOR] = _isDefined(interval) && (interval < minInterval || !_isDefined(minInterval)) ? interval : minInterval
  44842. }
  44843. }
  44844. };
  44845. var _addToVisibleRange = function(series, value) {
  44846. var data = series._rangeData.val,
  44847. isDiscrete = series.valueAxisType === "discrete";
  44848. if (isDiscrete) {
  44849. data.visibleCategories = data.visibleCategories || [];
  44850. data.visibleCategories.push(value)
  44851. }
  44852. else {
  44853. if (value < data.minVisible || !_isDefined(data.minVisible))
  44854. data.minVisible = value;
  44855. if (value > data.maxVisible || !_isDefined(data.maxVisible))
  44856. data.maxVisible = value
  44857. }
  44858. };
  44859. var _processRangeValue = function(series, val, minVal, prevVal, prevMinVal) {
  44860. var data = series._rangeData.val,
  44861. interval,
  44862. currentInterval = data[INTERVAL_SELECTOR];
  44863. if (series.valueAxisType === "discrete") {
  44864. data.categories = data.categories || [];
  44865. data.categories.push(val, minVal)
  44866. }
  44867. else {
  44868. _truncateValue(data, MIN, MAX, val);
  44869. _truncateValue(data, MIN, MAX, minVal)
  44870. }
  44871. };
  44872. var _unique = function(array) {
  44873. var values = {};
  44874. return $.map(array, function(item) {
  44875. var result = !values[item] ? item : null;
  44876. values[item] = true;
  44877. return result
  44878. })
  44879. };
  44880. var _processZoomArgument = function(series, zoomArgs) {
  44881. var data = series._rangeData.arg,
  44882. minArg,
  44883. maxArg;
  44884. minArg = zoomArgs.minArg < zoomArgs.maxArg ? zoomArgs.minArg : zoomArgs.maxArg;
  44885. maxArg = zoomArgs.maxArg > zoomArgs.minArg ? zoomArgs.maxArg : zoomArgs.minArg;
  44886. data.min = minArg < data.min ? minArg : data.min;
  44887. data.max = maxArg > data.max ? maxArg : data.max;
  44888. data.minVisible = minArg;
  44889. data.maxVisible = maxArg
  44890. };
  44891. var _correctZoomValue = function(series, zoomArgs) {
  44892. var minVal,
  44893. maxVal;
  44894. if (_isDefined(zoomArgs.minVal) && _isDefined(zoomArgs.maxVal)) {
  44895. minVal = zoomArgs.minVal < zoomArgs.maxVal ? zoomArgs.minVal : zoomArgs.maxVal;
  44896. maxVal = zoomArgs.maxVal > zoomArgs.minVal ? zoomArgs.maxVal : zoomArgs.minVal
  44897. }
  44898. if (_isDefined(zoomArgs.minVal)) {
  44899. series._rangeData.val.min = minVal < series._rangeData.val.min ? minVal : series._rangeData.val.min;
  44900. series._rangeData.val.minVisible = minVal
  44901. }
  44902. if (_isDefined(zoomArgs.maxVal)) {
  44903. series._rangeData.val.max = maxVal > series._rangeData.val.max ? maxVal : series._rangeData.val.max;
  44904. series._rangeData.val.maxVisible = maxVal
  44905. }
  44906. };
  44907. var _processZoomValue = function(series, zoomArgs) {
  44908. var adjustOnZoom = zoomArgs.adjustOnZoom,
  44909. points = series._points || [],
  44910. lastVisibleIndex,
  44911. prevPointAdded = false;
  44912. _each(points, function(index, point) {
  44913. var arg = point.argument,
  44914. prevPoint = index > 0 ? points[index - 1] : null;
  44915. if (adjustOnZoom && arg >= series._rangeData.arg.minVisible && arg <= series._rangeData.arg.maxVisible) {
  44916. if (!prevPointAdded) {
  44917. prevPoint && prevPoint.hasValue() && _addToVisibleRange(series, prevPoint.value);
  44918. prevPointAdded = true
  44919. }
  44920. point.hasValue() && _addToVisibleRange(series, point.value);
  44921. lastVisibleIndex = index
  44922. }
  44923. });
  44924. if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
  44925. _addToVisibleRange(series, points[lastVisibleIndex + 1].value);
  44926. _correctZoomValue(series, zoomArgs)
  44927. };
  44928. var _processZoomRangeValue = function(series, zoomArgs, maxValueName, minValueName) {
  44929. var adjustOnZoom = zoomArgs.adjustOnZoom,
  44930. points = series._points || [],
  44931. lastVisibleIndex,
  44932. prevPointAdded = false;
  44933. _each(points, function(index, point) {
  44934. var arg = point.argument,
  44935. prevPoint = index > 0 ? points[index - 1] : null;
  44936. if (adjustOnZoom && arg >= series._rangeData.arg.minVisible && arg <= series._rangeData.arg.maxVisible) {
  44937. if (!prevPointAdded) {
  44938. if (prevPoint && prevPoint.hasValue()) {
  44939. _addToVisibleRange(series, prevPoint[maxValueName]);
  44940. _addToVisibleRange(series, prevPoint[minValueName])
  44941. }
  44942. prevPointAdded = true
  44943. }
  44944. if (point.hasValue()) {
  44945. _addToVisibleRange(series, point[maxValueName]);
  44946. _addToVisibleRange(series, point[minValueName])
  44947. }
  44948. lastVisibleIndex = index
  44949. }
  44950. });
  44951. if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
  44952. _addToVisibleRange(series, points[lastVisibleIndex + 1].value);
  44953. _correctZoomValue(series, zoomArgs)
  44954. };
  44955. var _processNewInterval = function(series, calcInterval) {
  44956. var data = series._rangeData,
  44957. points = series._points || [],
  44958. isArgumentAxisDiscrete = series.argumentAxisType === "discrete";
  44959. delete data.arg.interval;
  44960. _each(points, function(index, point) {
  44961. var arg = point.argument,
  44962. prevPoint = index > 0 ? points[index - 1] : null,
  44963. prevArg = prevPoint && prevPoint.argument;
  44964. !isArgumentAxisDiscrete && _processValue(series, "arg", arg, prevArg, calcInterval)
  44965. })
  44966. };
  44967. var _fillRangeData = function(series) {
  44968. var data = series._rangeData,
  44969. mainAxis = series._getMainAxisName(),
  44970. axis = mainAxis === "X" ? "Y" : "X";
  44971. data.arg.categories && (data.arg.categories = _unique(data.arg.categories));
  44972. data.val.categories && (data.val.categories = _unique(data.val.categories));
  44973. data.arg.visibleCategories && (data.arg.visibleCategories = _unique(data.arg.visibleCategories));
  44974. data.val.visibleCategories && (data.val.visibleCategories = _unique(data.val.visibleCategories));
  44975. data.arg.axisType = series.argumentAxisType;
  44976. data.arg.dataType = series.argumentType;
  44977. data.val.axisType = series.valueAxisType;
  44978. data.val.dataType = series.valueType;
  44979. data.val.isValueRange = true
  44980. };
  44981. var _setPadding = function(range, prefix, val, priority) {
  44982. range[prefix] = val;
  44983. range[prefix + "Priority"] = priority
  44984. };
  44985. var _setZeroPadding = function(range, val, prefix) {
  44986. val === 0 && _setPadding(range, prefix, 0, BAR_ZERO_VALUE_MARGIN_PRIORITY)
  44987. };
  44988. var _calculateRangeMinValue = function(series, zoomArgs) {
  44989. var data = series._rangeData.val,
  44990. minVisible = data[MIN_VISIBLE],
  44991. maxVisible = data[MAX_VISIBLE];
  44992. zoomArgs = zoomArgs || {};
  44993. if (data) {
  44994. data.alwaysCorrectMin = true;
  44995. series._rangeData.arg.keepValueMargins = true;
  44996. if (series.valueAxisType !== "logarithmic" && series.valueType !== "datetime" && series.getOptions().showZero !== false) {
  44997. data[MIN_VISIBLE] = minVisible > (zoomArgs.minVal || 0) ? zoomArgs.minVal || 0 : minVisible;
  44998. data[MAX_VISIBLE] = maxVisible < (zoomArgs.maxVal || 0) ? zoomArgs.maxVal || 0 : maxVisible;
  44999. data[MIN] = data[MIN] > 0 ? 0 : data[MIN];
  45000. _setZeroPadding(data, data[MIN], MIN_VALUE_MARGIN_SELECTOR);
  45001. data[MAX] = data[MAX] < 0 ? 0 : data[MAX];
  45002. if (data[MAX] === 0 || data[MAX] > 0 && data[MIN] < 0) {
  45003. data[MIN_VALUE_MARGIN_SELECTOR] = data[MAX_VALUE_MARGIN_SELECTOR];
  45004. data[MIN_VALUE_MARGIN_SELECTOR + "Priority"] = data[MAX_VALUE_MARGIN_SELECTOR + "Priority"]
  45005. }
  45006. _setZeroPadding(data, data[MAX], MAX_VALUE_MARGIN_SELECTOR)
  45007. }
  45008. }
  45009. };
  45010. var _processFullStackedRange = function(series) {
  45011. var data = series._rangeData.val,
  45012. isRangeEmpty = _isEmptyObject(data);
  45013. _setPadding(data, "minValueMargin", 0, FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY);
  45014. _setPadding(data, "maxValueMargin", 0, FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY);
  45015. !isRangeEmpty && (data.min = 0)
  45016. };
  45017. var _processRange = function(series, point, prevPoint) {
  45018. var val = point.value,
  45019. arg = point.argument,
  45020. prevVal = prevPoint && prevPoint.value,
  45021. prevArg = prevPoint && prevPoint.argument;
  45022. point.hasValue() && _processValue(series, "val", val, prevVal);
  45023. _processValue(series, "arg", arg, prevArg)
  45024. };
  45025. var _addLabelPaddings = function(series) {
  45026. var labelOptions = series.getOptions().label;
  45027. if (series.areLabelsVisible() && labelOptions && labelOptions.visible && labelOptions.position !== "inside")
  45028. _setPadding(series._rangeData.val, "maxValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY)
  45029. };
  45030. var _addRangeSeriesLabelPaddings = function(series) {
  45031. var data = series._rangeData.val;
  45032. if (series.areLabelsVisible() && series._options.label.visible && series._options.label.position !== "inside") {
  45033. _setPadding(data, "maxValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY);
  45034. _setPadding(data, "minValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY)
  45035. }
  45036. };
  45037. var _calculateRangeData = function(series, zoomArgs, calcIntervalFunction) {
  45038. var valueData = series._rangeData.val;
  45039. if (series.argumentAxisType !== "discrete" && zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {
  45040. valueData[MIN_VISIBLE] = zoomArgs.minVal;
  45041. valueData[MAX_VISIBLE] = zoomArgs.maxVal;
  45042. _processZoomArgument(series, zoomArgs);
  45043. _processZoomValue(series, zoomArgs)
  45044. }
  45045. else if (!zoomArgs && calcIntervalFunction)
  45046. _processNewInterval(series, calcIntervalFunction);
  45047. _fillRangeData(series)
  45048. };
  45049. var _calculateTwoValuesRangeData = function(series, zoomArgs, calcIntervalFunction, maxValueName, minValueName) {
  45050. var valueData = series._rangeData.val;
  45051. if (series.argumentAxisType !== "discrete" && zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {
  45052. valueData[MIN_VISIBLE] = zoomArgs.minVal;
  45053. valueData[MAX_VISIBLE] = zoomArgs.maxVal;
  45054. _processZoomArgument(series, zoomArgs);
  45055. _processZoomRangeValue(series, zoomArgs, maxValueName, minValueName)
  45056. }
  45057. else if (!zoomArgs && calcIntervalFunction)
  45058. _processNewInterval(series);
  45059. _fillRangeData(series)
  45060. };
  45061. return {
  45062. processRange: _processRange,
  45063. calculateRangeData: _calculateRangeData,
  45064. calculateTwoValuesRangeData: _calculateTwoValuesRangeData,
  45065. addLabelPaddings: _addLabelPaddings,
  45066. addRangeSeriesLabelPaddings: _addRangeSeriesLabelPaddings,
  45067. processFullStackedRange: _processFullStackedRange,
  45068. calculateRangeMinValue: _calculateRangeMinValue,
  45069. processTwoValues: _processTwoValues
  45070. }
  45071. }
  45072. })(jQuery, DevExpress);
  45073. /*! Module viz-core, file scatterSeries.js */
  45074. (function($, DX) {
  45075. var viz = DX.viz,
  45076. series = viz.core.series,
  45077. rangeCalculator = series.helpers.rangeDataCalculator(),
  45078. _each = $.each,
  45079. _extend = $.extend,
  45080. _map = $.map,
  45081. _noop = $.noop,
  45082. _isDefined = DX.utils.isDefined,
  45083. _floor = Math.floor,
  45084. DEFAULT_SYMBOL_POINT_SIZE = 2,
  45085. DEFAULT_TRACKER_WIDTH = 20,
  45086. DEFAULT_DURATION = 400;
  45087. series.mixins.chart.scatter = {
  45088. _defaultDuration: DEFAULT_DURATION,
  45089. _defaultTrackerWidth: DEFAULT_TRACKER_WIDTH,
  45090. _applyStyle: _noop,
  45091. _adjustLabels: _noop,
  45092. _updateOptions: _noop,
  45093. _parseStyle: _noop,
  45094. _prepareSegment: _noop,
  45095. _drawSegment: _noop,
  45096. _generateDefaultSegments: _noop,
  45097. _prepareSeriesToDrawing: function() {
  45098. this._deleteOldAnimationMethods();
  45099. this._firstDrawing && this._clearSeries();
  45100. this._disposePoints(this._oldPoints);
  45101. this._oldPoints = null
  45102. },
  45103. _applyTrackersClippings: function() {
  45104. this._markerTrackerGroup.applySettings({clipId: this._forceClipping ? this._paneClipRectID : null})
  45105. },
  45106. updateTeamplateFieldNames: function() {
  45107. var that = this,
  45108. options = that._options;
  45109. options.valueField = that.getValueFields()[0] + that.name;
  45110. options.tagField = that.getTagField() + that.name
  45111. },
  45112. _applyElementsClipRect: function(settings) {
  45113. settings.clipId = this._paneClipRectID
  45114. },
  45115. _applyMarkerClipRect: function(settings) {
  45116. settings.clipId = this._forceClipping ? this._paneClipRectID : null
  45117. },
  45118. _createGroup: function(groupName, parent, target, settings) {
  45119. var group = parent[groupName];
  45120. if (!group)
  45121. parent[groupName] = group = this._renderer.createGroup(settings);
  45122. else
  45123. group.applySettings(settings);
  45124. group.append(target)
  45125. },
  45126. _applyClearingSettings: function(settings) {
  45127. settings.opacity = null;
  45128. settings.scale = null;
  45129. if (this._options.rotated)
  45130. settings.translateX = null;
  45131. else
  45132. settings.translateY = null
  45133. },
  45134. _createMarkerGroup: function() {
  45135. var settings = this._getPointOptions().styles.normal;
  45136. settings["class"] = "dxc-markers";
  45137. settings.opacity = 1;
  45138. this._applyMarkerClipRect(settings);
  45139. this._createGroup("_markersGroup", this, this._group, settings)
  45140. },
  45141. _createLabelGroup: function() {
  45142. var settings = {
  45143. "class": "dxc-labels",
  45144. visibility: this.getLabelVisibility() ? "visible" : "hidden"
  45145. };
  45146. this._applyElementsClipRect(settings);
  45147. this._applyClearingSettings(settings);
  45148. this._createGroup("_labelsGroup", this, this._options.labelsGroup, settings)
  45149. },
  45150. _createGroups: function(animationEnabled) {
  45151. this._createMarkerGroup();
  45152. this._createLabelGroup();
  45153. animationEnabled && this._labelsGroup && this._labelsGroup.applySettings({opacity: 0.001})
  45154. },
  45155. _getCreatingPointOptions: function() {
  45156. if (!this._predefinedPointOptions) {
  45157. var defaultPointOptions = this._getPointOptions(),
  45158. r = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.r,
  45159. strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
  45160. creatingPointOptions = _extend(true, {}, defaultPointOptions);
  45161. creatingPointOptions.styles = creatingPointOptions.styles || {};
  45162. creatingPointOptions.styles.normal = {
  45163. r: r,
  45164. strokeWidth: strokeWidth
  45165. };
  45166. this._predefinedPointOptions = creatingPointOptions
  45167. }
  45168. return this._predefinedPointOptions
  45169. },
  45170. _getSpecialColor: function(mainSeriesColor) {
  45171. return mainSeriesColor
  45172. },
  45173. _getPointOptions: function() {
  45174. return this._pointOptions || (this._pointOptions = this._parsePointOptions(this._preparePointOptions(), this._options.label))
  45175. },
  45176. _preparePointOptions: function(customOptions) {
  45177. return customOptions ? _extend(true, {}, this._options.point, customOptions) : this._options.point
  45178. },
  45179. _parsePointStyle: function(style, defaultColor, defaultBorderColor) {
  45180. var border = style.border || {};
  45181. return {
  45182. fill: style.color || defaultColor,
  45183. stroke: border.color || defaultBorderColor,
  45184. strokeWidth: border.visible ? border.width : 0,
  45185. r: style.size / 2 + (border.visible && style.size !== 0 ? ~~(border.width / 2) || 0 : 0)
  45186. }
  45187. },
  45188. _createPointStyles: function(pointOptions) {
  45189. var mainPointColor = pointOptions.color || this._options.mainSeriesColor,
  45190. containerColor = this._options.containerBackgroundColor,
  45191. normalStyle = this._parsePointStyle(pointOptions, mainPointColor, mainPointColor);
  45192. normalStyle.visibility = pointOptions.visible ? "visible" : "hidden";
  45193. return {
  45194. normal: normalStyle,
  45195. hover: this._parsePointStyle(pointOptions.hoverStyle, containerColor, mainPointColor),
  45196. selection: this._parsePointStyle(pointOptions.selectionStyle, containerColor, mainPointColor)
  45197. }
  45198. },
  45199. _checkData: function(data) {
  45200. return _isDefined(data.argument) && data.value !== undefined
  45201. },
  45202. _processRange: function(point, prevPoint) {
  45203. rangeCalculator.processRange(this, point, prevPoint)
  45204. },
  45205. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  45206. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  45207. rangeCalculator.addLabelPaddings(this);
  45208. return this._rangeData
  45209. },
  45210. _getPointData: function(data, options) {
  45211. var argumentField = options.argumentField || "arg",
  45212. valueField = options.valueField || "val",
  45213. tagField = options.tagField || "tag";
  45214. return {
  45215. value: data[valueField],
  45216. argument: data[argumentField],
  45217. tag: data[tagField]
  45218. }
  45219. },
  45220. _drawPoint: function(point, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
  45221. if (point.isInVisibleArea()) {
  45222. point.clearVisibility();
  45223. point.draw(this._renderer, markersGroup, labelsGroup, animationEnabled, firstDrawing);
  45224. this._drawedPoints.push(point)
  45225. }
  45226. else
  45227. point.setInvisibility()
  45228. },
  45229. _clearingAnimation: function(translators, drawComplete) {
  45230. var that = this,
  45231. params = {opacity: 0.001},
  45232. options = {
  45233. duration: that._defaultDuration,
  45234. partitionDuration: 0.5
  45235. };
  45236. that._labelsGroup && that._labelsGroup.animate(params, options, function() {
  45237. that._markersGroup && that._markersGroup.animate(params, options, drawComplete)
  45238. })
  45239. },
  45240. _animate: function(complete) {
  45241. var that = this,
  45242. lastPointIndex = that._drawedPoints.length - 1,
  45243. labelAnimFunc = function() {
  45244. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  45245. },
  45246. settings;
  45247. _each(that._drawedPoints || [], function(i, p) {
  45248. settings = {translate: {
  45249. x: p.x,
  45250. y: p.y
  45251. }};
  45252. p.animate(i === lastPointIndex ? labelAnimFunc : undefined, settings)
  45253. })
  45254. },
  45255. _getPointSize: function() {
  45256. return this._options.point.visible ? this._options.point.size : DEFAULT_SYMBOL_POINT_SIZE
  45257. },
  45258. _calcMedianValue: function(fusionPoints, valueField) {
  45259. var result,
  45260. allValue;
  45261. allValue = _map(fusionPoints, function(point) {
  45262. return point[valueField]
  45263. });
  45264. allValue.sort(function(a, b) {
  45265. return a - b
  45266. });
  45267. result = allValue[_floor(allValue.length / 2)];
  45268. return _isDefined(result) ? result : null
  45269. },
  45270. _fusionPoints: function(fusionPoints, tick, index) {
  45271. var result = this._calcMedianValue(fusionPoints, "value");
  45272. return {
  45273. value: result,
  45274. argument: tick,
  45275. tag: null,
  45276. index: index,
  45277. seriesName: this.name
  45278. }
  45279. },
  45280. _endUpdateData: function() {
  45281. delete this._predefinedPointOptions
  45282. },
  45283. getArgumentField: function() {
  45284. return this._options.argumentField || "arg"
  45285. },
  45286. getValueFields: function() {
  45287. return [this._options.valueField || "val"]
  45288. },
  45289. _beginUpdateData: $.noop
  45290. }
  45291. })(jQuery, DevExpress);
  45292. /*! Module viz-core, file lineSeries.js */
  45293. (function($, DX) {
  45294. var viz = DX.viz,
  45295. series = viz.core.series.mixins.chart,
  45296. utils = DX.utils,
  45297. scatterSeries = series.scatter,
  45298. _extend = $.extend,
  45299. _map = $.map,
  45300. _each = $.each;
  45301. series.line = _extend({}, scatterSeries, {
  45302. _createElementsGroup: function(elementsStyle) {
  45303. var settings = _extend({"class": "dxc-elements"}, elementsStyle);
  45304. this._applyElementsClipRect(settings);
  45305. this._createGroup("_elementsGroup", this, this._group, settings)
  45306. },
  45307. _createBordersGroup: function(borderStyle) {
  45308. var settings = _extend({"class": "dxc-borders"}, borderStyle);
  45309. this._applyElementsClipRect(settings);
  45310. this._createGroup("_bordersGroup", this, this._group, settings)
  45311. },
  45312. _applyTrackersClippings: function() {
  45313. scatterSeries._applyTrackersClippings.call(this);
  45314. this._trackersGroup.applySettings({clipId: this._paneClipRectID})
  45315. },
  45316. _createGroups: function(animationEnabled, style) {
  45317. var style = style || this._styles.normal;
  45318. this._createElementsGroup(style.elements);
  45319. this._areBordersVisible() && this._createBordersGroup(style.border);
  45320. scatterSeries._createGroups.call(this, animationEnabled, {});
  45321. animationEnabled && this._markersGroup && this._markersGroup.applySettings({opacity: 0.001})
  45322. },
  45323. _areBordersVisible: function() {
  45324. return false
  45325. },
  45326. _getDefaultSegment: function(segment) {
  45327. return {line: _map(segment.line || [], function(pt) {
  45328. return pt.getDefaultCoords()
  45329. })}
  45330. },
  45331. _prepareSegment: function(points) {
  45332. return {line: points}
  45333. },
  45334. _parseLineOptions: function(options, defaultColor) {
  45335. return {
  45336. stroke: options.color || defaultColor,
  45337. strokeWidth: options.width,
  45338. dashStyle: options.dashStyle || 'solid'
  45339. }
  45340. },
  45341. _parseStyle: function(options, defaultColor) {
  45342. return {elements: this._parseLineOptions(options, defaultColor)}
  45343. },
  45344. _applyStyle: function(style) {
  45345. this._elementsGroup && this._elementsGroup.applySettings(style.elements);
  45346. _each(this._graphics || [], function(_, graphic) {
  45347. graphic.line && graphic.line.applySettings({strokeWidth: style.elements.strokeWidth})
  45348. })
  45349. },
  45350. _drawElement: function(segment, group) {
  45351. return {line: this._createMainElement(segment.line, {strokeWidth: this._styles.normal.elements.strokeWidth}).append(group)}
  45352. },
  45353. _removeElement: function(element) {
  45354. element.line.remove()
  45355. },
  45356. _generateDefaultSegments: function() {
  45357. var that = this,
  45358. segments = [];
  45359. _each(that._segments || [], function(_, segment) {
  45360. segments.push(that._getDefaultSegment(segment))
  45361. });
  45362. return segments
  45363. },
  45364. _updateElement: function(element, segment, animate, animateParams, complete) {
  45365. var params = {points: segment.line};
  45366. animate ? element.line.animate(params, animateParams, complete) : element.line.applySettings(params)
  45367. },
  45368. _clearingAnimation: function(translator, drawComplete) {
  45369. var that = this,
  45370. lastIndex = that._graphics.length - 1,
  45371. settings = {opacity: 0.001},
  45372. options = {
  45373. duration: that._defaultDuration,
  45374. partitionDuration: 0.5
  45375. };
  45376. that._labelsGroup && that._labelsGroup.animate(settings, options, function() {
  45377. that._markersGroup && that._markersGroup.animate(settings, options, function() {
  45378. _each(that._defaultSegments || [], function(i, segment) {
  45379. that._oldUpdateElement(that._graphics[i], segment, true, {partitionDuration: 0.5}, i === lastIndex ? drawComplete : undefined)
  45380. })
  45381. })
  45382. })
  45383. },
  45384. _animate: function() {
  45385. var that = this,
  45386. lastIndex = that._graphics.length - 1;
  45387. _each(that._graphics || [], function(i, elem) {
  45388. that._updateElement(elem, that._segments[i], true, {complete: i === lastIndex ? function() {
  45389. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration});
  45390. that._markersGroup && that._markersGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  45391. } : undefined})
  45392. })
  45393. },
  45394. _drawPoint: function(point, group, labelsGroup) {
  45395. scatterSeries._drawPoint.call(this, point, group, labelsGroup)
  45396. },
  45397. _createMainElement: function(points, settings) {
  45398. return this._renderer.createPath(points, settings)
  45399. },
  45400. _drawSegment: function(points, animationEnabled, segmentCount) {
  45401. var segment = this._prepareSegment(points, this._options.rotated);
  45402. this._segments.push(segment);
  45403. if (!this._graphics[segmentCount])
  45404. this._graphics[segmentCount] = this._drawElement(animationEnabled ? this._getDefaultSegment(segment) : segment, this._elementsGroup);
  45405. else if (!animationEnabled)
  45406. this._updateElement(this._graphics[segmentCount], segment)
  45407. },
  45408. _getTrackerSettings: function() {
  45409. return {
  45410. strokeWidth: this._styles.normal.elements.strokeWidth > this._defaultTrackerWidth ? this._styles.normal.elements.strokeWidth : this._defaultTrackerWidth,
  45411. fill: "none"
  45412. }
  45413. },
  45414. _getMainPointsFromSegment: function(segment) {
  45415. return segment.line
  45416. },
  45417. _drawTrackerElement: function(segment) {
  45418. return this._createMainElement(this._getMainPointsFromSegment(segment), this._getTrackerSettings(segment))
  45419. },
  45420. _updateTrackerElement: function(segment, element) {
  45421. var settings = this._getTrackerSettings(segment);
  45422. settings.points = this._getMainPointsFromSegment(segment);
  45423. element.applySettings(settings)
  45424. }
  45425. });
  45426. series.stepline = _extend({}, series.line, {
  45427. _calculateStepLinePoints: function(points) {
  45428. var segment = [];
  45429. _each(points, function(i, pt) {
  45430. var stepY;
  45431. if (!i) {
  45432. segment.push(pt);
  45433. return
  45434. }
  45435. stepY = segment[segment.length - 1].y;
  45436. if (stepY !== pt.y) {
  45437. var point = utils.clone(pt);
  45438. point.y = stepY;
  45439. segment.push(point)
  45440. }
  45441. segment.push(pt)
  45442. });
  45443. return segment
  45444. },
  45445. _prepareSegment: function(points) {
  45446. return series.line._prepareSegment(this._calculateStepLinePoints(points))
  45447. }
  45448. });
  45449. series.stackedline = _extend({}, series.line, {});
  45450. series.fullstackedline = _extend({}, series.line, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  45451. var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
  45452. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  45453. rangeCalculator.addLabelPaddings(this);
  45454. rangeCalculator.processFullStackedRange(this);
  45455. return this._rangeData
  45456. }});
  45457. series.spline = _extend({}, series.line, {
  45458. _calculateBezierPoints: function(src, rotated) {
  45459. var bezierPoints = [],
  45460. pointsCopy = src;
  45461. var checkExtr = function(otherPointCoord, pointCoord, controlCoord) {
  45462. return otherPointCoord > pointCoord && controlCoord > otherPointCoord || otherPointCoord < pointCoord && controlCoord < otherPointCoord ? otherPointCoord : controlCoord
  45463. };
  45464. var clonePoint = function(point, newX, newY) {
  45465. var p = utils.clone(point);
  45466. p.x = newX;
  45467. p.y = newY;
  45468. return p
  45469. };
  45470. if (pointsCopy.length !== 1)
  45471. _each(pointsCopy, function(i, curPoint) {
  45472. var leftControlX,
  45473. leftControlY,
  45474. rightControlX,
  45475. rightControlY,
  45476. prevPoint,
  45477. nextPoint,
  45478. xCur,
  45479. yCur,
  45480. x1,
  45481. x2,
  45482. y1,
  45483. y2,
  45484. delta,
  45485. lambda = 0.5,
  45486. curIsExtremum,
  45487. leftPoint,
  45488. rightPoint,
  45489. a,
  45490. b,
  45491. c,
  45492. xc,
  45493. yc,
  45494. shift;
  45495. if (!i) {
  45496. bezierPoints.push(curPoint);
  45497. bezierPoints.push(curPoint);
  45498. return
  45499. }
  45500. prevPoint = pointsCopy[i - 1];
  45501. if (i < pointsCopy.length - 1) {
  45502. nextPoint = pointsCopy[i + 1];
  45503. xCur = curPoint.x;
  45504. yCur = curPoint.y;
  45505. x1 = prevPoint.x;
  45506. x2 = nextPoint.x;
  45507. y1 = prevPoint.y;
  45508. y2 = nextPoint.y;
  45509. 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));
  45510. if (curIsExtremum)
  45511. if (!rotated) {
  45512. rightControlY = leftControlY = yCur;
  45513. rightControlX = (xCur + nextPoint.x) / 2;
  45514. leftControlX = (xCur + prevPoint.x) / 2
  45515. }
  45516. else {
  45517. rightControlX = leftControlX = xCur;
  45518. rightControlY = (yCur + nextPoint.y) / 2;
  45519. leftControlY = (yCur + prevPoint.y) / 2
  45520. }
  45521. else {
  45522. a = y2 - y1;
  45523. b = x1 - x2;
  45524. c = y1 * x2 - x1 * y2;
  45525. if (!rotated) {
  45526. xc = xCur;
  45527. yc = -1 * (a * xc + c) / b;
  45528. shift = yc - yCur || 0;
  45529. y1 -= shift;
  45530. y2 -= shift
  45531. }
  45532. else {
  45533. yc = yCur;
  45534. xc = -1 * (b * yc + c) / a;
  45535. shift = xc - xCur || 0;
  45536. x1 -= shift;
  45537. x2 -= shift
  45538. }
  45539. rightControlX = (xCur + lambda * x2) / (1 + lambda);
  45540. rightControlY = (yCur + lambda * y2) / (1 + lambda);
  45541. leftControlX = (xCur + lambda * x1) / (1 + lambda);
  45542. leftControlY = (yCur + lambda * y1) / (1 + lambda)
  45543. }
  45544. if (!rotated) {
  45545. leftControlY = checkExtr(prevPoint.y, yCur, leftControlY);
  45546. rightControlY = checkExtr(nextPoint.y, yCur, rightControlY)
  45547. }
  45548. else {
  45549. leftControlX = checkExtr(prevPoint.x, xCur, leftControlX);
  45550. rightControlX = checkExtr(nextPoint.x, xCur, rightControlX)
  45551. }
  45552. leftPoint = clonePoint(curPoint, leftControlX, leftControlY);
  45553. rightPoint = clonePoint(curPoint, rightControlX, rightControlY);
  45554. bezierPoints.push(leftPoint, curPoint, rightPoint)
  45555. }
  45556. else {
  45557. bezierPoints.push(curPoint, curPoint);
  45558. return
  45559. }
  45560. });
  45561. else
  45562. bezierPoints.push(pointsCopy[0]);
  45563. return bezierPoints
  45564. },
  45565. _prepareSegment: function(points, rotated) {
  45566. return series.line._prepareSegment(this._calculateBezierPoints(points, rotated))
  45567. },
  45568. _createMainElement: function(points, settings) {
  45569. return this._renderer.createBezierPath(points, settings)
  45570. }
  45571. })
  45572. })(jQuery, DevExpress);
  45573. /*! Module viz-core, file areaSeries.js */
  45574. (function($, DX) {
  45575. var viz = DX.viz,
  45576. utils = DX.utils,
  45577. series = viz.core.series.mixins.chart,
  45578. lineSeries = series.line,
  45579. _map = $.map,
  45580. _extend = $.extend,
  45581. HOVER_COLOR_HIGHLIGHTING = 20;
  45582. series.area = _extend({}, lineSeries, {
  45583. _createBorderElement: lineSeries._createMainElement,
  45584. _processSinglePointsAreaSegment: function(points, rotated) {
  45585. if (points.length == 1) {
  45586. var p = points[0],
  45587. p1 = utils.clone(p),
  45588. coord = rotated ? "y" : "x";
  45589. p1[coord] += 1;
  45590. return [p, p1]
  45591. }
  45592. return points
  45593. },
  45594. _prepareSegment: function(points, rotated) {
  45595. var processedPoints = this._processSinglePointsAreaSegment(points, rotated);
  45596. return {
  45597. line: processedPoints,
  45598. area: _map(processedPoints, function(pt) {
  45599. return pt.getCoords()
  45600. }).concat(_map(processedPoints.slice().reverse(), function(pt) {
  45601. return pt.getCoords(true)
  45602. })),
  45603. singlePointSegment: processedPoints !== points
  45604. }
  45605. },
  45606. _getSpecialColor: function(color) {
  45607. return this._options._IE8 ? new DX.Color(color).highlight(HOVER_COLOR_HIGHLIGHTING) : color
  45608. },
  45609. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  45610. var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
  45611. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  45612. rangeCalculator.addLabelPaddings(this);
  45613. rangeCalculator.calculateRangeMinValue(this, zoomArgs);
  45614. return this._rangeData
  45615. },
  45616. _getDefaultSegment: function(segment) {
  45617. var defaultSegment = lineSeries._getDefaultSegment(segment);
  45618. defaultSegment.area = defaultSegment.line.concat(defaultSegment.line.slice().reverse());
  45619. return defaultSegment
  45620. },
  45621. _updateElement: function(element, segment, animate, animateParams, complete) {
  45622. var lineParams = {points: segment.line},
  45623. areaParams = {points: segment.area},
  45624. borderElement = element.line;
  45625. if (animate) {
  45626. borderElement && borderElement.animate(lineParams, animateParams);
  45627. element.area.animate(areaParams, animateParams, complete)
  45628. }
  45629. else {
  45630. borderElement && borderElement.applySettings(lineParams);
  45631. element.area.applySettings(areaParams)
  45632. }
  45633. },
  45634. _removeElement: function(element) {
  45635. element.line && element.line.remove();
  45636. element.area.remove()
  45637. },
  45638. _drawElement: function(segment, group) {
  45639. return {
  45640. line: this._bordersGroup && this._createBorderElement(segment.line, {strokeWidth: this._styles.normal.border.strokeWidth}).append(this._bordersGroup),
  45641. area: this._createMainElement(segment.area).append(this._elementsGroup)
  45642. }
  45643. },
  45644. _applyStyle: function(style) {
  45645. this._elementsGroup && this._elementsGroup.applySettings(style.elements);
  45646. this._bordersGroup && this._bordersGroup.applySettings(style.border);
  45647. $.each(this._graphics || [], function(_, graphic) {
  45648. graphic.line && graphic.line.applySettings({strokeWidth: style.border.strokeWidth})
  45649. })
  45650. },
  45651. _createPattern: function(color, hatching) {
  45652. if (hatching && utils.isObject(hatching)) {
  45653. var pattern = this._renderer.createPattern(color, hatching);
  45654. this._patterns.push(pattern);
  45655. return pattern.id
  45656. }
  45657. return color
  45658. },
  45659. _parseStyle: function(options, defaultColor, defaultBorderColor) {
  45660. var borderOptions = options.border || {},
  45661. borderStyle = lineSeries._parseLineOptions(borderOptions, defaultBorderColor);
  45662. borderStyle.strokeWidth = borderOptions.visible ? borderStyle.strokeWidth : 0;
  45663. return {
  45664. border: borderStyle,
  45665. elements: {
  45666. stroke: "none",
  45667. fill: this._createPattern(options.color || defaultColor, options.hatching),
  45668. opacity: options.opacity
  45669. }
  45670. }
  45671. },
  45672. _areBordersVisible: function() {
  45673. var options = this._options;
  45674. return options.border.visible || options.hoverStyle.border.visible || options.selectionStyle.border.visible
  45675. },
  45676. _createMainElement: function(points, settings) {
  45677. return this._renderer.createArea(points, settings)
  45678. },
  45679. _getTrackerSettings: function(segment) {
  45680. return {strokeWidth: segment.singlePointSegment ? this._defaultTrackerWidth : 0}
  45681. },
  45682. _getMainPointsFromSegment: function(segment) {
  45683. return segment.area
  45684. }
  45685. });
  45686. series.steparea = _extend({}, series.area, {_prepareSegment: function(points, rotated) {
  45687. points = series.area._processSinglePointsAreaSegment(points, rotated);
  45688. return series.area._prepareSegment.call(this, series.stepline._calculateStepLinePoints(points))
  45689. }});
  45690. series.splinearea = _extend({}, series.area, {
  45691. _areaPointsToSplineAreaPoints: function(areaPoints) {
  45692. var lastFwPoint = areaPoints[areaPoints.length / 2 - 1],
  45693. firstBwPoint = areaPoints[areaPoints.length / 2];
  45694. areaPoints.splice(areaPoints.length / 2, 0, {
  45695. x: lastFwPoint.x,
  45696. y: lastFwPoint.y
  45697. }, {
  45698. x: firstBwPoint.x,
  45699. y: firstBwPoint.y
  45700. });
  45701. if (lastFwPoint.defaultCoords)
  45702. areaPoints[areaPoints.length / 2].defaultCoords = true;
  45703. if (firstBwPoint.defaultCoords)
  45704. areaPoints[areaPoints.length / 2 - 1].defaultCoords = true
  45705. },
  45706. _prepareSegment: function(points, rotated) {
  45707. var areaSeries = series.area,
  45708. processedPoints = areaSeries._processSinglePointsAreaSegment(points, rotated),
  45709. areaSegment = areaSeries._prepareSegment.call(this, series.spline._calculateBezierPoints(processedPoints, rotated));
  45710. this._areaPointsToSplineAreaPoints(areaSegment.area);
  45711. areaSegment.singlePointSegment = processedPoints !== points;
  45712. return areaSegment
  45713. },
  45714. _getDefaultSegment: function(segment) {
  45715. var areaDefaultSegment = series.area._getDefaultSegment(segment);
  45716. this._areaPointsToSplineAreaPoints(areaDefaultSegment.area);
  45717. return areaDefaultSegment
  45718. },
  45719. _createMainElement: function(points, settings) {
  45720. return this._renderer.createBezierArea(points, settings)
  45721. },
  45722. _createBorderElement: series.spline._createMainElement
  45723. })
  45724. })(jQuery, DevExpress);
  45725. /*! Module viz-core, file barSeries.js */
  45726. (function($, DX) {
  45727. var viz = DX.viz,
  45728. series = viz.core.series.mixins.chart,
  45729. scatterSeries = series.scatter,
  45730. areaSeries = series.area,
  45731. _extend = $.extend,
  45732. _each = $.each,
  45733. DEFAULT_BAR_POINT_SIZE = 3;
  45734. series.bar = _extend({}, scatterSeries, {
  45735. _getSpecialColor: areaSeries._getSpecialColor,
  45736. _createPattern: areaSeries._createPattern,
  45737. _updateOptions: function(options) {
  45738. this._stackName = "axis_" + (options.axis || "default") + "_stack_" + (options.stack || "default")
  45739. },
  45740. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  45741. var rangeData = areaSeries._getRangeData.apply(this, arguments);
  45742. rangeData.arg.stick = false;
  45743. return rangeData
  45744. },
  45745. _parsePointStyle: function(style, defaultColor, defaultBorderColor) {
  45746. var color = this._createPattern(style.color || defaultColor, style.hatching),
  45747. base = scatterSeries._parsePointStyle.call(this, style, color, defaultBorderColor);
  45748. base.fill = color;
  45749. base.dashStyle = style.border && style.border.dashStyle || "solid";
  45750. delete base.r;
  45751. return base
  45752. },
  45753. _applyMarkerClipRect: function(settings) {
  45754. settings.clipId = null
  45755. },
  45756. _applyTrackersClippings: function() {
  45757. this._markerTrackerGroup.applySettings({clipId: this._paneClipRectID})
  45758. },
  45759. _clearingAnimation: function(translators, drawComplete) {
  45760. var that = this,
  45761. settings;
  45762. if (that._options.rotated)
  45763. settings = {
  45764. scale: {
  45765. x: 0.001,
  45766. y: 1
  45767. },
  45768. translate: {x: translators.x.translate("canvas_position_default")}
  45769. };
  45770. else
  45771. settings = {
  45772. scale: {
  45773. x: 1,
  45774. y: 0.001
  45775. },
  45776. translate: {y: translators.y.translate("canvas_position_default")}
  45777. };
  45778. that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {
  45779. duration: that._defaultDuration,
  45780. partitionDuration: 0.5
  45781. }, function() {
  45782. that._markersGroup.animate(settings, {partitionDuration: 0.5}, function() {
  45783. that._markersGroup.applySettings({
  45784. scale: null,
  45785. translateX: 0,
  45786. translateY: 0
  45787. });
  45788. drawComplete()
  45789. })
  45790. })
  45791. },
  45792. _createGroups: function(animationEnabled, style, firstDrawing) {
  45793. var settings = {};
  45794. scatterSeries._createGroups.apply(this, arguments);
  45795. if (animationEnabled && firstDrawing)
  45796. if (!this._options.rotated)
  45797. settings = {
  45798. scale: {
  45799. x: 1,
  45800. y: 0.001
  45801. },
  45802. translateY: this.translators.y.translate("canvas_position_default")
  45803. };
  45804. else
  45805. settings = {
  45806. scale: {
  45807. x: 0.001,
  45808. y: 1
  45809. },
  45810. translateX: this.translators.x.translate("canvas_position_default")
  45811. };
  45812. else if (!animationEnabled)
  45813. settings = {
  45814. scale: {
  45815. x: 1,
  45816. y: 1
  45817. },
  45818. translateX: 0,
  45819. translateY: 0
  45820. };
  45821. this._markersGroup.applySettings(settings)
  45822. },
  45823. _drawPoint: function(point, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
  45824. scatterSeries._drawPoint.call(this, point, markersGroup, labelsGroup, animationEnabled && !firstDrawing)
  45825. },
  45826. _getMainColor: function() {
  45827. return this._options.mainSeriesColor
  45828. },
  45829. _createPointStyles: function(pointOptions) {
  45830. var mainColor = pointOptions.color || this._getMainColor(),
  45831. specialMainColor = this._getSpecialColor(mainColor);
  45832. return {
  45833. normal: this._parsePointStyle(pointOptions, mainColor, mainColor),
  45834. hover: this._parsePointStyle(pointOptions.hoverStyle || {}, specialMainColor, mainColor),
  45835. selection: this._parsePointStyle(pointOptions.selectionStyle || {}, specialMainColor, mainColor)
  45836. }
  45837. },
  45838. _preparePointOptions: function(customOptions) {
  45839. return customOptions ? _extend(true, {}, this._options, customOptions) : this._options
  45840. },
  45841. _animate: function(firstDrawing) {
  45842. var that = this,
  45843. labelAnimFunc = function() {
  45844. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  45845. },
  45846. lastPointIndex;
  45847. that._markersGroup.animate({
  45848. scale: {
  45849. x: 1,
  45850. y: 1
  45851. },
  45852. translate: {
  45853. y: 0,
  45854. x: 0
  45855. }
  45856. }, undefined, labelAnimFunc);
  45857. if (!firstDrawing) {
  45858. lastPointIndex = that._drawedPoints.length - 1;
  45859. _each(this._drawedPoints || [], function(i, point) {
  45860. point.animate(i === lastPointIndex ? labelAnimFunc : undefined, {
  45861. x: point.x,
  45862. y: point.y,
  45863. height: point.height,
  45864. width: point.width
  45865. })
  45866. })
  45867. }
  45868. },
  45869. _getPointSize: function() {
  45870. return DEFAULT_BAR_POINT_SIZE
  45871. }
  45872. })
  45873. })(jQuery, DevExpress);
  45874. /*! Module viz-core, file rangeSeries.js */
  45875. (function($, DX) {
  45876. var viz = DX.viz,
  45877. series = viz.core.series.mixins.chart,
  45878. _extend = $.extend,
  45879. _isDefined = DX.utils.isDefined,
  45880. _map = $.map,
  45881. rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
  45882. areaSeries = series.area;
  45883. var baseRangeSeries = {
  45884. _checkData: function(data) {
  45885. return _isDefined(data.argument) && data.value !== undefined && data.minValue !== undefined
  45886. },
  45887. updateTeamplateFieldNames: function() {
  45888. var that = this,
  45889. options = that._options,
  45890. valueFields = that.getValueFields(),
  45891. name = that.name;
  45892. options.rangeValue1Field = valueFields[0] + name;
  45893. options.rangeValue2Field = valueFields[1] + name;
  45894. options.tagField = that.getTagField() + name
  45895. },
  45896. _processRange: function(point, prevPoint) {
  45897. rangeCalculator.processTwoValues(this, point, prevPoint, "value", "minValue")
  45898. },
  45899. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  45900. rangeCalculator.calculateTwoValuesRangeData(this, zoomArgs, calcIntervalFunction, "value", "minValue");
  45901. rangeCalculator.addRangeSeriesLabelPaddings(this);
  45902. return this._rangeData
  45903. },
  45904. _getPointData: function(data, options) {
  45905. var argumentField = options.argumentField || "arg",
  45906. tagField = options.tagField || "tag",
  45907. rangeValue1Field = options.rangeValue1Field || "val1",
  45908. rangeValue2Field = options.rangeValue2Field || "val2";
  45909. return {
  45910. tag: data[tagField],
  45911. minValue: data[rangeValue1Field],
  45912. value: data[rangeValue2Field],
  45913. argument: data[argumentField]
  45914. }
  45915. },
  45916. _fusionPoints: function(fusionPoints, tick, index) {
  45917. var scatterSeries = series.scatter,
  45918. value = scatterSeries._calcMedianValue.call(this, fusionPoints, "value"),
  45919. minValue = scatterSeries._calcMedianValue.call(this, fusionPoints, "minValue"),
  45920. pointData;
  45921. if (value === null || minValue === null)
  45922. value = minValue = null;
  45923. pointData = {
  45924. minValue: minValue,
  45925. value: value,
  45926. argument: tick,
  45927. tag: null
  45928. };
  45929. return pointData
  45930. },
  45931. getValueFields: function() {
  45932. return [this._options.rangeValue1Field || "val1", this._options.rangeValue2Field || "val2"]
  45933. }
  45934. };
  45935. series.rangebar = _extend({}, series.bar, baseRangeSeries);
  45936. series.rangearea = _extend({}, areaSeries, {
  45937. _drawPoint: function(point, markersGroup, labelsGroup, animationEnabled) {
  45938. if (point.isInVisibleArea()) {
  45939. point.clearVisibility();
  45940. point.draw(this._renderer, markersGroup, labelsGroup, animationEnabled);
  45941. this._drawedPoints.push(point);
  45942. if (!point.visibleTopMarker)
  45943. point.hideMarker("top");
  45944. if (!point.visibleBottomMarker)
  45945. point.hideMarker("bottom")
  45946. }
  45947. else
  45948. point.setInvisibility()
  45949. },
  45950. _prepareSegment: function(points, rotated) {
  45951. var processedPoints = this._processSinglePointsAreaSegment(points, rotated),
  45952. processedMinPointsCoords = $.map(processedPoints, function(pt) {
  45953. return pt.getCoords(true)
  45954. });
  45955. return {
  45956. line: processedPoints,
  45957. bottomLine: processedMinPointsCoords,
  45958. area: $.map(processedPoints, function(pt) {
  45959. return pt.getCoords()
  45960. }).concat(processedMinPointsCoords.slice().reverse()),
  45961. singlePointSegment: processedPoints !== points
  45962. }
  45963. },
  45964. _getDefaultSegment: function(segment) {
  45965. var defaultSegment = areaSeries._getDefaultSegment.call(this, segment);
  45966. defaultSegment.bottomLine = defaultSegment.line;
  45967. return defaultSegment
  45968. },
  45969. _removeElement: function(element) {
  45970. areaSeries._removeElement.call(this, element);
  45971. element.bottomLine && element.bottomLine.remove()
  45972. },
  45973. _drawElement: function(segment, group) {
  45974. var drawnElement = areaSeries._drawElement.call(this, segment, group);
  45975. drawnElement.bottomLine = this._bordersGroup && this._createBorderElement(segment.bottomLine, {strokeWidth: this._styles.normal.border.strokeWidth}).append(this._bordersGroup);
  45976. return drawnElement
  45977. },
  45978. _applyStyle: function(style) {
  45979. this._elementsGroup && this._elementsGroup.applySettings(style.elements);
  45980. this._bordersGroup && this._bordersGroup.applySettings(style.border);
  45981. $.each(this._graphics || [], function(_, graphic) {
  45982. graphic.line && graphic.line.applySettings({strokeWidth: style.border.strokeWidth});
  45983. graphic.bottomLine && graphic.bottomLine.applySettings({strokeWidth: style.border.strokeWidth})
  45984. })
  45985. },
  45986. _updateElement: function(element, segment, animate, animateParams, complete) {
  45987. areaSeries._updateElement.call(this, element, segment, animate, animateParams, complete);
  45988. var bottomLineParams = {points: segment.bottomLine},
  45989. bottomBorderElement = element.bottomLine;
  45990. if (bottomBorderElement)
  45991. animate ? bottomBorderElement.animate(bottomLineParams, animateParams) : bottomBorderElement.applySettings(bottomLineParams)
  45992. }
  45993. }, baseRangeSeries)
  45994. })(jQuery, DevExpress);
  45995. /*! Module viz-core, file bubbleSeries.js */
  45996. (function($, DX) {
  45997. var viz = DX.viz,
  45998. series = viz.core.series.mixins.chart,
  45999. scatterSeries = series.scatter,
  46000. barSeries = series.bar,
  46001. _isDefined = DX.utils.isDefined,
  46002. _extend = $.extend,
  46003. _each = $.each;
  46004. series.bubble = _extend({}, scatterSeries, {
  46005. _applyTrackersClippings: barSeries._applyTrackersClippings,
  46006. _getMainColor: barSeries._getMainColor,
  46007. _createPointStyles: barSeries._createPointStyles,
  46008. _createPattern: barSeries._createPattern,
  46009. _preparePointOptions: barSeries._preparePointOptions,
  46010. _getSpecialColor: barSeries._getSpecialColor,
  46011. _applyMarkerClipRect: series.line._applyElementsClipRect,
  46012. _parsePointStyle: function(style, defaultColor, defaultBorderColor) {
  46013. var base = barSeries._parsePointStyle.call(this, style, defaultColor, defaultBorderColor);
  46014. base.opacity = style.opacity;
  46015. return base
  46016. },
  46017. _createMarkerGroup: function() {
  46018. var markersSettings = this._getPointOptions().styles.normal,
  46019. groupSettings;
  46020. markersSettings["class"] = "dxc-markers";
  46021. this._applyMarkerClipRect(markersSettings);
  46022. groupSettings = _extend({}, markersSettings);
  46023. delete groupSettings.opacity;
  46024. this._createGroup("_markersGroup", this, this._group, groupSettings)
  46025. },
  46026. _getCreatingPointOptions: function() {
  46027. if (!this._predefinedPointOptions) {
  46028. var styles,
  46029. defaultPointOptions = this._getPointOptions(),
  46030. strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
  46031. r = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.r,
  46032. opacity = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.opacity,
  46033. creatingPointOptions = _extend(true, {}, defaultPointOptions);
  46034. creatingPointOptions.styles = styles = creatingPointOptions.styles || {};
  46035. styles.normal = {
  46036. strokeWidth: strokeWidth,
  46037. r: r,
  46038. opacity: opacity
  46039. };
  46040. this._predefinedPointOptions = creatingPointOptions
  46041. }
  46042. return this._predefinedPointOptions
  46043. },
  46044. _checkData: function(data) {
  46045. return _isDefined(data.argument) && _isDefined(data.size) && data.value !== undefined
  46046. },
  46047. _getPointData: function(data, options) {
  46048. var pointData = scatterSeries._getPointData.call(this, data, options),
  46049. sizeField = options.sizeField || "size";
  46050. pointData.size = data[sizeField];
  46051. return pointData
  46052. },
  46053. _fusionPoints: function(fusionPoints, tick, index) {
  46054. var medianValue = scatterSeries._calcMedianValue.call(this, fusionPoints, "value"),
  46055. medianSize = scatterSeries._calcMedianValue.call(this, fusionPoints, "size");
  46056. return {
  46057. size: medianSize,
  46058. value: medianValue,
  46059. argument: tick,
  46060. tag: null
  46061. }
  46062. },
  46063. getValueFields: function() {
  46064. return [this._options.valueField || "val", this._options.sizeField || "size"]
  46065. },
  46066. updateTeamplateFieldNames: function() {
  46067. var that = this,
  46068. options = that._options,
  46069. valueFields = that.getValueFields(),
  46070. name = that.name;
  46071. options.valueField = valueFields[0] + name;
  46072. options.sizeField = valueFields[1] + name;
  46073. options.tagField = that.getTagField() + name
  46074. },
  46075. _clearingAnimation: function(translators, drawComplete) {
  46076. var that = this,
  46077. settings = {r: 0},
  46078. partitionDuration = 0.5,
  46079. lastPointIndex = that._drawedPoints.length - 1;
  46080. that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {
  46081. duration: that._defaultDuration,
  46082. partitionDuration: partitionDuration
  46083. }, function() {
  46084. _each(that._drawedPoints || [], function(i, p) {
  46085. p.animate(i === lastPointIndex ? drawComplete : undefined, settings, partitionDuration)
  46086. })
  46087. })
  46088. },
  46089. _animate: function(firstDrawing) {
  46090. var that = this,
  46091. lastPointIndex = that._drawedPoints.length - 1,
  46092. labelAnimFunc = function() {
  46093. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  46094. };
  46095. _each(that._drawedPoints || [], function(i, p) {
  46096. p.animate(i === lastPointIndex ? labelAnimFunc : undefined, {
  46097. r: p.bubbleSize,
  46098. translate: {
  46099. x: p.x,
  46100. y: p.y
  46101. }
  46102. })
  46103. })
  46104. }
  46105. })
  46106. })(jQuery, DevExpress);
  46107. /*! Module viz-core, file pieSeries.js */
  46108. (function($, DX) {
  46109. var viz = DX.viz,
  46110. mixins = viz.core.series.mixins,
  46111. pieSeries = mixins.pieChart,
  46112. utils = DX.utils,
  46113. scatterSeries = mixins.chart.scatter,
  46114. barSeries = mixins.chart.bar,
  46115. _extend = $.extend,
  46116. _each = $.each,
  46117. _noop = $.noop,
  46118. _map = $.map,
  46119. _isFinite = isFinite,
  46120. _max = Math.max;
  46121. pieSeries.pie = _extend({}, barSeries, {
  46122. _createLabelGroup: scatterSeries._createLabelGroup,
  46123. _createGroups: scatterSeries._createGroups,
  46124. _drawPoint: function(point) {
  46125. scatterSeries._drawPoint.apply(this, arguments);
  46126. !point.isVisible() && point.setInvisibility()
  46127. },
  46128. _applyTrackersClippings: _noop,
  46129. _processRange: _noop,
  46130. _applyElementsClipRect: _noop,
  46131. _updateDataType: _noop,
  46132. getColor: _noop,
  46133. _prepareSeriesToDrawing: _noop,
  46134. _endUpdateData: scatterSeries._prepareSeriesToDrawing,
  46135. resetLabelEllipsis: function() {
  46136. _each(this._points || [], function(_, point) {
  46137. point._label.setLabelEllipsis = false
  46138. })
  46139. },
  46140. _adjustLabels: function(firstDrawing) {
  46141. var that = this,
  46142. options = that._options,
  46143. canvas = that.canvas,
  46144. points = that._points || [],
  46145. labelsBBoxes = [],
  46146. labelsSpaces = [],
  46147. labelSpace = 0,
  46148. maxLabelLength,
  46149. paneSpaceHeight,
  46150. paneSpaceWidth,
  46151. min;
  46152. if (options.label.position !== "inside") {
  46153. _each(points, function(_, point) {
  46154. if (point._label.hasText())
  46155. labelsBBoxes.push(point._label.getTextCoords().width)
  46156. });
  46157. if (labelsBBoxes.length) {
  46158. maxLabelLength = _max.apply(null, labelsBBoxes);
  46159. _each(points, function(_, point) {
  46160. if (point._label.hasText()) {
  46161. point._label.updatePosition(maxLabelLength);
  46162. point._label.setLabelEllipsis = true
  46163. }
  46164. });
  46165. that._firstDrawing = !that.redraw && firstDrawing;
  46166. that.redraw = true
  46167. }
  46168. }
  46169. else
  46170. _each(points, function(i, point) {
  46171. if (point._label.hasText()) {
  46172. point._label.setLabelEllipsis = true;
  46173. point._label.updatePosition()
  46174. }
  46175. })
  46176. },
  46177. _getCreatingPointOptions: function() {
  46178. return this._getPointOptions()
  46179. },
  46180. _updateOptions: function(options) {
  46181. this.labelSpace = 0;
  46182. this.innerRadius = this.type === "pie" ? 0 : options.innerRadius;
  46183. this.redraw = false
  46184. },
  46185. _checkData: function(data) {
  46186. var base = barSeries._checkData(data);
  46187. return this._options.paintNullPoints ? base : base && data.value !== null
  46188. },
  46189. _createMarkerGroup: function() {
  46190. if (!this._markersGroup)
  46191. this._markersGroup = this._renderer.createGroup({"class": "dxc-markers"}).append(this._group)
  46192. },
  46193. _getMainColor: function() {
  46194. return this._options.mainSeriesColor()
  46195. },
  46196. _getPointOptions: function() {
  46197. return this._parsePointOptions(this._preparePointOptions(), this._options.label)
  46198. },
  46199. _getRangeData: function() {
  46200. return this._rangeData
  46201. },
  46202. _getArrangeTotal: function(points) {
  46203. var total = 0;
  46204. _each(points, function(_, point) {
  46205. if (point.isVisible())
  46206. total += point.initialValue
  46207. });
  46208. return total
  46209. },
  46210. _createPointStyles: function(pointOptions) {
  46211. var mainColor = pointOptions.color || this._getMainColor(),
  46212. specialMainColor = this._getSpecialColor(mainColor);
  46213. return {
  46214. normal: this._parsePointStyle(pointOptions, mainColor, mainColor),
  46215. hover: this._parsePointStyle(pointOptions.hoverStyle, specialMainColor, mainColor),
  46216. selection: this._parsePointStyle(pointOptions.selectionStyle, specialMainColor, mainColor),
  46217. legendStyles: {
  46218. normal: this._createLegendState(pointOptions, mainColor),
  46219. hover: this._createLegendState(pointOptions.hoverStyle, specialMainColor),
  46220. selection: this._createLegendState(pointOptions.selectionStyle, specialMainColor)
  46221. }
  46222. }
  46223. },
  46224. _getArrangeMinShownValue: function(points, total) {
  46225. var minSegmentSize = this._options.minSegmentSize,
  46226. totalMinSegmentSize = 0,
  46227. totalNotMinValues = 0;
  46228. total = total || points.length;
  46229. _each(points, function(_, point) {
  46230. if (point.isVisible())
  46231. if (point.initialValue < minSegmentSize * total / 360)
  46232. totalMinSegmentSize += minSegmentSize;
  46233. else
  46234. totalNotMinValues += point.initialValue
  46235. });
  46236. return totalMinSegmentSize < 360 ? minSegmentSize * totalNotMinValues / (360 - totalMinSegmentSize) : 0
  46237. },
  46238. _applyArrangeCorrection: function(points, minShownValue, total) {
  46239. var options = this._options,
  46240. isClockWise = options.segmentsDirection !== "anticlockwise",
  46241. shiftedAngle = _isFinite(options.startAngle) ? utils.normalizeAngle(options.startAngle) : 0,
  46242. minSegmentSize = options.minSegmentSize,
  46243. percent,
  46244. correction = 0,
  46245. zeroTotalCorrection = 0;
  46246. if (total === 0) {
  46247. total = points.length;
  46248. zeroTotalCorrection = 1
  46249. }
  46250. _each(isClockWise ? points : points.concat([]).reverse(), function(_, point) {
  46251. var val = point.isVisible() ? zeroTotalCorrection || point.initialValue : 0,
  46252. updatedZeroValue;
  46253. if (minSegmentSize && point.isVisible() && val < minShownValue)
  46254. updatedZeroValue = minShownValue;
  46255. percent = val / total;
  46256. point.correctValue(correction, percent, zeroTotalCorrection + (updatedZeroValue || 0));
  46257. point.shiftedAngle = shiftedAngle;
  46258. correction = correction + (updatedZeroValue || val)
  46259. });
  46260. this._rangeData = {val: {
  46261. min: 0,
  46262. max: correction
  46263. }}
  46264. },
  46265. arrangePoints: function() {
  46266. var that = this,
  46267. minSegmentSize = that._options.minSegmentSize,
  46268. minShownValue,
  46269. pointIndex = 0,
  46270. total,
  46271. points = that._originalPoints = that._points = _map(that._originalPoints || [], function(point) {
  46272. if (point.value === null || point.value < 0 || point.value === 0 && !minSegmentSize) {
  46273. point.dispose();
  46274. return null
  46275. }
  46276. else {
  46277. point.index = pointIndex++;
  46278. return point
  46279. }
  46280. });
  46281. total = that._getArrangeTotal(points);
  46282. if (minSegmentSize)
  46283. minShownValue = this._getArrangeMinShownValue(points, total);
  46284. that._applyArrangeCorrection(points, minShownValue, total)
  46285. },
  46286. correctPosition: function(correction) {
  46287. var debug = DX.utils.debug;
  46288. debug.assert(correction, "correction was not passed");
  46289. debug.assertParam(correction.centerX, "correction.centerX was not passed");
  46290. debug.assertParam(correction.centerY, "correction.centerY was not passed");
  46291. debug.assertParam(correction.radiusInner, "correction.radiusInner was not passed");
  46292. debug.assertParam(correction.radiusOuter, "correction.radiusOuter was not passed");
  46293. _each(this._points, function(_, point) {
  46294. point.correctPosition(correction)
  46295. })
  46296. },
  46297. _animate: function(firstDrawing) {
  46298. var that = this,
  46299. index = 0,
  46300. timeThreshold = 0.2,
  46301. points = that._points,
  46302. pointsCount = points && points.length,
  46303. duration = 1 / (timeThreshold * (pointsCount - 1) + 1),
  46304. animateP = function() {
  46305. points[index] && points[index++].animate(index === pointsCount ? completeFunc : undefined, duration, stepFunc)
  46306. },
  46307. stepFunc = function(_, progress) {
  46308. if (progress >= timeThreshold) {
  46309. this.step = null;
  46310. animateP()
  46311. }
  46312. },
  46313. completeFunc = function() {
  46314. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: 400})
  46315. };
  46316. if (firstDrawing)
  46317. animateP();
  46318. else
  46319. $.each(points, function(i, p) {
  46320. p.animate(i == pointsCount - 1 ? completeFunc : undefined)
  46321. })
  46322. },
  46323. getVisiblePoints: function() {
  46324. return _map(this._points, function(p) {
  46325. return p.isVisible() ? p : null
  46326. })
  46327. },
  46328. _beginUpdateData: function() {
  46329. this._deletePatterns();
  46330. this._patterns = []
  46331. }
  46332. });
  46333. pieSeries.doughnut = pieSeries.donut = pieSeries.pie
  46334. })(jQuery, DevExpress);
  46335. /*! Module viz-core, file financialSeries.js */
  46336. (function($, DX) {
  46337. var viz = DX.viz,
  46338. series = viz.core.series.mixins.chart,
  46339. scatterSeries = series.scatter,
  46340. barSeries = series.bar,
  46341. rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
  46342. _isDefined = DX.utils.isDefined,
  46343. _extend = $.extend,
  46344. _each = $.each,
  46345. _noop = $.noop,
  46346. DEFAULT_FINANCIAL_POINT_SIZE = 10;
  46347. series.stock = _extend({}, scatterSeries, {
  46348. _animate: _noop,
  46349. _applyMarkerClipRect: series.line._applyElementsClipRect,
  46350. _applyTrackersClippings: barSeries._applyTrackersClippings,
  46351. _createPattern: barSeries._createPattern,
  46352. _preparePointOptions: barSeries._preparePointOptions,
  46353. _createMarkerGroup: function() {
  46354. var that = this,
  46355. markersGroup,
  46356. styles = that._getPointOptions().styles,
  46357. defaultStyle = styles.normal,
  46358. defaultPositiveStyle = styles.positive.normal,
  46359. reductionStyle = styles.reduction.normal,
  46360. reductionPositiveStyle = styles.reductionPositive.normal,
  46361. markerSettings = {"class": "dxc-markers"};
  46362. that._applyMarkerClipRect(markerSettings);
  46363. defaultStyle["class"] = "default-markers";
  46364. defaultPositiveStyle["class"] = "default-positive-markers";
  46365. reductionStyle["class"] = "reduction-markers";
  46366. reductionPositiveStyle["class"] = "reduction-positive-markers";
  46367. that._createGroup("_markersGroup", that, that._group, markerSettings);
  46368. markersGroup = that._markersGroup;
  46369. that._createGroup("defaultMarkersGroup", markersGroup, markersGroup, defaultStyle);
  46370. that._createGroup("reductionMarkersGroup", markersGroup, markersGroup, reductionStyle);
  46371. that._createGroup("defaultPositiveMarkersGroup", markersGroup, markersGroup, defaultPositiveStyle);
  46372. that._createGroup("reductionPositiveMarkersGroup", markersGroup, markersGroup, reductionPositiveStyle)
  46373. },
  46374. _createGroups: function() {
  46375. scatterSeries._createGroups.call(this, false)
  46376. },
  46377. _clearingAnimation: function(translators, drawComplete) {
  46378. drawComplete()
  46379. },
  46380. _getCreatingPointOptions: function() {
  46381. if (!this._predefinedPointOptions) {
  46382. var styles,
  46383. defaultPointOptions = this._getPointOptions(),
  46384. strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
  46385. creatingPointOptions = _extend(true, {}, defaultPointOptions);
  46386. creatingPointOptions.styles = styles = creatingPointOptions.styles || {};
  46387. styles.normal = styles.positive.normal = styles.reduction.normal = styles.reductionPositive.normal = {strokeWidth: strokeWidth};
  46388. this._predefinedPointOptions = creatingPointOptions
  46389. }
  46390. return this._predefinedPointOptions
  46391. },
  46392. _checkData: function(data) {
  46393. return _isDefined(data.argument) && data.highValue !== undefined && data.lowValue !== undefined && data.openValue !== undefined && data.closeValue !== undefined
  46394. },
  46395. _processRange: function(point, prevPoint) {
  46396. rangeCalculator.processTwoValues(this, point, prevPoint, "highValue", "lowValue")
  46397. },
  46398. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  46399. rangeCalculator.calculateTwoValuesRangeData(this, zoomArgs, calcIntervalFunction, "highValue", "lowValue");
  46400. rangeCalculator.addRangeSeriesLabelPaddings(this);
  46401. return this._rangeData
  46402. },
  46403. _getPointData: function(data, options) {
  46404. var that = this,
  46405. level,
  46406. argumentField = options.argumentField || "date",
  46407. tagField = options.tagField || "tag",
  46408. openValueField = options.openValueField || "open",
  46409. closeValueField = options.closeValueField || "close",
  46410. highValueField = options.highValueField || "high",
  46411. lowValueField = options.lowValueField || "low",
  46412. reductionValue;
  46413. that.level = options.reduction.level;
  46414. switch ((that.level || "").toLowerCase()) {
  46415. case"open":
  46416. level = openValueField;
  46417. break;
  46418. case"high":
  46419. level = highValueField;
  46420. break;
  46421. case"low":
  46422. level = lowValueField;
  46423. break;
  46424. default:
  46425. level = closeValueField;
  46426. that.level = "close";
  46427. break
  46428. }
  46429. reductionValue = data[level];
  46430. return {
  46431. argument: data[argumentField],
  46432. highValue: data[highValueField],
  46433. lowValue: data[lowValueField],
  46434. closeValue: data[closeValueField],
  46435. openValue: data[openValueField],
  46436. reductionValue: reductionValue,
  46437. tag: data[tagField],
  46438. isReduction: this._checkReduction(reductionValue)
  46439. }
  46440. },
  46441. _parsePointStyle: function(style, defaultColor, innerColor) {
  46442. return {
  46443. stroke: style.color || defaultColor,
  46444. strokeWidth: style.width,
  46445. fill: style.color || innerColor
  46446. }
  46447. },
  46448. updateTeamplateFieldNames: function() {
  46449. var that = this,
  46450. options = that._options,
  46451. valueFields = that.getValueFields(),
  46452. name = that.name;
  46453. options.openValueField = valueFields[0] + name;
  46454. options.highValueField = valueFields[1] + name;
  46455. options.lowValueField = valueFields[2] + name;
  46456. options.closeValueField = valueFields[3] + name;
  46457. options.tagField = that.getTagField() + name
  46458. },
  46459. _getDefaultStyle: function(options) {
  46460. var mainPointColor = options.color || this._options.mainSeriesColor;
  46461. return {
  46462. normal: this._parsePointStyle(options, mainPointColor, mainPointColor),
  46463. hover: this._parsePointStyle(options.hoverStyle, mainPointColor, mainPointColor),
  46464. selection: this._parsePointStyle(options.selectionStyle, mainPointColor, mainPointColor)
  46465. }
  46466. },
  46467. _getReductionStyle: function(options) {
  46468. var reductionColor = options.reduction.color,
  46469. normalStyle = this._parsePointStyle({
  46470. color: reductionColor,
  46471. width: options.width,
  46472. hatching: options.hatching
  46473. }, reductionColor, reductionColor);
  46474. return {
  46475. normal: normalStyle,
  46476. hover: this._parsePointStyle(options.hoverStyle, reductionColor, reductionColor),
  46477. selection: this._parsePointStyle(options.selectionStyle, reductionColor, reductionColor)
  46478. }
  46479. },
  46480. _createPointStyles: function(pointOptions) {
  46481. var that = this,
  46482. innerColor = that._options.innerColor,
  46483. styles = that._getDefaultStyle(pointOptions),
  46484. positiveStyle,
  46485. reductionStyle,
  46486. reductionPositiveStyle;
  46487. positiveStyle = _extend(true, {}, styles);
  46488. reductionStyle = that._getReductionStyle(pointOptions);
  46489. reductionPositiveStyle = _extend(true, {}, reductionStyle);
  46490. positiveStyle.normal.fill = positiveStyle.hover.fill = positiveStyle.selection.fill = innerColor;
  46491. reductionPositiveStyle.normal.fill = reductionPositiveStyle.hover.fill = reductionPositiveStyle.selection.fill = innerColor;
  46492. styles.positive = positiveStyle;
  46493. styles.reduction = reductionStyle;
  46494. styles.reductionPositive = reductionPositiveStyle;
  46495. return styles
  46496. },
  46497. _endUpdateData: function() {
  46498. delete this.prevLevelValue;
  46499. delete this._predefinedPointOptions
  46500. },
  46501. _checkReduction: function(value) {
  46502. var result = false;
  46503. if (value != null) {
  46504. if (_isDefined(this.prevLevelValue))
  46505. result = value < this.prevLevelValue;
  46506. this.prevLevelValue = value
  46507. }
  46508. return result
  46509. },
  46510. _fusionPoints: function(fusionPoints, tick, nowIndexTicks) {
  46511. var fusedPointData = {},
  46512. reductionLevel,
  46513. highValue = -Infinity,
  46514. lowValue = +Infinity,
  46515. openValue,
  46516. closeValue;
  46517. if (!fusionPoints.length)
  46518. return {};
  46519. _each(fusionPoints, function(_, point) {
  46520. if (!point.hasValue())
  46521. return;
  46522. highValue = Math.max(highValue, point.highValue);
  46523. lowValue = Math.min(lowValue, point.lowValue);
  46524. openValue = openValue !== undefined ? openValue : point.openValue;
  46525. closeValue = point.closeValue !== undefined ? point.closeValue : closeValue
  46526. });
  46527. fusedPointData.argument = tick;
  46528. fusedPointData.openValue = openValue;
  46529. fusedPointData.closeValue = closeValue;
  46530. fusedPointData.highValue = highValue;
  46531. fusedPointData.lowValue = lowValue;
  46532. fusedPointData.tag = null;
  46533. switch ((this.level || "").toLowerCase()) {
  46534. case"open":
  46535. reductionLevel = openValue;
  46536. break;
  46537. case"high":
  46538. reductionLevel = highValue;
  46539. break;
  46540. case"low":
  46541. reductionLevel = lowValue;
  46542. break;
  46543. default:
  46544. reductionLevel = closeValue;
  46545. break
  46546. }
  46547. fusedPointData.reductionValue = reductionLevel;
  46548. fusedPointData.isReduction = this._checkReduction(reductionLevel);
  46549. return fusedPointData
  46550. },
  46551. _getPointSize: function() {
  46552. return DEFAULT_FINANCIAL_POINT_SIZE
  46553. },
  46554. getValueFields: function() {
  46555. var options = this._options;
  46556. return [options.openValueField || "open", options.highValueField || "high", options.lowValueField || "low", options.closeValueField || "close"]
  46557. },
  46558. getArgumentField: function() {
  46559. return this._options.argumentField || "date"
  46560. }
  46561. });
  46562. series.candlestick = _extend({}, series.stock, {_parsePointStyle: function(style, defaultColor, innerColor) {
  46563. var color = this._createPattern(style.color || innerColor, style.hatching),
  46564. base = series.stock._parsePointStyle.call(this, style, defaultColor, color);
  46565. base.fill = color;
  46566. return base
  46567. }})
  46568. })(jQuery, DevExpress);
  46569. /*! Module viz-core, file stackedSeries.js */
  46570. (function($, DX) {
  46571. var viz = DX.viz,
  46572. series = viz.core.series.mixins.chart,
  46573. areaSeries = series.area,
  46574. barSeries = series.bar,
  46575. lineSeries = series.line,
  46576. rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
  46577. _extend = $.extend,
  46578. _noop = $.noop,
  46579. baseStackedSeries = {
  46580. _processRange: _noop,
  46581. _processStackedRange: function() {
  46582. var that = this,
  46583. prevPoint;
  46584. $.each(that.getAllPoints(), function(i, p) {
  46585. rangeCalculator.processRange(that, p, prevPoint);
  46586. prevPoint = p
  46587. })
  46588. },
  46589. _getRangeData: function() {
  46590. this._processStackedRange();
  46591. return areaSeries._getRangeData.apply(this, arguments)
  46592. }
  46593. },
  46594. baseFullStackedSeries = _extend({}, baseStackedSeries, {
  46595. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  46596. this._processStackedRange();
  46597. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  46598. rangeCalculator.addLabelPaddings(this);
  46599. rangeCalculator.processFullStackedRange(this);
  46600. rangeCalculator.calculateRangeMinValue(this, zoomArgs);
  46601. return this._rangeData
  46602. },
  46603. isFullStackedSeries: function() {
  46604. return true
  46605. }
  46606. });
  46607. series.stackedline = _extend({}, lineSeries, baseStackedSeries, {_getRangeData: function() {
  46608. this._processStackedRange();
  46609. return lineSeries._getRangeData.apply(this, arguments)
  46610. }});
  46611. series.fullstackedline = _extend({}, lineSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  46612. this._processStackedRange();
  46613. var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
  46614. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  46615. rangeCalculator.addLabelPaddings(this);
  46616. rangeCalculator.processFullStackedRange(this);
  46617. return this._rangeData
  46618. }});
  46619. series.stackedbar = _extend({}, barSeries, baseStackedSeries, {_getRangeData: function() {
  46620. this._processStackedRange();
  46621. return barSeries._getRangeData.apply(this, arguments)
  46622. }});
  46623. series.fullstackedbar = _extend({}, barSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  46624. var rangeData = baseFullStackedSeries._getRangeData.apply(this, arguments);
  46625. rangeData.arg.stick = false;
  46626. return rangeData
  46627. }});
  46628. series.stackedarea = _extend({}, areaSeries, baseStackedSeries);
  46629. series.fullstackedarea = _extend({}, areaSeries, baseFullStackedSeries)
  46630. })(jQuery, DevExpress);
  46631. /*! Module viz-core, file basePoint.js */
  46632. (function($, DX) {
  46633. var viz = DX.viz,
  46634. statesConsts = viz.core.series.helpers.consts.states,
  46635. _each = $.each,
  46636. _extend = $.extend,
  46637. _isDefined = DX.utils.isDefined,
  46638. _noop = $.noop,
  46639. pointTypes = {
  46640. scatter: "symbolPoint",
  46641. line: "symbolPoint",
  46642. spline: "symbolPoint",
  46643. stepline: "symbolPoint",
  46644. stackedline: "symbolPoint",
  46645. fullstackedline: "symbolPoint",
  46646. area: "symbolPoint",
  46647. splinearea: "symbolPoint",
  46648. steparea: "symbolPoint",
  46649. stackedarea: "symbolPoint",
  46650. fullstackedarea: "symbolPoint",
  46651. rangearea: "rangeSymbolPoint",
  46652. bar: "barPoint",
  46653. stackedbar: "barPoint",
  46654. fullstackedbar: "barPoint",
  46655. rangebar: "rangeBarPoint",
  46656. bubble: "bubblePoint",
  46657. pie: "piePoint",
  46658. doughnut: "piePoint",
  46659. donut: "piePoint",
  46660. stock: "stockPoint",
  46661. candlestick: "candlestickPoint"
  46662. };
  46663. viz.core.series.points = {};
  46664. viz.core.series.points.Point = DX.Class.inherit({
  46665. ctor: function(dataItem, options) {
  46666. this.update(dataItem, options);
  46667. this._emptySettings = {
  46668. fill: null,
  46669. stroke: null,
  46670. dashStyle: null
  46671. }
  46672. },
  46673. getColor: function() {
  46674. return this._styles.normal.fill || this.series.getColor()
  46675. },
  46676. _getStyle: function() {
  46677. var styles = this._styles,
  46678. style;
  46679. if (this.isSelected())
  46680. style = styles.selection;
  46681. else if (this.isHovered())
  46682. style = styles.hover;
  46683. else {
  46684. this.fullState = statesConsts.normalMark;
  46685. style = styles.normal
  46686. }
  46687. return style
  46688. },
  46689. update: function(dataItem, options) {
  46690. this.updateOptions(options);
  46691. this.updateData(dataItem)
  46692. },
  46693. updateData: function(dataItem) {
  46694. this._updateData(dataItem);
  46695. if (!this.hasValue())
  46696. this.setInvisibility();
  46697. else {
  46698. this._updateLabelData();
  46699. this._fillStyle()
  46700. }
  46701. },
  46702. deleteMarker: function() {
  46703. this.graphic && this.graphic.detach();
  46704. this.graphic = null
  46705. },
  46706. deleteTrackerMarker: function() {
  46707. this.trackerGraphic && this.trackerGraphic.remove();
  46708. this.trackerGraphic = null
  46709. },
  46710. draw: function(renderer, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
  46711. if (this._needDeletingOnDraw) {
  46712. this.deleteMarker();
  46713. this.deleteTrackerMarker();
  46714. this._needDeletingOnDraw = false
  46715. }
  46716. if (this._needClearingOnDraw) {
  46717. this.clearMarker();
  46718. this._needClearingOnDraw = false
  46719. }
  46720. if (!this._hasGraphic())
  46721. this._options.visible && this._drawMarker(renderer, markersGroup, animationEnabled, firstDrawing);
  46722. else
  46723. this._updateMarker(animationEnabled, undefined, markersGroup);
  46724. this._drawLabel(renderer, labelsGroup)
  46725. },
  46726. applyStyle: function(style) {
  46727. if (this.graphic) {
  46728. if (style === "normal")
  46729. this.clearMarker();
  46730. else
  46731. this.graphic.toForeground();
  46732. this._updateMarker(true, this._styles[style])
  46733. }
  46734. },
  46735. setHoverState: function() {
  46736. this.series.setPointHoverState(this)
  46737. },
  46738. releaseHoverState: function(callback) {
  46739. this.series.releasePointHoverState(this, callback);
  46740. if (this.graphic)
  46741. !this.isSelected() && this.graphic.toBackground()
  46742. },
  46743. setSelectedState: function() {
  46744. this.series.setPointSelectedState(this)
  46745. },
  46746. releaseSelectedState: function() {
  46747. this.series.releasePointSelectedState(this)
  46748. },
  46749. select: function() {
  46750. this.series.selectPoint(this)
  46751. },
  46752. clearSelection: function() {
  46753. this.series.deselectPoint(this)
  46754. },
  46755. showTooltip: function() {
  46756. this.series.showPointTooltip(this)
  46757. },
  46758. hideTooltip: function() {
  46759. this.series.hidePointTooltip(this)
  46760. },
  46761. _checkLabelsChanging: function(oldType, newType) {
  46762. if (oldType) {
  46763. var isNewRange = ~newType.indexOf("range"),
  46764. isOldRange = ~oldType.indexOf("range");
  46765. return isOldRange && !isNewRange || !isOldRange && isNewRange
  46766. }
  46767. else
  46768. return false
  46769. },
  46770. updateOptions: function(newOptions) {
  46771. if (!_isDefined(newOptions))
  46772. return;
  46773. var that = this,
  46774. oldOptions = that._options,
  46775. oldType = oldOptions && oldOptions.type,
  46776. newType = newOptions.type;
  46777. if (pointTypes[oldType] !== pointTypes[newType]) {
  46778. that._needDeletingOnDraw = true;
  46779. that._needClearingOnDraw = false;
  46780. that._checkLabelsChanging(oldType, newType) && that.deleteLabel();
  46781. that._resetType(oldType);
  46782. that._setType(newType)
  46783. }
  46784. else {
  46785. that._needDeletingOnDraw = that._checkSymbol(oldOptions, newOptions);
  46786. that._needClearingOnDraw = that._checkCustomize(oldOptions, newOptions)
  46787. }
  46788. that.series = newOptions.series;
  46789. that._options = newOptions;
  46790. that._fillStyle();
  46791. that._updateLabelOptions(pointTypes[newType])
  46792. },
  46793. translate: function(translators) {
  46794. this.translators = translators || this.translators;
  46795. this.translators && this.hasValue() && this._translate(this.translators)
  46796. },
  46797. drawTracker: function(renderer, group) {
  46798. if (!this.trackerGraphic)
  46799. this._drawTrackerMarker(renderer, group);
  46800. else
  46801. this._updateTracker()
  46802. },
  46803. _checkCustomize: function(oldOptions, newOptions) {
  46804. return oldOptions.styles.usePointCustomOptions && !newOptions.styles.usePointCustomOptions
  46805. },
  46806. _getCustomLabelVisibility: function() {
  46807. if (this._styles.useLabelCustomOptions)
  46808. return this._options.label.visible ? "visible" : "hidden"
  46809. },
  46810. _getGraphicSettings: function() {
  46811. return {
  46812. x: this.graphic.settings.x || 0,
  46813. y: this.graphic.settings.y || 0,
  46814. height: this.graphic.settings.height || 0,
  46815. width: this.graphic.settings.width || 0
  46816. }
  46817. },
  46818. _resetType: function(type) {
  46819. var that = this;
  46820. if (type)
  46821. _each(viz.core.series.points.mixins[pointTypes[type]], function(methodName) {
  46822. delete that[methodName]
  46823. })
  46824. },
  46825. _setType: function(type) {
  46826. var that = this;
  46827. _each(viz.core.series.points.mixins[pointTypes[type]], function(methodName, method) {
  46828. that[methodName] = method
  46829. })
  46830. },
  46831. _prepareStatesOptions: function() {
  46832. var that = this;
  46833. if (that._options.states && that._options.states.normal)
  46834. that._populatePointShape(that._options.states.normal.r)
  46835. },
  46836. isInVisibleArea: function() {
  46837. return this.inVisibleArea
  46838. },
  46839. isSelected: function() {
  46840. return !!(this.fullState & statesConsts.selectedMark)
  46841. },
  46842. isHovered: function() {
  46843. return !!(this.fullState & statesConsts.hoverMark)
  46844. },
  46845. getOptions: function() {
  46846. return this._options
  46847. },
  46848. animate: function(complete, settings, partitionDuration) {
  46849. if (!this.graphic) {
  46850. complete && complete();
  46851. return
  46852. }
  46853. this.graphic.animate(settings, {partitionDuration: partitionDuration}, complete)
  46854. },
  46855. getCoords: function(min) {
  46856. if (!min)
  46857. return {
  46858. x: this.x,
  46859. y: this.y
  46860. };
  46861. if (!this._options.rotated)
  46862. return {
  46863. x: this.x,
  46864. y: this.minY
  46865. };
  46866. return {
  46867. x: this.minX,
  46868. y: this.y
  46869. }
  46870. },
  46871. getDefaultCoords: function() {
  46872. return !this._options.rotated ? {
  46873. x: this.x,
  46874. y: this.defaultY
  46875. } : {
  46876. x: this.defaultX,
  46877. y: this.y
  46878. }
  46879. },
  46880. _calculateVisibility: function(x, y, width, height) {
  46881. var that = this,
  46882. visibleAreaX,
  46883. visibleAreaY,
  46884. rotated = that._options.rotated;
  46885. if (that.translators) {
  46886. visibleAreaX = that.translators.x.getCanvasVisibleArea();
  46887. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  46888. 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))
  46889. that.inVisibleArea = false;
  46890. else
  46891. that.inVisibleArea = true
  46892. }
  46893. },
  46894. correctPosition: _noop,
  46895. hasValue: function() {
  46896. return this.value !== null && this.minValue !== null
  46897. },
  46898. _populatePointShape: _noop,
  46899. _checkSymbol: _noop,
  46900. hide: _noop,
  46901. show: _noop,
  46902. hideMarker: _noop,
  46903. setInvisibility: _noop,
  46904. clearVisibility: _noop,
  46905. isVisible: _noop,
  46906. resetCorrection: _noop,
  46907. correctValue: _noop,
  46908. setPercentValue: _noop,
  46909. correctCoordinates: _noop,
  46910. dispose: function() {
  46911. this.deleteMarker();
  46912. this.deleteTrackerMarker();
  46913. this.deleteLabel();
  46914. this._options = null;
  46915. this._styles = null;
  46916. this.series = null;
  46917. this.translators = null
  46918. },
  46919. getTooltipFormatObject: function(tooltip) {
  46920. var that = this,
  46921. tooltipFormatObject = that._getFormatObject(tooltip),
  46922. sharedTooltipValuesArray = [],
  46923. tooltipStackPointsFormatObject = [];
  46924. if (that.stackPoints) {
  46925. _each(that.stackPoints, function(_, point) {
  46926. if (!point.isVisible())
  46927. return;
  46928. var formatObject = point._getFormatObject(tooltip);
  46929. tooltipStackPointsFormatObject.push(point._getFormatObject(tooltip));
  46930. sharedTooltipValuesArray.push(formatObject.seriesName + ": " + formatObject.valueText)
  46931. });
  46932. _extend(tooltipFormatObject, {
  46933. points: tooltipStackPointsFormatObject,
  46934. valueText: sharedTooltipValuesArray.join("\n"),
  46935. stackName: that.stackPoints.stackName
  46936. })
  46937. }
  46938. return tooltipFormatObject
  46939. }
  46940. })
  46941. })(jQuery, DevExpress);
  46942. /*! Module viz-core, file label.js */
  46943. (function($, DX) {
  46944. var _isDefined = DX.utils.isDefined,
  46945. _extend = $.extend,
  46946. _math = Math,
  46947. _round = _math.round,
  46948. _floor = _math.floor,
  46949. _isEmptyObject = $.isEmptyObject,
  46950. _noop = $.noop,
  46951. LABEL_BACKGROUND_PADDING_X = 8,
  46952. LABEL_BACKGROUND_PADDING_Y = 4,
  46953. LABEL_OFFSET = 10,
  46954. setPositionFuncCollection = {
  46955. symbolPoint: "_setPositionForSymbol",
  46956. barPoint: "_setPositionForBar",
  46957. bubblePoint: "_setPositionForBubble",
  46958. rangeSymbolPoint: "_setPositionForSymbol",
  46959. rangeBarPoint: "_setPositionForBar",
  46960. stockPoint: "_setPositionForFinancial",
  46961. candlestickPoint: "_setPositionForFinancial"
  46962. },
  46963. checkPositionFuncCollection = {
  46964. symbolPoint: "_checkPositionForSymbol",
  46965. barPoint: "_checkPositionForBar",
  46966. bubblePoint: "_checkPositionForSymbol",
  46967. rangeSymbolPoint: "_checkPositionForSymbol",
  46968. rangeBarPoint: "_checkPositionForBar",
  46969. stockPoint: "_checkPositionForBar",
  46970. candlestickPoint: "_checkPositionForBar"
  46971. };
  46972. DX.viz.core.series.points.Label = DX.Class.inherit({
  46973. ctor: function(data, options) {
  46974. this._offset = LABEL_OFFSET;
  46975. this.updateData(data);
  46976. this.setOptions(options)
  46977. },
  46978. clearVisibility: function() {
  46979. if (this._group && this._group.settings.visibility)
  46980. this._group.applySettings({visibility: null})
  46981. },
  46982. hide: function() {
  46983. if (this._group && this._group.settings.visibility !== "hidden")
  46984. this._group.applySettings({visibility: "hidden"})
  46985. },
  46986. updateData: function(data) {
  46987. if (_isDefined(data)) {
  46988. this._data = data.formatObject;
  46989. this._initialValue = data.initialValue
  46990. }
  46991. },
  46992. updateOptions: function(options) {
  46993. this.setOptions(_extend(true, {}, {options: this._options}, options))
  46994. },
  46995. setOptions: function(newOptions) {
  46996. var that = this,
  46997. oldOptions = that._options,
  46998. newOptions = newOptions || {},
  46999. pointType = newOptions.type || "symbolPoint";
  47000. that._options = newOptions.options;
  47001. that._rotated = newOptions.rotated;
  47002. that._isFullStacked = newOptions.isFullStacked;
  47003. that._isRange = newOptions.isRange;
  47004. that._setPosition = that[setPositionFuncCollection[pointType]];
  47005. that._checkPosition = that[checkPositionFuncCollection[pointType]];
  47006. if (oldOptions) {
  47007. that._isBackgroundChanged(oldOptions.background, that._options.background) && that._deleteBackground();
  47008. that._isConnectorChanged(oldOptions.connector, that._options.connector) && that._deleteConnector()
  47009. }
  47010. },
  47011. setDataField: function(fieldName, fieldValue) {
  47012. this._data = this._data || {};
  47013. this._data[fieldName] = fieldValue
  47014. },
  47015. getData: function() {
  47016. return this._data
  47017. },
  47018. setCoords: function(coords, graphicBbox, location, visibleArea) {
  47019. this._coords = coords;
  47020. this._graphicBbox = graphicBbox;
  47021. this._visibleArea = visibleArea;
  47022. this._location = location
  47023. },
  47024. hasText: function() {
  47025. return !!this._text
  47026. },
  47027. getTextCoords: function() {
  47028. return this._text && this._text.getBBox()
  47029. },
  47030. getCoords: function() {
  47031. var coords = {},
  47032. insideGroup = this._insideGroup;
  47033. if (insideGroup) {
  47034. coords = insideGroup.getBBox();
  47035. coords.x = insideGroup.settings.translateX || 0;
  47036. coords.y = insideGroup.settings.translateY || 0
  47037. }
  47038. return coords
  47039. },
  47040. updatePosition: function(x, y) {
  47041. var settings = {},
  47042. insideGroup = this._insideGroup;
  47043. insideGroup.applySettings({
  47044. translateX: x,
  47045. translateY: y
  47046. });
  47047. this._connector && this._drawConnector()
  47048. },
  47049. _deleteElements: function() {
  47050. this._deleteConnector();
  47051. this._deleteBackground();
  47052. this._deleteText();
  47053. this._deleteGroups()
  47054. },
  47055. dispose: function() {
  47056. this._data = null;
  47057. this._options = null;
  47058. this._positioningFunction = null;
  47059. this._graphicBbox = null;
  47060. this._visibleArea = null;
  47061. this._coords = null;
  47062. this._deleteElements()
  47063. },
  47064. _deleteText: function() {
  47065. this._text && this._text.detach();
  47066. this._text = null
  47067. },
  47068. _deleteGroups: function() {
  47069. this._insideGroup = null;
  47070. this._group && this._group.detach();
  47071. this._group = null
  47072. },
  47073. _drawGroups: function(renderer, group) {
  47074. if (!this._group)
  47075. this._group = renderer.createGroup().append(group);
  47076. if (!this._insideGroup)
  47077. this._insideGroup = renderer.createGroup().append(this._group)
  47078. },
  47079. _drawText: function(renderer, text) {
  47080. if (!this._text)
  47081. this._text = renderer.createText(text, 0, 0, this._options.attributes).append(this._insideGroup);
  47082. else
  47083. this._text.applySettings({text: text}, this._options.attributes)
  47084. },
  47085. _drawBackground: function(renderer) {
  47086. var that = this,
  47087. options = that._options,
  47088. background = options.background || {},
  47089. settings;
  47090. if (that._checkBackground(background)) {
  47091. settings = _extend(that._getBackgroundSettings(), background);
  47092. if (!that._background)
  47093. that._background = renderer.createRect(settings.x, settings.y, settings.width, settings.height, 0, background).append(that._insideGroup);
  47094. else
  47095. that._background.applySettings(settings);
  47096. that._background.toBackground()
  47097. }
  47098. },
  47099. _drawConnector: function(renderer) {
  47100. var that = this,
  47101. connector = that._options.connector || {},
  47102. points;
  47103. if (that._checkConnector(connector)) {
  47104. points = that._getConnectorPoints() || [];
  47105. if (!that._connector)
  47106. that._connector = renderer.createPath(points, connector).append(that._group);
  47107. else
  47108. that._connector.applySettings(_extend({points: points}, connector));
  47109. that._connector.toBackground()
  47110. }
  47111. },
  47112. _setVisibility: function(visibility) {
  47113. this._group && this._group.applySettings({visibility: visibility})
  47114. },
  47115. draw: function(renderer, group, visibility) {
  47116. var that = this,
  47117. options = that._options,
  47118. background = options.background,
  47119. text = that._format();
  47120. if (_isDefined(text) && text !== "") {
  47121. that._drawGroups(renderer, group);
  47122. that._setVisibility(visibility);
  47123. that._drawText(renderer, text);
  47124. that._drawBackground(renderer);
  47125. that._rotateLabel();
  47126. that._setPosition();
  47127. that._drawConnector(renderer)
  47128. }
  47129. else
  47130. that._setVisibility("hidden")
  47131. },
  47132. _deleteBackground: function() {
  47133. this._background && this._background.detach();
  47134. this._background = null
  47135. },
  47136. _isBackgroundChanged: function(oldBackground, newBackground) {
  47137. return this._checkBackground(oldBackground || {}) !== this._checkBackground(newBackground || {})
  47138. },
  47139. _checkBackground: function(background) {
  47140. var hasColor = background.fill && background.fill !== "none",
  47141. hasBorder = background.strokeWidth && background.stroke && background.stroke !== "none";
  47142. return hasColor || hasBorder
  47143. },
  47144. _getBackgroundSettings: function() {
  47145. var bbox = this._text.getBBox();
  47146. return {
  47147. x: bbox.x - LABEL_BACKGROUND_PADDING_X,
  47148. y: bbox.y - LABEL_BACKGROUND_PADDING_Y,
  47149. width: bbox.width + 2 * LABEL_BACKGROUND_PADDING_X,
  47150. height: bbox.height + 2 * LABEL_BACKGROUND_PADDING_Y
  47151. }
  47152. },
  47153. _deleteConnector: function() {
  47154. this._connector && this._connector.detach();
  47155. this._connector = null
  47156. },
  47157. _isConnectorChanged: function(oldConnector, newConnector) {
  47158. return this._checkConnector(oldConnector || {}) !== this._checkConnector(newConnector || {})
  47159. },
  47160. _checkConnector: function(connector) {
  47161. return connector && connector.strokeWidth
  47162. },
  47163. _getConnectorPoints: function() {
  47164. var that = this,
  47165. rotated = that._rotated,
  47166. labelBbox = that._insideGroup.getBBox(),
  47167. graphicBbox = that._graphicBbox,
  47168. centerLabelY,
  47169. centerLabelX,
  47170. rightLabelCoord,
  47171. bottomLabelCoord,
  47172. x1,
  47173. x2,
  47174. y1,
  47175. y2;
  47176. labelBbox.x += that._insideGroup.settings.translateX || 0;
  47177. labelBbox.y += that._insideGroup.settings.translateY || 0;
  47178. centerLabelY = that._background ? labelBbox.y + labelBbox.height / 2 : null;
  47179. centerLabelX = that._background ? labelBbox.x + labelBbox.width / 2 : null,
  47180. rightLabelCoord = labelBbox.x + labelBbox.width;
  47181. bottomLabelCoord = labelBbox.y + labelBbox.height;
  47182. x1 = _floor(labelBbox.x + labelBbox.width / 2);
  47183. x2 = _floor(graphicBbox.x + graphicBbox.width / 2);
  47184. if (bottomLabelCoord < graphicBbox.y) {
  47185. y1 = centerLabelY || bottomLabelCoord;
  47186. y2 = graphicBbox.y
  47187. }
  47188. else if (labelBbox.y > graphicBbox.y + graphicBbox.height) {
  47189. y1 = centerLabelY || labelBbox.y;
  47190. y2 = graphicBbox.y + graphicBbox.height
  47191. }
  47192. else {
  47193. if (labelBbox.x > graphicBbox.x + graphicBbox.width) {
  47194. x1 = centerLabelX || labelBbox.x;
  47195. x2 = graphicBbox.x + graphicBbox.width
  47196. }
  47197. else if (rightLabelCoord < graphicBbox.x) {
  47198. x1 = centerLabelX || rightLabelCoord;
  47199. x2 = graphicBbox.x
  47200. }
  47201. else
  47202. return;
  47203. y1 = _floor(labelBbox.y + labelBbox.height / 2);
  47204. y2 = _floor(graphicBbox.y + graphicBbox.height / 2)
  47205. }
  47206. return [{
  47207. x: x1,
  47208. y: y1
  47209. }, {
  47210. x: x2,
  47211. y: y2
  47212. }]
  47213. },
  47214. _rotateLabel: function() {
  47215. var bbox = this._insideGroup.getBBox();
  47216. this._insideGroup.rotate(this._options.rotationAngle)
  47217. },
  47218. _format: function() {
  47219. var that = this,
  47220. data = that._data,
  47221. options = that._options,
  47222. formatHelper = DX.formatHelper;
  47223. data.valueText = formatHelper.format(data.value, options.format, options.precision);
  47224. data.argumentText = formatHelper.format(data.argument, options.argumentFormat, options.argumentPrecision);
  47225. if (data.percent !== undefined)
  47226. data.percentText = formatHelper.format(data.percent, "percent", options.percentPrecision);
  47227. if (data.total !== undefined)
  47228. data.totalText = formatHelper.format(data.total, options.format, options.precision);
  47229. if (data.openValue !== undefined)
  47230. data.openValueText = formatHelper.format(data.openValue, options.format, options.precision);
  47231. if (data.closeValue !== undefined)
  47232. data.closeValueText = formatHelper.format(data.closeValue, options.format, options.precision);
  47233. if (data.lowValue !== undefined)
  47234. data.lowValueText = formatHelper.format(data.lowValue, options.format, options.precision);
  47235. if (data.highValue !== undefined)
  47236. data.highValueText = formatHelper.format(data.highValue, options.format, options.precision);
  47237. if (data.reductionValue !== undefined)
  47238. data.reductionValueText = formatHelper.format(data.reductionValue, options.format, options.precision);
  47239. return options.customizeText ? options.customizeText.call(data, data) : data.valueText
  47240. },
  47241. _getOutsideLabelCoords: function(labelBbox) {
  47242. var graphicBbox = this._graphicBbox,
  47243. x = 0,
  47244. y = 0,
  47245. isTop = this._location === "top";
  47246. if (!this._rotated) {
  47247. x += graphicBbox.width / 2 + graphicBbox.x;
  47248. if (isTop)
  47249. y += graphicBbox.y - labelBbox.y - labelBbox.height - this._offset;
  47250. else
  47251. y += graphicBbox.y + graphicBbox.height - labelBbox.y + this._offset
  47252. }
  47253. else {
  47254. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  47255. if (isTop)
  47256. x += graphicBbox.x + graphicBbox.width - labelBbox.x + this._offset;
  47257. else
  47258. x += graphicBbox.x - labelBbox.x - labelBbox.width - this._offset
  47259. }
  47260. return {
  47261. x: x,
  47262. y: y
  47263. }
  47264. },
  47265. _getInsideLabelCoords: function(labelBbox) {
  47266. var graphicBbox = this._graphicBbox,
  47267. isTop = this._location === "top",
  47268. x = 0,
  47269. y = 0;
  47270. if (!this._isRange)
  47271. if (!this._rotated) {
  47272. x += graphicBbox.width / 2 + graphicBbox.x;
  47273. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2
  47274. }
  47275. else {
  47276. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  47277. x += graphicBbox.x - labelBbox.x - labelBbox.width / 2 + graphicBbox.width / 2
  47278. }
  47279. else if (!this._rotated) {
  47280. x += graphicBbox.width / 2 + graphicBbox.x;
  47281. if (isTop)
  47282. y += graphicBbox.y - labelBbox.y - labelBbox.height + this._offset + labelBbox.height;
  47283. else
  47284. y += graphicBbox.y + graphicBbox.height - labelBbox.y - this._offset - labelBbox.height
  47285. }
  47286. else {
  47287. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  47288. if (isTop)
  47289. x += graphicBbox.x + graphicBbox.width - labelBbox.x - labelBbox.width - this._offset;
  47290. else
  47291. x += graphicBbox.x - labelBbox.x + this._offset
  47292. }
  47293. return {
  47294. x: x,
  47295. y: y
  47296. }
  47297. },
  47298. _getFullstackedLabelCoords: function(labelBbox) {
  47299. var x = 0,
  47300. y = 0,
  47301. graphicBbox = this._graphicBbox;
  47302. if (!this._rotated) {
  47303. x += graphicBbox.width / 2 + graphicBbox.x;
  47304. y += this._coords.defaultY - labelBbox.y - labelBbox.height - this._offset
  47305. }
  47306. else {
  47307. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  47308. x += this._coords.defaultX - labelBbox.x + this._offset
  47309. }
  47310. return {
  47311. x: x,
  47312. y: y
  47313. }
  47314. },
  47315. _setPositionForSymbol: function() {
  47316. var that = this,
  47317. offset = that._offset,
  47318. labelBBox = that._insideGroup.getBBox(),
  47319. graphicBbox = that._graphicBbox,
  47320. isTop = that._location === "top",
  47321. correctionY = 0,
  47322. correctionX = 0,
  47323. x = 0,
  47324. y = 0;
  47325. if (!that._rotated) {
  47326. correctionX = that._coords.x;
  47327. correctionY = isTop ? -labelBBox.y - labelBBox.height - offset : graphicBbox.height - labelBBox.y + offset;
  47328. correctionY += graphicBbox.y
  47329. }
  47330. else {
  47331. correctionY = graphicBbox.y - labelBBox.y - labelBBox.height / 2 + graphicBbox.height / 2;
  47332. correctionX = isTop ? graphicBbox.width - labelBBox.x + offset : -labelBBox.x - labelBBox.width - offset;
  47333. correctionX += graphicBbox.x
  47334. }
  47335. x += correctionX + that._options.horizontalOffset;
  47336. y += correctionY + that._options.verticalOffset;
  47337. that._checkPosition({
  47338. x: labelBBox.x + x,
  47339. y: labelBBox.y + y,
  47340. height: labelBBox.height,
  47341. width: labelBBox.width
  47342. }, x, y)
  47343. },
  47344. _checkPositionForSymbol: function(labelBbox, x, y) {
  47345. var that = this,
  47346. graphicBbox = that._graphicBbox,
  47347. visibleArea = that._visibleArea,
  47348. offset = that._offset;
  47349. if (!that._rotated) {
  47350. if (visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x) {
  47351. if (visibleArea.minX > labelBbox.x && that.adjustSeriesLabels)
  47352. x += visibleArea.minX - labelBbox.x;
  47353. if (visibleArea.maxX < labelBbox.x + labelBbox.width && that.adjustSeriesLabels)
  47354. x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
  47355. if (visibleArea.minY > labelBbox.y)
  47356. y += graphicBbox.y + graphicBbox.height - labelBbox.y + offset;
  47357. if (visibleArea.maxY < labelBbox.y + labelBbox.height)
  47358. y -= labelBbox.y + labelBbox.height - graphicBbox.y + offset
  47359. }
  47360. }
  47361. else if (visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y) {
  47362. if (visibleArea.minX > labelBbox.x)
  47363. x += graphicBbox.x + graphicBbox.width - labelBbox.x + offset;
  47364. if (visibleArea.maxX < labelBbox.x + labelBbox.width)
  47365. x -= labelBbox.x + labelBbox.width - graphicBbox.x + offset;
  47366. if (visibleArea.minY > graphicBbox.y && that.adjustSeriesLabels)
  47367. y += visibleArea.minY - labelBbox.y;
  47368. if (visibleArea.maxY < labelBbox.y + labelBbox.height && that.adjustSeriesLabels)
  47369. y -= labelBbox.y + labelBbox.height - visibleArea.maxY
  47370. }
  47371. that._insideGroup.applySettings({
  47372. translateX: _round(x),
  47373. translateY: _round(y)
  47374. })
  47375. },
  47376. _setPositionForBar: function() {
  47377. var that = this,
  47378. offset = that._offset,
  47379. labelPosition = that._options.position,
  47380. labelBbox = that._insideGroup.getBBox(),
  47381. coords;
  47382. if (that._initialValue === 0 && that._isFullStacked)
  47383. coords = that._getFullstackedLabelCoords(labelBbox);
  47384. else if (labelPosition === "inside")
  47385. coords = that._getInsideLabelCoords(labelBbox);
  47386. else
  47387. coords = that._getOutsideLabelCoords(labelBbox);
  47388. coords.x += that._options.horizontalOffset;
  47389. coords.y += that._options.verticalOffset;
  47390. that._checkPosition({
  47391. x: labelBbox.x + coords.x,
  47392. y: labelBbox.y + coords.y,
  47393. height: labelBbox.height,
  47394. width: labelBbox.width
  47395. }, coords.x, coords.y)
  47396. },
  47397. _checkPositionForBar: function(labelBbox, x, y) {
  47398. var that = this,
  47399. graphicBbox = that._graphicBbox,
  47400. visibleArea = that._visibleArea;
  47401. if (visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x && visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y)
  47402. if (!that._rotated) {
  47403. if (visibleArea.minX > labelBbox.x && that.adjustSeriesLabels)
  47404. x += visibleArea.minX - labelBbox.x;
  47405. if (visibleArea.maxX < labelBbox.x + labelBbox.width && that.adjustSeriesLabels)
  47406. x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
  47407. if (visibleArea.minY > labelBbox.y)
  47408. y += visibleArea.minY - labelBbox.y;
  47409. if (visibleArea.maxY < labelBbox.y + labelBbox.height)
  47410. y -= labelBbox.y + labelBbox.height - visibleArea.maxY
  47411. }
  47412. else {
  47413. if (visibleArea.minX > labelBbox.x)
  47414. x += visibleArea.minX - labelBbox.x;
  47415. if (visibleArea.maxX < labelBbox.x + labelBbox.width)
  47416. x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
  47417. if (visibleArea.minY > labelBbox.y && that.adjustSeriesLabels)
  47418. y += visibleArea.minY - labelBbox.y;
  47419. if (visibleArea.maxY < labelBbox.y + labelBbox.height && that.adjustSeriesLabels)
  47420. y -= labelBbox.y + labelBbox.height - visibleArea.maxY
  47421. }
  47422. if (that._options.resolveLabelsOverlapping && that._options.position === "inside")
  47423. if (that._rotated) {
  47424. if (labelBbox.width > graphicBbox.width || labelBbox.height > graphicBbox.height) {
  47425. that.hide();
  47426. return
  47427. }
  47428. }
  47429. else if (labelBbox.height > graphicBbox.height || labelBbox.width > graphicBbox.width) {
  47430. that.hide();
  47431. return
  47432. }
  47433. that._insideGroup.applySettings({
  47434. translateX: _round(x),
  47435. translateY: _round(y)
  47436. })
  47437. },
  47438. _setPositionForBubble: function() {
  47439. var that = this,
  47440. labelBbox = that._insideGroup.getBBox(),
  47441. graphicBbox = that._graphicBbox,
  47442. x = 0,
  47443. y = 0;
  47444. if (that._options.position === "inside") {
  47445. x = that._coords.x;
  47446. y += graphicBbox.y + graphicBbox.height / 2 - labelBbox.y - labelBbox.height / 2;
  47447. x += that._options.horizontalOffset;
  47448. y += that._options.verticalOffset;
  47449. that._checkPosition({
  47450. x: labelBbox.x + x,
  47451. y: labelBbox.y + y,
  47452. height: labelBbox.height,
  47453. width: labelBbox.width
  47454. }, x, y)
  47455. }
  47456. else
  47457. that._setPositionForSymbol()
  47458. },
  47459. _setPositionForFinancial: function() {
  47460. var that = this,
  47461. offset = that._offset,
  47462. labelBbox = that._insideGroup.getBBox(),
  47463. coords;
  47464. coords = that._getOutsideLabelCoords(labelBbox);
  47465. coords.x += that._options.horizontalOffset;
  47466. coords.y += that._options.verticalOffset;
  47467. that._checkPosition({
  47468. x: labelBbox.x + coords.x,
  47469. y: labelBbox.y + coords.y,
  47470. height: labelBbox.height,
  47471. width: labelBbox.width
  47472. }, coords.x, coords.y)
  47473. }
  47474. })
  47475. })(jQuery, DevExpress);
  47476. /*! Module viz-core, file pieLabel.js */
  47477. (function($, DX) {
  47478. var getCosAndSin = DX.utils.getCosAndSin,
  47479. _extend = $.extend,
  47480. _math = Math,
  47481. _round = _math.round,
  47482. _max = _math.max,
  47483. _inArray = $.inArray,
  47484. _isDefined = DX.utils.isDefined,
  47485. INDENT_FROM_PIE = 30,
  47486. CONNECTOR_LENGTH = 20;
  47487. DX.viz.core.series.points.PieLabel = DX.viz.core.series.points.Label.inherit({
  47488. ctor: function(data, options) {
  47489. this.setLabelEllipsis = false;
  47490. this.indentFromPie = INDENT_FROM_PIE;
  47491. this.updateData(data);
  47492. this.setOptions(options)
  47493. },
  47494. updateData: function(data) {
  47495. if (_isDefined(data))
  47496. this._data = data.formatObject
  47497. },
  47498. setOptions: function(newOptions) {
  47499. var that = this,
  47500. oldOptions = that._options,
  47501. newOptions = newOptions || {};
  47502. that._options = newOptions.options;
  47503. that._borderWidth = newOptions.borderWidth;
  47504. if (oldOptions) {
  47505. that._isBackgroundChanged(oldOptions.background, that._options.background) && that._deleteBackground();
  47506. that._isConnectorChanged(oldOptions.connector, that._options.connector) && that._deleteConnector()
  47507. }
  47508. },
  47509. setCoords: function(coords, canvas) {
  47510. this._middleAngle = coords.middleAngle;
  47511. this._radiusOuter = coords.radiusOuter;
  47512. this._centerX = coords.centerX;
  47513. this._centerY = coords.centerY;
  47514. this._canvas = canvas
  47515. },
  47516. updatePosition: function(maxLabelLength) {
  47517. this._setPosition(maxLabelLength);
  47518. this._checkEllipsis();
  47519. this._drawBackground();
  47520. this._rotateLabel();
  47521. this._checkPosition();
  47522. this._connector && this._drawConnector()
  47523. },
  47524. dispose: function() {
  47525. this._data = null;
  47526. this._options = null;
  47527. this._canvas = null;
  47528. this._deleteElements()
  47529. },
  47530. draw: function(renderer, group, visibility) {
  47531. var that = this,
  47532. options = that._options,
  47533. background = options.background,
  47534. text = that._format();
  47535. if (_isDefined(text) && text !== "") {
  47536. that._drawGroups(renderer, group);
  47537. that._setVisibility(visibility);
  47538. that._drawText(renderer, text);
  47539. that._setPosition();
  47540. that._checkEllipsis();
  47541. that._drawBackground(renderer);
  47542. that._rotateLabel();
  47543. that._checkPosition();
  47544. that._drawConnector(renderer)
  47545. }
  47546. else
  47547. that._setVisibility("hidden")
  47548. },
  47549. _getOutsideGroupLabelPosition: function() {
  47550. this._deleteConnector();
  47551. return this._group && this._group.getBBox()
  47552. },
  47553. _setPosition: function(maxLabelLength) {
  47554. var that = this,
  47555. bbox = that._text.getBBox(),
  47556. options = that._options,
  47557. angleFunctions = getCosAndSin(that._middleAngle),
  47558. align = "center",
  47559. rad = that._radiusOuter + options.radialOffset,
  47560. canvas = that._canvas,
  47561. rightBorderX = canvas.width - canvas.right,
  47562. leftBorderX = canvas.left,
  47563. x,
  47564. y;
  47565. if (options.position === 'inside') {
  47566. rad -= that.indentFromPie;
  47567. x = that._centerX + rad * angleFunctions.cos
  47568. }
  47569. else if (options.position === 'columns') {
  47570. rad += CONNECTOR_LENGTH;
  47571. if (angleFunctions.cos >= 0) {
  47572. align = "right";
  47573. x = maxLabelLength ? that._centerX + rad + maxLabelLength : rightBorderX;
  47574. x = x > rightBorderX ? rightBorderX : x
  47575. }
  47576. else if (angleFunctions.cos < 0) {
  47577. align = "left";
  47578. x = maxLabelLength ? that._centerX - rad - maxLabelLength : leftBorderX;
  47579. x = x < leftBorderX ? leftBorderX : x
  47580. }
  47581. }
  47582. else {
  47583. rad += that.indentFromPie;
  47584. if (angleFunctions.cos > 0.1)
  47585. align = "left";
  47586. else if (angleFunctions.cos < -0.1)
  47587. align = "right";
  47588. x = that._centerX + rad * angleFunctions.cos
  47589. }
  47590. y = _round(that._text.settings.y + that._centerY - rad * angleFunctions.sin - bbox.y - bbox.height / 2);
  47591. that._text.applySettings({
  47592. x: x,
  47593. y: y,
  47594. align: align
  47595. })
  47596. },
  47597. _getConnectorPoints: function() {
  47598. var that = this,
  47599. options = that._options,
  47600. position = options.position,
  47601. angleFunctions,
  47602. rad = that._radiusOuter,
  47603. box,
  47604. x,
  47605. y,
  47606. points = [];
  47607. if (position !== "inside") {
  47608. angleFunctions = getCosAndSin(_round(that._middleAngle));
  47609. points.push({
  47610. x: _round(that._centerX + (rad - that._borderWidth) * angleFunctions.cos),
  47611. y: _round(that._centerY - (rad - that._borderWidth) * angleFunctions.sin)
  47612. });
  47613. x = _round(that._centerX + (rad + options.radialOffset + CONNECTOR_LENGTH) * angleFunctions.cos);
  47614. if (position === "columns") {
  47615. box = that._insideGroup.getBBox();
  47616. box.x = box.x + (that._insideGroup.settings.translateX || 0);
  47617. box.y = box.y + (that._insideGroup.settings.translateY || 0);
  47618. y = box.y + box.height / 2;
  47619. points.push({
  47620. x: x,
  47621. y: y
  47622. });
  47623. if (that._background)
  47624. x = box.x + box.width / 2;
  47625. else if (angleFunctions.cos < 0)
  47626. x = box.x + box.width;
  47627. else if (angleFunctions.cos > 0)
  47628. x = box.x;
  47629. points.push({
  47630. x: x,
  47631. y: y
  47632. })
  47633. }
  47634. else {
  47635. y = _round(that._centerY - (rad + options.radialOffset + CONNECTOR_LENGTH) * angleFunctions.sin);
  47636. points.push({
  47637. x: x,
  47638. y: y
  47639. })
  47640. }
  47641. }
  47642. return points
  47643. },
  47644. _rotateLabel: function() {
  47645. var that = this,
  47646. options = that._options,
  47647. shift = that._radiusOuter + options.radialOffset * 2 + CONNECTOR_LENGTH,
  47648. angleFunctions = getCosAndSin(that._middleAngle),
  47649. x,
  47650. y,
  47651. box = that._insideGroup.getBBox();
  47652. if (options.position === "inside" || options.position === "columns") {
  47653. x = box.x + box.width / 2;
  47654. y = box.y + box.height / 2
  47655. }
  47656. else {
  47657. x = that._centerX + shift * angleFunctions.cos;
  47658. y = that._centerY - shift * angleFunctions.sin
  47659. }
  47660. that._insideGroup.applySettings({
  47661. x: x,
  47662. y: y,
  47663. rotate: options.rotationAngle
  47664. })
  47665. },
  47666. _checkEllipsis: function() {
  47667. var that = this,
  47668. i,
  47669. LABEL_OFFSET = 10,
  47670. labelBox,
  47671. text,
  47672. textLength = 0,
  47673. linesLength = [],
  47674. numLastSpan = [],
  47675. maxLength,
  47676. numSpan,
  47677. index,
  47678. x,
  47679. y,
  47680. width,
  47681. rotationAngleFunction = getCosAndSin(that._options.rotationAngle),
  47682. canvas = that._canvas,
  47683. labelOptions = that._options,
  47684. angleFunctions = getCosAndSin(that._middleAngle),
  47685. borderX = that._centerX + (that._radiusOuter + CONNECTOR_LENGTH) * angleFunctions.cos;
  47686. if (!that._text.tspans || !that.setLabelEllipsis)
  47687. return;
  47688. labelBox = that._text.getBBox();
  47689. x = labelBox.x + labelBox.width < that._centerX ? labelBox.x + labelBox.width : labelBox.x;
  47690. y = labelBox.y + labelBox.height / 2;
  47691. width = labelBox.x + labelBox.width < that._centerX ? -labelBox.width : labelBox.width;
  47692. if (y + width * rotationAngleFunction.sin > canvas.height - canvas.bottom + LABEL_OFFSET || y + width * rotationAngleFunction.sin < canvas.top - LABEL_OFFSET || x + width * rotationAngleFunction.cos < canvas.left - LABEL_OFFSET || x + width * rotationAngleFunction.cos > canvas.width - canvas.right + LABEL_OFFSET || labelOptions.position === "columns" && (angleFunctions.cos < 0 && borderX < x || angleFunctions.cos > 0 && borderX > x))
  47693. for (i = 0; i < that._text.tspans.length; i++) {
  47694. textLength += that._text.tspans[i].element.getNumberOfChars();
  47695. if (!that._text.tspans[i + 1] || that._text.tspans[i + 1].settings.dy > 0) {
  47696. linesLength.push(textLength);
  47697. numLastSpan.push(i);
  47698. textLength = 0
  47699. }
  47700. }
  47701. while (y + width * rotationAngleFunction.sin > canvas.height - canvas.bottom + LABEL_OFFSET || y + width * rotationAngleFunction.sin < canvas.top - LABEL_OFFSET || x + width * rotationAngleFunction.cos < canvas.left - LABEL_OFFSET || x + width * rotationAngleFunction.cos > canvas.width - canvas.right + LABEL_OFFSET || labelOptions.position === "columns" && (angleFunctions.cos < 0 && borderX < x || angleFunctions.cos > 0 && borderX > x)) {
  47702. maxLength = _max.apply(null, linesLength);
  47703. if (maxLength === 0)
  47704. break;
  47705. index = _inArray(maxLength, linesLength);
  47706. numSpan = numLastSpan[index];
  47707. if (that._text.tspans[numSpan].element.textContent === "...") {
  47708. if (that._text.tspans[numSpan].settings.dy > 0 || !that._text.tspans[numSpan - 1])
  47709. linesLength[index] = 0;
  47710. else if (that._text.tspans[numSpan - 1]) {
  47711. that._text.tspans[numSpan].element.textContent = "";
  47712. numLastSpan[index] -= 1;
  47713. that._text.tspans[numSpan - 1].element.textContent += "..."
  47714. }
  47715. }
  47716. else {
  47717. text = that._text.tspans[numSpan].element.textContent;
  47718. text = text.substr(0, text.length - 1 - 3) + "...";
  47719. that._text.tspans[numSpan].element.textContent = text;
  47720. linesLength[index] -= 1
  47721. }
  47722. labelBox = that._text.getBBox();
  47723. x = labelBox.x + labelBox.width < that._centerX ? labelBox.x + labelBox.width : labelBox.x;
  47724. y = labelBox.y + labelBox.height / 2;
  47725. width = labelBox.x + labelBox.width < that._centerX ? -labelBox.width : labelBox.width
  47726. }
  47727. },
  47728. _checkPosition: function() {
  47729. var that = this,
  47730. group = that._insideGroup,
  47731. box = group.getBBox(),
  47732. canvas = that._canvas,
  47733. x = 0,
  47734. y = 0;
  47735. if (box.y + box.height > canvas.height - canvas.bottom)
  47736. y = canvas.height - box.y - box.height - canvas.bottom;
  47737. else if (box.y < canvas.top)
  47738. y = canvas.top - box.y;
  47739. if (box.x + box.width > canvas.width - canvas.right)
  47740. x = canvas.width - canvas.right - box.x - box.width;
  47741. else if (box.x < canvas.left)
  47742. x = canvas.left - box.x;
  47743. group.applySettings({
  47744. translateX: x,
  47745. translateY: y
  47746. })
  47747. },
  47748. setPosition: function(position) {
  47749. this._options.position = position
  47750. },
  47751. getPosition: function() {
  47752. return this._options.position
  47753. }
  47754. })
  47755. })(jQuery, DevExpress);
  47756. /*! Module viz-core, file symbolPoint.js */
  47757. (function($, DX) {
  47758. var viz = DevExpress.viz,
  47759. core = viz.core,
  47760. series = core.series,
  47761. _extend = $.extend,
  47762. _each = $.each,
  47763. _isNumber = DX.utils.isNumber,
  47764. _isDefined = DX.utils.isDefined,
  47765. _isEmptyObject = $.isEmptyObject,
  47766. _math = Math,
  47767. _round = _math.round,
  47768. _floor = _math.floor,
  47769. _ceil = _math.ceil,
  47770. DEFAULT_IMAGE_WIDTH = 20,
  47771. DEFAULT_IMAGE_HEIGHT = 20,
  47772. CANVAS_POSITION_DEFAULT = "canvas_position_default";
  47773. series.points.mixins = series.points.mixins || {};
  47774. series.points.mixins.symbolPoint = {
  47775. deleteLabel: function() {
  47776. this._label.dispose();
  47777. this._label = null
  47778. },
  47779. _hasGraphic: function() {
  47780. return this.graphic
  47781. },
  47782. _clearTrackerVisibility: function() {
  47783. if (this.trackerGraphic && this.trackerGraphic.settings.visibility)
  47784. this.trackerGraphic.applySettings({visibility: null})
  47785. },
  47786. clearVisibility: function() {
  47787. if (this.graphic && this.graphic.settings.visibility)
  47788. this.graphic.applySettings({visibility: null});
  47789. this._clearTrackerVisibility();
  47790. this._label.clearVisibility()
  47791. },
  47792. isVisible: function() {
  47793. return this.inVisibleArea && this.series.isVisible()
  47794. },
  47795. _setTrackerInvisibility: function() {
  47796. if (this.trackerGraphic && this.trackerGraphic.settings.visibility !== "hidden")
  47797. this.trackerGraphic.applySettings({visibility: "hidden"})
  47798. },
  47799. setInvisibility: function() {
  47800. if (this.graphic && this.graphic.settings.visibility !== "hidden")
  47801. this.graphic.applySettings({visibility: "hidden"});
  47802. this._setTrackerInvisibility();
  47803. this._label.hide()
  47804. },
  47805. clearMarker: function() {
  47806. this.graphic && this.graphic.applySettings(this._emptySettings)
  47807. },
  47808. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  47809. this._label.adjustSeriesLabels = adjustSeriesLabels
  47810. },
  47811. _getLabelOptions: function(type) {
  47812. var options = this._options;
  47813. return {
  47814. options: options.label,
  47815. rotated: options.rotated,
  47816. type: type,
  47817. isFullStacked: options.series.isFullStackedSeries(),
  47818. isRange: options.type.indexOf("range") !== -1
  47819. }
  47820. },
  47821. _createLabel: function() {
  47822. this._label = core.CoreFactory.createLabel(this._options.type)
  47823. },
  47824. _updateLabelData: function() {
  47825. this._label.updateData({
  47826. formatObject: this._getLabelFormatObject(),
  47827. initialValue: this.initialValue
  47828. })
  47829. },
  47830. _updateLabelOptions: function(type) {
  47831. !this._label && this._createLabel();
  47832. this._label.setOptions(this._getLabelOptions(type))
  47833. },
  47834. _checkImage: function(image) {
  47835. return _isDefined(image) && (typeof image === "string" || _isDefined(image.url))
  47836. },
  47837. _fillStyle: function() {
  47838. this._styles = this._options.styles
  47839. },
  47840. _checkSymbol: function(oldOptions, newOptions) {
  47841. var oldSymbol = oldOptions.symbol,
  47842. newSymbol = newOptions.symbol,
  47843. symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
  47844. imageChanged = this._checkImage(oldOptions.image) !== this._checkImage(newOptions.image);
  47845. if (symbolChanged || imageChanged)
  47846. return true;
  47847. return false
  47848. },
  47849. _getSquareMarkerCoords: function(radius) {
  47850. return [{
  47851. x: -radius,
  47852. y: -radius
  47853. }, {
  47854. x: radius,
  47855. y: -radius
  47856. }, {
  47857. x: radius,
  47858. y: radius
  47859. }, {
  47860. x: -radius,
  47861. y: radius
  47862. }, {
  47863. x: -radius,
  47864. y: -radius
  47865. }]
  47866. },
  47867. _getPolygonMarkerCoords: function(radius) {
  47868. var r = _ceil(radius);
  47869. return [{
  47870. x: -r,
  47871. y: 0
  47872. }, {
  47873. x: 0,
  47874. y: -r
  47875. }, {
  47876. x: r,
  47877. y: 0
  47878. }, {
  47879. x: 0,
  47880. y: r
  47881. }, {
  47882. x: -r,
  47883. y: 0
  47884. }]
  47885. },
  47886. _getTriangleMarkerCoords: function(radius) {
  47887. return [{
  47888. x: -radius,
  47889. y: -radius
  47890. }, {
  47891. x: radius,
  47892. y: -radius
  47893. }, {
  47894. x: 0,
  47895. y: radius
  47896. }, {
  47897. x: -radius,
  47898. y: -radius
  47899. }]
  47900. },
  47901. _getCrossMarkerCoords: function(radius) {
  47902. var r = _ceil(radius),
  47903. floorHalfRadius = _floor(r / 2),
  47904. ceilHalfRadius = _ceil(r / 2);
  47905. return [{
  47906. x: -r,
  47907. y: -floorHalfRadius
  47908. }, {
  47909. x: -floorHalfRadius,
  47910. y: -r
  47911. }, {
  47912. x: 0,
  47913. y: -ceilHalfRadius
  47914. }, {
  47915. x: floorHalfRadius,
  47916. y: -r
  47917. }, {
  47918. x: r,
  47919. y: -floorHalfRadius
  47920. }, {
  47921. x: ceilHalfRadius,
  47922. y: 0
  47923. }, {
  47924. x: r,
  47925. y: floorHalfRadius
  47926. }, {
  47927. x: floorHalfRadius,
  47928. y: r
  47929. }, {
  47930. x: 0,
  47931. y: ceilHalfRadius
  47932. }, {
  47933. x: -floorHalfRadius,
  47934. y: r
  47935. }, {
  47936. x: -r,
  47937. y: floorHalfRadius
  47938. }, {
  47939. x: -ceilHalfRadius,
  47940. y: 0
  47941. }]
  47942. },
  47943. _populatePointShape: function(symbol, radius) {
  47944. switch (symbol) {
  47945. case"square":
  47946. return this._getSquareMarkerCoords(radius);
  47947. case"polygon":
  47948. return this._getPolygonMarkerCoords(radius);
  47949. case"triangle":
  47950. return this._getTriangleMarkerCoords(radius);
  47951. case"cross":
  47952. return this._getCrossMarkerCoords(radius)
  47953. }
  47954. },
  47955. correctValue: function(correction) {
  47956. if (this.hasValue()) {
  47957. this.value = this.initialValue + correction;
  47958. this.minValue = correction;
  47959. this.translate()
  47960. }
  47961. },
  47962. resetCorrection: function() {
  47963. this.value = this.initialValue;
  47964. this.minValue = CANVAS_POSITION_DEFAULT
  47965. },
  47966. _getTranslates: function(animationEnabled) {
  47967. var translateX,
  47968. translateY;
  47969. translateX = this.x;
  47970. translateY = this.y;
  47971. if (animationEnabled)
  47972. if (this._options.rotated)
  47973. translateX = this.defaultX;
  47974. else
  47975. translateY = this.defaultY;
  47976. return {
  47977. x: translateX,
  47978. y: translateY
  47979. }
  47980. },
  47981. _createImageMarker: function(renderer, settings, options) {
  47982. var url,
  47983. width,
  47984. height,
  47985. offsetY,
  47986. attr = {
  47987. location: "center",
  47988. translateX: settings.attr.translateX,
  47989. translateY: settings.attr.translateY,
  47990. visibility: settings.attr.visibility
  47991. };
  47992. url = options.url ? options.url.toString() : options.toString();
  47993. width = options.width || DEFAULT_IMAGE_WIDTH;
  47994. height = options.height || DEFAULT_IMAGE_HEIGHT;
  47995. return renderer.createImage(-_round(width * 0.5), -_round(height * 0.5), width, height, url, attr)
  47996. },
  47997. _createSymbolMarker: function(renderer, pointSettings, animationEnabled) {
  47998. var marker,
  47999. options = this._options;
  48000. switch (options.symbol) {
  48001. case"circle":
  48002. marker = renderer.createCircle(0, 0, pointSettings.r, pointSettings.attr);
  48003. break;
  48004. case"square":
  48005. case"polygon":
  48006. case"triangle":
  48007. case"cross":
  48008. marker = renderer.createArea(pointSettings.points, pointSettings.attr);
  48009. break
  48010. }
  48011. return marker
  48012. },
  48013. _createMarker: function(renderer, group, image, settings, animationEnabled) {
  48014. var marker = this._checkImage(image) ? this._createImageMarker(renderer, settings, image) : this._createSymbolMarker(renderer, settings, animationEnabled);
  48015. marker && marker.append(group);
  48016. return marker
  48017. },
  48018. _getSymbolBbox: function(x, y, r) {
  48019. var bbox = {};
  48020. bbox.x = x - r;
  48021. bbox.y = y - r;
  48022. bbox.width = bbox.height = r * 2;
  48023. return bbox
  48024. },
  48025. _getImageBbox: function(x, y) {
  48026. var bbox = {},
  48027. image = this._options.image,
  48028. width = image.width || DEFAULT_IMAGE_WIDTH,
  48029. height = image.height || DEFAULT_IMAGE_HEIGHT;
  48030. bbox.x = x - _round(width / 2);
  48031. bbox.y = y - _round(height / 2);
  48032. bbox.width = width;
  48033. bbox.height = height;
  48034. return bbox
  48035. },
  48036. _getGraphicBbox: function() {
  48037. var options = this._options,
  48038. x = this.x,
  48039. y = this.y,
  48040. bbox;
  48041. if (options.visible)
  48042. bbox = this._checkImage(options.image) ? this._getImageBbox(x, y) : this._getSymbolBbox(x, y, options.styles.normal.r);
  48043. else
  48044. bbox = {
  48045. x: x,
  48046. y: y,
  48047. width: 0,
  48048. height: 0
  48049. };
  48050. return bbox
  48051. },
  48052. _drawLabel: function(renderer, group) {
  48053. var that = this,
  48054. customVisibility = that._getCustomLabelVisibility(),
  48055. visibleArea,
  48056. translators = that.translators;
  48057. if ((that._options.series.getLabelVisibility() || customVisibility) && that.hasValue()) {
  48058. if (translators)
  48059. visibleArea = {
  48060. minX: translators.x.getCanvasVisibleArea().min,
  48061. maxX: translators.x.getCanvasVisibleArea().max,
  48062. minY: translators.y.getCanvasVisibleArea().min,
  48063. maxY: translators.y.getCanvasVisibleArea().max
  48064. };
  48065. that._label.setCoords({
  48066. x: that.x,
  48067. y: that.y
  48068. }, that._getGraphicBbox(), that._getLabelPosition(), visibleArea);
  48069. that._label.draw(renderer, group, customVisibility)
  48070. }
  48071. else
  48072. that._label.hide()
  48073. },
  48074. _drawMarker: function(renderer, group, animationEnabled) {
  48075. var that = this,
  48076. options = that._options,
  48077. translates = that._getTranslates(animationEnabled),
  48078. marker,
  48079. style = that._getStyle(),
  48080. pointAttributes = _extend({
  48081. translateX: translates.x,
  48082. translateY: translates.y
  48083. }, style),
  48084. pointSettings = {
  48085. attr: pointAttributes,
  48086. points: that._populatePointShape(options.symbol, style.r),
  48087. r: style.r
  48088. };
  48089. marker = that._createMarker(renderer, group, options.image, pointSettings, animationEnabled);
  48090. that.graphic = marker
  48091. },
  48092. _drawTrackerMarker: function(renderer, group) {
  48093. var radius = this._options.trackerR || this.storeTrackerR();
  48094. this.trackerGraphic = renderer.createCircle(this.x, this.y, radius).append(group);
  48095. this.trackerGraphic.data({point: this})
  48096. },
  48097. getTooltipCoords: function() {
  48098. var coords;
  48099. if (this.graphic)
  48100. coords = {
  48101. x: this.x,
  48102. y: this.y,
  48103. offset: this.graphic.getBBox().height / 2
  48104. };
  48105. else
  48106. coords = {
  48107. x: this.x,
  48108. y: this.y,
  48109. offset: 0
  48110. };
  48111. return coords
  48112. },
  48113. hasValue: function() {
  48114. return this.value !== null && this.minValue !== null
  48115. },
  48116. setPercentValue: function(total) {
  48117. var valuePercent = this.value / total || 0,
  48118. percent = valuePercent,
  48119. minValuePercent = this.minValue / total || 0;
  48120. percent -= _isNumber(this.minValue) ? minValuePercent : 0;
  48121. this._label.setDataField("percent", percent);
  48122. this._label.setDataField("total", total);
  48123. if (this._options.series.isFullStackedSeries() && this.hasValue()) {
  48124. this.value = valuePercent;
  48125. this.minValue = !minValuePercent ? this.minValue : minValuePercent;
  48126. this.translate()
  48127. }
  48128. },
  48129. storeTrackerR: function() {
  48130. var navigator = window.navigator,
  48131. r = this._options.styles.normal.r,
  48132. minTrackerSize;
  48133. navigator = this.__debug_navigator || navigator;
  48134. this.__debug_browserNavigator = navigator;
  48135. minTrackerSize = "ontouchstart" in window || navigator.msPointerEnabled && navigator.msMaxTouchPoints || navigator.pointerEnabled && navigator.maxTouchPoints ? 20 : 6;
  48136. this._options.trackerR = r < minTrackerSize ? minTrackerSize : r;
  48137. return this._options.trackerR
  48138. },
  48139. _translate: function(translators) {
  48140. var that = this,
  48141. mainAxis = that._options.rotated ? "x" : "y",
  48142. upperMainAxis = mainAxis.toUpperCase(),
  48143. mainTranslator = translators[mainAxis],
  48144. axis = that._options.rotated ? "y" : "x";
  48145. that[mainAxis] = mainTranslator.translate(that.value);
  48146. that[axis] = translators[axis].translate(that.argument);
  48147. that["min" + upperMainAxis] = mainTranslator.translate(that.minValue);
  48148. that["default" + upperMainAxis] = mainTranslator.translate(CANVAS_POSITION_DEFAULT);
  48149. that._calculateVisibility(that.x, that.y);
  48150. that._prepareStatesOptions()
  48151. },
  48152. _changeData: function(data) {
  48153. this.value = this.initialValue = this.originalValue = data.value;
  48154. this.argument = this.initialArgument = this.originalArgument = data.argument;
  48155. this.minValue = this.initialMinValue = this.originalMinValue = _isDefined(data.minValue) ? data.minValue : CANVAS_POSITION_DEFAULT;
  48156. this.tag = data.tag;
  48157. this.index = data.index
  48158. },
  48159. _updateData: function(data) {
  48160. if (this.argument !== data.argument || this.value !== data.value || this.tag !== data.tag)
  48161. this._changeData(data)
  48162. },
  48163. _getImageSettings: function(image) {
  48164. return {
  48165. href: image.url || image.toString(),
  48166. width: image.width || DEFAULT_IMAGE_WIDTH,
  48167. height: image.height || DEFAULT_IMAGE_HEIGHT
  48168. }
  48169. },
  48170. _updateMarker: function(animationEnabled, style) {
  48171. var that = this,
  48172. options = that._options,
  48173. style = style || this._getStyle(),
  48174. settings,
  48175. image = options.image;
  48176. if (that._checkImage(image))
  48177. settings = _extend({}, {visibility: style.visibility}, that._getImageSettings(image));
  48178. else
  48179. settings = _extend({}, style, {points: that._populatePointShape(options.symbol, style.r)});
  48180. if (!animationEnabled) {
  48181. settings.translateX = that.x;
  48182. settings.translateY = that.y
  48183. }
  48184. that.graphic.applySettings(settings)
  48185. },
  48186. _updateTracker: function() {
  48187. this.trackerGraphic.applySettings({
  48188. cx: this.x,
  48189. cy: this.y,
  48190. r: this.storeTrackerR()
  48191. })
  48192. },
  48193. _getLabelFormatObject: function() {
  48194. return {
  48195. argument: this.initialArgument,
  48196. value: this.initialValue,
  48197. originalArgument: this.originalArgument,
  48198. originalValue: this.originalValue,
  48199. seriesName: this._options.series.name,
  48200. point: this
  48201. }
  48202. },
  48203. _getLabelPosition: function() {
  48204. if (this._options.series.isFullStackedSeries() || this.initialValue > 0)
  48205. return "top";
  48206. else
  48207. return "bottom"
  48208. },
  48209. _getFormatObject: function(tooltip) {
  48210. var labelFormatObject = this._label.getData(),
  48211. valueObject = {
  48212. argumentText: tooltip.formatValue(this.initialArgument, "argument"),
  48213. valueText: tooltip.formatValue(this.initialValue)
  48214. },
  48215. percentObject = _isDefined(labelFormatObject.percent) ? {percentText: tooltip.formatValue(labelFormatObject.percent, "percent")} : {},
  48216. totalObject = _isDefined(labelFormatObject.total) ? {totalText: tooltip.formatValue(labelFormatObject.total)} : {};
  48217. return _extend({}, labelFormatObject, valueObject, percentObject, totalObject)
  48218. }
  48219. }
  48220. })(jQuery, DevExpress);
  48221. /*! Module viz-core, file barPoint.js */
  48222. (function($, DX) {
  48223. var viz = DevExpress.viz,
  48224. points = viz.core.series.points.mixins,
  48225. _extend = $.extend,
  48226. _math = Math,
  48227. _round = _math.round,
  48228. _abs = _math.abs,
  48229. _min = _math.min,
  48230. CANVAS_POSITION_DEFAULT = "canvas_position_default",
  48231. DEFAULT_BAR_TRACKER_SIZE = 9,
  48232. CORRECTING_BAR_TRACKER_VALUE = 4;
  48233. points.barPoint = _extend({}, points.symbolPoint, {
  48234. correctCoordinates: function(correctOptions) {
  48235. var correction = correctOptions.offset - _round(correctOptions.width / 2),
  48236. rotated = this._options.rotated,
  48237. valueSelector = rotated ? "height" : "width",
  48238. correctionSelector = (rotated ? "y" : "x") + "Correction";
  48239. this[valueSelector] = correctOptions.width;
  48240. this[correctionSelector] = correction
  48241. },
  48242. _getGraphicBbox: function() {
  48243. var bbox = {};
  48244. bbox.x = this.x;
  48245. bbox.y = this.y;
  48246. bbox.width = this.width;
  48247. bbox.height = this.height;
  48248. return bbox
  48249. },
  48250. _getLabelPosition: function() {
  48251. var position,
  48252. invertX = this.translators.x.getBusinessRange().invert,
  48253. invertY = this.translators.y.getBusinessRange().invert,
  48254. isDiscreteValue = this.series.valueAxisType === "discrete",
  48255. isFullStacked = this.series.isFullStackedSeries(),
  48256. notVerticalInverted = !isDiscreteValue && (this.initialValue >= 0 && !invertY || this.initialValue < 0 && invertY) || isDiscreteValue && !invertY || isFullStacked,
  48257. notHorizontalInverted = !isDiscreteValue && (this.initialValue >= 0 && !invertX || this.initialValue < 0 && invertX) || isDiscreteValue && !invertX || isFullStacked;
  48258. if (!this._options.rotated)
  48259. position = notVerticalInverted ? "top" : "bottom";
  48260. else
  48261. position = notHorizontalInverted ? "top" : "bottom";
  48262. return position
  48263. },
  48264. _drawLabel: function(renderer, group) {
  48265. var that = this,
  48266. options = that._options,
  48267. coords,
  48268. commonVisibility = options.series.getLabelVisibility(),
  48269. customVisibility = that._getCustomLabelVisibility(),
  48270. visibleArea,
  48271. translators = that.translators;
  48272. if (that.hasValue() && (options.label.showForZeroValues || that.initialValue) && (customVisibility || commonVisibility)) {
  48273. coords = {
  48274. x: that.x,
  48275. y: that.y,
  48276. defaultX: that.defaultX,
  48277. defaultY: that.defaultY
  48278. };
  48279. if (translators)
  48280. visibleArea = {
  48281. minX: translators.x.getCanvasVisibleArea().min,
  48282. maxX: translators.x.getCanvasVisibleArea().max,
  48283. minY: translators.y.getCanvasVisibleArea().min,
  48284. maxY: translators.y.getCanvasVisibleArea().max
  48285. };
  48286. that._label.setCoords(coords, that._getGraphicBbox(), that._getLabelPosition(), visibleArea);
  48287. that._label.draw(renderer, group, customVisibility)
  48288. }
  48289. else
  48290. that._label.hide()
  48291. },
  48292. _drawMarker: function(renderer, group, animationEnabled) {
  48293. var style = this._getStyle(),
  48294. x = this.x,
  48295. y = this.y,
  48296. width = this.width,
  48297. height = this.height;
  48298. if (animationEnabled)
  48299. if (this._options.rotated) {
  48300. width = 0;
  48301. x = this.defaultX
  48302. }
  48303. else {
  48304. height = 0;
  48305. y = this.defaultY
  48306. }
  48307. this.graphic = renderer.createRect(x, y, width, height, this._options.cornerRadius, style).append(group)
  48308. },
  48309. _getSettingsForTracker: function() {
  48310. var that = this,
  48311. y = that.y,
  48312. height = that.height,
  48313. x = that.x,
  48314. width = that.width;
  48315. if (that._options.rotated) {
  48316. if (width === 1) {
  48317. width = DEFAULT_BAR_TRACKER_SIZE;
  48318. x -= CORRECTING_BAR_TRACKER_VALUE
  48319. }
  48320. }
  48321. else if (height === 1) {
  48322. height = DEFAULT_BAR_TRACKER_SIZE;
  48323. y -= CORRECTING_BAR_TRACKER_VALUE
  48324. }
  48325. return {
  48326. x: x,
  48327. y: y,
  48328. width: width,
  48329. height: height
  48330. }
  48331. },
  48332. _drawTrackerMarker: function(renderer, group) {
  48333. var settings = this._getSettingsForTracker();
  48334. this.trackerGraphic = renderer.createRect(settings.x, settings.y, settings.width, settings.height, this._options.cornerRadius).append(group);
  48335. this.trackerGraphic.data({point: this})
  48336. },
  48337. getGraphicSettings: function() {
  48338. return {
  48339. x: this.graphic.settings.x || 0,
  48340. y: this.graphic.settings.y || 0,
  48341. height: this.graphic.settings.height || 0,
  48342. width: this.graphic.settings.width || 0
  48343. }
  48344. },
  48345. getTooltipCoords: function() {
  48346. var x = this.x + this.width / 2,
  48347. y = this.y + this.height / 2;
  48348. return {
  48349. x: x,
  48350. y: y,
  48351. offset: 0
  48352. }
  48353. },
  48354. _truncateCoord: function(coord, minBounce, maxBounce) {
  48355. if (coord < minBounce)
  48356. return minBounce;
  48357. if (coord > maxBounce)
  48358. return maxBounce;
  48359. return coord
  48360. },
  48361. _translate: function(translators) {
  48362. var that = this,
  48363. rotated = that._options.rotated,
  48364. valAxis = rotated ? "x" : "y",
  48365. argAxis = rotated ? "y" : "x",
  48366. valIntervalName = rotated ? "width" : "height",
  48367. argIntervalName = rotated ? "height" : "width",
  48368. argTranslator = translators[argAxis],
  48369. valTranslator = translators[valAxis],
  48370. argVisibleArea = argTranslator.getCanvasVisibleArea(),
  48371. valVisibleArea = valTranslator.getCanvasVisibleArea(),
  48372. arg,
  48373. minArg,
  48374. val,
  48375. minVal;
  48376. arg = minArg = argTranslator.translate(that.argument) + (that[argAxis + "Correction"] || 0);
  48377. val = valTranslator.translate(that.value);
  48378. minVal = valTranslator.translate(that.minValue);
  48379. that[valIntervalName] = _abs(val - minVal);
  48380. that._calculateVisibility(rotated ? _min(val, minVal) : _min(arg, minArg), rotated ? _min(arg, minArg) : _min(val, minVal), that.width, that.height);
  48381. val = that._truncateCoord(val, valVisibleArea.min, valVisibleArea.max);
  48382. minVal = that._truncateCoord(minVal, valVisibleArea.min, valVisibleArea.max);
  48383. that[argAxis] = arg;
  48384. that["min" + argAxis.toUpperCase()] = minArg;
  48385. that[valIntervalName] = _abs(val - minVal);
  48386. that[valAxis] = _min(val, minVal) + (that[valAxis + "Correction"] || 0);
  48387. that["min" + valAxis.toUpperCase()] = minVal + (that[valAxis + "Correction"] || 0);
  48388. that["default" + valAxis.toUpperCase()] = valTranslator.translate(CANVAS_POSITION_DEFAULT);
  48389. if (that.inVisibleArea) {
  48390. if (that[argAxis] < argVisibleArea.min) {
  48391. that[argIntervalName] = that[argIntervalName] - (argVisibleArea.min - that[argAxis]);
  48392. that[argAxis] = argVisibleArea.min;
  48393. that["min" + argAxis.toUpperCase()] = argVisibleArea.min
  48394. }
  48395. if (that[argAxis] + that[argIntervalName] > argVisibleArea.max)
  48396. that[argIntervalName] = argVisibleArea.max - that[argAxis]
  48397. }
  48398. },
  48399. _updateMarker: function(animationEnabled, style) {
  48400. var style = style || this._getStyle(),
  48401. attributes = _extend({}, style);
  48402. if (!animationEnabled) {
  48403. attributes.x = this.x;
  48404. attributes.y = this.y;
  48405. attributes.width = this.width;
  48406. attributes.height = this.height
  48407. }
  48408. else
  48409. attributes.sharpEdges = false;
  48410. this.graphic.applySettings(attributes)
  48411. },
  48412. _updateTracker: function() {
  48413. this.trackerGraphic.applySettings(this._getSettingsForTracker())
  48414. }
  48415. })
  48416. })(jQuery, DevExpress);
  48417. /*! Module viz-core, file bubblePoint.js */
  48418. (function($, DX) {
  48419. var viz = DX.viz,
  48420. points = viz.core.series.points.mixins,
  48421. _extend = $.extend,
  48422. MIN_BUBBLE_HEIGHT = 20;
  48423. points.bubblePoint = _extend({}, points.symbolPoint, {
  48424. correctCoordinates: function(diameter) {
  48425. this.bubbleSize = diameter / 2
  48426. },
  48427. _drawMarker: function(renderer, group, animationEnabled) {
  48428. var style = this._getStyle(),
  48429. attr = _extend({
  48430. translateX: this.x,
  48431. translateY: this.y
  48432. }, style),
  48433. marker = renderer.createCircle(0, 0, animationEnabled ? 0 : this.bubbleSize, attr).append(group);
  48434. this.graphic = marker
  48435. },
  48436. _drawTrackerMarker: function(renderer, group) {
  48437. this.trackerGraphic = renderer.createCircle(this.x, this.y, this.bubbleSize).append(group);
  48438. this.trackerGraphic.data({point: this})
  48439. },
  48440. getTooltipCoords: function() {
  48441. if (this.graphic) {
  48442. var height = this.graphic.getBBox().height;
  48443. return {
  48444. x: this.x,
  48445. y: this.y,
  48446. offset: height < MIN_BUBBLE_HEIGHT ? height / 2 : 0
  48447. }
  48448. }
  48449. },
  48450. _getLabelFormatObject: function() {
  48451. var symbolMethods = points.symbolPoint,
  48452. formatObject = symbolMethods._getLabelFormatObject.call(this);
  48453. formatObject.size = this.initialSize;
  48454. return formatObject
  48455. },
  48456. _updateData: function(data) {
  48457. var symbolMethods = points.symbolPoint;
  48458. if (this.argument !== data.argument || this.value !== data.value || this.size !== data.size || this.tag !== data.tag) {
  48459. symbolMethods._changeData.call(this, data);
  48460. this.size = this.initialSize = data.size
  48461. }
  48462. },
  48463. _getGraphicBbox: function() {
  48464. return this._getSymbolBbox(this.x, this.y, this.bubbleSize)
  48465. },
  48466. _updateMarker: function(animationEnabled, style) {
  48467. var style = style || this._getStyle();
  48468. if (!animationEnabled)
  48469. style = $.extend({
  48470. r: this.bubbleSize,
  48471. translateX: this.x,
  48472. translateY: this.y
  48473. }, style);
  48474. this.graphic.applySettings(style)
  48475. },
  48476. _updateTracker: function() {
  48477. this.trackerGraphic.applySettings({
  48478. cx: this.x,
  48479. cy: this.y,
  48480. r: this.bubbleSize
  48481. })
  48482. },
  48483. _getFormatObject: function(tooltip) {
  48484. var symbolMethods = points.symbolPoint,
  48485. formatObject = symbolMethods._getFormatObject.call(this, tooltip);
  48486. formatObject.sizeText = tooltip.formatValue(this.initialSize);
  48487. return formatObject
  48488. }
  48489. })
  48490. })(jQuery, DevExpress);
  48491. /*! Module viz-core, file piePoint.js */
  48492. (function($, DX) {
  48493. var viz = DevExpress.viz,
  48494. points = viz.core.series.points.mixins,
  48495. _extend = $.extend,
  48496. _round = Math.round,
  48497. _getCosAndSin = DX.utils.getCosAndSin;
  48498. points.piePoint = _extend({}, points.symbolPoint, {
  48499. _populatePointShape: function(target, deltaRadius) {
  48500. var angleFunctions = _getCosAndSin(point.middleAngle);
  48501. target.x = point.centerX - ~~(deltaRadius * angleFunctions.cos);
  48502. target.y = point.centerY + ~~(deltaRadius * angleFunctions.sin);
  48503. target.outerRadius = this.radiusOuter + deltaRadius;
  48504. target.innerRadius = this.radiusInner;
  48505. target.startAngle = this.toAngle;
  48506. target.endAngle = this.fromAngle
  48507. },
  48508. _changeData: function(data) {
  48509. var that = this;
  48510. that.value = that.initialValue = that.originalValue = data.value;
  48511. that.argument = that.initialArgument = that.originalArgument = data.argument;
  48512. that.minValue = that.initialMinValue = that.originalMinValue = DevExpress.utils.isDefined(data.minValue) ? data.minValue : 0;
  48513. that.tag = data.tag;
  48514. that._visible = true;
  48515. that.index = data.index
  48516. },
  48517. animate: function(complete, duration, step) {
  48518. this.graphic.animate({
  48519. x: this.centerX,
  48520. y: this.centerY,
  48521. outerRadius: this.radiusOuter,
  48522. innerRadius: this.radiusInner,
  48523. startAngle: this.toAngle,
  48524. endAngle: this.fromAngle
  48525. }, {
  48526. partitionDuration: duration,
  48527. step: step
  48528. }, complete)
  48529. },
  48530. correctPosition: function(correction) {
  48531. this.radiusInner = correction.radiusInner;
  48532. this.radiusOuter = correction.radiusOuter;
  48533. this.centerX = correction.centerX;
  48534. this.centerY = correction.centerY
  48535. },
  48536. correctValue: function(correction, percent, base) {
  48537. this.value = (base || this.initialValue) + correction;
  48538. this.minValue = correction;
  48539. this.percent = percent;
  48540. this._label.setDataField("percent", percent)
  48541. },
  48542. _getLabelOptions: function() {
  48543. var options = this._options,
  48544. series = options.series,
  48545. seriesStyle = this._options.styles.normal,
  48546. borderWidth = series._options.containerBackgroundColor === seriesStyle.stroke ? _round(seriesStyle.strokeWidth / 2) : _round(-seriesStyle.strokeWidth / 2);
  48547. return {
  48548. options: options.label,
  48549. borderWidth: borderWidth
  48550. }
  48551. },
  48552. _updateLabelData: function() {
  48553. this._label.updateData({formatObject: this._getLabelFormatObject()})
  48554. },
  48555. _updateLabelOptions: function() {
  48556. !this._label && this._createLabel();
  48557. this._label.setOptions(this._getLabelOptions())
  48558. },
  48559. _drawLabel: function(renderer, group) {
  48560. var commonVisibility = this._options.series.getLabelVisibility(),
  48561. customVisibility = this._getCustomLabelVisibility();
  48562. if ((commonVisibility || customVisibility) && this.hasValue()) {
  48563. this._label.setCoords({
  48564. middleAngle: this.middleAngle,
  48565. radiusOuter: this.radiusOuter,
  48566. centerX: this.centerX,
  48567. centerY: this.centerY
  48568. }, this._options.series.canvas);
  48569. this._label.draw(renderer, group, customVisibility)
  48570. }
  48571. else
  48572. this._label.hide()
  48573. },
  48574. _drawMarker: function(renderer, group, animationEnabled, firstDrawing) {
  48575. var styles = this._getStyle(),
  48576. radiusOuter = this.radiusOuter,
  48577. radiusInner = this.radiusInner,
  48578. fromAngle = this.fromAngle,
  48579. toAngle = this.toAngle;
  48580. if (animationEnabled) {
  48581. radiusInner = radiusOuter = 0;
  48582. if (!firstDrawing)
  48583. fromAngle = toAngle = this.shiftedAngle
  48584. }
  48585. this.graphic = renderer.createArc(this.centerX, this.centerY, radiusOuter, radiusInner, toAngle, fromAngle, styles).append(group)
  48586. },
  48587. _drawTrackerMarker: function(renderer, group) {
  48588. this.trackerGraphic = renderer.createArc(this.centerX, this.centerY, this.radiusOuter, this.radiusInner, this.toAngle, this.fromAngle).append(group);
  48589. this.trackerGraphic.data({point: this})
  48590. },
  48591. getTooltipCoords: function() {
  48592. var angleFunctions = _getCosAndSin(this.middleAngle);
  48593. return {
  48594. x: this.centerX + (this.radiusInner + (this.radiusOuter - this.radiusInner) / 2) * angleFunctions.cos,
  48595. y: this.centerY - (this.radiusInner + (this.radiusOuter - this.radiusInner) / 2) * angleFunctions.sin,
  48596. offset: 0
  48597. }
  48598. },
  48599. _translate: function(translator) {
  48600. var angle = this.shiftedAngle || 0;
  48601. this.fromAngle = translator.translate(this.minValue) + angle;
  48602. this.toAngle = translator.translate(this.value) + angle;
  48603. this.middleAngle = translator.translate((this.value - this.minValue) / 2 + this.minValue) + angle;
  48604. if (!this.isVisible())
  48605. this.middleAngle = this.toAngle = this.fromAngle = this.fromAngle || angle
  48606. },
  48607. _updateMarker: function(animationEnabled, style) {
  48608. style = style || this._getStyle();
  48609. if (!animationEnabled)
  48610. style = _extend({
  48611. x: this.centerX,
  48612. y: this.centerY,
  48613. outerRadius: this.radiusOuter,
  48614. innerRadius: this.radiusInner,
  48615. startAngle: this.toAngle,
  48616. endAngle: this.fromAngle
  48617. }, style);
  48618. this.graphic.applySettings(style)
  48619. },
  48620. _updateTracker: function() {
  48621. this.trackerGraphic.applySettings({
  48622. x: this.centerX,
  48623. y: this.centerY,
  48624. outerRadius: this.radiusOuter,
  48625. innerRadius: this.radiusInner,
  48626. startAngle: this.toAngle,
  48627. endAngle: this.fromAngle
  48628. })
  48629. },
  48630. getLegendStyles: function() {
  48631. return this._styles.legendStyles
  48632. },
  48633. isInVisibleArea: function() {
  48634. return true
  48635. },
  48636. hide: function() {
  48637. if (this._visible) {
  48638. this._visible = false;
  48639. this.hideTooltip();
  48640. this._options.visibilityChanged(this)
  48641. }
  48642. },
  48643. show: function() {
  48644. if (!this._visible) {
  48645. this._visible = true;
  48646. this._options.visibilityChanged(this)
  48647. }
  48648. },
  48649. setInvisibility: function() {
  48650. this._setTrackerInvisibility();
  48651. this._label.hide()
  48652. },
  48653. isVisible: function() {
  48654. return this._visible
  48655. },
  48656. _getFormatObject: function(tooltip) {
  48657. var symbolMethods = points.symbolPoint,
  48658. formatObject = symbolMethods._getFormatObject.call(this, tooltip);
  48659. formatObject.percent = this.percent;
  48660. formatObject.percentText = tooltip.formatValue(this.percent, "percent");
  48661. return formatObject
  48662. },
  48663. getColor: function() {
  48664. return this._styles.normal.fill
  48665. }
  48666. })
  48667. })(jQuery, DevExpress);
  48668. /*! Module viz-core, file rangeSymbolPoint.js */
  48669. (function($, DX) {
  48670. var viz = DevExpress.viz,
  48671. points = viz.core.series.points.mixins,
  48672. _extend = $.extend,
  48673. _isDefined = DX.utils.isDefined,
  48674. _math = Math,
  48675. _abs = _math.abs,
  48676. _min = _math.min,
  48677. _max = _math.max,
  48678. _round = _math.round,
  48679. DEFAULT_IMAGE_WIDTH = 20,
  48680. DEFAULT_IMAGE_HEIGHT = 20;
  48681. points.rangeSymbolPoint = _extend({}, points.symbolPoint, {
  48682. deleteLabel: function() {
  48683. this._topLabel.dispose();
  48684. this._topLabel = null;
  48685. this._bottomLabel.dispose();
  48686. this._bottomLabel = null
  48687. },
  48688. hideMarker: function(type) {
  48689. var marker = this.graphic && this.graphic[type + "Marker"],
  48690. label = this["_" + type + "Label"];
  48691. if (marker && marker.settings.visibility !== "hidden")
  48692. marker.applySettings({visibility: "hidden"});
  48693. label.hide()
  48694. },
  48695. setInvisibility: function() {
  48696. this.hideMarker("top");
  48697. this.hideMarker("bottom");
  48698. this._setTrackerInvisibility()
  48699. },
  48700. clearVisibility: function() {
  48701. var graphic = this.graphic;
  48702. if (graphic) {
  48703. if (graphic.topMarker && graphic.topMarker.settings.visibility)
  48704. graphic.topMarker.applySettings({visibility: null});
  48705. if (graphic.bottomMarker && graphic.bottomMarker.settings.visibility)
  48706. graphic.bottomMarker.applySettings({visibility: null})
  48707. }
  48708. this._clearTrackerVisibility();
  48709. this._topLabel.clearVisibility();
  48710. this._bottomLabel.clearVisibility()
  48711. },
  48712. clearMarker: function() {
  48713. if (this.graphic) {
  48714. this.graphic.topMarker && this.graphic.topMarker.applySettings(this._emptySettings);
  48715. this.graphic.bottomMarker && this.graphic.bottomMarker.applySettings(this._emptySettings)
  48716. }
  48717. },
  48718. _getLabelPosition: function(markerType) {
  48719. var position,
  48720. rotated = this._options.rotated,
  48721. invertY = this.translators.y.getBusinessRange().invert,
  48722. invertX = this.translators.x.getBusinessRange().invert,
  48723. isDiscreteValue = this._options.series._options.valueAxisType === "discrete",
  48724. notInverted = isDiscreteValue && (!invertY && !rotated || invertX && rotated) || !isDiscreteValue && this.value > this.minValue && (!invertY && !rotated || !invertX && rotated);
  48725. if (markerType === "top")
  48726. position = notInverted ? "top" : "bottom";
  48727. else
  48728. position = notInverted ? "bottom" : "top";
  48729. return position
  48730. },
  48731. _getLabelMinFormatObject: function() {
  48732. return {
  48733. index: 0,
  48734. argument: this.initialArgument,
  48735. value: this.initialMinValue,
  48736. seriesName: this._options.series.name,
  48737. originalValue: this.originalMinValue,
  48738. originalArgument: this.originalArgument,
  48739. point: this
  48740. }
  48741. },
  48742. _updateLabelData: function() {
  48743. var maxFormatObject = this._getLabelFormatObject();
  48744. maxFormatObject.index = 1;
  48745. this._topLabel.updateData({
  48746. formatObject: maxFormatObject,
  48747. initialValue: this.initialValue
  48748. });
  48749. this._bottomLabel.updateData({
  48750. formatObject: this._getLabelMinFormatObject(),
  48751. initialValue: this.initialMinValue
  48752. })
  48753. },
  48754. _updateLabelOptions: function(type) {
  48755. var options = this._getLabelOptions(type);
  48756. (!this._topLabel || !this._bottomLabel) && this._createLabel();
  48757. this._topLabel.setOptions(options);
  48758. this._bottomLabel.setOptions(options)
  48759. },
  48760. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  48761. this._topLabel.adjustSeriesLabels = adjustSeriesLabels;
  48762. this._bottomLabel.adjustSeriesLabels = adjustSeriesLabels
  48763. },
  48764. _createLabel: function() {
  48765. this._topLabel = viz.core.CoreFactory.createLabel();
  48766. this._bottomLabel = viz.core.CoreFactory.createLabel()
  48767. },
  48768. _getLabelCoords: function(location) {
  48769. var coords = {},
  48770. isTop = location === "top";
  48771. if (!this._options.rotated) {
  48772. coords.x = this.x;
  48773. coords.y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)
  48774. }
  48775. else {
  48776. coords.x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);
  48777. coords.y = this.y
  48778. }
  48779. return coords
  48780. },
  48781. _getGraphicBbox: function(location) {
  48782. var options = this._options,
  48783. rotated = options.rotated,
  48784. isTop = location === "top",
  48785. images = this._getImage(options.image),
  48786. image = isTop ? this._checkImage(images.top) : this._checkImage(images.bottom),
  48787. bbox,
  48788. x,
  48789. y;
  48790. if (!rotated) {
  48791. x = this.x;
  48792. y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)
  48793. }
  48794. else {
  48795. x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);
  48796. y = this.y
  48797. }
  48798. if (options.visible)
  48799. bbox = image ? this._getImageBbox(x, y) : this._getSymbolBbox(x, y, options.styles.normal.r);
  48800. else
  48801. bbox = {
  48802. x: x,
  48803. y: y,
  48804. width: 0,
  48805. height: 0
  48806. };
  48807. return bbox
  48808. },
  48809. _checkOverlay: function(bottomCoord, topCoord, topValue) {
  48810. return bottomCoord < topCoord + topValue
  48811. },
  48812. _getOverlayCorrections: function(type, topCoords, bottomCoords) {
  48813. var isVertical = type === "vertical",
  48814. coordSelector = isVertical ? "y" : "x",
  48815. valueSelector = isVertical ? "height" : "width",
  48816. visibleArea = this.translators[coordSelector].getCanvasVisibleArea(),
  48817. minBound = visibleArea.min,
  48818. maxBound = visibleArea.max,
  48819. delta = _round((topCoords[coordSelector] + topCoords[valueSelector] - bottomCoords[coordSelector]) / 2),
  48820. coord1 = topCoords[coordSelector] - delta,
  48821. coord2 = bottomCoords[coordSelector] + delta;
  48822. if (coord1 < minBound) {
  48823. delta = minBound - topCoords[coordSelector];
  48824. coord1 += delta;
  48825. coord2 += delta
  48826. }
  48827. else if (coord2 + bottomCoords[valueSelector] > maxBound) {
  48828. delta = -(bottomCoords[coordSelector] + bottomCoords[valueSelector] - maxBound);
  48829. coord1 += delta;
  48830. coord2 += delta
  48831. }
  48832. return {
  48833. coord1: coord1,
  48834. coord2: coord2
  48835. }
  48836. },
  48837. _checkLabelsOverlay: function(topLocation) {
  48838. var that = this,
  48839. topCoords = that._topLabel.getCoords(),
  48840. bottomCoords = that._bottomLabel.getCoords(),
  48841. corrections = {};
  48842. if (!that._options.rotated) {
  48843. if (topLocation === "top") {
  48844. if (this._checkOverlay(bottomCoords.y, topCoords.y, topCoords.height)) {
  48845. corrections = this._getOverlayCorrections("vertical", topCoords, bottomCoords);
  48846. that._topLabel.updatePosition(undefined, corrections.coord1);
  48847. that._bottomLabel.updatePosition(undefined, corrections.coord2)
  48848. }
  48849. }
  48850. else if (this._checkOverlay(topCoords.y, bottomCoords.y, bottomCoords.height)) {
  48851. corrections = this._getOverlayCorrections("vertical", bottomCoords, topCoords);
  48852. that._topLabel.updatePosition(undefined, corrections.coord2);
  48853. that._bottomLabel.updatePosition(undefined, corrections.coord1)
  48854. }
  48855. }
  48856. else if (topLocation === "top") {
  48857. if (this._checkOverlay(topCoords.x, bottomCoords.x, bottomCoords.width)) {
  48858. corrections = this._getOverlayCorrections("horizontal", bottomCoords, topCoords);
  48859. that._topLabel.updatePosition(corrections.coord2);
  48860. that._bottomLabel.updatePosition(corrections.coord1)
  48861. }
  48862. }
  48863. else if (this._checkOverlay(bottomCoords.x, topCoords.x, topCoords.width)) {
  48864. corrections = this._getOverlayCorrections("horizontal", topCoords, bottomCoords);
  48865. that._topLabel.updatePosition(corrections.coord1);
  48866. that._bottomLabel.updatePosition(corrections.coord2)
  48867. }
  48868. },
  48869. _drawLabel: function(renderer, group) {
  48870. var topCoords,
  48871. bottomCoords,
  48872. rotated = this._options.rotated,
  48873. topLocation = this._getLabelPosition("top"),
  48874. bottomLocation = this._getLabelPosition("bottom"),
  48875. isInside = this._options.label.position === "inside",
  48876. topPosition = isInside ? bottomLocation : topLocation,
  48877. bottomPosition = isInside ? topLocation : bottomLocation,
  48878. translators = this.translators,
  48879. visibleArea,
  48880. customVisibility = this._getCustomLabelVisibility(),
  48881. commonVisibility = this._options.series.getLabelVisibility();
  48882. if ((commonVisibility || customVisibility) && this.hasValue()) {
  48883. if (translators)
  48884. visibleArea = {
  48885. minX: translators.x.getCanvasVisibleArea().min,
  48886. maxX: translators.x.getCanvasVisibleArea().max,
  48887. minY: translators.y.getCanvasVisibleArea().min,
  48888. maxY: translators.y.getCanvasVisibleArea().max
  48889. };
  48890. this._topLabel.setCoords(this._getLabelCoords(topLocation), this._getGraphicBbox(topLocation), topPosition, visibleArea);
  48891. this._bottomLabel.setCoords(this._getLabelCoords(bottomLocation), this._getGraphicBbox(bottomLocation), bottomPosition, visibleArea);
  48892. this.visibleTopMarker && this._topLabel.draw(renderer, group, customVisibility);
  48893. this.visibleBottomMarker && this._bottomLabel.draw(renderer, group, customVisibility);
  48894. this._checkLabelsOverlay(topLocation)
  48895. }
  48896. else {
  48897. this._topLabel.hide();
  48898. this._bottomLabel.hide()
  48899. }
  48900. },
  48901. _getImage: function(imageOption) {
  48902. var image = {};
  48903. if (_isDefined(imageOption))
  48904. if (typeof imageOption === "string")
  48905. image.top = image.bottom = imageOption;
  48906. else {
  48907. image.top = {
  48908. url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMaxPoint,
  48909. width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMaxPoint,
  48910. height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMaxPoint
  48911. };
  48912. image.bottom = {
  48913. url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMinPoint,
  48914. width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMinPoint,
  48915. height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMinPoint
  48916. }
  48917. }
  48918. return image
  48919. },
  48920. _checkSymbol: function(oldOptions, newOptions) {
  48921. var oldSymbol = oldOptions.symbol,
  48922. newSymbol = newOptions.symbol,
  48923. symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
  48924. oldImages = this._getImage(oldOptions.image),
  48925. newImages = this._getImage(newOptions.image),
  48926. topImageChanged = this._checkImage(oldImages.top) !== this._checkImage(newImages.top),
  48927. bottomImageChanged = this._checkImage(oldImages.bottom) !== this._checkImage(newImages.bottom);
  48928. return symbolChanged || topImageChanged || bottomImageChanged
  48929. },
  48930. _getSettingsForTwoMarkers: function(style) {
  48931. var that = this,
  48932. options = that._options,
  48933. settings = {},
  48934. x = options.rotated ? _min(that.x, that.minX) : that.x,
  48935. y = options.rotated ? that.y : _min(that.y, that.minY),
  48936. radius = style.r,
  48937. points = that._populatePointShape(options.symbol, radius);
  48938. settings.top = {
  48939. r: radius,
  48940. points: points,
  48941. attr: _extend({
  48942. translateX: x + that.width,
  48943. translateY: y
  48944. }, style)
  48945. };
  48946. settings.bottom = {
  48947. r: radius,
  48948. points: points,
  48949. attr: _extend({
  48950. translateX: x,
  48951. translateY: y + that.height
  48952. }, style)
  48953. };
  48954. return settings
  48955. },
  48956. _hasGraphic: function() {
  48957. return this.graphic && this.graphic.topMarker && this.graphic.bottomMarker
  48958. },
  48959. _drawOneMarker: function(renderer, markerType, imageSettings, settings) {
  48960. if (this.graphic[markerType])
  48961. this._updateOneMarker(markerType, settings);
  48962. else
  48963. this.graphic[markerType] = this._createMarker(renderer, this.graphic, imageSettings, settings)
  48964. },
  48965. _drawMarker: function(renderer, group, animationEnabled, style) {
  48966. var that = this,
  48967. style = style || that._getStyle(),
  48968. settings = that._getSettingsForTwoMarkers(style),
  48969. image = that._getImage(that._options.image);
  48970. if (that._checkImage(image.top))
  48971. settings.top = that._getImageSettings(settings.top, image.top);
  48972. if (that._checkImage(image.bottom))
  48973. settings.bottom = that._getImageSettings(settings.bottom, image.bottom);
  48974. that.graphic = that.graphic || renderer.createGroup().append(group);
  48975. that.visibleTopMarker && that._drawOneMarker(renderer, 'topMarker', image.top, settings.top);
  48976. that.visibleBottomMarker && that._drawOneMarker(renderer, 'bottomMarker', image.bottom, settings.bottom)
  48977. },
  48978. _getSettingsForTracker: function(radius) {
  48979. var that = this,
  48980. options = that._options,
  48981. x = options.rotated ? _min(that.x, that.minX) - radius : that.x - radius,
  48982. y = options.rotated ? that.y - radius : _min(that.y, that.minY) - radius,
  48983. width = that.width + 2 * radius,
  48984. height = that.height + 2 * radius;
  48985. return {
  48986. translateX: x,
  48987. translateY: y,
  48988. width: width,
  48989. height: height
  48990. }
  48991. },
  48992. _drawTrackerMarker: function(renderer, group) {
  48993. var that = this,
  48994. options = that._options,
  48995. radius = options.trackerR || that.storeTrackerR(),
  48996. settings = that._getSettingsForTracker(radius),
  48997. attr = {
  48998. translateX: settings.translateX,
  48999. translateY: settings.translateY
  49000. };
  49001. that.trackerGraphic = renderer.createRect(0, 0, settings.width, settings.height, 0, attr).append(group);
  49002. that.trackerGraphic.data({point: that})
  49003. },
  49004. isInVisibleArea: function() {
  49005. var that = this,
  49006. minArgument = _min(that.minX, that.x) || that.x,
  49007. maxArgument = _max(that.minX, that.x) || that.x,
  49008. maxValue = _max(that.minY, that.y) || that.y,
  49009. minValue = _min(that.minY, that.y) || that.y,
  49010. notVisibleBothMarkersRight,
  49011. notVisibleBothMarkersLeft,
  49012. notVisibleBothMarkersBottom,
  49013. notVisibleBothMarkersTop,
  49014. visibleTopMarker = true,
  49015. visibleBottomMarker = true,
  49016. visibleRangeArea = true,
  49017. visibleAreaX,
  49018. visibleAreaY;
  49019. if (that.translators) {
  49020. visibleAreaX = that.translators.x.getCanvasVisibleArea();
  49021. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  49022. notVisibleBothMarkersRight = visibleAreaX.max < minArgument && visibleAreaX.max < maxArgument;
  49023. notVisibleBothMarkersLeft = visibleAreaX.min > minArgument && visibleAreaX.min > maxArgument;
  49024. notVisibleBothMarkersTop = visibleAreaY.min > minValue && visibleAreaY.min > maxValue;
  49025. notVisibleBothMarkersBottom = visibleAreaY.max < minValue && visibleAreaY.max < maxValue;
  49026. if (notVisibleBothMarkersTop || notVisibleBothMarkersBottom || notVisibleBothMarkersRight || notVisibleBothMarkersLeft)
  49027. visibleTopMarker = visibleBottomMarker = visibleRangeArea = false;
  49028. else if (!that._options.rotated) {
  49029. visibleTopMarker = visibleAreaY.min < minValue && visibleAreaY.max > minValue;
  49030. visibleBottomMarker = visibleAreaY.min < maxValue && visibleAreaY.max > maxValue
  49031. }
  49032. else {
  49033. visibleBottomMarker = visibleAreaX.min < minArgument && visibleAreaX.max > minArgument;
  49034. visibleTopMarker = visibleAreaX.min < maxArgument && visibleAreaX.max > maxArgument
  49035. }
  49036. }
  49037. that.visibleTopMarker = visibleTopMarker;
  49038. that.visibleBottomMarker = visibleBottomMarker;
  49039. that.visibleRangeArea = visibleRangeArea;
  49040. return visibleRangeArea
  49041. },
  49042. getTooltipCoords: function() {
  49043. var that = this,
  49044. x,
  49045. y,
  49046. min,
  49047. max,
  49048. minValue,
  49049. visibleAreaX = that.translators.x.getCanvasVisibleArea(),
  49050. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  49051. if (!that._options.rotated) {
  49052. minValue = _min(that.y, that.minY);
  49053. x = that.x;
  49054. min = visibleAreaY.min > minValue ? visibleAreaY.min : minValue;
  49055. max = visibleAreaY.max < minValue + that.height ? visibleAreaY.max : minValue + that.height;
  49056. y = min + (max - min) / 2
  49057. }
  49058. else {
  49059. minValue = _min(that.x, that.minX);
  49060. y = that.y;
  49061. min = visibleAreaX.min > minValue ? visibleAreaX.min : minValue;
  49062. max = visibleAreaX.max < minValue + that.width ? visibleAreaX.max : minValue + that.width;
  49063. x = min + (max - min) / 2
  49064. }
  49065. return {
  49066. x: x,
  49067. y: y,
  49068. offset: 0
  49069. }
  49070. },
  49071. _translate: function(translators) {
  49072. var symbolMethods = points.symbolPoint;
  49073. this.minX = this.minY = translators.y.translate(this.minValue);
  49074. symbolMethods._translate.call(this, translators);
  49075. this.height = this._options.rotated ? 0 : _abs(this.minY - this.y);
  49076. this.width = this._options.rotated ? _abs(this.x - this.minX) : 0
  49077. },
  49078. _updateData: function(data) {
  49079. if (this.argument !== data.argument || this.value !== data.value || this.minValue !== data.minValue || this.tag !== data.tag) {
  49080. this._changeData(data);
  49081. this.minValue = this.initialMinValue = this.originalMinValue = data.minValue
  49082. }
  49083. },
  49084. _getImageSettings: function(settings, image) {
  49085. var x = settings.attr.translateX,
  49086. y = settings.attr.translateY;
  49087. return {
  49088. href: image.url || image.toString(),
  49089. width: image.width || DEFAULT_IMAGE_WIDTH,
  49090. height: image.height || DEFAULT_IMAGE_HEIGHT,
  49091. attr: {
  49092. translateX: x,
  49093. translateY: y
  49094. }
  49095. }
  49096. },
  49097. _updateOneMarker: function(markerType, settings) {
  49098. this.graphic && this.graphic[markerType] && this.graphic[markerType].applySettings(_extend({}, settings, settings.attr))
  49099. },
  49100. _updateMarker: function(animationEnabled, style) {
  49101. this._drawMarker(undefined, undefined, undefined, style)
  49102. },
  49103. _updateTracker: function() {
  49104. var radius = this.storeTrackerR(),
  49105. settings = this._getSettingsForTracker(radius);
  49106. this.trackerGraphic.applySettings(settings)
  49107. },
  49108. _getFormatObject: function(tooltip) {
  49109. var minValue = tooltip.formatValue(this.initialMinValue),
  49110. value = tooltip.formatValue(this.initialValue);
  49111. return {
  49112. argument: this.initialArgument,
  49113. argumentText: tooltip.formatValue(this.initialArgument, "argument"),
  49114. valueText: minValue + " - " + value,
  49115. rangeValue1Text: minValue,
  49116. rangeValue2Text: value,
  49117. rangeValue1: this.initialMinValue,
  49118. rangeValue2: this.initialValue,
  49119. seriesName: this.series.name,
  49120. point: this,
  49121. originalMinValue: this.originalMinValue,
  49122. originalValue: this.originalValue,
  49123. originalArgument: this.originalArgument
  49124. }
  49125. }
  49126. })
  49127. })(jQuery, DevExpress);
  49128. /*! Module viz-core, file rangeBarPoint.js */
  49129. (function($, DX) {
  49130. var viz = DevExpress.viz,
  49131. points = viz.core.series.points.mixins,
  49132. _isDefined = DX.utils.isDefined,
  49133. rangeSymbolPointMethods = points.rangeSymbolPoint,
  49134. _extend = $.extend;
  49135. points.rangeBarPoint = _extend({}, points.barPoint, {
  49136. deleteLabel: rangeSymbolPointMethods.deleteLabel,
  49137. _getFormatObject: rangeSymbolPointMethods._getFormatObject,
  49138. setAdjustSeriesLabels: rangeSymbolPointMethods.setAdjustSeriesLabels,
  49139. clearVisibility: function() {
  49140. if (this.graphic && this.graphic.settings.visibility)
  49141. this.graphic.applySettings({visibility: null});
  49142. this._topLabel.clearVisibility();
  49143. this._bottomLabel.clearVisibility()
  49144. },
  49145. setInvisibility: function() {
  49146. if (this.graphic && this.graphic.settings.visibility !== "hidden")
  49147. this.graphic.applySettings({visibility: "hidden"});
  49148. this._topLabel.hide();
  49149. this._bottomLabel.hide()
  49150. },
  49151. _translate: function(translator) {
  49152. var barMethods = points.barPoint;
  49153. barMethods._translate.call(this, translator);
  49154. if (this._options.rotated)
  49155. this.width = this.width || 1;
  49156. else
  49157. this.height = this.height || 1
  49158. },
  49159. _updateData: rangeSymbolPointMethods._updateData,
  49160. _getLabelPosition: rangeSymbolPointMethods._getLabelPosition,
  49161. _getLabelMinFormatObject: rangeSymbolPointMethods._getLabelMinFormatObject,
  49162. _updateLabelData: rangeSymbolPointMethods._updateLabelData,
  49163. _updateLabelOptions: rangeSymbolPointMethods._updateLabelOptions,
  49164. _createLabel: rangeSymbolPointMethods._createLabel,
  49165. _checkOverlay: rangeSymbolPointMethods._checkOverlay,
  49166. _getOverlayCorrections: rangeSymbolPointMethods._getOverlayCorrections,
  49167. _drawLabel: function(renderer, group) {
  49168. var topCoords,
  49169. bottomCoords,
  49170. rotated = this._options.rotated,
  49171. topLocation = this._getLabelPosition("top"),
  49172. bottomLocation = this._getLabelPosition("bottom"),
  49173. bbox = this._getGraphicBbox(),
  49174. coords = {
  49175. x: this.x,
  49176. y: this.y,
  49177. defaultX: this.defaultX,
  49178. defaultY: this.defaultY
  49179. },
  49180. translators = this.translators,
  49181. visibleArea,
  49182. customVisibility = this._getCustomLabelVisibility(),
  49183. commonVisibility = this._options.series.getLabelVisibility();
  49184. if ((customVisibility || commonVisibility) && this.hasValue()) {
  49185. if (translators)
  49186. visibleArea = {
  49187. minX: translators.x.getCanvasVisibleArea().min,
  49188. maxX: translators.x.getCanvasVisibleArea().max,
  49189. minY: translators.y.getCanvasVisibleArea().min,
  49190. maxY: translators.y.getCanvasVisibleArea().max
  49191. };
  49192. this._topLabel.setCoords(coords, bbox, topLocation, visibleArea);
  49193. this._bottomLabel.setCoords(coords, bbox, bottomLocation, visibleArea);
  49194. this._topLabel.draw(renderer, group, customVisibility);
  49195. this._bottomLabel.draw(renderer, group, customVisibility);
  49196. rangeSymbolPointMethods._checkLabelsOverlay.call(this, topLocation)
  49197. }
  49198. else {
  49199. this._topLabel.hide();
  49200. this._bottomLabel.hide()
  49201. }
  49202. }
  49203. })
  49204. })(jQuery, DevExpress);
  49205. /*! Module viz-core, file candlestickPoint.js */
  49206. (function($, DX) {
  49207. var viz = DevExpress.viz,
  49208. points = viz.core.series.points.mixins,
  49209. _isNumeric = $.isNumeric,
  49210. _extend = $.extend,
  49211. _math = Math,
  49212. _abs = _math.abs,
  49213. _min = _math.min,
  49214. _max = _math.max,
  49215. _round = _math.round,
  49216. DEFAULT_FINANCIAL_TRACKER_MARGIN = 2;
  49217. points.candlestickPoint = _extend({}, points.barPoint, {
  49218. _getContinuousPoints: function(minValueName, maxValueName) {
  49219. var that = this,
  49220. x = that.x,
  49221. createPoint = that._options.rotated ? function(x, y) {
  49222. return {
  49223. x: y,
  49224. y: x
  49225. }
  49226. } : function(x, y) {
  49227. return {
  49228. x: x,
  49229. y: y
  49230. }
  49231. },
  49232. width = that.width,
  49233. min = that[minValueName],
  49234. max = that[maxValueName],
  49235. points;
  49236. if (min === max)
  49237. points = [createPoint(x, that.highY), createPoint(x, that.lowY), createPoint(x, that.closeY), createPoint(x - width / 2, that.closeY), createPoint(x + width / 2, that.closeY), createPoint(x, that.closeY)];
  49238. else
  49239. points = [createPoint(x, that.highY), createPoint(x, max), createPoint(x + width / 2, max), createPoint(x + width / 2, min), createPoint(x, min), createPoint(x, that.lowY), createPoint(x, min), createPoint(x - width / 2, min), createPoint(x - width / 2, max), createPoint(x, max)];
  49240. return points
  49241. },
  49242. _getCategoryPoints: function(y) {
  49243. var that = this,
  49244. x = that.x,
  49245. createPoint = that._options.rotated ? function(x, y) {
  49246. return {
  49247. x: y,
  49248. y: x
  49249. }
  49250. } : function(x, y) {
  49251. return {
  49252. x: x,
  49253. y: y
  49254. }
  49255. };
  49256. return [createPoint(x, that.highY), createPoint(x, that.lowY), createPoint(x, y), createPoint(x - that.width / 2, y), createPoint(x + that.width / 2, y), createPoint(x, y)]
  49257. },
  49258. _getPoints: function() {
  49259. var that = this,
  49260. points,
  49261. minValueName,
  49262. maxValueName,
  49263. openValue = that.openValue,
  49264. closeValue = that.closeValue;
  49265. if (_isNumeric(openValue) && _isNumeric(closeValue)) {
  49266. minValueName = openValue > closeValue ? "closeY" : "openY";
  49267. maxValueName = openValue > closeValue ? "openY" : "closeY";
  49268. points = that._getContinuousPoints(minValueName, maxValueName)
  49269. }
  49270. else if (openValue === closeValue)
  49271. points = [{
  49272. x: that.x,
  49273. y: that.highY
  49274. }, {
  49275. x: that.x,
  49276. y: that.lowY
  49277. }];
  49278. else
  49279. points = that._getCategoryPoints(_isNumeric(openValue) ? that.openY : that.closeY);
  49280. return points
  49281. },
  49282. getColor: function() {
  49283. return this._isReduction ? this._options.reduction.color : this._styles.normal.stroke || this.series.getColor()
  49284. },
  49285. _drawMarkerInGroup: function(group, attributes, renderer) {
  49286. this.graphic = renderer.createArea(this._getPoints(), attributes).append(group)
  49287. },
  49288. _fillStyle: function() {
  49289. var styles = this._options.styles;
  49290. if (this._isReduction && this._isPositive)
  49291. this._styles = styles.reductionPositive;
  49292. else if (this._isReduction)
  49293. this._styles = styles.reduction;
  49294. else if (this._isPositive)
  49295. this._styles = styles.positive;
  49296. else
  49297. this._styles = styles
  49298. },
  49299. _getMinTrackerWidth: function() {
  49300. return 1 + 2 * this._styles.normal.strokeWidth
  49301. },
  49302. correctCoordinates: function(correctOptions) {
  49303. var minWidth = this._getMinTrackerWidth(),
  49304. maxWidth = 10;
  49305. this.width = correctOptions.width < minWidth ? minWidth : correctOptions.width > maxWidth ? maxWidth : correctOptions.width;
  49306. this.xCorrection = correctOptions.offset
  49307. },
  49308. _getMarkerGroup: function(group) {
  49309. var markerGroup;
  49310. if (this._isReduction && this._isPositive)
  49311. markerGroup = group.reductionPositiveMarkersGroup;
  49312. else if (this._isReduction)
  49313. markerGroup = group.reductionMarkersGroup;
  49314. else if (this._isPositive)
  49315. markerGroup = group.defaultPositiveMarkersGroup;
  49316. else
  49317. markerGroup = group.defaultMarkersGroup;
  49318. return markerGroup
  49319. },
  49320. _drawMarker: function(renderer, group) {
  49321. var attributes = this._getStyle(),
  49322. rotated = this._options.rotated,
  49323. pointGroup = this._getMarkerGroup(group);
  49324. this._drawMarkerInGroup(pointGroup, attributes, renderer)
  49325. },
  49326. _getSettingsForTracker: function() {
  49327. var that = this,
  49328. highY = that.highY,
  49329. lowY = that.lowY,
  49330. rotated = that._options.rotated,
  49331. x,
  49332. y,
  49333. width,
  49334. height;
  49335. if (highY === lowY) {
  49336. highY = rotated ? highY + DEFAULT_FINANCIAL_TRACKER_MARGIN : highY - DEFAULT_FINANCIAL_TRACKER_MARGIN;
  49337. lowY = rotated ? lowY - DEFAULT_FINANCIAL_TRACKER_MARGIN : lowY + DEFAULT_FINANCIAL_TRACKER_MARGIN
  49338. }
  49339. if (rotated) {
  49340. x = _min(lowY, highY);
  49341. y = that.x - that.width / 2;
  49342. width = _abs(lowY - highY);
  49343. height = that.width
  49344. }
  49345. else {
  49346. x = that.x - that.width / 2;
  49347. y = _min(lowY, highY);
  49348. width = that.width;
  49349. height = _abs(lowY - highY)
  49350. }
  49351. return {
  49352. x: x,
  49353. y: y,
  49354. width: width,
  49355. height: height
  49356. }
  49357. },
  49358. _drawTrackerMarker: function(renderer, group) {
  49359. var settings = this._getSettingsForTracker();
  49360. this.trackerGraphic = renderer.createRect(settings.x, settings.y, settings.width, settings.height, 0).append(group);
  49361. this.trackerGraphic.data({point: this})
  49362. },
  49363. _getGraphicBbox: function() {
  49364. var bbox = {},
  49365. rotated = this._options.rotated;
  49366. bbox.x = !rotated ? this.x - _round(this.width / 2) : this.lowY;
  49367. bbox.y = !rotated ? this.highY : this.x - _round(this.width / 2);
  49368. bbox.width = !rotated ? this.width : this.highY - this.lowY;
  49369. bbox.height = !rotated ? this.lowY - this.highY : this.width;
  49370. return bbox
  49371. },
  49372. _drawLabel: function(renderer, group) {
  49373. var coords,
  49374. commonVisibility = this._options.series.getLabelVisibility(),
  49375. customVisibility = this._getCustomLabelVisibility(),
  49376. visibleArea,
  49377. reductionColor = this._options.reduction.color,
  49378. translators = this.translators;
  49379. if (this.hasValue() && (commonVisibility || customVisibility)) {
  49380. visibleArea = {
  49381. minX: translators.x.getCanvasVisibleArea().min,
  49382. maxX: translators.x.getCanvasVisibleArea().max,
  49383. minY: translators.y.getCanvasVisibleArea().min,
  49384. maxY: translators.y.getCanvasVisibleArea().max
  49385. };
  49386. if (this._isReduction)
  49387. this._label.updateOptions({options: {
  49388. background: {fill: reductionColor},
  49389. connector: {stroke: reductionColor}
  49390. }});
  49391. coords = this._options.rotated ? {
  49392. x: this.highY,
  49393. y: this.x
  49394. } : {
  49395. x: this.x,
  49396. y: this.highY
  49397. };
  49398. this._label.setCoords(coords, this._getGraphicBbox(), "top", visibleArea);
  49399. this._label.draw(renderer, group, customVisibility)
  49400. }
  49401. },
  49402. getTooltipCoords: function() {
  49403. var that = this;
  49404. if (that.graphic) {
  49405. var x,
  49406. y,
  49407. min,
  49408. max,
  49409. minValue = _min(that.lowY, that.highY),
  49410. maxValue = _max(that.lowY, that.highY),
  49411. visibleAreaX = that.translators.x.getCanvasVisibleArea(),
  49412. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  49413. if (!that._options.rotated) {
  49414. min = _max(visibleAreaY.min, minValue);
  49415. max = _min(visibleAreaY.max, maxValue);
  49416. x = that.x;
  49417. y = min + (max - min) / 2
  49418. }
  49419. else {
  49420. min = _max(visibleAreaX.min, minValue);
  49421. max = _min(visibleAreaX.max, maxValue);
  49422. y = that.x;
  49423. x = min + (max - min) / 2
  49424. }
  49425. return {
  49426. x: x,
  49427. y: y,
  49428. offset: 0
  49429. }
  49430. }
  49431. },
  49432. hasValue: function() {
  49433. return this.highValue !== null && this.lowValue !== null
  49434. },
  49435. _translate: function(translator) {
  49436. var that = this,
  49437. rotated = that._options.rotated,
  49438. argTranslator = rotated ? that.translators.y : that.translators.x,
  49439. valTranslator = rotated ? that.translators.x : that.translators.y,
  49440. centerValue,
  49441. height;
  49442. that.x = argTranslator.translate(that.argument) + (that.xCorrection || 0);
  49443. that.openY = that.openValue !== null ? valTranslator.translate(that.openValue) : null;
  49444. that.highY = valTranslator.translate(that.highValue);
  49445. that.lowY = valTranslator.translate(that.lowValue);
  49446. that.closeY = that.closeValue !== null ? valTranslator.translate(that.closeValue) : null;
  49447. height = _abs(that.lowY - that.highY);
  49448. centerValue = _min(that.lowY, that.highY) + _abs(that.lowY - that.highY) / 2;
  49449. that._calculateVisibility(!rotated ? that.x : centerValue, !rotated ? centerValue : that.x)
  49450. },
  49451. _updateData: function(data) {
  49452. var that = this;
  49453. if (that.argument !== data.argument || that.reductionValue !== data.reductionValue || that.highValue !== data.highValue || that.lowValue !== data.lowValue || that.openValue !== data.openValue || that.closeValue !== data.closeValue || that.tag !== data.tag) {
  49454. that.value = that.initialValue = data.reductionValue;
  49455. that.originalValue = data.value;
  49456. that.argument = that.initialArgument = data.argument;
  49457. that.originalArgument = data.argument;
  49458. that.lowValue = data.lowValue;
  49459. that.originalLowValue = data.lowValue;
  49460. that.highValue = data.highValue;
  49461. that.originalHighValue = data.highValue;
  49462. that.openValue = data.openValue;
  49463. that.originalOpenValue = data.openValue;
  49464. that.closeValue = data.closeValue;
  49465. that.originalCloseValue = data.closeValue;
  49466. that.tag = data.tag;
  49467. that.pointClassName = data.pointClassName;
  49468. that._isPositive = data.openValue < data.closeValue;
  49469. that._isReduction = data.isReduction
  49470. }
  49471. },
  49472. _updateMarker: function(animationEnabled, style, group) {
  49473. var style = style || this._getStyle();
  49474. this.graphic.applySettings(_extend({points: this._getPoints()}, style));
  49475. group && this.graphic.append(this._getMarkerGroup(group))
  49476. },
  49477. _updateTracker: function() {
  49478. this.trackerGraphic.applySettings(this._getSettingsForTracker())
  49479. },
  49480. _getLabelFormatObject: function() {
  49481. return {
  49482. openValue: this.openValue,
  49483. highValue: this.highValue,
  49484. lowValue: this.lowValue,
  49485. closeValue: this.closeValue,
  49486. reductionValue: this.initialValue,
  49487. argument: this.initialArgument,
  49488. value: this.initialValue,
  49489. seriesName: this._options.series.name,
  49490. originalOpenValue: this.originalOpenValue,
  49491. originalCloseValue: this.originalCloseValue,
  49492. originalLowValue: this.originalLowValue,
  49493. originalHighValue: this.originalHighValue,
  49494. originalArgument: this.originalArgument,
  49495. point: this
  49496. }
  49497. },
  49498. _getFormatObject: function(tooltip) {
  49499. var highValue = tooltip.formatValue(this.highValue),
  49500. openValue = tooltip.formatValue(this.openValue),
  49501. closeValue = tooltip.formatValue(this.closeValue),
  49502. lowValue = tooltip.formatValue(this.lowValue),
  49503. symbolMethods = points.symbolPoint,
  49504. formatObject = symbolMethods._getFormatObject.call(this, tooltip);
  49505. return _extend({}, formatObject, {
  49506. valueText: "h: " + highValue + (openValue !== "" ? " o: " + openValue : "") + (closeValue !== "" ? " c: " + closeValue : "") + " l: " + lowValue,
  49507. highValueText: highValue,
  49508. openValueText: openValue,
  49509. closeValueText: closeValue,
  49510. lowValueText: lowValue
  49511. })
  49512. }
  49513. })
  49514. })(jQuery, DevExpress);
  49515. /*! Module viz-core, file stockPoint.js */
  49516. (function($, DX) {
  49517. var viz = DevExpress.viz,
  49518. points = viz.core.series.points.mixins,
  49519. _extend = $.extend,
  49520. _isNumeric = $.isNumeric;
  49521. points.stockPoint = _extend({}, points.candlestickPoint, {
  49522. _getPoints: function() {
  49523. var that = this,
  49524. createPoint = that._options.rotated ? function(x, y) {
  49525. return {
  49526. x: y,
  49527. y: x
  49528. }
  49529. } : function(x, y) {
  49530. return {
  49531. x: x,
  49532. y: y
  49533. }
  49534. },
  49535. openYExist = _isNumeric(that.openY),
  49536. closeYExist = _isNumeric(that.closeY),
  49537. x = that.x,
  49538. width = that.width,
  49539. points = [createPoint(x, that.highY), openYExist && createPoint(x, that.openY), openYExist && createPoint(x - width / 2, that.openY), openYExist && createPoint(x, that.openY), closeYExist && createPoint(x, that.closeY), closeYExist && createPoint(x + width / 2, that.closeY), closeYExist && createPoint(x, that.closeY), createPoint(x, that.lowY)];
  49540. return points
  49541. },
  49542. _drawMarkerInGroup: function(group, attributes, renderer) {
  49543. this.graphic = renderer.createPath(this._getPoints(), attributes).append(group)
  49544. },
  49545. _getMinTrackerWidth: function() {
  49546. return 2 + this._styles.normal.strokeWidth
  49547. }
  49548. })
  49549. })(jQuery, DevExpress);
  49550. /*! Module viz-core, file default.js */
  49551. (function($, DX, undefined) {
  49552. DX.viz.themes = DX.viz.themes || [];
  49553. var fontFamilyDefault = "'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
  49554. fontFamilyLight = "'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
  49555. baseChartTheme = {
  49556. containerBackgroundColor: '#ffffff',
  49557. animation: {
  49558. enabled: true,
  49559. duration: 1000,
  49560. easing: 'easeOutCubic',
  49561. maxPointCountSupported: 300
  49562. },
  49563. commonSeriesSettings: {
  49564. border: {
  49565. visible: false,
  49566. width: 2
  49567. },
  49568. showInLegend: true,
  49569. visible: true,
  49570. hoverMode: 'excludePoints',
  49571. selectionMode: 'includePoints',
  49572. hoverStyle: {
  49573. hatching: {
  49574. direction: 'right',
  49575. width: 2,
  49576. step: 6,
  49577. opacity: 0.75
  49578. },
  49579. border: {
  49580. visible: false,
  49581. width: 3
  49582. }
  49583. },
  49584. selectionStyle: {
  49585. hatching: {
  49586. direction: 'right',
  49587. width: 2,
  49588. step: 6,
  49589. opacity: 0.5
  49590. },
  49591. border: {
  49592. visible: false,
  49593. width: 3
  49594. }
  49595. },
  49596. label: {
  49597. visible: false,
  49598. alignment: 'center',
  49599. rotationAngle: 0,
  49600. horizontalOffset: 0,
  49601. verticalOffset: 0,
  49602. radialOffset: 0,
  49603. format: '',
  49604. argumentFormat: '',
  49605. precision: 0,
  49606. argumentPrecision: 0,
  49607. percentPrecision: 0,
  49608. showForZeroValues: true,
  49609. customizeText: undefined,
  49610. maxLabelCount: undefined,
  49611. position: 'outside',
  49612. font: {color: '#ffffff'},
  49613. border: {
  49614. visible: false,
  49615. width: 1,
  49616. color: '#d3d3d3',
  49617. dashStyle: 'solid'
  49618. },
  49619. connector: {
  49620. visible: false,
  49621. width: 1
  49622. }
  49623. }
  49624. },
  49625. redrawOnResize: true,
  49626. margin: {
  49627. left: 0,
  49628. top: 0,
  49629. right: 0,
  49630. bottom: 0
  49631. },
  49632. seriesSelectionMode: 'single',
  49633. pointSelectionMode: 'single',
  49634. legend: {
  49635. hoverMode: 'includePoints',
  49636. verticalAlignment: 'top',
  49637. horizontalAlignment: 'right',
  49638. position: 'outside',
  49639. visible: true,
  49640. customizeText: undefined,
  49641. itemTextPosition: undefined,
  49642. margin: 10,
  49643. equalColumnWidth: false,
  49644. markerSize: 12,
  49645. backgroundColor: undefined,
  49646. backgroundOpacity: undefined,
  49647. border: {
  49648. visible: false,
  49649. width: 1,
  49650. color: '#d3d3d3',
  49651. cornerRadius: 0,
  49652. dashStyle: 'solid'
  49653. },
  49654. paddingLeftRight: 20,
  49655. paddingTopBottom: 15,
  49656. columnCount: 0,
  49657. rowCount: 0,
  49658. columnItemSpacing: 20,
  49659. rowItemSpacing: 8
  49660. },
  49661. tooltip: {
  49662. enabled: false,
  49663. border: {
  49664. width: 1,
  49665. color: '#d3d3d3',
  49666. dashStyle: 'solid',
  49667. visible: true
  49668. },
  49669. font: {
  49670. family: fontFamilyDefault,
  49671. weight: 400,
  49672. size: 12,
  49673. color: '#232323'
  49674. },
  49675. color: '#ffffff',
  49676. arrowLength: 10,
  49677. paddingLeftRight: 18,
  49678. paddingTopBottom: 15,
  49679. shared: false,
  49680. format: '',
  49681. argumentFormat: '',
  49682. precision: 0,
  49683. argumentPrecision: 0,
  49684. percentPrecision: 0,
  49685. customizeText: undefined,
  49686. customizeTooltip: undefined,
  49687. shadow: {
  49688. opacity: 0.4,
  49689. offsetX: 0,
  49690. offsetY: 4,
  49691. blur: 2,
  49692. color: '#000000'
  49693. }
  49694. },
  49695. size: {
  49696. width: undefined,
  49697. height: undefined
  49698. },
  49699. loadingIndicator: {
  49700. font: {},
  49701. backgroundColor: '#ffffff',
  49702. text: 'Loading...'
  49703. },
  49704. dataPrepareSettings: {
  49705. checkTypeForAllData: false,
  49706. convertToAxisDataType: true,
  49707. sortingMethod: true
  49708. },
  49709. title: {
  49710. font: {
  49711. family: fontFamilyLight,
  49712. weight: 200,
  49713. color: '#232323',
  49714. size: 28
  49715. },
  49716. margin: 10
  49717. },
  49718. adaptiveLayout: {
  49719. width: 80,
  49720. height: 80,
  49721. keepLabels: true
  49722. },
  49723. _rtl: {legend: {itemTextPosition: 'left'}}
  49724. },
  49725. baseDarkChartTheme = {
  49726. containerBackgroundColor: '#2b2b2b',
  49727. commonSeriesSettings: {label: {border: {color: '#494949'}}},
  49728. legend: {border: {color: '#494949'}},
  49729. loadingIndicator: {backgroundColor: '#2b2b2b'},
  49730. title: {font: {color: '#929292'}},
  49731. tooltip: {
  49732. color: '#2b2b2b',
  49733. border: {color: '#494949'},
  49734. font: {color: '#929292'}
  49735. }
  49736. };
  49737. DX.viz.themes.push({
  49738. name: 'desktop',
  49739. font: {
  49740. color: '#767676',
  49741. family: fontFamilyDefault,
  49742. weight: 400,
  49743. size: 12,
  49744. cursor: 'default'
  49745. },
  49746. chart: $.extend(true, {}, baseChartTheme, {
  49747. commonSeriesSettings: {
  49748. type: 'line',
  49749. stack: 'default',
  49750. point: {
  49751. visible: true,
  49752. symbol: 'circle',
  49753. size: 12,
  49754. border: {
  49755. visible: false,
  49756. width: 1
  49757. },
  49758. hoverMode: 'onlyPoint',
  49759. selectionMode: 'onlyPoint',
  49760. hoverStyle: {
  49761. border: {
  49762. visible: true,
  49763. width: 4
  49764. },
  49765. size: 12
  49766. },
  49767. selectionStyle: {
  49768. border: {
  49769. visible: true,
  49770. width: 4
  49771. },
  49772. size: 12
  49773. }
  49774. },
  49775. scatter: {},
  49776. line: {
  49777. width: 2,
  49778. dashStyle: 'solid',
  49779. hoverStyle: {
  49780. width: 3,
  49781. hatching: {direction: 'none'}
  49782. },
  49783. selectionStyle: {width: 3}
  49784. },
  49785. stackedline: {
  49786. width: 2,
  49787. dashStyle: 'solid',
  49788. hoverStyle: {
  49789. width: 3,
  49790. hatching: {direction: 'none'}
  49791. },
  49792. selectionStyle: {width: 3}
  49793. },
  49794. fullstackedline: {
  49795. width: 2,
  49796. dashStyle: 'solid',
  49797. hoverStyle: {
  49798. width: 3,
  49799. hatching: {direction: 'none'}
  49800. },
  49801. selectionStyle: {width: 3}
  49802. },
  49803. stepline: {
  49804. width: 2,
  49805. dashStyle: 'solid',
  49806. hoverStyle: {
  49807. width: 3,
  49808. hatching: {direction: 'none'}
  49809. },
  49810. selectionStyle: {width: 3}
  49811. },
  49812. area: {
  49813. point: {visible: false},
  49814. opacity: 0.5
  49815. },
  49816. stackedarea: {
  49817. point: {visible: false},
  49818. opacity: 0.5
  49819. },
  49820. fullstackedarea: {
  49821. point: {visible: false},
  49822. opacity: 0.5
  49823. },
  49824. steparea: {
  49825. border: {
  49826. visible: true,
  49827. width: 2
  49828. },
  49829. point: {visible: false},
  49830. hoverStyle: {border: {
  49831. visible: true,
  49832. width: 3
  49833. }},
  49834. selectionStyle: {border: {
  49835. visible: true,
  49836. width: 3
  49837. }},
  49838. opacity: 0.5
  49839. },
  49840. spline: {
  49841. width: 2,
  49842. hoverStyle: {
  49843. width: 3,
  49844. hatching: {direction: 'none'}
  49845. },
  49846. selectionStyle: {width: 3}
  49847. },
  49848. splinearea: {
  49849. point: {visible: false},
  49850. opacity: 0.5
  49851. },
  49852. bar: {
  49853. cornerRadius: 0,
  49854. point: {
  49855. hoverStyle: {border: {visible: false}},
  49856. selectionStyle: {border: {visible: false}}
  49857. }
  49858. },
  49859. stackedbar: {
  49860. cornerRadius: 0,
  49861. point: {
  49862. hoverStyle: {border: {visible: false}},
  49863. selectionStyle: {border: {visible: false}}
  49864. },
  49865. label: {position: "inside"}
  49866. },
  49867. fullstackedbar: {
  49868. cornerRadius: 0,
  49869. point: {
  49870. hoverStyle: {border: {visible: false}},
  49871. selectionStyle: {border: {visible: false}}
  49872. },
  49873. label: {position: "inside"}
  49874. },
  49875. rangebar: {
  49876. cornerRadius: 0,
  49877. point: {
  49878. hoverStyle: {border: {visible: false}},
  49879. selectionStyle: {border: {visible: false}}
  49880. }
  49881. },
  49882. rangearea: {
  49883. point: {visible: false},
  49884. opacity: 0.5
  49885. },
  49886. rangesplinearea: {
  49887. point: {visible: false},
  49888. opacity: 0.5
  49889. },
  49890. bubble: {
  49891. opacity: 0.5,
  49892. point: {
  49893. hoverStyle: {border: {visible: false}},
  49894. selectionStyle: {border: {visible: false}}
  49895. }
  49896. },
  49897. candlestick: {
  49898. width: 1,
  49899. innerColor: '#ffffff',
  49900. reduction: {color: '#ff0000'},
  49901. hoverStyle: {
  49902. width: 3,
  49903. hatching: {direction: 'none'}
  49904. },
  49905. selectionStyle: {width: 3},
  49906. point: {border: {visible: true}}
  49907. },
  49908. stock: {
  49909. width: 1,
  49910. reduction: {color: '#ff0000'},
  49911. hoverStyle: {
  49912. width: 3,
  49913. hatching: {direction: 'none'}
  49914. },
  49915. selectionStyle: {width: 3},
  49916. point: {border: {visible: true}}
  49917. }
  49918. },
  49919. crosshair: {
  49920. enabled: false,
  49921. color: '#c6c6c6',
  49922. width: 1,
  49923. dashStyle: 'solid',
  49924. verticalLine: {visible: true},
  49925. horizontalLine: {visible: true}
  49926. },
  49927. commonAxisSettings: {
  49928. tickInterval: undefined,
  49929. setTicksAtUnitBeginning: true,
  49930. valueMarginsEnabled: true,
  49931. placeholderSize: null,
  49932. logarithmBase: 10,
  49933. discreteAxisDivisionMode: 'betweenLabels',
  49934. visible: false,
  49935. color: '#d3d3d3',
  49936. width: 1,
  49937. multipleAxesSpacing: 5,
  49938. label: {
  49939. visible: true,
  49940. overlappingBehavior: {
  49941. mode: 'auto',
  49942. rotationAngle: 90,
  49943. staggeringSpacing: 5
  49944. },
  49945. precision: 0,
  49946. format: '',
  49947. customizeText: undefined,
  49948. indentFromAxis: 10
  49949. },
  49950. grid: {
  49951. visible: false,
  49952. color: '#d3d3d3',
  49953. width: 1
  49954. },
  49955. tick: {
  49956. visible: false,
  49957. color: '#d3d3d3'
  49958. },
  49959. title: {
  49960. font: {size: 16},
  49961. margin: 10
  49962. },
  49963. stripStyle: {
  49964. paddingLeftRight: 10,
  49965. paddingTopBottom: 5
  49966. },
  49967. constantLineStyle: {
  49968. paddingLeftRight: 10,
  49969. paddingTopBottom: 10,
  49970. width: 1,
  49971. color: '#000000',
  49972. dashStyle: 'solid',
  49973. label: {
  49974. visible: true,
  49975. position: 'inside'
  49976. }
  49977. }
  49978. },
  49979. horizontalAxis: {
  49980. isHorizontal: true,
  49981. position: 'bottom',
  49982. axisDivisionFactor: 50,
  49983. label: {alignment: "center"},
  49984. stripStyle: {label: {
  49985. horizontalAlignment: 'center',
  49986. verticalAlignment: 'top'
  49987. }},
  49988. constantLineStyle: {label: {
  49989. horizontalAlignment: 'right',
  49990. verticalAlignment: 'top'
  49991. }},
  49992. constantLines: {}
  49993. },
  49994. verticalAxis: {
  49995. isHorizontal: false,
  49996. position: 'left',
  49997. axisDivisionFactor: 30,
  49998. label: {
  49999. alignment: 'right',
  50000. overlappingBehavior: {mode: 'enlargeTickInterval'}
  50001. },
  50002. stripStyle: {label: {
  50003. horizontalAlignment: 'left',
  50004. verticalAlignment: 'center'
  50005. }},
  50006. constantLineStyle: {label: {
  50007. horizontalAlignment: 'left',
  50008. verticalAlignment: 'top'
  50009. }},
  50010. constantLines: {}
  50011. },
  50012. argumentAxis: {},
  50013. valueAxis: {grid: {visible: true}},
  50014. commonPaneSettings: {
  50015. backgroundColor: 'none',
  50016. border: {
  50017. color: '#d3d3d3',
  50018. width: 1,
  50019. visible: false,
  50020. top: true,
  50021. bottom: true,
  50022. left: true,
  50023. right: true,
  50024. dashStyle: 'solid'
  50025. }
  50026. },
  50027. useAggregation: false,
  50028. adjustOnZoom: true,
  50029. rotated: false,
  50030. synchronizeMultiAxes: true,
  50031. equalBarWidth: true,
  50032. minBubbleSize: 12,
  50033. maxBubbleSize: 0.2
  50034. }),
  50035. pie: $.extend(true, {}, baseChartTheme, {
  50036. commonSeriesSettings: {
  50037. type: 'pie',
  50038. pie: {
  50039. border: {
  50040. visible: false,
  50041. width: 2,
  50042. color: '#ffffff'
  50043. },
  50044. hoverStyle: {
  50045. hatching: {
  50046. direction: 'right',
  50047. width: 4,
  50048. step: 10,
  50049. opacity: 0.75
  50050. },
  50051. border: {
  50052. visible: false,
  50053. width: 2
  50054. }
  50055. },
  50056. selectionStyle: {
  50057. hatching: {
  50058. direction: 'right',
  50059. width: 4,
  50060. step: 10,
  50061. opacity: 0.5
  50062. },
  50063. border: {
  50064. visible: false,
  50065. width: 2
  50066. }
  50067. }
  50068. },
  50069. doughnut: {
  50070. innerRadius: 0.5,
  50071. border: {
  50072. visible: false,
  50073. width: 2,
  50074. color: '#ffffff'
  50075. },
  50076. hoverStyle: {
  50077. hatching: {
  50078. direction: 'right',
  50079. width: 4,
  50080. step: 10,
  50081. opacity: 0.75
  50082. },
  50083. border: {
  50084. visible: false,
  50085. width: 2
  50086. }
  50087. },
  50088. selectionStyle: {
  50089. hatching: {
  50090. direction: 'right',
  50091. width: 4,
  50092. step: 10,
  50093. opacity: 0.5
  50094. },
  50095. border: {
  50096. visible: false,
  50097. width: 2
  50098. }
  50099. }
  50100. },
  50101. donut: {
  50102. innerRadius: 0.5,
  50103. border: {
  50104. visible: false,
  50105. width: 2,
  50106. color: '#ffffff'
  50107. },
  50108. hoverStyle: {
  50109. hatching: {
  50110. direction: 'right',
  50111. width: 4,
  50112. step: 10,
  50113. opacity: 0.75
  50114. },
  50115. border: {
  50116. visible: false,
  50117. width: 2
  50118. }
  50119. },
  50120. selectionStyle: {
  50121. hatching: {
  50122. direction: 'right',
  50123. width: 4,
  50124. step: 10,
  50125. opacity: 0.5
  50126. },
  50127. border: {
  50128. visible: false,
  50129. width: 2
  50130. }
  50131. }
  50132. }
  50133. },
  50134. legend: {hoverMode: 'markPoint'},
  50135. adaptiveLayout: {keepLabels: false}
  50136. }),
  50137. pieIE8: {commonSeriesSettings: {
  50138. pie: {
  50139. hoverStyle: {border: {
  50140. visible: true,
  50141. color: '#ffffff'
  50142. }},
  50143. selectionStyle: {border: {
  50144. visible: true,
  50145. color: '#ffffff'
  50146. }}
  50147. },
  50148. donut: {
  50149. hoverStyle: {border: {
  50150. visible: true,
  50151. color: '#ffffff'
  50152. }},
  50153. selectionStyle: {border: {
  50154. visible: true,
  50155. color: '#ffffff'
  50156. }}
  50157. },
  50158. doughnut: {
  50159. hoverStyle: {border: {
  50160. visible: true,
  50161. color: '#ffffff'
  50162. }},
  50163. selectionStyle: {border: {
  50164. visible: true,
  50165. color: '#ffffff'
  50166. }}
  50167. }
  50168. }},
  50169. gauge: {
  50170. containerBackgroundColor: '#ffffff',
  50171. scale: {
  50172. majorTick: {
  50173. visible: true,
  50174. length: 5,
  50175. width: 2,
  50176. showCalculatedTicks: true,
  50177. useTicksAutoArrangement: true,
  50178. color: '#ffffff'
  50179. },
  50180. minorTick: {
  50181. visible: false,
  50182. length: 3,
  50183. width: 1,
  50184. showCalculatedTicks: true,
  50185. color: '#ffffff'
  50186. },
  50187. label: {
  50188. visible: true,
  50189. font: {}
  50190. }
  50191. },
  50192. rangeContainer: {
  50193. offset: 0,
  50194. width: 5,
  50195. backgroundColor: '#808080'
  50196. },
  50197. valueIndicator: {
  50198. _default: {color: '#c2c2c2'},
  50199. rangebar: {
  50200. space: 2,
  50201. size: 10,
  50202. color: '#cbc5cf',
  50203. backgroundColor: 'none',
  50204. text: {
  50205. indent: 0,
  50206. font: {
  50207. size: 14,
  50208. color: null
  50209. }
  50210. }
  50211. },
  50212. twocolorneedle: {secondColor: '#e18e92'},
  50213. twocolorrectangle: {secondColor: '#e18e92'}
  50214. },
  50215. subvalueIndicator: {
  50216. _default: {color: '#8798a5'},
  50217. trianglemarker: {
  50218. space: 2,
  50219. length: 14,
  50220. width: 13,
  50221. color: '#8798a5'
  50222. },
  50223. triangle: {
  50224. space: 2,
  50225. length: 14,
  50226. width: 13,
  50227. color: '#8798a5'
  50228. },
  50229. textcloud: {
  50230. arrowLength: 5,
  50231. horizontalOffset: 6,
  50232. verticalOffset: 3,
  50233. color: '#679ec5',
  50234. text: {font: {
  50235. color: '#ffffff',
  50236. size: 18
  50237. }}
  50238. }
  50239. },
  50240. valueIndicators: {
  50241. _default: {color: '#c2c2c2'},
  50242. rangebar: {
  50243. space: 2,
  50244. size: 10,
  50245. color: '#cbc5cf',
  50246. backgroundColor: 'none',
  50247. text: {
  50248. indent: 0,
  50249. font: {
  50250. size: 14,
  50251. color: null
  50252. }
  50253. }
  50254. },
  50255. twocolorneedle: {secondColor: '#e18e92'},
  50256. trianglemarker: {
  50257. space: 2,
  50258. length: 14,
  50259. width: 13,
  50260. color: '#8798a5'
  50261. },
  50262. textcloud: {
  50263. arrowLength: 5,
  50264. horizontalOffset: 6,
  50265. verticalOffset: 3,
  50266. color: '#679ec5',
  50267. text: {font: {
  50268. color: '#ffffff',
  50269. size: 18
  50270. }}
  50271. }
  50272. },
  50273. title: {
  50274. layout: {
  50275. horizontalAlignment: 'center',
  50276. verticalAlignment: 'top',
  50277. overlay: 0
  50278. },
  50279. font: {
  50280. size: 16,
  50281. color: '#232323',
  50282. family: fontFamilyDefault,
  50283. weight: 400
  50284. }
  50285. },
  50286. subtitle: {font: {
  50287. size: 14,
  50288. color: '#232323',
  50289. family: fontFamilyDefault,
  50290. weight: 400
  50291. }},
  50292. indicator: {
  50293. hasPositiveMeaning: true,
  50294. layout: {
  50295. horizontalAlignment: 'center',
  50296. verticalAlignment: 'bottom',
  50297. overlay: 0
  50298. },
  50299. text: {font: {size: 18}}
  50300. },
  50301. tooltip: {
  50302. arrowLength: 10,
  50303. paddingLeftRight: 18,
  50304. paddingTopBottom: 15,
  50305. enabled: false,
  50306. border: {
  50307. width: 1,
  50308. color: '#d3d3d3',
  50309. dashStyle: 'solid',
  50310. visible: true
  50311. },
  50312. color: '#ffffff',
  50313. font: {
  50314. color: '#232323',
  50315. size: 12,
  50316. family: fontFamilyDefault,
  50317. weight: 400
  50318. },
  50319. shadow: {
  50320. opacity: 0.4,
  50321. offsetX: 0,
  50322. offsetY: 4,
  50323. blur: 2,
  50324. color: '#000000'
  50325. }
  50326. },
  50327. loadingIndicator: {
  50328. font: {},
  50329. backgroundColor: '#ffffff',
  50330. text: 'Loading...'
  50331. },
  50332. _circular: {
  50333. scale: {
  50334. orientation: 'outside',
  50335. label: {indentFromTick: 10}
  50336. },
  50337. rangeContainer: {orientation: 'outside'},
  50338. valueIndicator: {
  50339. type: 'rectangleneedle',
  50340. _default: {
  50341. offset: 20,
  50342. indentFromCenter: 0,
  50343. width: 2,
  50344. spindleSize: 14,
  50345. spindleGapSize: 10
  50346. },
  50347. triangleneedle: {width: 4},
  50348. triangle: {width: 4},
  50349. twocolorneedle: {
  50350. space: 2,
  50351. secondFraction: 0.4
  50352. },
  50353. twocolorrectangle: {
  50354. space: 2,
  50355. secondFraction: 0.4
  50356. },
  50357. rangebar: {offset: 30}
  50358. },
  50359. subvalueIndicator: {
  50360. type: 'trianglemarker',
  50361. trianglemarker: {offset: 6},
  50362. triangle: {offset: 6},
  50363. textcloud: {offset: -6}
  50364. },
  50365. valueIndicators: {
  50366. _type: 'rectangleneedle',
  50367. _default: {
  50368. offset: 20,
  50369. indentFromCenter: 0,
  50370. width: 2,
  50371. spindleSize: 14,
  50372. spindleGapSize: 10
  50373. },
  50374. triangleneedle: {width: 4},
  50375. twocolorneedle: {
  50376. space: 2,
  50377. secondFraction: 0.4
  50378. },
  50379. rangebar: {offset: 30},
  50380. trianglemarker: {offset: 6},
  50381. textcloud: {offset: -6}
  50382. }
  50383. },
  50384. _linear: {
  50385. scale: {
  50386. horizontalOrientation: 'right',
  50387. verticalOrientation: 'bottom',
  50388. label: {indentFromTick: -10}
  50389. },
  50390. rangeContainer: {
  50391. horizontalOrientation: 'right',
  50392. verticalOrientation: 'bottom'
  50393. },
  50394. valueIndicator: {
  50395. type: 'rangebar',
  50396. _default: {
  50397. offset: 2.5,
  50398. length: 15,
  50399. width: 15
  50400. },
  50401. rectangle: {width: 10},
  50402. rangebar: {
  50403. offset: 10,
  50404. horizontalOrientation: 'right',
  50405. verticalOrientation: 'bottom'
  50406. }
  50407. },
  50408. subvalueIndicator: {
  50409. type: 'trianglemarker',
  50410. _default: {
  50411. offset: -1,
  50412. horizontalOrientation: 'left',
  50413. verticalOrientation: 'top'
  50414. }
  50415. },
  50416. valueIndicators: {
  50417. _type: 'rectangle',
  50418. _default: {
  50419. offset: 2.5,
  50420. length: 15,
  50421. width: 15
  50422. },
  50423. rectangle: {width: 10},
  50424. rangebar: {
  50425. offset: 10,
  50426. horizontalOrientation: 'right',
  50427. verticalOrientation: 'bottom'
  50428. },
  50429. trianglemarker: {
  50430. offset: -1,
  50431. horizontalOrientation: 'left',
  50432. verticalOrientation: 'top'
  50433. },
  50434. textcloud: {
  50435. offset: -1,
  50436. horizontalOrientation: 'left',
  50437. verticalOrientation: 'top'
  50438. }
  50439. }
  50440. }
  50441. },
  50442. barGauge: {
  50443. backgroundColor: '#e0e0e0',
  50444. relativeInnerRadius: 0.3,
  50445. barSpacing: 4,
  50446. label: {
  50447. indent: 20,
  50448. connectorWidth: 2,
  50449. font: {size: 16}
  50450. },
  50451. title: {
  50452. layout: {
  50453. horizontalAlignment: 'center',
  50454. verticalAlignment: 'top',
  50455. overlay: 0
  50456. },
  50457. font: {
  50458. size: 16,
  50459. color: '#232323',
  50460. family: fontFamilyDefault,
  50461. weight: 400
  50462. }
  50463. },
  50464. subtitle: {font: {
  50465. size: 14,
  50466. color: '#232323',
  50467. family: fontFamilyDefault,
  50468. weight: 400
  50469. }},
  50470. indicator: {
  50471. hasPositiveMeaning: true,
  50472. layout: {
  50473. horizontalAlignment: 'center',
  50474. verticalAlignment: 'bottom',
  50475. overlay: 0
  50476. },
  50477. text: {font: {size: 18}}
  50478. },
  50479. tooltip: {
  50480. arrowLength: 10,
  50481. paddingLeftRight: 18,
  50482. paddingTopBottom: 15,
  50483. enabled: false,
  50484. border: {
  50485. width: 1,
  50486. color: '#d3d3d3',
  50487. dashStyle: 'solid',
  50488. visible: true
  50489. },
  50490. color: '#ffffff',
  50491. font: {
  50492. size: 12,
  50493. color: '#232323',
  50494. family: fontFamilyDefault,
  50495. weight: 400
  50496. },
  50497. shadow: {
  50498. opacity: 0.4,
  50499. offsetX: 0,
  50500. offsetY: 4,
  50501. blur: 2,
  50502. color: '#000000'
  50503. }
  50504. },
  50505. loadingIndicator: {
  50506. font: {},
  50507. backgroundColor: '#ffffff',
  50508. text: 'Loading...'
  50509. }
  50510. },
  50511. rangeSelector: {
  50512. containerBackgroundColor: '#ffffff',
  50513. scale: {
  50514. label: {
  50515. topIndent: 7,
  50516. font: {size: 11}
  50517. },
  50518. tick: {
  50519. width: 1,
  50520. color: '#000000',
  50521. opacity: 0.1
  50522. },
  50523. marker: {
  50524. separatorHeight: 33,
  50525. topIndent: 10,
  50526. textLeftIndent: 7,
  50527. textTopIndent: 11
  50528. }
  50529. },
  50530. loadingIndicator: {
  50531. font: {},
  50532. backgroundColor: '#ffffff',
  50533. text: 'Loading...'
  50534. },
  50535. sliderMarker: {
  50536. padding: 7,
  50537. pointerSize: 6,
  50538. color: '#9b9b9b',
  50539. invalidRangeColor: '#ff0000',
  50540. font: {
  50541. color: '#ffffff',
  50542. size: 11
  50543. }
  50544. },
  50545. sliderHandle: {
  50546. width: 1,
  50547. color: '#000000',
  50548. opacity: 0.2
  50549. },
  50550. shutter: {
  50551. color: undefined,
  50552. opacity: 0.75
  50553. },
  50554. background: {color: "#c0bae1"},
  50555. chart: {
  50556. containerBackgroundColor: undefined,
  50557. commonSeriesSettings: {
  50558. label: baseChartTheme.commonSeriesSettings.label,
  50559. border: {
  50560. visible: false,
  50561. width: 1
  50562. },
  50563. visible: true,
  50564. type: 'area',
  50565. hoverMode: 'none',
  50566. hoverStyle: {border: {}},
  50567. selectionStyle: {border: {}},
  50568. point: {
  50569. visible: false,
  50570. symbol: 'circle',
  50571. border: {
  50572. visible: false,
  50573. width: 1
  50574. },
  50575. size: 12,
  50576. hoverStyle: {border: {}},
  50577. selectionStyle: {border: {}}
  50578. },
  50579. line: {width: 2},
  50580. stepline: {width: 2},
  50581. scatter: {point: {visible: true}},
  50582. stackedline: {width: 2},
  50583. fullstackedline: {width: 2},
  50584. area: {opacity: 0.5},
  50585. stackedarea: {opacity: 0.5},
  50586. fullstackedarea: {opacity: 0.5},
  50587. spline: {width: 2},
  50588. splinearea: {opacity: 0.5},
  50589. steparea: {
  50590. border: {
  50591. visible: true,
  50592. width: 2
  50593. },
  50594. opacity: 0.5
  50595. },
  50596. bubble: {
  50597. opacity: 0.5,
  50598. point: {visible: true}
  50599. },
  50600. bar: {
  50601. cornerRadius: 0,
  50602. point: {visible: true}
  50603. },
  50604. stackedbar: {
  50605. cornerRadius: 0,
  50606. point: {visible: true}
  50607. },
  50608. fullstackedbar: {
  50609. cornerRadius: 0,
  50610. point: {visible: true}
  50611. },
  50612. rangebar: {
  50613. cornerRadius: 0,
  50614. point: {visible: true}
  50615. },
  50616. rangearea: {opacity: 0.5},
  50617. rangesplinearea: {opacity: 0.5},
  50618. candlestick: {
  50619. width: 1,
  50620. innerColor: '#ffffff',
  50621. reduction: {color: '#ff0000'}
  50622. },
  50623. stock: {
  50624. width: 1,
  50625. reduction: {color: '#ff0000'}
  50626. }
  50627. },
  50628. dataPrepareSettings: {
  50629. checkTypeForAllData: false,
  50630. convertToAxisDataType: true,
  50631. sortingMethod: true
  50632. },
  50633. useAggregation: false,
  50634. equalBarWidth: true,
  50635. minBubbleSize: 12,
  50636. maxBubbleSize: 0.2,
  50637. topIndent: 0.1,
  50638. bottomIndent: 0,
  50639. valueAxis: {
  50640. min: undefined,
  50641. max: undefined,
  50642. inverted: false,
  50643. logarithmBase: 10
  50644. }
  50645. }
  50646. },
  50647. map: {
  50648. background: {
  50649. borderWidth: 1,
  50650. borderColor: '#cacaca',
  50651. color: '#ffffff'
  50652. },
  50653. area: {
  50654. borderWidth: 1,
  50655. borderColor: '#ffffff',
  50656. color: '#d2d2d2',
  50657. hoveredBorderColor: '#303030',
  50658. selectedBorderWidth: 2,
  50659. selectedBorderColor: '#303030'
  50660. },
  50661. marker: {
  50662. font: {
  50663. color: '#2b2b2b',
  50664. size: 12
  50665. },
  50666. _dot: {
  50667. borderWidth: 2,
  50668. borderColor: '#ffffff',
  50669. color: '#ba4d51',
  50670. size: 8,
  50671. selectedStep: 2,
  50672. backStep: 18,
  50673. backColor: '#ffffff',
  50674. backOpacity: 0.32,
  50675. shadow: true
  50676. },
  50677. _bubble: {
  50678. minSize: 20,
  50679. maxSize: 50,
  50680. color: '#ba4d51',
  50681. hoveredBorderWidth: 1,
  50682. hoveredBorderColor: '#303030',
  50683. selectedBorderWidth: 2,
  50684. selectedBorderColor: '#303030'
  50685. },
  50686. _pie: {
  50687. size: 50,
  50688. hoveredBorderWidth: 1,
  50689. hoveredBorderColor: '#303030',
  50690. selectedBorderWidth: 2,
  50691. selectedBorderColor: '#303030'
  50692. },
  50693. _image: {size: 20}
  50694. },
  50695. controlBar: {
  50696. borderColor: '#5d5d5d',
  50697. borderWidth: 3,
  50698. color: '#ffffff'
  50699. },
  50700. tooltip: {
  50701. borderWidth: 1,
  50702. borderColor: '#d7d7d7',
  50703. arrowLength: 10,
  50704. paddingLeftRight: 18,
  50705. paddingTopBottom: 15,
  50706. border: {
  50707. width: 1,
  50708. color: '#d3d3d3',
  50709. dashStyle: 'solid',
  50710. visible: true
  50711. },
  50712. color: '#ffffff',
  50713. font: {
  50714. color: '#232323',
  50715. size: 12,
  50716. family: fontFamilyDefault,
  50717. weight: 400
  50718. },
  50719. shadow: {
  50720. opacity: 0.4,
  50721. offsetX: 0,
  50722. offsetY: 4,
  50723. blur: 2,
  50724. color: '#000000'
  50725. }
  50726. },
  50727. legend: {
  50728. verticalAlignment: 'bottom',
  50729. horizontalAlignment: 'right',
  50730. position: 'inside',
  50731. visible: true,
  50732. margin: 10,
  50733. equalColumnWidth: false,
  50734. markerSize: 12,
  50735. backgroundColor: '#ffffff',
  50736. backgroundOpacity: 0.65,
  50737. border: {
  50738. visible: true,
  50739. width: 1,
  50740. color: '#cacaca',
  50741. cornerRadius: 0,
  50742. dashStyle: 'solid'
  50743. },
  50744. paddingLeftRight: 16,
  50745. paddingTopBottom: 12,
  50746. columnItemSpacing: 20,
  50747. rowItemSpacing: 8,
  50748. font: {
  50749. color: '#2b2b2b',
  50750. size: 12
  50751. }
  50752. },
  50753. loadingIndicator: {
  50754. backgroundColor: '#ffffff',
  50755. font: {},
  50756. text: 'Loading...'
  50757. },
  50758. _rtl: {legend: {itemTextPosition: 'left'}}
  50759. },
  50760. sparkline: {
  50761. lineColor: '#666666',
  50762. lineWidth: 2,
  50763. areaOpacity: 0.2,
  50764. minColor: '#e8c267',
  50765. maxColor: '#e55253',
  50766. barPositiveColor: '#a9a9a9',
  50767. barNegativeColor: '#d7d7d7',
  50768. winColor: '#a9a9a9',
  50769. lossColor: '#d7d7d7',
  50770. firstLastColor: '#666666',
  50771. pointSymbol: 'circle',
  50772. pointColor: '#ffffff',
  50773. pointSize: 4,
  50774. tooltip: {
  50775. enabled: true,
  50776. allowContainerResizing: true,
  50777. verticalAlignment: 'top',
  50778. horizontalAlignment: 'center',
  50779. format: '',
  50780. paddingLeftRight: 18,
  50781. paddingTopBottom: 15,
  50782. arrowLength: 10,
  50783. precision: 0,
  50784. color: '#ffffff',
  50785. border: {
  50786. width: 1,
  50787. color: '#d3d3d3',
  50788. dashStyle: 'solid',
  50789. visible: true
  50790. },
  50791. font: {
  50792. color: '#232323',
  50793. family: fontFamilyDefault,
  50794. size: 12,
  50795. weight: 400
  50796. },
  50797. shadow: {
  50798. opacity: 0.4,
  50799. offsetX: 0,
  50800. offsetY: 4,
  50801. blur: 2,
  50802. color: '#000000'
  50803. }
  50804. }
  50805. },
  50806. bullet: {
  50807. color: '#e8c267',
  50808. targetColor: '#666666',
  50809. targetWidth: 4,
  50810. showTarget: true,
  50811. showZeroLevel: true,
  50812. tooltip: {
  50813. enabled: true,
  50814. allowContainerResizing: true,
  50815. verticalAlignment: 'top',
  50816. horizontalAlignment: 'center',
  50817. format: '',
  50818. precision: 0,
  50819. paddingLeftRight: 18,
  50820. paddingTopBottom: 15,
  50821. arrowLength: 10,
  50822. color: '#ffffff',
  50823. border: {
  50824. width: 1,
  50825. color: '#d3d3d3',
  50826. dashStyle: 'solid',
  50827. visible: true
  50828. },
  50829. font: {
  50830. color: '#232323',
  50831. family: fontFamilyDefault,
  50832. size: 12,
  50833. weight: 400
  50834. },
  50835. shadow: {
  50836. opacity: 0.4,
  50837. offsetX: 0,
  50838. offsetY: 4,
  50839. blur: 2,
  50840. color: '#000000'
  50841. }
  50842. }
  50843. }
  50844. });
  50845. DX.viz.core.registerTheme({
  50846. name: 'desktop-dark',
  50847. font: {color: '#808080'},
  50848. chart: $.extend(true, {}, baseDarkChartTheme, {
  50849. commonSeriesSettings: {candlestick: {innerColor: '#2b2b2b'}},
  50850. crosshair: {color: '#515151'},
  50851. commonAxisSettings: {
  50852. color: '#494949',
  50853. grid: {color: '#494949'},
  50854. tick: {color: '#494949'},
  50855. constantLineStyle: {color: '#ffffff'}
  50856. },
  50857. commonPaneSettings: {border: {color: '#494949'}}
  50858. }),
  50859. pie: $.extend(true, {}, baseDarkChartTheme),
  50860. pieIE8: {commonSeriesSettings: {
  50861. pie: {
  50862. hoverStyle: {border: {color: '#2b2b2b'}},
  50863. selectionStyle: {border: {color: '#2b2b2b'}}
  50864. },
  50865. donut: {
  50866. hoverStyle: {border: {color: '#2b2b2b'}},
  50867. selectionStyle: {border: {color: '#2b2b2b'}}
  50868. },
  50869. doughnut: {
  50870. hoverStyle: {border: {color: '#2b2b2b'}},
  50871. selectionStyle: {border: {color: '#2b2b2b'}}
  50872. }
  50873. }},
  50874. gauge: {
  50875. containerBackgroundColor: '#2b2b2b',
  50876. scale: {
  50877. majorTick: {color: '#303030'},
  50878. minorTick: {color: '#303030'}
  50879. },
  50880. rangeContainer: {backgroundColor: '#b5b5b5'},
  50881. valueIndicator: {
  50882. _default: {color: '#b5b5b5'},
  50883. rangebar: {color: '#84788b'},
  50884. twocolorneedle: {secondColor: '#ba544d'},
  50885. twocolorrectangle: {secondColor: '#ba544d'}
  50886. },
  50887. subvalueIndicator: {_default: {color: '#b7918f'}},
  50888. valueIndicators: {
  50889. _default: {color: '#b5b5b5'},
  50890. rangebar: {color: '#84788b'},
  50891. twocolorneedle: {secondColor: '#ba544d'},
  50892. trianglemarker: {color: '#b7918f'},
  50893. textcloud: {color: '#ba544d'}
  50894. },
  50895. title: {font: {color: '#929292'}},
  50896. subtitle: {font: {color: '#929292'}},
  50897. loadingIndicator: {backgroundColor: '#2b2b2b'},
  50898. tooltip: {
  50899. color: '#2b2b2b',
  50900. border: {color: '#494949'},
  50901. font: {color: '#929292'}
  50902. }
  50903. },
  50904. barGauge: {
  50905. title: {font: {color: '#929292'}},
  50906. subtitle: {font: {color: '#929292'}},
  50907. tooltip: {
  50908. color: '#2b2b2b',
  50909. border: {color: '#494949'},
  50910. font: {color: '#929292'}
  50911. },
  50912. loadingIndicator: {backgroundColor: '#2b2b2b'}
  50913. },
  50914. rangeSelector: {
  50915. containerBackgroundColor: '#2b2b2b',
  50916. scale: {tick: {
  50917. color: '#ffffff',
  50918. opacity: 0.05
  50919. }},
  50920. loadingIndicator: {backgroundColor: '#2b2b2b'},
  50921. sliderMarker: {
  50922. color: '#b5b5b5',
  50923. font: {color: '#303030'}
  50924. },
  50925. sliderHandle: {
  50926. color: '#ffffff',
  50927. opacity: 0.35
  50928. },
  50929. shutter: {
  50930. color: '#2b2b2b',
  50931. opacity: 0.9
  50932. }
  50933. },
  50934. map: {
  50935. background: {
  50936. borderColor: '#3f3f3f',
  50937. color: '#303030'
  50938. },
  50939. area: {
  50940. borderColor: '#303030',
  50941. color: '#686868',
  50942. hoveredBorderColor: '#ffffff',
  50943. selectedBorderColor: '#ffffff'
  50944. },
  50945. marker: {
  50946. font: {color: '#ffffff'},
  50947. _bubble: {
  50948. hoveredBorderColor: '#ffffff',
  50949. selectedBorderColor: '#ffffff'
  50950. },
  50951. _pie: {
  50952. hoveredBorderColor: '#ffffff',
  50953. selectedBorderColor: '#ffffff'
  50954. }
  50955. },
  50956. controlBar: {
  50957. borderColor: '#c7c7c7',
  50958. color: '#303030'
  50959. },
  50960. legend: {
  50961. border: {color: '#3f3f3f'},
  50962. backgroundColor: '#303030',
  50963. font: {color: '#ffffff'}
  50964. },
  50965. tooltip: {
  50966. color: '#2b2b2b',
  50967. border: {color: '#494949'},
  50968. font: {color: '#929292'}
  50969. },
  50970. loadingIndicator: {backgroundColor: '#2b2b2b'}
  50971. },
  50972. sparkline: {
  50973. lineColor: '#c7c7c7',
  50974. firstLastColor: '#c7c7c7',
  50975. barPositiveColor: '#b8b8b8',
  50976. barNegativeColor: '#8e8e8e',
  50977. winColor: '#b8b8b8',
  50978. lossColor: '#8e8e8e',
  50979. pointColor: '#303030',
  50980. tooltip: {
  50981. color: '#2b2b2b',
  50982. border: {color: '#494949'},
  50983. font: {color: '#929292'}
  50984. }
  50985. },
  50986. bullet: {
  50987. targetColor: '#8e8e8e',
  50988. tooltip: {
  50989. color: '#2b2b2b',
  50990. border: {color: '#494949'},
  50991. font: {color: '#929292'}
  50992. }
  50993. }
  50994. }, 'desktop')
  50995. })(jQuery, DevExpress);
  50996. /*! Module viz-core, file android.js */
  50997. (function($, DX, undefined) {
  50998. var baseChartTheme = {
  50999. containerBackgroundColor: '#050506',
  51000. title: {font: {color: '#ffffff'}},
  51001. commonSeriesSettings: {label: {border: {color: '#4c4c4c'}}},
  51002. legend: {
  51003. font: {
  51004. color: '#ffffff',
  51005. size: 11
  51006. },
  51007. border: {color: '#4c4c4c'}
  51008. },
  51009. loadingIndicator: {backgroundColor: '#050506'},
  51010. tooltip: {
  51011. color: '#050506',
  51012. border: {color: '#4c4c4c'},
  51013. font: {color: '#ffffff'}
  51014. }
  51015. },
  51016. baseLightChartTheme = {
  51017. containerBackgroundColor: '#e8e8e8',
  51018. title: {font: {color: '#808080'}},
  51019. legend: {font: {
  51020. color: '#000000',
  51021. size: 11
  51022. }},
  51023. loadingIndicator: {backgroundColor: '#e8e8e8'},
  51024. tooltip: {
  51025. color: '#e8e8e8',
  51026. font: {color: '#808080'}
  51027. }
  51028. };
  51029. DX.viz.core.registerTheme({
  51030. name: 'android',
  51031. chart: $.extend(true, {}, baseChartTheme, {
  51032. commonSeriesSettings: {candlestick: {innerColor: '#050506'}},
  51033. commonAxisSettings: {
  51034. color: '#4c4c4c',
  51035. grid: {color: '#4c4c4c'},
  51036. tick: {color: '#4c4c4c'},
  51037. title: {font: {color: '#545455'}},
  51038. label: {font: {
  51039. color: '#ffffff',
  51040. size: 11
  51041. }}
  51042. },
  51043. commonPaneSettings: {border: {color: '#4c4c4c'}}
  51044. }),
  51045. pie: $.extend(true, {}, baseChartTheme),
  51046. pieIE8: {commonSeriesSettings: {
  51047. pie: {
  51048. hoverStyle: {border: {color: '#050506'}},
  51049. selectionStyle: {border: {color: '#050506'}}
  51050. },
  51051. donut: {
  51052. hoverStyle: {border: {color: '#050506'}},
  51053. selectionStyle: {border: {color: '#050506'}}
  51054. },
  51055. doughnut: {
  51056. hoverStyle: {border: {color: '#050506'}},
  51057. selectionStyle: {border: {color: '#050506'}}
  51058. }
  51059. }},
  51060. gauge: {
  51061. containerBackgroundColor: '#050506',
  51062. title: {font: {color: '#ffffff'}},
  51063. subtitle: {font: {color: '#ffffff'}},
  51064. loadingIndicator: {backgroundColor: '#050506'},
  51065. tooltip: {
  51066. color: '#050506',
  51067. border: {color: '#4c4c4c'},
  51068. font: {color: '#ffffff'}
  51069. }
  51070. },
  51071. barGauge: {
  51072. title: {font: {color: '#ffffff'}},
  51073. subtitle: {font: {color: '#ffffff'}},
  51074. tooltip: {
  51075. color: '#050506',
  51076. border: {color: '#4c4c4c'},
  51077. font: {color: '#ffffff'}
  51078. },
  51079. loadingIndicator: {backgroundColor: '#050506'}
  51080. },
  51081. rangeSelector: {
  51082. containerBackgroundColor: '#050506',
  51083. loadingIndicator: {backgroundColor: '#050506'}
  51084. },
  51085. map: {
  51086. loadingIndicator: {backgroundColor: '#050506'},
  51087. tooltip: {
  51088. color: '#050506',
  51089. border: {color: '#4c4c4c'},
  51090. font: {color: '#ffffff'}
  51091. }
  51092. },
  51093. sparkline: {tooltip: {
  51094. color: '#050506',
  51095. border: {color: '#4c4c4c'},
  51096. font: {color: '#ffffff'}
  51097. }},
  51098. bullet: {tooltip: {
  51099. color: '#050506',
  51100. border: {color: '#4c4c4c'},
  51101. font: {color: '#ffffff'}
  51102. }}
  51103. }, 'desktop-dark');
  51104. DX.viz.core.registerTheme({
  51105. name: 'android-holo-light',
  51106. chart: $.extend(true, {}, baseLightChartTheme, {
  51107. commonSeriesSettings: {candlestick: {innerColor: '#e8e8e8'}},
  51108. commonAxisSettings: {
  51109. title: {font: {color: '#939393'}},
  51110. label: {font: {
  51111. color: '#404040',
  51112. size: 11
  51113. }}
  51114. }
  51115. }),
  51116. pie: $.extend(true, {}, baseLightChartTheme),
  51117. pieIE8: {commonSeriesSettings: {
  51118. pie: {
  51119. hoverStyle: {border: {color: '#e8e8e8'}},
  51120. selectionStyle: {border: {color: '#e8e8e8'}}
  51121. },
  51122. donut: {
  51123. hoverStyle: {border: {color: '#e8e8e8'}},
  51124. selectionStyle: {border: {color: '#e8e8e8'}}
  51125. },
  51126. doughnut: {
  51127. hoverStyle: {border: {color: '#e8e8e8'}},
  51128. selectionStyle: {border: {color: '#e8e8e8'}}
  51129. }
  51130. }},
  51131. gauge: {
  51132. containerBackgroundColor: '#e8e8e8',
  51133. title: {font: {color: '#808080'}},
  51134. subtitle: {font: {color: '#808080'}},
  51135. loadingIndicator: {backgroundColor: '#e8e8e8'},
  51136. tooltip: {
  51137. color: '#e8e8e8',
  51138. font: {color: '#808080'}
  51139. }
  51140. },
  51141. barGauge: {
  51142. title: {font: {color: '#808080'}},
  51143. subtitle: {font: {color: '#808080'}},
  51144. tooltip: {
  51145. color: '#e8e8e8',
  51146. font: {color: '#808080'}
  51147. },
  51148. loadingIndicator: {backgroundColor: '#e8e8e8'}
  51149. },
  51150. rangeSelector: {
  51151. containerBackgroundColor: '#e8e8e8',
  51152. loadingIndicator: {backgroundColor: '#e8e8e8'}
  51153. },
  51154. map: {
  51155. loadingIndicator: {backgroundColor: '#e8e8e8'},
  51156. tooltip: {
  51157. color: '#e8e8e8',
  51158. font: {color: '#808080'}
  51159. }
  51160. },
  51161. sparkline: {tooltip: {
  51162. color: '#e8e8e8',
  51163. font: {color: '#808080'}
  51164. }},
  51165. bullet: {tooltip: {
  51166. color: '#e8e8e8',
  51167. font: {color: '#808080'}
  51168. }}
  51169. }, 'desktop')
  51170. })(jQuery, DevExpress);
  51171. /*! Module viz-core, file ios.js */
  51172. (function($, DX, undefined) {
  51173. var baseChartTheme = {
  51174. containerBackgroundColor: '#cbd0da',
  51175. title: {font: {color: '#808080'}},
  51176. commonSeriesSettings: {label: {border: {color: '#b0b3ba'}}},
  51177. legend: {
  51178. font: {
  51179. color: '#000000',
  51180. size: 11
  51181. },
  51182. border: {color: '#b0b3ba'}
  51183. },
  51184. loadingIndicator: {backgroundColor: '#cbd0da'},
  51185. tooltip: {font: {color: '#808080'}}
  51186. },
  51187. baseIos7ChartTheme = {
  51188. containerBackgroundColor: '#ffffff',
  51189. title: {font: {color: '#808080'}},
  51190. commonSeriesSettings: {label: {border: {color: '#d3d3d3'}}},
  51191. legend: {
  51192. font: {
  51193. color: '#000000',
  51194. size: 11
  51195. },
  51196. border: {color: '#d3d3d3'}
  51197. },
  51198. loadingIndicator: {backgroundColor: '#ffffff'},
  51199. tooltip: {font: {color: '#808080'}}
  51200. };
  51201. DX.viz.core.registerTheme({
  51202. name: 'ios',
  51203. chart: $.extend(true, {}, baseChartTheme, {
  51204. commonSeriesSettings: {candlestick: {innerColor: '#cbd0da'}},
  51205. commonAxisSettings: {
  51206. color: '#b0b3ba',
  51207. grid: {color: '#b0b3ba'},
  51208. tick: {color: '#b0b3ba'},
  51209. title: {font: {color: '#939393'}},
  51210. label: {font: {
  51211. color: '#000000',
  51212. size: 11
  51213. }}
  51214. },
  51215. commonPaneSettings: {border: {color: '#b0b3ba'}}
  51216. }),
  51217. pie: $.extend(true, {}, baseChartTheme),
  51218. pieIE8: {commonSeriesSettings: {
  51219. pie: {
  51220. hoverStyle: {border: {color: '#cbd0da'}},
  51221. selectionStyle: {border: {color: '#cbd0da'}}
  51222. },
  51223. donut: {
  51224. hoverStyle: {border: {color: '#cbd0da'}},
  51225. selectionStyle: {border: {color: '#cbd0da'}}
  51226. },
  51227. doughnut: {
  51228. hoverStyle: {border: {color: '#cbd0da'}},
  51229. selectionStyle: {border: {color: '#cbd0da'}}
  51230. }
  51231. }},
  51232. gauge: {
  51233. title: {font: {color: '#808080'}},
  51234. subtitle: {font: {color: '#808080'}},
  51235. tooltip: {font: {color: '#808080'}}
  51236. },
  51237. barGauge: {
  51238. title: {font: {color: '#808080'}},
  51239. subtitle: {font: {color: '#808080'}},
  51240. tooltip: {font: {color: '#808080'}}
  51241. },
  51242. map: {tooltip: {font: {color: '#808080'}}},
  51243. sparkline: {tooltip: {font: {color: '#808080'}}},
  51244. bullet: {tooltip: {font: {color: '#808080'}}}
  51245. }, 'desktop');
  51246. DX.viz.core.registerTheme({
  51247. name: 'ios:7',
  51248. chart: $.extend(true, {}, baseIos7ChartTheme, {
  51249. commonAxisSettings: {
  51250. color: '#d3d3d3',
  51251. grid: {color: '#d3d3d3'},
  51252. tick: {color: '#d3d3d3'},
  51253. title: {font: {color: '#939393'}},
  51254. label: {font: {
  51255. color: '#000000',
  51256. size: 11
  51257. }}
  51258. },
  51259. commonPaneSettings: {border: {color: '#d3d3d3'}}
  51260. }),
  51261. pie: $.extend(true, {}, baseIos7ChartTheme),
  51262. gauge: {
  51263. title: {font: {color: '#808080'}},
  51264. subtitle: {font: {color: '#808080'}},
  51265. tooltip: {font: {color: '#808080'}}
  51266. },
  51267. barGauge: {
  51268. title: {font: {color: '#808080'}},
  51269. subtitle: {font: {color: '#808080'}},
  51270. tooltip: {font: {color: '#808080'}}
  51271. },
  51272. map: {tooltip: {font: {color: '#808080'}}},
  51273. sparkline: {tooltip: {font: {color: '#808080'}}},
  51274. bullet: {tooltip: {font: {color: '#808080'}}}
  51275. }, 'desktop')
  51276. })(jQuery, DevExpress);
  51277. /*! Module viz-core, file win8.js */
  51278. (function($, DX) {
  51279. var baseChartTheme = {
  51280. containerBackgroundColor: '#000000',
  51281. title: {font: {color: '#ffffff'}},
  51282. commonSeriesSettings: {label: {border: {color: '#454545'}}},
  51283. legend: {
  51284. font: {
  51285. color: '#ffffff',
  51286. size: 11
  51287. },
  51288. border: {color: '#454545'}
  51289. },
  51290. loadingIndicator: {backgroundColor: '#000000'},
  51291. tooltip: {
  51292. color: '#000000',
  51293. font: {color: '#ffffff'}
  51294. }
  51295. },
  51296. baseWhiteChartTheme = {
  51297. title: {font: {color: '#808080'}},
  51298. legend: {font: {
  51299. color: '#000000',
  51300. size: 11
  51301. }},
  51302. tooltip: {font: {color: '#808080'}}
  51303. };
  51304. DX.viz.core.registerTheme({
  51305. name: 'win8',
  51306. chart: $.extend(true, {}, baseChartTheme, {
  51307. commonSeriesSettings: {candlestick: {innerColor: '#000000'}},
  51308. commonAxisSettings: {
  51309. color: '#454545',
  51310. grid: {color: '#454545'},
  51311. tick: {color: '#454545'},
  51312. title: {font: {color: '#535353'}},
  51313. label: {font: {
  51314. color: '#ffffff',
  51315. size: 11
  51316. }}
  51317. },
  51318. commonPaneSettings: {border: {color: '#454545'}}
  51319. }),
  51320. pie: $.extend(true, {}, baseChartTheme),
  51321. pieIE8: {commonSeriesSettings: {
  51322. pie: {
  51323. hoverStyle: {border: {color: '#000000'}},
  51324. selectionStyle: {border: {color: '#000000'}}
  51325. },
  51326. donut: {
  51327. hoverStyle: {border: {color: '#000000'}},
  51328. selectionStyle: {border: {color: '#000000'}}
  51329. },
  51330. doughnut: {
  51331. hoverStyle: {border: {color: '#000000'}},
  51332. selectionStyle: {border: {color: '#000000'}}
  51333. }
  51334. }},
  51335. gauge: {
  51336. containerBackgroundColor: '#000000',
  51337. title: {font: {color: '#ffffff'}},
  51338. subtitle: {font: {color: '#ffffff'}},
  51339. loadingIndicator: {backgroundColor: '#000000'},
  51340. tooltip: {
  51341. color: '#000000',
  51342. font: {color: '#ffffff'}
  51343. }
  51344. },
  51345. barGauge: {
  51346. title: {font: {color: '#ffffff'}},
  51347. subtitle: {font: {color: '#ffffff'}},
  51348. tooltip: {
  51349. color: '#000000',
  51350. font: {color: '#ffffff'}
  51351. },
  51352. loadingIndicator: {backgroundColor: '#000000'}
  51353. },
  51354. rangeSelector: {
  51355. containerBackgroundColor: '#000000',
  51356. loadingIndicator: {backgroundColor: '#000000'}
  51357. },
  51358. map: {
  51359. loadingIndicator: {backgroundColor: '#000000'},
  51360. tooltip: {
  51361. color: '#000000',
  51362. font: {color: '#ffffff'}
  51363. }
  51364. },
  51365. sparkline: {tooltip: {
  51366. color: '#000000',
  51367. font: {color: '#ffffff'}
  51368. }},
  51369. bullet: {tooltip: {
  51370. color: '#000000',
  51371. font: {color: '#ffffff'}
  51372. }}
  51373. }, 'desktop-dark');
  51374. DX.viz.core.registerTheme({
  51375. name: 'win8-white',
  51376. chart: $.extend(true, {}, baseWhiteChartTheme, {commonAxisSettings: {
  51377. title: {font: {color: '#939393'}},
  51378. label: {font: {
  51379. color: '#404040',
  51380. size: 11
  51381. }}
  51382. }}),
  51383. pie: $.extend(true, {}, baseWhiteChartTheme),
  51384. gauge: {
  51385. title: {font: {color: '#808080'}},
  51386. subtitle: {font: {color: '#808080'}},
  51387. tooltip: {font: {color: '#808080'}}
  51388. },
  51389. barGauge: {
  51390. title: {font: {color: '#808080'}},
  51391. subtitle: {font: {color: '#808080'}},
  51392. tooltip: {font: {color: '#808080'}}
  51393. },
  51394. map: {tooltip: {font: {color: '#808080'}}},
  51395. sparkline: {tooltip: {font: {color: '#808080'}}},
  51396. bullet: {tooltip: {font: {color: '#808080'}}}
  51397. }, 'desktop')
  51398. })(jQuery, DevExpress);
  51399. /*! Module viz-core, file others.js */
  51400. (function($, DX) {
  51401. DX.viz.core.registerTheme({name: 'generic'}, 'desktop');
  51402. DX.viz.core.registerTheme({name: 'generic-dark'}, 'desktop-dark');
  51403. DX.viz.core.registerTheme({name: 'tizen'}, 'desktop');
  51404. DX.viz.core.registerTheme({name: 'tizen-black'}, 'desktop-dark')
  51405. })(jQuery, DevExpress);
  51406. /*! Module viz-core, file namespaces.js */
  51407. (function(DevExpress) {
  51408. DevExpress.viz.renderers = {}
  51409. })(DevExpress);
  51410. /*! Module viz-core, file svgRenderer.js */
  51411. (function($, DX) {
  51412. var renderers = DX.viz.renderers,
  51413. utils = DX.utils,
  51414. Class = DX.Class,
  51415. doc = document,
  51416. MAX_PIXEL_COUNT = 10000000000;
  51417. function createElement(name) {
  51418. return doc.createElementNS('http://www.w3.org/2000/svg', name)
  51419. }
  51420. function getPatternUrl(id, pathModified) {
  51421. return id !== null ? 'url(' + (pathModified ? window.location.href : '') + '#' + id + ')' : null
  51422. }
  51423. var BaseSvgElement = Class.inherit({
  51424. ctor: function baseSvgElementCtor(renderer, name, params) {
  51425. this.renderer = renderer;
  51426. this.element = this.createElement(name);
  51427. this.$element = $(this.element);
  51428. this.applySettings($.extend({}, this.defaultSettings(), params));
  51429. this.__passedParams = params
  51430. },
  51431. defaultSettings: $.noop,
  51432. createElement: function(nodeName) {
  51433. this._nodeName = nodeName;
  51434. return createElement(nodeName)
  51435. },
  51436. dispose: function() {
  51437. this.off();
  51438. this.remove();
  51439. this.renderer = null;
  51440. this.element = null;
  51441. this.settings = null;
  51442. this.$element = null;
  51443. this.transformation = null;
  51444. this.__passedParams = null;
  51445. this.__appliedSettings = null;
  51446. this.__appliedStyle = null
  51447. },
  51448. append: function(svgElement) {
  51449. var toElement = svgElement || this.renderer.getRoot();
  51450. toElement.element.appendChild(this.element);
  51451. return this
  51452. },
  51453. insertBefore: function(target) {
  51454. target.element.parentNode.insertBefore(this.element, target.element);
  51455. return this
  51456. },
  51457. toBackground: function() {
  51458. this.element.parentNode && this.element.parentNode.insertBefore(this.element, this.element.parentNode.firstChild);
  51459. return this
  51460. },
  51461. toForeground: function() {
  51462. this.element.parentNode && this.element.parentNode.appendChild(this.element);
  51463. return this
  51464. },
  51465. addClass: function(className) {
  51466. var classAttribute = this.$element.attr('class'),
  51467. classNameIndex,
  51468. classNames;
  51469. if (className) {
  51470. if (classAttribute) {
  51471. classNames = classAttribute.split(' ');
  51472. classNameIndex = $.inArray(className, classNames);
  51473. if (classNameIndex === -1)
  51474. classAttribute += ' ' + className
  51475. }
  51476. else
  51477. classAttribute = className;
  51478. this.$element.attr('class', classAttribute)
  51479. }
  51480. return this.$element
  51481. },
  51482. removeClass: function(className) {
  51483. var classAttribute = this.$element.attr('class'),
  51484. classNames,
  51485. indexDeleteElement,
  51486. resultClassNames = '',
  51487. i;
  51488. if (classAttribute && className) {
  51489. classNames = classAttribute.split(' ');
  51490. indexDeleteElement = $.inArray(className, classNames);
  51491. if (indexDeleteElement !== -1) {
  51492. for (i = 0; i < classNames.length; i++)
  51493. if (i !== indexDeleteElement)
  51494. resultClassNames += classNames[i] + ' ';
  51495. this.$element.attr('class', resultClassNames.replace(/ $/, ''))
  51496. }
  51497. }
  51498. return this.$element
  51499. },
  51500. applySettings: function(settings) {
  51501. var normalized;
  51502. this.settings = $.extend(this.settings || {}, settings || {});
  51503. this.adjustSettings();
  51504. normalized = this._normalizeSettings(this.settings);
  51505. this.applyStyle(this._style);
  51506. this._applyAttributes(normalized);
  51507. return this
  51508. },
  51509. _applyAttributes: function(settings) {
  51510. this.$element.attr(settings);
  51511. this.__appliedSettings = settings
  51512. },
  51513. adjustSettings: function(){},
  51514. applyStyle: function(style) {
  51515. this.$element.css(style || {});
  51516. this.__appliedStyle = style || {};
  51517. return this
  51518. },
  51519. trigger: function(event, data) {
  51520. this.$element.trigger(event, data)
  51521. },
  51522. on: function(events, data, handler) {
  51523. this.$element.on.apply(this.$element, arguments);
  51524. return this
  51525. },
  51526. data: function(key, value) {
  51527. this.$element.data(key, value);
  51528. return this
  51529. },
  51530. removeData: function() {
  51531. this.$element.removeData();
  51532. return this
  51533. },
  51534. off: function(events) {
  51535. this.$element.off(events);
  51536. return this
  51537. },
  51538. getBBox: function() {
  51539. var that = this,
  51540. bBox,
  51541. element = this.element,
  51542. transformation = that.transformation,
  51543. rotateAngle = transformation.rotateAngle || 0,
  51544. rotateX = transformation.rotateX || 0,
  51545. rotateY = transformation.rotateY || 0,
  51546. mabs = Math.abs,
  51547. mmin = Math.min;
  51548. function bBox(el) {
  51549. var ret = {};
  51550. try {
  51551. if (!$.isFunction(el.getBBox))
  51552. throw{};
  51553. else
  51554. ret = el.getBBox()
  51555. }
  51556. catch(e) {
  51557. ret = {
  51558. x: 0,
  51559. y: 0,
  51560. width: el.offsetWidth || 0,
  51561. height: el.offsetHeight || 0
  51562. }
  51563. }
  51564. return ret
  51565. }
  51566. bBox = $.extend({}, bBox(element));
  51567. if (rotateAngle) {
  51568. var cossin = utils.getCosAndSin(rotateAngle),
  51569. sin = cossin.sin.toFixed(3),
  51570. cos = cossin.cos.toFixed(3),
  51571. ltx = bBox.x - rotateX,
  51572. lty = bBox.y - rotateY,
  51573. rtx = bBox.x + bBox.width - rotateX,
  51574. rty = bBox.y - rotateY,
  51575. lbx = bBox.x - rotateX,
  51576. lby = bBox.y + bBox.height - rotateY,
  51577. rbx = bBox.x + bBox.width - rotateX,
  51578. rby = bBox.y + bBox.height - rotateY,
  51579. w,
  51580. h;
  51581. w = mabs(bBox.height * sin) + mabs(bBox.width * cos);
  51582. h = mabs(bBox.height * cos) + mabs(bBox.width * sin);
  51583. bBox.x = mmin(ltx * cos - lty * sin + rotateX, rtx * cos - rty * sin + rotateX, lbx * cos - lby * sin + rotateX, rbx * cos - rby * sin + rotateX);
  51584. bBox.y = mmin(ltx * sin + lty * cos + rotateY, rtx * sin + rty * cos + rotateY, lbx * sin + lby * cos + rotateY, rbx * sin + rby * cos + rotateY);
  51585. bBox.width = w;
  51586. bBox.height = h
  51587. }
  51588. return that._normalizeBBox(bBox)
  51589. },
  51590. _normalizeBBox: function(bBox) {
  51591. var ceil = Math.ceil,
  51592. floor = Math.floor,
  51593. $isNumeric = $.isNumeric,
  51594. rxl = floor(bBox.x),
  51595. ryt = floor(bBox.y),
  51596. rxr = ceil(bBox.width + bBox.x),
  51597. ryb = ceil(bBox.height + bBox.y),
  51598. width,
  51599. height;
  51600. bBox.x = $isNumeric(rxl) && rxl < MAX_PIXEL_COUNT && rxl > -MAX_PIXEL_COUNT ? rxl : 0;
  51601. bBox.y = $isNumeric(ryt) && ryt < MAX_PIXEL_COUNT && ryt > -MAX_PIXEL_COUNT ? ryt : 0;
  51602. width = rxr - rxl;
  51603. height = ryb - ryt;
  51604. bBox.width = $isNumeric(width) && width < MAX_PIXEL_COUNT && width > -MAX_PIXEL_COUNT ? width : 0;
  51605. bBox.height = $isNumeric(height) && height < MAX_PIXEL_COUNT && height > -MAX_PIXEL_COUNT ? height : 0;
  51606. bBox.isEmpty = !bBox.x && !bBox.y && !bBox.width && !bBox.height;
  51607. return bBox
  51608. },
  51609. clear: function(selector) {
  51610. selector ? this.$element.find(selector).remove() : this.$element.empty();
  51611. return this
  51612. },
  51613. detach: function() {
  51614. this.$element.detach();
  51615. return this
  51616. },
  51617. animate: function(params, options, complete) {
  51618. options = options || {};
  51619. var that = this,
  51620. animationParams = {};
  51621. if (complete)
  51622. $.extend(options, {complete: complete});
  51623. if (this.renderer.animOptions.enabled) {
  51624. $.each(params, function(name, to) {
  51625. switch (name) {
  51626. case'scale':
  51627. animationParams['transform'] = animationParams['transform'] || {};
  51628. var scale = that.transformation.scale || {};
  51629. animationParams['transform'].scale = {
  51630. x: {
  51631. from: utils.isDefined(scale.x) ? scale.x : 1,
  51632. to: utils.isDefined(to.x) ? to.x : 1
  51633. },
  51634. y: {
  51635. from: utils.isDefined(scale.y) ? scale.y : 1,
  51636. to: utils.isDefined(to.y) ? to.y : 1
  51637. }
  51638. };
  51639. break;
  51640. case'rotate':
  51641. animationParams['transform'] = animationParams['transform'] || {};
  51642. animationParams['transform'].rotate = {
  51643. angle: {
  51644. from: that.transformation.rotateAngle || 0,
  51645. to: to.angle
  51646. },
  51647. y: to.y || 0,
  51648. x: to.x || 0
  51649. };
  51650. break;
  51651. case'translate':
  51652. animationParams['transform'] = animationParams['transform'] || {};
  51653. animationParams['transform'].translate = {
  51654. x: {
  51655. from: that.transformation.translateX || 0,
  51656. to: to.x || 0
  51657. },
  51658. y: {
  51659. from: that.transformation.translateY || 0,
  51660. to: to.y || 0
  51661. }
  51662. };
  51663. break;
  51664. case'arc':
  51665. case'points':
  51666. animationParams[name] = to;
  51667. break;
  51668. default:
  51669. animationParams[name] = {
  51670. from: that.settings[name] || 0,
  51671. to: to
  51672. }
  51673. }
  51674. });
  51675. that.renderer.animateElement(that, animationParams, $.extend({}, this.renderer.animOptions, options))
  51676. }
  51677. else {
  51678. if (params.translate) {
  51679. if ('x' in params.translate)
  51680. params.translateX = params.translate.x;
  51681. if ('y' in params.translate)
  51682. params.translateY = params.translate.y;
  51683. delete params.translate
  51684. }
  51685. if (options) {
  51686. options.step && options.step.call(that, 1, 1);
  51687. options.complete && options.complete.call(that)
  51688. }
  51689. this.applySettings(params)
  51690. }
  51691. },
  51692. stopAnimation: function(disableComplete) {
  51693. var that = this;
  51694. that.animation && that.animation.stop(true, disableComplete);
  51695. return that
  51696. },
  51697. move: function(x, y, animate, animOptions) {
  51698. x = x || 0,
  51699. y = y || 0;
  51700. animOptions = animOptions || {};
  51701. if (!animate)
  51702. this.applySettings({
  51703. translateX: x,
  51704. translateY: y
  51705. });
  51706. else
  51707. this.animate({translate: {
  51708. x: x,
  51709. y: y
  51710. }}, animOptions);
  51711. return this
  51712. },
  51713. rotate: function(angle, x, y, animate, animOptions) {
  51714. angle = angle || 0;
  51715. x = x || 0;
  51716. y = y || 0;
  51717. animOptions = animOptions || {};
  51718. if (!animate)
  51719. this.applySettings({rotate: [angle, x, y]});
  51720. else
  51721. this.animate({rotate: {
  51722. angle: angle,
  51723. x: x,
  51724. y: y
  51725. }}, animOptions)
  51726. },
  51727. remove: function() {
  51728. this.$element.remove()
  51729. },
  51730. _normalizeSettings: function(settings) {
  51731. var key,
  51732. style,
  51733. firstChar,
  51734. styleName,
  51735. prop,
  51736. value,
  51737. normalized = {},
  51738. fontSetting,
  51739. rtl = this.renderer.rtl;
  51740. for (key in settings) {
  51741. prop = key,
  51742. value = settings[prop];
  51743. if (prop === 'align') {
  51744. prop = 'text-anchor';
  51745. value = {
  51746. left: rtl ? 'end' : 'start',
  51747. center: 'middle',
  51748. right: rtl ? 'start' : 'end'
  51749. }[value]
  51750. }
  51751. else if (prop === 'font') {
  51752. style = this['_style'] = this['_style'] || {};
  51753. if (!$.isPlainObject(value))
  51754. continue;
  51755. $.each(value, function(fontSetting) {
  51756. switch (fontSetting) {
  51757. case'color':
  51758. styleName = 'fill';
  51759. break;
  51760. case'opacity':
  51761. styleName = 'fillOpacity';
  51762. break;
  51763. case'cursor':
  51764. styleName = fontSetting;
  51765. break;
  51766. default:
  51767. firstChar = fontSetting.charAt(0);
  51768. styleName = 'font' + fontSetting.replace(firstChar, firstChar.toUpperCase())
  51769. }
  51770. style[styleName] = value[fontSetting]
  51771. });
  51772. continue
  51773. }
  51774. else if (prop === 'dashStyle') {
  51775. prop = 'stroke-dasharray';
  51776. value = (value || 'none').toLowerCase();
  51777. if (value === 'solid' || value === 'none')
  51778. value = null;
  51779. else {
  51780. value = value.replace(/longdash/g, '8,3,').replace(/dash/g, '4,3,').replace(/dot/g, '1,3,').replace(/,$/, '').split(',');
  51781. value = $.map(value, function(p) {
  51782. return +p * (settings.strokeWidth || 1)
  51783. }).join(',')
  51784. }
  51785. }
  51786. else if (/^(linecap|linejoin)$/i.test(prop))
  51787. prop = 'stroke-' + prop;
  51788. else if (/^(translateX|translateY|rotate|scale)$/i.test(prop)) {
  51789. this['_' + prop] = value;
  51790. continue
  51791. }
  51792. else if (prop === 'clipId') {
  51793. prop = 'clip-path';
  51794. value = getPatternUrl(value, this.renderer.pathModified)
  51795. }
  51796. else if (prop === 'style') {
  51797. this['_style'] = this['_style'] || {};
  51798. $.extend(true, this['_style'], value);
  51799. continue
  51800. }
  51801. else if (prop === 'sharpEdges')
  51802. continue;
  51803. else if (prop === 'text')
  51804. continue;
  51805. else if (prop === 'segments')
  51806. continue;
  51807. else
  51808. prop = DX.inflector.dasherize(prop);
  51809. normalized[prop] = value
  51810. }
  51811. return this._applyTransformation(normalized)
  51812. },
  51813. _applyTransformation: function(settings) {
  51814. this.transformation = {
  51815. translateX: this._translateX,
  51816. translateY: this._translateY,
  51817. rotateAngle: 0,
  51818. rotateX: 0,
  51819. rotateY: 0
  51820. };
  51821. var tr = this.transformation,
  51822. rotate = this._rotate,
  51823. scale = this._scale,
  51824. transformations = [];
  51825. if (utils.isDefined(tr.translateX) || utils.isDefined(tr.translateY))
  51826. transformations.push('translate(' + (tr.translateX || 0) + ',' + (tr.translateY || 0) + ')');
  51827. if (utils.isDefined(rotate)) {
  51828. if (utils.isNumber(rotate)) {
  51829. tr.rotateAngle = rotate;
  51830. tr.rotateX = settings.x || 0;
  51831. tr.rotateY = settings.y || 0
  51832. }
  51833. else if ($.isArray(rotate)) {
  51834. tr.rotateAngle = rotate[0] || 0;
  51835. tr.rotateX = rotate[1] || 0;
  51836. tr.rotateY = rotate[2] || 0
  51837. }
  51838. else if (utils.isObject(rotate)) {
  51839. tr.rotateAngle = rotate.angle || 0;
  51840. tr.rotateX = rotate.x || 0;
  51841. tr.rotateY = rotate.y || 0
  51842. }
  51843. transformations.push('rotate(' + tr.rotateAngle + ',' + tr.rotateX + ',' + tr.rotateY + ')')
  51844. }
  51845. if (utils.isNumber(scale)) {
  51846. var value = utils.isDefined(scale) ? scale : 1;
  51847. transformations.push('scale(' + value + ',' + value + ')');
  51848. tr.scale = {
  51849. x: value,
  51850. y: value
  51851. }
  51852. }
  51853. else if (utils.isObject(scale)) {
  51854. var valueX = utils.isDefined(scale.x) ? scale.x : 1;
  51855. var valueY = utils.isDefined(scale.y) ? scale.y : 1;
  51856. transformations.push('scale(' + valueX + ',' + valueY + ')');
  51857. tr.scale = {
  51858. x: valueX,
  51859. y: valueY
  51860. }
  51861. }
  51862. if (transformations.length)
  51863. settings.transform = transformations.join(' ');
  51864. return settings
  51865. }
  51866. });
  51867. var RootSvgElement = BaseSvgElement.inherit({
  51868. defaultSettings: function() {
  51869. return {
  51870. width: 0,
  51871. height: 0,
  51872. style: {
  51873. '-webkit-tap-highlight-color': 'rgba(0, 0, 0, 0)',
  51874. display: 'block',
  51875. overflow: 'hidden'
  51876. },
  51877. xmlns: 'http://www.w3.org/2000/svg',
  51878. 'xmlns:xlink': 'http://www.w3.org/1999/xlink',
  51879. version: '1.1',
  51880. stroke: 'none',
  51881. strokeWidth: 0,
  51882. fill: 'none'
  51883. }
  51884. },
  51885. ctor: function(renderer, params) {
  51886. this.callBase(renderer, 'svg', params)
  51887. }
  51888. });
  51889. var RectSvgBaseElement = {
  51890. defaultSettings: function() {
  51891. return {
  51892. x: 0,
  51893. y: 0,
  51894. width: 0,
  51895. height: 0
  51896. }
  51897. },
  51898. adjustSettings: function() {
  51899. if (!utils.isDefined(this.settings.sharpEdges) || this.settings.sharpEdges) {
  51900. this.sharpEdges();
  51901. delete this.settings.sharpEdges
  51902. }
  51903. },
  51904. prepareSettings: function(settings) {
  51905. var prevStrokeWidth = this.settings ? Number(this.settings.strokeWidth) || 0 : 0,
  51906. newStrokeWidth,
  51907. maxStrokeWidth,
  51908. strokeWidthChanged = false;
  51909. if (utils.isDefined(settings.width))
  51910. this._realWidth = Number(settings.width);
  51911. if (utils.isDefined(settings.height))
  51912. this._realHeight = Number(settings.height);
  51913. if (utils.isDefined(settings.x))
  51914. this._realX = Number(settings.x);
  51915. if (utils.isDefined(settings.y))
  51916. this._realY = Number(settings.y);
  51917. if (utils.isDefined(settings.strokeWidth))
  51918. this._realStrokeWidth = Number(settings.strokeWidth);
  51919. this._realStrokeWidth = this._realStrokeWidth || this.defaultSettings().strokeWidth || 0;
  51920. maxStrokeWidth = ~~((this._realWidth < this._realHeight ? this._realWidth : this._realHeight) / 2);
  51921. newStrokeWidth = this._realStrokeWidth < maxStrokeWidth ? this._realStrokeWidth : maxStrokeWidth;
  51922. if (newStrokeWidth !== prevStrokeWidth) {
  51923. strokeWidthChanged = true;
  51924. settings.sharpEdges = true;
  51925. newStrokeWidth > 0 && (settings.strokeWidth = newStrokeWidth)
  51926. }
  51927. (utils.isDefined(settings.x) || strokeWidthChanged) && (settings.x = this._realX + newStrokeWidth / 2);
  51928. (utils.isDefined(settings.y) || strokeWidthChanged) && (settings.y = this._realY + newStrokeWidth / 2);
  51929. (utils.isDefined(settings.width) || strokeWidthChanged) && (settings.width = this._realWidth - newStrokeWidth);
  51930. (utils.isDefined(settings.height) || strokeWidthChanged) && (settings.height = this._realHeight - newStrokeWidth)
  51931. },
  51932. applySettings: function(settings) {
  51933. var settings = $.extend(true, {}, settings);
  51934. this.prepareSettings(settings);
  51935. return this.callBase(settings)
  51936. },
  51937. sharpEdges: function() {
  51938. var strokeWidth = Math.round(this.settings.strokeWidth || 0),
  51939. correction = strokeWidth % 2 / 2;
  51940. this.settings.x = Math.floor(this.settings.x - correction || 0) + correction;
  51941. this.settings.y = Math.floor(this.settings.y - correction || 0) + correction;
  51942. this.settings.width = Math.floor(this.settings.width || 0);
  51943. this.settings.height = Math.floor(this.settings.height || 0);
  51944. this.settings.strokeWidth > 0 && (this.settings.strokeWidth = strokeWidth)
  51945. }
  51946. };
  51947. var ImageSvgElement = BaseSvgElement.inherit(RectSvgBaseElement).inherit({
  51948. ctor: function(renderer, params, href, location) {
  51949. var locationToPreserveAspectRatioMap = {
  51950. full: 'none',
  51951. lefttop: 'xMinYMin',
  51952. leftcenter: 'xMinYMid',
  51953. leftbottom: 'xMinYMax',
  51954. centertop: 'xMidYMin',
  51955. center: 'xMidYMid',
  51956. centerbottom: 'xMidYMax',
  51957. righttop: 'xMaxYMin',
  51958. rightcenter: 'xMaxYMid',
  51959. rightbottom: 'xMaxYMax'
  51960. };
  51961. this.href = utils.isDefined(href) ? href : '';
  51962. this.preserveAspectRatio = locationToPreserveAspectRatioMap[(location || '').toLowerCase()];
  51963. this.preserveAspectRatio = this.preserveAspectRatio || 'none';
  51964. this.callBase(renderer, 'image', params)
  51965. },
  51966. adjustSettings: function() {
  51967. this.callBase();
  51968. this.element.setAttributeNS('http://www.w3.org/1999/xlink', 'href', this.href);
  51969. if (this.preserveAspectRatio)
  51970. this.element.setAttribute('preserveAspectRatio', this.preserveAspectRatio)
  51971. }
  51972. });
  51973. var RectSvgElement = BaseSvgElement.inherit(RectSvgBaseElement).inherit({
  51974. defaultSettings: function() {
  51975. return {
  51976. x: 0,
  51977. y: 0,
  51978. width: 0,
  51979. height: 0,
  51980. rx: 0,
  51981. ry: 0
  51982. }
  51983. },
  51984. ctor: function(renderer, params) {
  51985. this.callBase(renderer, 'rect', params)
  51986. }
  51987. });
  51988. var PathSvgElement = BaseSvgElement.inherit({
  51989. defaultSettings: function() {
  51990. return {points: {
  51991. x: 0,
  51992. y: 0
  51993. }}
  51994. },
  51995. getNodeName: function() {
  51996. return 'path'
  51997. },
  51998. getPathAttributeName: function() {
  51999. return 'd'
  52000. },
  52001. ctor: function(renderer, params) {
  52002. this.callBase(renderer, this.getNodeName(), params)
  52003. },
  52004. dispose: function() {
  52005. this.segments = null;
  52006. this.fromSegments = null;
  52007. this.callBase()
  52008. },
  52009. adjustSettings: function() {
  52010. this.prepareSegments(this.settings)
  52011. },
  52012. applySettings: function(settings) {
  52013. var settings = settings || {};
  52014. if (this.settings && settings.strokeWidth && this.settings.strokeWidth !== settings.strokeWidth)
  52015. settings.sharpEdges = true;
  52016. return this.callBase(settings)
  52017. },
  52018. prepareSegments: function(params) {
  52019. if ('points' in params) {
  52020. var points = params.points,
  52021. firstElem = points[0],
  52022. close = this.closePath || params.closePath,
  52023. segments = [],
  52024. i;
  52025. if (utils.isObject(firstElem))
  52026. segments = $.map(points, function(pt, i) {
  52027. if (!pt)
  52028. return null;
  52029. if (!i)
  52030. return [['M', pt.x, pt.y]];
  52031. return [['L', pt.x, pt.y]]
  52032. });
  52033. else if (utils.isNumber(firstElem))
  52034. for (i = 0; i < points.length; i += 2) {
  52035. if (!i) {
  52036. segments = [['M', points[i] || 0, points[i + 1] || 0]];
  52037. continue
  52038. }
  52039. segments.push(['L', points[i] || 0, points[i + 1] || 0])
  52040. }
  52041. else
  52042. segments = [['M', 0, 0]];
  52043. if (close)
  52044. segments.push(['Z']);
  52045. this.segments = segments;
  52046. delete params.points;
  52047. delete params.closePath;
  52048. params.sharpEdges = true
  52049. }
  52050. if (params.sharpEdges) {
  52051. this.sharpEdges();
  52052. this.combinePathParams(params);
  52053. delete params.sharpEdges
  52054. }
  52055. },
  52056. customizeSegments: function(segments) {
  52057. return segments
  52058. },
  52059. combinePathParams: function(params) {
  52060. var path;
  52061. this.segments = this.customizeSegments(this.segments);
  52062. if (this.segments) {
  52063. path = $.map(this.segments, function(seg, i) {
  52064. return seg.join(' ')
  52065. });
  52066. path = path.join(' ');
  52067. params[this.getPathAttributeName()] = path
  52068. }
  52069. },
  52070. _prepareDifferrentPath: function(from, to) {
  52071. var end = {},
  52072. constsSeg;
  52073. if (to.length > from.length)
  52074. this._makeEqualPath(from, to);
  52075. else {
  52076. this.combinePathParams(end);
  52077. this._makeEqualPath(to, from)
  52078. }
  52079. return end.d
  52080. },
  52081. _prepareConstSegment: function(seg) {
  52082. seg[0] = "L"
  52083. },
  52084. _makeEqualPath: function(short, long) {
  52085. var constSeg = short[short.length - 1].slice();
  52086. this._prepareConstSegment(constSeg);
  52087. for (var i = short.length; i < long.length; i++)
  52088. short[i] = constSeg
  52089. },
  52090. animate: function(params, options, complete) {
  52091. var that = this;
  52092. if (!('points' in params) || !that.renderer.animOptions.enabled)
  52093. return that.callBase(params, options, complete);
  52094. var fromPath = that.segments,
  52095. end;
  52096. that.prepareSegments(params);
  52097. delete params.d;
  52098. if (fromPath.length === that.segments.length)
  52099. params.points = {
  52100. from: fromPath,
  52101. to: that.segments
  52102. };
  52103. else
  52104. end = that._prepareDifferrentPath(fromPath, that.segments);
  52105. params.points = {
  52106. from: fromPath,
  52107. to: that.segments,
  52108. end: end
  52109. };
  52110. that.callBase(params, options, complete)
  52111. },
  52112. sharpEdges: function() {
  52113. var that = this,
  52114. segLength = that.segments.length,
  52115. i = 0,
  52116. curSeg,
  52117. nextSeg,
  52118. curX,
  52119. curY,
  52120. nextX,
  52121. nextY,
  52122. curXIdx,
  52123. curYIdx,
  52124. nextXIdx,
  52125. nextYIdx,
  52126. strokeWidth = Math.round(that.settings.strokeWidth || 0),
  52127. correction = strokeWidth % 2 / 2;
  52128. for (i; i < segLength - 1; i++) {
  52129. curSeg = that.segments[i];
  52130. nextSeg = that.segments[i + 1];
  52131. if (nextSeg[0] === 'Z' && i)
  52132. nextSeg = that.segments[0];
  52133. switch (curSeg[0]) {
  52134. case'M':
  52135. case'L':
  52136. curXIdx = 1;
  52137. curYIdx = 2;
  52138. break;
  52139. case'C':
  52140. curXIdx = 5;
  52141. curYIdx = 6;
  52142. break;
  52143. case'A':
  52144. curXIdx = 6;
  52145. curYIdx = 7;
  52146. break;
  52147. case'Z':
  52148. continue
  52149. }
  52150. switch (nextSeg[0]) {
  52151. case'M':
  52152. case'L':
  52153. nextXIdx = 1;
  52154. nextYIdx = 2;
  52155. break;
  52156. case'C':
  52157. nextXIdx = 5;
  52158. nextYIdx = 6;
  52159. break;
  52160. case'A':
  52161. nextXIdx = 6;
  52162. nextYIdx = 7;
  52163. break;
  52164. case'Z':
  52165. continue
  52166. }
  52167. curX = Math.floor(curSeg[curXIdx]);
  52168. curY = Math.floor(curSeg[curYIdx]);
  52169. nextX = nextSeg[nextXIdx] = Math.floor(nextSeg[nextXIdx]);
  52170. nextY = nextSeg[nextYIdx] = Math.floor(nextSeg[nextYIdx]);
  52171. curSeg[curXIdx] = i == 0 ? curX : curSeg[curXIdx];
  52172. curSeg[curYIdx] = i == 0 ? curY : curSeg[curYIdx];
  52173. if (curX == nextX) {
  52174. curSeg[curXIdx] = curX + correction;
  52175. nextSeg[nextXIdx] = nextX + correction
  52176. }
  52177. if (curY == nextY) {
  52178. curSeg[curYIdx] = curY + correction;
  52179. nextSeg[nextYIdx] = nextY + correction
  52180. }
  52181. }
  52182. }
  52183. });
  52184. var SegmentRectSvgElement = PathSvgElement.inherit(RectSvgBaseElement).inherit({
  52185. defaultSettings: function() {
  52186. return $.extend(true, {}, this.callBase(), {segments: {
  52187. top: true,
  52188. bottom: true,
  52189. left: true,
  52190. right: true
  52191. }})
  52192. },
  52193. prepareSegments: function() {
  52194. var that = this,
  52195. settings = that.settings,
  52196. left = settings.x,
  52197. right = left + settings.width,
  52198. top = settings.y,
  52199. bottom = top + settings.height,
  52200. segments = [],
  52201. segmentSequence,
  52202. visiblyOpt = 0,
  52203. prevSegmentVisibility = 0;
  52204. var allSegment = {
  52205. top: [['M', left, top], ['L', right, top]],
  52206. right: [['M', right, top], ['L', right, bottom]],
  52207. bottom: [['M', right, bottom], ['L', left, bottom]],
  52208. left: [['M', left, bottom], ['L', left, top]]
  52209. };
  52210. $.each(allSegment, function(seg, _) {
  52211. var visibility = !!that.settings.segments[seg];
  52212. visiblyOpt = visiblyOpt * 2 + ~~visibility
  52213. });
  52214. switch (visiblyOpt) {
  52215. case(13):
  52216. case(9):
  52217. segmentSequence = ['left', 'top', 'right', 'bottom'];
  52218. break;
  52219. case(11):
  52220. segmentSequence = ['bottom', 'left', 'top', 'right'];
  52221. break;
  52222. default:
  52223. segmentSequence = ['top', 'right', 'bottom', 'left']
  52224. }
  52225. $.each(segmentSequence, function(_, seg) {
  52226. var segmentVisibility = !!that.settings.segments[seg];
  52227. if (segmentVisibility)
  52228. $.each(allSegment[seg].slice(prevSegmentVisibility), function(_, segment) {
  52229. segments.push(segment)
  52230. });
  52231. prevSegmentVisibility = ~~segmentVisibility
  52232. });
  52233. visiblyOpt == 15 && segments.push(['Z']);
  52234. this.segments = segments.length ? segments : [['M', 0, 0], ['Z']];
  52235. this.combinePathParams(settings)
  52236. },
  52237. adjustSettings: function() {
  52238. this.callBase();
  52239. this.prepareSegments()
  52240. },
  52241. applySettings: function(settings) {
  52242. var segments = this.settings && this.settings.segments || this.defaultSettings().segments;
  52243. settings.segments = $.extend(true, {}, segments || {}, settings.segments);
  52244. return this.callBase(settings)
  52245. }
  52246. });
  52247. var baseAreaElement = {
  52248. defaultSettings: function() {
  52249. return {points: {
  52250. x: 0,
  52251. y: 0
  52252. }}
  52253. },
  52254. ctor: function(renderer, params) {
  52255. this.closePath = true;
  52256. this.callBase(renderer, params)
  52257. },
  52258. _tailIndex: 0,
  52259. _makeEqualPath: function(short, long) {
  52260. var i,
  52261. tail,
  52262. head,
  52263. constsSeg1,
  52264. constsSeg2,
  52265. newTail = [];
  52266. if ((short.length - 1) % 2 == 0 && (long.length - 1) % 2 == 0) {
  52267. i = (short.length - 1) / 2 - 1;
  52268. tail = short.slice(i + 1);
  52269. head = short.slice(0, i + 1);
  52270. constsSeg1 = head[head.length - 1];
  52271. constsSeg2 = tail[this._tailIndex];
  52272. this._prepareConstSegment(constsSeg1);
  52273. for (var j = i; j < (long.length - 1) / 2 - 1; j++) {
  52274. head.push(constsSeg1);
  52275. newTail.push(constsSeg2)
  52276. }
  52277. head = this._concatAnimationSegment(head, newTail, tail);
  52278. for (i = 0; i < head.length; i++)
  52279. short[i] = head[i]
  52280. }
  52281. },
  52282. _concatAnimationSegment: function(head, newTail, tail) {
  52283. return head.concat(newTail, tail)
  52284. }
  52285. };
  52286. var AreaSvgElement = PathSvgElement.inherit(baseAreaElement);
  52287. var BezierSvgElement = PathSvgElement.inherit({
  52288. defaultSettings: function() {
  52289. return {points: {
  52290. x: 0,
  52291. y: 0
  52292. }}
  52293. },
  52294. _prepareConstSegment: function(seg) {
  52295. var x = seg[seg.length - 2],
  52296. y = seg[seg.length - 1];
  52297. seg[0] = "C";
  52298. seg[5] = seg[3] = seg[1] = x;
  52299. seg[6] = seg[4] = seg[2] = y
  52300. },
  52301. prepareSegments: function(params) {
  52302. if (!('points' in params))
  52303. return;
  52304. var points = params.points,
  52305. firstElem = points[0],
  52306. close = this.closePath || params.closePath,
  52307. segments = [],
  52308. seg = [],
  52309. i,
  52310. x,
  52311. y;
  52312. var cnt = 0;
  52313. if (utils.isObject(firstElem)) {
  52314. for (i = 0; i < points.length; i++) {
  52315. x = points[i].x;
  52316. y = points[i].y;
  52317. if (!i) {
  52318. segments = [['M', x, y]];
  52319. continue
  52320. }
  52321. if ((i - 1) % 3 == 0) {
  52322. if (seg.length > 0)
  52323. segments.push(seg);
  52324. seg = ['C', x, y];
  52325. continue
  52326. }
  52327. seg.push(x);
  52328. seg.push(y)
  52329. }
  52330. if (seg.length > 0)
  52331. segments.push(seg)
  52332. }
  52333. else if (utils.isNumber(firstElem)) {
  52334. for (i = 0; i < points.length; i += 2) {
  52335. x = points[i];
  52336. y = points[i + 1];
  52337. if (!i) {
  52338. segments = [['M', x, y || 0]];
  52339. continue
  52340. }
  52341. if ((i - 2) % 6 == 0) {
  52342. if (seg.length > 0)
  52343. segments.push(seg);
  52344. seg = ['C', x, y || 0];
  52345. continue
  52346. }
  52347. seg.push(x);
  52348. seg.push(y || 0)
  52349. }
  52350. if (seg.length > 0)
  52351. segments.push(seg)
  52352. }
  52353. else
  52354. segments = [['M', 0, 0]];
  52355. if (close)
  52356. segments.push(['Z']);
  52357. this.segments = segments;
  52358. delete params.points;
  52359. delete params.closePath;
  52360. this.combinePathParams(params)
  52361. }
  52362. });
  52363. var BezierAreaSvgElement = BezierSvgElement.inherit(baseAreaElement).inherit({
  52364. _concatAnimationSegment: function(head, newTail, tail) {
  52365. var point = tail.splice(0, 1);
  52366. return head.concat(point.concat(newTail), tail)
  52367. },
  52368. _tailIndex: 1
  52369. });
  52370. var ArcSvgElement = PathSvgElement.inherit({
  52371. defaultSettings: function() {
  52372. return {
  52373. x: 0,
  52374. y: 0,
  52375. linejoin: 'round'
  52376. }
  52377. },
  52378. createArcSegments: function(x, y, innerR, outerR, startAngle, endAngle, isCircle) {
  52379. var longFlag = Math.floor(Math.abs(endAngle - startAngle) / Math.PI) % 2 ? '1' : '0',
  52380. xOuterStart = x + outerR * Math.cos(startAngle),
  52381. yOuterStart = y - outerR * Math.sin(startAngle),
  52382. xOuterEnd = x + outerR * Math.cos(endAngle),
  52383. yOuterEnd = y - outerR * Math.sin(endAngle),
  52384. xInnerStart = x + innerR * Math.cos(endAngle),
  52385. yInnerStart = y - innerR * Math.sin(endAngle),
  52386. xInnerEnd = x + innerR * Math.cos(startAngle),
  52387. yInnerEnd = y - innerR * Math.sin(startAngle);
  52388. return [['M', xOuterStart, yOuterStart], ['A', outerR, outerR, 0, longFlag, 0, xOuterEnd, yOuterEnd], [isCircle ? 'M' : 'L', xInnerStart, yInnerStart], ['A', innerR, innerR, 0, longFlag, 1, xInnerEnd, yInnerEnd], ['Z']]
  52389. },
  52390. prepareSegments: function(params) {
  52391. if (!('x' in params) && !('y' in params) && !('outerRadius' in params) && !('innerRadius' in params) && !('startAngle' in params) && !('endAngle' in params))
  52392. return;
  52393. var x = utils.isNumber(params.x) ? Number(params.x) : 0,
  52394. y = utils.isNumber(params.y) ? Number(params.y) : 0,
  52395. outerR = utils.isNumber(params.outerRadius) ? Number(params.outerRadius) : 0,
  52396. innerR = utils.isNumber(params.innerRadius) ? Number(params.innerRadius) : 0,
  52397. startAngle = utils.isNumber(params.startAngle) ? Number(params.startAngle) : 0,
  52398. endAngle = utils.isNumber(params.endAngle) ? Number(params.endAngle) : 360,
  52399. isCircle;
  52400. this.segments = [['M', 0, 0], ['Z']];
  52401. if (outerR || innerR) {
  52402. var tmp = Math.min(outerR, innerR);
  52403. outerR = Math.max(outerR, innerR);
  52404. innerR = tmp;
  52405. if (Math.round(startAngle) != Math.round(endAngle)) {
  52406. if (Math.abs(endAngle - startAngle) % 360 == 0) {
  52407. startAngle = 0;
  52408. endAngle = 360;
  52409. isCircle = true;
  52410. endAngle -= 0.0001
  52411. }
  52412. if (startAngle > 360)
  52413. startAngle = startAngle % 360;
  52414. if (endAngle > 360)
  52415. endAngle = endAngle % 360;
  52416. if (startAngle > endAngle)
  52417. startAngle -= 360;
  52418. startAngle = startAngle * Math.PI / 180;
  52419. endAngle = endAngle * Math.PI / 180;
  52420. this.segments = this.createArcSegments(x, y, innerR, outerR, startAngle, endAngle, isCircle)
  52421. }
  52422. }
  52423. this.x = params.x;
  52424. this.y = params.y;
  52425. this.outerRadius = params.outerRadius;
  52426. this.innerRadius = params.innerRadius;
  52427. this.startAngle = params.startAngle;
  52428. this.endAngle = params.endAngle;
  52429. delete params.x;
  52430. delete params.y;
  52431. delete params.outerRadius;
  52432. delete params.innerRadius;
  52433. delete params.startAngle;
  52434. delete params.endAngle;
  52435. this.combinePathParams(params)
  52436. },
  52437. animate: function(params) {
  52438. var _this = this;
  52439. if ('x' in params && 'y' in params && 'outerRadius' in params && 'innerRadius' in params && 'startAngle' in params && 'endAngle' in params && this.renderer.animOptions.enabled) {
  52440. var settings = this.settings;
  52441. params.arc = {
  52442. from: {
  52443. x: this.x,
  52444. y: this.y,
  52445. outerRadius: this.outerRadius,
  52446. innerRadius: this.innerRadius,
  52447. startAngle: this.startAngle,
  52448. endAngle: this.endAngle
  52449. },
  52450. to: {
  52451. x: params.x,
  52452. y: params.y,
  52453. outerRadius: params.outerRadius,
  52454. innerRadius: params.innerRadius,
  52455. startAngle: params.startAngle,
  52456. endAngle: params.endAngle
  52457. }
  52458. };
  52459. delete params.d;
  52460. delete params.x;
  52461. delete params.y;
  52462. delete params.outerRadius;
  52463. delete params.innerRadius;
  52464. delete params.startAngle;
  52465. delete params.endAngle
  52466. }
  52467. this.callBase.apply(this, arguments)
  52468. }
  52469. });
  52470. var CircleSvgElement = BaseSvgElement.inherit({
  52471. defaultSettings: function() {
  52472. return {
  52473. cx: 0,
  52474. cy: 0,
  52475. r: 0
  52476. }
  52477. },
  52478. ctor: function(renderer, params) {
  52479. this.callBase(renderer, 'circle', params)
  52480. }
  52481. });
  52482. var TextSvgElement = BaseSvgElement.inherit({
  52483. defaultSettings: function() {
  52484. return {
  52485. x: 0,
  52486. y: 0
  52487. }
  52488. },
  52489. ctor: function(renderer, params) {
  52490. this.tspans = [];
  52491. this.callBase(renderer, 'text', params)
  52492. },
  52493. dispose: function() {
  52494. this.tspans = null;
  52495. this.callBase()
  52496. },
  52497. updateText: function(text) {
  52498. if (!utils.isDefined(text))
  52499. text = '';
  52500. this.applySettings({text: text})
  52501. },
  52502. adjustSettings: function() {
  52503. if (!('text' in this.settings)) {
  52504. this.changeX();
  52505. return
  52506. }
  52507. this._createElementWithText(this.settings.text)
  52508. },
  52509. changeX: function() {
  52510. for (var i = 0; i < this.tspans.length; i++)
  52511. if (this.tspans[i].settings.x != undefined)
  52512. this.tspans[i].applySettings({x: this.settings.x})
  52513. },
  52514. _createElementWithText: function(text) {
  52515. var div,
  52516. i;
  52517. this.clear();
  52518. text = text.toString().replace(/\r/g, "");
  52519. text = text.replace(/\n/g, "<br/>");
  52520. div = doc.createElement("div");
  52521. div.innerHTML = text;
  52522. div.params = {style: {}};
  52523. this._orderText(div)
  52524. },
  52525. clear: function() {
  52526. this.callBase();
  52527. this.tspans = []
  52528. },
  52529. _orderText: function(node) {
  52530. var textArray = [],
  52531. defaultFontSize = (this.settings.font ? this.settings.font.size : 12) || 12;
  52532. var order = function(strCount, node, textArray) {
  52533. var params = {style: {}},
  52534. textArray = textArray || [];
  52535. node.params = node.params || {};
  52536. if (node.parentNode && node.nodeName != "#text")
  52537. if (node.parentNode.params)
  52538. for (var i in node.parentNode.params)
  52539. node.params[i] = node.parentNode.params[i];
  52540. switch (node.tagName) {
  52541. case"B" || "STRONG":
  52542. node.params.fontWeight = "bold";
  52543. break;
  52544. case"I" || "EM":
  52545. node.params.fontStyle = "italic";
  52546. break;
  52547. case"U":
  52548. node.params.textDecoration = "underline";
  52549. break;
  52550. case"BR":
  52551. strCount++;
  52552. break
  52553. }
  52554. if (node.style) {
  52555. if (node.style.fontSize)
  52556. node.params.fontSize = (parseInt(node.style.fontSize) || node.params.fontSize) + "px";
  52557. node.params.fill = node.style.color || node.params.fill;
  52558. node.params.fontStyle = node.style.fontStyle || node.params.fontStyle;
  52559. node.params.fontWeight = node.style.fontWeight || node.params.fontWeight;
  52560. node.params.textDecoration = node.style.textDecoration || node.params.textDecoration
  52561. }
  52562. var childnum = node.childNodes.length;
  52563. var count = 0;
  52564. while (count != childnum)
  52565. strCount = order(strCount, node.childNodes[count++], textArray);
  52566. if (node.wholeText != undefined) {
  52567. params.fill = node.parentNode.params.fill;
  52568. params.text = node.wholeText;
  52569. node.parentNode.params.fontSize && (params.style.fontSize = node.parentNode.params.fontSize);
  52570. node.parentNode.params.fontStyle && (params.style.fontStyle = node.parentNode.params.fontStyle);
  52571. node.parentNode.params.fontWeight && (params.style.fontWeight = node.parentNode.params.fontWeight);
  52572. node.parentNode.params.textDecoration && (params.style.textDecoration = node.parentNode.params.textDecoration);
  52573. textArray.push({
  52574. params: params,
  52575. line: strCount
  52576. })
  52577. }
  52578. return strCount
  52579. };
  52580. order(0, node, textArray);
  52581. for (var txt = 0; txt < textArray.length; txt++) {
  52582. if (txt != 0)
  52583. if (textArray[txt].line != textArray[txt - 1].line) {
  52584. textArray[txt].params.dy = textArray[txt].params.style.fontSize || defaultFontSize;
  52585. textArray[txt].params.x = this.settings.x
  52586. }
  52587. else {
  52588. textArray[txt].params.dy = 0;
  52589. textArray[txt].params.dx = 0
  52590. }
  52591. else {
  52592. textArray[txt].params.x = this.settings.x;
  52593. textArray[txt].params.dy = 0
  52594. }
  52595. var tspan = new TspanSvgElement(this.renderer, textArray[txt].params);
  52596. tspan.append(this);
  52597. this.tspans.push(tspan)
  52598. }
  52599. }
  52600. });
  52601. var TspanSvgElement = BaseSvgElement.inherit({ctor: function(renderer, params) {
  52602. var text = params.text || '';
  52603. delete params.text;
  52604. this.callBase(renderer, 'tspan', params);
  52605. this.element.appendChild(doc.createTextNode(text))
  52606. }});
  52607. var GroupSvgElement = BaseSvgElement.inherit({
  52608. ctor: function(renderer, params) {
  52609. this.callBase(renderer, 'g', params)
  52610. },
  52611. update: $.noop
  52612. });
  52613. var PatternSvgElement = BaseSvgElement.inherit({
  52614. ctor: function(renderer, params) {
  52615. this.__patternParams = $.extend({}, params);
  52616. var id = utils.getNextDefsSvgId(),
  52617. color = params.color,
  52618. hatching = params.hatching,
  52619. opacity = hatching.opacity,
  52620. width = hatching.width || 1,
  52621. step = hatching.step || 6,
  52622. direction = hatching.direction,
  52623. options = {
  52624. strokeWidth: width,
  52625. stroke: color
  52626. };
  52627. this.callBase(renderer, 'pattern', {
  52628. id: id,
  52629. width: step,
  52630. height: step
  52631. });
  52632. this.element.setAttribute('patternUnits', 'userSpaceOnUse');
  52633. this._rect = renderer.createRect(0, 0, step, step, 0, {
  52634. fill: color,
  52635. opacity: opacity
  52636. }).append(this);
  52637. this._path = renderer.createPath(0, options).append(this);
  52638. if (direction === 'right')
  52639. this._path.applySettings({d: "M " + step / 2 + " " + -step / 2 + " L " + -step / 2 + " " + step / 2 + "M 0 " + step + " L " + step + " 0 M " + step * 1.5 + " " + step / 2 + " L " + step / 2 + " " + step * 1.5});
  52640. else if (direction === 'left')
  52641. this._path.applySettings({d: "M 0 0 L " + step + ' ' + step + " M " + -step / 2 + " " + step / 2 + " L " + step / 2 + " " + step * 1.5 + " M " + step / 2 + -step / 2 + " L " + step * 1.5 + " " + step / 2});
  52642. this.id = getPatternUrl(id, renderer.pathModified)
  52643. },
  52644. append: function() {
  52645. return this.callBase(this.renderer.getDefsSvg())
  52646. },
  52647. clear: function() {
  52648. this.callBase();
  52649. this._path = null
  52650. },
  52651. dispose: function() {
  52652. this._path = null;
  52653. this.callBase()
  52654. }
  52655. });
  52656. var ClipRectSvgElement = BaseSvgElement.inherit({
  52657. ctor: function(renderer, params) {
  52658. this.__clipRectParams = $.extend({}, params);
  52659. var x = params.x,
  52660. y = params.y,
  52661. w = params.w,
  52662. h = params.h,
  52663. id = utils.getNextDefsSvgId();
  52664. delete params.x;
  52665. delete params.y;
  52666. delete params.w;
  52667. delete params.h;
  52668. this.callBase(renderer, 'clipPath', {id: id});
  52669. this.id = id;
  52670. this._rect = renderer.createRect(x, y, w, h, 0, params);
  52671. this._rect.append(this)
  52672. },
  52673. append: function() {
  52674. return this.callBase(this.renderer.getDefsSvg())
  52675. },
  52676. updateRectangle: function(settings) {
  52677. this._rect.applySettings(settings)
  52678. },
  52679. dispose: function() {
  52680. this._rect = null;
  52681. this.callBase()
  52682. }
  52683. });
  52684. var BaseFilterSvgElement = BaseSvgElement.inherit({
  52685. ctor: function(renderer) {
  52686. this.applySettings = $.noop;
  52687. this.callBase(renderer, 'filter');
  52688. delete this.applySettings;
  52689. this.ref = null;
  52690. this._create()
  52691. },
  52692. append: function() {
  52693. return this.callBase(this.renderer.getDefsSvg())
  52694. },
  52695. dispose: function() {
  52696. while (this.element.firstChild)
  52697. this.element.removeChild(this.element.firstChild);
  52698. this.callBase();
  52699. return this
  52700. },
  52701. applySettings: function(settings) {
  52702. settings = settings || {};
  52703. settings.id = utils.getNextDefsSvgId();
  52704. this.$element.attr({
  52705. id: settings.id,
  52706. x: settings.x || null,
  52707. y: settings.y || null,
  52708. width: settings.width || null,
  52709. height: settings.height || null
  52710. });
  52711. this.ref = settings.id ? getPatternUrl(settings.id, this.renderer.pathModified) : null;
  52712. this._update(settings);
  52713. return this
  52714. }
  52715. });
  52716. function setAttributes(element, attr) {
  52717. $.each(attr, function(name, value) {
  52718. element.setAttribute(name, value)
  52719. })
  52720. }
  52721. var ShadowFilterSvgElement = BaseFilterSvgElement.inherit({
  52722. _create: function() {
  52723. var that = this,
  52724. gaussianBlur = that._gaussianBlur = createElement('feGaussianBlur'),
  52725. offset = that._offset = createElement('feOffset'),
  52726. flood = that._flood = createElement('feFlood'),
  52727. composite = that._composite = createElement('feComposite'),
  52728. finalComposite = createElement('feComposite');
  52729. setAttributes(gaussianBlur, {
  52730. 'in': 'SourceGraphic',
  52731. result: 'gaussianBlurResult'
  52732. });
  52733. setAttributes(offset, {
  52734. 'in': 'gaussianBlurResult',
  52735. result: 'offsetResult'
  52736. });
  52737. setAttributes(flood, {result: 'floodResult'});
  52738. setAttributes(composite, {
  52739. 'in': 'floodResult',
  52740. in2: 'offsetResult',
  52741. operator: 'in',
  52742. result: 'compositeResult'
  52743. });
  52744. setAttributes(finalComposite, {
  52745. 'in': 'SourceGraphic',
  52746. in2: 'compositeResult',
  52747. operator: 'over'
  52748. });
  52749. that.element.appendChild(gaussianBlur);
  52750. that.element.appendChild(offset);
  52751. that.element.appendChild(flood);
  52752. that.element.appendChild(composite);
  52753. that.element.appendChild(finalComposite)
  52754. },
  52755. _update: function(settings) {
  52756. setAttributes(this._gaussianBlur, {stdDeviation: settings.blur || 0});
  52757. setAttributes(this._offset, {
  52758. dx: settings.dx || 0,
  52759. dy: settings.dy || 0
  52760. });
  52761. setAttributes(this._flood, {
  52762. 'flood-color': settings.color,
  52763. 'flood-opacity': settings.opacity
  52764. })
  52765. }
  52766. });
  52767. renderers.SvgRenderer = Class.inherit({
  52768. ctor: function(options) {
  52769. var that = this;
  52770. options = options || {};
  52771. that._setAnimationOptions(options.animation || {});
  52772. that.animationController = new renderers.AnimationController;
  52773. that.pathModified = options.pathModified;
  52774. that.rtl = !!options.rtl;
  52775. that.cssClass = options.cssClass || '';
  52776. that.recreateCanvas(options.width, options.height)
  52777. },
  52778. dispose: function() {
  52779. var that = this;
  52780. that.detachContainer();
  52781. that.svgRoot && (that.svgRoot.remove(), that.svgRoot = null);
  52782. that.animationController.dispose();
  52783. that.animOptions = null;
  52784. that.animationController = null
  52785. },
  52786. _setAnimationOptions: function(options) {
  52787. this.animOptions = {
  52788. enabled: true,
  52789. duration: 1000,
  52790. easing: 'easeOutCubic'
  52791. };
  52792. if ('enabled' in options)
  52793. this.animOptions.enabled = options.enabled;
  52794. if ('duration' in options)
  52795. this.animOptions.duration = options.duration;
  52796. if ('easing' in options)
  52797. this.animOptions.easing = options.easing
  52798. },
  52799. animationEnabled: function() {
  52800. return !!this.animOptions.enabled
  52801. },
  52802. updateAnimationOptions: function(newOptions) {
  52803. this._setAnimationOptions($.extend(this.animOptions || {}, newOptions))
  52804. },
  52805. stopAllAnimations: function(lock) {
  52806. lock ? this.animationController.lock() : this.animationController.stop()
  52807. },
  52808. detachContainer: function() {
  52809. var that = this;
  52810. that.svgRoot && that.svgRoot.detach();
  52811. that.defsSvg && (that.defsSvg.remove(), that.defsSvg = null);
  52812. that.drawn = null
  52813. },
  52814. recreateCanvas: function(width, height, cssClass) {
  52815. if (width >= 0 && height >= 0) {
  52816. if (!this.svgRoot) {
  52817. this.cssClass = cssClass || this.cssClass;
  52818. this.svgRoot = new RootSvgElement(this, {
  52819. width: width,
  52820. height: height,
  52821. 'class': this.cssClass,
  52822. direction: this.rtl ? 'rtl' : 'ltr'
  52823. });
  52824. this.animationController.element = this.svgRoot.element
  52825. }
  52826. else
  52827. this.svgRoot.applySettings({
  52828. width: width,
  52829. height: height
  52830. });
  52831. this.defsSvg && this.defsSvg.clear("pattern")
  52832. }
  52833. },
  52834. resize: function(width, height) {
  52835. var root = this.getRoot();
  52836. root && width > 0 && height > 0 && root.applySettings({
  52837. width: width,
  52838. height: height
  52839. })
  52840. },
  52841. getRoot: function() {
  52842. return this.svgRoot
  52843. },
  52844. isInitialized: function() {
  52845. return !!this.svgRoot
  52846. },
  52847. draw: function(container) {
  52848. if (!container || this.drawn)
  52849. return;
  52850. container.appendChild(this.getRoot().element);
  52851. this.drawn = true
  52852. },
  52853. updateParams: function(params, options) {
  52854. if (options && options.strokeWidth)
  52855. params.strokeWidth = options.strokeWidth
  52856. },
  52857. animateElement: function(element, params, options) {
  52858. this.animationController.animateElement(element, params, options)
  52859. },
  52860. createRect: function(x, y, w, h, r, options) {
  52861. var params = {
  52862. x: x,
  52863. y: y,
  52864. width: w,
  52865. height: h,
  52866. rx: r,
  52867. ry: r
  52868. };
  52869. if (options && !options.inh)
  52870. $.extend(params, options);
  52871. this.updateParams(params, options);
  52872. return new RectSvgElement(this, params)
  52873. },
  52874. createSegmentRect: function(x, y, w, h, r, segments, options) {
  52875. var params = $.extend({}, options || {}, {
  52876. x: x,
  52877. y: y,
  52878. width: w,
  52879. height: h,
  52880. rx: r,
  52881. ry: r,
  52882. segments: segments
  52883. });
  52884. return new SegmentRectSvgElement(this, params)
  52885. },
  52886. createClipRect: function(x, y, w, h) {
  52887. var attr = {
  52888. x: x,
  52889. y: y,
  52890. w: w,
  52891. h: h,
  52892. fill: 'none',
  52893. stroke: 'none',
  52894. strokeWidth: 0
  52895. };
  52896. return new ClipRectSvgElement(this, attr)
  52897. },
  52898. createPattern: function(color, hatching) {
  52899. hatching = hatching || {};
  52900. hatching.direction = (hatching.direction || '').toLowerCase();
  52901. if (hatching.direction !== 'right' && hatching.direction !== 'left')
  52902. return {
  52903. id: color,
  52904. append: function() {
  52905. return this
  52906. },
  52907. clear: function(){},
  52908. dispose: function(){}
  52909. };
  52910. return new PatternSvgElement(this, {
  52911. hatching: hatching,
  52912. color: color
  52913. })
  52914. },
  52915. createImage: function(x, y, w, h, href, options) {
  52916. var params = $.extend({}, options || {}, {
  52917. x: x,
  52918. y: y,
  52919. width: w,
  52920. height: h
  52921. });
  52922. return new ImageSvgElement(this, params, href, params.location)
  52923. },
  52924. createLine: function(x1, y1, x2, y2, options) {
  52925. var params = {points: [x1, y1, x2, y2]};
  52926. if (options && !options.inh)
  52927. $.extend(params, options);
  52928. this.updateParams(params, options);
  52929. return new PathSvgElement(this, params)
  52930. },
  52931. createPath: function(points, options) {
  52932. var params = {points: points};
  52933. if (options && !options.inh)
  52934. $.extend(params, options);
  52935. this.updateParams(params, options);
  52936. return new PathSvgElement(this, params)
  52937. },
  52938. createSimplePath: function(options) {
  52939. return new BaseSvgElement(this, 'path', options)
  52940. },
  52941. createBezierPath: function(points, options) {
  52942. var params = {points: points};
  52943. if (options && !options.inh)
  52944. $.extend(params, options);
  52945. this.updateParams(params, options);
  52946. return new BezierSvgElement(this, params)
  52947. },
  52948. createArea: function(points, options) {
  52949. var params = {points: points};
  52950. if (options && !options.inh)
  52951. $.extend(params, options);
  52952. this.updateParams(params, options);
  52953. return new AreaSvgElement(this, params)
  52954. },
  52955. createBezierArea: function(points, options) {
  52956. var params = {points: points};
  52957. if (options && !options.inh)
  52958. $.extend(params, options);
  52959. this.updateParams(params, options);
  52960. return new BezierAreaSvgElement(this, params)
  52961. },
  52962. createCircle: function(x, y, r, options) {
  52963. var params = {
  52964. cx: x,
  52965. cy: y,
  52966. r: r
  52967. };
  52968. if (options && !options.inh)
  52969. $.extend(params, options);
  52970. return new CircleSvgElement(this, params)
  52971. },
  52972. createArc: function(x, y, outerRadius, innerRadius, startAngle, endAngle, options) {
  52973. var params = {
  52974. x: x,
  52975. y: y,
  52976. outerRadius: outerRadius,
  52977. innerRadius: innerRadius,
  52978. startAngle: startAngle,
  52979. endAngle: endAngle
  52980. };
  52981. if (options && !options.inh)
  52982. $.extend(params, options);
  52983. this.updateParams(params, options);
  52984. return new ArcSvgElement(this, params)
  52985. },
  52986. createText: function(text, x, y, options) {
  52987. var params = {
  52988. x: x,
  52989. y: y,
  52990. text: text
  52991. };
  52992. if (options && !options.inh)
  52993. $.extend(params, options);
  52994. return new TextSvgElement(this, params)
  52995. },
  52996. createGroup: function(options) {
  52997. return new GroupSvgElement(this, options)
  52998. },
  52999. createFilter: function(type) {
  53000. var filterType = type === 'shadow' ? ShadowFilterSvgElement : null;
  53001. if (filterType)
  53002. return new filterType(this);
  53003. return null
  53004. },
  53005. getDefsSvg: function() {
  53006. this.defsSvg = this.defsSvg || new BaseSvgElement(this, 'defs').append();
  53007. return this.defsSvg
  53008. },
  53009. svg: function() {
  53010. return this.svgRoot.$element.parent().html()
  53011. }
  53012. });
  53013. function buildPath(points) {
  53014. var i = 0,
  53015. ii = points.length,
  53016. list = [];
  53017. for (; i < ii; )
  53018. list.push('L', points[i++].toFixed(2), points[i++].toFixed(2));
  53019. if (ii) {
  53020. list[0] = 'M';
  53021. list.push('Z');
  53022. list = list.join(' ')
  53023. }
  53024. else
  53025. list = '';
  53026. return list
  53027. }
  53028. function processCircleSettings(x, y, size, borderWidth) {
  53029. var correct = size + ~~borderWidth & 1;
  53030. return {
  53031. cx: correct ? x + 0.5 : x,
  53032. cy: correct ? y + 0.5 : y,
  53033. r: size / 2
  53034. }
  53035. }
  53036. renderers._svgBuildPath = buildPath;
  53037. renderers._svgProcessCircleSettings = processCircleSettings;
  53038. renderers._svgRendererInternals = {
  53039. BaseSvgElement: BaseSvgElement,
  53040. RootSvgElement: RootSvgElement,
  53041. RectSvgElement: RectSvgElement,
  53042. ImageSvgElement: ImageSvgElement,
  53043. PathSvgElement: PathSvgElement,
  53044. AreaSvgElement: AreaSvgElement,
  53045. BezierSvgElement: BezierSvgElement,
  53046. BezierAreaSvgElement: BezierAreaSvgElement,
  53047. CircleSvgElement: CircleSvgElement,
  53048. TextSvgElement: TextSvgElement,
  53049. TspanSvgElement: TspanSvgElement,
  53050. GroupSvgElement: GroupSvgElement,
  53051. ArcSvgElement: ArcSvgElement,
  53052. RectSvgBaseElement: RectSvgBaseElement,
  53053. SegmentRectSvgElement: SegmentRectSvgElement,
  53054. ClipRectSvgElement: ClipRectSvgElement,
  53055. PatternSvgElement: PatternSvgElement,
  53056. ShadowFilterSvgElement: ShadowFilterSvgElement
  53057. }
  53058. })(jQuery, DevExpress);
  53059. /*! Module viz-core, file vmlRenderer.js */
  53060. (function($, DX) {
  53061. var renderers = DX.viz.renderers,
  53062. utils = DX.utils,
  53063. doc = document,
  53064. svgRendererInternals = renderers._svgRendererInternals,
  53065. documentFragment = doc.createDocumentFragment();
  53066. function createVmlElement(nodeName) {
  53067. var element = doc.createElement(nodeName);
  53068. return documentFragment.appendChild(element)
  53069. }
  53070. var appendTimerID;
  53071. var vmlElementsToAppend = [];
  53072. var CSS_PROPERTIES = ['position', 'display', 'visibility', 'filter', 'margin', 'marginTop', 'marginLeft', 'marginRight', 'marginBottom', 'whiteSpace', 'clip', 'overflow'];
  53073. var INHERITABLE_PROPERTIES = ['stroke', 'fill', 'opacity', 'strokeWidth', 'align', 'dashStyle'];
  53074. var defaultVmlSettings = {
  53075. x: 0,
  53076. y: 0,
  53077. width: 1,
  53078. height: 1,
  53079. position: 'absolute',
  53080. behavior: 'url(#default#VML)',
  53081. display: 'inline-block',
  53082. xmlns: "urn:schemas-microsoft-com:vml"
  53083. };
  53084. var CLIP_RECT_CLASS = "dx-vml-clip-rect";
  53085. var extendDefaultVmlOptions = function(customOptions, baseOptions) {
  53086. return $.extend(true, baseOptions || {}, defaultVmlSettings, customOptions)
  53087. };
  53088. var parseRotateParameter = function(rotate, defaultX, defaultY) {
  53089. var rotateObject;
  53090. if (utils.isDefined(rotate))
  53091. if (utils.isNumber(rotate))
  53092. rotateObject = {
  53093. angle: rotate,
  53094. x: defaultX || 0,
  53095. y: defaultY || 0
  53096. };
  53097. else if ($.isArray(rotate))
  53098. rotateObject = {
  53099. angle: rotate[0] || 0,
  53100. x: rotate[1] || 0,
  53101. y: rotate[2] || 0
  53102. };
  53103. else if (utils.isObject(rotate))
  53104. rotateObject = {
  53105. angle: rotate.angle || 0,
  53106. x: rotate.x || 0,
  53107. y: rotate.y || 0
  53108. };
  53109. return rotateObject
  53110. };
  53111. function adjustOpacity(value) {
  53112. return value >= 0.002 ? value : value === null ? 1 : 0.002
  53113. }
  53114. var applySubElementAttribute = function(vmlElement, params, name) {
  53115. var element = vmlElement.element,
  53116. subElement,
  53117. value = params[name];
  53118. if (name === 'opacity' || name === 'fillOpacity')
  53119. if (element.fill)
  53120. element.fill.opacity = adjustOpacity(value);
  53121. if (name === 'joinStyle')
  53122. if (element.stroke)
  53123. element.stroke.joinStyle = value;
  53124. if (name === 'opacity' || name === 'strokeOpacity')
  53125. if (element.stroke)
  53126. element.stroke.opacity = value >= 0.002 ? value : value === null ? 1 : 0.002;
  53127. if (name === 'dashstyle')
  53128. if (element.stroke)
  53129. element.stroke.dashstyle = value
  53130. };
  53131. var getBoundingClientRect = function(element) {
  53132. var i,
  53133. resultRect,
  53134. rect,
  53135. tagName = element.tagName.toLowerCase(),
  53136. points,
  53137. value,
  53138. halfStrokeWidth;
  53139. if (element.className && element.className.indexOf(CLIP_RECT_CLASS) !== -1)
  53140. return;
  53141. if (tagName === 'div') {
  53142. if (element.childNodes.length > 0) {
  53143. resultRect = {};
  53144. for (i = 0; i < element.childNodes.length; i++) {
  53145. rect = getBoundingClientRect(element.childNodes[i]);
  53146. if (!rect)
  53147. continue;
  53148. resultRect.left = resultRect.left === undefined || rect.left < resultRect.left ? rect.left : resultRect.left;
  53149. resultRect.top = resultRect.top === undefined || rect.top < resultRect.top ? rect.top : resultRect.top;
  53150. resultRect.right = resultRect.right === undefined || rect.right > resultRect.right ? rect.right : resultRect.right;
  53151. resultRect.bottom = resultRect.bottom === undefined || rect.bottom > resultRect.bottom ? rect.bottom : resultRect.bottom
  53152. }
  53153. }
  53154. }
  53155. else if (tagName === 'shape' || tagName === 'vml:shape') {
  53156. points = (element.path.value || element.path).match(/[-0-9]+/g);
  53157. resultRect = {};
  53158. rect = element.getBoundingClientRect();
  53159. for (i = 0; i < points.length; i++) {
  53160. value = parseInt(points[i]);
  53161. if (i % 2) {
  53162. resultRect.top = resultRect.top === undefined || value < resultRect.top ? value : resultRect.top;
  53163. resultRect.bottom = resultRect.bottom === undefined || value > resultRect.bottom ? value : resultRect.bottom
  53164. }
  53165. else {
  53166. resultRect.left = resultRect.left === undefined || value < resultRect.left ? value : resultRect.left;
  53167. resultRect.right = resultRect.right === undefined || value > resultRect.right ? value : resultRect.right
  53168. }
  53169. }
  53170. resultRect.left = resultRect.left || 0;
  53171. resultRect.top = resultRect.top || 0;
  53172. resultRect.right = resultRect.right || 0;
  53173. resultRect.bottom = resultRect.bottom || 0;
  53174. if (rect.right - rect.left <= 1 && rect.top - rect.bottom <= 1) {
  53175. resultRect.right = resultRect.right + rect.left;
  53176. resultRect.bottom = resultRect.bottom + rect.top;
  53177. resultRect.left = resultRect.left + rect.left;
  53178. resultRect.top = resultRect.top + rect.top
  53179. }
  53180. else {
  53181. resultRect.right = resultRect.right - resultRect.left + rect.left;
  53182. resultRect.bottom = resultRect.bottom - resultRect.top + rect.top;
  53183. resultRect.left = rect.left;
  53184. resultRect.top = rect.top
  53185. }
  53186. halfStrokeWidth = Math.ceil(parseFloat(element.strokeweight) / 2);
  53187. if (halfStrokeWidth && halfStrokeWidth > 1) {
  53188. resultRect.left -= halfStrokeWidth;
  53189. resultRect.top -= halfStrokeWidth;
  53190. resultRect.right += halfStrokeWidth;
  53191. resultRect.bottom += halfStrokeWidth
  53192. }
  53193. }
  53194. else
  53195. resultRect = element.getBoundingClientRect();
  53196. return resultRect
  53197. };
  53198. var BaseVmlElement = {
  53199. isVml: function() {
  53200. return true
  53201. },
  53202. dispose: function() {
  53203. this.childElements = null;
  53204. this._style = null;
  53205. this._fullSettings = null;
  53206. this.callBase()
  53207. },
  53208. defaultSettings: function(customOptions) {
  53209. return extendDefaultVmlOptions(customOptions, this.callBase ? this.callBase() : {})
  53210. },
  53211. createElement: function(nodeName) {
  53212. this._nodeName = nodeName;
  53213. this.childElements = [];
  53214. this._fullSettings = {};
  53215. if (this.isVml()) {
  53216. var result = createVmlElement('vml:' + nodeName);
  53217. return result
  53218. }
  53219. else
  53220. return doc.createElement(nodeName)
  53221. },
  53222. append: function(element) {
  53223. var toElement = element || this.renderer.getRoot();
  53224. if (toElement) {
  53225. toElement.element.appendChild(this.element);
  53226. toElement.childElements.push(this);
  53227. if (this.parentElement)
  53228. this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
  53229. this.parentElement = toElement
  53230. }
  53231. if (toElement === this.renderer.getRoot() || toElement._isAppended)
  53232. this.appendComplete();
  53233. return this
  53234. },
  53235. insertBefore: function(target) {
  53236. var parent = target.parentElement;
  53237. parent.element.insertBefore(this.element, target.element);
  53238. this.parentElement = parent;
  53239. parent.childElements.splice($.inArray(target, parent.childElements), 0, this);
  53240. parent._isAppended && this.appendComplete();
  53241. return this
  53242. },
  53243. remove: function() {
  53244. this.callBase.apply(this, arguments);
  53245. if (this.parentElement) {
  53246. this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
  53247. this.parentElement = null
  53248. }
  53249. return this
  53250. },
  53251. detach: function() {
  53252. this.callBase.apply(this, arguments);
  53253. this._delayAttributes(['opacity']);
  53254. this._onDetach();
  53255. if (this.parentElement) {
  53256. this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
  53257. this.parentElement = null
  53258. }
  53259. return this
  53260. },
  53261. clear: function() {
  53262. this.callBase.apply(this, arguments);
  53263. $.each(this.childElements, function(_, element) {
  53264. element._delayAttributes(['opacity']);
  53265. element._onDetach();
  53266. element.parentElement = null
  53267. });
  53268. this.childElements = [];
  53269. return this
  53270. },
  53271. applyStyle: function(style) {
  53272. this.callBase(style);
  53273. if (style.opacity)
  53274. this.element.style.opacity = style.opacity;
  53275. if (style.clip)
  53276. try {
  53277. this.element.style.clip = style.clip
  53278. }
  53279. catch(e) {}
  53280. },
  53281. _fillAttributesFromParentAndCurrentStyle: function(attributes) {
  53282. var element = this.element,
  53283. parent = this.parentElement,
  53284. i,
  53285. settingToStyleMap = {strokeWidth: 'stroke-width'},
  53286. propertyName,
  53287. styleName,
  53288. settingsToApply = {};
  53289. if (parent)
  53290. for (i = 0; i < INHERITABLE_PROPERTIES.length; i++) {
  53291. propertyName = INHERITABLE_PROPERTIES[i];
  53292. if (!this.settings[propertyName] && parent._fullSettings[propertyName])
  53293. settingsToApply[propertyName] = parent._fullSettings[propertyName]
  53294. }
  53295. if (element.style && element.currentStyle)
  53296. for (i = 0; i < INHERITABLE_PROPERTIES.length; i++) {
  53297. propertyName = INHERITABLE_PROPERTIES[i];
  53298. styleName = settingToStyleMap[propertyName] || propertyName;
  53299. if (element.currentStyle[styleName])
  53300. settingsToApply[propertyName] = element.currentStyle[styleName]
  53301. }
  53302. $.extend(this._fullSettings, this.settings, settingsToApply);
  53303. if (this.isVml())
  53304. $.extend(attributes, this._normalizeSettings(settingsToApply))
  53305. },
  53306. _applyAttributes: function(params) {
  53307. var name,
  53308. value;
  53309. if (params && params.arcsize !== undefined) {
  53310. try {
  53311. this.element.setAttribute('arcsize', params.arcsize)
  53312. }
  53313. catch(e) {}
  53314. this.__appliedSettings = {arcsize: params.arcsize};
  53315. delete params.arcsize
  53316. }
  53317. if (params && params['class']) {
  53318. this.element.className = params['class'];
  53319. delete params['class']
  53320. }
  53321. if (!this._isAppended)
  53322. this._delayedAttributes = params;
  53323. else {
  53324. params = params || this._delayedAttributes;
  53325. if (params) {
  53326. this._fillAttributesFromParentAndCurrentStyle(params);
  53327. if (this.isVml()) {
  53328. for (name in params) {
  53329. value = params[name];
  53330. if (name === 'opacity' || name === 'fillOpacity' || name === 'strokeOpacity' || name === 'dashstyle' || name === 'joinStyle')
  53331. applySubElementAttribute(this, params, name);
  53332. else
  53333. this.element[name] = value
  53334. }
  53335. $.each(this.element.children, function(_, e) {
  53336. e.style.behavior = 'url(#default#VML)';
  53337. e.style.display = 'inline-block';
  53338. e.xmlns = "urn:schemas-microsoft-com:vml"
  53339. })
  53340. }
  53341. this.__appliedSettings = this.isVml() ? params : {};
  53342. delete this._delayedAttributes
  53343. }
  53344. }
  53345. },
  53346. _onDetach: function() {
  53347. this._isAppended = false;
  53348. $.each(this.childElements, function(_, child) {
  53349. child._onDetach()
  53350. })
  53351. },
  53352. appendComplete: function() {
  53353. if (this.renderer.isElementAppendedToPage(this)) {
  53354. this._isAppended = true;
  53355. this._applyAttributes();
  53356. $.each(this.childElements, function(_, child) {
  53357. child.appendComplete()
  53358. });
  53359. if (this.parentElement instanceof GroupVmlElement && this.parentElement._clipRect && this.parentElement._clipRect !== this)
  53360. if (this.parentElement._clipRect._isAppended)
  53361. this.parentElement._clipRect.toForeground();
  53362. else
  53363. this.parentElement._clipRect.append(this.parentElement)
  53364. }
  53365. else {
  53366. vmlElementsToAppend.push(this);
  53367. $(this.element).data('vmlNeedAppendComplete', true);
  53368. if (appendTimerID === undefined)
  53369. appendTimerID = setTimeout(function() {
  53370. appendTimerID = undefined;
  53371. var vmlElements = vmlElementsToAppend;
  53372. vmlElementsToAppend = [];
  53373. $.each(vmlElements, function() {
  53374. if ($(this.element).data('vmlNeedAppendComplete') && !this._isAppended)
  53375. this.appendComplete()
  53376. })
  53377. }, 200)
  53378. }
  53379. },
  53380. _delayAttributes: function(attributes) {
  53381. var attr,
  53382. val,
  53383. i,
  53384. settings = this.settings || {};
  53385. attributes = attributes || [];
  53386. this._delayedAttributes = this._delayedAttributes || {};
  53387. for (i = 0; i < attributes.length; i++) {
  53388. attr = attributes[i];
  53389. val = settings[attr];
  53390. if (val)
  53391. this._delayedAttributes[attr] = val
  53392. }
  53393. $.each(this.childElements || [], function(_, child) {
  53394. child._delayAttributes(attributes)
  53395. })
  53396. },
  53397. _normalizeSettings: function(settings) {
  53398. var key,
  53399. style = {},
  53400. normalized = {},
  53401. clipRect,
  53402. pos,
  53403. prop,
  53404. value;
  53405. for (key in settings) {
  53406. prop = key;
  53407. value = settings[prop];
  53408. if (prop === 'x' || prop === 'translateX') {
  53409. pos = settings.x || 0;
  53410. if (settings.translateX)
  53411. pos += settings.translateX;
  53412. style.left = pos + 'px'
  53413. }
  53414. else if (prop === 'y' || prop === 'translateY') {
  53415. pos = settings.y || 0;
  53416. if (settings.translateY)
  53417. pos += settings.translateY;
  53418. style.top = pos + 'px'
  53419. }
  53420. else if (prop === 'width')
  53421. style.width = value + 'px';
  53422. else if (prop === "behavior")
  53423. style[prop] = value;
  53424. else if (prop === 'height')
  53425. style.height = value + 'px';
  53426. else if (prop === 'align')
  53427. continue;
  53428. else if (prop === 'scale')
  53429. continue;
  53430. else if ($.inArray(prop, CSS_PROPERTIES) != -1)
  53431. style[prop] = value !== null ? value : '';
  53432. else if (prop === 'font') {
  53433. if (!$.isPlainObject(value))
  53434. continue;
  53435. $.each(value, function(fontSetting) {
  53436. var styleName,
  53437. firstChar;
  53438. switch (fontSetting) {
  53439. case'color':
  53440. styleName = "fill";
  53441. break;
  53442. case'opacity':
  53443. styleName = "opacity";
  53444. break;
  53445. case'cursor':
  53446. styleName = fontSetting;
  53447. break;
  53448. default:
  53449. firstChar = fontSetting.charAt(0);
  53450. styleName = 'font' + fontSetting.replace(firstChar, firstChar.toUpperCase())
  53451. }
  53452. if (styleName)
  53453. style[styleName] = value[fontSetting]
  53454. })
  53455. }
  53456. else if (prop === 'style')
  53457. $.extend(true, style, value);
  53458. else if (prop === 'rotate')
  53459. this['_rotate'] = value;
  53460. else if (prop === 'clipId') {
  53461. clipRect = this.renderer.getClipRect(value, this);
  53462. if (clipRect) {
  53463. var width = clipRect.width,
  53464. height = clipRect.height,
  53465. x = clipRect.x,
  53466. y = clipRect.y,
  53467. clipWidth = width + x,
  53468. clipHeight = height + y,
  53469. canvasSize = this.renderer._getSize();
  53470. style.width = canvasSize.width;
  53471. style.height = canvasSize.height;
  53472. style.clip = "rect(" + y + "px, " + clipWidth + "px, " + clipHeight + "px, " + x + "px)"
  53473. }
  53474. }
  53475. else if (prop === 'segments')
  53476. continue;
  53477. else if (prop === 'fill') {
  53478. normalized.filled = value === 'none' ? 'f' : 't';
  53479. normalized.fillcolor = value === 'grey' ? '#808080' : value
  53480. }
  53481. else if (prop === 'opacity')
  53482. normalized.opacity = value < 0.002 ? value : value;
  53483. else if (prop === 'stroke') {
  53484. normalized.stroked = value === 'none' ? 'f' : 't';
  53485. normalized.strokecolor = value
  53486. }
  53487. else if (prop === 'strokeWidth')
  53488. normalized.strokeweight = value + 'px';
  53489. else if (prop === 'lineJoin')
  53490. normalized.joinStyle = value;
  53491. else if (prop === 'dashStyle') {
  53492. value = (value || "").toLowerCase();
  53493. normalized.dashstyle = value
  53494. }
  53495. else
  53496. normalized[prop] = value
  53497. }
  53498. this['_style'] = style;
  53499. return normalized
  53500. },
  53501. _getBBox: function() {
  53502. var width,
  53503. height,
  53504. rect,
  53505. parentRect,
  53506. x = 0,
  53507. y = 0,
  53508. element = this.element,
  53509. parent;
  53510. try {
  53511. rect = getBoundingClientRect(element);
  53512. width = rect.right - rect.left;
  53513. height = rect.bottom - rect.top;
  53514. parent = this.element.parentNode || this.renderer.getRoot().element;
  53515. parentRect = parent.getBoundingClientRect();
  53516. x = rect.left - parentRect.left;
  53517. y = rect.top - parentRect.top;
  53518. if (element.tagName.toLowerCase() === 'div') {
  53519. x = x - (parseInt(element.style.left, 10) || 0);
  53520. y = y - (parseInt(element.style.top, 10) || 0)
  53521. }
  53522. }
  53523. catch(e) {
  53524. width = element.offsetWidth || 0;
  53525. height = element.offsetHeight || 0
  53526. }
  53527. return {
  53528. x: x,
  53529. y: y,
  53530. width: width,
  53531. height: height,
  53532. isEmpty: !x && !y && !width && !height
  53533. }
  53534. },
  53535. getBBox: function() {
  53536. return this._getBBox()
  53537. },
  53538. sharpEdges: function(){}
  53539. };
  53540. var convertSvgPathCommandToVml = function(command) {
  53541. switch (command) {
  53542. case'M':
  53543. return 'm';
  53544. case'L':
  53545. return 'l';
  53546. case'Z':
  53547. return 'x e'
  53548. }
  53549. return command
  53550. };
  53551. var BasePathVmlElement = {
  53552. defaultSettings: function() {
  53553. return $.extend(this.callBase(), {coordsize: '1,1'})
  53554. },
  53555. getNodeName: function() {
  53556. return 'shape'
  53557. },
  53558. getPathAttributeName: function() {
  53559. return 'path'
  53560. },
  53561. customizeSegments: function(segments) {
  53562. var result = segments;
  53563. if (segments)
  53564. result = $.map(segments, function(s, i) {
  53565. var pos,
  53566. segmentArray = [],
  53567. command = convertSvgPathCommandToVml(s[0]);
  53568. segmentArray.push(command);
  53569. for (pos = 1; pos < s.length; pos++)
  53570. segmentArray.push(Math.floor(s[pos]));
  53571. return [segmentArray]
  53572. });
  53573. return result
  53574. }
  53575. };
  53576. var RootVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  53577. isVml: function() {
  53578. return false
  53579. },
  53580. defaultSettings: function() {
  53581. return {
  53582. width: 0,
  53583. height: 0,
  53584. position: 'relative',
  53585. display: 'inline-block',
  53586. overflow: 'hidden',
  53587. stroke: 'none',
  53588. strokeWidth: 0,
  53589. fill: 'none'
  53590. }
  53591. },
  53592. ctor: function(renderer, params) {
  53593. this.callBase(renderer, 'div', params)
  53594. }
  53595. });
  53596. var ImageVmlElement = svgRendererInternals.BaseSvgElement.inherit(svgRendererInternals.RectSvgBaseElement).inherit(BaseVmlElement).inherit({
  53597. ctor: function(renderer, params) {
  53598. this.callBase(renderer, 'image', params)
  53599. },
  53600. defaultSettings: function() {
  53601. return $.extend(this.callBase(), {
  53602. strokeWidth: 0,
  53603. fill: 'none',
  53604. stroke: 'none'
  53605. })
  53606. },
  53607. adjustSettings: function() {
  53608. var defaultSettings = this.defaultSettings();
  53609. this.callBase();
  53610. if (this.settings.href) {
  53611. this.settings.src = this.settings.href;
  53612. delete this.settings.href
  53613. }
  53614. this.settings.fill = defaultSettings.fill;
  53615. this.settings.stroke = defaultSettings.stroke;
  53616. this.settings.strokeWidth = defaultSettings.strokeWidth
  53617. }
  53618. });
  53619. var RectVmlElement = svgRendererInternals.BaseSvgElement.inherit(svgRendererInternals.RectSvgBaseElement).inherit(BaseVmlElement).inherit({
  53620. defaultSettings: function() {
  53621. return extendDefaultVmlOptions({
  53622. stroked: 'f',
  53623. strokeWidth: 0,
  53624. rx: 0,
  53625. ry: 0
  53626. })
  53627. },
  53628. recreateElement: function(name) {
  53629. this._nodeName = name;
  53630. var parent = this.$element.parent()[0];
  53631. if (parent) {
  53632. var $oldElement = this.$element;
  53633. this.element = this.createElement(name);
  53634. this.$element = $(this.element);
  53635. this.$element.insertBefore($oldElement);
  53636. $oldElement.remove()
  53637. }
  53638. else {
  53639. this.element = this.createElement(name);
  53640. this.$element = $(this.element)
  53641. }
  53642. this.applySettings()
  53643. },
  53644. _adjustArcSize: function() {
  53645. var settings = this.settings;
  53646. var rx = settings.rx || 0,
  53647. ry = settings.ry || 0,
  53648. width = settings.width,
  53649. height = settings.height,
  53650. r,
  53651. halfsize,
  53652. arcsize;
  53653. if (settings.rx !== undefined || settings.ry !== undefined) {
  53654. r = Math.max(rx, ry);
  53655. halfsize = Math.max(width, height) / 2;
  53656. arcsize = r / halfsize;
  53657. settings.arcsize = arcsize;
  53658. if ($.isNumeric(arcsize) && arcsize != 0)
  53659. this._nodeName !== 'roundrect' && this.recreateElement('roundrect');
  53660. else
  53661. this._nodeName === 'roundrect' && this.recreateElement('rect');
  53662. delete settings.rx;
  53663. delete settings.ry
  53664. }
  53665. },
  53666. _adjustRotation: function() {
  53667. var settings = this.settings;
  53668. var rotate = this.settings.rotate,
  53669. rotateAngle,
  53670. radianAngle,
  53671. cos,
  53672. sin,
  53673. rotateX,
  53674. rotateY,
  53675. marginTop,
  53676. marginLeft,
  53677. cx,
  53678. cy,
  53679. rotateObject;
  53680. rotateObject = parseRotateParameter(rotate, settings.x, settings.y);
  53681. if (rotateObject) {
  53682. rotateAngle = rotateObject.angle;
  53683. rotateX = rotateObject.x;
  53684. rotateY = rotateObject.y;
  53685. radianAngle = rotateAngle * Math.PI / 180.0;
  53686. cos = Math.cos(radianAngle);
  53687. sin = Math.sin(radianAngle);
  53688. cx = settings.x + (settings.translateX || 0) + settings.width / 2;
  53689. cy = settings.y + (settings.translateY || 0) + settings.height / 2;
  53690. marginLeft = (cx - rotateX) * cos - (cy - rotateY) * sin + rotateX - cx;
  53691. marginTop = (cx - rotateX) * sin + (cy - rotateY) * cos + rotateY - cy;
  53692. this.settings.marginLeft = Math.round(marginLeft) + 'px';
  53693. this.settings.marginTop = Math.round(marginTop) + 'px';
  53694. this.settings.rotation = rotateAngle
  53695. }
  53696. },
  53697. adjustSettings: function() {
  53698. this.callBase();
  53699. this._adjustArcSize();
  53700. this._adjustRotation()
  53701. },
  53702. ctor: function(renderer, params) {
  53703. this.callBase(renderer, 'rect', params)
  53704. }
  53705. });
  53706. var PathVmlElement = svgRendererInternals.PathSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({prepareSegments: function(settings) {
  53707. var that = this,
  53708. rotate = settings.rotate,
  53709. rotateAngle,
  53710. rotateX,
  53711. rotateY,
  53712. oldSegments,
  53713. radianAngle,
  53714. cos,
  53715. sin,
  53716. x,
  53717. y,
  53718. rotatedX,
  53719. rotatedY,
  53720. rotateObject;
  53721. this.callBase(settings);
  53722. oldSegments = that.segments;
  53723. rotateObject = parseRotateParameter(rotate, settings.x, settings.y);
  53724. if (rotateObject) {
  53725. rotateAngle = rotateObject.angle;
  53726. rotateX = rotateObject.x;
  53727. rotateY = rotateObject.y;
  53728. if (that.segments) {
  53729. radianAngle = rotateAngle * Math.PI / 180.0;
  53730. cos = Math.cos(radianAngle);
  53731. sin = Math.sin(radianAngle);
  53732. that.segments = $.map(that.segments, function(s, i) {
  53733. if (s.length === 3) {
  53734. x = s[1],
  53735. y = s[2];
  53736. rotatedX = (x - rotateX) * cos - (y - rotateY) * sin + rotateX;
  53737. rotatedY = (x - rotateX) * sin + (y - rotateY) * cos + rotateY;
  53738. return [[s[0], Math.floor(rotatedX), Math.floor(rotatedY)]]
  53739. }
  53740. else
  53741. return [s]
  53742. });
  53743. that.combinePathParams(settings);
  53744. that.segments = oldSegments
  53745. }
  53746. }
  53747. }});
  53748. var SimplePathVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  53749. ctor: function(renderer, options) {
  53750. this.callBase(renderer, 'shape', options)
  53751. },
  53752. defaultSettings: function() {
  53753. return extendDefaultVmlOptions({coordsize: '1,1'})
  53754. },
  53755. adjustSettings: function() {
  53756. var settings = this.settings;
  53757. if (settings.d !== undefined) {
  53758. settings.path = settings.d;
  53759. delete settings.d
  53760. }
  53761. }
  53762. });
  53763. var AreaVmlElement = PathVmlElement.inherit({
  53764. defaultSettings: function() {
  53765. var baseOptions = this.callBase();
  53766. return extendDefaultVmlOptions({points: {
  53767. x: 0,
  53768. y: 0
  53769. }}, baseOptions)
  53770. },
  53771. ctor: function(renderer, params) {
  53772. this.closePath = true;
  53773. this.callBase(renderer, params)
  53774. }
  53775. });
  53776. var SegmentRectVmlElement = svgRendererInternals.SegmentRectSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({
  53777. defaultSettings: function() {
  53778. var settings = this.callBase();
  53779. settings.lineJoin = 'miter';
  53780. delete settings.fill;
  53781. delete settings.stroke;
  53782. delete settings.strokecolor;
  53783. delete settings.stroked;
  53784. return settings
  53785. },
  53786. prepareSegments: function() {
  53787. this.callBase();
  53788. this.segments = this.customizeSegments(this.segments);
  53789. this.settings.x = 0;
  53790. this.settings.y = 0;
  53791. this.settings.width = 1;
  53792. this.settings.height = 1
  53793. },
  53794. applySettings: function(settings) {
  53795. var x = settings.x,
  53796. y = settings.y,
  53797. w = settings.width,
  53798. h = settings.height;
  53799. this.callBase(settings);
  53800. this.settings.x = x;
  53801. this.settings.y = y;
  53802. this.settings.width = w;
  53803. this.settings.height = h;
  53804. return this
  53805. }
  53806. });
  53807. var BezierVmlElement = svgRendererInternals.BezierSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement);
  53808. var BezierAreaVmlElement = BezierVmlElement.inherit({
  53809. defaultSettings: function() {
  53810. var baseOptions = this.callBase();
  53811. return extendDefaultVmlOptions({points: {
  53812. x: 0,
  53813. y: 0
  53814. }}, baseOptions)
  53815. },
  53816. ctor: function(renderer, params) {
  53817. this.closePath = true;
  53818. this.callBase(renderer, params)
  53819. }
  53820. });
  53821. var ArcVmlElement = svgRendererInternals.ArcSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({createArcSegments: function(x, y, innerR, outerR, startAngle, endAngle, isCircle) {
  53822. var xOuterStart = x + outerR * Math.cos(startAngle),
  53823. yOuterStart = y - outerR * Math.sin(startAngle),
  53824. xOuterEnd = x + outerR * Math.cos(endAngle),
  53825. yOuterEnd = y - outerR * Math.sin(endAngle),
  53826. xInnerStart = x + innerR * Math.cos(endAngle),
  53827. yInnerStart = y - innerR * Math.sin(endAngle),
  53828. xInnerEnd = x + innerR * Math.cos(startAngle),
  53829. yInnerEnd = y - innerR * Math.sin(startAngle);
  53830. return [['wr', x - innerR, y - innerR, x + innerR, y + innerR, xInnerStart, yInnerStart, xInnerEnd, yInnerEnd], [isCircle ? 'wr' : 'at', x - outerR, y - outerR, x + outerR, y + outerR, xOuterStart, yOuterStart, xOuterEnd, yOuterEnd], ['x e']]
  53831. }});
  53832. var CircleVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  53833. defaultSettings: function() {
  53834. return extendDefaultVmlOptions({
  53835. cx: 0,
  53836. cy: 0,
  53837. r: 0
  53838. })
  53839. },
  53840. applySettings: function(settings) {
  53841. settings.cx = settings.cx || settings.x;
  53842. settings.cy = settings.cy || settings.y;
  53843. return this.callBase(settings)
  53844. },
  53845. adjustSettings: function() {
  53846. var r,
  53847. cx,
  53848. cy;
  53849. if (this.settings.cx !== undefined || this.settings.cy !== undefined || this.settings.r !== undefined) {
  53850. r = 'r' in this.settings ? this.settings.r : this.settings.width / 2;
  53851. cx = 'cx' in this.settings ? this.settings.cx : this.settings.x + this.settings.width / 2;
  53852. cy = 'cy' in this.settings ? this.settings.cy : this.settings.y + this.settings.width / 2;
  53853. this.settings.x = cx - r;
  53854. this.settings.y = cy - r;
  53855. this.settings.width = this.settings.height = r * 2;
  53856. delete this.settings.cx;
  53857. delete this.settings.cy;
  53858. delete this.settings.r
  53859. }
  53860. },
  53861. ctor: function(renderer, params) {
  53862. this.callBase(renderer, 'oval', params)
  53863. }
  53864. });
  53865. var TextVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  53866. isVml: function() {
  53867. return false
  53868. },
  53869. defaultSettings: function() {
  53870. return {
  53871. x: 0,
  53872. y: 0,
  53873. position: 'absolute',
  53874. whiteSpace: 'nowrap'
  53875. }
  53876. },
  53877. ctor: function(renderer, params) {
  53878. this.callBase(renderer, 'span', params)
  53879. },
  53880. adjustSettings: function() {
  53881. var text,
  53882. settings = this.settings;
  53883. if (settings.font) {
  53884. settings.fill = settings.fill || settings.font.color;
  53885. settings.opacity = settings.opacity || settings.font.opacity
  53886. }
  53887. if ('text' in settings) {
  53888. text = utils.isDefined(settings.text) ? settings.text : '';
  53889. text = text.toString().replace(/\r/g, "");
  53890. text = text.replace(/\n/g, "<br/>");
  53891. $(this.element).html(text);
  53892. delete settings.text
  53893. }
  53894. if (this.renderer.rtl)
  53895. $(this.element).css('direction', 'rtl')
  53896. },
  53897. updateText: function(text) {
  53898. this.applySettings({text: utils.isDefined(text) ? text : ''})
  53899. },
  53900. _applyAttributes: function(settings) {
  53901. this.callBase(settings);
  53902. settings = this._fullSettings;
  53903. var rotate = settings.rotate,
  53904. rotateAngle = 0,
  53905. rotateX,
  53906. rotateY,
  53907. cos = 1,
  53908. sin = 0,
  53909. osin = 0,
  53910. ocos = 1,
  53911. angle,
  53912. otg,
  53913. rad,
  53914. y = settings.y + (settings.translateY || 0),
  53915. x = settings.x + (settings.translateX || 0),
  53916. align = settings.align,
  53917. bBox = this.getBBox(),
  53918. style = this._style || {},
  53919. marginLeft = 0,
  53920. marginTop = 0,
  53921. fontHeightOffset,
  53922. alignMultiplier,
  53923. rotateObject,
  53924. textWidth,
  53925. textHeight;
  53926. if (this._oldRotate && !bBox.isEmpty) {
  53927. rad = this._oldRotate.angle * Math.PI / 180.0;
  53928. osin = Math.sin(rad);
  53929. ocos = Math.cos(rad);
  53930. if ((this._oldRotate.angle | 0) % 90 !== 0)
  53931. if ((this._oldRotate.angle | 0) % 45 === 0)
  53932. textWidth = bBox.width,
  53933. textHeight = bBox.height;
  53934. else {
  53935. otg = Math.abs(Math.tan(rad));
  53936. var b = (bBox.width - bBox.height * otg) / (1 - otg * otg);
  53937. var a = bBox.width - b;
  53938. textHeight = Math.abs(a / osin);
  53939. textWidth = Math.abs(b / ocos)
  53940. }
  53941. else {
  53942. textHeight = Math.abs(bBox.height * ocos - bBox.width * osin);
  53943. textWidth = Math.abs(bBox.width * ocos - bBox.height * osin)
  53944. }
  53945. }
  53946. else
  53947. textWidth = bBox.width,
  53948. textHeight = bBox.height;
  53949. this.__textWidth = textWidth;
  53950. this.__textHeight = textHeight;
  53951. if (textHeight || textWidth) {
  53952. rotateObject = parseRotateParameter(rotate, x, y);
  53953. this._oldRotate = rotateObject;
  53954. if (rotateObject) {
  53955. rotateAngle = rotateObject.angle;
  53956. rotateX = rotateObject.x;
  53957. rotateY = rotateObject.y;
  53958. if (Math.abs(rotateAngle) > 360)
  53959. rotateAngle = rotateAngle % 360;
  53960. if (rotateAngle < 0)
  53961. rotateAngle = rotateAngle + 360;
  53962. if (rotateAngle) {
  53963. rad = rotateAngle * Math.PI / 180.0;
  53964. cos = Math.cos(rad);
  53965. sin = Math.sin(rad);
  53966. style.filter = 'progid:DXImageTransform.Microsoft.Matrix(sizingMethod="auto expand", M11 = ' + cos.toFixed(5) + ', M12 = ' + (-sin).toFixed(5) + ', M21 = ' + sin.toFixed(5) + ', M22 = ' + cos.toFixed(5) + ')'
  53967. }
  53968. else {
  53969. style.filter = '';
  53970. this._oldRotate = null
  53971. }
  53972. marginLeft = (x - rotateX) * (cos - 1) - (y - rotateY) * sin;
  53973. marginTop = (x - rotateX) * sin + (y - rotateY) * (cos - 1)
  53974. }
  53975. fontHeightOffset = textHeight * (0.55 + 0.45 / 2);
  53976. if (rotateAngle < 90) {
  53977. marginTop -= fontHeightOffset * cos;
  53978. marginLeft -= (textHeight - fontHeightOffset) * sin
  53979. }
  53980. else if (rotateAngle < 180) {
  53981. marginTop += (textHeight - fontHeightOffset) * cos;
  53982. marginLeft += textWidth * cos - (textHeight - fontHeightOffset) * sin
  53983. }
  53984. else if (rotateAngle < 270) {
  53985. marginTop += (textHeight - fontHeightOffset) * cos + textWidth * sin;
  53986. marginLeft += textWidth * cos + fontHeightOffset * sin
  53987. }
  53988. else {
  53989. marginTop += textWidth * sin - fontHeightOffset * cos;
  53990. marginLeft += fontHeightOffset * sin
  53991. }
  53992. if (rotateAngle && this.renderer.rtl)
  53993. marginLeft -= textWidth - (textHeight * Math.abs(sin) + textWidth * Math.abs(cos));
  53994. alignMultiplier = {
  53995. center: 0.5,
  53996. right: 1
  53997. }[align];
  53998. if (alignMultiplier) {
  53999. marginLeft -= textWidth * alignMultiplier * cos;
  54000. marginTop -= textWidth * alignMultiplier * sin
  54001. }
  54002. style.marginLeft = Math.round(marginLeft) + 'px';
  54003. style.marginTop = Math.round(marginTop) + 'px'
  54004. }
  54005. if (settings.fill && settings.fill !== 'none')
  54006. style.color = settings.fill;
  54007. if (settings.opacity)
  54008. this.element.style.filter = 'alpha(opacity=' + settings.opacity * 100 + ')';
  54009. this.applyStyle(style)
  54010. }
  54011. });
  54012. var GroupVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  54013. isVml: function() {
  54014. return false
  54015. },
  54016. defaultSettings: function() {
  54017. return {
  54018. x: 0,
  54019. y: 0,
  54020. position: 'absolute'
  54021. }
  54022. },
  54023. ctor: function(renderer, params) {
  54024. this.callBase(renderer, 'div', params)
  54025. },
  54026. adjustSettings: function() {
  54027. if (this.settings.clipId || this._clipRect) {
  54028. var rect = this.renderer.getClipRect(this.settings.clipId, this);
  54029. if (this._clipRect)
  54030. if (rect)
  54031. this._clipRect.applySettings({
  54032. x: rect.x,
  54033. y: rect.y,
  54034. width: rect.width,
  54035. height: rect.height
  54036. });
  54037. else {
  54038. this._clipRect.remove();
  54039. this._clipRect = null
  54040. }
  54041. else
  54042. this._clipRect = this.renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
  54043. fill: "none",
  54044. opacity: 0.002,
  54045. "class": CLIP_RECT_CLASS
  54046. });
  54047. if (this._clipRect)
  54048. this.childElements.length && this._clipRect.append(this)
  54049. }
  54050. },
  54051. applySettings: function(settings) {
  54052. var rotate;
  54053. settings = settings || {};
  54054. rotate = settings.rotate;
  54055. if (rotate) {
  54056. if (utils.isNumber(rotate))
  54057. rotate = [rotate, settings.x || 0, settings.y || 0];
  54058. $.each(this.childElements, function(_, child) {
  54059. child.applySettings({rotate: rotate})
  54060. })
  54061. }
  54062. delete settings.rotate;
  54063. delete settings.x;
  54064. delete settings.y;
  54065. this.callBase(settings);
  54066. $.each(this.childElements || [], function(_, c) {
  54067. c.applySettings({})
  54068. });
  54069. return this
  54070. },
  54071. getBBox: function() {
  54072. return this._getBBox()
  54073. },
  54074. update: function() {
  54075. if (this.settings.clipId) {
  54076. var bbox = this.getBBox();
  54077. this.applyStyle({
  54078. left: bbox.x + (this.settings.translateX || 0),
  54079. right: bbox.y + (this.settings.translateY || 0),
  54080. width: bbox.width,
  54081. height: bbox.height
  54082. })
  54083. }
  54084. }
  54085. });
  54086. renderers.VmlRenderer = renderers.SvgRenderer.inherit({
  54087. ctor: function(options) {
  54088. options = options || {};
  54089. options.animation = {enabled: false};
  54090. if (doc.namespaces && !doc.namespaces.vml) {
  54091. doc.namespaces.add('vml', 'urn:schemas-microsoft-com:vml');
  54092. var cssText = 'vml\\:fill, vml\\:path, vml\\:shape, vml\\:stroke, vml\\:rect, vml\\:oval' + '{ behavior:url(#default#VML); display: inline-block; };';
  54093. try {
  54094. doc.createStyleSheet().cssText = cssText
  54095. }
  54096. catch(e) {
  54097. doc.styleSheets[0].cssText += cssText
  54098. }
  54099. }
  54100. this._clipRects = {};
  54101. this.cssClass = options.cssClass || '';
  54102. this.callBase(options)
  54103. },
  54104. dispose: function() {
  54105. this.callBase();
  54106. this._clipRects = null;
  54107. this._size = null
  54108. },
  54109. updateAnimationOptions: $.noop,
  54110. draw: function(container) {
  54111. var root = this.getRoot();
  54112. this.callBase(container);
  54113. if (root)
  54114. root.appendComplete()
  54115. },
  54116. recreateCanvas: function(width, height, cssClass) {
  54117. if (width >= 0 && height >= 0) {
  54118. this._size = {
  54119. width: width,
  54120. height: height
  54121. };
  54122. if (!this.svgRoot) {
  54123. this.cssClass = cssClass || this.cssClass;
  54124. this.svgRoot = new RootVmlElement(this, {
  54125. width: width,
  54126. height: height,
  54127. 'class': this.cssClass
  54128. })
  54129. }
  54130. else
  54131. this.svgRoot.applySettings({
  54132. width: width,
  54133. height: height
  54134. });
  54135. this.defsSvg && this.defsSvg.clear()
  54136. }
  54137. },
  54138. _getSize: function() {
  54139. return this._size || {}
  54140. },
  54141. isElementAppendedToPage: function(element) {
  54142. return $(element.element).closest(doc.documentElement).length
  54143. },
  54144. createRect: function(x, y, w, h, r, options) {
  54145. var params = $.extend(true, {}, options || {}, {
  54146. x: x,
  54147. y: y,
  54148. width: w,
  54149. height: h,
  54150. rx: r,
  54151. ry: r
  54152. });
  54153. return new RectVmlElement(this, params)
  54154. },
  54155. createSegmentRect: function(x, y, w, h, r, segments, options) {
  54156. var params = $.extend({}, options || {}, {
  54157. x: x,
  54158. y: y,
  54159. width: w,
  54160. height: h,
  54161. rx: r,
  54162. ry: r,
  54163. segments: segments
  54164. });
  54165. return new SegmentRectVmlElement(this, params)
  54166. },
  54167. createClipRect: function(x, y, width, height) {
  54168. var clipId = utils.getNextDefsSvgId(),
  54169. elements = [],
  54170. clipRect = {
  54171. id: clipId,
  54172. x: x,
  54173. y: y,
  54174. width: width,
  54175. height: height,
  54176. addElement: function(element) {
  54177. var hasElement = false;
  54178. $.each(elements, function() {
  54179. if (this === element) {
  54180. hasElement = true;
  54181. return false
  54182. }
  54183. });
  54184. if (!hasElement)
  54185. elements.push(element)
  54186. },
  54187. append: function() {
  54188. return this
  54189. },
  54190. remove: function(){},
  54191. dispose: function(){},
  54192. updateRectangle: function(settings) {
  54193. if ('x' in settings)
  54194. this.x = settings.x;
  54195. if ('translateX' in settings)
  54196. this.x += settings.translateX;
  54197. if ('y' in settings)
  54198. this.y = settings.y;
  54199. if ('translateY' in settings)
  54200. this.y += settings.translateY;
  54201. if ('width' in settings)
  54202. this.width = settings.width;
  54203. if ('height' in settings)
  54204. this.height = settings.height;
  54205. $.each(elements, function() {
  54206. this.applySettings({clipId: clipId})
  54207. });
  54208. return this
  54209. }
  54210. };
  54211. this._clipRects[clipId] = clipRect;
  54212. return clipRect
  54213. },
  54214. getClipRect: function(clipId, element) {
  54215. var clipRect = this._clipRects[clipId];
  54216. if (clipRect && element)
  54217. clipRect.addElement(element);
  54218. return this._clipRects[clipId]
  54219. },
  54220. createImage: function(x, y, w, h, href, options) {
  54221. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  54222. x: x,
  54223. y: y,
  54224. width: w,
  54225. height: h,
  54226. href: href
  54227. });
  54228. return new ImageVmlElement(this, params)
  54229. },
  54230. createLine: function(x1, y1, x2, y2, options) {
  54231. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: [x1, y1, x2, y2]});
  54232. return new PathVmlElement(this, params)
  54233. },
  54234. createPath: function(points, options) {
  54235. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  54236. return new PathVmlElement(this, params)
  54237. },
  54238. createSimplePath: function(options) {
  54239. return new SimplePathVmlElement(this, options)
  54240. },
  54241. createBezierPath: function(points, options) {
  54242. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  54243. return new BezierVmlElement(this, params)
  54244. },
  54245. createArea: function(points, options) {
  54246. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  54247. return new AreaVmlElement(this, params)
  54248. },
  54249. createBezierArea: function(points, options) {
  54250. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  54251. return new BezierAreaVmlElement(this, params)
  54252. },
  54253. createCircle: function(x, y, r, options) {
  54254. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  54255. cx: x,
  54256. cy: y,
  54257. r: r
  54258. });
  54259. return new CircleVmlElement(this, params)
  54260. },
  54261. createArc: function(x, y, outerRadius, innerRadius, startAngle, endAngle, options) {
  54262. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  54263. x: x,
  54264. y: y,
  54265. outerRadius: outerRadius,
  54266. innerRadius: innerRadius,
  54267. startAngle: startAngle,
  54268. endAngle: endAngle
  54269. });
  54270. return new ArcVmlElement(this, params)
  54271. },
  54272. createText: function(text, x, y, options) {
  54273. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  54274. x: x,
  54275. y: y,
  54276. text: text
  54277. });
  54278. return new TextVmlElement(this, params)
  54279. },
  54280. createGroup: function(options) {
  54281. return new GroupVmlElement(this, options)
  54282. },
  54283. createPattern: function(color, hatching) {
  54284. return {
  54285. id: color,
  54286. append: function() {
  54287. return this
  54288. },
  54289. clear: function(){},
  54290. dispose: function(){}
  54291. }
  54292. },
  54293. createFilter: function(type) {
  54294. if (type === 'shadow')
  54295. return {
  54296. ref: null,
  54297. append: function() {
  54298. return this
  54299. },
  54300. dispose: function() {
  54301. return this
  54302. },
  54303. applySettings: function() {
  54304. return this
  54305. }
  54306. };
  54307. return null
  54308. },
  54309. svg: function() {
  54310. return ''
  54311. }
  54312. });
  54313. function buildPath(points) {
  54314. var i = 0,
  54315. ii = points.length,
  54316. list = [];
  54317. for (; i < ii; )
  54318. list.push('l', points[i++].toFixed(0), points[i++].toFixed(0));
  54319. if (ii) {
  54320. list[0] = 'm';
  54321. list.push('x e');
  54322. list = list.join(' ')
  54323. }
  54324. else
  54325. list = '';
  54326. return list
  54327. }
  54328. function processCircleSettings(x, y, size) {
  54329. return {
  54330. cx: x,
  54331. cy: y,
  54332. r: size / 2
  54333. }
  54334. }
  54335. renderers._vmlBuildPath = buildPath;
  54336. renderers._vmlProcessCircleSettings = processCircleSettings;
  54337. renderers.__vmlRendererInternals = {
  54338. RootVmlElement: RootVmlElement,
  54339. RectVmlElement: RectVmlElement,
  54340. ImageVmlElement: ImageVmlElement,
  54341. PathVmlElement: PathVmlElement,
  54342. AreaVmlElement: AreaVmlElement,
  54343. BezierVmlElement: BezierVmlElement,
  54344. BezierAreaVmlElement: BezierAreaVmlElement,
  54345. SimplePathVmlElement: SimplePathVmlElement,
  54346. CircleVmlElement: CircleVmlElement,
  54347. TextVmlElement: TextVmlElement,
  54348. GroupVmlElement: GroupVmlElement,
  54349. ArcVmlElement: ArcVmlElement,
  54350. SegmentRectVmlElement: SegmentRectVmlElement
  54351. }
  54352. })(jQuery, DevExpress);
  54353. /*! Module viz-core, file renderer.js */
  54354. (function($, DX) {
  54355. var renderers = DX.viz.renderers,
  54356. browser = DX.browser;
  54357. function isSvg() {
  54358. return !(browser.msie && browser.version < 9) || !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect
  54359. }
  54360. if (!isSvg()) {
  54361. renderers.Renderer = renderers.VmlRenderer;
  54362. renderers.buildPath = renderers._vmlBuildPath;
  54363. renderers.processCircleSettings = renderers._vmlProcessCircleSettings
  54364. }
  54365. else {
  54366. renderers.Renderer = renderers.SvgRenderer;
  54367. renderers.buildPath = renderers._svgBuildPath;
  54368. renderers.processCircleSettings = renderers._svgProcessCircleSettings
  54369. }
  54370. renderers.isSvg = isSvg
  54371. })(jQuery, DevExpress);
  54372. /*! Module viz-core, file animation.js */
  54373. (function(DX) {
  54374. var renderers = DX.viz.renderers,
  54375. Class = DX.Class,
  54376. noop = function(){},
  54377. easingFunctions = {
  54378. easeOutCubic: function(pos, start, end) {
  54379. return pos === 1 ? end : (1 - Math.pow(1 - pos, 3)) * (end - start) + +start
  54380. },
  54381. linear: function(pos, start, end) {
  54382. return pos === 1 ? end : pos * (end - start) + +start
  54383. }
  54384. };
  54385. renderers.easingFunctions = easingFunctions;
  54386. renderers.animationSvgStep = {
  54387. points: function(elem, params, progress, easing, currentParams) {
  54388. var from = params.from,
  54389. to = params.to,
  54390. path = [],
  54391. i,
  54392. j,
  54393. seg,
  54394. d;
  54395. for (i = 0; i < from.length; i++) {
  54396. seg = [from[i][0]];
  54397. if (from[i].length > 1)
  54398. for (j = 1; j < from[i].length; j++)
  54399. seg.push(easing(progress, from[i][j], to[i][j]));
  54400. path[i] = seg.join(' ')
  54401. }
  54402. d = path.join(' ');
  54403. currentParams.d = params.end && progress === 1 ? params.end : d;
  54404. elem.element.setAttribute('d', d)
  54405. },
  54406. arc: function(elem, params, progress, easing) {
  54407. var from = params.from,
  54408. to = params.to,
  54409. current = {};
  54410. for (var i in from)
  54411. current[i] = easing(progress, from[i], to[i]);
  54412. elem.applySettings(current)
  54413. },
  54414. transform: function(elem, params, progress, easing, currentParams) {
  54415. var translate = params.translate,
  54416. rotate = params.rotate,
  54417. scale = params.scale,
  54418. transformations = [],
  54419. elemSettings = elem.settings;
  54420. if (translate) {
  54421. currentParams.translateX = easing(progress, translate.x.from, translate.x.to);
  54422. currentParams.translateY = easing(progress, translate.y.from, translate.y.to);
  54423. transformations.push('translate(' + currentParams.translateX + ',' + currentParams.translateY + ')')
  54424. }
  54425. else if (elemSettings.translateX || elemSettings.translateY)
  54426. transformations.push('translate(' + (elemSettings.translateX || 0) + ',' + (elemSettings.translateY || 0) + ')');
  54427. if (rotate) {
  54428. currentParams.rotate = {
  54429. angle: easing(progress, rotate.angle.from, rotate.angle.to),
  54430. x: rotate.x,
  54431. y: rotate.y
  54432. };
  54433. transformations.push('rotate(' + currentParams.rotate.angle + ',' + rotate.x + ',' + rotate.y + ')')
  54434. }
  54435. else if (elemSettings.rotate)
  54436. transformations.push('rotate(' + elemSettings.rotate.angle + ',' + (elemSettings.rotate.x || 0) + ',' + (elemSettings.rotate.y || 0) + ')');
  54437. if (scale) {
  54438. currentParams.scale = {
  54439. x: easing(progress, scale.x.from, scale.x.to),
  54440. y: easing(progress, scale.y.from, scale.y.to)
  54441. };
  54442. transformations.push('scale(' + currentParams.scale.x + ',' + currentParams.scale.y + ')')
  54443. }
  54444. else if (elemSettings.scale)
  54445. transformations.push('scale(' + elemSettings.scale.x + ',' + elemSettings.scale.y + ')');
  54446. elem.element.setAttribute('transform', transformations.join())
  54447. },
  54448. base: function(elem, params, progress, easing, currentParams, attributeName) {
  54449. currentParams[attributeName] = easing(progress, params.from, params.to);
  54450. elem.element.setAttribute(attributeName, currentParams[attributeName])
  54451. },
  54452. _: noop,
  54453. complete: function(element, currentSettings) {
  54454. element.applySettings(currentSettings)
  54455. }
  54456. };
  54457. var Animation = Class.inherit({
  54458. ctor: function(element, params, options) {
  54459. var that = this;
  54460. that._progress = 0;
  54461. that.element = element;
  54462. that.params = params;
  54463. that.options = options;
  54464. that.duration = options.partitionDuration ? options.duration * options.partitionDuration : options.duration;
  54465. that._animateStep = options.animateStep || renderers.animationSvgStep;
  54466. that._easing = easingFunctions[options.easing] || easingFunctions['easeOutCubic'];
  54467. that._currentParams = {};
  54468. that.tick = that._start
  54469. },
  54470. _calcProgress: function(now) {
  54471. return Math.min(1, (now - this._startTime) / this.duration)
  54472. },
  54473. _step: function(now) {
  54474. var that = this,
  54475. animateStep = that._animateStep,
  54476. attrName;
  54477. that._progress = that._calcProgress(now);
  54478. for (attrName in that.params) {
  54479. if (!that.params.hasOwnProperty(attrName))
  54480. continue;
  54481. var anim = animateStep[attrName] || animateStep.base;
  54482. anim(that.element, that.params[attrName], that._progress, that._easing, that._currentParams, attrName)
  54483. }
  54484. that.options.step && that.options.step(that._easing(that._progress, 0, 1), that._progress);
  54485. if (that._progress === 1)
  54486. return that.stop();
  54487. return true
  54488. },
  54489. _start: function(now) {
  54490. this._startTime = now;
  54491. this.tick = this._step;
  54492. return true
  54493. },
  54494. _end: function(disableComplete) {
  54495. var that = this;
  54496. that.stop = noop;
  54497. that.tick = noop;
  54498. that._animateStep.complete && that._animateStep.complete(that.element, that._currentParams);
  54499. that.options.complete && !disableComplete && that.options.complete()
  54500. },
  54501. tick: function(now) {
  54502. return true
  54503. },
  54504. stop: function(breakAnimation, disableComplete) {
  54505. var options = this.options;
  54506. if (!breakAnimation && options.repeatCount && --options.repeatCount > 0) {
  54507. this.tick = this._start;
  54508. return true
  54509. }
  54510. else
  54511. this._end(disableComplete)
  54512. }
  54513. });
  54514. renderers.AnimationController = Class.inherit(function() {
  54515. var FPS = 1000 / 60,
  54516. requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
  54517. setTimeout(callback, FPS)
  54518. };
  54519. return {
  54520. ctor: function() {
  54521. var that = this;
  54522. that.requestAnimationFrame = requestAnimationFrame;
  54523. that._animationCount = 0;
  54524. that._timerId = null;
  54525. that._animations = {}
  54526. },
  54527. _loop: function() {
  54528. var that = this,
  54529. animations = that._animations,
  54530. activeAnimation = 0,
  54531. now = (new Date).getTime(),
  54532. an;
  54533. for (an in animations) {
  54534. if (!animations.hasOwnProperty(an))
  54535. continue;
  54536. if (!animations[an].tick(now))
  54537. delete animations[an];
  54538. activeAnimation++
  54539. }
  54540. if (activeAnimation === 0) {
  54541. that.stop();
  54542. return
  54543. }
  54544. that._timerId = that.requestAnimationFrame.call(null, function() {
  54545. that._loop()
  54546. }, that.element)
  54547. },
  54548. addAnimation: function(animation) {
  54549. var that = this;
  54550. that._animations[that._animationCount++] = animation;
  54551. if (!that._timerId) {
  54552. clearTimeout(that._startDelay);
  54553. that._startDelay = setTimeout(function() {
  54554. that._timerId = 1;
  54555. that._loop()
  54556. }, 0)
  54557. }
  54558. },
  54559. animateElement: function(elem, params, options) {
  54560. if (elem && params && options) {
  54561. elem.animation && elem.animation.stop(true);
  54562. this.addAnimation(elem.animation = new Animation(elem, params, options))
  54563. }
  54564. },
  54565. dispose: function() {
  54566. this.stop();
  54567. this.element = null
  54568. },
  54569. stop: function() {
  54570. this._animations = {};
  54571. this._animationCount = 0;
  54572. clearTimeout(this._startDelay);
  54573. this._timerId = null
  54574. },
  54575. lock: function() {
  54576. var animations = this._animations;
  54577. for (var an in animations)
  54578. animations.hasOwnProperty(an) && animations[an].stop(true, true);
  54579. this.stop()
  54580. }
  54581. }
  54582. }());
  54583. renderers.Animation = Animation;
  54584. renderers.noop = noop
  54585. })(DevExpress);
  54586. /*! Module viz-core, file namespaces.js */
  54587. (function(DevExpress) {
  54588. DevExpress.viz.charts = {series: {}}
  54589. })(DevExpress);
  54590. /*! Module viz-core, file chartsConsts.js */
  54591. (function(DX) {
  54592. DX.viz.charts.consts = {
  54593. dataTypes: {
  54594. STRING: 'string',
  54595. NUMERIC: 'numeric',
  54596. DATETIME: 'datetime'
  54597. },
  54598. axisTypes: {
  54599. DISCRETE: 'discrete',
  54600. CONTINUOUS: 'continuous',
  54601. LOGARITHMIC: 'logarithmic'
  54602. }
  54603. }
  54604. })(DevExpress);
  54605. /*! Module viz-core, file dataValidator.js */
  54606. (function($, DX) {
  54607. var viz = DX.viz,
  54608. parseUtils = new viz.core.ParseUtils,
  54609. chartConst = viz.charts.consts,
  54610. dataTypes = chartConst.dataTypes,
  54611. axisTypes = chartConst.axisTypes,
  54612. utils = DX.utils,
  54613. _each = $.each,
  54614. _isDefined = utils.isDefined;
  54615. var mergeSort = function(data, field) {
  54616. function merge_sort(array, low, high, field) {
  54617. if (low < high) {
  54618. var mid = Math.floor((low + high) / 2);
  54619. merge_sort(array, low, mid, field);
  54620. merge_sort(array, mid + 1, high, field);
  54621. merge(array, low, mid, high, field)
  54622. }
  54623. }
  54624. var n = data.length;
  54625. merge_sort(data, 0, n - 1, field);
  54626. return data
  54627. };
  54628. var merge = function(array, low, mid, high, field) {
  54629. var newArray = new Array(high - low + 1),
  54630. countL = low,
  54631. countR = mid + 1,
  54632. k,
  54633. i = 0;
  54634. while (countL <= mid && countR <= high) {
  54635. if (array[countL][field] <= array[countR][field] || !_isDefined(array[countR][field])) {
  54636. newArray[i] = array[countL];
  54637. countL++
  54638. }
  54639. else {
  54640. newArray[i] = array[countR];
  54641. countR++
  54642. }
  54643. i++
  54644. }
  54645. if (countL > mid)
  54646. for (k = countR; k <= high; k++, i++)
  54647. newArray[i] = array[k];
  54648. else
  54649. for (k = countL; k <= mid; k++, i++)
  54650. newArray[i] = array[k];
  54651. for (k = 0; k <= high - low; k++)
  54652. array[k + low] = newArray[k];
  54653. return array
  54654. };
  54655. viz.charts.DataValidator = DX.Class.inherit({
  54656. ctor: function(data, groups, incidentOccured, dataPrepareOptions) {
  54657. var that = this;
  54658. groups = groups || [[]];
  54659. if (!data)
  54660. that._nullData = true;
  54661. that.groups = groups;
  54662. that.data = data || [];
  54663. that._parsers = {};
  54664. that._errorShowList = {};
  54665. that._skipFields = {};
  54666. that.options = dataPrepareOptions || {};
  54667. that.incidentOccured = incidentOccured;
  54668. that.userArgumentCategories = that.groups.length && that.groups[0].length && that.groups[0][0].getArgumentCategories();
  54669. if (!incidentOccured)
  54670. that.incidentOccured = $.noop
  54671. },
  54672. validate: function validate() {
  54673. var that = this;
  54674. that._data = that.data;
  54675. if (!utils.isArray(that.data) || that._nullData)
  54676. that._incorrectDataMessage();
  54677. that.groups.argumentType = null;
  54678. that.groups.argumentAxisType = null;
  54679. $.each(that.groups, function(_, group) {
  54680. group.valueType = null;
  54681. group.valueAxisType = null;
  54682. $.each(group, function(_, series) {
  54683. series.updateDataType({})
  54684. })
  54685. });
  54686. that._checkType();
  54687. that._checkAxisType();
  54688. if (that.options.convertToAxisDataType) {
  54689. that._createParser();
  54690. that._parse()
  54691. }
  54692. that._groupData();
  54693. that._sort();
  54694. $.each(that._skipFields, function(field, fieldValue) {
  54695. if (fieldValue === that._data.length)
  54696. that.incidentOccured("W2002", [field])
  54697. });
  54698. return that._data
  54699. },
  54700. _checkType: function _checkType() {
  54701. var that = this,
  54702. groupsWithUndefinedValueType = [],
  54703. groupsWithUndefinedArgumentType = [],
  54704. checkValueTypeOfGroup = function checkValueTypeOfGroup(group, cell) {
  54705. $.each(group, function(_, series) {
  54706. $.each(series.getValueFields(), function(_, field) {
  54707. group.valueType = that._getType(cell[field], group.valueType)
  54708. })
  54709. });
  54710. if (group.valueType)
  54711. return true
  54712. },
  54713. checkArgumentTypeOfGroup = function checkArgumentTypeOfGroup(group, cell) {
  54714. $.each(group, function(_, series) {
  54715. that.groups.argumentType = that._getType(cell[series.getArgumentField()], that.groups.argumentType)
  54716. });
  54717. if (that.groups.argumentType)
  54718. return true
  54719. };
  54720. $.each(that.groups, function(_, group) {
  54721. if (!group.length)
  54722. return null;
  54723. var options = group[0].getOptions(),
  54724. valueTypeGroup = options.valueType,
  54725. argumentTypeGroup = options.argumentType;
  54726. group.valueType = valueTypeGroup;
  54727. that.groups.argumentType = argumentTypeGroup;
  54728. valueTypeGroup ? null : groupsWithUndefinedValueType.push(group);
  54729. argumentTypeGroup ? null : groupsWithUndefinedArgumentType.push(group)
  54730. });
  54731. if (groupsWithUndefinedValueType.length || groupsWithUndefinedArgumentType.length)
  54732. $.each(that.data, function(_, cell) {
  54733. var define = true;
  54734. if (!utils.isObject(cell))
  54735. return;
  54736. $.each(groupsWithUndefinedValueType, function(index, group) {
  54737. define = define && checkValueTypeOfGroup(group, cell)
  54738. });
  54739. $.each(groupsWithUndefinedArgumentType, function(index, group) {
  54740. define = define && checkArgumentTypeOfGroup(group, cell)
  54741. });
  54742. if (!that.options.checkTypeForAllData && define)
  54743. return false
  54744. })
  54745. },
  54746. _checkAxisType: function _checkAxisType() {
  54747. var that = this;
  54748. $.each(that.groups, function(_, group) {
  54749. $.each(group, function(_, series) {
  54750. var optionsSeries = {},
  54751. existingSeriesOptions = series.getOptions();
  54752. optionsSeries.argumentAxisType = that._correctAxisType(that.groups.argumentType, existingSeriesOptions.argumentAxisType, !!that.userArgumentCategories.length);
  54753. optionsSeries.valueAxisType = that._correctAxisType(group.valueType, existingSeriesOptions.valueAxisType, !!series.getValueCategories().length);
  54754. that.groups.argumentAxisType = that.groups.argumentAxisType || optionsSeries.argumentAxisType;
  54755. group.valueAxisType = group.valueAxisType || optionsSeries.valueAxisType;
  54756. optionsSeries.argumentType = that.groups.argumentType;
  54757. optionsSeries.valueType = group.valueType;
  54758. series.updateDataType(optionsSeries)
  54759. })
  54760. })
  54761. },
  54762. _createParser: function _createParser() {
  54763. var that = this;
  54764. $.each(that.groups, function(index, group) {
  54765. $.each(group, function(_, series) {
  54766. that._parsers[series.getArgumentField()] = that._createParserUnit(that.groups.argumentType, that.groups.argumentAxisType === axisTypes.LOGARITHMIC ? that._filterForLogAxis : null);
  54767. $.each(series.getValueFields(), function(_, field) {
  54768. that._parsers[field] = that._createParserUnit(group.valueType, group.valueAxisType === axisTypes.LOGARITHMIC ? that._filterForLogAxis : null, series.getOptions().ignoreEmptyPoints)
  54769. });
  54770. if (series.getTagField())
  54771. that._parsers[series.getTagField()] = null
  54772. })
  54773. })
  54774. },
  54775. _parse: function _parse() {
  54776. var that = this,
  54777. parsedData = [];
  54778. $.each(that.data, function(_, cell) {
  54779. var parserObject = {};
  54780. if (!utils.isObject(cell)) {
  54781. cell && that._incorrectDataMessage();
  54782. return
  54783. }
  54784. $.each(that._parsers, function(field, parser) {
  54785. parserObject[field] = parser ? parser(cell[field], field) : cell[field];
  54786. parserObject['original' + field] = cell[field]
  54787. });
  54788. parsedData.push(parserObject)
  54789. });
  54790. this._data = parsedData
  54791. },
  54792. _groupMinSlices: function(argumentField, valueField, smallValuesGrouping) {
  54793. var that = this,
  54794. smallValuesGrouping = smallValuesGrouping || {},
  54795. mode = smallValuesGrouping.mode,
  54796. count = smallValuesGrouping.topCount,
  54797. threshold = smallValuesGrouping.threshold,
  54798. name = smallValuesGrouping.groupName || 'others',
  54799. others = {},
  54800. data = that._data.slice(),
  54801. index;
  54802. var groupingValues = function(index) {
  54803. if (!_isDefined(index) || index < 0)
  54804. return;
  54805. _each(data.slice(index), function(_, cell) {
  54806. if (!_isDefined(cell[valueField]))
  54807. return;
  54808. others[valueField] += cell[valueField];
  54809. cell[valueField] = undefined;
  54810. cell['original' + valueField] = undefined
  54811. })
  54812. };
  54813. if (!mode || mode === 'none')
  54814. return;
  54815. others[argumentField] = name + '';
  54816. others[valueField] = 0;
  54817. data.sort(function(a, b) {
  54818. if (_isDefined(b[valueField]) && _isDefined(a[valueField]))
  54819. return b[valueField] - a[valueField];
  54820. else if (!_isDefined(b[valueField]) && a[valueField])
  54821. return -1;
  54822. else if (!_isDefined(a[valueField]) && b[valueField])
  54823. return 1
  54824. });
  54825. if (mode === 'smallValueThreshold') {
  54826. _each(data, function(i, cell) {
  54827. if (_isDefined(index) || !_isDefined(cell[valueField]))
  54828. return;
  54829. if (threshold > cell[valueField])
  54830. index = i
  54831. });
  54832. groupingValues(index)
  54833. }
  54834. else if (mode === 'topN')
  54835. groupingValues(count);
  54836. others[valueField] && that._data.push(others)
  54837. },
  54838. _groupData: function() {
  54839. var that = this,
  54840. groups = that.groups,
  54841. isPie = groups.length && groups[0].length && (groups[0][0].type === 'pie' || groups[0][0].type === 'doughnut' || groups[0][0].type === 'donut'),
  54842. argumentField,
  54843. valueFields;
  54844. if (!isPie)
  54845. return;
  54846. _each(groups, function(_, group) {
  54847. _each(group, function(_, series) {
  54848. argumentField = series.getArgumentField();
  54849. valueFields = series.getValueFields();
  54850. if (groups.argumentAxisType === axisTypes.DISCRETE)
  54851. that._groupSameArguments(argumentField, valueFields);
  54852. that._groupMinSlices(argumentField, valueFields[0], series.getOptions().smallValuesGrouping)
  54853. })
  54854. })
  54855. },
  54856. _groupSameArguments: function(argumentField, valueFields) {
  54857. var that = this,
  54858. argument,
  54859. dataOfArguments = {},
  54860. parsedData = that._data;
  54861. _each(parsedData, function(i, cell) {
  54862. if (!_isDefined(cell[argumentField]) || !_isDefined(cell[valueFields[0]]))
  54863. return;
  54864. argument = cell[argumentField];
  54865. if (_isDefined(dataOfArguments[argument])) {
  54866. var data = parsedData[dataOfArguments[argument]];
  54867. _each(valueFields, function(_, field) {
  54868. data[field] += cell[field];
  54869. cell[field] = undefined;
  54870. cell['original' + field] = undefined
  54871. })
  54872. }
  54873. else
  54874. dataOfArguments[argument] = i
  54875. })
  54876. },
  54877. _getType: function _getType(unit, type) {
  54878. if (type === dataTypes.STRING || utils.isString(unit))
  54879. return dataTypes.STRING;
  54880. if (type === dataTypes.DATETIME || utils.isDate(unit))
  54881. return dataTypes.DATETIME;
  54882. if (utils.isNumber(unit))
  54883. return dataTypes.NUMERIC;
  54884. return type
  54885. },
  54886. _correctAxisType: function _correctAxisType(type, axisType, hasCategories) {
  54887. if (type === dataTypes.STRING && (axisType === axisTypes.CONTINUOUS || axisType === axisTypes.LOGARITHMIC))
  54888. this.incidentOccured("E2002");
  54889. if (axisType === axisTypes.LOGARITHMIC)
  54890. return axisTypes.LOGARITHMIC;
  54891. axisType = (hasCategories || axisType === axisTypes.DISCRETE || type === dataTypes.STRING) && axisTypes.DISCRETE;
  54892. return axisType || axisTypes.CONTINUOUS
  54893. },
  54894. _filterForLogAxis: function(val, field) {
  54895. if (val <= 0) {
  54896. this.incidentOccured("E2004", [field]);
  54897. return null
  54898. }
  54899. return val
  54900. },
  54901. _createParserUnit: function _createParserUnit(type, filter, ignoreEmptyPoints) {
  54902. var that = this,
  54903. parser = type ? parseUtils.getParser(type, undefined, true) : function(unit) {
  54904. return unit
  54905. };
  54906. return function(unit, field) {
  54907. var parseUnit = parser(unit);
  54908. if (filter)
  54909. parseUnit = filter.call(that, parseUnit, field);
  54910. parseUnit === null && ignoreEmptyPoints && (parseUnit = undefined);
  54911. if (parseUnit === undefined) {
  54912. that._addSkipFields(field);
  54913. that._validUnit(unit, field, type)
  54914. }
  54915. return parseUnit
  54916. }
  54917. },
  54918. _validUnit: function _validUnit(unit, field, type) {
  54919. if (!unit)
  54920. return;
  54921. if (!utils.isNumber(unit) && !utils.isDate(unit) && !utils.isString(unit)) {
  54922. this.incidentOccured("E2003", [field]);
  54923. return
  54924. }
  54925. this.incidentOccured("E2004", [field])
  54926. },
  54927. _sort: function _sort() {
  54928. var that = this,
  54929. groups = that.groups,
  54930. hash = {},
  54931. argumentField = groups.length && groups[0].length && groups[0][0].getArgumentField();
  54932. if (utils.isFunction(that.options.sortingMethod))
  54933. that._data.sort(that.options.sortingMethod);
  54934. else if (that.userArgumentCategories.length) {
  54935. $.each(that.userArgumentCategories, function(index, value) {
  54936. hash[value] = index
  54937. });
  54938. that._data.sort(function sortCat(a, b) {
  54939. a = a[argumentField];
  54940. b = b[argumentField];
  54941. return hash[a] - hash[b]
  54942. })
  54943. }
  54944. else if (that.options.sortingMethod === true && groups.argumentType !== dataTypes.STRING)
  54945. mergeSort(that._data, argumentField)
  54946. },
  54947. _addSkipFields: function _addSkipFields(field) {
  54948. this._skipFields[field] = (this._skipFields[field] || 0) + 1
  54949. },
  54950. _incorrectDataMessage: function() {
  54951. if (this._erorrDataSource !== true) {
  54952. this._erorrDataSource = true;
  54953. this.incidentOccured("E2001")
  54954. }
  54955. }
  54956. })
  54957. })(jQuery, DevExpress);
  54958. /*! Module viz-core, file themeManager.js */
  54959. (function($, DX, undefined) {
  54960. var viz = DX.viz,
  54961. Palette = viz.core.Palette,
  54962. utils = DX.utils;
  54963. var HOVER_COLOR_HIGHLIGHTING = 20,
  54964. HIGHLIGHTING_STEP = 50;
  54965. viz.charts.ThemeManager = viz.core.BaseThemeManager.inherit(function() {
  54966. var ctor = function(options, themeGroupName) {
  54967. var that = this;
  54968. options = options || {};
  54969. that._userOptions = options;
  54970. that._mergeAxisTitleOptions = [];
  54971. themeGroupName && (that._themeSection = themeGroupName);
  54972. that._IE8 = DX.browser.msie && DX.browser.version < 9;
  54973. that.setTheme(options.theme);
  54974. that.palette = new Palette(options.palette, {
  54975. stepHighlight: HIGHLIGHTING_STEP,
  54976. theme: that._themeName
  54977. })
  54978. };
  54979. var dispose = function() {
  54980. var that = this;
  54981. that.palette.dispose();
  54982. that.palette = that._userOptions = that._mergedSettings = null;
  54983. that.callBase()
  54984. };
  54985. var initDefaultSeriesTheme = function(that) {
  54986. var commonSeriesSettings = that._theme.commonSeriesSettings;
  54987. commonSeriesSettings.point = commonSeriesSettings.point || {};
  54988. commonSeriesSettings.label = commonSeriesSettings.label || {};
  54989. that._initializeFont(commonSeriesSettings.label.font)
  54990. };
  54991. var initAxisTheme = function(that) {
  54992. var axisTheme = that._theme.commonAxisSettings;
  54993. if (axisTheme) {
  54994. axisTheme.label = axisTheme.label || {};
  54995. axisTheme.grid = axisTheme.grid || {};
  54996. axisTheme.ticks = axisTheme.ticks || {};
  54997. axisTheme.line = axisTheme.line || {};
  54998. axisTheme.title = axisTheme.title || {};
  54999. axisTheme.label.font = axisTheme.label.font || {};
  55000. that._initializeFont(axisTheme.label.font);
  55001. axisTheme.title.font = axisTheme.title.font || {};
  55002. that._initializeFont(axisTheme.title.font)
  55003. }
  55004. };
  55005. var resetPalette = function() {
  55006. this.palette.reset()
  55007. };
  55008. var updatePalette = function(palette) {
  55009. this.palette = new Palette(palette || this._theme.defaultPalette, {
  55010. stepHighlight: HIGHLIGHTING_STEP,
  55011. theme: this.themeName
  55012. })
  55013. };
  55014. var processTitleOptions = function(options) {
  55015. return utils.isString(options) ? {text: options} : options
  55016. };
  55017. var processAxisOptions = function(axisOptions, name) {
  55018. if (!axisOptions)
  55019. return;
  55020. axisOptions = $.extend(true, {}, axisOptions);
  55021. axisOptions.title = processTitleOptions(axisOptions.title);
  55022. if (axisOptions.type === 'logarithmic' && axisOptions.logarithmBase <= 0 || axisOptions.logarithmBase && !$.isNumeric(axisOptions.logarithmBase)) {
  55023. axisOptions.logarithmBase = undefined;
  55024. axisOptions.logarithmBaseError = true
  55025. }
  55026. if (axisOptions.label) {
  55027. if (axisOptions.label.alignment)
  55028. axisOptions.label['userAlignment'] = true;
  55029. if (!axisOptions.label.overlappingBehavior) {
  55030. if (axisOptions.label.staggered)
  55031. axisOptions.label.overlappingBehavior = {
  55032. mode: 'stagger',
  55033. staggeringSpacing: axisOptions.label.staggeringSpacing
  55034. };
  55035. if (axisOptions.label.rotationAngle)
  55036. axisOptions.label.overlappingBehavior = {
  55037. mode: 'rotate',
  55038. rotationAngle: axisOptions.label.rotationAngle
  55039. }
  55040. }
  55041. if (utils.isString(axisOptions.label.overlappingBehavior))
  55042. axisOptions.label.overlappingBehavior = {mode: axisOptions.label.overlappingBehavior};
  55043. if (!axisOptions.label.overlappingBehavior || !axisOptions.label.overlappingBehavior.mode)
  55044. axisOptions.label.overlappingBehavior = axisOptions.label.overlappingBehavior || {}
  55045. }
  55046. return axisOptions
  55047. };
  55048. var applyParticularAxisOptions = function(name, userOptions, rotated) {
  55049. var theme = this._theme,
  55050. position = !(rotated ^ name === "valueAxis") ? "horizontalAxis" : "verticalAxis",
  55051. commonAxisSettings = processAxisOptions(this._userOptions["commonAxisSettings"], name);
  55052. return $.extend(true, {}, theme.commonAxisSettings, theme[position], theme[name], commonAxisSettings, processAxisOptions(userOptions, name))
  55053. };
  55054. var mergeOptions = function(name, userOptions) {
  55055. userOptions = userOptions || this._userOptions[name];
  55056. var theme = this._theme[name],
  55057. result = this._mergedSettings[name];
  55058. if (result)
  55059. return result;
  55060. if ($.isPlainObject(theme) && $.isPlainObject(userOptions))
  55061. result = $.extend(true, {}, theme, userOptions);
  55062. else
  55063. result = utils.isDefined(userOptions) ? userOptions : theme;
  55064. this._mergedSettings[name] = result;
  55065. return result
  55066. };
  55067. var applyParticularTheme = {
  55068. base: mergeOptions,
  55069. argumentAxis: applyParticularAxisOptions,
  55070. valueAxisRangeSelector: function() {
  55071. return mergeOptions.call(this, 'valueAxis')
  55072. },
  55073. valueAxis: applyParticularAxisOptions,
  55074. title: function(name) {
  55075. var userOptions = processTitleOptions(this._userOptions[name]);
  55076. return mergeOptions.call(this, name, userOptions)
  55077. },
  55078. series: function(name, userOptions, isPie) {
  55079. var theme = this._theme,
  55080. userCommonSettings = this._userOptions.commonSeriesSettings || {},
  55081. themeCommonSettings = theme.commonSeriesSettings,
  55082. type = ((userOptions.type || userCommonSettings.type || themeCommonSettings.type) + '').toLowerCase(),
  55083. settings,
  55084. palette = this.palette,
  55085. isBar = ~type.indexOf('bar'),
  55086. isBubble = ~type.indexOf('bubble'),
  55087. mainSeriesColor,
  55088. containerBackgroundColor = this.getOptions("containerBackgroundColor");
  55089. if (isBar || isBubble) {
  55090. userOptions = $.extend(true, {}, userCommonSettings, userCommonSettings[type], userOptions);
  55091. var seriesVisibility = userOptions.visible;
  55092. userCommonSettings = {type: {}};
  55093. $.extend(true, userOptions, userOptions.point);
  55094. userOptions.visible = seriesVisibility
  55095. }
  55096. settings = $.extend(true, {}, themeCommonSettings, themeCommonSettings[type], userCommonSettings, userCommonSettings[type], userOptions);
  55097. settings.type = type;
  55098. settings.containerBackgroundColor = containerBackgroundColor;
  55099. if (!isPie) {
  55100. settings.widgetType = 'chart';
  55101. mainSeriesColor = settings.color || palette.getNextColor()
  55102. }
  55103. else {
  55104. settings.widgetType = 'pieChart';
  55105. mainSeriesColor = function() {
  55106. return palette.getNextColor()
  55107. }
  55108. }
  55109. settings.mainSeriesColor = mainSeriesColor;
  55110. settings._IE8 = this._IE8;
  55111. return settings
  55112. },
  55113. pieSegment: function(name, seriesSettings, segmentSettings) {
  55114. var settings = $.extend(true, {}, seriesSettings, segmentSettings);
  55115. var mainColor = new DX.Color(settings.color || this.palette.getNextColor());
  55116. settings.color = mainColor.toHex();
  55117. settings.border.color = settings.border.color || mainColor.toHex();
  55118. settings.hoverStyle.color = settings.hoverStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
  55119. settings.hoverStyle.border.color = settings.hoverStyle.border.color || mainColor.toHex();
  55120. settings.selectionStyle.color = settings.selectionStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
  55121. settings.selectionStyle.border.color = settings.selectionStyle.border.color || mainColor.toHex();
  55122. return settings
  55123. },
  55124. animation: function(name) {
  55125. var userOptions = this._userOptions[name];
  55126. userOptions = $.isPlainObject(userOptions) ? userOptions : utils.isDefined(userOptions) ? {enabled: !!userOptions} : {};
  55127. return mergeOptions.call(this, name, userOptions)
  55128. }
  55129. };
  55130. return {
  55131. _themeSection: 'chart',
  55132. ctor: ctor,
  55133. dispose: dispose,
  55134. _initializeTheme: function() {
  55135. var that = this,
  55136. theme = this._theme;
  55137. theme.legend = theme.legend || {};
  55138. theme.legend.font = theme.legend.font || {};
  55139. that._initializeFont(theme.legend.font);
  55140. initDefaultSeriesTheme(that);
  55141. initAxisTheme(that);
  55142. theme.title = theme.title || {};
  55143. theme.title.font = theme.title.font || {};
  55144. that._initializeFont(theme.title.font);
  55145. theme.tooltip = theme.tooltip || {};
  55146. theme.tooltip.font = theme.tooltip.font || {};
  55147. that._initializeFont(theme.tooltip.font);
  55148. theme.loadingIndicator = theme.loadingIndicator || {};
  55149. theme.loadingIndicator.font = theme.loadingIndicator.font || {};
  55150. that._initializeFont(theme.loadingIndicator.font)
  55151. },
  55152. resetPalette: resetPalette,
  55153. getOptions: function(name) {
  55154. return (applyParticularTheme[name] || applyParticularTheme["base"]).apply(this, arguments)
  55155. },
  55156. setTheme: function(theme) {
  55157. var that = this;
  55158. that._mergedSettings = {};
  55159. that.callBase(theme);
  55160. that.getOptions('rtlEnabled') && $.extend(true, that._theme, that._theme._rtl)
  55161. },
  55162. resetOptions: function(name) {
  55163. this._mergedSettings[name] = null
  55164. },
  55165. update: function(options) {
  55166. this._userOptions = options
  55167. },
  55168. updatePalette: updatePalette
  55169. }
  55170. }())
  55171. })(jQuery, DevExpress);
  55172. /*! Module viz-core, file factory.js */
  55173. (function($, DX) {
  55174. var viz = DX.viz,
  55175. charts = viz.charts,
  55176. series = charts.series;
  55177. charts.factory = function() {
  55178. var createSeriesFamily = function(options) {
  55179. return new series.SeriesFamily(options)
  55180. };
  55181. var createAxis = function(renderer, options) {
  55182. return new charts.Axis(renderer, options)
  55183. };
  55184. var createThemeManager = function(options, groupName) {
  55185. return new charts.ThemeManager(options, groupName)
  55186. };
  55187. var createDataValidator = function(data, groups, incidentOccured, dataPrepareOptions) {
  55188. return new charts.DataValidator(data, groups, incidentOccured, dataPrepareOptions)
  55189. };
  55190. var createTracker = function(options) {
  55191. return new charts.Tracker(options)
  55192. };
  55193. var createTitle = function(renderer, canvas, options, group) {
  55194. return new charts.ChartTitle(renderer, canvas, options, group)
  55195. };
  55196. var createChartLayoutManager = function(options) {
  55197. return new charts.LayoutManager(options)
  55198. };
  55199. return {
  55200. createSeriesFamily: createSeriesFamily,
  55201. createAxis: createAxis,
  55202. createThemeManager: createThemeManager,
  55203. createDataValidator: createDataValidator,
  55204. createTracker: createTracker,
  55205. createChartLayoutManager: createChartLayoutManager,
  55206. createTitle: createTitle
  55207. }
  55208. }()
  55209. })(jQuery, DevExpress);
  55210. /*! Module viz-core, file baseWidget.js */
  55211. (function($, DX, undefined) {
  55212. var core = DX.viz.core,
  55213. utils = DX.utils;
  55214. DX.viz.core.BaseWidget = DX.DOMComponent.inherit({
  55215. NAMESPACE: DX.ui,
  55216. _init: function() {
  55217. this._setRedrawOnResize(this._getOptionRedrawOnResize());
  55218. this._incidentOccured = this._createIncidentOccured();
  55219. this._renderVisiblityChange()
  55220. },
  55221. _optionChanged: function(name, value, prevValue) {
  55222. var that = this;
  55223. switch (name) {
  55224. case'redrawOnResize':
  55225. that._setRedrawOnResize(that._getOptionRedrawOnResize());
  55226. break;
  55227. case'loadingIndicator':
  55228. that._updateLoadIndicator(that._getLoadIndicatorOption());
  55229. break;
  55230. default:
  55231. that._invalidate()
  55232. }
  55233. that.callBase(name, value, prevValue)
  55234. },
  55235. _getOptionRedrawOnResize: function() {
  55236. var redrawOnResize = this.option('redrawOnResize');
  55237. redrawOnResize = redrawOnResize !== undefined ? !!redrawOnResize : true;
  55238. return redrawOnResize
  55239. },
  55240. _getLoadIndicatorOption: function() {
  55241. return this.option('loadingIndicator')
  55242. },
  55243. _dispose: function() {
  55244. var that = this;
  55245. if (that._resizeHandlerCallback)
  55246. that._removeResizeCallbacks();
  55247. that._incidentOccured = null;
  55248. that.callBase()
  55249. },
  55250. _visibilityChanged: function(visible) {
  55251. if (visible)
  55252. this.render()
  55253. },
  55254. _setRedrawOnResize: function(redrawOnResize) {
  55255. var that = this;
  55256. if (redrawOnResize) {
  55257. if (!that._resizeHandlerCallback && utils.isFunction(that._resize)) {
  55258. that._resizeHandlerCallback = DX.utils.createResizeHandler(function() {
  55259. that._resize()
  55260. });
  55261. utils.windowResizeCallbacks.add(that._resizeHandlerCallback)
  55262. }
  55263. }
  55264. else
  55265. that._removeResizeCallbacks()
  55266. },
  55267. _removeResizeCallbacks: function() {
  55268. var that = this;
  55269. that._resizeHandlerCallback && that._resizeHandlerCallback.stop();
  55270. utils.windowResizeCallbacks.remove(that._resizeHandlerCallback);
  55271. delete that._resizeHandlerCallback
  55272. },
  55273. _showLoadIndicator: function(options, canvas) {
  55274. var that = this;
  55275. that._loadIndicator = this._loadIndicator || core.CoreFactory.createLoadIndicator(options, that._element());
  55276. that._loadIndicator.show(canvas.width, canvas.height);
  55277. that._initializing && that._loadIndicator.endLoading(undefined, true)
  55278. },
  55279. _updateLoadIndicator: function(options, width, height) {
  55280. this._loadIndicator && this._loadIndicator.applyOptions(options, width, height)
  55281. },
  55282. _endLoading: function(complete) {
  55283. if (this._loadIndicator)
  55284. this._loadIndicator.endLoading(complete);
  55285. else
  55286. complete && complete()
  55287. },
  55288. _reappendLoadIndicator: function() {
  55289. this._loadIndicator && this._loadIndicator.toForeground()
  55290. },
  55291. _disposeLoadIndicator: function() {
  55292. this._loadIndicator && this._loadIndicator.dispose();
  55293. this._loadIndicator = null
  55294. },
  55295. _setDefaultOptions: function() {
  55296. this.callBase();
  55297. this.option({incidentOccured: function(options) {
  55298. var message = "" + options.id + " - " + options.text,
  55299. majorVerision = options.version.split(".").slice(0, 2).join("_"),
  55300. url = "http://js.devexpress.com/error/" + majorVerision + "/" + options.id;
  55301. utils.logger.warn(message + "\n" + url)
  55302. }})
  55303. },
  55304. _createIncidentOccured: function() {
  55305. var that = this;
  55306. return function(errorOrWarningId, options) {
  55307. var isError = errorOrWarningId[0] === 'E',
  55308. type = isError ? "error" : "warning",
  55309. formattingArray = options ? options.slice(0) : [],
  55310. text,
  55311. incidentOccuredFunc = that.option('incidentOccured');
  55312. formattingArray.unshift(core.errorsWarnings[errorOrWarningId]);
  55313. text = utils.stringFormat.apply(null, formattingArray);
  55314. if (utils.isFunction(incidentOccuredFunc))
  55315. setTimeout(function() {
  55316. incidentOccuredFunc({
  55317. id: errorOrWarningId,
  55318. type: type,
  55319. args: options,
  55320. text: text,
  55321. widget: that.NAME,
  55322. version: DevExpress.VERSION
  55323. })
  55324. })
  55325. }
  55326. },
  55327. _normalizeHtml: function(html) {
  55328. var re = /xmlns="[\s\S]*?"/gi,
  55329. first = true;
  55330. html = html.replace(re, function(match) {
  55331. if (!first)
  55332. return "";
  55333. first = false;
  55334. return match
  55335. });
  55336. return html.replace(/xmlns:NS1="[\s\S]*?"/gi, "").replace(/NS1:xmlns:xlink="([\s\S]*?)"/gi, 'xmlns:xlink="$1"')
  55337. },
  55338. _drawn: function() {
  55339. var that = this,
  55340. drawnCallback = that.option('drawn');
  55341. utils.isFunction(drawnCallback) && setTimeout(function() {
  55342. drawnCallback(that)
  55343. })
  55344. },
  55345. showLoadingIndicator: function() {
  55346. this._showLoadIndicator(this.option('loadingIndicator'), this.canvas || {})
  55347. },
  55348. hideLoadingIndicator: function() {
  55349. this._loadIndicator && this._loadIndicator.hide()
  55350. },
  55351. endUpdate: function() {
  55352. if (this._updateLockCount === 1 && !this._requireRefresh)
  55353. this.hideLoadingIndicator();
  55354. this.callBase()
  55355. },
  55356. svg: function() {
  55357. var renderer = this.renderer || this._renderer;
  55358. return renderer ? this._normalizeHtml(renderer.svg()) : ''
  55359. }
  55360. })
  55361. })(jQuery, DevExpress);
  55362. /*! Module viz-core, file CoreFactory.js */
  55363. (function(DX, undefined) {
  55364. var renderers = DX.viz.renderers,
  55365. core = DX.viz.core;
  55366. DX.viz.core.CoreFactory = function() {
  55367. return {
  55368. createSeries: function(renderer, options) {
  55369. return new core.series.Series(renderer, options)
  55370. },
  55371. createPoint: function(data, options) {
  55372. return new core.series.points.Point(data, options)
  55373. },
  55374. createLabel: function(type, data, options) {
  55375. if (type === "pie" || type === "doughnut" || type === "donut")
  55376. return new core.series.points.PieLabel(data, options);
  55377. else
  55378. return new core.series.points.Label(data, options)
  55379. },
  55380. createRenderer: function(options) {
  55381. return new renderers.Renderer(options)
  55382. },
  55383. createTranslator1D: function(fromValue, toValue, fromAngle, toAngle) {
  55384. return (new core.Translator1D).setDomain(fromValue, toValue).setCodomain(fromAngle, toAngle)
  55385. },
  55386. createTranslator2D: function(range, canvas, options) {
  55387. return new core.Translator2D(range, canvas, options)
  55388. },
  55389. getTickProvider: function() {
  55390. return core.tickProvider
  55391. },
  55392. createTooltip: function(options, group, renderer) {
  55393. return new core.Tooltip(options, group, renderer)
  55394. },
  55395. createLoadIndicator: function(options, group) {
  55396. return new core.LoadIndicator(options, group)
  55397. },
  55398. createLegend: function(data, options, renderer, group) {
  55399. return new core.Legend(data, options, renderer, group)
  55400. },
  55401. createSeriesFamily: function(options) {
  55402. return new core.series.helpers.SeriesFamily(options)
  55403. }
  55404. }
  55405. }()
  55406. })(DevExpress);
  55407. DevExpress.MOD_VIZ_CORE = true
  55408. }
  55409. if (!DevExpress.MOD_VIZ_CHARTS) {
  55410. if (!DevExpress.MOD_VIZ_CORE)
  55411. throw Error('Required module is not referenced: viz-core');
  55412. /*! Module viz-charts, file chartTitle.js */
  55413. (function($, DX, undefined) {
  55414. var isDefined = DX.utils.isDefined,
  55415. endsWith = function(value, pattern) {
  55416. return value.substr(value.length - pattern.length) === pattern
  55417. },
  55418. startsWith = function(value, pattern) {
  55419. return value.indexOf(pattern) === 0
  55420. },
  55421. decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
  55422. DEFAULT_MARGIN = 10;
  55423. DX.viz.charts.ChartTitle = DX.Class.inherit({
  55424. ctor: function(renderer, options, width, group) {
  55425. var that = this;
  55426. that._init(options, width);
  55427. that.renderer = renderer;
  55428. that.titleGroup = group
  55429. },
  55430. dispose: function() {
  55431. var that = this;
  55432. that.renderer = null;
  55433. that.clipRect = null;
  55434. that.title = null;
  55435. that.innerTitleGroup = null;
  55436. that.titleGroup = null;
  55437. that.options = null
  55438. },
  55439. update: function(options, width) {
  55440. this._init(options, width)
  55441. },
  55442. _init: function(options, width) {
  55443. var that = this;
  55444. if (options) {
  55445. that._parseAlignments(options);
  55446. that.horizontalAlignment = options.horizontalAlignment;
  55447. that.verticalAlignment = options.verticalAlignment;
  55448. that._parseMargins(options);
  55449. that.margin = options.margin;
  55450. that.options = options
  55451. }
  55452. that.setSize({width: width})
  55453. },
  55454. _parseMargins: function(options) {
  55455. options.margin = isDefined(options.margin) ? options.margin : {};
  55456. if (typeof options.margin === 'number') {
  55457. options.margin = options.margin >= 0 ? options.margin : DEFAULT_MARGIN;
  55458. options.margin = {
  55459. top: options.margin,
  55460. bottom: options.margin,
  55461. left: options.margin,
  55462. right: options.margin
  55463. }
  55464. }
  55465. else {
  55466. options.margin.top = options.margin.top >= 0 ? options.margin.top : DEFAULT_MARGIN;
  55467. options.margin.bottom = options.margin.bottom >= 0 ? options.margin.bottom : DEFAULT_MARGIN;
  55468. options.margin.left = options.margin.left >= 0 ? options.margin.left : DEFAULT_MARGIN;
  55469. options.margin.right = options.margin.right >= 0 ? options.margin.right : DEFAULT_MARGIN
  55470. }
  55471. },
  55472. _parseAlignments: function(options) {
  55473. if (isDefined(options.position) && !(isDefined(options.verticalAlignment) && isDefined(options.horizontalAlignment))) {
  55474. options.position = options.position.toLowerCase();
  55475. options.verticalAlignment = endsWith(options.position, 'top') ? 'top' : 'bottom';
  55476. options.horizontalAlignment = startsWith(options.position, 'left') ? 'left' : startsWith(options.position, 'center') && 'center' || 'right';
  55477. return
  55478. }
  55479. options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();
  55480. options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();
  55481. if (options.verticalAlignment !== 'top' && options.verticalAlignment !== 'bottom')
  55482. options.verticalAlignment = 'top';
  55483. if (options.horizontalAlignment !== 'left' && options.horizontalAlignment !== 'center' && options.horizontalAlignment !== 'right')
  55484. options.horizontalAlignment = 'center'
  55485. },
  55486. _setBoundingRect: function() {
  55487. var that = this,
  55488. options = that.options,
  55489. margin = that.changedMargin || that.margin,
  55490. box;
  55491. if (!that.innerTitleGroup)
  55492. return;
  55493. box = that.innerTitleGroup.getBBox();
  55494. box.height += margin.top + margin.bottom;
  55495. box.width += margin.left + margin.right;
  55496. box.x -= margin.left;
  55497. box.y -= margin.top;
  55498. if (isDefined(options.placeholderSize))
  55499. box.height = options.placeholderSize;
  55500. that.boundingRect = box
  55501. },
  55502. draw: function() {
  55503. var that = this,
  55504. titleOptions = that.options,
  55505. renderer = that.renderer,
  55506. attr;
  55507. if (!titleOptions.text)
  55508. return;
  55509. that.changedMargin = null;
  55510. if (!that.innerTitleGroup) {
  55511. that.innerTitleGroup = renderer.createGroup();
  55512. that.clipRect = that.createClipRect();
  55513. that.titleGroup && that.clipRect && that.titleGroup.applySettings({clipId: that.clipRect.id})
  55514. }
  55515. else
  55516. that.innerTitleGroup.clear();
  55517. that.innerTitleGroup.append(that.titleGroup);
  55518. attr = {
  55519. font: titleOptions.font,
  55520. align: that.horizontalAlignment,
  55521. style: titleOptions.fontStyle
  55522. };
  55523. that.title = renderer.createText(titleOptions.text, 0, 0, attr).append(that.innerTitleGroup);
  55524. that.title.text = titleOptions.text;
  55525. that._correctTitleLength();
  55526. that._setClipRectSettings()
  55527. },
  55528. _correctTitleLength: function() {
  55529. var that = this,
  55530. text = that.title.text,
  55531. updateText,
  55532. lineLength,
  55533. box;
  55534. that.title.updateText(text);
  55535. that._setBoundingRect();
  55536. box = that.getLayoutOptions();
  55537. if (that._width > box.width || text.indexOf("<br/>") !== -1)
  55538. return;
  55539. lineLength = text.length * that._width / box.width;
  55540. updateText = text.substr(0, ~~lineLength - 1 - 3) + "...";
  55541. that.title.updateText(updateText);
  55542. that._setBoundingRect()
  55543. },
  55544. changeSize: function(size) {
  55545. var that = this,
  55546. margin = $.extend(true, {}, that.margin);
  55547. if (margin.top + margin.bottom < size.height) {
  55548. if (this.innerTitleGroup) {
  55549. that.options._incidentOccured("W2103");
  55550. this.innerTitleGroup.remove();
  55551. this.innerTitleGroup = null
  55552. }
  55553. if (that.clipRect) {
  55554. that.clipRect.remove();
  55555. that.clipRect = null
  55556. }
  55557. }
  55558. else if (size.height > 0) {
  55559. decreaseGaps(margin, ["top", "bottom"], size.height);
  55560. size.height && (that.changedMargin = margin)
  55561. }
  55562. that._correctTitleLength();
  55563. that._setBoundingRect();
  55564. that._setClipRectSettings()
  55565. },
  55566. getLayoutOptions: function() {
  55567. var options = this.options,
  55568. boundingRect = this.innerTitleGroup ? this.boundingRect : {
  55569. width: 0,
  55570. height: 0,
  55571. x: 0,
  55572. y: 0
  55573. };
  55574. boundingRect.verticalAlignment = options.verticalAlignment;
  55575. boundingRect.horizontalAlignment = options.horizontalAlignment;
  55576. boundingRect.cutLayoutSide = options.verticalAlignment;
  55577. return boundingRect
  55578. },
  55579. setSize: function(size) {
  55580. this._width = size.width || this._width
  55581. },
  55582. shift: function(x, y) {
  55583. var that = this,
  55584. box = that.getLayoutOptions();
  55585. x -= box.x;
  55586. y -= box.y;
  55587. that.innerTitleGroup && that.innerTitleGroup.move(x, y);
  55588. that.clipRect && that.clipRect.updateRectangle({
  55589. translateX: x,
  55590. translateY: y
  55591. })
  55592. },
  55593. createClipRect: function() {
  55594. if (isDefined(this.options.placeholderSize))
  55595. return this.renderer.createClipRect(0, 0, 0, 0)
  55596. },
  55597. _setClipRectSettings: function() {
  55598. var bbox = this.getLayoutOptions(),
  55599. clipRect = this.clipRect;
  55600. if (clipRect) {
  55601. clipRect.append();
  55602. clipRect.updateRectangle({
  55603. x: bbox.x,
  55604. y: bbox.y,
  55605. width: bbox.width,
  55606. height: bbox.height
  55607. })
  55608. }
  55609. }
  55610. });
  55611. DX.viz.charts.ChartTitle.__DEFAULT_MARGIN = DEFAULT_MARGIN
  55612. })(jQuery, DevExpress);
  55613. /*! Module viz-charts, file axis.js */
  55614. (function($, DX, undefined) {
  55615. var utils = DX.utils,
  55616. isDefinedUtils = utils.isDefined,
  55617. isDateUtils = utils.isDate,
  55618. mathAbs = Math.abs,
  55619. core = DX.viz.core,
  55620. AXIS_VALUE_MARGIN_PRIORITY = 100,
  55621. DEFAULT_AXIS_LABEL_SPACING = 5,
  55622. AXIS_STAGGER_OVERLAPPING_KOEF = 2,
  55623. MAX_GRID_BORDER_ADHENSION = 4,
  55624. CANVAS_POSITION_PREFIX = 'canvas_position_',
  55625. CANVAS_POSITION_START = 'canvas_position_start',
  55626. CANVAS_POSITION_END = 'canvas_position_end',
  55627. TOP = 'top',
  55628. BOTTOM = 'bottom',
  55629. LEFT = 'left',
  55630. RIGHT = 'right',
  55631. CENTER = 'center';
  55632. DX.viz.charts.AXIS_STAGGER_OVERLAPPING_KOEF = AXIS_STAGGER_OVERLAPPING_KOEF;
  55633. var processCustomOptions = function(options) {
  55634. var label = options.label,
  55635. position = options.position;
  55636. if (options.isHorizontal) {
  55637. if (!(position === BOTTOM || position === TOP))
  55638. position = BOTTOM
  55639. }
  55640. else if (!(position === LEFT || position === RIGHT))
  55641. position = LEFT;
  55642. options.position = position;
  55643. if (position === RIGHT && !label.userAlignment)
  55644. label.alignment = LEFT
  55645. };
  55646. var formatLabel = function(value, options, axisMinMax) {
  55647. var formatObject = {
  55648. value: value,
  55649. valueText: DX.formatHelper.format(value, options.format, options.precision) || ''
  55650. };
  55651. if (axisMinMax) {
  55652. formatObject.min = axisMinMax.min;
  55653. formatObject.max = axisMinMax.max
  55654. }
  55655. return options.customizeText ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText
  55656. };
  55657. var nextState = function(state) {
  55658. switch (state) {
  55659. case'overlap':
  55660. return 'stagger';
  55661. case'stagger':
  55662. return 'rotate';
  55663. case'rotate':
  55664. default:
  55665. return 'end'
  55666. }
  55667. };
  55668. DX.viz.charts.Axis = function(renderer, options) {
  55669. var debug = DX.utils.debug;
  55670. debug.assertParam(renderer, 'renderer was not passed');
  55671. debug.assertParam(options.label, 'label was not passed');
  55672. debug.assertParam(options.tick, 'tick was not passed');
  55673. debug.assertParam(options.grid, 'grid was not passed');
  55674. debug.assertParam(options.title, 'title was not passed');
  55675. debug.assert(options.axisDivisionFactor, 'axisDivisionFactor was not passed');
  55676. debug.assert(options.stripStyle, 'stripStyle was not passed');
  55677. debug.assert(options.constantLineStyle, 'constantLineStyle was not passed');
  55678. debug.assert(options.position, 'position was not passed');
  55679. debug.assertParam(options.isHorizontal, 'isHorizontal was not passed');
  55680. this.renderer = renderer;
  55681. this._init(options)
  55682. };
  55683. $.extend(DX.viz.charts.Axis.prototype, {
  55684. dispose: function() {
  55685. var that = this;
  55686. that._axisElementsGroup && that._axisElementsGroup.dispose();
  55687. $.each(that.labels || [], function(_, label) {
  55688. label.removeData()
  55689. });
  55690. that.labels = null;
  55691. that.title = null;
  55692. that.stripLabels = null;
  55693. that.stripRects = null;
  55694. that.constantLineLabels = null;
  55695. that.constantLines = null;
  55696. that._axisStripGroup = null;
  55697. that._axisConstantLineGroup = null;
  55698. that._axisLableGroup = null;
  55699. that._axisLineGroup = null;
  55700. that._axisElementsGroup = null;
  55701. that._axisGridGroup = null;
  55702. that._axisGroup = null;
  55703. that.axesContainerGroup = null;
  55704. that.stripsGroup = null;
  55705. that.constantLinesGroup = null;
  55706. that._axisTitleGroup = null;
  55707. that.renderer = null;
  55708. that.translator = null;
  55709. that.orthogonalTranslator = null;
  55710. that.options = null;
  55711. that.textOptions = null;
  55712. that._tickValues = null;
  55713. that._fullTickValues = null;
  55714. that._fullTickPositions = null
  55715. },
  55716. _init: function(options) {
  55717. var that = this,
  55718. categories = options.categories,
  55719. labelOptions = options.label;
  55720. options.hoverMode = options.hoverMode ? options.hoverMode.toLowerCase() : 'none';
  55721. that.hasLabelFormat = labelOptions.format !== '' && isDefinedUtils(labelOptions.format);
  55722. that.options = options;
  55723. that.staggered = labelOptions.staggered;
  55724. labelOptions.minSpacing = isDefinedUtils(labelOptions.minSpacing) ? labelOptions.minSpacing : DEFAULT_AXIS_LABEL_SPACING;
  55725. processCustomOptions(options);
  55726. if (categories) {
  55727. that.labelsNumber = categories.length;
  55728. that.ticksNumber = that.labelsNumber
  55729. }
  55730. options.range = {
  55731. min: options.min,
  55732. max: options.max,
  55733. categories: options.categories && options.categories.slice(0)
  55734. };
  55735. that.pane = options.pane;
  55736. that.textOptions = {
  55737. align: labelOptions.alignment,
  55738. font: labelOptions.font,
  55739. opacity: labelOptions.opacity,
  55740. style: labelOptions.style
  55741. };
  55742. if (options.type === 'logarithmic') {
  55743. if (options.logarithmBaseError) {
  55744. options.incidentOccured('E2104');
  55745. delete options.logarithmBaseError
  55746. }
  55747. that.calcInterval = function(value, prevValue) {
  55748. return utils.getLog(value / prevValue, options.logarithmBase)
  55749. }
  55750. }
  55751. },
  55752. updateSize: function(clearAxis) {
  55753. var that = this,
  55754. options = that.options,
  55755. direction = options.isHorizontal ? "horizontal" : "vertical";
  55756. if (that.title && that._axisTitleGroup) {
  55757. options.incidentOccured('W2105', [direction]);
  55758. that._axisTitleGroup.remove();
  55759. that._axisTitleGroup = null
  55760. }
  55761. if (clearAxis && that._axisElementsGroup && that.labels) {
  55762. options.incidentOccured('W2106', [direction]);
  55763. that._axisElementsGroup.remove();
  55764. that._axisElementsGroup = null
  55765. }
  55766. that._setBoundingRect()
  55767. },
  55768. _updateTranslatorInterval: function() {
  55769. var that = this,
  55770. i,
  55771. tickValues,
  55772. businessRange = that.translator.getBusinessRange();
  55773. if (businessRange && businessRange.addRange && !that.options.categories) {
  55774. tickValues = that.getTickValues();
  55775. for (i = 0; i < tickValues.length - 1; i++)
  55776. businessRange.addRange({interval: mathAbs(tickValues[i] - tickValues[i + 1])})
  55777. }
  55778. },
  55779. setTranslator: function(translator, orthogonalTranslator) {
  55780. var that = this;
  55781. var debug = DX.utils.debug;
  55782. debug.assertParam(translator, 'translator was not passed');
  55783. that.translator = translator;
  55784. orthogonalTranslator && (that.orthogonalTranslator = orthogonalTranslator);
  55785. that.resetTicks();
  55786. that._updateTranslatorInterval()
  55787. },
  55788. resetTicks: function() {
  55789. var that = this;
  55790. that._tickValues = that._tickPositions = that._fullTickValues = that._fullTickPositions = null
  55791. },
  55792. setRange: function(range) {
  55793. var debug = DX.utils.debug;
  55794. debug.assertParam(range, 'range was not passed');
  55795. var options = this.options;
  55796. options.min = range.minVisible;
  55797. options.max = range.maxVisible;
  55798. options.categories = range.categories;
  55799. options.stubData = range.stubData;
  55800. this.resetTicks()
  55801. },
  55802. _drawAxis: function() {
  55803. var that = this,
  55804. translator = that.translator,
  55805. options = that.options,
  55806. hasCategories = !!options.categories,
  55807. axisPosition = that.axisPosition,
  55808. p11,
  55809. p12,
  55810. p21,
  55811. p22;
  55812. if (!options.visible)
  55813. return;
  55814. p11 = translator.translateSpecialCase(CANVAS_POSITION_START);
  55815. p21 = translator.translateSpecialCase(CANVAS_POSITION_END);
  55816. if (options.isHorizontal)
  55817. p12 = p22 = axisPosition;
  55818. else {
  55819. p12 = p11;
  55820. p22 = p21;
  55821. p11 = p21 = axisPosition
  55822. }
  55823. that.renderer.createLine(p11, p12, p21, p22, {
  55824. strokeWidth: options.width,
  55825. stroke: options.color,
  55826. strokeOpacity: options.opacity
  55827. }).append(that._axisLineGroup)
  55828. },
  55829. _getOptimalRotationAngle: function(tick1, tick2, labelOptions) {
  55830. var that = this,
  55831. translator = that.options.isHorizontal ? that.translator : that.orthogonalTranslator,
  55832. renderer = that.renderer,
  55833. outOfScreen = core.outOfScreen,
  55834. textOptions = that.textOptions,
  55835. svgElement1 = renderer.createText(formatLabel(tick1, labelOptions), outOfScreen.x + translator.translate(tick1), outOfScreen.y, textOptions).append(),
  55836. svgElement2 = renderer.createText(formatLabel(tick2, labelOptions), outOfScreen.x + translator.translate(tick2), outOfScreen.y, textOptions).append(),
  55837. bBox1 = svgElement1.getBBox(),
  55838. bBox2 = svgElement2.getBBox(),
  55839. angle = Math.asin((bBox1.height + labelOptions.minSpacing) / (bBox2.x - bBox1.x)) * 180 / Math.PI;
  55840. svgElement1.remove();
  55841. svgElement2.remove();
  55842. return isNaN(angle) ? 90 : Math.ceil(angle)
  55843. },
  55844. _applyOptimalOverlappingBehavior: function(ticks, ticksOptions) {
  55845. var that = this,
  55846. overlappingBehavior = that.overlappingBehavior,
  55847. isOverlapped = false,
  55848. rotationAngle = null,
  55849. mode = null,
  55850. options = $.extend({}, ticksOptions),
  55851. state = 'overlap';
  55852. while (state !== 'end') {
  55853. isOverlapped = rotationAngle && rotationAngle !== 90 ? false : that.options.tickProvider.isOverlappedTicks(ticks, options);
  55854. state = nextState(isOverlapped ? state : null);
  55855. that.testAutoOverlappingState = state;
  55856. switch (state) {
  55857. case'stagger':
  55858. options.screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
  55859. mode = state;
  55860. break;
  55861. case'rotate':
  55862. rotationAngle = that._getOptimalRotationAngle(ticks[0], ticks[1], that.options.label);
  55863. that.testAutoOverlappingRotationAngle = rotationAngle;
  55864. options.screenDelta = ticksOptions.screenDelta;
  55865. options.textOptions.rotate = rotationAngle;
  55866. mode = state;
  55867. break
  55868. }
  55869. }
  55870. that.testAutoOverlappingOptions = options;
  55871. overlappingBehavior.isOverlapped = isOverlapped;
  55872. overlappingBehavior.mode = mode;
  55873. overlappingBehavior.rotationAngle = rotationAngle
  55874. },
  55875. _getTicksOptions: function() {
  55876. var that = this,
  55877. options = that.options,
  55878. translator = that.translator,
  55879. screenDelta = mathAbs(translator.translateSpecialCase(CANVAS_POSITION_START) - translator.translateSpecialCase(CANVAS_POSITION_END)),
  55880. min = options.min,
  55881. max = options.max,
  55882. digitPosition = utils.getSignificantDigitPosition(mathAbs(max - min) / screenDelta),
  55883. correctingValue,
  55884. getText = function() {
  55885. return ''
  55886. };
  55887. if (utils.isNumber(min) && options.type !== 'logarithmic') {
  55888. min = utils.roundValue(options.min, digitPosition);
  55889. if (min < options.min) {
  55890. correctingValue = Math.pow(10, -digitPosition);
  55891. min = utils.applyPrecisionByMinDelta(min, correctingValue, min + correctingValue)
  55892. }
  55893. if (min > max)
  55894. min = options.min
  55895. }
  55896. if (!options.stubData)
  55897. getText = function(value) {
  55898. return formatLabel(value, options.label, {
  55899. min: min,
  55900. max: max
  55901. })
  55902. };
  55903. return {
  55904. min: min,
  55905. max: max,
  55906. base: options.type === 'logarithmic' ? options.logarithmBase : undefined,
  55907. axisType: options.type,
  55908. dataType: options.dataType,
  55909. customTicks: $.isArray(options.categories) ? options.categories : that._tickValues,
  55910. useTicksAutoArrangement: false,
  55911. textOptions: that.textOptions,
  55912. getText: getText,
  55913. renderer: that.renderer,
  55914. textSpacing: options.label.minSpacing,
  55915. translator: translator,
  55916. tickInterval: options.stubData ? null : options.tickInterval,
  55917. screenDelta: screenDelta,
  55918. gridSpacingFactor: options.axisDivisionFactor,
  55919. isHorizontal: options.isHorizontal,
  55920. setTicksAtUnitBeginning: options.setTicksAtUnitBeginning,
  55921. incidentOccured: options.incidentOccured
  55922. }
  55923. },
  55924. getTickValues: function() {
  55925. var that = this,
  55926. correctedScreenDelta,
  55927. options = that.options,
  55928. tickProvider = options.tickProvider,
  55929. labelOptions = options.label,
  55930. categories = options.categories,
  55931. ticksOptions = that._getTicksOptions();
  55932. that._fullTickValues = that._tickValues = tickProvider.getTicks(ticksOptions);
  55933. if ((isDateUtils(options.min) || isDateUtils(categories && categories[0])) && !that.hasLabelFormat && that._tickValues.length)
  55934. labelOptions.format = DX.formatHelper.getDateFormatByTicks(that._tickValues);
  55935. that.overlappingBehavior = labelOptions.overlappingBehavior ? $.extend({}, labelOptions.overlappingBehavior) : null;
  55936. if (that.overlappingBehavior) {
  55937. if (!options.isHorizontal && that.overlappingBehavior.mode !== 'ignore')
  55938. that.overlappingBehavior.mode = 'enlargeTickInterval';
  55939. ticksOptions.useTicksAutoArrangement = that.overlappingBehavior.mode !== 'ignore';
  55940. if (ticksOptions.useTicksAutoArrangement)
  55941. that._fullTickValues = that._tickValues = tickProvider.getCorrectedTicks(that._fullTickValues, ticksOptions);
  55942. if (that.overlappingBehavior.mode === 'auto') {
  55943. that.textOptions.rotate = 0;
  55944. that._applyOptimalOverlappingBehavior(that._fullTickValues, ticksOptions);
  55945. ticksOptions.useTicksAutoArrangement = that.overlappingBehavior.isOverlapped
  55946. }
  55947. if (that.overlappingBehavior.mode === 'rotate') {
  55948. that.textOptions.rotate = that.overlappingBehavior.rotationAngle;
  55949. if (!labelOptions.userAlignment)
  55950. that.textOptions.align = LEFT
  55951. }
  55952. else if (!labelOptions.userAlignment)
  55953. that.textOptions.align = labelOptions.alignment
  55954. }
  55955. if (ticksOptions.useTicksAutoArrangement) {
  55956. correctedScreenDelta = that._tickValues.length ? that.translator.translate(that._tickValues[that._tickValues.length - 1]) - that.translator.translate(that._tickValues[0]) : null;
  55957. if (correctedScreenDelta) {
  55958. ticksOptions.screenDelta = mathAbs(correctedScreenDelta);
  55959. ticksOptions.ticksCount = that._tickValues.length - 1
  55960. }
  55961. else
  55962. ticksOptions.ticksCount = that._tickValues.length;
  55963. if (that.overlappingBehavior && that.overlappingBehavior.mode === 'stagger')
  55964. ticksOptions.screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
  55965. ticksOptions.customTicks = that._tickValues;
  55966. that._tickValues = tickProvider.getTicks(ticksOptions)
  55967. }
  55968. that._testTKScreenDelta = ticksOptions.screenDelta;
  55969. that._autoArrangementStep = that._tickValues.autoArrangementStep;
  55970. that._useTicksAutoArrangement = ticksOptions.useTicksAutoArrangement;
  55971. if (that.options.stubData) {
  55972. that._testSkippedFormattingAndOverlapping = true;
  55973. return that._tickValues
  55974. }
  55975. if (!$.isArray(categories))
  55976. that._fullTickValues = that._tickValues;
  55977. return that._tickValues
  55978. },
  55979. setTickValues: function(tickValues) {
  55980. this.resetTicks();
  55981. this._fullTickValues = this._tickValues = tickValues
  55982. },
  55983. _prepareLabelsToDraw: function() {
  55984. var that = this,
  55985. ticksValues = that.getTickValues(),
  55986. ticks = [],
  55987. i;
  55988. if (ticksValues.hideLabels || that.options.stubData)
  55989. ticks.hideLabels = true;
  55990. for (i = 0; i < ticksValues.length; i++)
  55991. ticks.push({
  55992. text: ticksValues[i],
  55993. pos: that.translator.translate(ticksValues[i])
  55994. });
  55995. return ticks
  55996. },
  55997. _correctTicksPosition: function(ticks) {
  55998. var that = this,
  55999. options = that.options,
  56000. tickDelta = that.translator.getInterval() / 2,
  56001. i;
  56002. if (options.categories && (options.discreteAxisDivisionMode !== 'crossLabels' || !options.discreteAxisDivisionMode)) {
  56003. if (options.isHorizontal) {
  56004. if (!options.valueMarginsEnabled)
  56005. ticks = ticks.slice(0, ticks.length - 1)
  56006. }
  56007. else {
  56008. tickDelta = -tickDelta;
  56009. if (!options.valueMarginsEnabled)
  56010. ticks = ticks.slice(1, ticks.length)
  56011. }
  56012. for (i = 0; i < ticks.length; i++)
  56013. ticks[i].pos = ticks[i].pos + tickDelta
  56014. }
  56015. return ticks
  56016. },
  56017. _prepareFullTicksToDraw: function() {
  56018. var that = this,
  56019. ticksValues = that._fullTickValues,
  56020. ticks = [],
  56021. i;
  56022. if (!that._fullTickPositions) {
  56023. if (!ticksValues) {
  56024. that.getTickValues();
  56025. ticksValues = that._fullTickValues || []
  56026. }
  56027. for (i = 0; i < ticksValues.length; i++)
  56028. ticks.push({pos: that.translator.translate(ticksValues[i])});
  56029. that._fullTickPositions = that._correctTicksPosition(ticks)
  56030. }
  56031. return that._fullTickPositions
  56032. },
  56033. _drawTicks: function() {
  56034. var that = this,
  56035. options = that.options,
  56036. ticksOptions = options.tick,
  56037. i,
  56038. axisPosition = that.axisPosition,
  56039. tickStart = axisPosition - 4,
  56040. tickEnd = axisPosition + 4,
  56041. tick,
  56042. ticksToDraw;
  56043. if (!ticksOptions.visible)
  56044. return;
  56045. var drawLine = function(p11, p12, p21, p22) {
  56046. that.renderer.createLine(p11, p12, p21, p22, {
  56047. strokeWidth: 1,
  56048. stroke: ticksOptions.color,
  56049. strokeOpacity: ticksOptions.opacity
  56050. }).append(that._axisLineGroup)
  56051. };
  56052. ticksToDraw = that._prepareFullTicksToDraw();
  56053. if (options.isHorizontal)
  56054. for (i = 0; i < ticksToDraw.length; i++) {
  56055. tick = ticksToDraw[i];
  56056. drawLine(tick.pos, tickStart, tick.pos, tickEnd)
  56057. }
  56058. else
  56059. for (i = 0; i < ticksToDraw.length; i++) {
  56060. tick = ticksToDraw[i];
  56061. drawLine(tickStart, tick.pos, tickEnd, tick.pos)
  56062. }
  56063. },
  56064. setPercentLabelFormat: function() {
  56065. var labelOptions = this.options.label;
  56066. if (!this.hasLabelFormat)
  56067. labelOptions.format = 'percent'
  56068. },
  56069. resetAutoLabelFormat: function() {
  56070. var labelOptions = this.options.label;
  56071. if (!this.hasLabelFormat)
  56072. delete labelOptions.format
  56073. },
  56074. _drawLabels: function() {
  56075. var that = this,
  56076. i,
  56077. options = that.options,
  56078. renderer = that.renderer,
  56079. axisPosition = that.axisPosition,
  56080. labelOptions = options.label,
  56081. labelOffset = labelOptions.indentFromAxis,
  56082. labelsToDraw,
  56083. labelPoint,
  56084. label,
  56085. labels = [],
  56086. createText = options.isHorizontal ? renderer.createText : function(text, y, x, textOptions) {
  56087. return this.createText(text, x, y, textOptions)
  56088. },
  56089. emptyStrRegExp = /^\s+$/,
  56090. currentLabelConst = options.position === TOP || options.position === LEFT ? axisPosition - labelOffset : axisPosition + labelOffset,
  56091. text;
  56092. if (!labelOptions.visible || !that._axisElementsGroup)
  56093. return;
  56094. labelsToDraw = that._prepareLabelsToDraw();
  56095. if (labelsToDraw.length === 0 || labelsToDraw.hideLabels)
  56096. return true;
  56097. for (i = 0; i < labelsToDraw.length; i++) {
  56098. labelPoint = labelsToDraw[i];
  56099. text = formatLabel(labelPoint.text, labelOptions, {
  56100. min: options.min,
  56101. max: options.max
  56102. });
  56103. if (isDefinedUtils(text) && text !== '' && !emptyStrRegExp.test(text)) {
  56104. label = createText.call(renderer, text, labelPoint.pos, currentLabelConst, that.textOptions);
  56105. labels.push(label);
  56106. label.append(that._axisElementsGroup);
  56107. label.data({argument: labelPoint.text})
  56108. }
  56109. }
  56110. that.labels = labels
  56111. },
  56112. getMultipleAxesSpacing: function() {
  56113. return this.options.multipleAxesSpacing || 0
  56114. },
  56115. _drawTitle: function() {
  56116. var that = this,
  56117. i,
  56118. options = that.options,
  56119. renderer = that.renderer,
  56120. axisPosition = that.axisPosition,
  56121. titleOptions = options.title,
  56122. title,
  56123. attr = {
  56124. font: titleOptions.font,
  56125. opacity: titleOptions.opacity,
  56126. align: CENTER,
  56127. 'class': 'dx-chart-axis-title'
  56128. },
  56129. centerPosition = that.translator.translateSpecialCase(CANVAS_POSITION_PREFIX + CENTER),
  56130. x,
  56131. y;
  56132. if (!titleOptions.text || !that._axisTitleGroup)
  56133. return;
  56134. if (options.isHorizontal) {
  56135. x = centerPosition;
  56136. y = axisPosition
  56137. }
  56138. else {
  56139. if (options.position === LEFT)
  56140. attr.rotate = 270;
  56141. else
  56142. attr.rotate = 90;
  56143. x = axisPosition;
  56144. y = centerPosition
  56145. }
  56146. that.title = renderer.createText(titleOptions.text, x, y, attr).append(that._axisTitleGroup)
  56147. },
  56148. _drawGrid: function(borderOptions) {
  56149. var that = this,
  56150. positionsToDraw,
  56151. options = that.options,
  56152. gridOptions = options.grid,
  56153. i;
  56154. if (!gridOptions.visible)
  56155. return;
  56156. borderOptions = borderOptions || {visible: false};
  56157. var drawLine = function() {
  56158. var translator = that.translator,
  56159. orthogonalTranslator = that.orthogonalTranslator,
  56160. isHorizontal = options.isHorizontal,
  56161. canvasStart = isHorizontal ? LEFT : TOP,
  56162. canvasEnd = isHorizontal ? RIGHT : BOTTOM,
  56163. positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START),
  56164. positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END),
  56165. firstBorderLinePosition = borderOptions.visible && borderOptions[canvasStart] ? translator.translateSpecialCase(CANVAS_POSITION_PREFIX + canvasStart) : undefined,
  56166. lastBorderLinePosition = borderOptions.visible && borderOptions[canvasEnd] ? translator.translateSpecialCase(CANVAS_POSITION_PREFIX + canvasEnd) : undefined;
  56167. return function(tick) {
  56168. if (mathAbs(tick.pos - firstBorderLinePosition) < MAX_GRID_BORDER_ADHENSION || mathAbs(tick.pos - lastBorderLinePosition) < MAX_GRID_BORDER_ADHENSION)
  56169. return;
  56170. var p11 = tick.pos,
  56171. p12 = positionFrom,
  56172. p21 = tick.pos,
  56173. p22 = positionTo;
  56174. if (!isHorizontal) {
  56175. p11 = positionFrom;
  56176. p12 = p22 = tick.pos;
  56177. p21 = positionTo
  56178. }
  56179. that.renderer.createLine(p11, p12, p21, p22, {
  56180. strokeWidth: gridOptions.width,
  56181. stroke: gridOptions.color,
  56182. strokeOpacity: gridOptions.opacity
  56183. }).append(that._axisGridGroup)
  56184. }
  56185. }();
  56186. positionsToDraw = that._prepareFullTicksToDraw();
  56187. for (i = 0; i < positionsToDraw.length; i++)
  56188. drawLine(positionsToDraw[i])
  56189. },
  56190. _drawConstantLine: function() {
  56191. var that = this,
  56192. group = that._axisConstantLineGroup,
  56193. renderer = that.renderer,
  56194. options = that.options,
  56195. data = options.constantLines,
  56196. translator = that.translator,
  56197. orthogonalTranslator = that.orthogonalTranslator,
  56198. isHorizontal = options.isHorizontal,
  56199. i,
  56200. lines = [],
  56201. labels = [],
  56202. positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START),
  56203. positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END),
  56204. canvasStart = translator.translateSpecialCase(CANVAS_POSITION_START),
  56205. canvasEnd = translator.translateSpecialCase(CANVAS_POSITION_END),
  56206. range = translator.getBusinessRange();
  56207. var getPos = function(lineValue) {
  56208. var parsedValue = that.validateUnit(lineValue, "E2105", 'constantLine'),
  56209. value = translator.translate(parsedValue),
  56210. isContinous = !!(range.minVisible || range.maxVisible);
  56211. if (!isContinous && $.inArray(lineValue, range.categories || []) === -1 || !isDefinedUtils(value) || value < Math.min(canvasStart, canvasEnd) || value > Math.max(canvasStart, canvasEnd))
  56212. return {};
  56213. return {
  56214. value: value,
  56215. parsedValue: parsedValue
  56216. }
  56217. };
  56218. var drawLinesAndLabels = function(lineOptions) {
  56219. if (lineOptions.value === undefined)
  56220. return;
  56221. var pos = getPos(lineOptions.value),
  56222. labelOptions = lineOptions.label || {},
  56223. value = pos.value,
  56224. line,
  56225. attr = {
  56226. stroke: lineOptions.color,
  56227. strokeWidth: lineOptions.width,
  56228. dashStyle: lineOptions.dashStyle
  56229. };
  56230. if (!isDefinedUtils(value)) {
  56231. lines.push(null);
  56232. if (labelOptions.visible)
  56233. labels.push(null);
  56234. return
  56235. }
  56236. line = isHorizontal ? renderer.createLine(value, positionTo, value, positionFrom, attr) : renderer.createLine(positionFrom, value, positionTo, value, attr);
  56237. lines.push(line.append(group));
  56238. if (labelOptions.visible)
  56239. labels.push(that._drawConstantLineLabels(pos.parsedValue, labelOptions, value, group));
  56240. else
  56241. labels.push(null)
  56242. };
  56243. for (i = 0; i < data.length; i++)
  56244. drawLinesAndLabels(data[i]);
  56245. that.constantLines = lines;
  56246. that.constantLineLabels = labels
  56247. },
  56248. _checkAlignmentConstantLineLabels: function(labelOptions) {
  56249. var options = this.options;
  56250. labelOptions.verticalAlignment = (labelOptions.verticalAlignment || '').toLowerCase();
  56251. labelOptions.horizontalAlignment = (labelOptions.horizontalAlignment || '').toLowerCase();
  56252. if (options.isHorizontal && labelOptions.position === 'outside') {
  56253. labelOptions.verticalAlignment = labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
  56254. labelOptions.horizontalAlignment = CENTER
  56255. }
  56256. if (options.isHorizontal && labelOptions.position === 'inside') {
  56257. labelOptions.verticalAlignment = labelOptions.verticalAlignment === CENTER ? CENTER : labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
  56258. labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === LEFT ? LEFT : RIGHT
  56259. }
  56260. if (!options.isHorizontal && labelOptions.position === 'outside') {
  56261. labelOptions.verticalAlignment = CENTER;
  56262. labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === LEFT ? LEFT : RIGHT
  56263. }
  56264. if (!options.isHorizontal && labelOptions.position === 'inside') {
  56265. labelOptions.verticalAlignment = labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
  56266. labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === RIGHT ? RIGHT : labelOptions.horizontalAlignment === CENTER ? CENTER : LEFT
  56267. }
  56268. },
  56269. _drawConstantLineLabels: function(parsedValue, lineLabelOptions, value, group) {
  56270. var that = this,
  56271. text = lineLabelOptions.text,
  56272. orthogonalTranslator = that.orthogonalTranslator,
  56273. options = that.options,
  56274. labelOptions = options.label,
  56275. attr = {
  56276. align: CENTER,
  56277. font: $.extend({}, labelOptions.font, lineLabelOptions.font)
  56278. },
  56279. x,
  56280. y;
  56281. that._checkAlignmentConstantLineLabels(lineLabelOptions);
  56282. text = isDefinedUtils(text) ? text : formatLabel(parsedValue, labelOptions);
  56283. if (options.isHorizontal) {
  56284. x = value;
  56285. switch (lineLabelOptions.horizontalAlignment) {
  56286. case LEFT:
  56287. attr.align = RIGHT;
  56288. break;
  56289. case RIGHT:
  56290. attr.align = LEFT;
  56291. break
  56292. }
  56293. y = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.verticalAlignment)
  56294. }
  56295. else {
  56296. y = value;
  56297. x = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.horizontalAlignment);
  56298. switch (lineLabelOptions.horizontalAlignment) {
  56299. case LEFT:
  56300. attr.align = lineLabelOptions.position === 'inside' ? LEFT : RIGHT;
  56301. break;
  56302. case CENTER:
  56303. attr.align = CENTER;
  56304. break;
  56305. case RIGHT:
  56306. attr.align = lineLabelOptions.position === 'inside' ? RIGHT : LEFT;
  56307. break
  56308. }
  56309. }
  56310. return that.renderer.createText(text, x, y, attr).append(group)
  56311. },
  56312. _adjustConstantLineLabels: function() {
  56313. var that = this,
  56314. options = that.options,
  56315. isHorizontal = options.isHorizontal,
  56316. lines = that.constantLines,
  56317. labels = that.constantLineLabels,
  56318. label,
  56319. line,
  56320. lineBox,
  56321. linesOptions,
  56322. labelOptions,
  56323. box,
  56324. x,
  56325. y,
  56326. i,
  56327. padding = isHorizontal ? {
  56328. top: 0,
  56329. bottom: 0
  56330. } : {
  56331. left: 0,
  56332. right: 0
  56333. };
  56334. if (labels === undefined && lines === undefined)
  56335. return;
  56336. for (i = 0; i < labels.length; i++) {
  56337. x = y = 0;
  56338. linesOptions = options.constantLines[i];
  56339. labelOptions = linesOptions.label;
  56340. label = labels[i];
  56341. if (label !== null) {
  56342. line = lines[i];
  56343. box = label.getBBox();
  56344. lineBox = line.getBBox();
  56345. if (isHorizontal)
  56346. if (labelOptions.position === 'inside') {
  56347. switch (labelOptions.horizontalAlignment) {
  56348. case LEFT:
  56349. x -= linesOptions.paddingLeftRight;
  56350. break;
  56351. default:
  56352. x += linesOptions.paddingLeftRight;
  56353. break
  56354. }
  56355. switch (labelOptions.verticalAlignment) {
  56356. case CENTER:
  56357. y += lineBox.y + lineBox.height / 2 - box.y - box.height / 2;
  56358. break;
  56359. case BOTTOM:
  56360. y -= linesOptions.paddingTopBottom;
  56361. break;
  56362. default:
  56363. y += linesOptions.paddingTopBottom + box.height;
  56364. break
  56365. }
  56366. }
  56367. else
  56368. switch (labelOptions.verticalAlignment) {
  56369. case BOTTOM:
  56370. y += box.height + linesOptions.paddingTopBottom - (box.y + box.height - that.orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + labelOptions.verticalAlignment));
  56371. if (padding[BOTTOM] < box.height + linesOptions.paddingTopBottom)
  56372. padding[BOTTOM] = box.height + linesOptions.paddingTopBottom;
  56373. break;
  56374. default:
  56375. y -= linesOptions.paddingTopBottom;
  56376. if (padding[TOP] < linesOptions.paddingTopBottom + box.height)
  56377. padding[TOP] = linesOptions.paddingTopBottom + box.height;
  56378. break
  56379. }
  56380. else if (labelOptions.position === 'inside') {
  56381. switch (labelOptions.horizontalAlignment) {
  56382. case CENTER:
  56383. x += lineBox.x + lineBox.width / 2 - box.x - box.width / 2;
  56384. break;
  56385. case RIGHT:
  56386. x -= linesOptions.paddingLeftRight;
  56387. break;
  56388. default:
  56389. x += linesOptions.paddingLeftRight;
  56390. break
  56391. }
  56392. switch (labelOptions.verticalAlignment) {
  56393. case BOTTOM:
  56394. y += lineBox.y - box.y + linesOptions.paddingTopBottom;
  56395. break;
  56396. default:
  56397. y -= linesOptions.paddingTopBottom;
  56398. break
  56399. }
  56400. }
  56401. else {
  56402. y += lineBox.y + lineBox.height / 2 - box.y - box.height / 2;
  56403. switch (labelOptions.horizontalAlignment) {
  56404. case RIGHT:
  56405. x += linesOptions.paddingLeftRight;
  56406. if (padding[RIGHT] < linesOptions.paddingLeftRight + box.width)
  56407. padding[RIGHT] = linesOptions.paddingLeftRight + box.width;
  56408. break;
  56409. default:
  56410. x -= linesOptions.paddingLeftRight;
  56411. if (padding[LEFT] < linesOptions.paddingLeftRight + box.width)
  56412. padding[LEFT] = linesOptions.paddingLeftRight + box.width;
  56413. break
  56414. }
  56415. }
  56416. label.move(x, y)
  56417. }
  56418. }
  56419. that.padding = padding
  56420. },
  56421. _drawStrip: function() {
  56422. var that = this,
  56423. renderer = that.renderer,
  56424. options = that.options,
  56425. stripData = options.strips,
  56426. translator = that.translator,
  56427. orthogonalTranslator = that.orthogonalTranslator,
  56428. range = translator.getBusinessRange(),
  56429. i,
  56430. stripLabels = [],
  56431. stripRects = [],
  56432. rect,
  56433. isHorizontal = options.isHorizontal,
  56434. stripOptions,
  56435. positionFrom,
  56436. positionTo,
  56437. stripPos,
  56438. stripLabelOptions,
  56439. attr;
  56440. if (options.stubData)
  56441. return;
  56442. var getPos = function(startV, endV) {
  56443. var isContinous = !!(range.minVisible || range.maxVisible),
  56444. cateories = range.categories || [],
  56445. start = translator.translate(that.validateUnit(startV, "E2105", "strip")),
  56446. end = translator.translate(that.validateUnit(endV, "E2105", "strip")),
  56447. canvasStart = translator.translateSpecialCase(CANVAS_POSITION_START),
  56448. canvasEnd = translator.translateSpecialCase(CANVAS_POSITION_END),
  56449. min = range.minVisible;
  56450. if (!isContinous && ($.inArray(startV, cateories) === -1 || $.inArray(endV, cateories) === -1))
  56451. return {
  56452. stripFrom: 0,
  56453. stripTo: 0
  56454. };
  56455. if (!isDefinedUtils(start) && isContinous)
  56456. start = startV < min ? canvasStart : canvasEnd;
  56457. if (!isDefinedUtils(end) && isContinous)
  56458. end = endV < min ? canvasStart : canvasEnd;
  56459. return start < end ? {
  56460. stripFrom: start,
  56461. stripTo: end
  56462. } : {
  56463. stripFrom: end,
  56464. stripTo: start
  56465. }
  56466. };
  56467. positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START);
  56468. positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END);
  56469. for (i = 0; i < stripData.length; i++) {
  56470. stripOptions = stripData[i];
  56471. stripLabelOptions = stripOptions.label || {};
  56472. attr = {fill: stripOptions.color};
  56473. if (stripOptions.startValue !== undefined && stripOptions.endValue !== undefined && stripOptions.color !== undefined) {
  56474. stripPos = getPos(stripOptions.startValue, stripOptions.endValue);
  56475. if (stripPos.stripTo - stripPos.stripFrom === 0 || !stripPos.stripTo && stripPos.stripTo !== 0 || !stripPos.stripFrom && stripPos.stripFrom !== 0) {
  56476. stripRects.push(null);
  56477. if (stripLabelOptions.text)
  56478. stripLabels.push(null);
  56479. continue
  56480. }
  56481. rect = isHorizontal ? renderer.createRect(stripPos.stripFrom, Math.min(positionFrom, positionTo), stripPos.stripTo - stripPos.stripFrom, mathAbs(positionFrom - positionTo), 0, attr) : renderer.createRect(Math.min(positionFrom, positionTo), stripPos.stripFrom, mathAbs(positionFrom - positionTo), stripPos.stripTo - stripPos.stripFrom, 0, attr);
  56482. stripRects.push(rect.append(that._axisStripGroup));
  56483. if (stripLabelOptions.text)
  56484. stripLabels.push(that._drawStripLabel(stripLabelOptions, stripPos.stripFrom, stripPos.stripTo));
  56485. else
  56486. stripLabels.push(null)
  56487. }
  56488. }
  56489. that.stripLabels = stripLabels;
  56490. that.stripRects = stripRects
  56491. },
  56492. _drawStripLabel: function(stripLabelOptions, stripFrom, stripTo) {
  56493. var that = this,
  56494. orthogonalTranslator = that.orthogonalTranslator,
  56495. options = that.options,
  56496. isHorizontal = options.isHorizontal,
  56497. attr = {
  56498. align: isHorizontal ? CENTER : LEFT,
  56499. font: $.extend({}, options.label.font, stripLabelOptions.font)
  56500. },
  56501. x,
  56502. y;
  56503. if (isHorizontal) {
  56504. if (stripLabelOptions.horizontalAlignment === CENTER) {
  56505. x = stripFrom + (stripTo - stripFrom) / 2;
  56506. attr.align = CENTER
  56507. }
  56508. else if (stripLabelOptions.horizontalAlignment === LEFT) {
  56509. x = stripFrom;
  56510. attr.align = LEFT
  56511. }
  56512. else if (stripLabelOptions.horizontalAlignment === RIGHT) {
  56513. x = stripTo;
  56514. attr.align = RIGHT
  56515. }
  56516. y = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.verticalAlignment)
  56517. }
  56518. else {
  56519. x = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.horizontalAlignment);
  56520. attr.align = stripLabelOptions.horizontalAlignment;
  56521. if (stripLabelOptions.verticalAlignment === TOP)
  56522. y = stripFrom;
  56523. else if (stripLabelOptions.verticalAlignment === CENTER)
  56524. y = stripTo + (stripFrom - stripTo) / 2;
  56525. else if (stripLabelOptions.verticalAlignment === BOTTOM)
  56526. y = stripTo
  56527. }
  56528. return that.renderer.createText(stripLabelOptions.text, x, y, attr).append(that._axisLableGroup)
  56529. },
  56530. _initAxisPositions: function() {
  56531. var that = this,
  56532. position = that.options.position,
  56533. delta = 0;
  56534. if (that.delta)
  56535. delta = that.delta[position] || 0;
  56536. that.axisPosition = that.orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + position) + delta
  56537. },
  56538. _adjustLabels: function() {
  56539. var that = this,
  56540. options = that.options,
  56541. isHorizontal = options.isHorizontal,
  56542. position = options.position,
  56543. labels = that.labels,
  56544. label,
  56545. labelHeight,
  56546. isNeedLabelAdjustment,
  56547. staggeringSpacing,
  56548. i,
  56549. xt,
  56550. shift = that.padding && that.padding[position] || 0,
  56551. boxAxis = that._axisElementsGroup && that._axisElementsGroup.getBBox() || {},
  56552. box;
  56553. if (!options.label.visible || !labels || !labels.length)
  56554. return;
  56555. for (i = 0; i < labels.length; i++) {
  56556. label = labels[i];
  56557. box = label.getBBox();
  56558. if (isHorizontal && position === BOTTOM)
  56559. label.applySettings({y: 2 * label.settings.y - box.y + shift});
  56560. else if (!isHorizontal) {
  56561. if (position === LEFT)
  56562. if (that.textOptions.align === RIGHT)
  56563. xt = box.x + box.width - shift;
  56564. else if (that.textOptions.align === CENTER)
  56565. xt = box.x + box.width / 2 - shift - (boxAxis.width / 2 || 0);
  56566. else
  56567. xt = box.x - shift - (boxAxis.width || 0);
  56568. else if (that.textOptions.align === CENTER)
  56569. xt = box.x + box.width / 2 + (boxAxis.width / 2 || 0) + shift;
  56570. else if (that.textOptions.align === RIGHT)
  56571. xt = box.x + box.width + (boxAxis.width || 0) + shift;
  56572. else
  56573. xt = box.x + shift;
  56574. label.applySettings({
  56575. x: xt,
  56576. y: label.settings.y + ~~(label.settings.y - box.y - box.height / 2)
  56577. })
  56578. }
  56579. else if (isHorizontal && position === TOP)
  56580. label.applySettings({y: 2 * label.settings.y - box.y - box.height - shift})
  56581. }
  56582. isNeedLabelAdjustment = isHorizontal && that.overlappingBehavior && that.overlappingBehavior.mode === 'stagger';
  56583. that._testIsNeedLabelAdjustment = isNeedLabelAdjustment;
  56584. if (isNeedLabelAdjustment) {
  56585. labelHeight = 0;
  56586. for (i = 0; i < labels.length; i = i + 2) {
  56587. label = labels[i];
  56588. box = label.getBBox();
  56589. if (box.height > labelHeight)
  56590. labelHeight = box.height
  56591. }
  56592. staggeringSpacing = that.overlappingBehavior.staggeringSpacing;
  56593. that._testStaggeringSpacing = staggeringSpacing;
  56594. labelHeight = Math.round(labelHeight) + staggeringSpacing;
  56595. for (i = 1; i < labels.length; i = i + 2) {
  56596. label = labels[i];
  56597. if (position === BOTTOM)
  56598. label.move(0, labelHeight);
  56599. else if (position === TOP)
  56600. label.move(0, -labelHeight)
  56601. }
  56602. for (i = 0; i < labels.length; i++)
  56603. labels[i].rotate(0)
  56604. }
  56605. },
  56606. _adjustStripLabels: function() {
  56607. var that = this,
  56608. labelOptions,
  56609. labels = that.stripLabels,
  56610. rects = that.stripRects,
  56611. label,
  56612. i,
  56613. box,
  56614. rectBox,
  56615. stripOptions,
  56616. x,
  56617. y;
  56618. if (labels === undefined && rects === undefined)
  56619. return;
  56620. for (i = 0; i < labels.length; i++) {
  56621. x = y = 0;
  56622. stripOptions = that.options.strips[i];
  56623. labelOptions = stripOptions.label;
  56624. label = labels[i];
  56625. if (label !== null) {
  56626. box = label.getBBox();
  56627. rectBox = rects[i].getBBox();
  56628. if (labelOptions.horizontalAlignment === LEFT)
  56629. x += stripOptions.paddingLeftRight;
  56630. else if (labelOptions.horizontalAlignment === RIGHT)
  56631. x -= stripOptions.paddingLeftRight;
  56632. if (labelOptions.verticalAlignment === TOP)
  56633. y += rectBox.y - box.y + stripOptions.paddingTopBottom;
  56634. else if (labelOptions.verticalAlignment === CENTER)
  56635. y += rectBox.y + rectBox.height / 2 - box.y - box.height / 2;
  56636. else if (labelOptions.verticalAlignment === BOTTOM)
  56637. y -= stripOptions.paddingTopBottom;
  56638. label.move(x, y)
  56639. }
  56640. }
  56641. },
  56642. _adjustTitle: function() {
  56643. var that = this,
  56644. options = that.options,
  56645. position = options.position,
  56646. title = that.title,
  56647. margin = options.title.margin,
  56648. boxGroup,
  56649. boxTitle;
  56650. if (!title || !that._axisElementsGroup)
  56651. return;
  56652. boxTitle = title.getBBox();
  56653. boxGroup = that._axisElementsGroup.getBBox();
  56654. if (options.isHorizontal)
  56655. if (position === BOTTOM)
  56656. title.applySettings({
  56657. y: boxGroup.isEmpty ? undefined : boxGroup.y + boxGroup.height,
  56658. translateY: margin + boxTitle.height
  56659. });
  56660. else
  56661. title.applySettings({
  56662. y: boxGroup.isEmpty ? undefined : boxGroup.y,
  56663. translateY: -margin
  56664. });
  56665. else if (position === LEFT)
  56666. title.applySettings({
  56667. x: boxGroup.isEmpty ? undefined : boxGroup.x,
  56668. translateX: -margin
  56669. });
  56670. else
  56671. title.applySettings({
  56672. x: boxGroup.isEmpty ? undefined : boxGroup.x + boxGroup.width,
  56673. translateX: margin
  56674. })
  56675. },
  56676. draw: function(externalOptions, adjustAxis) {
  56677. var that = this,
  56678. options = that.options,
  56679. isHorizontal = options.isHorizontal,
  56680. cssClass = isHorizontal ? 'dxc-h-axis' : 'dxc-v-axis',
  56681. stripClass = isHorizontal ? 'dxc-h-strips' : 'dxc-v-strips',
  56682. constantLineClass = isHorizontal ? 'dxc-h-constant-lines' : 'dxc-v-constant-lines';
  56683. externalOptions = externalOptions || {};
  56684. var debug = DX.utils.debug;
  56685. debug.assertParam(this.translator, 'translator was not set before Draw call');
  56686. if (that._axisGroup) {
  56687. that._axisGroup.detach();
  56688. that._axisStripGroup.detach();
  56689. that._axisLableGroup.detach();
  56690. that._axisConstantLineGroup.detach();
  56691. that._axisTitleGroup ? that._axisTitleGroup.clear() : !adjustAxis && (that._axisTitleGroup = that.renderer.createGroup({'class': 'dxc-title'}).append(that._axisGroup));
  56692. that._axisGridGroup.clear();
  56693. that._axisElementsGroup ? that._axisElementsGroup.clear() : !adjustAxis && (that._axisElementsGroup = that.renderer.createGroup({'class': 'dxc-elements'}).append(that._axisGroup));
  56694. that._axisLineGroup.clear();
  56695. that._axisStripGroup.clear();
  56696. that._axisConstantLineGroup.clear();
  56697. that._axisLableGroup.clear()
  56698. }
  56699. else {
  56700. that._axisGroup = that.renderer.createGroup({
  56701. 'class': cssClass,
  56702. clipId: that.clipRectID
  56703. });
  56704. that._axisStripGroup = that.renderer.createGroup({'class': stripClass});
  56705. that._axisGridGroup = that.renderer.createGroup({'class': 'dxc-grid'}).append(that._axisGroup);
  56706. that._axisElementsGroup = that.renderer.createGroup({'class': 'dxc-elements'}).append(that._axisGroup);
  56707. that._axisLineGroup = that.renderer.createGroup({'class': 'dxc-line'}).append(that._axisGroup);
  56708. that._axisTitleGroup = that.renderer.createGroup({'class': 'dxc-title'}).append(that._axisGroup);
  56709. that._axisConstantLineGroup = that.renderer.createGroup({'class': constantLineClass});
  56710. that._axisLableGroup = that.renderer.createGroup({'class': 'dxc-axis-labels'})
  56711. }
  56712. that._initAxisPositions();
  56713. if (!that._virtual) {
  56714. that._drawAxis();
  56715. that._drawTicks();
  56716. that._drawLabels();
  56717. that._drawTitle()
  56718. }
  56719. if (options.strips)
  56720. that._drawStrip();
  56721. if (options.constantLines)
  56722. that._drawConstantLine();
  56723. that._drawGrid(externalOptions.borderOptions);
  56724. that._axisStripGroup.append(that.stripsGroup);
  56725. that._axisConstantLineGroup.append(that.constantLinesGroup);
  56726. that._axisGroup.append(that.axesContainerGroup);
  56727. that._axisLableGroup.append(that.labelAxesGroup);
  56728. that._adjustConstantLineLabels();
  56729. that._adjustLabels();
  56730. that._adjustStripLabels();
  56731. that._adjustTitle();
  56732. that._setBoundingRect()
  56733. },
  56734. _setBoundingRect: function() {
  56735. var that = this,
  56736. options = that.options,
  56737. axisBox = that._axisElementsGroup ? that._axisElementsGroup.getBBox() : {
  56738. x: 0,
  56739. y: 0,
  56740. width: 0,
  56741. height: 0,
  56742. isEmpty: true
  56743. },
  56744. lineBox = that._axisLineGroup.getBBox(),
  56745. placeholderSize = options.placeholderSize,
  56746. start,
  56747. isHorizontal = options.isHorizontal,
  56748. coord = isHorizontal && 'y' || 'x',
  56749. side = isHorizontal && 'height' || 'width',
  56750. axisTitleBox = that.title && that._axisTitleGroup ? that._axisTitleGroup.getBBox() : axisBox;
  56751. if (axisBox.isEmpty && axisTitleBox.isEmpty && !placeholderSize) {
  56752. that.boundingRect = axisBox;
  56753. return
  56754. }
  56755. start = lineBox[coord] || that.axisPosition;
  56756. if (options.position === (isHorizontal && BOTTOM || RIGHT)) {
  56757. axisBox[side] = placeholderSize || axisTitleBox[coord] + axisTitleBox[side] - start;
  56758. axisBox[coord] = start
  56759. }
  56760. else {
  56761. axisBox[side] = placeholderSize || lineBox[side] + start - axisTitleBox[coord];
  56762. axisBox[coord] = axisTitleBox.isEmpty ? start : axisTitleBox[coord]
  56763. }
  56764. that.boundingRect = axisBox
  56765. },
  56766. getBoundingRect: function() {
  56767. return this._axisElementsGroup ? this.boundingRect : {
  56768. x: 0,
  56769. y: 0,
  56770. width: 0,
  56771. height: 0
  56772. }
  56773. },
  56774. shift: function(x, y) {
  56775. var settings = {};
  56776. if (x)
  56777. settings.translateX = x;
  56778. if (y)
  56779. settings.translateY = y;
  56780. this._axisGroup.applySettings(settings)
  56781. },
  56782. applyClipRect: function(clipId) {
  56783. this._axisStripGroup.applySettings({clipId: clipId})
  56784. },
  56785. validate: function(isArgumentAxis, incidentOccured) {
  56786. var that = this,
  56787. options = that.options,
  56788. range = options.range,
  56789. parseUtils = new core.ParseUtils,
  56790. dataType = isArgumentAxis ? options.argumentType : options.valueType,
  56791. parser = dataType ? parseUtils.getParser(dataType, 'axis') : function(unit) {
  56792. return unit
  56793. };
  56794. that.parser = parser;
  56795. that.incidentOccured = incidentOccured;
  56796. options.dataType = dataType;
  56797. if (options.min)
  56798. options.min = that.validateUnit(options.min, "E2106");
  56799. if (options.max)
  56800. options.max = that.validateUnit(options.max, "E2106");
  56801. if (range.min)
  56802. range.min = that.validateUnit(range.min);
  56803. if (range.max)
  56804. range.max = that.validateUnit(range.max)
  56805. },
  56806. validateUnit: function(unit, idError, parameters) {
  56807. var that = this,
  56808. dataType = that.options.dataType;
  56809. unit = that.parser(unit);
  56810. if (unit === undefined && idError)
  56811. that.incidentOccured(idError, [parameters]);
  56812. return unit
  56813. },
  56814. adjustZoomValues: function(min, max) {
  56815. var that = this,
  56816. range = that.options.range;
  56817. min = that.validateUnit(min);
  56818. max = that.validateUnit(max);
  56819. if (range && isDefinedUtils(range.min)) {
  56820. min = isDefinedUtils(min) ? range.min < min ? min : range.min : min;
  56821. max = isDefinedUtils(max) ? range.min < max ? max : range.min : max
  56822. }
  56823. if (range && isDefinedUtils(range.max)) {
  56824. max = isDefinedUtils(max) ? range.max > max ? max : range.max : max;
  56825. min = isDefinedUtils(min) ? range.max > min ? min : range.max : min
  56826. }
  56827. that.minRangeArg = min;
  56828. that.maxRangeArg = max;
  56829. return {
  56830. min: min,
  56831. max: max
  56832. }
  56833. },
  56834. getRangeData: function() {
  56835. var that = this,
  56836. options = that.options,
  56837. optionsRange = options.range,
  56838. range = {},
  56839. min,
  56840. max;
  56841. var addValueMarginToRange = function(prefix) {
  56842. if (options.valueMarginsEnabled) {
  56843. if (isDefinedUtils(options[prefix])) {
  56844. range[prefix] = options[prefix];
  56845. range[prefix + 'Priority'] = AXIS_VALUE_MARGIN_PRIORITY
  56846. }
  56847. }
  56848. else {
  56849. range[prefix] = 0;
  56850. range[prefix + 'Priority'] = AXIS_VALUE_MARGIN_PRIORITY
  56851. }
  56852. };
  56853. if (isDefinedUtils(optionsRange.min) && isDefinedUtils(optionsRange.max)) {
  56854. min = optionsRange.min < optionsRange.max ? optionsRange.min : optionsRange.max;
  56855. max = optionsRange.max > optionsRange.min ? optionsRange.max : optionsRange.min
  56856. }
  56857. else {
  56858. min = optionsRange.min;
  56859. max = optionsRange.max
  56860. }
  56861. range.min = min;
  56862. range.max = max;
  56863. addValueMarginToRange('minValueMargin');
  56864. addValueMarginToRange('maxValueMargin');
  56865. range.stick = !options.valueMarginsEnabled;
  56866. range.categories = optionsRange.categories;
  56867. range.dataType = options.dataType;
  56868. range.axisType = options.type;
  56869. if (range.axisType === 'logarithmic')
  56870. range.base = options.logarithmBase;
  56871. if (options.isHorizontal) {
  56872. range.minVisible = isDefinedUtils(that.minRangeArg) ? that.minRangeArg : optionsRange.min;
  56873. range.maxVisible = isDefinedUtils(that.maxRangeArg) ? that.maxRangeArg : optionsRange.max;
  56874. range.invert = options.inverted
  56875. }
  56876. else {
  56877. range.minVisible = optionsRange.min;
  56878. range.maxVisible = optionsRange.max;
  56879. range.invert = options.inverted || options.type === 'discrete' && options.oppositeDirectionYAxis
  56880. }
  56881. return range
  56882. }
  56883. })
  56884. })(jQuery, DevExpress);
  56885. /*! Module viz-charts, file baseChart.js */
  56886. (function($, DX, undefined) {
  56887. var ui = DX.ui,
  56888. charts = DX.viz.charts,
  56889. utils = DX.utils,
  56890. TRACKER_RENDERING_DELAY = 1200,
  56891. resizeRedrawOptions = {
  56892. animate: false,
  56893. isResize: true
  56894. },
  56895. ACTIONS_BY_PRIORITY = ['reinit', '_reinitDataSource', '_handleDataSourceChanged', 'force_render'],
  56896. core = DX.viz.core,
  56897. DEFAULT_ANIMATION_OPTIONS = {
  56898. asyncSeriesRendering: true,
  56899. asyncTrackersRendering: true,
  56900. trackerRenderingDelay: TRACKER_RENDERING_DELAY
  56901. };
  56902. charts.BaseChart = core.BaseWidget.inherit({
  56903. _setDefaultOptions: function() {
  56904. this.callBase();
  56905. this.option({
  56906. done: $.noop,
  56907. drawn: $.noop,
  56908. seriesClick: null,
  56909. pointClick: null,
  56910. legendClick: null,
  56911. argumentAxisClick: null,
  56912. seriesHover: null,
  56913. pointHover: null,
  56914. seriesSelected: null,
  56915. pointSelected: null,
  56916. seriesSelectionChanged: null,
  56917. pointSelectionChanged: null,
  56918. seriesHoverChanged: null,
  56919. pointHoverChanged: null
  56920. })
  56921. },
  56922. _createThemeManager: function() {
  56923. return charts.factory.createThemeManager(this.option())
  56924. },
  56925. _init: function() {
  56926. this.__TRACKER_RENDERING_DELAY = TRACKER_RENDERING_DELAY;
  56927. var that = this;
  56928. that.callBase();
  56929. that.themeManager = this._createThemeManager();
  56930. that._initRenderer();
  56931. that.canvasClipRect = that.renderer.createClipRect();
  56932. that._createHtmlStructure();
  56933. that._needHandleRenderComplete = true;
  56934. that.layoutManager = charts.factory.createChartLayoutManager(that.themeManager.getOptions("adaptiveLayout"));
  56935. that._reinit();
  56936. that._element().css({webkitUserSelect: 'none'}).on('contextmenu', function(event) {
  56937. that.eventType = 'contextmenu';
  56938. if (ui.events.isTouchEvent(event) || ui.events.isPointerEvent(event))
  56939. event.preventDefault()
  56940. }).on('MSHoldVisual', function(event) {
  56941. that.eventType = 'MSHoldVisual';
  56942. event.preventDefault()
  56943. })
  56944. },
  56945. _reinit: function() {
  56946. var that = this;
  56947. that.layoutManager.update(that);
  56948. that._createTracker();
  56949. that._reinitDataSource()
  56950. },
  56951. _createHtmlStructure: function() {
  56952. var that = this,
  56953. renderer = that.renderer;
  56954. that._panesBackgroundGroup = renderer.createGroup({'class': 'dxc-background'});
  56955. that._titleGroup = renderer.createGroup({'class': 'dxc-title'});
  56956. that._legendGroup = renderer.createGroup({
  56957. 'class': 'dxc-legend',
  56958. clipId: that._getCanvasClipRectID()
  56959. });
  56960. that._stripsGroup = renderer.createGroup({'class': 'dxc-strips-group'});
  56961. that._constantLinesGroup = renderer.createGroup({'class': 'dxc-constant-lines-group'});
  56962. that._axesGroup = renderer.createGroup({'class': 'dxc-axes-group'});
  56963. that._panesBorderGroup = renderer.createGroup({'class': 'dxc-border'});
  56964. that._labelAxesGroup = renderer.createGroup({'class': 'dxc-strips-labels-group'});
  56965. that._seriesGroup = renderer.createGroup({'class': 'dxc-series-group'});
  56966. that._labelsGroup = renderer.createGroup({'class': 'dxc-labels-group'});
  56967. that._tooltipGroup = renderer.createGroup({'class': 'dxc-tooltip'});
  56968. that._trackerGroup = renderer.createGroup({
  56969. 'class': 'dxc-trackers',
  56970. opacity: 0.0001,
  56971. stroke: "gray",
  56972. fill: "gray"
  56973. });
  56974. that._crosshairTrackerGroup = renderer.createGroup({
  56975. 'class': 'dxc-crosshair-trackers',
  56976. stroke: 'none',
  56977. fill: 'grey'
  56978. }).append(that._trackerGroup);
  56979. that._seriesTrackerGroup = renderer.createGroup({'class': 'dxc-series-trackers'}).append(that._trackerGroup);
  56980. that._markerTrackerGroup = renderer.createGroup({
  56981. 'class': 'dxc-markers-trackers',
  56982. stroke: 'none',
  56983. fill: 'grey'
  56984. }).append(that._trackerGroup);
  56985. that._crossHairCursorGroup = renderer.createGroup({'class': 'dxc-crosshair-cursor'})
  56986. },
  56987. _cleanHtmlStructure: function() {
  56988. var that = this;
  56989. that._panesBackgroundGroup && that._panesBackgroundGroup.clear();
  56990. that._titleGroup && that._titleGroup.clear();
  56991. that._legendGroup && (that._legendGroup.detach(), that._legendGroup.clear());
  56992. that._stripsGroup && (that._stripsGroup.detach(), that._stripsGroup.clear());
  56993. that._constantLinesGroup && (that._constantLinesGroup.detach(), that._constantLinesGroup.clear());
  56994. that._axesGroup && (that._axesGroup.detach(), that._axesGroup.clear());
  56995. that._labelAxesGroup && (that._labelAxesGroup.detach(), that._labelAxesGroup.clear());
  56996. that._seriesGroup && (that._seriesGroup.detach(), that._seriesGroup.clear());
  56997. that._labelsGroup && (that._labelsGroup.detach(), that._labelsGroup.clear());
  56998. that._trackerGroup && (that._trackerGroup.detach(), that._seriesTrackerGroup.clear(), that._markerTrackerGroup.clear(), that._crosshairTrackerGroup.clear());
  56999. that._panesBorderGroup && that._panesBorderGroup.clear();
  57000. that._tooltipGroup && that._tooltipGroup.clear();
  57001. that._crossHairCursorGroup && (that._crossHairCursorGroup.clear(), that._crossHairCursorGroup.detach())
  57002. },
  57003. _disposeObjectsInArray: function(propName, fieldNames) {
  57004. $.each(this[propName] || [], function(_, item) {
  57005. if (fieldNames && item)
  57006. $.each(fieldNames, function(_, field) {
  57007. item[field] && item[field].dispose()
  57008. });
  57009. else
  57010. item && item.dispose()
  57011. });
  57012. this[propName] = null
  57013. },
  57014. _dispose: function() {
  57015. var that = this,
  57016. disposeObject = function(propName) {
  57017. that[propName] && that[propName].dispose(),
  57018. that[propName] = null
  57019. },
  57020. detachGroup = function(groupName) {
  57021. that[groupName] && that[groupName].detach()
  57022. },
  57023. disposeObjectsInArray = this._disposeObjectsInArray;
  57024. clearTimeout(that.delayedRedraw);
  57025. that.callBase();
  57026. disposeObjectsInArray.call(that, "businessRanges", ["arg", "val"]);
  57027. that.translators = null;
  57028. disposeObjectsInArray.call(that, "series");
  57029. disposeObject("layoutManager");
  57030. disposeObject("themeManager");
  57031. disposeObject("renderer");
  57032. disposeObject("tracker");
  57033. disposeObject("tooltip");
  57034. disposeObject("chartTitle");
  57035. that.paneAxis = null;
  57036. that._userOptions = null;
  57037. that.dirtyCanvas = null;
  57038. that.canvas = null;
  57039. detachGroup("_legendGroup");
  57040. detachGroup("_stripsGroup");
  57041. detachGroup("_constantLinesGroup");
  57042. detachGroup("_axesGroup");
  57043. detachGroup("_labelAxesGroup");
  57044. detachGroup("_seriesGroup");
  57045. detachGroup("_labelsGroup");
  57046. detachGroup("_trackerGroup");
  57047. detachGroup("_crossHairCursorGroup");
  57048. disposeObject("canvasClipRect");
  57049. disposeObject("_panesBackgroundGroup");
  57050. disposeObject("_titleGroup");
  57051. disposeObject("_legendGroup");
  57052. disposeObject("_stripsGroup");
  57053. disposeObject("_constantLinesGroup");
  57054. disposeObject("_axesGroup");
  57055. disposeObject("_labelAxesGroup");
  57056. disposeObject("_panesBorderGroup");
  57057. disposeObject("_seriesGroup");
  57058. disposeObject("_labelsGroup");
  57059. disposeObject("_tooltipGroup");
  57060. disposeObject("_crossHairCursorGroup");
  57061. disposeObject("_seriesTrackerGroup");
  57062. disposeObject("_markerTrackerGroup");
  57063. disposeObject("_crosshairTrackerGroup");
  57064. disposeObject("_trackerGroup");
  57065. that._disposeLoadIndicator()
  57066. },
  57067. _clean: function _clean(hideLoadIndicator) {
  57068. this.renderer && this.renderer.stopAllAnimations();
  57069. hideLoadIndicator && this.hideLoadingIndicator();
  57070. this._cleanHtmlStructure();
  57071. this.callBase();
  57072. this._saveDirtyCanvas()
  57073. },
  57074. _getAnimationOptions: function() {
  57075. return $.extend({}, DEFAULT_ANIMATION_OPTIONS, this.themeManager.getOptions("animation"))
  57076. },
  57077. _initRenderer: function _initRenderer() {
  57078. if (this.renderer)
  57079. return;
  57080. this.renderer = core.CoreFactory.createRenderer({
  57081. animation: this._getAnimationOptions(),
  57082. cssClass: 'dxc dxc-chart',
  57083. pathModified: this.option('pathModified'),
  57084. rtl: this.themeManager.getOptions('rtlEnabled')
  57085. })
  57086. },
  57087. _initSeries: function() {
  57088. this.series = this.series || this._populateSeries()
  57089. },
  57090. _reinitDataSource: function() {
  57091. this._refreshDataSource()
  57092. },
  57093. _saveDirtyCanvas: function() {
  57094. this.dirtyCanvas = $.extend({}, this.canvas)
  57095. },
  57096. _resize: function() {
  57097. this._render(resizeRedrawOptions)
  57098. },
  57099. _calculateCanvas: function() {
  57100. var canvas = this.themeManager.getOptions('size'),
  57101. result = {},
  57102. container = this._element();
  57103. if (!utils.isDefined(canvas.width))
  57104. result.width = container.width() || 400;
  57105. else
  57106. result.width = canvas.width < 0 ? 0 : canvas.width;
  57107. if (!utils.isDefined(canvas.height))
  57108. result.height = container.height() || 400;
  57109. else
  57110. result.height = canvas.height < 0 ? 0 : canvas.height;
  57111. return $.extend({}, result, this.themeManager.getOptions('margin'))
  57112. },
  57113. _createTracker: function() {
  57114. var that = this,
  57115. tooltipOptions = that.themeManager.getOptions('tooltip') || {};
  57116. if (that.tracker)
  57117. that.tracker.dispose();
  57118. that.tracker = charts.factory.createTracker({
  57119. series: that.series,
  57120. valueAxis: that._valueAxes,
  57121. argumentAxis: that._argumentAxes,
  57122. seriesSelectionMode: that.themeManager.getOptions('seriesSelectionMode'),
  57123. pointSelectionMode: that.themeManager.getOptions('pointSelectionMode'),
  57124. tooltipShown: that.option('tooltipShown'),
  57125. tooltipHidden: that.option('tooltipHidden'),
  57126. markerTrackerGroup: that._markerTrackerGroup,
  57127. crossHairOptions: that._crossHairOptions,
  57128. seriesTrackerGroup: that._seriesTrackerGroup,
  57129. seriesGroup: that._seriesGroup,
  57130. tooltipEnabled: tooltipOptions.enabled,
  57131. renderer: that.renderer,
  57132. events: {
  57133. seriesClick: that.option('seriesClick'),
  57134. pointClick: that.option('pointClick'),
  57135. argumentAxisClick: that.option('argumentAxisClick'),
  57136. seriesHover: that.option('seriesHover'),
  57137. seriesSelected: that.option('seriesSelected'),
  57138. pointHover: that.option('pointHover'),
  57139. pointSelected: that.option('pointSelected'),
  57140. legendClick: that.option('legendClick'),
  57141. seriesSelectionChanged: that.option('seriesSelectionChanged'),
  57142. pointSelectionChanged: that.option('pointSelectionChanged'),
  57143. seriesHoverChanged: that.option('seriesHoverChanged'),
  57144. pointHoverChanged: that.option('pointHoverChanged')
  57145. }
  57146. })
  57147. },
  57148. _updateTracker: function() {
  57149. var that = this;
  57150. if (!that.tracker)
  57151. that._createTracker();
  57152. else
  57153. that.tracker._reinit({
  57154. series: that.series,
  57155. valueAxis: that._valueAxes,
  57156. argumentAxis: that._argumentAxes,
  57157. legendGroup: that.legend.getTrackerGroup(),
  57158. legendCallback: $.proxy(that.legend.getActionCallback, that.legend)
  57159. })
  57160. },
  57161. _render: function(drawOptions) {
  57162. this._optionsInitializing = false;
  57163. var that = this,
  57164. renderer = that.renderer,
  57165. updatedCanvas = that.canvas,
  57166. container = this._element(),
  57167. currentDirtyCanvas = that._calculateCanvas(),
  57168. oldDirtyCanvas = that.dirtyCanvas;
  57169. drawOptions = drawOptions || {recreateCanvas: true};
  57170. drawOptions.recreateCanvas = drawOptions.recreateCanvas || !renderer.isInitialized();
  57171. if (!drawOptions.force && oldDirtyCanvas && oldDirtyCanvas.width === currentDirtyCanvas.width && oldDirtyCanvas.height === currentDirtyCanvas.height && !that.hiddenContainer) {
  57172. that.stopRedraw = true;
  57173. return
  57174. }
  57175. clearTimeout(that.delayedRedraw);
  57176. if (drawOptions.recreateCanvas)
  57177. that.canvas = updatedCanvas = that._calculateCanvas();
  57178. if (updatedCanvas.width && updatedCanvas.height && container.is(':visible'))
  57179. that.hiddenContainer = false;
  57180. else {
  57181. that._incidentOccured('W2001', [that.NAME]);
  57182. that.hiddenContainer = true;
  57183. that.stopRedraw = true;
  57184. renderer.detachContainer();
  57185. return
  57186. }
  57187. if (drawOptions.recreateCanvas) {
  57188. renderer.recreateCanvas(that.canvas.width, that.canvas.height);
  57189. renderer.draw(that._element()[0]);
  57190. that._reappendLoadIndicator();
  57191. that._updateLoadIndicator(undefined, updatedCanvas.width, updatedCanvas.height);
  57192. that._updateCanvasClipRect()
  57193. }
  57194. that.renderer.stopAllAnimations(true);
  57195. that.layoutManager.update(that);
  57196. that._cleanGroups(drawOptions);
  57197. that._saveDirtyCanvas()
  57198. },
  57199. _cleanGroups: function(drawOptions) {
  57200. var that = this;
  57201. that._stripsGroup.detach();
  57202. that._constantLinesGroup.detach();
  57203. that._axesGroup.detach();
  57204. that._labelAxesGroup.detach();
  57205. that._labelsGroup.detach();
  57206. that._tooltipGroup.detach();
  57207. that._crossHairCursorGroup.detach();
  57208. if (!drawOptions || drawOptions.drawLegend) {
  57209. that._legendGroup.detach();
  57210. that._legendGroup.clear()
  57211. }
  57212. if (!drawOptions || drawOptions.drawTitle) {
  57213. that._titleGroup.detach();
  57214. that._titleGroup.clear()
  57215. }
  57216. that._stripsGroup.clear();
  57217. that._constantLinesGroup.clear();
  57218. that._axesGroup.clear();
  57219. that._labelAxesGroup.clear();
  57220. that._labelsGroup.clear();
  57221. that._tooltipGroup.clear();
  57222. that._crossHairCursorGroup.clear();
  57223. that._crosshairTrackerGroup.clear()
  57224. },
  57225. _drawTitle: function() {
  57226. var that = this,
  57227. options = that.themeManager.getOptions("title"),
  57228. width = that.canvas.width - that.canvas.left - that.canvas.right;
  57229. options._incidentOccured = that._incidentOccured;
  57230. if (that.chartTitle)
  57231. that.chartTitle.update(options, width);
  57232. else
  57233. that.chartTitle = charts.factory.createTitle(that.renderer, options, width, that._titleGroup)
  57234. },
  57235. _createTooltip: function() {
  57236. var that = this,
  57237. tooltipOptions = $.extend(true, {
  57238. canvasWidth: that.canvas.width,
  57239. canvasHeight: that.canvas.height
  57240. }, that.themeManager.getOptions('tooltip') || {}),
  57241. tooltipCoords,
  57242. point = this.tracker.pointAtShownTooltip;
  57243. if (!$.isFunction(tooltipOptions.customizeText) && utils.isDefined(tooltipOptions.customizeText)) {
  57244. that._incidentOccured("E2103", ['customizeText']);
  57245. tooltipOptions.customizeText = undefined
  57246. }
  57247. if (that.tooltip)
  57248. that.tooltip.update(tooltipOptions);
  57249. else
  57250. that.tooltip = core.CoreFactory.createTooltip(tooltipOptions, that._tooltipGroup, that.renderer);
  57251. that.tracker.setTooltip(that.tooltip);
  57252. if (point) {
  57253. tooltipCoords = point.getTooltipCoords();
  57254. that.tooltip.move(~~tooltipCoords.x, ~~tooltipCoords.y, tooltipCoords.offset);
  57255. that.tooltip.show()
  57256. }
  57257. },
  57258. _prepareDrawOptions: function(drawOptions) {
  57259. var animationOptions = this._getAnimationOptions(),
  57260. options;
  57261. options = $.extend({}, {
  57262. force: false,
  57263. adjustAxes: true,
  57264. drawLegend: true,
  57265. drawTitle: true,
  57266. adjustSeriesLabels: true,
  57267. animate: animationOptions.enabled,
  57268. animationPointsLimit: animationOptions.maxPointCountSupported,
  57269. asyncSeriesRendering: animationOptions.asyncSeriesRendering,
  57270. asyncTrackersRendering: animationOptions.asyncTrackersRendering,
  57271. trackerRenderingDelay: animationOptions.trackerRenderingDelay
  57272. }, drawOptions);
  57273. if (!utils.isDefined(options.recreateCanvas))
  57274. options.recreateCanvas = options.adjustAxes && options.drawLegend && options.drawTitle;
  57275. return options
  57276. },
  57277. _processRefreshData: function(newRefreshAction) {
  57278. var currentRefreshActionPosition = $.inArray(this._currentRefreshData, ACTIONS_BY_PRIORITY),
  57279. newRefreshActionPosition = $.inArray(newRefreshAction, ACTIONS_BY_PRIORITY);
  57280. if (!this._currentRefreshData || currentRefreshActionPosition >= 0 && newRefreshActionPosition < currentRefreshActionPosition)
  57281. this._currentRefreshData = newRefreshAction
  57282. },
  57283. _disposeSeries: function() {
  57284. var that = this;
  57285. that.tracker._clean();
  57286. $.each(that.series || [], function(_, series) {
  57287. series.dispose()
  57288. });
  57289. that.series = null;
  57290. $.each(that.seriesFamilies || [], function(_, family) {
  57291. family.dispose()
  57292. });
  57293. that.seriesFamilies = null
  57294. },
  57295. _optionChanged: function(name) {
  57296. var that = this,
  57297. themeManager = this.themeManager;
  57298. themeManager.resetOptions(name);
  57299. themeManager.update(that._options);
  57300. if (name === 'animation') {
  57301. that.renderer.updateAnimationOptions(this._getAnimationOptions());
  57302. return
  57303. }
  57304. clearTimeout(that.delayedRedraw);
  57305. switch (name) {
  57306. case'dataSource':
  57307. that._needHandleRenderComplete = true;
  57308. that._processRefreshData('_reinitDataSource');
  57309. break;
  57310. case'palette':
  57311. that.themeManager.updatePalette(this.option(name));
  57312. that._disposeSeries();
  57313. that._needHandleRenderComplete = true;
  57314. that._processRefreshData('_handleDataSourceChanged');
  57315. break;
  57316. case'series':
  57317. case'commonSeriesSettings':
  57318. case'containerBackgroundColor':
  57319. case'dataPrepareSettings':
  57320. that._disposeSeries();
  57321. that._needHandleRenderComplete = true;
  57322. that._processRefreshData('_handleDataSourceChanged');
  57323. break;
  57324. case'legend':
  57325. case'seriesTemplate':
  57326. that._processRefreshData('_handleDataSourceChanged');
  57327. break;
  57328. case'title':
  57329. that._processRefreshData('force_render');
  57330. break;
  57331. case'valueAxis':
  57332. case'argumentAxis':
  57333. case'commonAxisSettings':
  57334. that._needHandleRenderComplete = true;
  57335. that._processRefreshData('reinit');
  57336. that._disposeSeries();
  57337. that.paneAxis = {};
  57338. break;
  57339. case'panes':
  57340. case'defaultPane':
  57341. that._disposeSeries();
  57342. that.paneAxis = {};
  57343. that._needHandleRenderComplete = true;
  57344. that._processRefreshData('reinit');
  57345. break;
  57346. case'size':
  57347. that._processRefreshData('force_render');
  57348. break;
  57349. case'rotated':
  57350. case'equalBarWidth':
  57351. case'customizePoint':
  57352. case'customizeLabel':
  57353. that._disposeSeries();
  57354. that._needHandleRenderComplete = true;
  57355. that._processRefreshData('reinit');
  57356. break;
  57357. case'theme':
  57358. that._disposeSeries();
  57359. themeManager.setTheme(that.option(name));
  57360. that._processRefreshData('reinit');
  57361. break;
  57362. default:
  57363. that._processRefreshData('reinit')
  57364. }
  57365. that.callBase.apply(that, arguments)
  57366. },
  57367. _getLoadIndicatorOption: function() {
  57368. return this.themeManager.getOptions("loadingIndicator")
  57369. },
  57370. _refresh: function() {
  57371. var that = this;
  57372. this.renderer.stopAllAnimations(true);
  57373. if (that._currentRefreshData) {
  57374. switch (that._currentRefreshData) {
  57375. case'force_render':
  57376. that._render({force: true});
  57377. break;
  57378. case'reinit':
  57379. that._reinit(true);
  57380. break;
  57381. default:
  57382. that[that._currentRefreshData] && that[that._currentRefreshData]()
  57383. }
  57384. delete that._currentRefreshData
  57385. }
  57386. else
  57387. that._render({force: true})
  57388. },
  57389. _dataSourceOptions: function() {
  57390. return {
  57391. paginate: false,
  57392. _preferSync: true
  57393. }
  57394. },
  57395. _updateCanvasClipRect: function(canvas) {
  57396. var that = this,
  57397. width,
  57398. height;
  57399. canvas = canvas || that.canvas;
  57400. width = Math.max(canvas.width - canvas.left - canvas.right, 0);
  57401. height = Math.max(canvas.height - canvas.top - canvas.bottom, 0);
  57402. that.canvasClipRect.updateRectangle({
  57403. x: canvas.left,
  57404. y: canvas.top,
  57405. width: width,
  57406. height: height
  57407. });
  57408. that.canvasClipRect.append()
  57409. },
  57410. _getCanvasClipRectID: function() {
  57411. return this.canvasClipRect.id
  57412. },
  57413. _handleDataSourceChanged: function() {
  57414. clearTimeout(this.delayedRedraw);
  57415. this._dataSpecificInit(true)
  57416. },
  57417. _groupSeries: function() {
  57418. this._groupedSeries = [this.series]
  57419. },
  57420. _dataSpecificInit: function(needRedraw) {
  57421. this._initSeries();
  57422. this._repopulateSeries();
  57423. this._handleSeriesPopulated(needRedraw)
  57424. },
  57425. _processSingleSeries: function(){},
  57426. _repopulateSeries: function() {
  57427. var that = this,
  57428. parsedData,
  57429. data = that._dataSource && that._dataSource.items(),
  57430. dataValidatorOptions = that.themeManager.getOptions('dataPrepareSettings'),
  57431. seriesTemplate = that.themeManager.getOptions('seriesTemplate');
  57432. if (that._dataSource && seriesTemplate) {
  57433. that._templatedSeries = utils.processSeriesTemplate(seriesTemplate, that._dataSource.items());
  57434. that._populateSeries();
  57435. delete that._templatedSeries;
  57436. data = that.teamplateData || data
  57437. }
  57438. that._groupSeries();
  57439. that._dataValidator = charts.factory.createDataValidator(data, that._groupedSeries, that._incidentOccured, dataValidatorOptions);
  57440. parsedData = that._dataValidator.validate();
  57441. that.themeManager.resetPalette();
  57442. $.each(that.series, function(_, singleSeries) {
  57443. singleSeries.updateData(parsedData);
  57444. that._processSingleSeries(singleSeries)
  57445. })
  57446. },
  57447. _handleRenderComplete: function() {
  57448. var that = this,
  57449. userHandle = this.option('done'),
  57450. allSeriesInited = true;
  57451. if (that._needHandleRenderComplete) {
  57452. $.each(that.series, function(_, s) {
  57453. allSeriesInited = allSeriesInited && s.canRenderCompleteHandle()
  57454. });
  57455. if (allSeriesInited) {
  57456. that._needHandleRenderComplete = false;
  57457. $.isFunction(userHandle) && userHandle.call(that)
  57458. }
  57459. }
  57460. },
  57461. _renderTitleAndLegend: function(drawOptions, legendHasInsidePosition) {
  57462. var that = this,
  57463. titleOptions = that.themeManager.getOptions("title"),
  57464. drawTitle = titleOptions.text && drawOptions.drawTitle,
  57465. drawLegend = drawOptions.drawLegend && that.legend && !legendHasInsidePosition,
  57466. drawElements = [];
  57467. if (drawTitle) {
  57468. that._titleGroup.append();
  57469. that._drawTitle();
  57470. drawElements.push(that.chartTitle)
  57471. }
  57472. if (drawLegend) {
  57473. that._legendGroup.append();
  57474. drawElements.push(that.legend)
  57475. }
  57476. drawElements.length && that.layoutManager.drawElements(drawElements, that.canvas);
  57477. if (drawTitle)
  57478. that.layoutManager.correctSizeElement(that.chartTitle, that.canvas)
  57479. },
  57480. getAllSeries: function getAllSeries() {
  57481. return this.series.slice()
  57482. },
  57483. getSeriesByName: function getSeriesByName(name) {
  57484. var found = null;
  57485. $.each(this.series, function(i, singleSeries) {
  57486. if (singleSeries.name === name) {
  57487. found = singleSeries;
  57488. return false
  57489. }
  57490. });
  57491. return found
  57492. },
  57493. getSeriesByPos: function getSeriesByPos(pos) {
  57494. return this.series[pos]
  57495. },
  57496. getSelectedSeries: function getSelectedSeries() {
  57497. return null
  57498. },
  57499. clearSelection: function clearSelection() {
  57500. this.tracker.clearSelection()
  57501. },
  57502. hideTooltip: function() {
  57503. this.tracker._hideTooltip()
  57504. },
  57505. showLoadingIndicator: function() {
  57506. this._showLoadIndicator(this.themeManager.getOptions("loadingIndicator"), this.canvas || {})
  57507. },
  57508. render: function(renderOptions) {
  57509. this._render(renderOptions)
  57510. },
  57511. getSize: function() {
  57512. var canvas = this.canvas || {};
  57513. return {
  57514. width: canvas.width,
  57515. height: canvas.height
  57516. }
  57517. }
  57518. }).include(ui.DataHelperMixin)
  57519. })(jQuery, DevExpress);
  57520. /*! Module viz-charts, file chart.js */
  57521. (function($, DX, undefined) {
  57522. var core = DX.viz.core,
  57523. charts = DX.viz.charts,
  57524. utils = DX.utils,
  57525. MAX_ADJUSTMENT_ATTEMPTS = 5,
  57526. DEFAULT_PANE_NAME = 'default',
  57527. DEFAULT_AXIS_NAME = 'defaultAxisName',
  57528. DEFAULT_BUSINESS_RANGE_VALUE_MARGIN = 0.1,
  57529. ASYNC_SERIES_RENDERING_DELAY = 25,
  57530. _each = $.each;
  57531. function prepareAxis(axisOptions) {
  57532. return $.isArray(axisOptions) ? axisOptions.length === 0 ? [{}] : axisOptions : [axisOptions]
  57533. }
  57534. charts.Chart = charts.BaseChart.inherit({
  57535. _setDefaultOptions: function() {
  57536. this.callBase();
  57537. this.option({
  57538. defaultPane: DEFAULT_PANE_NAME,
  57539. panes: [{
  57540. name: DEFAULT_PANE_NAME,
  57541. border: {}
  57542. }]
  57543. })
  57544. },
  57545. _dispose: function() {
  57546. var that = this,
  57547. disposeObjectsInArray = this._disposeObjectsInArray;
  57548. that.callBase();
  57549. that.panes = null;
  57550. that.legend && (that.legend.dispose(), that.legend = null);
  57551. disposeObjectsInArray.call(that, "panesBackground");
  57552. disposeObjectsInArray.call(that, "panesClipRects");
  57553. disposeObjectsInArray.call(that, "financialPanesClipRects");
  57554. disposeObjectsInArray.call(that, "_argumentAxes");
  57555. disposeObjectsInArray.call(that, "_valueAxes");
  57556. disposeObjectsInArray.call(that, "seriesFamilies");
  57557. _each(that._paneTrackerGroups || [], function(_, groups) {
  57558. groups.paneSeriesGroup.dispose();
  57559. groups.paneMarkerGroup.dispose()
  57560. });
  57561. that._paneTrackerGroups = null
  57562. },
  57563. _init: function() {
  57564. this.__ASYNC_SERIES_RENDERING_DELAY = ASYNC_SERIES_RENDERING_DELAY;
  57565. this.paneAxis = {};
  57566. this._crossHairOptions = {};
  57567. this.callBase()
  57568. },
  57569. _reinit: function(needRedraw) {
  57570. var that = this;
  57571. that.translators = {};
  57572. that.panes = that._createPanes();
  57573. that._populateAxes();
  57574. that.callBase();
  57575. delete that._seriesInitializing;
  57576. if (!that.series)
  57577. that._dataSpecificInit();
  57578. else
  57579. that._correctValueAxes();
  57580. that._endLoading(function() {
  57581. needRedraw && that._render({force: true})
  57582. })
  57583. },
  57584. _correctBusinessRange: function(range, tickInterval, setTicksAtUnitBeginning) {
  57585. var min = 'min',
  57586. max = 'max';
  57587. if (!tickInterval || !utils.isDefined(range[min]) || !utils.isDefined(range[max]))
  57588. return false;
  57589. var tickIntervalRange = {},
  57590. originInterval = tickInterval;
  57591. tickInterval = $.isNumeric(tickInterval) ? tickInterval : utils.convertDateTickIntervalToMilliseconds(tickInterval);
  57592. if (tickInterval >= Math.abs(range[max] - range[min])) {
  57593. if (utils.isDate(range[min])) {
  57594. if (!$.isNumeric(originInterval)) {
  57595. tickIntervalRange[min] = utils.addInterval(range[min], originInterval, true);
  57596. tickIntervalRange[max] = utils.addInterval(range[max], originInterval, false)
  57597. }
  57598. else {
  57599. tickIntervalRange[min] = new Date(range[min].valueOf() - tickInterval);
  57600. tickIntervalRange[max] = new Date(range[max].valueOf() + tickInterval)
  57601. }
  57602. if (setTicksAtUnitBeginning) {
  57603. utils.correctDateWithUnitBeginning(tickIntervalRange[max], originInterval);
  57604. utils.correctDateWithUnitBeginning(tickIntervalRange[min], originInterval)
  57605. }
  57606. }
  57607. else {
  57608. tickIntervalRange[min] = range[min] - tickInterval;
  57609. tickIntervalRange[max] = range[max] + tickInterval
  57610. }
  57611. range.addRange(tickIntervalRange);
  57612. return true
  57613. }
  57614. return false
  57615. },
  57616. _seriesVisibilityChanged: function() {
  57617. this._processSeriesFamilies();
  57618. this._populateBusinessRange();
  57619. this.renderer.stopAllAnimations(true);
  57620. this._render({
  57621. force: true,
  57622. asyncSeriesRendering: false,
  57623. asyncTrackersRendering: false
  57624. })
  57625. },
  57626. _populateBusinessRange: function(visibleArea) {
  57627. var that = this,
  57628. businessRanges = [],
  57629. aggregationRange,
  57630. minBound,
  57631. maxBound,
  57632. i,
  57633. themeManager = that.themeManager,
  57634. rotated = themeManager.getOptions('rotated'),
  57635. singleSeriesRange,
  57636. valAxes = that._valueAxes,
  57637. valueAxes = {},
  57638. argAxes = that._argumentAxes,
  57639. useAggregation = themeManager.getOptions('useAggregation'),
  57640. argumentTickInterval,
  57641. setTicksAtUnitBeginning,
  57642. paneAxis = that.paneAxis,
  57643. groupedSeries = that._groupedSeries;
  57644. that._disposeObjectsInArray("businessRanges", ["arg", "val"]);
  57645. var argRange = new core.Range({
  57646. rotated: !!rotated,
  57647. minValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN,
  57648. maxValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN
  57649. });
  57650. _each(valAxes, function(_, axis) {
  57651. valueAxes[axis.name] = axis
  57652. });
  57653. _each(paneAxis, function(paneName, pane) {
  57654. _each(pane, function(axisName, _) {
  57655. var seriesForRange = [],
  57656. firstSeriesForRange,
  57657. options,
  57658. valueAxesForRange,
  57659. valRange = new core.Range({
  57660. isValueRange: true,
  57661. rotated: !!rotated,
  57662. pane: paneName,
  57663. axis: axisName,
  57664. minValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN,
  57665. maxValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN
  57666. }),
  57667. valueType,
  57668. calcInterval;
  57669. _each(groupedSeries, function(_, particularSeriesGroup) {
  57670. if (particularSeriesGroup[0].pane === paneName && particularSeriesGroup[0].axis === axisName)
  57671. seriesForRange = particularSeriesGroup
  57672. });
  57673. _each(valAxes, function(_, axis) {
  57674. if (axis.pane === paneName && axis.name === axisName) {
  57675. valueAxesForRange = axis;
  57676. return false
  57677. }
  57678. });
  57679. firstSeriesForRange = seriesForRange && seriesForRange.length ? seriesForRange[0] : {};
  57680. _each(argAxes, function(_, axis) {
  57681. var options = axis.options;
  57682. options.type = firstSeriesForRange.argumentAxisType || options.type;
  57683. options.argumentType = firstSeriesForRange.argumentType || options.argumentType;
  57684. axis.validate(true, that._incidentOccured);
  57685. argRange = argRange.addRange(axis.getRangeData());
  57686. argumentTickInterval = options.tickInterval;
  57687. setTicksAtUnitBeginning = options.setTicksAtUnitBeginning;
  57688. calcInterval = axis.calcInterval
  57689. });
  57690. options = valueAxesForRange.options;
  57691. options.type = firstSeriesForRange.valueAxisType || options.type;
  57692. options.valueType = firstSeriesForRange.valueType || options.valueType;
  57693. valueAxesForRange.validate(false, that._incidentOccured);
  57694. var axisRange = new core.Range(valueAxesForRange.getRangeData());
  57695. valueType = valueType || options.valueType === 'datetime' ? 'datetime' : undefined;
  57696. valRange = valRange.addRange(axisRange);
  57697. minBound = valRange.min;
  57698. maxBound = valRange.max;
  57699. for (i = 0; i < seriesForRange.length; i++) {
  57700. if (visibleArea) {
  57701. visibleArea.minVal = minBound;
  57702. visibleArea.maxVal = maxBound;
  57703. if (useAggregation && !visibleArea.adjustOnZoom) {
  57704. aggregationRange = seriesForRange[i]._originalBusinessRange;
  57705. visibleArea.minVal = utils.isDefined(visibleArea.minVal) ? visibleArea.minVal : aggregationRange.val.min;
  57706. visibleArea.maxVal = utils.isDefined(visibleArea.maxVal) ? visibleArea.maxVal : aggregationRange.val.max
  57707. }
  57708. }
  57709. singleSeriesRange = seriesForRange[i].getRangeData(visibleArea, calcInterval);
  57710. valRange = valRange.addRange(singleSeriesRange.val);
  57711. argRange = argRange.addRange(singleSeriesRange.arg)
  57712. }
  57713. if (!valRange.isDefined())
  57714. valRange.setStubData(valueType);
  57715. businessRanges.push({val: valRange})
  57716. })
  57717. });
  57718. if (!argRange.isDefined())
  57719. argRange.setStubData(argAxes[0].options.argumentType);
  57720. var bussinesRangeCorrectedWithTickInterval = that._correctBusinessRange(argRange, argumentTickInterval, setTicksAtUnitBeginning);
  57721. !bussinesRangeCorrectedWithTickInterval && argRange.applyValueMargins();
  57722. _each(businessRanges, function(_, item) {
  57723. var range = item.val,
  57724. vAxis = valueAxes[range.axis];
  57725. range.applyValueMargins();
  57726. if (vAxis && vAxis.options.showZero)
  57727. range.correctValueZeroLevel();
  57728. item.arg = argRange
  57729. });
  57730. that.businessRanges = businessRanges
  57731. },
  57732. _groupSeries: function() {
  57733. var that = this,
  57734. panes = that.panes,
  57735. valAxes = that._valueAxes,
  57736. paneList = $.map(panes, function(pane) {
  57737. return pane.name
  57738. }),
  57739. series = that.series,
  57740. paneAxis = that.paneAxis,
  57741. groupedSeries = that._groupedSeries = [];
  57742. var getFirstAxisNameForPane = function(axes, paneName) {
  57743. var result;
  57744. for (var i = 0; i < axes.length; i++)
  57745. if (axes[i].pane === paneName) {
  57746. result = axes[i].name;
  57747. break
  57748. }
  57749. if (!result)
  57750. result = valAxes[0].name;
  57751. return result
  57752. };
  57753. _each(series, function(i, particularSeries) {
  57754. particularSeries.axis = particularSeries.axis || getFirstAxisNameForPane(valAxes, particularSeries.pane);
  57755. if (particularSeries.axis) {
  57756. paneAxis[particularSeries.pane] = paneAxis[particularSeries.pane] || {};
  57757. paneAxis[particularSeries.pane][particularSeries.axis] = true
  57758. }
  57759. });
  57760. _each(valAxes, function(_, axis) {
  57761. if (axis.name && axis.pane && $.inArray(axis.pane, paneList) != -1) {
  57762. paneAxis[axis.pane] = paneAxis[axis.pane] || {};
  57763. paneAxis[axis.pane][axis.name] = true
  57764. }
  57765. });
  57766. that._correctValueAxes();
  57767. var hideGridsOnNonFirstValueAxisForPane = function(paneName) {
  57768. var axesForPane = [],
  57769. firstShownAxis;
  57770. _each(valAxes, function(_, axis) {
  57771. if (axis.pane === paneName)
  57772. axesForPane.push(axis)
  57773. });
  57774. if (axesForPane.length > 1 && that.themeManager.getOptions('synchronizeMultiAxes'))
  57775. _each(axesForPane, function(_, axis) {
  57776. var gridOpt = axis.options.grid;
  57777. if (firstShownAxis && gridOpt && gridOpt.visible)
  57778. gridOpt.visible = false;
  57779. else
  57780. firstShownAxis = firstShownAxis ? firstShownAxis : gridOpt && gridOpt.visible
  57781. })
  57782. };
  57783. _each(paneAxis, function(paneName, pane) {
  57784. hideGridsOnNonFirstValueAxisForPane(paneName);
  57785. _each(pane, function(axisName, _) {
  57786. var group = [];
  57787. _each(series, function(_, particularSeries) {
  57788. if (particularSeries.pane === paneName && particularSeries.axis === axisName)
  57789. group.push(particularSeries)
  57790. });
  57791. group.length && groupedSeries.push(group)
  57792. })
  57793. })
  57794. },
  57795. _cleanPanesClipRects: function(clipArrayName) {
  57796. var that = this,
  57797. clipArray = that[clipArrayName];
  57798. _each(clipArray || [], function(_, clipRect) {
  57799. clipRect && clipRect.remove()
  57800. });
  57801. that[clipArrayName] = []
  57802. },
  57803. _createPanes: function() {
  57804. var that = this,
  57805. panes = that.option('panes'),
  57806. panesNameCounter = 0,
  57807. bottomPaneName;
  57808. if (panes && utils.isArray(panes) && !panes.length || $.isEmptyObject(panes))
  57809. panes = that.initialOption("panes");
  57810. that._cleanPanesClipRects('panesClipRects');
  57811. that._cleanPanesClipRects('financialPanesClipRects');
  57812. that.defaultPane = that.option('defaultPane');
  57813. panes = $.isArray(panes) ? panes : panes ? [panes] : [];
  57814. _each(panes, function(_, pane) {
  57815. pane.name = !utils.isDefined(pane.name) ? DEFAULT_PANE_NAME + panesNameCounter++ : pane.name
  57816. });
  57817. if (!that._doesPaneExists(panes, that.defaultPane) && panes.length > 0) {
  57818. bottomPaneName = panes[panes.length - 1].name;
  57819. that._incidentOccured('W2101', [that.defaultPane, bottomPaneName]);
  57820. that.defaultPane = bottomPaneName
  57821. }
  57822. panes = that.themeManager.getOptions('rotated') ? panes.reverse() : panes;
  57823. return panes
  57824. },
  57825. _doesPaneExists: function(panes, paneName) {
  57826. var found = false;
  57827. _each(panes, function(_, pane) {
  57828. if (pane.name === paneName) {
  57829. found = true;
  57830. return false
  57831. }
  57832. });
  57833. return found
  57834. },
  57835. _populateSeries: function() {
  57836. var that = this,
  57837. themeManager = that.themeManager,
  57838. hasSeriesTemplate = !!themeManager.getOptions('seriesTemplate'),
  57839. series = hasSeriesTemplate ? that._templatedSeries : that.option('series'),
  57840. allSeriesOptions = $.isArray(series) ? series : series ? [series] : [],
  57841. argumentAxisOptions = that.option('argumentAxis'),
  57842. valueAxisOptions = that.option('valueAxis'),
  57843. data,
  57844. particularSeriesOptions,
  57845. particularSeries,
  57846. rotated = themeManager.getOptions('rotated'),
  57847. i,
  57848. paneList = $.map(that.panes, function(pane) {
  57849. return pane.name
  57850. }),
  57851. paneName,
  57852. paneIndex;
  57853. that.teamplateData = [];
  57854. _each(that._paneTrackerGroups || [], function(_, groups) {
  57855. groups.paneSeriesGroup.remove();
  57856. groups.paneMarkerGroup.remove()
  57857. });
  57858. that._paneTrackerGroups = [];
  57859. _each(that.panes, function(_, pane) {
  57860. var paneSeriesTrackerGroup = that.renderer.createGroup({'class': 'dxc-pane-tracker'}),
  57861. paneMarkerTrackerGroup = that.renderer.createGroup({'class': 'dxc-pane-tracker'});
  57862. that._paneTrackerGroups.push({
  57863. paneSeriesGroup: paneSeriesTrackerGroup,
  57864. paneMarkerGroup: paneMarkerTrackerGroup
  57865. })
  57866. });
  57867. that._disposeSeries();
  57868. that.series = [];
  57869. themeManager.resetPalette();
  57870. for (i = 0; i < allSeriesOptions.length; i++) {
  57871. particularSeriesOptions = $.extend(true, {}, allSeriesOptions[i]);
  57872. if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))
  57873. particularSeriesOptions.type = '';
  57874. data = particularSeriesOptions.data;
  57875. particularSeriesOptions.data = null;
  57876. particularSeriesOptions.rotated = rotated;
  57877. particularSeriesOptions.customizePoint = themeManager.getOptions("customizePoint");
  57878. particularSeriesOptions.customizeLabel = themeManager.getOptions("customizeLabel");
  57879. particularSeriesOptions.visibilityChanged = $.proxy(this._seriesVisibilityChanged, this);
  57880. particularSeriesOptions.resolveLabelsOverlapping = themeManager.getOptions("resolveLabelsOverlapping");
  57881. if (argumentAxisOptions) {
  57882. particularSeriesOptions.argumentCategories = argumentAxisOptions.categories;
  57883. particularSeriesOptions.argumentAxisType = argumentAxisOptions.type;
  57884. particularSeriesOptions.argumentType = argumentAxisOptions.argumentType
  57885. }
  57886. if (valueAxisOptions)
  57887. if (utils.isArray(valueAxisOptions))
  57888. _each(valueAxisOptions, function(iter, options) {
  57889. if (!particularSeriesOptions.axis && !iter || particularSeriesOptions.axis === options.name) {
  57890. particularSeriesOptions.valueCategories = options.categories;
  57891. particularSeriesOptions.valueAxisType = options.type;
  57892. particularSeriesOptions.valueType = options.valueType;
  57893. particularSeriesOptions.showZero = options.showZero
  57894. }
  57895. });
  57896. else {
  57897. particularSeriesOptions.valueCategories = valueAxisOptions.categories;
  57898. particularSeriesOptions.valueAxisType = valueAxisOptions.type;
  57899. particularSeriesOptions.valueType = valueAxisOptions.valueType;
  57900. particularSeriesOptions.showZero = valueAxisOptions.showZero
  57901. }
  57902. particularSeriesOptions.incidentOccured = that._incidentOccured;
  57903. if (!particularSeriesOptions.name)
  57904. particularSeriesOptions.name = 'Series ' + (i + 1).toString();
  57905. var seriesTheme = themeManager.getOptions("series", particularSeriesOptions);
  57906. seriesTheme.pane = seriesTheme.pane || that.defaultPane;
  57907. paneName = seriesTheme.pane;
  57908. paneIndex = that._getPaneIndex(paneName);
  57909. if ($.inArray(paneName, paneList) === -1)
  57910. continue;
  57911. seriesTheme.seriesGroup = that._seriesGroup;
  57912. seriesTheme.labelsGroup = that._labelsGroup;
  57913. seriesTheme.trackersGroup = that._paneTrackerGroups[paneIndex].paneSeriesGroup;
  57914. seriesTheme.markerTrackerGroup = that._paneTrackerGroups[paneIndex].paneMarkerGroup;
  57915. particularSeries = core.CoreFactory.createSeries(that.renderer, seriesTheme);
  57916. if (!particularSeries.isUpdated)
  57917. that._incidentOccured("E2101", [seriesTheme.type]);
  57918. else {
  57919. particularSeries.index = i;
  57920. that.series.push(particularSeries)
  57921. }
  57922. if (hasSeriesTemplate) {
  57923. _each(data, function(_, data) {
  57924. _each(particularSeries.getTeamplatedFields(), function(_, field) {
  57925. data[field.teamplateField] = data[field.originalField]
  57926. });
  57927. that.teamplateData.push(data)
  57928. });
  57929. particularSeries.updateTeamplateFieldNames()
  57930. }
  57931. }
  57932. return that.series
  57933. },
  57934. _createValueAxis: function(axisOptions, rotated, tickProvider) {
  57935. var that = this,
  57936. axis;
  57937. axisOptions = that.themeManager.getOptions("valueAxis", $.extend({
  57938. isHorizontal: rotated,
  57939. tickProvider: tickProvider,
  57940. incidentOccured: that._incidentOccured
  57941. }, axisOptions), rotated);
  57942. if (axisOptions.strips)
  57943. _each(axisOptions.strips, function(i, strips) {
  57944. axisOptions.strips[i] = $.extend(true, {}, axisOptions.stripStyle, axisOptions.strips[i])
  57945. });
  57946. if (axisOptions.constantLines)
  57947. _each(axisOptions.constantLines, function(i, line) {
  57948. axisOptions.constantLines[i] = $.extend(true, {}, axisOptions.constantLineStyle, line)
  57949. });
  57950. axis = charts.factory.createAxis(that.renderer, axisOptions);
  57951. axis.name = axisOptions.name;
  57952. axis.pane = axis.pane || axisOptions.pane;
  57953. axis.priority = axisOptions.priority;
  57954. return axis
  57955. },
  57956. _disposeAxes: function() {
  57957. var that = this;
  57958. _each(that._valueAxes || [], function(_, axis) {
  57959. axis.dispose()
  57960. });
  57961. _each(that._argumentAxes || [], function(_, axis) {
  57962. axis.dispose()
  57963. });
  57964. that._valueAxes = null;
  57965. that._argumentAxes = null
  57966. },
  57967. _populateAxes: function() {
  57968. var that = this,
  57969. valueAxes = [],
  57970. argumentAxes = [],
  57971. panes = that.panes,
  57972. themeManager = that.themeManager,
  57973. rotated = themeManager.getOptions('rotated'),
  57974. valueAxisOptions = that.option('valueAxis') || {},
  57975. argumentOption = that.option('argumentAxis') || {},
  57976. argumentAxesOptions = prepareAxis(argumentOption),
  57977. valueAxesOptions = prepareAxis(valueAxisOptions),
  57978. axis,
  57979. axisNames = [],
  57980. tickProvider = core.CoreFactory.getTickProvider(),
  57981. paneWithNonVirtualAxis;
  57982. that._disposeAxes();
  57983. var createArgumentAxis = function(axisOptions, virtual) {
  57984. axisOptions = that.themeManager.getOptions("argumentAxis", $.extend(true, {
  57985. isHorizontal: !rotated,
  57986. tickProvider: tickProvider,
  57987. pane: that.defaultPane,
  57988. incidentOccured: that._incidentOccured
  57989. }, axisOptions), rotated);
  57990. if (axisOptions.strips)
  57991. _each(axisOptions.strips, function(i, strips) {
  57992. axisOptions.strips[i] = $.extend(true, {}, axisOptions.stripStyle, axisOptions.strips[i])
  57993. });
  57994. if (axisOptions.constantLines)
  57995. _each(axisOptions.constantLines, function(i, line) {
  57996. axisOptions.constantLines[i] = $.extend(true, {}, axisOptions.constantLineStyle, line)
  57997. });
  57998. axis = charts.factory.createAxis(that.renderer, axisOptions);
  57999. axis._virtual = virtual;
  58000. argumentAxes.push(axis);
  58001. return axis
  58002. };
  58003. if (rotated)
  58004. paneWithNonVirtualAxis = argumentAxesOptions[0].position === 'right' ? panes[panes.length - 1].name : panes[0].name;
  58005. else
  58006. paneWithNonVirtualAxis = argumentAxesOptions[0].position === 'top' ? panes[0].name : panes[panes.length - 1].name;
  58007. _each(panes, function(_, pane) {
  58008. var paneName = pane.name,
  58009. virtual = paneName != paneWithNonVirtualAxis;
  58010. var axisOptions = $.extend(true, {}, argumentAxesOptions[0], {pane: paneName});
  58011. createArgumentAxis(axisOptions, virtual)
  58012. });
  58013. var valueAxesCounter = 0;
  58014. var getNextAxisName = function() {
  58015. return DEFAULT_AXIS_NAME + valueAxesCounter++
  58016. };
  58017. var unique = function(array) {
  58018. var values = {},
  58019. i,
  58020. len = array.length;
  58021. for (i = 0; i < len; i++)
  58022. values[array[i]] = true;
  58023. return $.map(values, function(_, key) {
  58024. return key
  58025. })
  58026. };
  58027. _each(valueAxesOptions, function(priority, axisOptions) {
  58028. var axisPanes = [],
  58029. name = axisOptions.name;
  58030. if (name && $.inArray(name, axisNames) != -1) {
  58031. that._incidentOccured("E2102");
  58032. return
  58033. }
  58034. name && axisNames.push(name);
  58035. if (axisOptions.pane)
  58036. axisPanes.push(axisOptions.pane);
  58037. if (axisOptions.panes && axisOptions.panes.length)
  58038. axisPanes = axisPanes.concat(axisOptions.panes.slice(0));
  58039. axisPanes = unique(axisPanes);
  58040. if (!axisPanes.length)
  58041. axisPanes.push(undefined);
  58042. _each(axisPanes, function(_, pane) {
  58043. valueAxes.push(that._createValueAxis($.extend(true, {}, axisOptions, {
  58044. name: name || getNextAxisName(),
  58045. pane: pane,
  58046. priority: priority
  58047. }), rotated, tickProvider))
  58048. })
  58049. });
  58050. that._valueAxes = valueAxes;
  58051. that._argumentAxes = argumentAxes
  58052. },
  58053. _correctValueAxes: function() {
  58054. var that = this,
  58055. rotated = that.themeManager.getOptions('rotated'),
  58056. valueAxisOptions = that.option('valueAxis') || {},
  58057. valueAxesOptions = $.isArray(valueAxisOptions) ? valueAxisOptions : [valueAxisOptions],
  58058. tickProvider = core.CoreFactory.getTickProvider(),
  58059. valueAxes = that._valueAxes || [],
  58060. defaultAxisName = valueAxes[0].name,
  58061. paneAxis = that.paneAxis || {},
  58062. panes = that.panes,
  58063. i,
  58064. neededAxis = {};
  58065. var getPaneForAxis = function(axisNameWithoutPane) {
  58066. var result;
  58067. _each(that.paneAxis, function(paneName, pane) {
  58068. _each(pane, function(axisName, _) {
  58069. if (axisNameWithoutPane == axisName) {
  58070. result = paneName;
  58071. return false
  58072. }
  58073. })
  58074. });
  58075. return result
  58076. };
  58077. var axesWithoutPanes = $.map(valueAxes, function(axis) {
  58078. if (axis.pane)
  58079. return null;
  58080. return axis
  58081. });
  58082. _each(axesWithoutPanes, function(_, axis) {
  58083. axis.pane = getPaneForAxis(axis.name);
  58084. if (!axis.pane) {
  58085. axis.pane = that.defaultPane;
  58086. paneAxis[axis.pane] = paneAxis[axis.pane] || {};
  58087. paneAxis[axis.pane][axis.name] = true
  58088. }
  58089. axis.options.pane = axis.pane
  58090. });
  58091. for (i = 0; i < panes.length; i++)
  58092. if (!paneAxis[panes[i].name]) {
  58093. paneAxis[panes[i].name] = {};
  58094. paneAxis[panes[i].name][defaultAxisName] = true
  58095. }
  58096. var findAxisOptions = function(axisName) {
  58097. var result,
  58098. axInd;
  58099. for (axInd = 0; axInd < valueAxesOptions.length; axInd++)
  58100. if (valueAxesOptions[axInd].name == axisName) {
  58101. result = valueAxesOptions[axInd];
  58102. result.priority = axInd;
  58103. break
  58104. }
  58105. if (!result)
  58106. for (axInd = 0; axInd < valueAxes.length; axInd++)
  58107. if (valueAxes[axInd].name == axisName) {
  58108. result = valueAxes[axInd].options;
  58109. result.priority = valueAxes[axInd].priority;
  58110. break
  58111. }
  58112. if (!result) {
  58113. that._incidentOccured("W2102", [axisName]);
  58114. result = {
  58115. name: axisName,
  58116. priority: valueAxes.length
  58117. }
  58118. }
  58119. return result
  58120. };
  58121. var findAxis = function(paneName, axisName) {
  58122. var axis;
  58123. for (i = 0; i < valueAxes.length; i++) {
  58124. axis = valueAxes[i];
  58125. if (axis.name === axisName && axis.pane === paneName)
  58126. return axis
  58127. }
  58128. };
  58129. _each(that.paneAxis, function(paneName, axisNames) {
  58130. _each(axisNames, function(axisName, _) {
  58131. neededAxis[axisName + '-' + paneName] = true;
  58132. if (!findAxis(paneName, axisName)) {
  58133. var axisOptions = findAxisOptions(axisName);
  58134. if (axisOptions)
  58135. valueAxes.push(that._createValueAxis($.extend(true, {}, axisOptions, {
  58136. pane: paneName,
  58137. name: axisName
  58138. }), rotated, tickProvider))
  58139. }
  58140. })
  58141. });
  58142. valueAxes = $.grep(valueAxes, function(elem) {
  58143. return !!neededAxis[elem.name + '-' + elem.pane]
  58144. });
  58145. valueAxes.sort(function(a, b) {
  58146. return a.priority - b.priority
  58147. });
  58148. that._valueAxes = valueAxes
  58149. },
  58150. _processSeriesFamilies: function() {
  58151. var that = this,
  58152. types = [],
  58153. families = [],
  58154. paneSeries,
  58155. themeManager = that.themeManager,
  58156. rotated = themeManager.getOptions('rotated');
  58157. if (that.seriesFamilies && that.seriesFamilies.length) {
  58158. _each(that.seriesFamilies, function(_, family) {
  58159. family.adjustSeriesValues()
  58160. });
  58161. return
  58162. }
  58163. _each(that.series, function(_, item) {
  58164. if ($.inArray(item.type, types) === -1)
  58165. types.push(item.type)
  58166. });
  58167. _each(that.panes, function(_, pane) {
  58168. paneSeries = [];
  58169. _each(that.series, function(_, oneSeries) {
  58170. if (oneSeries.pane === pane.name)
  58171. paneSeries.push(oneSeries)
  58172. });
  58173. _each(types, function(_, type) {
  58174. var family = core.CoreFactory.createSeriesFamily({
  58175. type: type,
  58176. pane: pane.name,
  58177. rotated: rotated,
  58178. equalBarWidth: themeManager.getOptions('equalBarWidth'),
  58179. minBubbleSize: themeManager.getOptions('minBubbleSize'),
  58180. maxBubbleSize: themeManager.getOptions('maxBubbleSize')
  58181. });
  58182. family.add(paneSeries);
  58183. family.adjustSeriesValues();
  58184. families.push(family)
  58185. })
  58186. });
  58187. that.seriesFamilies = families
  58188. },
  58189. _createLegend: function() {
  58190. var that = this,
  58191. legendData = [],
  58192. legendOptions = that.themeManager.getOptions('legend');
  58193. legendData = $.map(that.series, function(seriesItem) {
  58194. if (seriesItem.getOptions().showInLegend)
  58195. return {
  58196. text: seriesItem.name,
  58197. color: seriesItem.getColor(),
  58198. id: seriesItem.index,
  58199. states: seriesItem.getLegendStyles()
  58200. }
  58201. });
  58202. legendOptions.containerBackgroundColor = that.themeManager.getOptions("containerBackgroundColor");
  58203. legendOptions._incidentOccured = that._incidentOccured;
  58204. if (that.legend)
  58205. that.legend.update(legendData, legendOptions);
  58206. else
  58207. that.legend = core.CoreFactory.createLegend(legendData, legendOptions, that.renderer, that._legendGroup)
  58208. },
  58209. _createTranslator: function(range, canvas, options) {
  58210. return core.CoreFactory.createTranslator2D(range, canvas, options)
  58211. },
  58212. _createPanesBorderOptions: function() {
  58213. var commonBorderOptions = this.themeManager.getOptions('commonPaneSettings').border,
  58214. panesBorderOptions = {};
  58215. _each(this.panes, function(_, pane) {
  58216. var borderOptions = $.extend(true, {}, commonBorderOptions, pane.border);
  58217. panesBorderOptions[pane.name] = borderOptions
  58218. });
  58219. return panesBorderOptions
  58220. },
  58221. _render: function(drawOptions) {
  58222. var that = this,
  58223. themeManager = that.themeManager,
  58224. rotated = themeManager.getOptions('rotated'),
  58225. i,
  58226. layoutManager = that.layoutManager,
  58227. panesBorderOptions = that._createPanesBorderOptions(),
  58228. needHideLoadIndicator,
  58229. legendHasInsidePosition = that.legend && that.legend.getPosition() === "inside";
  58230. var drawSeries = function drawSeries() {
  58231. var panes = that.panes,
  58232. hideLayoutLabels = that.layoutManager.needMoreSpaceForPanesCanvas(that.panes, rotated) && !that.themeManager.getOptions("adaptiveLayout").keepLabels,
  58233. stackPoints = {};
  58234. _each(that.seriesFamilies || [], function(_, seriesFamily) {
  58235. var tr = that._getTranslator(seriesFamily.pane) || {},
  58236. translators = {};
  58237. translators[rotated ? 'x' : 'y'] = tr.val;
  58238. translators[rotated ? 'y' : 'x'] = tr.arg;
  58239. seriesFamily.updateSeriesValues(translators);
  58240. seriesFamily.adjustSeriesDimensions(translators)
  58241. });
  58242. that._createCrossHairCursor();
  58243. function applyPaneClipRect(seriesOptions) {
  58244. var paneIndex = that._getPaneIndex(seriesOptions.pane);
  58245. seriesOptions.setClippingParams(seriesOptions.isFinancialSeries() ? that.financialPanesClipRects[paneIndex].id : that.panesClipRects[paneIndex].id, that._getPaneBorderVisibility(paneIndex))
  58246. }
  58247. function preparePointsForSharedTooltip(singleSeries, stackPoints) {
  58248. if (!themeManager.getOptions('tooltip').shared)
  58249. return;
  58250. var points = singleSeries.getPoints(),
  58251. stackName = singleSeries.getStackName();
  58252. _each(points, function(index, point) {
  58253. var argument = point.argument;
  58254. if (!stackPoints[argument]) {
  58255. stackPoints[argument] = {};
  58256. stackPoints[argument][null] = []
  58257. }
  58258. if (stackName && !DX.utils.isArray(stackPoints[argument][stackName])) {
  58259. stackPoints[argument][stackName] = [];
  58260. _each(stackPoints[argument][null], function(_, point) {
  58261. if (!point.stackName)
  58262. stackPoints[argument][stackName].push(point)
  58263. })
  58264. }
  58265. if (stackName) {
  58266. stackPoints[argument][stackName].push(point);
  58267. stackPoints[argument][null].push(point)
  58268. }
  58269. else
  58270. _each(stackPoints[argument], function(_, stack) {
  58271. stack.push(point)
  58272. });
  58273. point.stackPoints = stackPoints[argument][stackName];
  58274. point.stackName = stackName
  58275. })
  58276. }
  58277. _each(that.series, function(_, particularSeries) {
  58278. preparePointsForSharedTooltip(particularSeries, stackPoints);
  58279. applyPaneClipRect(particularSeries);
  58280. particularSeries.setAdjustSeriesLabels(drawOptions.adjustSeriesLabels);
  58281. var tr = that._getTranslator(particularSeries.pane, particularSeries.axis),
  58282. translators = {};
  58283. translators[rotated ? 'x' : 'y'] = tr.val;
  58284. translators[rotated ? 'y' : 'x'] = tr.arg;
  58285. particularSeries.draw(translators, drawOptions.animate && particularSeries.getPoints().length <= drawOptions.animationPointsLimit && that.renderer.animationEnabled(), hideLayoutLabels, that.legend && that.legend.getActionCallback(particularSeries))
  58286. });
  58287. that._trackerGroup.append();
  58288. if (drawOptions.drawLegend && that.legend && legendHasInsidePosition) {
  58289. var newCanvas = $.extend({}, panes[0].canvas),
  58290. layoutManager = charts.factory.createChartLayoutManager();
  58291. newCanvas.right = panes[panes.length - 1].canvas.right;
  58292. newCanvas.bottom = panes[panes.length - 1].canvas.bottom;
  58293. that._legendGroup.append();
  58294. that._tooltipGroup.append();
  58295. layoutManager.drawElements([that.legend], newCanvas);
  58296. layoutManager.placeDrawnElements(newCanvas)
  58297. }
  58298. needHideLoadIndicator && that.hideLoadingIndicator();
  58299. that._drawn();
  58300. var drawChartTrackers = function drawChartTrackers() {
  58301. var i;
  58302. for (i = 0; i < that.series.length; i++)
  58303. that.series[i].drawTrackers();
  58304. if (that.legend) {
  58305. that.legend.drawTrackers();
  58306. legendHasInsidePosition && that._legendGroup.append();
  58307. legendHasInsidePosition && that._tooltipGroup.append()
  58308. }
  58309. that.tracker._prepare();
  58310. _each(that._paneTrackerGroups, function(index, paneGroups) {
  58311. paneGroups.paneSeriesGroup.append(that._seriesTrackerGroup);
  58312. paneGroups.paneMarkerGroup.append(that._markerTrackerGroup)
  58313. });
  58314. that._handleRenderComplete()
  58315. };
  58316. that._createTooltip();
  58317. if (drawOptions.asyncTrackersRendering)
  58318. that.delayedRedraw = setTimeout(drawChartTrackers, drawOptions.trackerRenderingDelay);
  58319. else
  58320. drawChartTrackers()
  58321. };
  58322. drawOptions = that._prepareDrawOptions(drawOptions);
  58323. that.callBase(drawOptions);
  58324. if (that.stopRedraw) {
  58325. that.stopRedraw = false;
  58326. return
  58327. }
  58328. that._createPanesBackground();
  58329. that._stripsGroup.append();
  58330. that._axesGroup.append();
  58331. that._constantLinesGroup.append();
  58332. that._labelAxesGroup.append();
  58333. that._createTranslators(drawOptions);
  58334. that._options.useAggregation && _each(that.series, function(_, series) {
  58335. series._originalBusinessRange = series._originalBusinessRange || series.getRangeData();
  58336. var tr = that._getTranslator(series.pane, series.axis),
  58337. translators = {};
  58338. translators[rotated ? 'x' : 'y'] = tr.val;
  58339. translators[rotated ? 'y' : 'x'] = tr.arg;
  58340. series.resamplePoints(translators, that._zoomMinArg, that._zoomMaxArg)
  58341. });
  58342. if (utils.isDefined(that._zoomMinArg) || utils.isDefined(that._zoomMaxArg))
  58343. that._populateBusinessRange({
  58344. adjustOnZoom: themeManager.getOptions('adjustOnZoom'),
  58345. minArg: that._zoomMinArg,
  58346. maxArg: that._zoomMaxArg
  58347. });
  58348. if (that._options.useAggregation || utils.isDefined(that._zoomMinArg) || utils.isDefined(that._zoomMaxArg))
  58349. that._updateTranslators();
  58350. that._renderTitleAndLegend(drawOptions, legendHasInsidePosition);
  58351. if (drawOptions && drawOptions.recreateCanvas)
  58352. layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
  58353. that._drawAxes(panesBorderOptions, drawOptions);
  58354. if (layoutManager.needMoreSpaceForPanesCanvas(that.panes, rotated)) {
  58355. layoutManager.updateDrawnElements(that._argumentAxes, that._valueAxes, that.canvas, that.dirtyCanvas, that.panes, rotated);
  58356. if (that.chartTitle)
  58357. that.layoutManager.correctSizeElement(that.chartTitle, that.canvas);
  58358. that._updateCanvasClipRect(that.dirtyCanvas);
  58359. layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
  58360. that._drawAxes(panesBorderOptions, drawOptions, true)
  58361. }
  58362. layoutManager.placeDrawnElements(that.canvas);
  58363. that._drawPanesBorders(panesBorderOptions);
  58364. that._createClipRectsForPanes();
  58365. for (i = 0; i < that._argumentAxes.length; i++)
  58366. that._argumentAxes[i].applyClipRect(that._getElementsClipRectID(that._argumentAxes[i].pane));
  58367. for (i = 0; i < that._valueAxes.length; i++)
  58368. that._valueAxes[i].applyClipRect(that._getElementsClipRectID(that._valueAxes[i].pane));
  58369. that._fillPanesBackground();
  58370. that._seriesGroup.append();
  58371. that._labelsGroup.append();
  58372. that._crossHairCursorGroup.append();
  58373. that._legendGroup.append();
  58374. that._tooltipGroup.append();
  58375. needHideLoadIndicator = that._loadIndicator && that._loadIndicator.isShown && that._dataSource && that._dataSource.isLoaded() && !drawOptions.isResize;
  58376. if (drawOptions.asyncSeriesRendering)
  58377. that.delayedRedraw = setTimeout(drawSeries, ASYNC_SERIES_RENDERING_DELAY);
  58378. else
  58379. drawSeries()
  58380. },
  58381. _createTranslators: function(drawOptions) {
  58382. var that = this,
  58383. rotated = that.themeManager.getOptions("rotated"),
  58384. translators;
  58385. if (!drawOptions.recreateCanvas)
  58386. return;
  58387. that.translators = translators = {};
  58388. that.layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
  58389. _each(that.paneAxis, function(paneName, pane) {
  58390. translators[paneName] = translators[paneName] || {};
  58391. _each(pane, function(axisName, _) {
  58392. var translator = that._createTranslator(new core.Range(that._getBusinessRange(paneName, axisName).val), that._getCanvasForPane(paneName), rotated ? {direction: 'horizontal'} : {});
  58393. translator.pane = paneName;
  58394. translator.axis = axisName;
  58395. translators[paneName][axisName] = {val: translator}
  58396. })
  58397. });
  58398. _each(that._argumentAxes, function(_, axis) {
  58399. var translator = that._createTranslator(new core.Range(that._getBusinessRange(axis.pane).arg), that._getCanvasForPane(axis.pane), !rotated ? {direction: 'horizontal'} : {});
  58400. _each(translators[axis.pane], function(valAxis, paneAsixTran) {
  58401. paneAsixTran.arg = translator
  58402. })
  58403. })
  58404. },
  58405. _updateTranslators: function() {
  58406. var that = this;
  58407. _each(that.translators, function(pane, axisTrans) {
  58408. _each(axisTrans, function(axis, translator) {
  58409. translator.arg.updateBusinessRange(new core.Range(that._getBusinessRange(pane).arg));
  58410. delete translator.arg._originalBusinessRange;
  58411. translator.val.updateBusinessRange(new core.Range(that._getBusinessRange(pane, axis).val));
  58412. delete translator.val._originalBusinessRange
  58413. })
  58414. })
  58415. },
  58416. _reinitTranslators: function() {
  58417. var that = this;
  58418. _each(that._argumentAxes, function(_, axis) {
  58419. var translator = that._getTranslator(axis.pane);
  58420. if (translator) {
  58421. translator.arg.reinit();
  58422. axis.setRange(translator.arg.getBusinessRange());
  58423. axis.setTranslator(translator.arg, translator.val)
  58424. }
  58425. });
  58426. _each(that._valueAxes, function(_, axis) {
  58427. var translator = that._getTranslator(axis.pane, axis.name);
  58428. if (translator) {
  58429. translator.val.reinit();
  58430. axis.setRange(translator.val.getBusinessRange());
  58431. axis.setTranslator(translator.val, translator.arg)
  58432. }
  58433. })
  58434. },
  58435. _drawAxes: function(panesBorderOptions, drawOptions, adjustUnits) {
  58436. var that = this,
  58437. i = 0,
  58438. layoutManager = that.layoutManager,
  58439. rotated = that.themeManager.getOptions("rotated"),
  58440. translators = that.translators,
  58441. adjustmentCounter = 0,
  58442. synchronizeMultiAxes = that.themeManager.getOptions('synchronizeMultiAxes');
  58443. that._reinitTranslators();
  58444. do {
  58445. for (i = 0; i < that._argumentAxes.length; i++)
  58446. that._argumentAxes[i].resetTicks();
  58447. for (i = 0; i < that._valueAxes.length; i++)
  58448. that._valueAxes[i].resetTicks();
  58449. if (synchronizeMultiAxes)
  58450. charts.multiAxesSynchronizer.synchronize(that._valueAxes);
  58451. drawAxes(rotated ? that._valueAxes : that._argumentAxes);
  58452. layoutManager.requireAxesRedraw = false;
  58453. if (drawOptions.adjustAxes) {
  58454. layoutManager.applyHorizontalAxesLayout(rotated ? that._valueAxes : that._argumentAxes);
  58455. !layoutManager.stopDrawAxes && _each(translators, function(pane, axisTrans) {
  58456. _each(axisTrans, function(axis, translator) {
  58457. translator.arg.reinit();
  58458. translator.val.reinit()
  58459. })
  58460. })
  58461. }
  58462. drawAxes(rotated ? that._argumentAxes : that._valueAxes);
  58463. if (drawOptions.adjustAxes && !layoutManager.stopDrawAxes) {
  58464. layoutManager.applyVerticalAxesLayout(rotated ? that._argumentAxes : that._valueAxes);
  58465. !layoutManager.stopDrawAxes && _each(translators, function(pane, axisTrans) {
  58466. _each(axisTrans, function(axis, translator) {
  58467. translator.arg.reinit();
  58468. translator.val.reinit()
  58469. })
  58470. })
  58471. }
  58472. adjustmentCounter = adjustmentCounter + 1
  58473. } while (!layoutManager.stopDrawAxes && layoutManager.requireAxesRedraw && adjustmentCounter < MAX_ADJUSTMENT_ATTEMPTS);
  58474. that.__axisAdjustmentsCount = adjustmentCounter;
  58475. function drawAxes(axes) {
  58476. _each(axes, function(_, axis) {
  58477. axis.clipRectID = that._getCanvasClipRectID();
  58478. axis.stripsGroup = that._stripsGroup;
  58479. axis.labelAxesGroup = that._labelAxesGroup;
  58480. axis.constantLinesGroup = that._constantLinesGroup;
  58481. axis.axesContainerGroup = that._axesGroup;
  58482. axis.draw({borderOptions: panesBorderOptions[axis.pane]}, adjustUnits)
  58483. })
  58484. }
  58485. },
  58486. _createCrossHairCursor: function() {
  58487. var that = this,
  58488. renderer = that.renderer,
  58489. panes = that.panes,
  58490. commonCanvas,
  58491. canvas,
  58492. options = that.themeManager.getOptions('crosshair') || {},
  58493. hLine,
  58494. vLine,
  58495. attrHLine,
  58496. attrVLine,
  58497. i;
  58498. if (!options || !options.enabled)
  58499. return;
  58500. attrHLine = {
  58501. stroke: options.horizontalLine.color || options.color,
  58502. strokeWidth: options.horizontalLine.width || options.width,
  58503. dashStyle: options.horizontalLine.dashStyle || options.dashStyle,
  58504. visibility: 'hidden',
  58505. opacity: options.horizontalLine.opacity || options.opacity
  58506. };
  58507. attrVLine = {
  58508. stroke: options.verticalLine.color || options.color,
  58509. strokeWidth: options.verticalLine.width || options.width,
  58510. dashStyle: options.verticalLine.dashStyle || options.dashStyle,
  58511. visibility: 'hidden',
  58512. opacity: options.verticalLine.opacity || options.opacity
  58513. };
  58514. for (i = 0; i < panes.length; i++) {
  58515. canvas = panes[i].canvas;
  58516. if (!commonCanvas)
  58517. commonCanvas = $.extend({}, canvas);
  58518. else {
  58519. commonCanvas.right = canvas.right;
  58520. commonCanvas.bottom = canvas.bottom
  58521. }
  58522. renderer.createRect(canvas.left, canvas.top, canvas.width - canvas.right - canvas.left, canvas.height - canvas.bottom - canvas.top, 0).append(this._crosshairTrackerGroup)
  58523. }
  58524. if (options.horizontalLine && options.horizontalLine.visible)
  58525. hLine = renderer.createLine(commonCanvas.left, commonCanvas.top, commonCanvas.width - commonCanvas.right, commonCanvas.top, attrHLine).append(that._crossHairCursorGroup);
  58526. if (options.verticalLine && options.verticalLine.visible)
  58527. vLine = renderer.createLine(commonCanvas.left, commonCanvas.top, commonCanvas.left, commonCanvas.height - commonCanvas.bottom, attrVLine).append(that._crossHairCursorGroup);
  58528. that._crossHairOptions.horizontalLine = hLine;
  58529. that._crossHairOptions.verticalLine = vLine;
  58530. that._crossHairOptions.canvas = commonCanvas
  58531. },
  58532. _createPanesBackground: function() {
  58533. var that = this,
  58534. defaultBackgroundColor = that.themeManager.getOptions('commonPaneSettings').backgroundColor,
  58535. backgroundColor,
  58536. renderer = that.renderer,
  58537. rect,
  58538. i,
  58539. rects = [];
  58540. that._panesBackgroundGroup && that._panesBackgroundGroup.clear();
  58541. for (i = 0; i < that.panes.length; i++) {
  58542. backgroundColor = that.panes[i].backgroundColor || defaultBackgroundColor;
  58543. if (!backgroundColor || backgroundColor === 'none') {
  58544. rects.push(null);
  58545. continue
  58546. }
  58547. rect = renderer.createRect(0, 0, 0, 0, 0, {
  58548. fill: backgroundColor,
  58549. strokeWidth: 0
  58550. }).append(that._panesBackgroundGroup);
  58551. rects.push(rect)
  58552. }
  58553. that.panesBackground = rects;
  58554. that._panesBackgroundGroup.append()
  58555. },
  58556. _fillPanesBackground: function() {
  58557. var that = this,
  58558. bc;
  58559. _each(that.panes, function(i, pane) {
  58560. bc = pane.borderCoords;
  58561. if (that.panesBackground[i] != null)
  58562. that.panesBackground[i].applySettings({
  58563. x: bc.left,
  58564. y: bc.top,
  58565. width: bc.width,
  58566. height: bc.height
  58567. })
  58568. })
  58569. },
  58570. _calcPaneBorderCoords: function(pane, rotated) {
  58571. var canvas = pane.canvas,
  58572. bc = pane.borderCoords = pane.borderCoords || {};
  58573. bc.left = canvas.left;
  58574. bc.top = canvas.top;
  58575. bc.right = canvas.width - canvas.right;
  58576. bc.bottom = canvas.height - canvas.bottom;
  58577. bc.width = Math.max(bc.right - bc.left, 0);
  58578. bc.height = Math.max(bc.bottom - bc.top, 0)
  58579. },
  58580. _drawPanesBorders: function(panesBorderOptions) {
  58581. var that = this,
  58582. rotated = that.themeManager.getOptions('rotated');
  58583. that._panesBorderGroup && (that._panesBorderGroup.detach(), that._panesBorderGroup.clear());
  58584. _each(that.panes, function(i, pane) {
  58585. var bc,
  58586. borderOptions = panesBorderOptions[pane.name],
  58587. attr = {
  58588. fill: 'none',
  58589. stroke: borderOptions.color,
  58590. strokeOpacity: borderOptions.opacity,
  58591. strokeWidth: borderOptions.width,
  58592. dashStyle: borderOptions.dashStyle
  58593. };
  58594. that._calcPaneBorderCoords(pane, rotated);
  58595. if (!borderOptions.visible)
  58596. return;
  58597. bc = pane.borderCoords;
  58598. that.renderer.createSegmentRect(bc.left, bc.top, bc.width, bc.height, 0, borderOptions, attr).append(that._panesBorderGroup)
  58599. });
  58600. that._panesBorderGroup.append()
  58601. },
  58602. _createClipRect: function(clipArray, index, left, top, width, height) {
  58603. var that = this,
  58604. clipRect = clipArray[index];
  58605. if (!clipRect) {
  58606. clipRect = that.renderer.createClipRect(left, top, width, height);
  58607. clipArray[index] = clipRect
  58608. }
  58609. else
  58610. clipRect.updateRectangle({
  58611. x: left,
  58612. y: top,
  58613. width: width,
  58614. height: height
  58615. });
  58616. clipRect.append()
  58617. },
  58618. _createClipRectsForPanes: function() {
  58619. var that = this,
  58620. canvas = that.canvas;
  58621. _each(that.panes, function(i, pane) {
  58622. var hasFinancialSeries = false,
  58623. bc = pane.borderCoords,
  58624. left = bc.left,
  58625. top = bc.top,
  58626. width = bc.width,
  58627. height = bc.height;
  58628. that._createClipRect(that.panesClipRects, i, left, top, width, height);
  58629. _each(that.series, function(_, series) {
  58630. if (series.pane === pane.name && series.isFinancialSeries())
  58631. hasFinancialSeries = true
  58632. });
  58633. if (hasFinancialSeries) {
  58634. if (that.themeManager.getOptions('rotated')) {
  58635. top = 0;
  58636. height = canvas.height
  58637. }
  58638. else {
  58639. left = 0;
  58640. width = canvas.width
  58641. }
  58642. that._createClipRect(that.financialPanesClipRects, i, left, top, width, height)
  58643. }
  58644. else
  58645. that.financialPanesClipRects.push(null)
  58646. })
  58647. },
  58648. _getPaneIndex: function(paneName) {
  58649. var paneIndex;
  58650. _each(this.panes, function(index, pane) {
  58651. if (pane.name === paneName) {
  58652. paneIndex = index;
  58653. return false
  58654. }
  58655. });
  58656. return paneIndex
  58657. },
  58658. _getPaneBorderVisibility: function(paneIndex) {
  58659. var commonPaneBorderVisible = this.themeManager.getOptions('commonPaneSettings').border.visible,
  58660. pane = this.panes[paneIndex] || {},
  58661. paneBorder = pane.border || {};
  58662. return 'visible' in paneBorder ? paneBorder.visible : commonPaneBorderVisible
  58663. },
  58664. _getElementsClipRectID: function(paneName) {
  58665. return this.panesClipRects[this._getPaneIndex(paneName)].id
  58666. },
  58667. _getTranslator: function(paneName, axisName) {
  58668. var paneTrans = this.translators[paneName],
  58669. foundTranslator = null;
  58670. if (!paneTrans)
  58671. return foundTranslator;
  58672. foundTranslator = paneTrans[axisName];
  58673. if (!foundTranslator)
  58674. _each(paneTrans, function(axis, trans) {
  58675. foundTranslator = trans;
  58676. return false
  58677. });
  58678. return foundTranslator
  58679. },
  58680. _getCanvasForPane: function(paneName) {
  58681. var panes = this.panes,
  58682. panesNumber = panes.length,
  58683. i;
  58684. for (i = 0; i < panesNumber; i++)
  58685. if (panes[i].name === paneName)
  58686. return panes[i].canvas
  58687. },
  58688. _getBusinessRange: function(paneName, axisName) {
  58689. var ranges = this.businessRanges || [],
  58690. rangesNumber = ranges.length,
  58691. foundRange,
  58692. i;
  58693. for (i = 0; i < rangesNumber; i++)
  58694. if (ranges[i].val.pane === paneName && ranges[i].val.axis === axisName) {
  58695. foundRange = ranges[i];
  58696. break
  58697. }
  58698. if (!foundRange)
  58699. for (i = 0; i < rangesNumber; i++)
  58700. if (ranges[i].val.pane === paneName) {
  58701. foundRange = ranges[i];
  58702. break
  58703. }
  58704. return foundRange
  58705. },
  58706. _handleSeriesPopulated: function(needRedraw) {
  58707. var that = this;
  58708. that._processSeriesFamilies();
  58709. that._createLegend();
  58710. that._populateBusinessRange();
  58711. that._processValueAxisFormat();
  58712. that._updateTracker();
  58713. that._endLoading(function() {
  58714. needRedraw && that._render({force: true})
  58715. })
  58716. },
  58717. _processValueAxisFormat: function() {
  58718. var that = this,
  58719. valueAxes = that._valueAxes,
  58720. axesWithFullStackedFormat = [];
  58721. _each(that.series, function() {
  58722. if (this.isFullStackedSeries() && $.inArray(this.axis, axesWithFullStackedFormat) === -1)
  58723. axesWithFullStackedFormat.push(this.axis)
  58724. });
  58725. _each(valueAxes, function() {
  58726. if ($.inArray(this.name, axesWithFullStackedFormat) !== -1)
  58727. this.setPercentLabelFormat();
  58728. else
  58729. this.resetAutoLabelFormat()
  58730. })
  58731. },
  58732. zoomArgument: function(min, max) {
  58733. var that = this,
  58734. zoomArg = that._argumentAxes[0].adjustZoomValues(min, max);
  58735. that._zoomMinArg = zoomArg.min;
  58736. that._zoomMaxArg = zoomArg.max;
  58737. that._render({
  58738. force: true,
  58739. drawTitle: false,
  58740. drawLegend: false,
  58741. adjustAxes: false,
  58742. animate: false,
  58743. adjustSeriesLabels: false,
  58744. asyncSeriesRendering: false
  58745. })
  58746. }
  58747. })
  58748. })(jQuery, DevExpress);
  58749. /*! Module viz-charts, file pieChart.js */
  58750. (function($, DX, undefined) {
  58751. var core = DX.viz.core,
  58752. charts = DX.viz.charts,
  58753. utils = DX.utils;
  58754. charts.PieChart = charts.BaseChart.inherit({
  58755. _createThemeManager: function() {
  58756. return charts.factory.createThemeManager(this.option(), "pie")
  58757. },
  58758. _reinit: function(needRedraw) {
  58759. var that = this;
  58760. that.callBase();
  58761. if (!that.series)
  58762. that._dataSpecificInit();
  58763. that._endLoading(function() {
  58764. needRedraw && that._render({force: true})
  58765. })
  58766. },
  58767. _populateBusinessRange: function() {
  58768. var businessRanges = [],
  58769. series = this.series,
  58770. singleSeries = series[0],
  58771. range,
  58772. singleSeriesRange;
  58773. this._disposeObjectsInArray("businessRanges");
  58774. if (singleSeries) {
  58775. range = new core.Range({series: singleSeries});
  58776. singleSeriesRange = singleSeries.getRangeData();
  58777. range = range.addRange(singleSeriesRange.val);
  58778. if (!range.isDefined())
  58779. range.setStubData();
  58780. businessRanges.push(range)
  58781. }
  58782. this.businessRanges = businessRanges
  58783. },
  58784. _seriesVisibilytyChanged: function() {
  58785. this.series[0].arrangePoints();
  58786. this._populateBusinessRange();
  58787. this._refresh()
  58788. },
  58789. _createTranslator: function(range) {
  58790. return core.CoreFactory.createTranslator1D(range.min, range.max, 360, 0)
  58791. },
  58792. _populateSeries: function() {
  58793. var that = this,
  58794. renderer = that.renderer,
  58795. themeManager = that.themeManager,
  58796. hasSeriesTemplate = !!themeManager.getOptions("seriesTemplate"),
  58797. seriesOptions = hasSeriesTemplate ? that._templatedSeries : that.option("series"),
  58798. allSeriesOptions = $.isArray(seriesOptions) ? seriesOptions : seriesOptions ? [seriesOptions] : [],
  58799. data,
  58800. particularSeriesOptions,
  58801. particularSeries,
  58802. seriesTheme;
  58803. that._disposeSeries();
  58804. that.series = [];
  58805. themeManager.resetPalette();
  58806. if (allSeriesOptions.length) {
  58807. particularSeriesOptions = $.extend(true, {}, allSeriesOptions[0]);
  58808. if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))
  58809. particularSeriesOptions.type = "";
  58810. data = particularSeriesOptions.data;
  58811. particularSeriesOptions.data = null;
  58812. particularSeriesOptions.incidentOccured = that._incidentOccured;
  58813. seriesTheme = themeManager.getOptions("series", particularSeriesOptions, true);
  58814. seriesTheme.seriesGroup = that._seriesGroup;
  58815. seriesTheme.trackerGroup = that._trackerGroup;
  58816. seriesTheme.seriesLabelsGroup = that._labelsGroup;
  58817. seriesTheme.seriesTrackerGroup = that._seriesTrackerGroup;
  58818. seriesTheme.markerTrackerGroup = that._markerTrackerGroup;
  58819. seriesTheme.visibilityChanged = $.proxy(this._seriesVisibilytyChanged, this);
  58820. seriesTheme.customizePoint = themeManager.getOptions("customizePoint");
  58821. seriesTheme.customizeLabel = themeManager.getOptions("customizeLabel");
  58822. particularSeries = core.CoreFactory.createSeries(renderer, seriesTheme);
  58823. if (!particularSeries.isUpdated)
  58824. that._incidentOccured("E2101", [seriesTheme.type]);
  58825. else {
  58826. that._processSingleSeries(particularSeries);
  58827. that.series.push(particularSeries)
  58828. }
  58829. particularSeriesOptions.data = data
  58830. }
  58831. return that.series
  58832. },
  58833. _processSingleSeries: function(singleSeries) {
  58834. singleSeries.arrangePoints()
  58835. },
  58836. _handleSeriesPopulated: function(needRedraw) {
  58837. var that = this;
  58838. that._populateBusinessRange();
  58839. that._createLegend();
  58840. that._updateTracker();
  58841. that._endLoading(function() {
  58842. needRedraw && that._render({
  58843. force: true,
  58844. recreateCanvas: true
  58845. })
  58846. })
  58847. },
  58848. _createLegend: function() {
  58849. var that = this,
  58850. legendOptions = that.themeManager.getOptions("legend"),
  58851. data = $.map(that.series[0] ? that.series[0].getPoints() : [], function(item) {
  58852. return {
  58853. text: item.argument,
  58854. color: item.getColor(),
  58855. id: item.index,
  58856. states: item.getLegendStyles()
  58857. }
  58858. });
  58859. legendOptions._incidentOccured = that._incidentOccured;
  58860. that.legend = core.CoreFactory.createLegend(data, legendOptions, that.renderer, that._legendGroup)
  58861. },
  58862. _render: function(drawOptions) {
  58863. var that = this,
  58864. singleSeries = that.series && that.series[0],
  58865. layoutManager = that.layoutManager,
  58866. hideLayoutLabels;
  58867. drawOptions = that._prepareDrawOptions(drawOptions);
  58868. that.callBase(drawOptions);
  58869. if (that.stopRedraw) {
  58870. that.stopRedraw = false;
  58871. return
  58872. }
  58873. that._renderTitleAndLegend(drawOptions);
  58874. if (layoutManager.needMoreSpaceForPanesCanvas([that])) {
  58875. layoutManager.updateDrawnElements([], [], that.canvas, that.dirtyCanvas, [that]);
  58876. if (that.chartTitle)
  58877. that.layoutManager.correctSizeElement(that.chartTitle, that.canvas);
  58878. that._updateCanvasClipRect(that.dirtyCanvas)
  58879. }
  58880. layoutManager.placeDrawnElements(that.canvas);
  58881. if (singleSeries) {
  58882. hideLayoutLabels = layoutManager.needMoreSpaceForPanesCanvas([that]) && !that.themeManager.getOptions("adaptiveLayout").keepLabels;
  58883. layoutManager.applyPieChartSeriesLayout(that.canvas, singleSeries, true);
  58884. that._seriesGroup.append();
  58885. that._labelsGroup.append();
  58886. singleSeries.canvas = that.canvas;
  58887. singleSeries.resetLabelEllipsis();
  58888. singleSeries.draw(that._createTranslator(that.businessRanges[0], that.canvas), drawOptions.animate && that.renderer.animationEnabled(), hideLayoutLabels);
  58889. if (singleSeries.redraw) {
  58890. that.renderer.stopAllAnimations(true);
  58891. layoutManager.applyPieChartSeriesLayout(that.canvas, singleSeries, hideLayoutLabels);
  58892. singleSeries.draw(that._createTranslator(that.businessRanges[0], that.canvas), drawOptions.animate && that.renderer.animationEnabled(), hideLayoutLabels)
  58893. }
  58894. that._tooltipGroup.append();
  58895. that._trackerGroup.append();
  58896. that._createTooltip();
  58897. singleSeries.drawTrackers();
  58898. that.tracker._prepare("pieChart")
  58899. }
  58900. that._dataSource && that._dataSource.isLoaded() && !drawOptions.isResize && that.hideLoadingIndicator();
  58901. that._drawn();
  58902. that._handleRenderComplete()
  58903. },
  58904. getSeries: function getSeries() {
  58905. return this.series && this.series[0]
  58906. }
  58907. })
  58908. })(jQuery, DevExpress);
  58909. /*! Module viz-charts, file layoutManager.js */
  58910. (function($, DX, undefined) {
  58911. var isNumber = DX.utils.isNumber,
  58912. math = Math,
  58913. decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
  58914. CONNECTOR_MARGIN = 10,
  58915. round = math.round;
  58916. DX.viz.charts.LayoutManager = DX.Class.inherit(function() {
  58917. var ctor = function(options) {
  58918. this.verticalElements = [];
  58919. this.horizontalElements = [];
  58920. this._options = options
  58921. };
  58922. var update = function(chart) {
  58923. this.chart = chart;
  58924. setCanvasValues(chart && chart.canvas)
  58925. };
  58926. var dispose = function() {
  58927. this.chart = null
  58928. };
  58929. var setCanvasValues = function(canvas) {
  58930. if (canvas) {
  58931. canvas.originalTop = canvas.top;
  58932. canvas.originalBottom = canvas.bottom;
  58933. canvas.originalLeft = canvas.left;
  58934. canvas.originalRight = canvas.right
  58935. }
  58936. };
  58937. var placeElementAndCutCanvas = function(elements, canvas) {
  58938. $.each(elements, function(_, element) {
  58939. var shiftX,
  58940. shiftY,
  58941. options = element.getLayoutOptions(),
  58942. length = getLength(options.cutLayoutSide);
  58943. if (!options.width)
  58944. return;
  58945. switch (options.horizontalAlignment) {
  58946. case"left":
  58947. shiftX = canvas.left;
  58948. break;
  58949. case"center":
  58950. shiftX = (canvas.width - canvas.left - canvas.right - options.width) / 2 + canvas.left;
  58951. break;
  58952. case"right":
  58953. shiftX = canvas.width - canvas.right - options.width;
  58954. break
  58955. }
  58956. switch (options.verticalAlignment) {
  58957. case"top":
  58958. shiftY = canvas.top;
  58959. break;
  58960. case"bottom":
  58961. shiftY = canvas.height - canvas.bottom - options.height;
  58962. break
  58963. }
  58964. element.shift(round(shiftX), round(shiftY));
  58965. canvas[options.cutLayoutSide] += options[length];
  58966. setCanvasValues(canvas)
  58967. })
  58968. };
  58969. var drawElements = function(elements, canvas) {
  58970. var that = this,
  58971. verticalElements = that.verticalElements = [],
  58972. horizontalElements = that.horizontalElements = [];
  58973. $.each(elements, function(_, element) {
  58974. var freeHeight = canvas.height - canvas.top - canvas.bottom,
  58975. freeWidth = canvas.width - canvas.left - canvas.right,
  58976. options,
  58977. length,
  58978. arrayElements;
  58979. element.setSize({
  58980. height: freeHeight,
  58981. width: freeWidth
  58982. });
  58983. element.draw();
  58984. options = element.getLayoutOptions();
  58985. length = getLength(options.cutLayoutSide);
  58986. arrayElements = length === "width" ? horizontalElements : verticalElements;
  58987. arrayElements.push(element);
  58988. canvas[options.cutLayoutSide] += options[length];
  58989. setCanvasValues(canvas)
  58990. })
  58991. };
  58992. var getLength = function(side) {
  58993. var length = "height";
  58994. if (side === "left" || side === "right")
  58995. length = "width";
  58996. return length
  58997. };
  58998. var updatePanesCanvases = function(panes, canvas, rotated) {
  58999. var pane,
  59000. i,
  59001. paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,
  59002. paneSpaceWidth = canvas.width - canvas.left - canvas.right,
  59003. weightSum = 0,
  59004. padding = panes.padding || 10;
  59005. for (i = 0; i < panes.length; i++) {
  59006. pane = panes[i];
  59007. pane.weight = pane.weight || 1;
  59008. weightSum = weightSum + pane.weight
  59009. }
  59010. rotated ? createPanes(panes, paneSpaceWidth, "left", "right") : createPanes(panes, paneSpaceHeight, "top", "bottom");
  59011. function createPanes(panes, paneSpace, startName, endName) {
  59012. var distributedSpace = 0,
  59013. oneWeight = (paneSpace - padding * (panes.length - 1)) / weightSum;
  59014. $.each(panes, function(_, pane) {
  59015. var calcLength = round(pane.weight * oneWeight);
  59016. pane.canvas = pane.canvas || {};
  59017. $.extend(pane.canvas, {
  59018. deltaLeft: 0,
  59019. deltaRight: 0,
  59020. deltaTop: 0,
  59021. deltaBottom: 0
  59022. }, canvas);
  59023. pane.canvas[startName] = canvas[startName] + distributedSpace;
  59024. pane.canvas[endName] = canvas[endName] + (paneSpace - calcLength - distributedSpace);
  59025. distributedSpace = distributedSpace + calcLength + padding;
  59026. setCanvasValues(pane.canvas)
  59027. })
  59028. }
  59029. };
  59030. var applyPieChartSeriesLayout = function(canvas, singleSeries, hideLayoutLabels) {
  59031. var paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,
  59032. paneSpaceWidth = canvas.width - canvas.left - canvas.right,
  59033. paneCenterX = paneSpaceWidth / 2 + canvas.left,
  59034. paneCenterY = paneSpaceHeight / 2 + canvas.top,
  59035. accessibleRadius = Math.min(paneSpaceWidth, paneSpaceHeight) / 2,
  59036. minR = 0.7 * accessibleRadius,
  59037. innerRadius = getInnerRadius(singleSeries);
  59038. if (!hideLayoutLabels)
  59039. $.each(singleSeries.getPoints(), function(_, point) {
  59040. if (point._label.hasText() && point.isVisible()) {
  59041. var labelBBox = point._label._getOutsideGroupLabelPosition(),
  59042. nearestX = getNearestCoord(labelBBox.x, labelBBox.x + labelBBox.width, paneCenterX),
  59043. nearestY = getNearestCoord(labelBBox.y, labelBBox.y + labelBBox.height, paneCenterY),
  59044. minRadiusWithLabels = Math.max(getLengthFromCenter(nearestX, nearestY) - CONNECTOR_MARGIN, minR);
  59045. accessibleRadius = Math.min(accessibleRadius, minRadiusWithLabels)
  59046. }
  59047. point._label.setPosition(point._label.originalPosition)
  59048. });
  59049. else
  59050. $.each(singleSeries.getPoints(), function(_, point) {
  59051. if (singleSeries.getOptions().label.position === "inside")
  59052. return false;
  59053. point._label.originalPosition = point._label.getPosition();
  59054. point._label.setPosition('outside')
  59055. });
  59056. singleSeries.correctPosition({
  59057. centerX: math.floor(paneCenterX),
  59058. centerY: math.floor(paneCenterY),
  59059. radiusInner: math.floor(accessibleRadius * innerRadius),
  59060. radiusOuter: math.floor(accessibleRadius)
  59061. });
  59062. function getNearestCoord(firstCoord, secondCoord, pointCenterCoord) {
  59063. var nearestCoord;
  59064. if (pointCenterCoord < firstCoord)
  59065. nearestCoord = firstCoord;
  59066. else if (secondCoord < pointCenterCoord)
  59067. nearestCoord = secondCoord;
  59068. else
  59069. nearestCoord = pointCenterCoord;
  59070. return nearestCoord
  59071. }
  59072. function getLengthFromCenter(x, y) {
  59073. return Math.sqrt(Math.pow(x - paneCenterX, 2) + Math.pow(y - paneCenterY, 2))
  59074. }
  59075. function getInnerRadius(series) {
  59076. var innerRadius;
  59077. if (singleSeries.type === 'pie')
  59078. innerRadius = 0;
  59079. else {
  59080. innerRadius = singleSeries.innerRadius;
  59081. if (!isNumber(innerRadius))
  59082. innerRadius = 0.5;
  59083. else {
  59084. innerRadius = Number(innerRadius);
  59085. if (innerRadius < 0.2)
  59086. innerRadius = 0.2;
  59087. if (innerRadius > 0.8)
  59088. innerRadius = 0.8
  59089. }
  59090. }
  59091. return innerRadius
  59092. }
  59093. };
  59094. var isValidBox = function isValidBox(box) {
  59095. return !!(box.x || box.y || box.width || box.height)
  59096. };
  59097. var correctDeltaMarginValue = function(panes, marginSides) {
  59098. var axisPanePosition,
  59099. canvasCell,
  59100. canvas,
  59101. deltaSide,
  59102. requireAxesRedraw;
  59103. $.each(panes, function(_, pane) {
  59104. canvas = pane.canvas;
  59105. $.each(marginSides, function(_, side) {
  59106. deltaSide = 'delta' + side;
  59107. canvas[deltaSide] = Math.max(canvas[deltaSide] - (canvas[side.toLowerCase()] - canvas['original' + side]), 0);
  59108. if (canvas[deltaSide] > 0)
  59109. requireAxesRedraw = true
  59110. })
  59111. });
  59112. return requireAxesRedraw
  59113. };
  59114. var getPane = function getPane(name, panes) {
  59115. var findPane = panes[0];
  59116. $.each(panes, function(_, pane) {
  59117. if (name === pane.name)
  59118. findPane = pane
  59119. });
  59120. return findPane
  59121. };
  59122. var applyAxesLayout = function(axes, panes, rotated) {
  59123. var that = this,
  59124. canvas,
  59125. axisPanePosition,
  59126. axisPosition,
  59127. canvasCell,
  59128. box,
  59129. delta,
  59130. axis,
  59131. axisLength,
  59132. direction,
  59133. directionMultiplier,
  59134. someDirection = [],
  59135. pane,
  59136. i;
  59137. $.each(panes, function(_, pane) {
  59138. $.extend(pane.canvas, {
  59139. deltaLeft: 0,
  59140. deltaRight: 0,
  59141. deltaTop: 0,
  59142. deltaBottom: 0
  59143. })
  59144. });
  59145. for (i = 0; i < axes.length; i++) {
  59146. axis = axes[i];
  59147. axisPosition = axis.options.position || 'left';
  59148. axis.delta = {};
  59149. box = axis.getBoundingRect();
  59150. pane = getPane(axis.pane, panes);
  59151. canvas = pane.canvas;
  59152. if (!isValidBox(box))
  59153. continue;
  59154. direction = "delta" + axisPosition.slice(0, 1).toUpperCase() + axisPosition.slice(1);
  59155. switch (axisPosition) {
  59156. case"right":
  59157. directionMultiplier = 1;
  59158. canvas.deltaLeft += axis.padding ? axis.padding.left : 0;
  59159. break;
  59160. case"left":
  59161. directionMultiplier = -1;
  59162. canvas.deltaRight += axis.padding ? axis.padding.right : 0;
  59163. break;
  59164. case"top":
  59165. directionMultiplier = -1;
  59166. canvas.deltaBottom += axis.padding ? axis.padding.bottom : 0;
  59167. break;
  59168. case"bottom":
  59169. directionMultiplier = 1;
  59170. canvas.deltaTop += axis.padding ? axis.padding.top : 0;
  59171. break
  59172. }
  59173. switch (axisPosition) {
  59174. case"right":
  59175. case"left":
  59176. if (!box.isEmpty) {
  59177. delta = box.y + box.height - (canvas.height - canvas.originalBottom);
  59178. if (delta > 0) {
  59179. that.requireAxesRedraw = true;
  59180. canvas.deltaBottom += delta
  59181. }
  59182. delta = canvas.originalTop - box.y;
  59183. if (delta > 0) {
  59184. that.requireAxesRedraw = true;
  59185. canvas.deltaTop += delta
  59186. }
  59187. }
  59188. axisLength = box.width;
  59189. someDirection = ['Left', 'Right'];
  59190. break;
  59191. case"top":
  59192. case"bottom":
  59193. if (!box.isEmpty) {
  59194. delta = box.x + box.width - (canvas.width - canvas.originalRight);
  59195. if (delta > 0) {
  59196. that.requireAxesRedraw = true;
  59197. canvas.deltaRight += delta
  59198. }
  59199. delta = canvas.originalLeft - box.x;
  59200. if (delta > 0) {
  59201. that.requireAxesRedraw = true;
  59202. canvas.deltaLeft += delta
  59203. }
  59204. }
  59205. someDirection = ['Bottom', 'Top'];
  59206. axisLength = box.height;
  59207. break
  59208. }
  59209. if (!axis.delta[axisPosition] && canvas[direction] > 0)
  59210. canvas[direction] += axis.getMultipleAxesSpacing();
  59211. axis.delta[axisPosition] = axis.delta[axisPosition] || 0;
  59212. axis.delta[axisPosition] += canvas[direction] * directionMultiplier;
  59213. canvas[direction] += axisLength
  59214. }
  59215. that.requireAxesRedraw = correctDeltaMarginValue(panes, someDirection) || that.requireAxesRedraw;
  59216. this.stopDrawAxes = applyFoundExceedings(panes, rotated)
  59217. };
  59218. var applyVerticalAxesLayout = function(axes) {
  59219. var chart = this.chart;
  59220. this.applyAxesLayout(axes, chart.panes, chart.option('rotated'))
  59221. };
  59222. var applyHorizontalAxesLayout = function(axes) {
  59223. var chart = this.chart;
  59224. axes.reverse();
  59225. this.applyAxesLayout(axes, chart.panes, chart.option('rotated'));
  59226. axes.reverse()
  59227. };
  59228. var placeDrawnElements = function(canvas) {
  59229. var that = this,
  59230. horizontalElements = that.horizontalElements,
  59231. verticalElements = that.verticalElements;
  59232. correctElementsPosition(horizontalElements, 'width');
  59233. placeElementAndCutCanvas(horizontalElements, canvas);
  59234. correctElementsPosition(verticalElements, 'height');
  59235. placeElementAndCutCanvas(verticalElements, canvas);
  59236. function correctElementsPosition(elements, direction) {
  59237. $.each(elements, function(_, element) {
  59238. var options = element.getLayoutOptions(),
  59239. side = options.cutLayoutSide;
  59240. canvas[side] -= options[direction]
  59241. })
  59242. }
  59243. };
  59244. var needMoreSpaceForPanesCanvas = function(panes, rotated) {
  59245. var that = this,
  59246. needHorizontalSpace = 0,
  59247. needVerticalSpace = 0;
  59248. $.each(panes, function(_, pane) {
  59249. var paneCanvas = pane.canvas,
  59250. needPaneHorizonralSpace = that._options.width - (paneCanvas.width - paneCanvas.left - paneCanvas.right),
  59251. needPaneVerticalSpace = that._options.height - (paneCanvas.height - paneCanvas.top - paneCanvas.bottom);
  59252. if (rotated) {
  59253. needHorizontalSpace += needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0;
  59254. needVerticalSpace = Math.max(needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0, needVerticalSpace)
  59255. }
  59256. else {
  59257. needHorizontalSpace = Math.max(needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0, needHorizontalSpace);
  59258. needVerticalSpace += needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0
  59259. }
  59260. });
  59261. return needHorizontalSpace > 0 || needVerticalSpace > 0 ? {
  59262. width: needHorizontalSpace,
  59263. height: needVerticalSpace
  59264. } : false
  59265. };
  59266. var updateDrawnElements = function(argumentAxis, valueAxis, canvas, dirtyCanvas, panes, rotated) {
  59267. var that = this,
  59268. needRemoveSpace,
  59269. saveDirtyCanvas = $.extend({}, dirtyCanvas),
  59270. verticalAxes = rotated ? argumentAxis : valueAxis,
  59271. horizontalAxes = rotated ? valueAxis : argumentAxis;
  59272. needRemoveSpace = this.needMoreSpaceForPanesCanvas(panes, rotated);
  59273. if (!needRemoveSpace)
  59274. return;
  59275. needRemoveSpace.height = decreaseGaps(dirtyCanvas, ["top", "bottom"], needRemoveSpace.height);
  59276. needRemoveSpace.width = decreaseGaps(dirtyCanvas, ["left", "right"], needRemoveSpace.width);
  59277. canvas.top -= saveDirtyCanvas.top - dirtyCanvas.top;
  59278. canvas.bottom -= saveDirtyCanvas.bottom - dirtyCanvas.bottom;
  59279. canvas.left -= saveDirtyCanvas.left - dirtyCanvas.left;
  59280. canvas.right -= saveDirtyCanvas.right - dirtyCanvas.right;
  59281. updateElements(that.horizontalElements, "width", "height");
  59282. updateElements(that.verticalElements, "height", "width");
  59283. updateAxis(verticalAxes, "width");
  59284. updateAxis(horizontalAxes, "height");
  59285. function updateAxis(axes, side) {
  59286. if (axes && needRemoveSpace[side] > 0) {
  59287. $.each(axes, function(i, axis) {
  59288. var bbox = axis.getBoundingRect();
  59289. axis.updateSize();
  59290. needRemoveSpace[side] -= bbox[side] - axis.getBoundingRect()[side]
  59291. });
  59292. if (needRemoveSpace[side] > 0)
  59293. $.each(axes, function(_, axis) {
  59294. axis.updateSize(true)
  59295. })
  59296. }
  59297. }
  59298. function updateElements(elements, length, otherLength) {
  59299. $.each(elements, function(_, element) {
  59300. var options = element.getLayoutOptions(),
  59301. side = options.cutLayoutSide,
  59302. freeSpaceWidth = dirtyCanvas.width - dirtyCanvas.left - dirtyCanvas.right,
  59303. freeSpaceHeight = dirtyCanvas.height - dirtyCanvas.top - dirtyCanvas.bottom,
  59304. updateObject = {};
  59305. element.setSize({
  59306. width: freeSpaceWidth,
  59307. height: freeSpaceHeight
  59308. });
  59309. updateObject[otherLength] = 0;
  59310. updateObject[length] = needRemoveSpace[length];
  59311. element.changeSize(updateObject);
  59312. canvas[side] -= options[length] - element.getLayoutOptions()[length];
  59313. needRemoveSpace[length] -= options[length] - element.getLayoutOptions()[length]
  59314. })
  59315. }
  59316. };
  59317. var correctSizeElement = function(element, canvas) {
  59318. element.setSize({
  59319. width: canvas.width - canvas.right - canvas.left,
  59320. height: canvas.width - canvas.right - canvas.left
  59321. });
  59322. element.changeSize({
  59323. width: 0,
  59324. height: 0
  59325. })
  59326. };
  59327. var applyFoundExceedings = function applyFoundExceedings(panes, rotated) {
  59328. var col,
  59329. row,
  59330. stopDrawAxes,
  59331. maxLeft = 0,
  59332. maxRight = 0,
  59333. maxTop = 0,
  59334. maxBottom = 0,
  59335. maxColNumber = 0;
  59336. $.each(panes, function(_, pane) {
  59337. maxLeft = Math.max(maxLeft, pane.canvas.deltaLeft);
  59338. maxRight = Math.max(maxRight, pane.canvas.deltaRight);
  59339. maxTop = Math.max(maxTop, pane.canvas.deltaTop);
  59340. maxBottom = Math.max(maxBottom, pane.canvas.deltaBottom)
  59341. });
  59342. if (rotated)
  59343. $.each(panes, function(_, pane) {
  59344. pane.canvas.top += maxTop;
  59345. pane.canvas.bottom += maxBottom;
  59346. pane.canvas.right += pane.canvas.deltaRight;
  59347. pane.canvas.left += pane.canvas.deltaLeft
  59348. });
  59349. else
  59350. $.each(panes, function(_, pane) {
  59351. pane.canvas.top += pane.canvas.deltaTop;
  59352. pane.canvas.bottom += pane.canvas.deltaBottom;
  59353. pane.canvas.right += maxRight;
  59354. pane.canvas.left += maxLeft
  59355. });
  59356. $.each(panes, function(_, pane) {
  59357. if (pane.canvas.top + pane.canvas.bottom > pane.canvas.height)
  59358. stopDrawAxes = true;
  59359. if (pane.canvas.left + pane.canvas.right > pane.canvas.width)
  59360. stopDrawAxes = true
  59361. });
  59362. return stopDrawAxes
  59363. };
  59364. return {
  59365. ctor: ctor,
  59366. update: update,
  59367. drawElements: drawElements,
  59368. updatePanesCanvases: updatePanesCanvases,
  59369. applyVerticalAxesLayout: applyVerticalAxesLayout,
  59370. applyHorizontalAxesLayout: applyHorizontalAxesLayout,
  59371. applyAxesLayout: applyAxesLayout,
  59372. applyPieChartSeriesLayout: applyPieChartSeriesLayout,
  59373. dispose: dispose,
  59374. updateDrawnElements: updateDrawnElements,
  59375. placeDrawnElements: placeDrawnElements,
  59376. needMoreSpaceForPanesCanvas: needMoreSpaceForPanesCanvas,
  59377. correctSizeElement: correctSizeElement
  59378. }
  59379. }())
  59380. })(jQuery, DevExpress);
  59381. /*! Module viz-charts, file multiAxesSynchronizer.js */
  59382. (function($, DX, undefined) {
  59383. var Range = DX.viz.core.Range,
  59384. utils = DX.utils,
  59385. adjustValueUtils = utils.adjustValue,
  59386. applyPrecisionByMinDeltaUtils = utils.applyPrecisionByMinDelta,
  59387. isDefinedUtils = utils.isDefined,
  59388. math = Math,
  59389. mathFloor = math.floor,
  59390. mathMax = math.max,
  59391. _each = $.each,
  59392. MIN_RANGE_FOR_ADJUST_BOUNDS = 0.1;
  59393. var getValueAxesPerPanes = function(valueAxes) {
  59394. var result = {};
  59395. _each(valueAxes, function(_, axis) {
  59396. var pane = axis.pane;
  59397. if (!result[pane])
  59398. result[pane] = [];
  59399. result[pane].push(axis)
  59400. });
  59401. return result
  59402. };
  59403. var restoreOriginalBusinessRange = function(axis) {
  59404. var businessRange;
  59405. if (!axis.translator._originalBusinessRange)
  59406. axis.translator._originalBusinessRange = new Range(axis.translator.getBusinessRange());
  59407. else {
  59408. businessRange = new Range(axis.translator._originalBusinessRange);
  59409. axis.translator.updateBusinessRange(businessRange);
  59410. axis.setRange(businessRange)
  59411. }
  59412. };
  59413. var linearConvertor = {
  59414. transform: function(v, b) {
  59415. return utils.getLog(v, b)
  59416. },
  59417. addInterval: function(v, i) {
  59418. return v + i
  59419. },
  59420. getInterval: function(base, tickInterval) {
  59421. return tickInterval
  59422. },
  59423. adjustValue: mathFloor
  59424. };
  59425. var logConvertor = {
  59426. transform: function(v, b) {
  59427. return utils.raiseTo(v, b)
  59428. },
  59429. addInterval: function(v, i) {
  59430. return v * i
  59431. },
  59432. getInterval: function(base, tickInterval) {
  59433. return math.pow(base, tickInterval)
  59434. },
  59435. adjustValue: adjustValueUtils
  59436. };
  59437. var convertAxisInfo = function(axisInfo, convertor) {
  59438. if (!axisInfo.isLogarithmic)
  59439. return;
  59440. var base = axisInfo.logarithmicBase,
  59441. tickValues = axisInfo.tickValues,
  59442. tick,
  59443. ticks = [],
  59444. interval;
  59445. axisInfo.minValue = convertor.transform(axisInfo.minValue, base);
  59446. axisInfo.oldMinValue = convertor.transform(axisInfo.oldMinValue, base);
  59447. axisInfo.maxValue = convertor.transform(axisInfo.maxValue, base);
  59448. axisInfo.oldMaxValue = convertor.transform(axisInfo.oldMaxValue, base);
  59449. axisInfo.tickInterval = math.round(axisInfo.tickInterval);
  59450. if (axisInfo.tickInterval < 1)
  59451. axisInfo.tickInterval = 1;
  59452. interval = convertor.getInterval(base, axisInfo.tickInterval);
  59453. for (tick = convertor.adjustValue(convertor.transform(tickValues[0], base)); ticks.length < tickValues.length; tick = convertor.addInterval(tick, interval))
  59454. ticks.push(tick);
  59455. ticks.tickInterval = axisInfo.tickInterval;
  59456. axisInfo.tickValues = ticks
  59457. };
  59458. var populateAxesInfo = function(axes) {
  59459. return $.map(axes, function(axis) {
  59460. restoreOriginalBusinessRange(axis);
  59461. var tickValues = axis.getTickValues(),
  59462. options = axis.options,
  59463. minValue,
  59464. maxValue,
  59465. axisInfo = null,
  59466. businessRange,
  59467. tickInterval,
  59468. synchronizedValue;
  59469. if (tickValues && tickValues.length > 0 && utils.isNumber(tickValues[0]) && options.type !== 'discrete') {
  59470. tickInterval = tickValues.tickInterval;
  59471. businessRange = axis.translator.getBusinessRange();
  59472. minValue = businessRange.minVisible;
  59473. maxValue = businessRange.maxVisible;
  59474. synchronizedValue = options.synchronizedValue;
  59475. if (minValue === maxValue && isDefinedUtils(synchronizedValue)) {
  59476. minValue = tickValues[0] - 1;
  59477. maxValue = tickValues[0] + 1;
  59478. tickInterval = 1
  59479. }
  59480. axisInfo = {
  59481. axis: axis,
  59482. isLogarithmic: options.type === 'logarithmic',
  59483. logarithmicBase: businessRange.base,
  59484. tickValues: tickValues,
  59485. minValue: minValue,
  59486. oldMinValue: minValue,
  59487. maxValue: maxValue,
  59488. oldMaxValue: maxValue,
  59489. inverted: businessRange.invert,
  59490. tickInterval: tickInterval,
  59491. synchronizedValue: synchronizedValue
  59492. };
  59493. if (businessRange.stubData) {
  59494. axisInfo.stubData = true;
  59495. axisInfo.tickInterval = axisInfo.tickInterval || options.tickInterval;
  59496. axisInfo.isLogarithmic = false
  59497. }
  59498. convertAxisInfo(axisInfo, linearConvertor);
  59499. DX.utils.debug.assert(axisInfo.tickInterval !== undefined && axisInfo.tickInterval !== null, 'tickInterval was not provided')
  59500. }
  59501. return axisInfo
  59502. })
  59503. };
  59504. var updateTickValues = function(axesInfo) {
  59505. var maxTicksCount = 0;
  59506. _each(axesInfo, function(_, axisInfo) {
  59507. maxTicksCount = mathMax(maxTicksCount, axisInfo.tickValues.length)
  59508. });
  59509. _each(axesInfo, function(_, axisInfo) {
  59510. var ticksMultiplier,
  59511. ticksCount,
  59512. additionalStartTicksCount = 0,
  59513. synchronizedValue = axisInfo.synchronizedValue,
  59514. tickValues = axisInfo.tickValues,
  59515. tickInterval = axisInfo.tickInterval;
  59516. if (isDefinedUtils(synchronizedValue)) {
  59517. axisInfo.baseTickValue = axisInfo.invertedBaseTickValue = synchronizedValue;
  59518. axisInfo.tickValues = [axisInfo.baseTickValue]
  59519. }
  59520. else {
  59521. if (tickValues.length > 1 && tickInterval) {
  59522. ticksMultiplier = mathFloor((maxTicksCount + 1) / tickValues.length);
  59523. ticksCount = ticksMultiplier > 1 ? mathFloor((maxTicksCount + 1) / ticksMultiplier) : maxTicksCount;
  59524. additionalStartTicksCount = mathFloor((ticksCount - tickValues.length) / 2);
  59525. while (additionalStartTicksCount > 0 && tickValues[0] !== 0) {
  59526. tickValues.unshift(applyPrecisionByMinDeltaUtils(tickValues[0], tickInterval, tickValues[0] - tickInterval));
  59527. additionalStartTicksCount--
  59528. }
  59529. while (tickValues.length < ticksCount)
  59530. tickValues.push(applyPrecisionByMinDeltaUtils(tickValues[0], tickInterval, tickValues[tickValues.length - 1] + tickInterval));
  59531. axisInfo.tickInterval = tickInterval / ticksMultiplier
  59532. }
  59533. axisInfo.baseTickValue = tickValues[0];
  59534. axisInfo.invertedBaseTickValue = tickValues[tickValues.length - 1]
  59535. }
  59536. })
  59537. };
  59538. var getAxisRange = function(axisInfo) {
  59539. return axisInfo.maxValue - axisInfo.minValue || 1
  59540. };
  59541. var getMainAxisInfo = function(axesInfo) {
  59542. for (var i = 0; i < axesInfo.length; i++)
  59543. if (!axesInfo[i].stubData)
  59544. return axesInfo[i];
  59545. return null
  59546. };
  59547. var correctMinMaxValues = function(axesInfo) {
  59548. var mainAxisInfo = getMainAxisInfo(axesInfo),
  59549. mainAxisInfoTickInterval = mainAxisInfo.tickInterval;
  59550. _each(axesInfo, function(_, axisInfo) {
  59551. var scale,
  59552. move,
  59553. mainAxisBaseValueOffset,
  59554. valueFromAxisInfo;
  59555. if (axisInfo !== mainAxisInfo) {
  59556. if (mainAxisInfoTickInterval && axisInfo.tickInterval) {
  59557. if (axisInfo.stubData && isDefinedUtils(axisInfo.synchronizedValue)) {
  59558. axisInfo.oldMinValue = axisInfo.minValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.minValue) / mainAxisInfoTickInterval * axisInfo.tickInterval;
  59559. axisInfo.oldMaxValue = axisInfo.maxValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.maxValue) / mainAxisInfoTickInterval * axisInfo.tickInterval
  59560. }
  59561. scale = mainAxisInfoTickInterval / getAxisRange(mainAxisInfo) / axisInfo.tickInterval * getAxisRange(axisInfo);
  59562. axisInfo.maxValue = axisInfo.minValue + getAxisRange(axisInfo) / scale
  59563. }
  59564. if (mainAxisInfo.inverted && !axisInfo.inverted || !mainAxisInfo.inverted && axisInfo.inverted)
  59565. mainAxisBaseValueOffset = mainAxisInfo.maxValue - mainAxisInfo.invertedBaseTickValue;
  59566. else
  59567. mainAxisBaseValueOffset = mainAxisInfo.baseTickValue - mainAxisInfo.minValue;
  59568. valueFromAxisInfo = getAxisRange(axisInfo);
  59569. move = (mainAxisBaseValueOffset / getAxisRange(mainAxisInfo) - (axisInfo.baseTickValue - axisInfo.minValue) / valueFromAxisInfo) * valueFromAxisInfo;
  59570. axisInfo.minValue -= move;
  59571. axisInfo.maxValue -= move
  59572. }
  59573. })
  59574. };
  59575. var calculatePaddings = function(axesInfo) {
  59576. var minPadding,
  59577. maxPadding,
  59578. startPadding = 0,
  59579. endPadding = 0;
  59580. _each(axesInfo, function(_, axisInfo) {
  59581. var inverted = axisInfo.inverted;
  59582. minPadding = axisInfo.minValue > axisInfo.oldMinValue ? (axisInfo.minValue - axisInfo.oldMinValue) / getAxisRange(axisInfo) : 0;
  59583. maxPadding = axisInfo.maxValue < axisInfo.oldMaxValue ? (axisInfo.oldMaxValue - axisInfo.maxValue) / getAxisRange(axisInfo) : 0;
  59584. startPadding = mathMax(startPadding, inverted ? maxPadding : minPadding);
  59585. endPadding = mathMax(endPadding, inverted ? minPadding : maxPadding)
  59586. });
  59587. return {
  59588. start: startPadding,
  59589. end: endPadding
  59590. }
  59591. };
  59592. var correctMinMaxValuesByPaddings = function(axesInfo, paddings) {
  59593. _each(axesInfo, function(_, info) {
  59594. var range = getAxisRange(info),
  59595. inverted = info.inverted;
  59596. info.minValue -= paddings[inverted ? 'end' : 'start'] * range;
  59597. info.maxValue += paddings[inverted ? 'start' : 'end'] * range;
  59598. if (range > MIN_RANGE_FOR_ADJUST_BOUNDS) {
  59599. info.minValue = math.min(info.minValue, adjustValueUtils(info.minValue));
  59600. info.maxValue = mathMax(info.maxValue, adjustValueUtils(info.maxValue))
  59601. }
  59602. })
  59603. };
  59604. var updateTickValuesIfSyncronizedValueUsed = function(axesInfo) {
  59605. var hasSyncronizedValue = false;
  59606. _each(axesInfo, function(_, info) {
  59607. hasSyncronizedValue = hasSyncronizedValue || isDefinedUtils(info.synchronizedValue)
  59608. });
  59609. _each(axesInfo, function(_, info) {
  59610. var lastTickValue,
  59611. tickInterval = info.tickInterval,
  59612. tickValues = info.tickValues,
  59613. maxValue = info.maxValue,
  59614. minValue = info.minValue;
  59615. if (hasSyncronizedValue && tickInterval) {
  59616. while (tickValues[0] - tickInterval >= minValue)
  59617. tickValues.unshift(adjustValueUtils(tickValues[0] - tickInterval));
  59618. lastTickValue = tickValues[tickValues.length - 1];
  59619. while ((lastTickValue = lastTickValue + tickInterval) <= maxValue)
  59620. tickValues.push(utils.isExponential(lastTickValue) ? adjustValueUtils(lastTickValue) : utils.applyPrecisionByMinDelta(minValue, tickInterval, lastTickValue))
  59621. }
  59622. while (tickValues[0] < minValue)
  59623. tickValues.shift();
  59624. while (tickValues[tickValues.length - 1] > maxValue)
  59625. tickValues.pop()
  59626. })
  59627. };
  59628. var applyMinMaxValues = function(axesInfo) {
  59629. _each(axesInfo, function(_, info) {
  59630. var axis = info.axis,
  59631. range = axis.translator.getBusinessRange();
  59632. if (range.min === range.minVisible)
  59633. range.min = info.minValue;
  59634. if (range.max === range.maxVisible)
  59635. range.max = info.maxValue;
  59636. range.minVisible = info.minValue;
  59637. range.maxVisible = info.maxValue;
  59638. if (isDefinedUtils(info.stubData))
  59639. range.stubData = info.stubData;
  59640. if (range.min > range.minVisible)
  59641. range.min = range.minVisible;
  59642. if (range.max < range.maxVisible)
  59643. range.max = range.maxVisible;
  59644. axis.translator.updateBusinessRange(range);
  59645. axis.setRange(range);
  59646. axis.setTickValues(info.tickValues)
  59647. })
  59648. };
  59649. var correctAfterSynchronize = function(axesInfo) {
  59650. var invalidAxisInfo = [],
  59651. correctValue,
  59652. validAxisInfo;
  59653. _each(axesInfo, function(i, info) {
  59654. if (info.oldMaxValue - info.oldMinValue === 0)
  59655. invalidAxisInfo.push(info);
  59656. else if (!isDefinedUtils(correctValue) && !isDefinedUtils(info.synchronizedValue)) {
  59657. correctValue = math.abs((info.maxValue - info.minValue) / (info.tickValues[mathFloor(info.tickValues.length / 2)] || info.maxValue));
  59658. validAxisInfo = info
  59659. }
  59660. });
  59661. if (!isDefinedUtils(correctValue))
  59662. return;
  59663. _each(invalidAxisInfo, function(i, info) {
  59664. var firstTick = info.tickValues[0],
  59665. correctedTick = firstTick * correctValue,
  59666. tickValues = validAxisInfo.tickValues,
  59667. centralTick = tickValues[mathFloor(tickValues.length / 2)];
  59668. if (firstTick > 0) {
  59669. info.maxValue = correctedTick;
  59670. info.minValue = 0
  59671. }
  59672. else if (firstTick < 0) {
  59673. info.minValue = correctedTick;
  59674. info.maxValue = 0
  59675. }
  59676. else if (firstTick === 0) {
  59677. info.maxValue = validAxisInfo.maxValue - centralTick;
  59678. info.minValue = validAxisInfo.minValue - centralTick
  59679. }
  59680. })
  59681. };
  59682. DX.viz.charts.multiAxesSynchronizer = {synchronize: function(valueAxes) {
  59683. _each(getValueAxesPerPanes(valueAxes), function(_, axes) {
  59684. var axesInfo,
  59685. paddings;
  59686. if (axes.length > 1) {
  59687. axesInfo = populateAxesInfo(axes);
  59688. if (axesInfo.length === 0 || !getMainAxisInfo(axesInfo))
  59689. return;
  59690. updateTickValues(axesInfo);
  59691. correctMinMaxValues(axesInfo);
  59692. paddings = calculatePaddings(axesInfo);
  59693. correctMinMaxValuesByPaddings(axesInfo, paddings);
  59694. correctAfterSynchronize(axesInfo);
  59695. updateTickValuesIfSyncronizedValueUsed(axesInfo);
  59696. _each(axesInfo, function() {
  59697. convertAxisInfo(this, logConvertor)
  59698. });
  59699. applyMinMaxValues(axesInfo)
  59700. }
  59701. })
  59702. }}
  59703. })(jQuery, DevExpress);
  59704. /*! Module viz-charts, file tracker.js */
  59705. (function($, DX) {
  59706. var charts = DX.viz.charts,
  59707. eventsConsts = DX.viz.core.series.helpers.consts.events,
  59708. utils = DX.utils,
  59709. isFunction = utils.isFunction,
  59710. isDefined = utils.isDefined,
  59711. MULTIPLE_MODE = 'multiple',
  59712. SINGLE_MODE = 'single',
  59713. ALL_ARGUMENTS_POINTS_MODE = 'allargumentpoints',
  59714. ALL_SERIES_POINTS_MODE = 'allseriespoints',
  59715. msPointerEnabled = window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints || window.navigator.pointerEnabled && window.navigator.maxTouchPoints || null,
  59716. MOUSE_EVENT_LOCK_TIMEOUT = 1000,
  59717. CLICK_EVENT_LOCK_TIMEOUT = 600,
  59718. HOVER_START_DELAY = 100,
  59719. HOVER_HOLD_DELAY = 200,
  59720. TOOLTIP_HOLD_TIMEOUT = 400,
  59721. NONE_MODE = 'none';
  59722. var processMode = function(mode) {
  59723. return (mode + "").toLowerCase()
  59724. };
  59725. charts.Tracker = DX.Class.inherit({
  59726. ctor: function(options) {
  59727. this.__HOVER_HOLD_DELAY = HOVER_HOLD_DELAY;
  59728. this.__TOOLTIP_HOLD_TIMEOUT = TOOLTIP_HOLD_TIMEOUT;
  59729. this.__HOVER_START_DELAY = HOVER_START_DELAY;
  59730. var that = this,
  59731. events = options.events = options.events || {},
  59732. getEventHandler = function(func) {
  59733. return func && func.call ? function() {
  59734. var eventContext = this,
  59735. eventArgs = arguments;
  59736. setTimeout(function() {
  59737. func.apply(eventContext, eventArgs)
  59738. })
  59739. } : null
  59740. };
  59741. that._reinit(options);
  59742. that.pointSelectionMode = that._prepareMode(options.pointSelectionMode);
  59743. that.seriesSelectionMode = that._prepareMode(options.seriesSelectionMode);
  59744. that.hoverStartDelay = 0;
  59745. that.sensitivity = 7;
  59746. if (that.pointSelectionMode === MULTIPLE_MODE) {
  59747. that._releaseSelectedPoint = that._releaseSelectedPointMultiMode;
  59748. that.selectedPoint = []
  59749. }
  59750. else
  59751. that._releaseSelectedPoint = that._releaseSelectedPointSingleMode;
  59752. if (that.seriesSelectionMode === MULTIPLE_MODE) {
  59753. that._releaseSelectedSeries = that._releaseSelectedSeriesMultiMode;
  59754. that.selectedSeries = []
  59755. }
  59756. else
  59757. that._releaseSelectedSeries = that._releaseSelectedSeriesSingleMode;
  59758. that.tooltipEnabled = options.tooltipEnabled;
  59759. that.tooltipShown = options.tooltipShown;
  59760. that.tooltipHidden = options.tooltipHidden;
  59761. that.seriesClick = getEventHandler(events.seriesClick);
  59762. that.pointClick = getEventHandler(events.pointClick);
  59763. that.legendClick = getEventHandler(events.legendClick);
  59764. that.argumentAxisClick = getEventHandler(events.argumentAxisClick);
  59765. that.seriesHover = getEventHandler(events.seriesHover);
  59766. that.seriesSelected = getEventHandler(events.seriesSelected);
  59767. that.pointHover = getEventHandler(events.pointHover);
  59768. that.seriesSelectionChanged = getEventHandler(events.seriesSelectionChanged);
  59769. that.pointSelectionChanged = getEventHandler(events.pointSelectionChanged);
  59770. that.seriesHoverChanged = getEventHandler(events.seriesHoverChanged);
  59771. that.pointHoverChanged = getEventHandler(events.pointHoverChanged);
  59772. that.pointSelected = getEventHandler(events.pointSelected);
  59773. that.renderer = options.renderer;
  59774. that.seriesTrackerGroup = options.seriesTrackerGroup;
  59775. that.markerTrackerGroup = options.markerTrackerGroup;
  59776. that.seriesGroup = options.seriesGroup;
  59777. that.seriesGroup.on(eventsConsts.selectSeries, {tracker: that}, that._selectSeries);
  59778. that.seriesGroup.on(eventsConsts.deselectSeries, {tracker: that}, that._deselectSeries);
  59779. that.seriesGroup.on(eventsConsts.selectPoint, {tracker: that}, that._selectPoint);
  59780. that.seriesGroup.on(eventsConsts.deselectPoint, {tracker: that}, that._deselectPoint);
  59781. that.seriesGroup.on(eventsConsts.showPointTooltip, {tracker: that}, that._showPointTooltip);
  59782. that.seriesGroup.on(eventsConsts.hidePointTooltip, {tracker: that}, that._hidePointTooltip);
  59783. that.crossHairOptions = options.crossHairOptions
  59784. },
  59785. _clean: function() {
  59786. var that = this;
  59787. that.selectedPoint = that.pointSelectionMode === MULTIPLE_MODE ? [] : null;
  59788. that.selectedSeries = that.seriesSelectionMode === MULTIPLE_MODE ? [] : null;
  59789. that.hoveredPoint = null;
  59790. that.hoveredSeries = null;
  59791. that._hideTooltip(that.pointAtShownTooltip);
  59792. that._clearTimeouts()
  59793. },
  59794. _reinit: function(options) {
  59795. var that = this;
  59796. options = options || {};
  59797. if (that.storedSeries !== options.series) {
  59798. that.storedSeries = options.series || [];
  59799. that._clean()
  59800. }
  59801. else if (isDefined(that.storedSeries)) {
  59802. that._clearPointSelection();
  59803. that._clearHover(that);
  59804. that._clearTimeouts()
  59805. }
  59806. that.argumentAxis = options.argumentAxis || [];
  59807. that.legendGroup = options.legendGroup;
  59808. that.legendCallback = options.legendCallback || $.noop
  59809. },
  59810. _clearTimeouts: function() {
  59811. var that = this,
  59812. _clearTimeout = clearTimeout;
  59813. _clearTimeout(that.tooltipHoldTimeout);
  59814. _clearTimeout(that.cmpCoordTimeout);
  59815. _clearTimeout(that.hoverStartTimeOut);
  59816. _clearTimeout(that.hoverHoldTimeOut)
  59817. },
  59818. dispose: function() {
  59819. var that = this;
  59820. that._clearTimeouts();
  59821. clearTimeout(that.unlockMouseTimer);
  59822. clearTimeout(that.lockClickTimer);
  59823. $.each(that.argumentAxis, function(_, axis) {
  59824. axis._axisElementsGroup && axis._axisElementsGroup.off()
  59825. });
  59826. that.seriesTrackerGroup.off();
  59827. that.markerTrackerGroup.off();
  59828. that.legendGroup && that.legendGroup.off();
  59829. that.seriesGroup.off();
  59830. that.rootTracker && that.rootTracker.off();
  59831. that.argumentAxis = null;
  59832. that.seriesTrackerGroup = null;
  59833. that.markerTrackerGroup = null;
  59834. that.legendGroup = null;
  59835. that.legendCallback = null;
  59836. that.seriesGroup = null;
  59837. that.crossHairOptions = null;
  59838. that.selectedPoint = null;
  59839. that.selectedSeries = null;
  59840. that.hoveredSeries = null;
  59841. that.hoveredPoint = null;
  59842. that.storedSeries = null;
  59843. that.argumentAxis = null;
  59844. that.hoveredObject = null;
  59845. that.pointAtShownTooltip = null
  59846. },
  59847. _prepareMode: function(mode) {
  59848. mode = (mode || '').toLowerCase();
  59849. return mode = mode !== SINGLE_MODE && mode !== MULTIPLE_MODE ? SINGLE_MODE : mode
  59850. },
  59851. _prepare: function(typeChart) {
  59852. var that = this;
  59853. that.rootTracker = that.renderer.getRoot();
  59854. $.each(that.argumentAxis, function(_, axis) {
  59855. axis._axisElementsGroup && that._eventHandler(axis._axisElementsGroup, {
  59856. parser: that._getOptionsAxis,
  59857. condition: that._axisCondition,
  59858. execute: that._axisEvent
  59859. }, {
  59860. tracker: that,
  59861. axis: axis
  59862. })
  59863. });
  59864. that._eventHandler(that.seriesTrackerGroup, {
  59865. parser: that._getOptionsPointSeries,
  59866. condition: that._seriesCondition,
  59867. execute: that._seriesEvent
  59868. }, {tracker: that});
  59869. that._eventHandler(that.markerTrackerGroup, {
  59870. parser: that._getOptionsPointSeries,
  59871. condition: that._pointCondition,
  59872. execute: that._pointEvent
  59873. }, {tracker: that});
  59874. that.legendGroup && that._eventHandler(that.legendGroup, {
  59875. parser: that._getLegendData(typeChart),
  59876. condition: that._seriesCondition,
  59877. execute: that._getLegendEvent(typeChart)
  59878. }, {tracker: that});
  59879. that._eventHandler(that.rootTracker, {
  59880. parser: that._getOptionsCrossHair,
  59881. execute: that._crossHairEvent
  59882. }, {tracker: that})
  59883. },
  59884. _getLegendData: function(typeChart) {
  59885. return function(event) {
  59886. var target = $(event.target),
  59887. itemIndex = target.data('itemIndex'),
  59888. that = event.data.tracker,
  59889. mode = utils.isNumber(itemIndex) && target.data('mode');
  59890. if (event.type === 'mousemove')
  59891. return [that, event.pageX, event.pageY, event.offsetX, event.offsetY];
  59892. if (!utils.isNumber(itemIndex))
  59893. return null;
  59894. if (typeChart === 'pieChart')
  59895. return [that, that.storedSeries[0].getPoints()[itemIndex], mode, event];
  59896. else
  59897. return [that, that.storedSeries[itemIndex], mode, event]
  59898. }
  59899. },
  59900. _getLegendEvent: function(typeChart) {
  59901. var that = this,
  59902. legendEvent;
  59903. if (typeChart === 'pieChart')
  59904. legendEvent = $.extend({}, this._pointEvent, {
  59905. touchend: function(that, point, mode, event) {
  59906. if (!that.showHoldTooltip)
  59907. that._legendClick(that, point, true, event) || that._pointClick(that, point, true, event);
  59908. clearTimeout(that.tooltipHoldTimeout);
  59909. that._clickLock(that);
  59910. that._clearHover(that)
  59911. },
  59912. click: function(that, point, mode, event) {
  59913. that._legendClick(that, point, false, event) || that._pointClick(that, point, false, event)
  59914. }
  59915. });
  59916. else
  59917. legendEvent = $.extend({}, this._seriesEvent, {
  59918. click: function(that, series, mode, event) {
  59919. that._legendClick(that, series, false, event) || that._seriesClick(that, series, false, event)
  59920. },
  59921. touchend: function(that, series, mode, event) {
  59922. that._legendClick(that, series, true, event) || that._seriesClick(that, series, true, event);
  59923. that._clickLock(that)
  59924. }
  59925. });
  59926. this.__legendEvent = legendEvent;
  59927. return legendEvent
  59928. },
  59929. _eventHandler: function(group, handlers, data) {
  59930. var prepareHandlers = this._designerHandlers(handlers);
  59931. group.off(".dxc-tracker");
  59932. group.on(prepareHandlers, data)
  59933. },
  59934. _designerHandlers: function(handler) {
  59935. var handlers = {},
  59936. parser = handler.parser,
  59937. condition = handler.condition,
  59938. execute = handler.execute,
  59939. designerHandle = function(eventType, func) {
  59940. if (condition && condition[eventType] === null)
  59941. return;
  59942. handlers[eventType + ".dxc-tracker"] = function(event) {
  59943. var options = parser ? parser(event) : event;
  59944. if (!options)
  59945. return;
  59946. if (condition && condition[eventType] && condition[eventType].call)
  59947. condition[eventType].apply(null, options.concat([func]));
  59948. else
  59949. func.apply(null, options)
  59950. }
  59951. };
  59952. $.each(execute, designerHandle);
  59953. return handlers
  59954. },
  59955. _getOptionsCrossHair: function(event) {
  59956. var that = event.data.tracker;
  59957. var rootOffset = utils.getRootOffset(that.renderer);
  59958. var xe = event.pageX - rootOffset.left;
  59959. var ye = event.pageY - rootOffset.top;
  59960. return [that, xe, ye]
  59961. },
  59962. _getOptionsPointSeries: function(event) {
  59963. var object = $(event.target).data('point') || $(event.target).data('series'),
  59964. that = event.data.tracker,
  59965. mode = object && processMode($(event.target).data('mode') || object.getOptions().hoverMode);
  59966. if (event.type === 'mousemove')
  59967. return [that, event.pageX, event.pageY, event.offsetX, event.offsetY];
  59968. if (!object)
  59969. return null;
  59970. return [that, object, mode, event]
  59971. },
  59972. _getOptionsAxis: function(event) {
  59973. var that = event.data.tracker,
  59974. axis = event.data.axis,
  59975. mode = axis.options.hoverMode,
  59976. argument;
  59977. if (event.target.tagName === "tspan")
  59978. argument = $(event.target).parent().data('argument');
  59979. else
  59980. argument = $(event.target).data('argument');
  59981. if (event.type === 'mousemove')
  59982. return [that, event.pageX, event.pageY];
  59983. if (!axis)
  59984. return null;
  59985. return [that, axis, mode, argument, event]
  59986. },
  59987. _pointEvent: {
  59988. mouseover: function(that, point, mode) {
  59989. if (that.mouseLocked)
  59990. return;
  59991. that._setHoveredPoint(point, mode);
  59992. if (that.tooltipEnabled && point && point.getOptions())
  59993. that._compareCoords(that, function() {
  59994. that._showTooltip(that.tooltip, point)
  59995. })
  59996. },
  59997. mouseout: function(that, point, mode) {
  59998. if (that.mouseLocked)
  59999. return;
  60000. that._clearHover(that)
  60001. },
  60002. touchmove: function(that, point, mode) {
  60003. clearTimeout(that.tooltipHoldTimeout);
  60004. that.tooltipHoldTimeout = null;
  60005. that.showHoldTooltip = true
  60006. },
  60007. mousemove: function(that, pageX, pageY, offsetX, offsetY) {
  60008. that._setCurCoords(that, pageX, pageY)
  60009. },
  60010. touchstart: function(that, point, mode) {
  60011. that.showHoldTooltip = false;
  60012. that._mouseLock(that);
  60013. if (that.tooltipEnabled)
  60014. that.tooltipHoldTimeout = setTimeout(function() {
  60015. that.showHoldTooltip = true;
  60016. that._showTooltip(that.tooltip, point)
  60017. }, TOOLTIP_HOLD_TIMEOUT)
  60018. },
  60019. touchend: function(that, point, mode, event) {
  60020. if (!that.showHoldTooltip)
  60021. that._pointClick(that, point, true, event);
  60022. clearTimeout(that.tooltipHoldTimeout);
  60023. that._clickLock(that);
  60024. that._clearHover(that)
  60025. },
  60026. click: function(that, point, mode, event) {
  60027. that._pointClick(that, point, false, event)
  60028. },
  60029. mousedown: function(that, point, mode) {
  60030. that._pointEvent.touchstart(that, point, mode)
  60031. },
  60032. mouseup: function(that, point, mode, event) {
  60033. that._pointEvent.touchend(that, point, mode, event)
  60034. }
  60035. },
  60036. _pointCondition: {
  60037. mouseover: function(that, point, mode, event, func) {
  60038. if (mode === ALL_ARGUMENTS_POINTS_MODE && that.hoveredPoint && that.hoveredPoint.argument === point.argument) {
  60039. that.hoverHoldTimeOut = clearTimeout(that.hoverHoldTimeOut);
  60040. that.hoveredObject = point;
  60041. func(that, point, mode);
  60042. return
  60043. }
  60044. that._setHover(that, point, mode, func)
  60045. },
  60046. mouseout: function(that, point, mode, event, func) {
  60047. that._releaseHover(that, point, mode, func)
  60048. },
  60049. touchstart: !msPointerEnabled,
  60050. touchend: !msPointerEnabled,
  60051. mousedown: msPointerEnabled,
  60052. mouseup: msPointerEnabled
  60053. },
  60054. _seriesEvent: {
  60055. mouseover: function(that, series, mode) {
  60056. if (that.mouseLocked)
  60057. return;
  60058. that._setHoveredSeries(series, mode)
  60059. },
  60060. mouseout: function(that, series, mode) {
  60061. that._clearHover(that)
  60062. },
  60063. mousemove: function(that, pageX, pageY, offsetX, offsetY) {
  60064. that._setCurCoords(that, pageX, pageY)
  60065. },
  60066. touchstart: function(that) {
  60067. that._mouseLock(that)
  60068. },
  60069. touchend: function(that, series, _, event) {
  60070. that._seriesClick(that, series, true, event);
  60071. that._clickLock(that)
  60072. },
  60073. click: function(that, series, mode, event) {
  60074. that._seriesClick(that, series, false, event)
  60075. },
  60076. mousedown: function(that, point, mode) {
  60077. that._seriesEvent.touchstart(that, point, mode)
  60078. },
  60079. mouseup: function(that, point, mode) {
  60080. that._seriesEvent.touchend(that, point, mode)
  60081. }
  60082. },
  60083. _crossHairEvent: {
  60084. mousemove: function(that, x, y) {
  60085. if (!that.eventType) {
  60086. that.eventType = 'mouse';
  60087. return
  60088. }
  60089. else if (that.eventType === 'touch')
  60090. return;
  60091. else if (that.eventType === 'mouse') {
  60092. that._moveCrossHair(that, x, y);
  60093. that.eventType = null
  60094. }
  60095. },
  60096. mouseout: function(that) {
  60097. that._hideCrossHair(that);
  60098. that.eventType = null
  60099. },
  60100. touchstart: function(that, x, y) {
  60101. that.eventType = 'touch'
  60102. },
  60103. touchend: function(that, x, y) {
  60104. that.eventType = null
  60105. },
  60106. mousedown: function(that, x, y) {
  60107. that._crossHairEvent.touchstart(that, x, y)
  60108. },
  60109. mouseup: function(that, x, y) {
  60110. that._crossHairEvent.touchend(that, x, y)
  60111. }
  60112. },
  60113. _hideCrossHair: function(that) {
  60114. if (!that.crossHairOptions)
  60115. return;
  60116. var horizontalLine = that.crossHairOptions.horizontalLine,
  60117. verticalLine = that.crossHairOptions.verticalLine;
  60118. horizontalLine && horizontalLine.applySettings({visibility: 'hidden'});
  60119. verticalLine && verticalLine.applySettings({visibility: 'hidden'})
  60120. },
  60121. _moveCrossHair: function(that, x, y) {
  60122. if (!that.crossHairOptions)
  60123. return;
  60124. var horizontalLine = that.crossHairOptions.horizontalLine,
  60125. verticalLine = that.crossHairOptions.verticalLine,
  60126. canvas = that.crossHairOptions.canvas || {};
  60127. if (x > canvas.left && x < canvas.width - canvas.right && y > canvas.top && y < canvas.height - canvas.bottom) {
  60128. horizontalLine && horizontalLine.applySettings({visibility: 'visible'});
  60129. verticalLine && verticalLine.applySettings({visibility: 'visible'});
  60130. horizontalLine && horizontalLine.applySettings({translateY: y - canvas.top});
  60131. verticalLine && verticalLine.applySettings({translateX: x - canvas.left})
  60132. }
  60133. else {
  60134. horizontalLine && horizontalLine.applySettings({visibility: 'hidden'});
  60135. verticalLine && verticalLine.applySettings({visibility: 'hidden'})
  60136. }
  60137. },
  60138. _seriesCondition: {
  60139. mouseover: function(that, series, mode, event, func) {
  60140. that.hoverStartDelay = 0;
  60141. that._setHover(that, series, mode, func)
  60142. },
  60143. mouseout: function(that, series, mode, event, func) {
  60144. that.hoverStartDelay = HOVER_START_DELAY;
  60145. that._releaseHover(that, series, mode, func)
  60146. },
  60147. touchstart: !msPointerEnabled,
  60148. touchend: !msPointerEnabled,
  60149. mousedown: msPointerEnabled,
  60150. mouseup: msPointerEnabled
  60151. },
  60152. _axisEvent: {
  60153. mouseover: function(that, axis, argument) {
  60154. if (that.mouseLocked || isDefined(that.hoveredArgument) && that.hoveredArgument === argument)
  60155. return;
  60156. that._clearHover(that);
  60157. if (isDefined(that.hoveredArgument))
  60158. that._toAllArgumentPoints(that.hoveredArgument, 'releasePointHoverState');
  60159. that._toAllArgumentPoints(argument, 'setPointHoverState');
  60160. that.hoveredArgument = argument
  60161. },
  60162. mouseout: function(that, axis) {
  60163. if (that.mouseLocked || !isDefined(that.hoveredArgument))
  60164. return;
  60165. that._toAllArgumentPoints(that.hoveredArgument, 'releasePointHoverState');
  60166. that.hoveredArgument = null
  60167. },
  60168. mousemove: function(that, pageX, pageY) {
  60169. that._setCurCoords(that, pageX, pageY)
  60170. },
  60171. touchstart: function(that) {
  60172. that._mouseLock(that)
  60173. },
  60174. touchend: function(that, axis, mode, argument, event) {
  60175. that._argumentAxisClick(that, axis, argument, true, event);
  60176. that._clearHover(that);
  60177. that._clickLock(that)
  60178. },
  60179. click: function(that, axis, mode, argument, event) {
  60180. that._clearHover(that);
  60181. that._argumentAxisClick(that, axis, argument, false, event)
  60182. },
  60183. mousedown: function(that) {
  60184. that._axisEvent.touchstart(that)
  60185. },
  60186. mouseup: function(that, axis, mode, argument, event) {
  60187. that._axisEvent.touchend(that, axis, mode, argument, event)
  60188. }
  60189. },
  60190. _axisCondition: {
  60191. mouseover: function(that, axis, mode, argument, event, func) {
  60192. that._hideCrossHair(that);
  60193. if (mode === ALL_ARGUMENTS_POINTS_MODE)
  60194. that._setHover(that, axis, argument, func)
  60195. },
  60196. mouseout: function(that, axis, mode, argument, event, func) {
  60197. that._releaseHover(that, axis, argument, func)
  60198. },
  60199. touchstart: !msPointerEnabled,
  60200. touchend: !msPointerEnabled,
  60201. mousedown: msPointerEnabled,
  60202. mouseup: msPointerEnabled
  60203. },
  60204. _setHover: function(that, object, mode, func) {
  60205. if (object === that.hoveredObject) {
  60206. that.hoverHoldTimeOut = clearTimeout(that.hoverHoldTimeOut);
  60207. if (mode === object.lastHoverMode)
  60208. return
  60209. }
  60210. if (that.mouseLocked)
  60211. return;
  60212. clearTimeout(that.cmpCoordTimeout);
  60213. clearTimeout(that.hoverStartTimeOut);
  60214. that.hoverStartTimeOut = setTimeout(function() {
  60215. clearTimeout(that.hoverHoldTimeOut);
  60216. that.hoveredObject = object;
  60217. func(that, object, mode)
  60218. }, that.hoverStartDelay)
  60219. },
  60220. _releaseHover: function(that, object, mode, func) {
  60221. if (that.mouseLocked)
  60222. return;
  60223. clearTimeout(that.cmpCoordTimeout);
  60224. clearTimeout(that.hoverStartTimeOut);
  60225. if (object === that.hoveredObject)
  60226. that.hoverHoldTimeOut = setTimeout(function() {
  60227. that.hoveredObject = null;
  60228. func(that, object, mode);
  60229. that.hoverStartDelay = 0
  60230. }, HOVER_HOLD_DELAY)
  60231. },
  60232. _compareCoords: function(that, func) {
  60233. clearTimeout(that.cmpCoordTimeout);
  60234. if (Math.abs(that.pX - that.cX) + Math.abs(that.pY - that.cY) < that.sensitivity) {
  60235. if (that.mouseLocked)
  60236. return;
  60237. func()
  60238. }
  60239. else {
  60240. that.pX = that.cX;
  60241. that.pY = that.cY;
  60242. that.cmpCoordTimeout = setTimeout(function() {
  60243. that._compareCoords(that, func)
  60244. }, that.hoverStartDelay === 0 ? HOVER_START_DELAY : 0)
  60245. }
  60246. },
  60247. _seriesClick: function(that, series, touchEvent, event) {
  60248. if (that.lockClick && !touchEvent)
  60249. return;
  60250. that.seriesClick && that.seriesClick.call(series, series, event)
  60251. },
  60252. _legendClick: function(that, series, touchEvent, event) {
  60253. var legendClick = that.legendClick;
  60254. if (that.lockClick && !touchEvent)
  60255. return true;
  60256. if (legendClick) {
  60257. legendClick.call(series, series, event);
  60258. return true
  60259. }
  60260. return false
  60261. },
  60262. _pointClick: function(that, point, touchEvent, event) {
  60263. var series = point.series;
  60264. if (that.lockClick && !touchEvent)
  60265. return;
  60266. if (that.pointClick) {
  60267. that.pointClick.call(point, point, event);
  60268. return
  60269. }
  60270. that.seriesClick && that.seriesClick.call(series, series, event);
  60271. return
  60272. },
  60273. _argumentAxisClick: function(that, axis, argument, touchEvent, event) {
  60274. if (that.lockClick && !touchEvent)
  60275. return;
  60276. that.argumentAxisClick && that.argumentAxisClick.call(axis, axis, argument, event)
  60277. },
  60278. _selectSeries: function(event, mode) {
  60279. event.data.tracker._setSelectedSeries(event.target, mode)
  60280. },
  60281. _deselectSeries: function(event, mode) {
  60282. event.data.tracker._releaseSelectedSeries(event.target, mode)
  60283. },
  60284. _selectPoint: function(event, point) {
  60285. event.data.tracker._setSelectedPoint(point)
  60286. },
  60287. _deselectPoint: function(event, point) {
  60288. event.data.tracker._releaseSelectedPoint(point)
  60289. },
  60290. _showPointTooltip: function(event, point) {
  60291. var that = event.data.tracker;
  60292. that._showTooltip(that.tooltip, point)
  60293. },
  60294. _hidePointTooltip: function(event, point) {
  60295. event.data.tracker._hideTooltip(point)
  60296. },
  60297. _hideTooltip: function(point) {
  60298. var tooltip = this && this.tooltip;
  60299. if (!tooltip || point && this.pointAtShownTooltip !== point)
  60300. return;
  60301. point = point || this.pointAtShownTooltip;
  60302. tooltip.hide();
  60303. if (this.pointAtShownTooltip) {
  60304. this.pointAtShownTooltip = null;
  60305. isFunction(this.tooltipHidden) && this.tooltipHidden.call(point, point)
  60306. }
  60307. },
  60308. _showTooltip: function(tooltip, point) {
  60309. var tooltipFormatObject = point.getTooltipFormatObject(tooltip);
  60310. if (!isDefined(tooltipFormatObject.valueText) && !tooltipFormatObject.points || !point.isVisible())
  60311. return;
  60312. this.pointAtShownTooltip && this._hideTooltip(this.pointAtShownTooltip);
  60313. if (point && point.getOptions()) {
  60314. var tooltipCoords = point.getTooltipCoords();
  60315. if (!tooltip.prepare(tooltipFormatObject, {
  60316. x: tooltipCoords.x,
  60317. y: tooltipCoords.y,
  60318. offset: tooltipCoords.offset
  60319. }))
  60320. return;
  60321. tooltip.show();
  60322. !this.pointAtShownTooltip && isFunction(this.tooltipShown) && this.tooltipShown.call(point, point);
  60323. this.pointAtShownTooltip = point
  60324. }
  60325. },
  60326. _setHoveredSeries: function(series, mode) {
  60327. var that = this;
  60328. if (mode !== NONE_MODE && that.hoveredSeries !== series || series.lastHoverMode !== mode) {
  60329. that._clearHover(that);
  60330. that.hoveredSeries = series;
  60331. series.setHoverState(mode, that.legendCallback(series));
  60332. that.seriesHover && that.seriesHover.call(series, series);
  60333. that.seriesHoverChanged && that.seriesHoverChanged.call(series, series)
  60334. }
  60335. if (mode === NONE_MODE)
  60336. $(series).trigger('NoneMode')
  60337. },
  60338. _setSelectedSeries: function(series, mode) {
  60339. var that = this,
  60340. seriesContain = false;
  60341. if (this.seriesSelectionMode === MULTIPLE_MODE)
  60342. $.each(that.selectedSeries, function(_, sr) {
  60343. if (sr == series) {
  60344. seriesContain = true;
  60345. return false
  60346. }
  60347. });
  60348. else if (that.selectedSeries == series)
  60349. seriesContain = true;
  60350. if (!seriesContain || series.lastSelectionMode !== mode) {
  60351. if (that.seriesSelectionMode === SINGLE_MODE) {
  60352. this._releaseSelectedSeries();
  60353. that.selectedSeries = series
  60354. }
  60355. else
  60356. that.selectedSeries.push(series);
  60357. series.setSelectedState(mode, that.legendCallback(series));
  60358. that.seriesSelected && that.seriesSelected.call(series, series);
  60359. that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series)
  60360. }
  60361. },
  60362. _setHoveredPoint: function(point, mode) {
  60363. var that = this;
  60364. var debug = DX.utils.debug;
  60365. debug.assert(point.series, 'series was not assigned to point or empty');
  60366. if (that.hoveredPoint === point && !point.series)
  60367. return;
  60368. that._clearHover(that);
  60369. that.hoveredPoint = point;
  60370. if (point && point.getOptions())
  60371. that._setHoverStylePointWithMode(point, 'setPointHoverState', mode || processMode(point.getOptions().hoverMode), that.pointHoverChanged, that.legendCallback(point));
  60372. that.pointHover && that.pointHover.call(point, point)
  60373. },
  60374. _toAllArgumentPoints: function(argument, func, callBack) {
  60375. var that = this;
  60376. $.each(that.storedSeries, function(_, series) {
  60377. var neighborPoint = series.getPointByArg(argument);
  60378. if (neighborPoint) {
  60379. series[func](neighborPoint);
  60380. callBack && callBack.call(neighborPoint, neighborPoint)
  60381. }
  60382. })
  60383. },
  60384. _setHoverStylePointWithMode: function(point, func, mode, callBack, legendCallback) {
  60385. var that = this;
  60386. switch (mode) {
  60387. case ALL_ARGUMENTS_POINTS_MODE:
  60388. this._toAllArgumentPoints(point.argument, func, callBack);
  60389. break;
  60390. case ALL_SERIES_POINTS_MODE:
  60391. $.each(point.series.getPoints(), function(_, point) {
  60392. point.series[func](point);
  60393. callBack && callBack.call(point, point)
  60394. });
  60395. break;
  60396. case NONE_MODE:
  60397. break;
  60398. default:
  60399. point.series[func](point, legendCallback);
  60400. callBack && callBack.call(point, point)
  60401. }
  60402. },
  60403. _setSelectedPoint: function(point) {
  60404. var that = this,
  60405. pointContain = false;
  60406. if (this.pointSelectionMode === MULTIPLE_MODE) {
  60407. $.each(that.selectedPoint, function(_, pt) {
  60408. if (pt == point) {
  60409. pointContain = true;
  60410. return false
  60411. }
  60412. });
  60413. !pointContain && that.selectedPoint.push(point)
  60414. }
  60415. else if (that.selectedPoint !== point) {
  60416. this._releaseSelectedPoint();
  60417. that.selectedPoint = point
  60418. }
  60419. else
  60420. pointContain = true;
  60421. if (!pointContain) {
  60422. that._setHoverStylePointWithMode(point, 'setPointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
  60423. that.pointSelected && that.pointSelected.call(point, point)
  60424. }
  60425. },
  60426. _releaseHoveredSeries: function() {
  60427. var that = this;
  60428. if (!that.hoveredSeries)
  60429. return;
  60430. that.hoveredSeries.releaseHoverState(undefined, that.legendCallback(that.hoveredSeries));
  60431. that.seriesHoverChanged && that.seriesHoverChanged.call(that.hoveredSeries, that.hoveredSeries);
  60432. that.hoveredSeries = null
  60433. },
  60434. _releaseSelectedSeriesMultiMode: function(series) {
  60435. var that = this;
  60436. if (!that.selectedSeries)
  60437. return;
  60438. series.releaseSelectedState(undefined, that.legendCallback(series));
  60439. that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series);
  60440. that.selectedSeries = $.map(that.selectedSeries, function(sr) {
  60441. if (sr !== series)
  60442. return sr
  60443. })
  60444. },
  60445. _releaseSelectedSeriesSingleMode: function() {
  60446. var that = this,
  60447. series = this.selectedSeries;
  60448. if (!series)
  60449. return;
  60450. series.releaseSelectedState(undefined, that.legendCallback(series));
  60451. that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series);
  60452. that.selectedSeries = null
  60453. },
  60454. _releaseHoveredPoint: function() {
  60455. var that = this,
  60456. point = that.hoveredPoint,
  60457. mode;
  60458. if (!point || !point.getOptions())
  60459. return;
  60460. mode = processMode(point.getOptions().hoverMode);
  60461. if (mode === ALL_SERIES_POINTS_MODE)
  60462. $.each(point.series.getPoints(), function(_, point) {
  60463. point.series.releasePointHoverState(point);
  60464. that.pointHoverChanged && that.pointHoverChanged.call(point, point)
  60465. });
  60466. else if (mode === ALL_ARGUMENTS_POINTS_MODE)
  60467. that._toAllArgumentPoints(point.argument, 'releasePointHoverState', that.pointHoverChanged);
  60468. else {
  60469. point.releaseHoverState(that.legendCallback(point));
  60470. that.pointHoverChanged && that.pointHoverChanged.call(point, point)
  60471. }
  60472. if (that.tooltipEnabled && !that.showHoldTooltip)
  60473. that._hideTooltip(point);
  60474. that.hoveredPoint = null
  60475. },
  60476. _releaseSelectedPointMultiMode: function(point) {
  60477. var that = this,
  60478. points = that.selectedPoint;
  60479. if (!points)
  60480. return;
  60481. that._setHoverStylePointWithMode(point, 'releasePointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
  60482. this.selectedPoint = $.map(this.selectedPoint, function(pt) {
  60483. if (pt !== point)
  60484. return pt
  60485. })
  60486. },
  60487. _releaseSelectedPointSingleMode: function() {
  60488. var that = this,
  60489. point = that.selectedPoint;
  60490. if (!point)
  60491. return;
  60492. that._setHoverStylePointWithMode(point, 'releasePointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
  60493. this.selectedPoint = null
  60494. },
  60495. _clearPointSelection: function() {
  60496. var that = this;
  60497. if (that.pointSelectionMode === SINGLE_MODE)
  60498. that._releaseSelectedPoint();
  60499. else
  60500. $.each(that.selectedPoint || [], function(_, point) {
  60501. that._releaseSelectedPoint(point)
  60502. })
  60503. },
  60504. clearSelection: function() {
  60505. var that = this;
  60506. that._clearPointSelection();
  60507. if (that.seriesSelectionMode === SINGLE_MODE)
  60508. that._releaseSelectedSeries();
  60509. else
  60510. $.each(that.selectedSeries, function(_, series) {
  60511. that._releaseSelectedSeries(series)
  60512. })
  60513. },
  60514. setTooltip: function(tooltip) {
  60515. this.tooltip = tooltip
  60516. },
  60517. _mouseLock: function(tracker) {
  60518. if (tracker.unlockMouseTimer)
  60519. clearTimeout(tracker.unlockMouseTimer);
  60520. tracker.mouseLocked = true;
  60521. tracker.unlockMouseTimer = setTimeout(function() {
  60522. tracker.mouseLocked = false
  60523. }, MOUSE_EVENT_LOCK_TIMEOUT)
  60524. },
  60525. _clickLock: function(tracker) {
  60526. tracker.lockClick = true;
  60527. if (tracker.lockClickTimer)
  60528. clearTimeout(tracker.lockClickTimer);
  60529. tracker.lockClickTimer = setTimeout(function() {
  60530. tracker.lockClick = false
  60531. }, CLICK_EVENT_LOCK_TIMEOUT)
  60532. },
  60533. _setCurCoords: function(that, pageX, pageY) {
  60534. that.cX = pageX;
  60535. that.cY = pageY
  60536. },
  60537. _clearHover: function(that) {
  60538. that._releaseHoveredSeries();
  60539. that._releaseHoveredPoint()
  60540. }
  60541. })
  60542. })(jQuery, DevExpress);
  60543. /*! Module viz-charts, file dxChart.js */
  60544. (function($, DX, undefined) {
  60545. var ui = DX.ui,
  60546. viz = DX.viz;
  60547. DX.registerComponent("dxChart", viz.charts.Chart)
  60548. })(jQuery, DevExpress);
  60549. /*! Module viz-charts, file dxPieChart.js */
  60550. (function($, DX, undefined) {
  60551. var ui = DX.ui,
  60552. viz = DX.viz;
  60553. DX.registerComponent("dxPieChart", viz.charts.PieChart)
  60554. })(jQuery, DevExpress);
  60555. DevExpress.MOD_VIZ_CHARTS = true
  60556. }
  60557. if (!DevExpress.MOD_VIZ_GAUGES) {
  60558. if (!DevExpress.MOD_VIZ_CORE)
  60559. throw Error('Required module is not referenced: viz-core');
  60560. /*! Module viz-gauges, file namespaces.js */
  60561. (function(DX) {
  60562. DX.viz.gauges = {__internals: {
  60563. circularNeedles: {},
  60564. circularMarkers: {},
  60565. linearNeedles: {},
  60566. linearMarkers: {}
  60567. }};
  60568. DX.viz.gauges.__tests = {}
  60569. })(DevExpress);
  60570. /*! Module viz-gauges, file factory.js */
  60571. (function(DX, $, undefined) {
  60572. var internals = DX.viz.gauges.__internals,
  60573. circularNeedles = internals.circularNeedles,
  60574. circularMarkers = internals.circularMarkers,
  60575. linearNeedles = internals.linearNeedles,
  60576. linearMarkers = internals.linearMarkers;
  60577. var _String = window.String,
  60578. _isString = DX.utils.isString;
  60579. DX.viz.gauges.__factory = {
  60580. createCircularValueIndicator: function(type) {
  60581. var indicatorType = circularNeedles.RectangleNeedle;
  60582. switch (_String(type).toLowerCase()) {
  60583. case'rectangleneedle':
  60584. case'rectangle':
  60585. indicatorType = circularNeedles.RectangleNeedle;
  60586. break;
  60587. case'triangleneedle':
  60588. case'triangle':
  60589. indicatorType = circularNeedles.TriangleNeedle;
  60590. break;
  60591. case'twocolorneedle':
  60592. case'twocolorrectangle':
  60593. indicatorType = circularNeedles.TwoColorRectangleNeedle;
  60594. break;
  60595. case'rangebar':
  60596. indicatorType = internals.CircularRangeBar;
  60597. break
  60598. }
  60599. return new indicatorType
  60600. },
  60601. createLinearValueIndicator: function(type) {
  60602. var indicatorType = internals.LinearRangeBar;
  60603. switch (_String(type).toLowerCase()) {
  60604. case'rectangle':
  60605. indicatorType = linearNeedles.RectangleNeedle;
  60606. break;
  60607. case'rhombus':
  60608. indicatorType = linearNeedles.RhombusNeedle;
  60609. break;
  60610. case'circle':
  60611. indicatorType = linearNeedles.CircleNeedle;
  60612. break;
  60613. case'rangebar':
  60614. indicatorType = internals.LinearRangeBar;
  60615. break
  60616. }
  60617. return new indicatorType
  60618. },
  60619. createCircularSubvalueIndicator: function(type) {
  60620. var indicatorType = circularMarkers.TriangleMarker;
  60621. switch (_String(type).toLowerCase()) {
  60622. case'trianglemarker':
  60623. case'triangle':
  60624. indicatorType = circularMarkers.TriangleMarker;
  60625. break;
  60626. case'textcloud':
  60627. indicatorType = circularMarkers.TextCloudMarker;
  60628. break
  60629. }
  60630. return new indicatorType
  60631. },
  60632. createLinearSubvalueIndicator: function(type) {
  60633. var indicatorType = linearMarkers.TriangleMarker;
  60634. switch (_String(type).toLowerCase()) {
  60635. case'trianglemarker':
  60636. case'triangle':
  60637. indicatorType = linearMarkers.TriangleMarker;
  60638. break;
  60639. case'textcloud':
  60640. indicatorType = linearMarkers.TextCloudMarker;
  60641. break
  60642. }
  60643. return new indicatorType
  60644. },
  60645. createCircularValueIndicatorInHardMode: function(type) {
  60646. var indicatorType = null;
  60647. switch (_String(type).toLowerCase()) {
  60648. case'rectangleneedle':
  60649. indicatorType = circularNeedles.RectangleNeedle;
  60650. break;
  60651. case'triangleneedle':
  60652. indicatorType = circularNeedles.TriangleNeedle;
  60653. break;
  60654. case'twocolorneedle':
  60655. indicatorType = circularNeedles.TwoColorRectangleNeedle;
  60656. break;
  60657. case'rangebar':
  60658. indicatorType = internals.CircularRangeBar;
  60659. break;
  60660. case'trianglemarker':
  60661. indicatorType = circularMarkers.TriangleMarker;
  60662. break;
  60663. case'textcloud':
  60664. indicatorType = circularMarkers.TextCloudMarker;
  60665. break
  60666. }
  60667. return indicatorType ? new indicatorType : null
  60668. },
  60669. createLinearValueIndicatorInHardMode: function(type) {
  60670. var indicatorType = null;
  60671. switch (_String(type).toLowerCase()) {
  60672. case'rectangle':
  60673. indicatorType = linearNeedles.RectangleNeedle;
  60674. break;
  60675. case'rhombus':
  60676. indicatorType = linearNeedles.RhombusNeedle;
  60677. break;
  60678. case'circle':
  60679. indicatorType = linearNeedles.CircleNeedle;
  60680. break;
  60681. case'rangebar':
  60682. indicatorType = internals.LinearRangeBar;
  60683. break;
  60684. case'trianglemarker':
  60685. indicatorType = linearMarkers.TriangleMarker;
  60686. break;
  60687. case'textcloud':
  60688. indicatorType = linearMarkers.TextCloudMarker;
  60689. break
  60690. }
  60691. return indicatorType ? new indicatorType : null
  60692. },
  60693. createCircularNeedle: function(type) {
  60694. switch (_String(type).toLowerCase()) {
  60695. case'rectangleneedle':
  60696. case'rectangle':
  60697. return new circularNeedles.RectangleNeedle;
  60698. case'twocolorneedle':
  60699. case'twocolorrectangle':
  60700. return new circularNeedles.TwoColorRectangleNeedle;
  60701. case'triangleneedle':
  60702. case'triangle':
  60703. return new circularNeedles.TriangleNeedle;
  60704. case'rangebar':
  60705. return new internals.CircularRangeBar
  60706. }
  60707. return undefined
  60708. },
  60709. createLinearNeedle: function(type) {
  60710. switch (_String(type).toLowerCase()) {
  60711. case'rectangle':
  60712. return new linearNeedles.RectangleNeedle;
  60713. case'rhombus':
  60714. return new linearNeedles.RhombusNeedle;
  60715. case'circle':
  60716. return new linearNeedles.CircleNeedle;
  60717. case'rangebar':
  60718. return new internals.LinearRangeBar
  60719. }
  60720. return undefined
  60721. },
  60722. createCircularMarker: function(type) {
  60723. switch (_String(type).toLowerCase()) {
  60724. case'trianglemarker':
  60725. case'triangle':
  60726. return new circularMarkers.TriangleMarker;
  60727. case'textcloud':
  60728. return new circularMarkers.TextCloudMarker
  60729. }
  60730. return undefined
  60731. },
  60732. createLinearMarker: function(type) {
  60733. switch (_String(type).toLowerCase()) {
  60734. case'trianglemarker':
  60735. case'triangle':
  60736. return new linearMarkers.TriangleMarker;
  60737. case'textcloud':
  60738. return new linearMarkers.TextCloudMarker
  60739. }
  60740. return undefined
  60741. },
  60742. createCircularRangeBar: function(parameters) {
  60743. return new internals.CircularRangeBar(parameters)
  60744. },
  60745. createLinearRangeBar: function(parameters) {
  60746. return new internals.LinearRangeBar(parameters)
  60747. },
  60748. createCircularScale: function(parameters) {
  60749. return new internals.CircularScale(parameters)
  60750. },
  60751. createLinearScale: function(parameters) {
  60752. return new internals.LinearScale(parameters)
  60753. },
  60754. createCircularRangeContainer: function(parameters) {
  60755. return new internals.CircularRangeContainer(parameters)
  60756. },
  60757. createLinearRangeContainer: function(parameters) {
  60758. return new internals.LinearRangeContainer(parameters)
  60759. },
  60760. createTitle: function(parameters) {
  60761. return new internals.Title(parameters)
  60762. },
  60763. createIndicator: function() {
  60764. return internals.Indicator && new internals.Indicator || null
  60765. },
  60766. createLayoutManager: function() {
  60767. return new internals.LayoutManager
  60768. },
  60769. createThemeManager: function(options) {
  60770. return new internals.ThemeManager(options)
  60771. },
  60772. createTracker: function(parameters) {
  60773. return new internals.Tracker(parameters)
  60774. }
  60775. };
  60776. var _isFunction = DX.utils.isFunction,
  60777. _String = window.String,
  60778. _extend = $.extend;
  60779. var _formatHelper = DX.formatHelper;
  60780. internals.formatValue = function(value, options, extra) {
  60781. options = options || {};
  60782. var text = _formatHelper.format(value, options.format, options.precision),
  60783. context;
  60784. if (_isFunction(options.customizeText)) {
  60785. var context = _extend({
  60786. value: value,
  60787. valueText: text
  60788. }, extra);
  60789. return _String(options.customizeText.call(context, context))
  60790. }
  60791. return text
  60792. };
  60793. internals.getSampleText = function(translator, options) {
  60794. var text1 = internals.formatValue(translator.getDomainStart(), options),
  60795. text2 = internals.formatValue(translator.getDomainEnd(), options);
  60796. return text1.length >= text2.length ? text1 : text2
  60797. }
  60798. })(DevExpress, jQuery);
  60799. /*! Module viz-gauges, file scale.js */
  60800. (function(DX, $, undefined) {
  60801. var _Number = Number,
  60802. _String = String,
  60803. _isFinite = isFinite,
  60804. _min = Math.min,
  60805. _max = Math.max,
  60806. _abs = Math.abs,
  60807. _atan = Math.atan,
  60808. _acos = Math.acos,
  60809. _ceil = Math.ceil,
  60810. _isFunction = DX.utils.isFunction,
  60811. _isArray = DX.utils.isArray,
  60812. _getCosAndSin = DX.utils.getCosAndSin,
  60813. _normalizeAngle = DX.utils.normalizeAngle,
  60814. _convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  60815. _map = $.map;
  60816. var _formatHelper = DX.formatHelper,
  60817. _tickProvider = DX.viz.core.tickProvider;
  60818. var PI_DIV_180 = Math.PI / 180;
  60819. function binarySearch(x, list) {
  60820. var a = 0,
  60821. b = list.length - 1,
  60822. flag = list[a] - list[b] < 0,
  60823. c,
  60824. k = -1;
  60825. if (list[a] === x)
  60826. k = a;
  60827. if (list[b] === x)
  60828. k = b;
  60829. while (k < 0 && a <= b) {
  60830. c = ~~((a + b) / 2);
  60831. if (list[c] === x)
  60832. k = c;
  60833. else if (list[c] - x < 0 === flag)
  60834. a = c + 1;
  60835. else
  60836. b = c - 1
  60837. }
  60838. return k
  60839. }
  60840. function sortAsc(x, y) {
  60841. return x - y
  60842. }
  60843. function sortDes(x, y) {
  60844. return y - x
  60845. }
  60846. DX.viz.gauges.__internals.BaseScale = DX.Class.inherit({
  60847. ctor: function(parameters) {
  60848. var that = this;
  60849. that._renderer = parameters.renderer;
  60850. that._container = parameters.container;
  60851. that._translator = parameters.translator;
  60852. that._root = that._renderer.createGroup({'class': 'dxg-scale'});
  60853. that._majorTicks = that._renderer.createGroup({'class': 'dxg-major-ticks'});
  60854. that._minorTicks = that._renderer.createGroup({'class': 'dxg-minor-ticks'});
  60855. that._labels = that._renderer.createGroup({'class': 'dxg-labels'})
  60856. },
  60857. dispose: function() {
  60858. var that = this;
  60859. that._renderer = that._container = that._renderer = that._root = that._majorTicks = that._minorTicks = that._labels = null;
  60860. return that
  60861. },
  60862. clean: function() {
  60863. var that = this;
  60864. that._root.detach();
  60865. that._majorTicks.detach().clear();
  60866. that._minorTicks.detach().clear();
  60867. that._labels.detach().clear();
  60868. that._majorTicksEnabled = that._minorTicksEnabled = that._labelsEnabled = that._options = that.enabled = null;
  60869. return that
  60870. },
  60871. render: function(options) {
  60872. var that = this;
  60873. that._options = options;
  60874. that._processOptions(options);
  60875. if (that._majorTicksEnabled || that._minorTicksEnabled || that._labelsEnabled) {
  60876. that.enabled = true;
  60877. that._root.append(that._container);
  60878. if (that._majorTicksEnabled)
  60879. that._majorTicks.append(that._root);
  60880. if (that._minorTicksEnabled)
  60881. that._minorTicks.append(that._root);
  60882. if (that._labelsEnabled) {
  60883. that._labels.append(that._root);
  60884. that._measureText()
  60885. }
  60886. }
  60887. return that
  60888. },
  60889. _processOptions: function(options) {
  60890. var that = this;
  60891. that._majorTicksEnabled = options.majorTick.visible && options.majorTick.length > 0 && options.majorTick.width > 0;
  60892. that._minorTicksEnabled = options.minorTick.visible && options.minorTick.length > 0 && options.minorTick.width > 0;
  60893. that._labelsEnabled = options.label.visible && _Number(options.label.indentFromTick) !== 0;
  60894. that._setupOrientation()
  60895. },
  60896. _getSampleText: function() {
  60897. var that = this,
  60898. domain = that._translator.getDomain(),
  60899. texts = [],
  60900. i,
  60901. ii,
  60902. text,
  60903. maxLength = 0,
  60904. maxText = '';
  60905. var ticks = _tickProvider.getTicks({
  60906. min: domain[0],
  60907. max: domain[1],
  60908. tickInterval: that._options.majorTick.tickInterval > 0 ? _Number(that._options.majorTick.tickInterval) : undefined,
  60909. screenDelta: that._options.approximateScreenDelta,
  60910. gridSpacingFactor: that._getGridSpacingFactor().majorTicks
  60911. });
  60912. for (i = 0, ii = ticks.length; i < ii; ++i) {
  60913. text = that._formatValue(ticks[i]);
  60914. text.length > maxLength && (maxText = text) && (maxLength = text.length)
  60915. }
  60916. return maxText
  60917. },
  60918. _measureText: function() {
  60919. var that = this,
  60920. value = that._getSampleText(),
  60921. text = that._renderer.createText(value, 0, 0, {font: that._options.label.font}).append(that._labels),
  60922. bbox = text.getBBox();
  60923. text.remove();
  60924. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  60925. that._textWidth = bbox.width;
  60926. that._textHeight = bbox.height;
  60927. that._textLength = value.length
  60928. },
  60929. _formatValue: function(value) {
  60930. var options = this._options.label,
  60931. text = _formatHelper.format(value, options.format, options.precision);
  60932. if (_isFunction(options.customizeText)) {
  60933. text = {
  60934. value: value,
  60935. valueText: text
  60936. };
  60937. text = _String(options.customizeText.call(text, text))
  60938. }
  60939. return text
  60940. },
  60941. _setupOrientation: null,
  60942. _getCustomValues: function(values, compare) {
  60943. var translator = this._translator,
  60944. result = [];
  60945. if (_isArray(values)) {
  60946. result = _map(values, function(x) {
  60947. return _isFinite(translator.translate(x)) ? _Number(x) : null
  60948. }).sort(compare);
  60949. result = _map(result, function(x, i) {
  60950. return x !== result[i - 1] ? x : null
  60951. })
  60952. }
  60953. return result
  60954. },
  60955. _generateTicks: function(layout) {
  60956. var that = this,
  60957. majorTicksOptions = {
  60958. tickInterval: that._options.majorTick.tickInterval > 0 ? _Number(that._options.majorTick.tickInterval) : undefined,
  60959. gridSpacingFactor: that._getGridSpacingFactor().majorTicks,
  60960. numberMultipliers: [1, 2, 5]
  60961. },
  60962. minorTicksOptions = {
  60963. tickInterval: that._options.minorTick.tickInterval > 0 ? _Number(that._options.minorTick.tickInterval) : undefined,
  60964. gridSpacingFactor: that._getGridSpacingFactor().minorTicks,
  60965. numberMultipliers: [1, 2, 5]
  60966. };
  60967. if (that._options.majorTick.useTicksAutoArrangement) {
  60968. majorTicksOptions.useTicksAutoArrangement = true;
  60969. majorTicksOptions.renderer = that._renderer;
  60970. majorTicksOptions.translator = that._translator;
  60971. majorTicksOptions.getCustomAutoArrangementStep = function(values) {
  60972. return that._getCuttingFactor(values.length, {
  60973. width: that._textWidth,
  60974. height: that._textHeight
  60975. }, layout)
  60976. }
  60977. }
  60978. return _tickProvider.getFullTicks(that._translator.getDomain()[0], that._translator.getDomain()[1], that._getScreenDelta(layout), majorTicksOptions, minorTicksOptions)
  60979. },
  60980. _getTicks: function(layout) {
  60981. var that = this,
  60982. compareCallback = that._translator.getDomain()[0] < that._translator.getDomain()[1] ? sortAsc : sortDes,
  60983. info = that._generateTicks(layout);
  60984. var majorValues = that._options.majorTick.showCalculatedTicks ? info.majorTicks : [];
  60985. var customMajorValues = that._getCustomValues(that._options.majorTick.customTickValues, compareCallback);
  60986. customMajorValues = _map(customMajorValues, function(value) {
  60987. return binarySearch(value, majorValues) === -1 ? value : null
  60988. });
  60989. var minorValues = that._options.minorTick.showCalculatedTicks ? info.minorTicks : [];
  60990. minorValues = _map(minorValues, function(value) {
  60991. return binarySearch(value, customMajorValues) === -1 ? value : null
  60992. });
  60993. var customMinorValues = that._getCustomValues(that._options.minorTick.customTickValues, compareCallback);
  60994. var list = majorValues.concat(minorValues, customMajorValues).sort(compareCallback);
  60995. customMinorValues = _map(customMinorValues, function(value) {
  60996. return binarySearch(value, list) === -1 ? value : null
  60997. });
  60998. return {
  60999. major: _map(majorValues.concat(customMajorValues), function(value) {
  61000. return {
  61001. value: value,
  61002. position: that._translator.translate(value)
  61003. }
  61004. }),
  61005. minor: _map(minorValues.concat(customMinorValues), function(value) {
  61006. return {
  61007. value: value,
  61008. position: that._translator.translate(value)
  61009. }
  61010. })
  61011. }
  61012. },
  61013. _createMajorTicks: function(ticks, layout) {
  61014. var that = this;
  61015. that._majorTicks.clear().applySettings({fill: that._options.majorTick.color});
  61016. var points = that._getTickPoints(_Number(that._options.majorTick.length), _Number(that._options.majorTick.width), layout);
  61017. if (points) {
  61018. var i = 0,
  61019. ii = ticks.length,
  61020. element;
  61021. that._options.hideFirstTick && ++i;
  61022. that._options.hideLastTick && --ii;
  61023. for (; i < ii; ++i) {
  61024. element = that._renderer.createArea(points);
  61025. that._moveTick(element, ticks[i], layout);
  61026. element.append(that._majorTicks)
  61027. }
  61028. }
  61029. },
  61030. _createMinorTicks: function(ticks, layout) {
  61031. var that = this;
  61032. that._minorTicks.clear().applySettings({fill: that._options.minorTick.color});
  61033. var points = that._getTickPoints(_Number(that._options.minorTick.length), _Number(that._options.minorTick.width), layout);
  61034. if (points) {
  61035. var i = 0,
  61036. ii = ticks.length,
  61037. element;
  61038. for (; i < ii; ++i) {
  61039. element = that._renderer.createArea(points);
  61040. that._moveTick(element, ticks[i], layout);
  61041. element.append(that._minorTicks)
  61042. }
  61043. }
  61044. },
  61045. _createLabels: function(ticks, layout) {
  61046. var that = this,
  61047. indentFromTick = _Number(that._options.label.indentFromTick);
  61048. that._labels.clear().applySettings({
  61049. align: that._getLabelAlign(indentFromTick),
  61050. font: that._options.label.font
  61051. });
  61052. var textPosition = that._getLabelPosition(that._majorTicksEnabled ? _Number(that._options.majorTick.length) : 0, indentFromTick, layout);
  61053. if (textPosition) {
  61054. var i = 0,
  61055. ii = ticks.length,
  61056. points,
  61057. text;
  61058. that._options.hideFirstLabel && ++i;
  61059. that._options.hideLastLabel && --ii;
  61060. for (; i < ii; ++i) {
  61061. text = that._formatValue(ticks[i].value);
  61062. points = that._getLabelOptions(text, textPosition, indentFromTick, ticks[i], layout);
  61063. that._renderer.createText(text, points.x, points.y + that._textVerticalOffset).append(that._labels)
  61064. }
  61065. }
  61066. },
  61067. resize: function(layout) {
  61068. var that = this,
  61069. ticks = that._getTicks(layout);
  61070. if (that._majorTicksEnabled)
  61071. that._createMajorTicks(ticks.major, layout);
  61072. if (that._minorTicksEnabled)
  61073. that._createMinorTicks(ticks.minor, layout);
  61074. if (that._labelsEnabled)
  61075. that._createLabels(ticks.major, layout);
  61076. return that
  61077. }
  61078. });
  61079. function getBasedAngle(startAngle, endAngle) {
  61080. var startDelta,
  61081. endDelta,
  61082. tmp;
  61083. if (startAngle > endAngle) {
  61084. tmp = endAngle;
  61085. endAngle = startAngle;
  61086. startAngle = tmp
  61087. }
  61088. startDelta = 0 <= startAngle && startAngle <= 180 ? _abs(90 - startAngle) : _abs(270 - startAngle);
  61089. startDelta = startAngle < 90 && 90 < endAngle || startAngle < 270 && 270 < endAngle ? 0 : startDelta;
  61090. endDelta = 0 < endAngle && endAngle < 180 ? _abs(90 - endAngle) : _abs(270 - endAngle);
  61091. return startDelta < endDelta ? startDelta : endDelta
  61092. }
  61093. DX.viz.gauges.__internals.CircularScale = DX.viz.gauges.__internals.BaseScale.inherit({
  61094. _getGridSpacingFactor: function() {
  61095. return {
  61096. majorTicks: 17,
  61097. minorTicks: 5
  61098. }
  61099. },
  61100. _getScreenDelta: function(layout) {
  61101. return (this._translator.getCodomainStart() - this._translator.getCodomainEnd()) * layout.radius * PI_DIV_180
  61102. },
  61103. _getCuttingFactor: function(ticksCount, maxLabelSize, layout) {
  61104. var that = this,
  61105. options = that._options,
  61106. startAngle = that._translator.getCodomainStart(),
  61107. endAngle = that._translator.getCodomainEnd(),
  61108. radius = that._getLabelPosition(that._majorTicksEnabled ? _Number(that._options.majorTick.length) : 0, _Number(that._options.label.indentFromTick), layout),
  61109. baseAngle = getBasedAngle(_normalizeAngle(startAngle), _normalizeAngle(endAngle)),
  61110. baseAngleCosSin = _getCosAndSin(baseAngle),
  61111. degreesPerTick = (startAngle - endAngle) / ticksCount,
  61112. minAngleBetweenTicks,
  61113. widthBasedAngle,
  61114. tanOfWidthBasedAngle,
  61115. heightBasedAngle,
  61116. cosOfHeightBasedAngle,
  61117. cuttingBackFactor = 1;
  61118. tanOfWidthBasedAngle = (baseAngleCosSin.sin * radius + maxLabelSize.width) / (baseAngleCosSin.cos * radius);
  61119. widthBasedAngle = _abs(baseAngle - _atan(tanOfWidthBasedAngle) / PI_DIV_180);
  61120. cosOfHeightBasedAngle = baseAngleCosSin.cos - maxLabelSize.height / radius;
  61121. heightBasedAngle = -1 > cosOfHeightBasedAngle || cosOfHeightBasedAngle > 1 ? 90 : _abs(baseAngle - _acos(cosOfHeightBasedAngle) / PI_DIV_180);
  61122. minAngleBetweenTicks = widthBasedAngle < heightBasedAngle ? widthBasedAngle : heightBasedAngle;
  61123. if (degreesPerTick < minAngleBetweenTicks)
  61124. cuttingBackFactor = _ceil(minAngleBetweenTicks / degreesPerTick);
  61125. return _max(1, cuttingBackFactor)
  61126. },
  61127. _setupOrientation: function() {
  61128. var that = this;
  61129. that._inner = that._outer = 0;
  61130. switch (that._options.orientation) {
  61131. case'inside':
  61132. that._inner = 1;
  61133. break;
  61134. case'center':
  61135. that._inner = that._outer = 0.5;
  61136. break;
  61137. default:
  61138. that._outer = 1;
  61139. break
  61140. }
  61141. },
  61142. _getTickPoints: function(length, width, layout) {
  61143. var x1 = layout.x - width / 2,
  61144. x2 = layout.x + width / 2,
  61145. y1 = layout.y - layout.radius - length * this._outer,
  61146. y2 = layout.y - layout.radius + length * this._inner;
  61147. return y1 > 0 && y2 > 0 ? [x1, y1, x2, y1, x2, y2, x1, y2] : null
  61148. },
  61149. _moveTick: function(element, tick, layout) {
  61150. element.rotate(_convertAngleToRendererSpace(tick.position), layout.x, layout.y)
  61151. },
  61152. _getLabelPosition: function(tickLength, textIndent, layout) {
  61153. var position = layout.radius + tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
  61154. return position > 0 ? position : null
  61155. },
  61156. _getLabelAlign: function() {
  61157. return 'center'
  61158. },
  61159. _getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {
  61160. var cossin = _getCosAndSin(tick.position),
  61161. x = layout.x + cossin.cos * textPosition,
  61162. y = layout.y - cossin.sin * textPosition,
  61163. dx = cossin.cos * (textValue.length / this._textLength) * this._textWidth / 2,
  61164. dy = cossin.sin * this._textHeight / 2;
  61165. if (textIndent > 0) {
  61166. x += dx;
  61167. y -= dy
  61168. }
  61169. else {
  61170. x -= dx;
  61171. y += dy
  61172. }
  61173. return {
  61174. x: x,
  61175. y: y
  61176. }
  61177. },
  61178. measure: function(layout) {
  61179. var that = this,
  61180. result = {
  61181. min: layout.radius,
  61182. max: layout.radius
  61183. };
  61184. if (that._majorTicksEnabled) {
  61185. result.min = _min(result.min, layout.radius - that._inner * that._options.majorTick.length);
  61186. result.max = _max(result.max, layout.radius + that._outer * that._options.majorTick.length)
  61187. }
  61188. if (that._minorTicksEnabled) {
  61189. result.min = _min(result.min, layout.radius - that._inner * that._options.minorTick.length);
  61190. result.max = _max(result.max, layout.radius + that._outer * that._options.minorTick.length)
  61191. }
  61192. if (that._labelsEnabled) {
  61193. if (that._options.label.indentFromTick > 0) {
  61194. result.horizontalOffset = _Number(that._options.label.indentFromTick) + that._textWidth;
  61195. result.verticalOffset = _Number(that._options.label.indentFromTick) + that._textHeight
  61196. }
  61197. else {
  61198. result.horizontalOffset = result.verticalOffset = 0;
  61199. result.min -= -_Number(that._options.label.indentFromTick) + _max(that._textWidth, that._textHeight)
  61200. }
  61201. result.inverseHorizontalOffset = that._textWidth / 2;
  61202. result.inverseVerticalOffset = that._textHeight / 2
  61203. }
  61204. return result
  61205. }
  61206. });
  61207. DX.viz.gauges.__internals.LinearScale = DX.viz.gauges.__internals.BaseScale.inherit({
  61208. _getGridSpacingFactor: function() {
  61209. return {
  61210. majorTicks: 25,
  61211. minorTicks: 5
  61212. }
  61213. },
  61214. _getScreenDelta: function(layout) {
  61215. return _abs(this._translator.getCodomainEnd() - this._translator.getCodomainStart())
  61216. },
  61217. _getCuttingFactor: function(ticksCount, maxLabelSize, layout) {
  61218. var that = this,
  61219. labelSize = that.vertical ? maxLabelSize.height : maxLabelSize.width,
  61220. screenSize = _abs(that._translator.getCodomainEnd() - that._translator.getCodomainStart());
  61221. return _max(1, _ceil(ticksCount * labelSize / (screenSize + labelSize)))
  61222. },
  61223. _setupOrientation: function() {
  61224. var that = this;
  61225. that.vertical = that._options.vertical;
  61226. that._inner = that._outer = 0;
  61227. if (that.vertical)
  61228. switch (that._options.horizontalOrientation) {
  61229. case'left':
  61230. that._inner = 1;
  61231. break;
  61232. case'center':
  61233. that._inner = that._outer = 0.5;
  61234. break;
  61235. default:
  61236. that._outer = 1;
  61237. break
  61238. }
  61239. else
  61240. switch (that._options.verticalOrientation) {
  61241. case'top':
  61242. that._inner = 1;
  61243. break;
  61244. case'middle':
  61245. that._inner = that._outer = 0.5;
  61246. break;
  61247. default:
  61248. that._outer = 1;
  61249. break
  61250. }
  61251. },
  61252. _getTickPoints: function(length, width, layout) {
  61253. var that = this,
  61254. x1,
  61255. x2,
  61256. y1,
  61257. y2;
  61258. if (that.vertical) {
  61259. x1 = layout.x - length * that._inner;
  61260. x2 = layout.x + length * that._outer;
  61261. y1 = -width / 2;
  61262. y2 = +width / 2
  61263. }
  61264. else {
  61265. x1 = -width / 2;
  61266. x2 = +width / 2;
  61267. y1 = layout.y - length * that._inner;
  61268. y2 = layout.y + length * that._outer
  61269. }
  61270. return [x1, y1, x2, y1, x2, y2, x1, y2]
  61271. },
  61272. _moveTick: function(element, tick, layout) {
  61273. var x = 0,
  61274. y = 0;
  61275. if (this.vertical)
  61276. y = tick.position;
  61277. else
  61278. x = tick.position;
  61279. element.move(x, y)
  61280. },
  61281. _getLabelPosition: function(tickLength, textIndent, layout) {
  61282. var position = tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
  61283. if (this.vertical)
  61284. position += layout.x;
  61285. else
  61286. position += layout.y + (textIndent >= 0 ? 1 : -1) * this._textVerticalOffset;
  61287. return position
  61288. },
  61289. _getLabelAlign: function(textIndent) {
  61290. return this.vertical ? textIndent > 0 ? 'left' : 'right' : 'center'
  61291. },
  61292. _getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {
  61293. var x,
  61294. y;
  61295. if (this.vertical) {
  61296. x = textPosition;
  61297. y = tick.position
  61298. }
  61299. else {
  61300. x = tick.position;
  61301. y = textPosition
  61302. }
  61303. return {
  61304. x: x,
  61305. y: y
  61306. }
  61307. },
  61308. measure: function(layout) {
  61309. var that = this,
  61310. p = layout[that.vertical ? 'x' : 'y'],
  61311. result = {
  61312. min: p,
  61313. max: p
  61314. };
  61315. if (that._majorTicksEnabled) {
  61316. result.min = _min(result.min, p - that._inner * that._options.majorTick.length);
  61317. result.max = _max(result.max, p + that._outer * that._options.majorTick.length)
  61318. }
  61319. if (that._minorTicksEnabled) {
  61320. result.min = _min(result.min, p - that._inner * that._options.minorTick.length);
  61321. result.max = _max(result.max, p + that._outer * that._options.minorTick.length)
  61322. }
  61323. if (that._labelsEnabled) {
  61324. if (that._options.label.indentFromTick > 0)
  61325. result.max += +_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
  61326. else
  61327. result.min -= -_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
  61328. result.indent = that[that.vertical ? '_textHeight' : '_textWidth'] / 2
  61329. }
  61330. return result
  61331. }
  61332. })
  61333. })(DevExpress, jQuery);
  61334. /*! Module viz-gauges, file baseIndicator.js */
  61335. (function(DX, $, undefined) {
  61336. var _isFinite = isFinite,
  61337. _Number = Number,
  61338. _extend = $.extend;
  61339. DX.viz.gauges.__internals.BaseIndicator = DX.Class.inherit({
  61340. setup: function(parameters) {
  61341. var that = this;
  61342. that._renderer = parameters.renderer;
  61343. that._translator = parameters.translator;
  61344. that._owner = parameters.owner;
  61345. that._tracker = parameters.tracker;
  61346. that._className = parameters.className;
  61347. that._options = {};
  61348. that._rootElement = that._createRoot();
  61349. that._trackerElement = that._createTracker();
  61350. return that
  61351. },
  61352. dispose: function() {
  61353. var that = this;
  61354. that._renderer = that._owner = that._translator = that._tracker = that._options = that._rootElement = that._trackerElement = null;
  61355. return that
  61356. },
  61357. _setupAnimation: function() {
  61358. var that = this;
  61359. if (that._options.animation)
  61360. that._animation = {
  61361. step: function(pos) {
  61362. that._actualValue = that._animation.start + that._animation.delta * pos;
  61363. that._actualPosition = that._translator.translate(that._actualValue);
  61364. that._move()
  61365. },
  61366. duration: that._options.animation.duration > 0 ? _Number(that._options.animation.duration) : 0,
  61367. easing: that._options.animation.easing
  61368. }
  61369. },
  61370. _runAnimation: function(value) {
  61371. var that = this,
  61372. animation = that._animation;
  61373. animation.start = that._actualValue;
  61374. animation.delta = value - that._actualValue;
  61375. that._rootElement.animate({_: 0}, {
  61376. step: animation.step,
  61377. duration: animation.duration,
  61378. easing: animation.easing
  61379. })
  61380. },
  61381. _createRoot: function() {
  61382. return this._renderer.createGroup({'class': this._className})
  61383. },
  61384. _createTracker: function() {
  61385. return this._renderer.createArea()
  61386. },
  61387. _getTrackerSettings: function(){},
  61388. clean: function() {
  61389. var that = this;
  61390. that._animation && that._rootElement.stopAnimation();
  61391. that._rootElement.detach();
  61392. that._rootElement.clear();
  61393. that._clear();
  61394. that._tracker.detach(that._trackerElement);
  61395. that._options = that.enabled = that._animation = null;
  61396. return that
  61397. },
  61398. render: function(options) {
  61399. var that = this;
  61400. that.type = options.type;
  61401. that._options = options;
  61402. that._actualValue = that._currentValue = that._translator.adjust(that._options.currentValue);
  61403. that.enabled = that._isEnabled();
  61404. if (that.enabled) {
  61405. that._setupAnimation();
  61406. that._rootElement.applySettings({fill: that._options.color}).append(that._owner);
  61407. that._tracker.attach(that._trackerElement, that, that._trackerInfo)
  61408. }
  61409. return that
  61410. },
  61411. resize: function(layout) {
  61412. var that = this;
  61413. that._rootElement.clear();
  61414. that._clear();
  61415. that.visible = that._isVisible(layout);
  61416. if (that.visible) {
  61417. _extend(that._options, layout);
  61418. that._actualPosition = that._translator.translate(that._actualValue);
  61419. that._render();
  61420. that._trackerElement.applySettings(that._getTrackerSettings());
  61421. that._move()
  61422. }
  61423. return that
  61424. },
  61425. value: function(arg, _noAnimation) {
  61426. var that = this;
  61427. if (arg !== undefined) {
  61428. var val = that._translator.adjust(arg);
  61429. if (that._currentValue !== val && _isFinite(val)) {
  61430. that._currentValue = val;
  61431. if (that.visible)
  61432. if (that._animation && !_noAnimation)
  61433. that._runAnimation(val);
  61434. else {
  61435. that._actualValue = val;
  61436. that._actualPosition = that._translator.translate(val);
  61437. that._move()
  61438. }
  61439. }
  61440. return that
  61441. }
  61442. return that._currentValue
  61443. },
  61444. _isEnabled: null,
  61445. _isVisible: null,
  61446. _render: null,
  61447. _clear: null,
  61448. _move: null
  61449. })
  61450. })(DevExpress, jQuery);
  61451. /*! Module viz-gauges, file baseMarker.js */
  61452. (function(DX, undefined) {
  61453. var TextCloud = DX.viz.core.TextCloud;
  61454. var formatValue = DX.viz.gauges.__internals.formatValue,
  61455. getSampleText = DX.viz.gauges.__internals.getSampleText;
  61456. DX.viz.gauges.__internals.BaseTextCloudMarker = DX.viz.gauges.__internals.BaseIndicator.inherit({
  61457. _move: function() {
  61458. var that = this,
  61459. bbox,
  61460. info = new TextCloud,
  61461. textCloudOptions = that._getTextCloudOptions();
  61462. that._text.applySettings({text: formatValue(that._actualValue, that._options.text)});
  61463. bbox = that._text.getBBox();
  61464. info.setup({
  61465. x: textCloudOptions.x,
  61466. y: textCloudOptions.y,
  61467. textWidth: bbox.width,
  61468. textHeight: bbox.height,
  61469. horMargin: that._options.horizontalOffset,
  61470. verMargin: that._options.verticalOffset,
  61471. tailLength: that._options.arrowLength,
  61472. type: textCloudOptions.type
  61473. });
  61474. that._text.applySettings({
  61475. x: info.cx(),
  61476. y: info.cy() + that._textVerticalOffset
  61477. });
  61478. that._cloud.applySettings({points: info.points()});
  61479. that._trackerElement && that._trackerElement.applySettings({points: info.points()})
  61480. },
  61481. _measureText: function() {
  61482. var that = this,
  61483. root,
  61484. text,
  61485. bbox;
  61486. if (!that._textVerticalOffset) {
  61487. root = that._createRoot().append(that._owner);
  61488. text = that._renderer.createText(getSampleText(that._translator, that._options.text), 0, 0, {
  61489. align: 'center',
  61490. font: that._options.text.font
  61491. }).append(root);
  61492. bbox = text.getBBox();
  61493. root.remove();
  61494. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  61495. that._textWidth = bbox.width;
  61496. that._textHeight = bbox.height;
  61497. that._textFullWidth = that._textWidth + 2 * that._options.horizontalOffset;
  61498. that._textFullHeight = that._textHeight + 2 * that._options.verticalOffset
  61499. }
  61500. },
  61501. _render: function() {
  61502. var that = this;
  61503. that._measureText();
  61504. that._cloud = that._cloud || that._renderer.createArea().append(that._rootElement);
  61505. that._text = that._text || that._renderer.createText().append(that._rootElement);
  61506. that._text.applySettings({
  61507. align: 'center',
  61508. font: that._options.text.font
  61509. })
  61510. },
  61511. _clear: function() {
  61512. delete this._cloud;
  61513. delete this._text
  61514. },
  61515. getTooltipParameters: function() {
  61516. var position = this._getTextCloudOptions();
  61517. return {
  61518. x: position.x,
  61519. y: position.y,
  61520. value: this._currentValue,
  61521. color: this._options.color
  61522. }
  61523. }
  61524. })
  61525. })(DevExpress);
  61526. /*! Module viz-gauges, file baseRangeBar.js */
  61527. (function(DX, $, undefined) {
  61528. var $extend = $.extend;
  61529. var formatValue = DX.viz.gauges.__internals.formatValue,
  61530. getSampleText = DX.viz.gauges.__internals.getSampleText;
  61531. DX.viz.gauges.__internals.BaseRangeBar = DX.viz.gauges.__internals.BaseIndicator.inherit({
  61532. _measureText: function() {
  61533. var that = this,
  61534. root,
  61535. text,
  61536. bbox;
  61537. that._hasText = that._isTextVisible();
  61538. if (that._hasText && !that._textVerticalOffset) {
  61539. root = that._createRoot().append(that._owner);
  61540. text = that._renderer.createText(getSampleText(that._translator, that._options.text), 0, 0, {
  61541. 'class': 'dxg-text',
  61542. align: 'center',
  61543. font: that._options.text.font
  61544. }).append(root);
  61545. bbox = text.getBBox();
  61546. root.remove();
  61547. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  61548. that._textWidth = bbox.width;
  61549. that._textHeight = bbox.height
  61550. }
  61551. },
  61552. _move: function() {
  61553. var that = this;
  61554. that._updateBarItemsPositions();
  61555. if (that._hasText) {
  61556. that._text.applySettings({text: formatValue(that._actualValue, that._options.text)});
  61557. that._updateTextPosition();
  61558. that._updateLinePosition()
  61559. }
  61560. },
  61561. _updateBarItems: function() {
  61562. var that = this,
  61563. options = that._options,
  61564. backgroundColor,
  61565. spaceColor;
  61566. that._setBarSides();
  61567. that._startPosition = that._translator.translate(that._translator.getDomainStart());
  61568. that._endPosition = that._translator.translate(that._translator.getDomainEnd());
  61569. that._basePosition = that._translator.translate(options.baseValue);
  61570. that._space = that._getSpace();
  61571. backgroundColor = options.backgroundColor || 'none';
  61572. if (backgroundColor !== 'none' && that._space > 0)
  61573. spaceColor = options.containerBackgroundColor || 'none';
  61574. else {
  61575. that._space = 0;
  61576. spaceColor = 'none'
  61577. }
  61578. that._backItem1.applySettings({fill: backgroundColor});
  61579. that._backItem2.applySettings({fill: backgroundColor});
  61580. that._spaceItem1.applySettings({fill: spaceColor});
  61581. that._spaceItem2.applySettings({fill: spaceColor})
  61582. },
  61583. _getSpace: function() {
  61584. return 0
  61585. },
  61586. _updateTextItems: function() {
  61587. var that = this;
  61588. if (that._hasText) {
  61589. that._line = that._line || that._renderer.createPath([], {'class': 'dxg-main-bar'}).append(that._rootElement);
  61590. that._text = that._text || that._renderer.createText('', 0, 0, {'class': 'dxg-text'}).append(that._rootElement);
  61591. that._text.applySettings({
  61592. align: that._getTextAlign(),
  61593. font: that._getFontOptions()
  61594. });
  61595. that._setTextItemsSides()
  61596. }
  61597. else {
  61598. if (that._line) {
  61599. that._line.remove();
  61600. delete that._line
  61601. }
  61602. if (that._text) {
  61603. that._text.remove();
  61604. delete that._text
  61605. }
  61606. }
  61607. },
  61608. _isTextVisible: function() {
  61609. return false
  61610. },
  61611. _getTextAlign: function() {
  61612. return 'center'
  61613. },
  61614. _getFontOptions: function() {
  61615. var options = this._options,
  61616. font = options.text.font;
  61617. if (!font || !font.color)
  61618. font = $extend({}, font, {color: options.color});
  61619. return font
  61620. },
  61621. _updateBarItemsPositions: function() {
  61622. var that = this,
  61623. positions = that._getPositions();
  61624. that._backItem1.applySettings(that._buildItemSettings(positions.start, positions.back1));
  61625. that._backItem2.applySettings(that._buildItemSettings(positions.back2, positions.end));
  61626. that._spaceItem1.applySettings(that._buildItemSettings(positions.back1, positions.main1));
  61627. that._spaceItem2.applySettings(that._buildItemSettings(positions.main2, positions.back2));
  61628. that._mainItem.applySettings(that._buildItemSettings(positions.main1, positions.main2));
  61629. that._trackerElement && that._trackerElement.applySettings(that._buildItemSettings(positions.main1, positions.main2))
  61630. },
  61631. _render: function() {
  61632. var that = this;
  61633. that._measureText();
  61634. if (!that._backItem1) {
  61635. that._backItem1 = that._createBarItem();
  61636. that._backItem1.applySettings({'class': 'dxg-back-bar'})
  61637. }
  61638. if (!that._backItem2) {
  61639. that._backItem2 = that._createBarItem();
  61640. that._backItem2.applySettings({'class': 'dxg-back-bar'})
  61641. }
  61642. if (!that._spaceItem1) {
  61643. that._spaceItem1 = that._createBarItem();
  61644. that._spaceItem1.applySettings({'class': 'dxg-space-bar'})
  61645. }
  61646. if (!that._spaceItem2) {
  61647. that._spaceItem2 = that._createBarItem();
  61648. that._spaceItem2.applySettings({'class': 'dxg-space-bar'})
  61649. }
  61650. if (!that._mainItem) {
  61651. that._mainItem = that._createBarItem();
  61652. that._mainItem.applySettings({'class': 'dxg-main-bar'})
  61653. }
  61654. that._updateBarItems();
  61655. that._updateTextItems()
  61656. },
  61657. _clear: function() {
  61658. var that = this;
  61659. delete that._backItem1;
  61660. delete that._backItem2;
  61661. delete that._spaceItem1;
  61662. delete that._spaceItem2;
  61663. delete that._mainItem;
  61664. delete that._hasText;
  61665. delete that._line;
  61666. delete that._text
  61667. },
  61668. getTooltipParameters: function() {
  61669. var position = this._getTooltipPosition();
  61670. return {
  61671. x: position.x,
  61672. y: position.y,
  61673. value: this._currentValue,
  61674. color: this._options.color,
  61675. offset: 0
  61676. }
  61677. }
  61678. })
  61679. })(DevExpress, jQuery);
  61680. /*! Module viz-gauges, file circularNeedle.js */
  61681. (function(DX, undefined) {
  61682. var circularNeedles = DX.viz.gauges.__internals.circularNeedles;
  61683. var _Number = Number;
  61684. circularNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
  61685. _move: function() {
  61686. var that = this,
  61687. options = that._options,
  61688. angle = DX.utils.convertAngleToRendererSpace(that._actualPosition);
  61689. that._rootElement.rotate(angle, options.x, options.y);
  61690. that._trackerElement && that._trackerElement.rotate(angle, options.x, options.y)
  61691. },
  61692. _isEnabled: function() {
  61693. return this._options.width > 0
  61694. },
  61695. _isVisible: function(layout) {
  61696. return layout.radius - _Number(this._options.indentFromCenter) > 0
  61697. },
  61698. _getTrackerSettings: function() {
  61699. var options = this._options,
  61700. x = options.x,
  61701. y = options.y - (options.radius + _Number(options.indentFromCenter)) / 2,
  61702. width = options.width / 2,
  61703. length = (options.radius - _Number(options.indentFromCenter)) / 2;
  61704. width > 10 || (width = 10);
  61705. length > 10 || (length = 10);
  61706. return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
  61707. },
  61708. _renderSpindle: function() {
  61709. var that = this,
  61710. options = that._options,
  61711. gapSize;
  61712. if (options.spindleSize > 0) {
  61713. gapSize = _Number(options.spindleGapSize) || 0;
  61714. if (gapSize > 0)
  61715. gapSize = gapSize <= options.spindleSize ? gapSize : _Number(options.spindleSize);
  61716. that._spindleOuter = that._spindleOuter || that._renderer.createCircle().append(that._rootElement);
  61717. that._spindleInner = that._spindleInner || that._renderer.createCircle().append(that._rootElement);
  61718. that._spindleOuter.applySettings({
  61719. 'class': 'dxg-spindle-border',
  61720. cx: options.x,
  61721. cy: options.y,
  61722. r: options.spindleSize / 2
  61723. });
  61724. that._spindleInner.applySettings({
  61725. 'class': 'dxg-spindle-hole',
  61726. cx: options.x,
  61727. cy: options.y,
  61728. r: gapSize / 2,
  61729. fill: options.containerBackgroundColor
  61730. })
  61731. }
  61732. },
  61733. _render: function() {
  61734. var that = this;
  61735. that._renderPointer();
  61736. that._renderSpindle()
  61737. },
  61738. _clearSpindle: function() {
  61739. delete this._spindleOuter;
  61740. delete this._spindleInner
  61741. },
  61742. _clearPointer: function() {
  61743. delete this._element
  61744. },
  61745. _clear: function() {
  61746. this._clearPointer();
  61747. this._clearSpindle()
  61748. },
  61749. measure: function(layout) {
  61750. var result = {max: layout.radius};
  61751. if (this._options.indentFromCenter < 0)
  61752. result.inverseHorizontalOffset = result.inverseVerticalOffset = -_Number(this._options.indentFromCenter);
  61753. return result
  61754. },
  61755. getTooltipParameters: function() {
  61756. var options = this._options,
  61757. cossin = DX.utils.getCosAndSin(this._actualPosition),
  61758. r = (options.radius + _Number(options.indentFromCenter)) / 2;
  61759. return {
  61760. x: options.x + cossin.cos * r,
  61761. y: options.y - cossin.sin * r,
  61762. value: this._currentValue,
  61763. color: options.color,
  61764. offset: options.width / 2
  61765. }
  61766. }
  61767. });
  61768. circularNeedles.RectangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
  61769. var that = this,
  61770. options = that._options,
  61771. y2 = options.y - options.radius,
  61772. y1 = options.y - _Number(options.indentFromCenter),
  61773. x1 = options.x - options.width / 2,
  61774. x2 = x1 + _Number(options.width);
  61775. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  61776. that._element.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
  61777. }});
  61778. circularNeedles.TriangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
  61779. var that = this,
  61780. options = that._options,
  61781. y2 = options.y - options.radius,
  61782. y1 = options.y - _Number(options.indentFromCenter),
  61783. x1 = options.x - options.width / 2,
  61784. x2 = options.x + options.width / 2;
  61785. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  61786. that._element.applySettings({points: [x1, y1, options.x, y2, x2, y1]})
  61787. }});
  61788. circularNeedles.TwoColorRectangleNeedle = circularNeedles.SimpleIndicator.inherit({
  61789. _renderPointer: function() {
  61790. var that = this,
  61791. options = that._options,
  61792. x1 = options.x - options.width / 2,
  61793. x2 = options.x + options.width / 2,
  61794. y4 = options.y - options.radius,
  61795. y1 = options.y - _Number(options.indentFromCenter),
  61796. fraction = _Number(options.secondFraction) || 0,
  61797. y2,
  61798. y3;
  61799. if (fraction >= 1)
  61800. y2 = y3 = y1;
  61801. else if (fraction <= 0)
  61802. y2 = y3 = y2;
  61803. else {
  61804. y3 = y4 + (y1 - y4) * fraction;
  61805. y2 = y3 + options.space
  61806. }
  61807. that._firstElement = that._firstElement || that._renderer.createArea().append(that._rootElement);
  61808. that._spaceElement = that._spaceElement || that._renderer.createArea().append(that._rootElement);
  61809. that._secondElement = that._secondElement || that._renderer.createArea().append(that._rootElement);
  61810. that._firstElement.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]});
  61811. that._spaceElement.applySettings({
  61812. points: [x1, y2, x1, y3, x2, y3, x2, y2],
  61813. 'class': 'dxg-hole',
  61814. fill: options.containerBackgroundColor
  61815. });
  61816. that._secondElement.applySettings({
  61817. points: [x1, y3, x1, y4, x2, y4, x2, y3],
  61818. 'class': 'dxg-part',
  61819. fill: options.secondColor
  61820. })
  61821. },
  61822. _clearPointer: function() {
  61823. delete this._firstElement;
  61824. delete this._secondElement;
  61825. delete this._spaceElement
  61826. }
  61827. })
  61828. })(DevExpress);
  61829. /*! Module viz-gauges, file linearNeedle.js */
  61830. (function(DX, undefined) {
  61831. var linearNeedles = DX.viz.gauges.__internals.linearNeedles;
  61832. var _Number = Number;
  61833. linearNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
  61834. _move: function() {
  61835. var that = this,
  61836. delta = that._actualPosition - that._zeroPosition;
  61837. that._rootElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0);
  61838. that._trackerElement && that._trackerElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0)
  61839. },
  61840. _isEnabled: function() {
  61841. this.vertical = this._options.vertical;
  61842. return this._options.length > 0 && this._options.width > 0
  61843. },
  61844. _isVisible: function(layout) {
  61845. return true
  61846. },
  61847. _getTrackerSettings: function() {
  61848. var options = this._options,
  61849. x1,
  61850. x2,
  61851. y1,
  61852. y2,
  61853. width = options.width / 2,
  61854. length = options.length / 2,
  61855. p = this._zeroPosition;
  61856. width > 10 || (width = 10);
  61857. length > 10 || (length = 10);
  61858. if (this.vertical) {
  61859. x1 = options.x - length;
  61860. x2 = options.x + length;
  61861. y1 = p + width;
  61862. y2 = p - width
  61863. }
  61864. else {
  61865. x1 = p - width;
  61866. x2 = p + width;
  61867. y1 = options.y + length;
  61868. y2 = options.y - length
  61869. }
  61870. return {points: [x1, y1, x1, y2, x2, y2, x2, y1]}
  61871. },
  61872. _render: function() {
  61873. var that = this;
  61874. that._zeroPosition = that._translator.getCodomainStart()
  61875. },
  61876. _clear: function() {
  61877. delete this._element
  61878. },
  61879. measure: function(layout) {
  61880. var p = this.vertical ? layout.x : layout.y;
  61881. return {
  61882. min: p - this._options.length / 2,
  61883. max: p + this._options.length / 2
  61884. }
  61885. },
  61886. getTooltipParameters: function() {
  61887. var that = this,
  61888. options = that._options,
  61889. p = that._actualPosition,
  61890. parameters = {
  61891. x: p,
  61892. y: p,
  61893. value: that._currentValue,
  61894. color: options.color,
  61895. offset: options.width / 2
  61896. };
  61897. that.vertical ? parameters.x = options.x : parameters.y = options.y;
  61898. return parameters
  61899. }
  61900. });
  61901. linearNeedles.RectangleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  61902. var that = this,
  61903. options = that._options,
  61904. p,
  61905. x1,
  61906. x2,
  61907. y1,
  61908. y2;
  61909. that.callBase();
  61910. p = that._zeroPosition;
  61911. if (that.vertical) {
  61912. x1 = options.x - options.length / 2;
  61913. x2 = options.x + options.length / 2;
  61914. y1 = p + options.width / 2;
  61915. y2 = p - options.width / 2
  61916. }
  61917. else {
  61918. x1 = p - options.width / 2;
  61919. x2 = p + options.width / 2;
  61920. y1 = options.y + options.length / 2;
  61921. y2 = options.y - options.length / 2
  61922. }
  61923. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  61924. that._element.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
  61925. }});
  61926. linearNeedles.RhombusNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  61927. var that = this,
  61928. options = that._options,
  61929. x,
  61930. y,
  61931. dx,
  61932. dy;
  61933. that.callBase();
  61934. if (that.vertical) {
  61935. x = options.x;
  61936. y = that._zeroPosition;
  61937. dx = options.length / 2 || 0;
  61938. dy = options.width / 2 || 0
  61939. }
  61940. else {
  61941. x = that._zeroPosition;
  61942. y = options.y;
  61943. dx = options.width / 2 || 0;
  61944. dy = options.length / 2 || 0
  61945. }
  61946. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  61947. that._element.applySettings({points: [x - dx, y, x, y - dy, x + dx, y, x, y + dy]})
  61948. }});
  61949. linearNeedles.CircleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  61950. var that = this,
  61951. options = that._options,
  61952. x,
  61953. y,
  61954. r;
  61955. that.callBase();
  61956. if (that.vertical) {
  61957. x = options.x;
  61958. y = that._zeroPosition
  61959. }
  61960. else {
  61961. x = that._zeroPosition;
  61962. y = options.y
  61963. }
  61964. r = options.length / 2 || 0;
  61965. that._element = that._element || that._renderer.createCircle().append(that._rootElement);
  61966. that._element.applySettings({
  61967. cx: x,
  61968. cy: y,
  61969. r: r
  61970. })
  61971. }})
  61972. })(DevExpress);
  61973. /*! Module viz-gauges, file circularMarker.js */
  61974. (function(DX, undefined) {
  61975. var circularMarkers = DX.viz.gauges.__internals.circularMarkers;
  61976. var _Number = Number;
  61977. circularMarkers.TriangleMarker = DX.viz.gauges.__internals.circularNeedles.SimpleIndicator.inherit({
  61978. _isEnabled: function() {
  61979. return this._options.length > 0 && this._options.width > 0
  61980. },
  61981. _isVisible: function(layout) {
  61982. return layout.radius > 0
  61983. },
  61984. _render: function() {
  61985. var that = this,
  61986. options = that._options,
  61987. x = options.x,
  61988. y1 = options.y - options.radius,
  61989. dx = options.width / 2 || 0,
  61990. y2 = y1 - _Number(options.length),
  61991. settings;
  61992. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  61993. settings = {
  61994. points: [x, y1, x - dx, y2, x + dx, y2],
  61995. stroke: 'none',
  61996. strokeWidth: 0
  61997. };
  61998. if (options.space > 0) {
  61999. settings.strokeWidth = Math.min(options.space, options.width / 4) || 0;
  62000. settings.stroke = settings.strokeWidth > 0 ? options.containerBackgroundColor || 'none' : 'none'
  62001. }
  62002. that._element.applySettings(settings)
  62003. },
  62004. _clear: function() {
  62005. delete this._element
  62006. },
  62007. _getTrackerSettings: function() {
  62008. var options = this._options,
  62009. x = options.x,
  62010. y = options.y - options.radius - options.length / 2,
  62011. width = options.width / 2,
  62012. length = options.length / 2;
  62013. width > 10 || (width = 10);
  62014. length > 10 || (length = 10);
  62015. return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
  62016. },
  62017. measure: function(layout) {
  62018. return {
  62019. min: layout.radius,
  62020. max: layout.radius + _Number(this._options.length)
  62021. }
  62022. },
  62023. getTooltipParameters: function() {
  62024. var options = this._options,
  62025. cossin = DX.utils.getCosAndSin(this._actualPosition),
  62026. r = options.radius + options.length / 2,
  62027. parameters = this.callBase();
  62028. parameters.x = options.x + cossin.cos * r;
  62029. parameters.y = options.y - cossin.sin * r;
  62030. parameters.offset = options.length / 2;
  62031. return parameters
  62032. }
  62033. });
  62034. circularMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
  62035. _isEnabled: function() {
  62036. return true
  62037. },
  62038. _isVisible: function(layout) {
  62039. return layout.radius > 0
  62040. },
  62041. _getTextCloudOptions: function() {
  62042. var that = this,
  62043. cossin = DX.utils.getCosAndSin(that._actualPosition),
  62044. nangle = DX.utils.normalizeAngle(that._actualPosition);
  62045. return {
  62046. x: that._options.x + cossin.cos * that._options.radius,
  62047. y: that._options.y - cossin.sin * that._options.radius,
  62048. type: nangle > 270 ? 'left-top' : nangle > 180 ? 'top-right' : nangle > 90 ? 'right-bottom' : 'bottom-left'
  62049. }
  62050. },
  62051. measure: function(layout) {
  62052. var that = this;
  62053. that._measureText();
  62054. return {
  62055. min: layout.radius,
  62056. max: layout.radius,
  62057. horizontalOffset: that._textFullWidth + (_Number(that._options.arrowLength) || 0),
  62058. verticalOffset: that._textFullHeight + (_Number(that._options.arrowLength) || 0)
  62059. }
  62060. }
  62061. })
  62062. })(DevExpress);
  62063. /*! Module viz-gauges, file linearMarker.js */
  62064. (function(DX, undefined) {
  62065. var linearMarkers = DX.viz.gauges.__internals.linearMarkers;
  62066. var _Number = Number,
  62067. _String = String;
  62068. linearMarkers.TriangleMarker = DX.viz.gauges.__internals.linearNeedles.SimpleIndicator.inherit({
  62069. _isEnabled: function() {
  62070. var that = this;
  62071. that.vertical = that._options.vertical;
  62072. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  62073. return that._options.length > 0 && that._options.width > 0
  62074. },
  62075. _isVisible: function(layout) {
  62076. return true
  62077. },
  62078. _render: function() {
  62079. var that = this,
  62080. options = that._options,
  62081. x1,
  62082. x2,
  62083. y1,
  62084. y2,
  62085. settings = {
  62086. stroke: 'none',
  62087. strokeWidth: 0
  62088. };
  62089. that.callBase();
  62090. if (that.vertical) {
  62091. x1 = options.x;
  62092. y1 = that._zeroPosition;
  62093. x2 = x1 + _Number(that._inverted ? options.length : -options.length);
  62094. settings.points = [x1, y1, x2, y1 - options.width / 2, x2, y1 + options.width / 2]
  62095. }
  62096. else {
  62097. y1 = options.y;
  62098. x1 = that._zeroPosition;
  62099. y2 = y1 + _Number(that._inverted ? options.length : -options.length);
  62100. settings.points = [x1, y1, x1 - options.width / 2, y2, x1 + options.width / 2, y2]
  62101. }
  62102. if (options.space > 0) {
  62103. settings.strokeWidth = Math.min(options.space, options.width / 4) || 0;
  62104. settings.stroke = settings.strokeWidth > 0 ? options.containerBackgroundColor || 'none' : 'none'
  62105. }
  62106. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  62107. that._element.applySettings(settings)
  62108. },
  62109. _getTrackerSettings: function() {
  62110. var that = this,
  62111. options = that._options,
  62112. width = options.width / 2,
  62113. length = _Number(options.length),
  62114. x1,
  62115. x2,
  62116. y1,
  62117. y2,
  62118. result;
  62119. width > 10 || (width = 10);
  62120. length > 20 || (length = 20);
  62121. if (that.vertical) {
  62122. x1 = x2 = options.x;
  62123. x2 = x1 + (that._inverted ? length : -length);
  62124. y1 = that._zeroPosition + width;
  62125. y2 = that._zeroPosition - width;
  62126. result = [x1, y1, x2, y1, x2, y2, x1, y2]
  62127. }
  62128. else {
  62129. y1 = options.y;
  62130. y2 = y1 + (that._inverted ? length : -length);
  62131. x1 = that._zeroPosition - width;
  62132. x2 = that._zeroPosition + width;
  62133. result = [x1, y1, x1, y2, x2, y2, x2, y1]
  62134. }
  62135. return {points: result}
  62136. },
  62137. measure: function(layout) {
  62138. var that = this,
  62139. length = _Number(that._options.length),
  62140. minbound,
  62141. maxbound;
  62142. if (that.vertical) {
  62143. minbound = maxbound = layout.x;
  62144. if (that._inverted)
  62145. maxbound = minbound + length;
  62146. else
  62147. minbound = maxbound - length
  62148. }
  62149. else {
  62150. minbound = maxbound = layout.y;
  62151. if (that._inverted)
  62152. maxbound = minbound + length;
  62153. else
  62154. minbound = maxbound - length
  62155. }
  62156. return {
  62157. min: minbound,
  62158. max: maxbound,
  62159. indent: that._options.width / 2
  62160. }
  62161. },
  62162. getTooltipParameters: function() {
  62163. var that = this,
  62164. options = that._options,
  62165. s = (that._inverted ? options.length : -options.length) / 2,
  62166. parameters = that.callBase();
  62167. that.vertical ? parameters.x += s : parameters.y += s;
  62168. parameters.offset = options.length / 2;
  62169. return parameters
  62170. }
  62171. });
  62172. linearMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
  62173. _isEnabled: function() {
  62174. var that = this;
  62175. that.vertical = that._options.vertical;
  62176. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  62177. return true
  62178. },
  62179. _isVisible: function(layout) {
  62180. return true
  62181. },
  62182. _getTextCloudOptions: function() {
  62183. var that = this,
  62184. x = that._actualPosition,
  62185. y = that._actualPosition,
  62186. type;
  62187. if (that.vertical) {
  62188. x = that._options.x;
  62189. type = that._inverted ? 'top-left' : 'top-right'
  62190. }
  62191. else {
  62192. y = that._options.y;
  62193. type = that._inverted ? 'right-top' : 'right-bottom'
  62194. }
  62195. return {
  62196. x: x,
  62197. y: y,
  62198. type: type
  62199. }
  62200. },
  62201. measure: function(layout) {
  62202. var that = this,
  62203. minbound,
  62204. maxbound,
  62205. arrowLength = _Number(that._options.arrowLength) || 0,
  62206. indent;
  62207. that._measureText();
  62208. if (that.vertical) {
  62209. indent = that._textFullHeight;
  62210. if (that._inverted) {
  62211. minbound = layout.x;
  62212. maxbound = layout.x + arrowLength + that._textFullWidth
  62213. }
  62214. else {
  62215. minbound = layout.x - arrowLength - that._textFullWidth;
  62216. maxbound = layout.x
  62217. }
  62218. }
  62219. else {
  62220. indent = that._textFullWidth;
  62221. if (that._inverted) {
  62222. minbound = layout.y;
  62223. maxbound = layout.y + arrowLength + that._textFullHeight
  62224. }
  62225. else {
  62226. minbound = layout.y - arrowLength - that._textFullHeight;
  62227. maxbound = layout.y
  62228. }
  62229. }
  62230. return {
  62231. min: minbound,
  62232. max: maxbound,
  62233. indent: indent
  62234. }
  62235. }
  62236. })
  62237. })(DevExpress);
  62238. /*! Module viz-gauges, file circularRangeBar.js */
  62239. (function(DX, undefined) {
  62240. var _Number = Number,
  62241. getCosAndSin = DX.utils.getCosAndSin,
  62242. convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  62243. max = Math.max,
  62244. min = Math.min;
  62245. DX.viz.gauges.__internals.CircularRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
  62246. _isEnabled: function() {
  62247. return this._options.size > 0
  62248. },
  62249. _isVisible: function(layout) {
  62250. return layout.radius - _Number(this._options.size) > 0
  62251. },
  62252. _createBarItem: function() {
  62253. return this._renderer.createArc().append(this._rootElement)
  62254. },
  62255. _createTracker: function() {
  62256. return this._renderer.createArc()
  62257. },
  62258. _setBarSides: function() {
  62259. var that = this;
  62260. that._maxSide = that._options.radius;
  62261. that._minSide = that._maxSide - _Number(that._options.size)
  62262. },
  62263. _getSpace: function() {
  62264. var options = this._options;
  62265. return options.space > 0 ? options.space * 180 / options.radius / Math.PI : 0
  62266. },
  62267. _isTextVisible: function() {
  62268. var options = this._options.text || {};
  62269. return options.indent > 0
  62270. },
  62271. _setTextItemsSides: function() {
  62272. var that = this,
  62273. options = that._options;
  62274. that._lineFrom = options.y - options.radius;
  62275. that._lineTo = that._lineFrom - _Number(options.text.indent);
  62276. that._textRadius = options.radius + _Number(options.text.indent)
  62277. },
  62278. _getPositions: function() {
  62279. var that = this,
  62280. basePosition = that._basePosition,
  62281. actualPosition = that._actualPosition,
  62282. mainPosition1,
  62283. mainPosition2;
  62284. if (basePosition >= actualPosition) {
  62285. mainPosition1 = basePosition;
  62286. mainPosition2 = actualPosition
  62287. }
  62288. else {
  62289. mainPosition1 = actualPosition;
  62290. mainPosition2 = basePosition
  62291. }
  62292. return {
  62293. start: that._startPosition,
  62294. end: that._endPosition,
  62295. main1: mainPosition1,
  62296. main2: mainPosition2,
  62297. back1: min(mainPosition1 + that._space, that._startPosition),
  62298. back2: max(mainPosition2 - that._space, that._endPosition)
  62299. }
  62300. },
  62301. _buildItemSettings: function(from, to) {
  62302. var that = this;
  62303. return {
  62304. x: that._options.x,
  62305. y: that._options.y,
  62306. innerRadius: that._minSide,
  62307. outerRadius: that._maxSide,
  62308. startAngle: to,
  62309. endAngle: from
  62310. }
  62311. },
  62312. _updateTextPosition: function() {
  62313. var that = this,
  62314. cossin = getCosAndSin(that._actualPosition),
  62315. x = that._options.x + that._textRadius * cossin.cos,
  62316. y = that._options.y - that._textRadius * cossin.sin;
  62317. x += cossin.cos * that._textWidth * 0.6;
  62318. y -= cossin.sin * that._textHeight * 0.6;
  62319. that._text.applySettings({
  62320. x: x,
  62321. y: y + that._textVerticalOffset
  62322. })
  62323. },
  62324. _updateLinePosition: function() {
  62325. var that = this,
  62326. x = that._options.x,
  62327. x1,
  62328. x2;
  62329. if (that._basePosition > that._actualPosition) {
  62330. x1 = x - 2;
  62331. x2 = x
  62332. }
  62333. else if (that._basePosition < that._actualPosition) {
  62334. x1 = x;
  62335. x2 = x + 2
  62336. }
  62337. else {
  62338. x1 = x - 1;
  62339. x2 = x + 1
  62340. }
  62341. that._line.applySettings({points: [x1, that._lineFrom, x1, that._lineTo, x2, that._lineTo, x2, that._lineFrom]});
  62342. that._line.rotate(convertAngleToRendererSpace(that._actualPosition), x, that._options.y)
  62343. },
  62344. _getTooltipPosition: function() {
  62345. var that = this,
  62346. cossin = getCosAndSin((that._basePosition + that._actualPosition) / 2),
  62347. r = (that._minSide + that._maxSide) / 2;
  62348. return {
  62349. x: that._options.x + cossin.cos * r,
  62350. y: that._options.y - cossin.sin * r
  62351. }
  62352. },
  62353. measure: function(layout) {
  62354. var that = this,
  62355. result = {
  62356. min: layout.radius - _Number(that._options.size),
  62357. max: layout.radius
  62358. };
  62359. that._measureText();
  62360. if (that._hasText) {
  62361. result.max += _Number(that._options.text.indent);
  62362. result.horizontalOffset = that._textWidth;
  62363. result.verticalOffset = that._textHeight
  62364. }
  62365. return result
  62366. }
  62367. })
  62368. })(DevExpress);
  62369. /*! Module viz-gauges, file linearRangeBar.js */
  62370. (function(DX, undefined) {
  62371. var _Number = Number,
  62372. _String = String;
  62373. DX.viz.gauges.__internals.LinearRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
  62374. _isEnabled: function() {
  62375. var that = this;
  62376. that.vertical = that._options.vertical;
  62377. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  62378. return that._options.size > 0
  62379. },
  62380. _isVisible: function(layout) {
  62381. return true
  62382. },
  62383. _createBarItem: function() {
  62384. return this._renderer.createArea().append(this._rootElement)
  62385. },
  62386. _createTracker: function() {
  62387. return this._renderer.createArea()
  62388. },
  62389. _setBarSides: function() {
  62390. var that = this,
  62391. options = that._options,
  62392. size = _Number(options.size),
  62393. minSide,
  62394. maxSide;
  62395. if (that.vertical)
  62396. if (that._inverted) {
  62397. minSide = options.x;
  62398. maxSide = options.x + size
  62399. }
  62400. else {
  62401. minSide = options.x - size;
  62402. maxSide = options.x
  62403. }
  62404. else if (that._inverted) {
  62405. minSide = options.y;
  62406. maxSide = options.y + size
  62407. }
  62408. else {
  62409. minSide = options.y - size;
  62410. maxSide = options.y
  62411. }
  62412. that._minSide = minSide;
  62413. that._maxSide = maxSide;
  62414. that._minBound = minSide;
  62415. that._maxBound = maxSide
  62416. },
  62417. _getSpace: function() {
  62418. var options = this._options;
  62419. return options.space > 0 ? _Number(options.space) : 0
  62420. },
  62421. _isTextVisible: function() {
  62422. var textOptions = this._options.text || {};
  62423. return textOptions.indent > 0 || textOptions.indent < 0
  62424. },
  62425. _getTextAlign: function() {
  62426. return this.vertical ? this._options.text.indent > 0 ? 'left' : 'right' : 'center'
  62427. },
  62428. _setTextItemsSides: function() {
  62429. var that = this,
  62430. indent = _Number(that._options.text.indent);
  62431. if (indent > 0) {
  62432. that._lineStart = that._maxSide;
  62433. that._lineEnd = that._maxSide + indent;
  62434. that._textPosition = that._lineEnd + (that.vertical ? 2 : that._textHeight / 2);
  62435. that._maxBound = that._textPosition + (that.vertical ? that._textWidth : that._textHeight / 2)
  62436. }
  62437. else if (indent < 0) {
  62438. that._lineStart = that._minSide;
  62439. that._lineEnd = that._minSide + indent;
  62440. that._textPosition = that._lineEnd - (that.vertical ? 2 : that._textHeight / 2);
  62441. that._minBound = that._textPosition - (that.vertical ? that._textWidth : that._textHeight / 2)
  62442. }
  62443. },
  62444. _getPositions: function() {
  62445. var that = this,
  62446. options = that._options,
  62447. startPosition = that._startPosition,
  62448. endPosition = that._endPosition,
  62449. space = that._space,
  62450. basePosition = that._basePosition,
  62451. actualPosition = that._actualPosition,
  62452. mainPosition1,
  62453. mainPosition2,
  62454. backPosition1,
  62455. backPosition2;
  62456. if (startPosition < endPosition) {
  62457. if (basePosition < actualPosition) {
  62458. mainPosition1 = basePosition;
  62459. mainPosition2 = actualPosition
  62460. }
  62461. else {
  62462. mainPosition1 = actualPosition;
  62463. mainPosition2 = basePosition
  62464. }
  62465. backPosition1 = mainPosition1 - space;
  62466. backPosition2 = mainPosition2 + space
  62467. }
  62468. else {
  62469. if (basePosition > actualPosition) {
  62470. mainPosition1 = basePosition;
  62471. mainPosition2 = actualPosition
  62472. }
  62473. else {
  62474. mainPosition1 = actualPosition;
  62475. mainPosition2 = basePosition
  62476. }
  62477. backPosition1 = mainPosition1 + space;
  62478. backPosition2 = mainPosition2 - space
  62479. }
  62480. return {
  62481. start: startPosition,
  62482. end: endPosition,
  62483. main1: mainPosition1,
  62484. main2: mainPosition2,
  62485. back1: backPosition1,
  62486. back2: backPosition2
  62487. }
  62488. },
  62489. _buildItemSettings: function(from, to) {
  62490. var that = this,
  62491. side1 = that._minSide,
  62492. side2 = that._maxSide;
  62493. var points = that.vertical ? [side1, from, side1, to, side2, to, side2, from] : [from, side1, from, side2, to, side2, to, side1];
  62494. return {points: points}
  62495. },
  62496. _updateTextPosition: function() {
  62497. var that = this;
  62498. that._text.applySettings(that.vertical ? {
  62499. x: that._textPosition,
  62500. y: that._actualPosition + that._textVerticalOffset
  62501. } : {
  62502. x: that._actualPosition,
  62503. y: that._textPosition + that._textVerticalOffset
  62504. })
  62505. },
  62506. _updateLinePosition: function() {
  62507. var that = this,
  62508. actualPosition = that._actualPosition,
  62509. side1,
  62510. side2,
  62511. points;
  62512. if (that.vertical) {
  62513. if (that._basePosition >= actualPosition) {
  62514. side1 = actualPosition;
  62515. side2 = actualPosition + 2
  62516. }
  62517. else {
  62518. side1 = actualPosition - 2;
  62519. side2 = actualPosition
  62520. }
  62521. points = [that._lineStart, side1, that._lineStart, side2, that._lineEnd, side2, that._lineEnd, side1]
  62522. }
  62523. else {
  62524. if (that._basePosition <= actualPosition) {
  62525. side1 = actualPosition - 2;
  62526. side2 = actualPosition
  62527. }
  62528. else {
  62529. side1 = actualPosition;
  62530. side2 = actualPosition + 2
  62531. }
  62532. points = [side1, that._lineStart, side1, that._lineEnd, side2, that._lineEnd, side2, that._lineStart]
  62533. }
  62534. that._line.applySettings({points: points})
  62535. },
  62536. _getTooltipPosition: function() {
  62537. var that = this,
  62538. crossCenter = (that._minSide + that._maxSide) / 2,
  62539. alongCenter = (that._basePosition + that._actualPosition) / 2,
  62540. position = {};
  62541. if (that.vertical)
  62542. position = {
  62543. x: crossCenter,
  62544. y: alongCenter
  62545. };
  62546. else
  62547. position = {
  62548. x: alongCenter,
  62549. y: crossCenter
  62550. };
  62551. return position
  62552. },
  62553. measure: function(layout) {
  62554. var that = this,
  62555. size = _Number(that._options.size),
  62556. textIndent = _Number(that._options.text.indent),
  62557. minbound,
  62558. maxbound,
  62559. indent;
  62560. that._measureText();
  62561. if (that.vertical) {
  62562. minbound = maxbound = layout.x;
  62563. if (that._inverted)
  62564. maxbound = maxbound + size;
  62565. else
  62566. minbound = minbound - size;
  62567. if (that._hasText) {
  62568. indent = that._textHeight / 2;
  62569. if (textIndent > 0)
  62570. maxbound += textIndent + that._textWidth;
  62571. if (textIndent < 0)
  62572. minbound += textIndent - that._textWidth
  62573. }
  62574. }
  62575. else {
  62576. minbound = maxbound = layout.y;
  62577. if (that._inverted)
  62578. maxbound = maxbound + size;
  62579. else
  62580. minbound = minbound - size;
  62581. if (that._hasText) {
  62582. indent = that._textWidth / 2;
  62583. if (textIndent > 0)
  62584. maxbound += textIndent + that._textHeight;
  62585. if (textIndent < 0)
  62586. minbound += textIndent - that._textHeight
  62587. }
  62588. }
  62589. return {
  62590. min: minbound,
  62591. max: maxbound,
  62592. indent: indent
  62593. }
  62594. }
  62595. })
  62596. })(DevExpress);
  62597. /*! Module viz-gauges, file rangeContainer.js */
  62598. (function(DX, $, undefined) {
  62599. var _Number = Number,
  62600. _String = String,
  62601. _max = Math.max,
  62602. _abs = Math.abs,
  62603. _isString = DX.utils.isString,
  62604. _isArray = DX.utils.isArray,
  62605. _isFinite = isFinite,
  62606. _each = $.each,
  62607. _map = $.map;
  62608. var _Palette = DX.viz.core.Palette;
  62609. DX.viz.gauges.__internals.BaseRangeContainer = DX.Class.inherit({
  62610. ctor: function(parameters) {
  62611. var that = this;
  62612. that._renderer = parameters.renderer;
  62613. that._container = parameters.container;
  62614. that._translator = parameters.translator;
  62615. that._root = that._renderer.createGroup({'class': 'dxg-range-container'})
  62616. },
  62617. dispose: function() {
  62618. var that = this;
  62619. that._renderer = that._container = that._translator = that._root = null
  62620. },
  62621. clean: function() {
  62622. this._root.detach().clear();
  62623. this._options = this.enabled = null;
  62624. return this
  62625. },
  62626. _getRanges: function() {
  62627. var that = this,
  62628. options = that._options,
  62629. translator = that._translator,
  62630. totalStart = translator.getDomain()[0],
  62631. totalEnd = translator.getDomain()[1],
  62632. totalDelta = totalEnd - totalStart,
  62633. isNotEmptySegment = totalDelta >= 0 ? isNotEmptySegmentAsc : isNotEmptySegmentDes,
  62634. subtractSegment = totalDelta >= 0 ? subtractSegmentAsc : subtractSegmentDes,
  62635. list = [],
  62636. ranges = [],
  62637. backgroundRanges = [{
  62638. start: totalStart,
  62639. end: totalEnd
  62640. }],
  62641. threshold = _abs(totalDelta) / 1E4,
  62642. palette = new _Palette(options.palette, {
  62643. type: 'indicatingSet',
  62644. theme: options.themeName
  62645. }),
  62646. backgroundColor = _isString(options.backgroundColor) ? options.backgroundColor : 'none',
  62647. width = options.width || {},
  62648. startWidth = _Number(width > 0 ? width : width.start),
  62649. endWidth = _Number(width > 0 ? width : width.end),
  62650. deltaWidth = endWidth - startWidth;
  62651. if (options.ranges !== undefined && !_isArray(options.ranges))
  62652. return null;
  62653. if (!(startWidth >= 0 && endWidth >= 0 && startWidth + endWidth > 0))
  62654. return null;
  62655. list = _map(_isArray(options.ranges) ? options.ranges : [], function(rangeOptions, i) {
  62656. rangeOptions = rangeOptions || {};
  62657. var start = translator.adjust(rangeOptions.startValue),
  62658. end = translator.adjust(rangeOptions.endValue);
  62659. return _isFinite(start) && _isFinite(end) && isNotEmptySegment(start, end, threshold) ? {
  62660. start: start,
  62661. end: end,
  62662. color: rangeOptions.color,
  62663. classIndex: i
  62664. } : null
  62665. });
  62666. _each(list, function(i, item) {
  62667. var paletteColor = palette.getNextColor();
  62668. item.color = _isString(item.color) && item.color || paletteColor || 'none';
  62669. item.className = 'dxg-range dxg-range-' + item.classIndex;
  62670. delete item.classIndex
  62671. });
  62672. _each(list, function(_, item) {
  62673. var i,
  62674. ii,
  62675. sub,
  62676. subs,
  62677. range,
  62678. newRanges = [],
  62679. newBackgroundRanges = [];
  62680. for (i = 0, ii = ranges.length; i < ii; ++i) {
  62681. range = ranges[i];
  62682. subs = subtractSegment(range.start, range.end, item.start, item.end);
  62683. (sub = subs[0]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub);
  62684. (sub = subs[1]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub)
  62685. }
  62686. newRanges.push(item);
  62687. ranges = newRanges;
  62688. for (i = 0, ii = backgroundRanges.length; i < ii; ++i) {
  62689. range = backgroundRanges[i];
  62690. subs = subtractSegment(range.start, range.end, item.start, item.end);
  62691. (sub = subs[0]) && newBackgroundRanges.push(sub);
  62692. (sub = subs[1]) && newBackgroundRanges.push(sub)
  62693. }
  62694. backgroundRanges = newBackgroundRanges
  62695. });
  62696. _each(backgroundRanges, function(_, range) {
  62697. range.color = backgroundColor;
  62698. range.className = 'dxg-range dxg-background-range';
  62699. ranges.push(range)
  62700. });
  62701. _each(ranges, function(_, range) {
  62702. range.startWidth = (range.start - totalStart) / totalDelta * deltaWidth + startWidth;
  62703. range.endWidth = (range.end - totalStart) / totalDelta * deltaWidth + startWidth
  62704. });
  62705. return ranges
  62706. },
  62707. render: function(options) {
  62708. var that = this;
  62709. that._options = options;
  62710. that._processOptions();
  62711. that._ranges = that._getRanges();
  62712. if (that._ranges) {
  62713. that.enabled = true;
  62714. that._root.append(that._container)
  62715. }
  62716. return that
  62717. },
  62718. resize: function(layout) {
  62719. var that = this;
  62720. that._root.clear();
  62721. if (that._isVisible(layout))
  62722. _each(that._ranges, function(_, range) {
  62723. that._createRange(range, layout).applySettings({
  62724. fill: range.color,
  62725. 'class': range.className
  62726. }).append(that._root)
  62727. });
  62728. return that
  62729. },
  62730. _processOptions: null,
  62731. _isVisible: null,
  62732. _createRange: null
  62733. });
  62734. function subtractSegmentAsc(segmentStart, segmentEnd, otherStart, otherEnd) {
  62735. var result;
  62736. if (otherStart > segmentStart && otherEnd < segmentEnd)
  62737. result = [{
  62738. start: segmentStart,
  62739. end: otherStart
  62740. }, {
  62741. start: otherEnd,
  62742. end: segmentEnd
  62743. }];
  62744. else if (otherStart >= segmentEnd || otherEnd <= segmentStart)
  62745. result = [{
  62746. start: segmentStart,
  62747. end: segmentEnd
  62748. }];
  62749. else if (otherStart <= segmentStart && otherEnd >= segmentEnd)
  62750. result = [];
  62751. else if (otherStart > segmentStart)
  62752. result = [{
  62753. start: segmentStart,
  62754. end: otherStart
  62755. }];
  62756. else if (otherEnd < segmentEnd)
  62757. result = [{
  62758. start: otherEnd,
  62759. end: segmentEnd
  62760. }];
  62761. return result
  62762. }
  62763. function subtractSegmentDes(segmentStart, segmentEnd, otherStart, otherEnd) {
  62764. var result;
  62765. if (otherStart < segmentStart && otherEnd > segmentEnd)
  62766. result = [{
  62767. start: segmentStart,
  62768. end: otherStart
  62769. }, {
  62770. start: otherEnd,
  62771. end: segmentEnd
  62772. }];
  62773. else if (otherStart <= segmentEnd || otherEnd >= segmentStart)
  62774. result = [{
  62775. start: segmentStart,
  62776. end: segmentEnd
  62777. }];
  62778. else if (otherStart >= segmentStart && otherEnd <= segmentEnd)
  62779. result = [];
  62780. else if (otherStart < segmentStart)
  62781. result = [{
  62782. start: segmentStart,
  62783. end: otherStart
  62784. }];
  62785. else if (otherEnd > segmentEnd)
  62786. result = [{
  62787. start: otherEnd,
  62788. end: segmentEnd
  62789. }];
  62790. return result
  62791. }
  62792. function isNotEmptySegmentAsc(start, end, threshold) {
  62793. return end - start >= threshold
  62794. }
  62795. function isNotEmptySegmentDes(start, end, threshold) {
  62796. return start - end >= threshold
  62797. }
  62798. DX.viz.gauges.__internals.CircularRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
  62799. _processOptions: function() {
  62800. var that = this;
  62801. that._inner = that._outer = 0;
  62802. switch (_String(that._options.orientation).toLowerCase()) {
  62803. case'inside':
  62804. that._inner = 1;
  62805. break;
  62806. case'center':
  62807. that._inner = that._outer = 0.5;
  62808. break;
  62809. default:
  62810. that._outer = 1;
  62811. break
  62812. }
  62813. },
  62814. _isVisible: function(layout) {
  62815. var width = this._options.width;
  62816. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  62817. return layout.radius - this._inner * width > 0
  62818. },
  62819. _createRange: function(range, layout) {
  62820. var that = this,
  62821. width = (range.startWidth + range.endWidth) / 2;
  62822. return that._renderer.createArc(layout.x, layout.y, layout.radius + that._outer * width, layout.radius - that._inner * width, that._translator.translate(range.end), that._translator.translate(range.start))
  62823. },
  62824. measure: function(layout) {
  62825. var width = this._options.width;
  62826. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  62827. return {
  62828. min: layout.radius - this._inner * width,
  62829. max: layout.radius + this._outer * width
  62830. }
  62831. }
  62832. });
  62833. DX.viz.gauges.__internals.LinearRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
  62834. _processOptions: function() {
  62835. var that = this;
  62836. that.vertical = that._options.vertical;
  62837. that._inner = that._outer = 0;
  62838. if (that.vertical)
  62839. switch (_String(that._options.horizontalOrientation).toLowerCase()) {
  62840. case'left':
  62841. that._inner = 1;
  62842. break;
  62843. case'center':
  62844. that._inner = that._outer = 0.5;
  62845. break;
  62846. default:
  62847. that._outer = 1;
  62848. break
  62849. }
  62850. else
  62851. switch (_String(that._options.verticalOrientation).toLowerCase()) {
  62852. case'top':
  62853. that._inner = 1;
  62854. break;
  62855. case'middle':
  62856. that._inner = that._outer = 0.5;
  62857. break;
  62858. default:
  62859. that._outer = 1;
  62860. break
  62861. }
  62862. },
  62863. _isVisible: function(layout) {
  62864. return true
  62865. },
  62866. _createRange: function(range, layout) {
  62867. var that = this,
  62868. inner = that._inner,
  62869. outer = that._outer,
  62870. startPosition = that._translator.translate(range.start),
  62871. endPosition = that._translator.translate(range.end),
  62872. points;
  62873. if (that.vertical)
  62874. points = [layout.x - range.startWidth * inner, startPosition, layout.x - range.endWidth * inner, endPosition, layout.x + range.endWidth * outer, endPosition, layout.x + range.startWidth * outer, startPosition];
  62875. else
  62876. points = [startPosition, layout.y + range.startWidth * outer, startPosition, layout.y - range.startWidth * inner, endPosition, layout.y - range.endWidth * inner, endPosition, layout.y + range.endWidth * outer];
  62877. return that._renderer.createArea(points)
  62878. },
  62879. measure: function(layout) {
  62880. var result = {};
  62881. result.min = result.max = layout[this.vertical ? 'x' : 'y'];
  62882. var width = this._options.width;
  62883. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  62884. result.min -= this._inner * width;
  62885. result.max += this._outer * width;
  62886. return result
  62887. }
  62888. })
  62889. })(DevExpress, jQuery);
  62890. /*! Module viz-gauges, file title.js */
  62891. (function(DX, $, undefined) {
  62892. var _isString = DX.utils.isString,
  62893. _max = Math.max,
  62894. _extend = $.extend;
  62895. DX.viz.gauges.__internals.Title = DX.Class.inherit({
  62896. ctor: function(parameters) {
  62897. this._renderer = parameters.renderer;
  62898. this._container = parameters.container
  62899. },
  62900. dispose: function() {
  62901. this._renderer = this._container = null;
  62902. return this
  62903. },
  62904. clean: function() {
  62905. var that = this;
  62906. if (that._root) {
  62907. that._root.detach().clear();
  62908. that._root = that._layout = null
  62909. }
  62910. return that
  62911. },
  62912. render: function(titleOptions, subtitleOptions) {
  62913. var that = this,
  62914. hasTitle = _isString(titleOptions.text) && titleOptions.text.length > 0,
  62915. hasSubtitle = _isString(subtitleOptions.text) && subtitleOptions.text.length > 0;
  62916. if (!hasTitle && !hasSubtitle)
  62917. return that;
  62918. that._root = that._renderer.createGroup({'class': 'dxg-title'}).append(that._container);
  62919. var title = hasTitle ? that._renderer.createText(titleOptions.text, 0, 0, {
  62920. align: 'center',
  62921. font: titleOptions.font
  62922. }).append(that._root) : null,
  62923. subtitle = hasSubtitle ? that._renderer.createText(subtitleOptions.text, 0, 0, {
  62924. align: 'center',
  62925. font: subtitleOptions.font
  62926. }).append(that._root) : null,
  62927. titleBox = title ? title.getBBox() : {},
  62928. subtitleBox = subtitle ? subtitle.getBBox() : {},
  62929. y = 0;
  62930. if (title) {
  62931. y += -titleBox.y;
  62932. title.applySettings({
  62933. x: 0,
  62934. y: y
  62935. })
  62936. }
  62937. if (subtitle) {
  62938. y += -subtitleBox.y;
  62939. subtitle.applySettings({
  62940. x: 0,
  62941. y: y
  62942. })
  62943. }
  62944. that._layout = _extend({
  62945. position: titleOptions.position,
  62946. width: _max(titleBox.width || 0, subtitleBox.width || 0),
  62947. height: title && subtitle ? -titleBox.y + subtitleBox.height : titleBox.height || subtitleBox.height
  62948. }, titleOptions.layout);
  62949. return that
  62950. },
  62951. getLayoutOptions: function() {
  62952. return this._layout
  62953. },
  62954. locate: function(left, top) {
  62955. this._root.applySettings({
  62956. translateX: left + this._layout.width / 2,
  62957. translateY: top
  62958. });
  62959. return this
  62960. }
  62961. })
  62962. })(DevExpress, jQuery);
  62963. /*! Module viz-gauges, file tooltip.js */
  62964. (function(DX, $, undefined) {
  62965. var _extend = $.extend;
  62966. DX.viz.gauges.__internals.Tooltip = DX.viz.core.Tooltip.inherit({
  62967. ctor: function(parameters) {
  62968. var that = this;
  62969. that._container = parameters.container;
  62970. that._tracker = parameters.tracker;
  62971. that._root = parameters.renderer.createGroup({'class': 'dxg-tooltip'});
  62972. that.callBase(null, that._root, parameters.renderer);
  62973. that._setTrackerCallbacks()
  62974. },
  62975. dispose: function() {
  62976. var that = this;
  62977. that._container = that._tracker = that._root = null;
  62978. return that._shadow ? that.callBase.apply(that, arguments) : that
  62979. },
  62980. _setTrackerCallbacks: function() {
  62981. var that = this;
  62982. function prepareCallback(target, info) {
  62983. var tooltipParameters = target.getTooltipParameters(),
  62984. formatObject = _extend({
  62985. value: tooltipParameters.value,
  62986. valueText: that.formatValue(tooltipParameters.value),
  62987. color: tooltipParameters.color
  62988. }, info);
  62989. return that.prepare(formatObject, {
  62990. x: tooltipParameters.x,
  62991. y: tooltipParameters.y,
  62992. offset: tooltipParameters.offset
  62993. })
  62994. }
  62995. function showCallback() {
  62996. return that.show()
  62997. }
  62998. function hideCallback() {
  62999. return that.hide()
  63000. }
  63001. that._tracker.setCallbacks({
  63002. 'tooltip-prepare': prepareCallback,
  63003. 'tooltip-show': showCallback,
  63004. 'tooltip-hide': hideCallback
  63005. })
  63006. },
  63007. clean: function() {
  63008. this._root.detach();
  63009. return this
  63010. },
  63011. render: function(options, size) {
  63012. var that = this;
  63013. options.canvasWidth = size.width;
  63014. options.canvasHeight = size.height;
  63015. options.text = {'class': 'dxg-text'};
  63016. that.update(options);
  63017. that._tracker.setTooltipState(that.enabled());
  63018. that.enabled() && that._root.append(that._container);
  63019. return that
  63020. }
  63021. })
  63022. })(DevExpress, jQuery);
  63023. /*! Module viz-gauges, file layoutManager.js */
  63024. (function(DX, $, undefined) {
  63025. var _Number = Number,
  63026. _String = String,
  63027. _min = Math.min,
  63028. _max = Math.max,
  63029. _each = $.each;
  63030. function patchLayoutOptions(options) {
  63031. if (options.position) {
  63032. var position = _String(options.position).toLowerCase().split('-');
  63033. options.verticalAlignment = position[0];
  63034. options.horizontalAlignment = position[1]
  63035. }
  63036. }
  63037. DX.viz.gauges.__internals.LayoutManager = DX.Class.inherit({
  63038. setRect: function(rect) {
  63039. this._currentRect = rect.clone();
  63040. return this
  63041. },
  63042. getRect: function() {
  63043. return this._currentRect.clone()
  63044. },
  63045. beginLayout: function(rect) {
  63046. this._rootRect = rect.clone();
  63047. this._currentRect = rect.clone();
  63048. this._cache = [];
  63049. return this
  63050. },
  63051. applyLayout: function(target) {
  63052. var options = target.getLayoutOptions();
  63053. if (!options)
  63054. return this;
  63055. var currentRect = this._currentRect,
  63056. verticalOverlay = _Number(options.overlay) || 0;
  63057. patchLayoutOptions(options);
  63058. switch (_String(options.verticalAlignment).toLowerCase()) {
  63059. case'bottom':
  63060. currentRect.bottom -= _max(options.height - verticalOverlay, 0);
  63061. break;
  63062. default:
  63063. currentRect.top += _max(options.height - verticalOverlay, 0);
  63064. break
  63065. }
  63066. this._cache.push({
  63067. target: target,
  63068. options: options
  63069. });
  63070. return this
  63071. },
  63072. endLayout: function() {
  63073. var that = this,
  63074. rootRect = that._rootRect,
  63075. currentRect = that._currentRect;
  63076. _each(that._cache, function(_, cacheItem) {
  63077. var options = cacheItem.options,
  63078. left,
  63079. top,
  63080. verticalOverlay = _Number(options.overlay) || 0;
  63081. switch (_String(options.verticalAlignment).toLowerCase()) {
  63082. case'bottom':
  63083. top = currentRect.bottom - verticalOverlay;
  63084. currentRect.bottom += _max(options.height - verticalOverlay, 0);
  63085. break;
  63086. default:
  63087. top = currentRect.top - options.height + verticalOverlay;
  63088. currentRect.top -= _max(options.height - verticalOverlay, 0);
  63089. break
  63090. }
  63091. switch (_String(options.horizontalAlignment).toLowerCase()) {
  63092. case'left':
  63093. left = rootRect.left;
  63094. break;
  63095. case'right':
  63096. left = rootRect.right - options.width;
  63097. break;
  63098. default:
  63099. left = rootRect.horizontalMiddle() - options.width / 2;
  63100. break
  63101. }
  63102. cacheItem.target.locate(left, top)
  63103. });
  63104. that._cache = null;
  63105. return that
  63106. },
  63107. selectRectByAspectRatio: function(aspectRatio, margins) {
  63108. var rect = this._currentRect.clone(),
  63109. selfAspectRatio,
  63110. width = 0,
  63111. height = 0;
  63112. margins = margins || {};
  63113. if (aspectRatio > 0) {
  63114. rect.left += margins.left || 0;
  63115. rect.right -= margins.right || 0;
  63116. rect.top += margins.top || 0;
  63117. rect.bottom -= margins.bottom || 0;
  63118. if (rect.width() > 0 && rect.height() > 0) {
  63119. selfAspectRatio = rect.height() / rect.width();
  63120. if (selfAspectRatio > 1)
  63121. aspectRatio < selfAspectRatio ? width = rect.width() : height = rect.height();
  63122. else
  63123. aspectRatio > selfAspectRatio ? height = rect.height() : width = rect.width();
  63124. width > 0 || (width = height / aspectRatio);
  63125. height > 0 || (height = width * aspectRatio);
  63126. width = (rect.width() - width) / 2;
  63127. height = (rect.height() - height) / 2;
  63128. rect.left += width;
  63129. rect.right -= width;
  63130. rect.top += height;
  63131. rect.bottom -= height
  63132. }
  63133. else {
  63134. rect.left = rect.right = rect.horizontalMiddle();
  63135. rect.top = rect.bottom = rect.verticalMiddle()
  63136. }
  63137. }
  63138. return rect
  63139. },
  63140. selectRectBySizes: function(sizes, margins) {
  63141. var rect = this._currentRect.clone(),
  63142. step;
  63143. margins = margins || {};
  63144. if (sizes) {
  63145. rect.left += margins.left || 0;
  63146. rect.right -= margins.right || 0;
  63147. rect.top += margins.top || 0;
  63148. rect.bottom -= margins.bottom || 0;
  63149. if (sizes.width > 0) {
  63150. step = (rect.width() - sizes.width) / 2;
  63151. if (step > 0) {
  63152. rect.left += step;
  63153. rect.right -= step
  63154. }
  63155. }
  63156. if (sizes.height > 0) {
  63157. step = (rect.height() - sizes.height) / 2;
  63158. if (step > 0) {
  63159. rect.top += step;
  63160. rect.bottom -= step
  63161. }
  63162. }
  63163. }
  63164. return rect
  63165. }
  63166. })
  63167. })(DevExpress, jQuery);
  63168. /*! Module viz-gauges, file themeManager.js */
  63169. (function(DX, $, undefined) {
  63170. var _extend = $.extend;
  63171. DX.viz.gauges.__internals.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  63172. _themeSection: 'gauge',
  63173. _initializeTheme: function() {
  63174. var that = this;
  63175. if (that._subTheme) {
  63176. var subTheme = _extend(true, {}, that._theme[that._subTheme], that._theme);
  63177. _extend(true, that._theme, subTheme)
  63178. }
  63179. that._initializeFont(that._theme.scale.label.font);
  63180. that._initializeFont(that._theme.valueIndicator.rangebar.text.font);
  63181. that._initializeFont(that._theme.subvalueIndicator.textcloud.text.font);
  63182. that._initializeFont(that._theme.valueIndicators.rangebar.text.font);
  63183. that._initializeFont(that._theme.valueIndicators.textcloud.text.font);
  63184. that._initializeFont(that._theme.title.font);
  63185. that._initializeFont(that._theme.subtitle.font);
  63186. that._initializeFont(that._theme.tooltip.font);
  63187. that._initializeFont(that._theme.indicator.text.font);
  63188. that._initializeFont(that._theme.loadingIndicator.font)
  63189. }
  63190. })
  63191. })(DevExpress, jQuery);
  63192. /*! Module viz-gauges, file presetManager.js */
  63193. /*! Module viz-gauges, file baseGauge.js */
  63194. (function(DX, $, undefined) {
  63195. var _Number = Number,
  63196. _isNumber = DX.utils.isNumber,
  63197. _isString = DX.utils.isString,
  63198. _getAppropriateFormat = DX.utils.getAppropriateFormat,
  63199. _extend = $.extend,
  63200. _each = $.each;
  63201. DX.viz.gauges.__internals.BaseGauge = DX.viz.core.BaseWidget.inherit({
  63202. _init: function() {
  63203. var that = this;
  63204. that.callBase.apply(that, arguments);
  63205. that._renderer = that._factory.createRenderer({
  63206. width: 1,
  63207. height: 1,
  63208. pathModified: that.option('pathModified'),
  63209. rtl: that.option('rtlEnabled')
  63210. });
  63211. that._root = that._renderer.getRoot();
  63212. that._root.applySettings({'class': 'dxg ' + that._rootClass});
  63213. that._translator = that._factory.createTranslator();
  63214. that._themeManager = that._factory.createThemeManager();
  63215. that._tracker = that._factory.createTracker({
  63216. renderer: that._renderer,
  63217. container: that._root
  63218. });
  63219. that._layoutManager = that._factory.createLayoutManager();
  63220. that._tooltip = that._factory.createTooltip({
  63221. renderer: that._renderer,
  63222. container: that._root,
  63223. tracker: that._tracker
  63224. });
  63225. that._title = that._factory.createTitle({
  63226. renderer: that._renderer,
  63227. container: that._root
  63228. });
  63229. that._deltaIndicator = that._factory.createDeltaIndicator({
  63230. renderer: that._renderer,
  63231. container: that._root
  63232. });
  63233. that._setupDomain();
  63234. that._themeManager.setTheme(that.option('theme'))
  63235. },
  63236. _dispose: function() {
  63237. var that = this;
  63238. that.callBase.apply(that, arguments);
  63239. that._renderer.dispose();
  63240. that._themeManager.dispose();
  63241. that._tracker.dispose();
  63242. that._title.dispose();
  63243. that._deltaIndicator && that._deltaIndicator.dispose();
  63244. that._tooltip.dispose();
  63245. that._disposeLoadIndicator();
  63246. that._renderer = that._root = that._translator = that._themeManager = that._tracker = that._layoutManager = that._title = that._tooltip = null
  63247. },
  63248. _refresh: function() {
  63249. var that = this,
  63250. callBase = that.callBase;
  63251. that._endLoading(function() {
  63252. callBase.call(that)
  63253. })
  63254. },
  63255. _clean: function() {
  63256. this._cleanCore()
  63257. },
  63258. _render: function() {
  63259. var that = this;
  63260. that._setupCodomain();
  63261. that._setupAnimationSettings();
  63262. if (that._calculateSize() && that._checkDomain()) {
  63263. that._renderer.draw(that._element()[0]);
  63264. that._setupDefaultFormat();
  63265. that._renderCore()
  63266. }
  63267. that._drawn()
  63268. },
  63269. _cleanCore: function() {
  63270. var that = this;
  63271. that._tooltip.clean();
  63272. that._title.clean();
  63273. that._deltaIndicator && that._deltaIndicator.clean();
  63274. that._tracker.deactivate();
  63275. that._cleanContent()
  63276. },
  63277. _renderCore: function() {
  63278. var that = this;
  63279. that._title.render(_extend(true, {}, that._themeManager.theme()['title'], processTitleOptions(that.option('title'))), _extend(true, {}, that._themeManager.theme()['subtitle'], processTitleOptions(that.option('subtitle'))));
  63280. that._deltaIndicator && that._deltaIndicator.render(_extend(true, {}, that._themeManager.theme()['indicator'], that.option('indicator')));
  63281. that._layoutManager.beginLayout(that._rootRect);
  63282. _each([that._deltaIndicator, that._title], function(_, item) {
  63283. item && that._layoutManager.applyLayout(item)
  63284. });
  63285. that._mainRect = that._layoutManager.getRect();
  63286. that._renderContent();
  63287. that._layoutManager.endLayout();
  63288. that._tooltip.render(_extend(true, {}, that._themeManager.theme()['tooltip'], that.option('tooltip')), {
  63289. width: that._width,
  63290. height: that._height
  63291. });
  63292. that._tracker.activate();
  63293. that._updateLoadIndicator(undefined, that._width, that._height);
  63294. that._noAnimation = null;
  63295. that.option('debugMode') === true && that._renderDebugInfo();
  63296. that._debug_rendered && that._debug_rendered()
  63297. },
  63298. _renderDebugInfo: function() {
  63299. var that = this,
  63300. group = that._debugGroup || that._renderer.createGroup({'class': 'debug-info'}).append(),
  63301. rect;
  63302. group.clear();
  63303. rect = that._rootRect;
  63304. that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
  63305. stroke: '#000000',
  63306. strokeWidth: 1,
  63307. fill: 'none'
  63308. }).append(group);
  63309. rect = that._mainRect;
  63310. that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
  63311. stroke: '#0000FF',
  63312. strokeWidth: 1,
  63313. fill: 'none'
  63314. }).append(group);
  63315. rect = that._layoutManager.getRect();
  63316. rect && that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
  63317. stroke: '#FF0000',
  63318. strokeWidth: 1,
  63319. fill: 'none'
  63320. }).append(group);
  63321. rect = that._title.getLayoutOptions() ? that._title._root.getBBox() : null;
  63322. rect && that._renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
  63323. stroke: '#00FF00',
  63324. strokeWidth: 1,
  63325. fill: 'none'
  63326. }).append(group);
  63327. rect = that._deltaIndicator && that._deltaIndicator.getLayoutOptions() ? that._deltaIndicator._root.getBBox() : null;
  63328. rect && that._renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
  63329. stroke: '#00FF00',
  63330. strokeWidth: 1,
  63331. fill: 'none'
  63332. }).append(group)
  63333. },
  63334. _resize: function() {
  63335. var that = this;
  63336. if (that._calculateSize()) {
  63337. that._resizing = that._noAnimation = true;
  63338. that._cleanCore();
  63339. that._renderCore();
  63340. that._resizing = null
  63341. }
  63342. },
  63343. render: function(options) {
  63344. options && options.animate !== undefined && !options.animate && (this._noAnimation = true);
  63345. this._refresh();
  63346. return this
  63347. },
  63348. showLoadingIndicator: function() {
  63349. this._showLoadIndicator(this._getLoadIndicatorOption(), {
  63350. width: this._width,
  63351. height: this._height
  63352. })
  63353. },
  63354. _getLoadIndicatorOption: function() {
  63355. return _extend(true, {}, this._themeManager.theme()['loadingIndicator'], this.option('loadingIndicator'))
  63356. },
  63357. _optionChanged: function(name, newv, oldv) {
  63358. var that = this;
  63359. switch (name) {
  63360. case'theme':
  63361. that._themeManager.setTheme(newv);
  63362. that._invalidate();
  63363. break;
  63364. case'startValue':
  63365. case'endValue':
  63366. that._setupDomain();
  63367. that._invalidate();
  63368. break;
  63369. default:
  63370. that.callBase.apply(that, arguments);
  63371. break
  63372. }
  63373. },
  63374. _calculateSize: function() {
  63375. var that = this;
  63376. that._calculateSizeCore();
  63377. if (that._width === 0 || that._height === 0 || !that._element().is(':visible')) {
  63378. that._incidentOccured('W2001', [that.NAME]);
  63379. return false
  63380. }
  63381. else {
  63382. that._renderer.resize(that._width, that._height);
  63383. return true
  63384. }
  63385. },
  63386. _checkDomain: function() {
  63387. var that = this,
  63388. domain = that._translator.getDomain(),
  63389. isValid = isFinite(1 / (domain[1] - domain[0]));
  63390. if (!isValid)
  63391. that._incidentOccured('W2301');
  63392. return isValid
  63393. },
  63394. _setupAnimationSettings: function() {
  63395. var that = this,
  63396. option = that.option('animation');
  63397. that._animationSettings = null;
  63398. if (option === undefined || option) {
  63399. if (option === undefined)
  63400. option = {
  63401. enabled: that.option('animationEnabled'),
  63402. duration: that.option('animationDuration')
  63403. };
  63404. option = _extend({
  63405. enabled: true,
  63406. duration: 1000,
  63407. easing: 'easeOutCubic'
  63408. }, option);
  63409. if (option.enabled && option.duration > 0)
  63410. that._animationSettings = {
  63411. duration: _Number(option.duration),
  63412. easing: option.easing
  63413. }
  63414. }
  63415. that._containerBackgroundColor = that.option('containerBackgroundColor') || that._themeManager.theme().containerBackgroundColor
  63416. },
  63417. _setupDefaultFormat: function() {
  63418. var domain = this._translator.getDomain();
  63419. this._defaultFormatOptions = _getAppropriateFormat(domain[0], domain[1], this._getApproximateScreenRange())
  63420. },
  63421. _setupDomain: null,
  63422. _calculateSizeCore: null,
  63423. _cleanContent: null,
  63424. _renderContent: null,
  63425. _setupCodomain: null,
  63426. _getApproximateScreenRange: null,
  63427. _factory: {
  63428. createRenderer: DX.viz.core.CoreFactory.createRenderer,
  63429. createTranslator: function() {
  63430. return new DX.viz.core.Translator1D
  63431. },
  63432. createTracker: function(parameters) {
  63433. return new DX.viz.gauges.__internals.Tracker(parameters)
  63434. },
  63435. createLayoutManager: function() {
  63436. return new DX.viz.gauges.__internals.LayoutManager
  63437. },
  63438. createTitle: function(parameters) {
  63439. return new DX.viz.gauges.__internals.Title(parameters)
  63440. },
  63441. createDeltaIndicator: function(parameters) {
  63442. return DX.viz.gauges.__internals.DeltaIndicator ? new DX.viz.gauges.__internals.DeltaIndicator(parameters) : null
  63443. },
  63444. createTooltip: function(parameters) {
  63445. return new DX.viz.gauges.__internals.Tooltip(parameters)
  63446. }
  63447. }
  63448. });
  63449. function processTitleOptions(options) {
  63450. return _isString(options) ? {text: options} : options || {}
  63451. }
  63452. })(DevExpress, jQuery);
  63453. /*! Module viz-gauges, file gauge.js */
  63454. (function(DX, $, undefined) {
  63455. var _Rectangle = DX.viz.core.Rectangle;
  63456. var _isDefined = DX.utils.isDefined,
  63457. _isArray = DX.utils.isArray,
  63458. _isNumber = DX.utils.isNumber,
  63459. _isFinite = isFinite,
  63460. _Number = Number,
  63461. _String = String,
  63462. _abs = Math.abs,
  63463. _extend = $.extend,
  63464. _each = $.each,
  63465. _map = $.map,
  63466. _noop = $.noop;
  63467. var OPTION_VALUE = 'value',
  63468. OPTION_SUBVALUES = 'subvalues';
  63469. DX.viz.gauges.Gauge = DX.viz.gauges.__internals.BaseGauge.inherit({
  63470. _init: function() {
  63471. var that = this;
  63472. that.__value = that.option(OPTION_VALUE);
  63473. that.__subvalues = that.option(OPTION_SUBVALUES);
  63474. if (!_isArray(that.__subvalues))
  63475. that.__subvalues = _isNumber(that.__subvalues) ? [that.__subvalues] : null;
  63476. that._selectMode();
  63477. that.callBase.apply(that, arguments);
  63478. that._scale = that._createScale({
  63479. renderer: that._renderer,
  63480. container: that._root,
  63481. translator: that._translator
  63482. });
  63483. that._rangeContainer = that._createRangeContainer({
  63484. renderer: that._renderer,
  63485. container: that._root,
  63486. translator: that._translator
  63487. })
  63488. },
  63489. _dispose: function() {
  63490. var that = this;
  63491. that.callBase.apply(that, arguments);
  63492. that._scale.dispose();
  63493. that._rangeContainer.dispose();
  63494. that._disposeValueIndicators();
  63495. that._scale = that._rangeContainer = null
  63496. },
  63497. _disposeValueIndicators: function() {
  63498. var that = this;
  63499. that._valueIndicator && that._valueIndicator.dispose();
  63500. that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.dispose();
  63501. that._valueIndicator = that._subvalueIndicatorsSet = null
  63502. },
  63503. _selectMode: function() {
  63504. var that = this;
  63505. if (that.option(OPTION_VALUE) === undefined && that.option(OPTION_SUBVALUES) === undefined)
  63506. if (that.option('needles') !== undefined || that.option('markers') !== undefined || that.option('rangeBars') !== undefined) {
  63507. disableDefaultMode(that);
  63508. selectObsoleteMode(that)
  63509. }
  63510. else if (that.option('valueIndicators') !== undefined) {
  63511. disableDefaultMode(that);
  63512. selectHardMode(that)
  63513. }
  63514. },
  63515. _setupDomain: function() {
  63516. var that = this,
  63517. scaleOption = that.option('scale') || {},
  63518. startValue = that.option('startValue'),
  63519. endValue = that.option('endValue');
  63520. startValue = _isNumber(startValue) ? _Number(startValue) : _isNumber(scaleOption.startValue) ? _Number(scaleOption.startValue) : 0;
  63521. endValue = _isNumber(endValue) ? _Number(endValue) : _isNumber(scaleOption.endValue) ? _Number(scaleOption.endValue) : 100;
  63522. that._baseValue = startValue < endValue ? startValue : endValue;
  63523. that._translator.setDomain(startValue, endValue);
  63524. that._setupValueState()
  63525. },
  63526. _setupValueState: function() {
  63527. this._setupValue();
  63528. this.__subvalues !== null && this._setupSubvalues()
  63529. },
  63530. _calculateSizeCore: function() {
  63531. var that = this,
  63532. size = that.option('size') || {},
  63533. margin = that.option('margin') || {};
  63534. if (_Number(size.width) === 0 || _Number(size.height) === 0) {
  63535. that._width = that._height = 0;
  63536. that._rootRect = new _Rectangle
  63537. }
  63538. else {
  63539. var width = size.width > 0 ? _Number(size.width) : that._element().width() || that._getDefaultContainerSize().width,
  63540. height = size.height > 0 ? _Number(size.height) : that._element().height() || that._getDefaultContainerSize().height,
  63541. marginL = margin.left > 0 ? _Number(margin.left) : 0,
  63542. marginR = margin.right > 0 ? _Number(margin.right) : 0,
  63543. marginT = margin.top > 0 ? _Number(margin.top) : 0,
  63544. marginB = margin.bottom > 0 ? _Number(margin.bottom) : 0;
  63545. marginL + marginR >= width && (marginL = marginR = 0);
  63546. marginT + marginB >= height && (marginT = marginB = 0);
  63547. that._width = width;
  63548. that._height = height;
  63549. that._rootRect = new _Rectangle({
  63550. left: marginL,
  63551. top: marginT,
  63552. right: width - marginR,
  63553. bottom: height - marginB
  63554. })
  63555. }
  63556. },
  63557. _cleanContent: function() {
  63558. var that = this;
  63559. that._rangeContainer.clean();
  63560. that._scale.clean();
  63561. that._cleanValueIndicators()
  63562. },
  63563. _renderContent: function() {
  63564. var that = this;
  63565. that._rangeContainer.render(_extend(true, {}, that._themeManager.theme().rangeContainer, that.option('rangeContainer'), {
  63566. themeName: that._themeManager.themeName(),
  63567. vertical: that._area.vertical
  63568. }));
  63569. that._scale.render(_extend(true, {}, that._themeManager.theme().scale, that.option('scale'), {
  63570. approximateScreenDelta: that._getApproximateScreenRange(),
  63571. offset: 0,
  63572. vertical: that._area.vertical
  63573. }));
  63574. var elements = that._prepareValueIndicators();
  63575. elements = _map([that._scale, that._rangeContainer].concat(elements), function(element) {
  63576. return element && element.enabled ? element : null
  63577. });
  63578. that._applyMainLayout(elements);
  63579. _each(elements, function(_, element) {
  63580. that._updateElementPosition(element)
  63581. });
  63582. that._updateActiveElements()
  63583. },
  63584. _updateIndicatorSettings: function(settings) {
  63585. var that = this;
  63586. settings.currentValue = settings.baseValue = _isFinite(that._translator.translate(settings.baseValue)) ? _Number(settings.baseValue) : that._baseValue;
  63587. settings.vertical = that._area.vertical;
  63588. if (settings.text && !settings.text.format && !settings.text.precision) {
  63589. settings.text.format = that._defaultFormatOptions.format;
  63590. settings.text.precision = that._defaultFormatOptions.precision
  63591. }
  63592. },
  63593. _prepareValueIndicatorSettings: function() {
  63594. var that = this,
  63595. options = that.option('valueIndicator') || {},
  63596. defaultOptions = _extend(true, {}, that._themeManager.theme().valueIndicator),
  63597. type = _String(options.type || defaultOptions.type).toLowerCase();
  63598. that._valueIndicatorSettings = _extend(true, defaultOptions._default, defaultOptions[type], options, {
  63599. type: type,
  63600. animation: that._animationSettings,
  63601. containerBackgroundColor: that._containerBackgroundColor
  63602. });
  63603. that._updateIndicatorSettings(that._valueIndicatorSettings)
  63604. },
  63605. _prepareSubvalueIndicatorSettings: function() {
  63606. var that = this,
  63607. options = that.option('subvalueIndicator') || {},
  63608. defaultOptions = _extend(true, {}, that._themeManager.theme().subvalueIndicator),
  63609. type = _String(options.type || defaultOptions.type).toLowerCase();
  63610. that._subvalueIndicatorSettings = _extend(true, defaultOptions._default, defaultOptions[type], options, {
  63611. type: type,
  63612. animation: that._animationSettings,
  63613. containerBackgroundColor: that._containerBackgroundColor
  63614. });
  63615. that._updateIndicatorSettings(that._subvalueIndicatorSettings)
  63616. },
  63617. _cleanValueIndicators: function() {
  63618. this._valueIndicator && this._valueIndicator.clean();
  63619. this._subvalueIndicatorsSet && this._subvalueIndicatorsSet.clean()
  63620. },
  63621. _prepareValueIndicators: function() {
  63622. var that = this;
  63623. that._prepareValueIndicator();
  63624. that.__subvalues !== null && that._prepareSubvalueIndicators();
  63625. return [that._valueIndicator, that._subvalueIndicatorsSet]
  63626. },
  63627. _updateActiveElements: function() {
  63628. this._updateValueIndicator();
  63629. this._updateSubvalueIndicators()
  63630. },
  63631. _prepareValueIndicator: function() {
  63632. var that = this,
  63633. indicator = that._valueIndicator,
  63634. currentValue;
  63635. that._prepareValueIndicatorSettings();
  63636. indicator && that._valueIndicatorType !== that._valueIndicatorSettings.type && indicator.dispose() && (indicator = null);
  63637. that._valueIndicatorType = that._valueIndicatorSettings.type;
  63638. if (!indicator) {
  63639. indicator = that._valueIndicator = that._createValueIndicator(that._valueIndicatorType);
  63640. if (indicator) {
  63641. indicator.setup({
  63642. renderer: that._renderer,
  63643. translator: that._translator,
  63644. owner: that._root,
  63645. tracker: that._tracker,
  63646. className: 'dxg-value-indicator'
  63647. });
  63648. indicator._trackerInfo = {type: 'value-indicator'}
  63649. }
  63650. }
  63651. indicator.render(that._valueIndicatorSettings)
  63652. },
  63653. _prepareSubvalueIndicators: function() {
  63654. var that = this,
  63655. subvalueIndicatorsSet = that._subvalueIndicatorsSet;
  63656. if (!subvalueIndicatorsSet)
  63657. subvalueIndicatorsSet = that._subvalueIndicatorsSet = new DX.viz.gauges.__internals.ValueIndicatorsSet({
  63658. renderer: that._renderer,
  63659. translator: that._translator,
  63660. owner: that._root,
  63661. tracker: that._tracker,
  63662. className: 'dxg-subvalue-indicators',
  63663. indicatorClassName: 'dxg-subvalue-indicator',
  63664. trackerType: 'subvalue-indicator',
  63665. createIndicator: function() {
  63666. return that._createSubvalueIndicator(that._subvalueIndicatorType)
  63667. }
  63668. });
  63669. that._prepareSubvalueIndicatorSettings();
  63670. var isRecreate = that._subvalueIndicatorSettings.type !== that._subvalueIndicatorType;
  63671. that._subvalueIndicatorType = that._subvalueIndicatorSettings.type;
  63672. if (that._createSubvalueIndicator(that._subvalueIndicatorType))
  63673. subvalueIndicatorsSet.render(that._subvalueIndicatorSettings, isRecreate)
  63674. },
  63675. _processValue: function(value, fallbackValue) {
  63676. var _value = this._translator.adjust(value !== undefined ? value : this.__value);
  63677. return _isFinite(_value) ? _value : fallbackValue
  63678. },
  63679. _setupValue: function(value) {
  63680. this.__value = this._processValue(value, this.__value)
  63681. },
  63682. _setupSubvalues: function(subvalues) {
  63683. var _subvalues = subvalues === undefined ? this.__subvalues : _isArray(subvalues) ? subvalues : _isNumber(subvalues) ? [subvalues] : null;
  63684. if (_subvalues === null)
  63685. return;
  63686. var i = 0,
  63687. ii = _subvalues.length,
  63688. list = [];
  63689. for (; i < ii; ++i)
  63690. list.push(this._processValue(_subvalues[i], this.__subvalues[i]));
  63691. this.__subvalues = list
  63692. },
  63693. _updateValueIndicator: function() {
  63694. var that = this;
  63695. that._valueIndicator && that._valueIndicator.value(that.__value, that._noAnimation);
  63696. that._resizing || that.hideLoadingIndicator()
  63697. },
  63698. _updateSubvalueIndicators: function() {
  63699. var that = this;
  63700. that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.values(that.__subvalues, that._noAnimation);
  63701. that._resizing || that.hideLoadingIndicator()
  63702. },
  63703. value: function(arg) {
  63704. var that = this;
  63705. if (arg !== undefined) {
  63706. that._setupValue(arg);
  63707. that._updateValueIndicator();
  63708. that.option(OPTION_VALUE, that.__value);
  63709. return that
  63710. }
  63711. return that.__value
  63712. },
  63713. subvalues: function(arg) {
  63714. var that = this;
  63715. if (arg !== undefined) {
  63716. if (that.__subvalues !== null) {
  63717. that._setupSubvalues(arg);
  63718. that._updateSubvalueIndicators();
  63719. that.option(OPTION_SUBVALUES, that.__subvalues)
  63720. }
  63721. return that
  63722. }
  63723. return that.__subvalues !== null ? that.__subvalues.slice() : undefined
  63724. },
  63725. _handleValueChanged: function(name, newv, oldv) {
  63726. var that = this;
  63727. switch (name) {
  63728. case OPTION_VALUE:
  63729. that._setupValue(newv);
  63730. that._updateValueIndicator();
  63731. that.option(OPTION_VALUE, that.__value);
  63732. return true;
  63733. case OPTION_SUBVALUES:
  63734. if (that.__subvalues !== null) {
  63735. that._setupSubvalues(newv);
  63736. that._updateSubvalueIndicators();
  63737. that.option(OPTION_SUBVALUES, that.__subvalues);
  63738. return true
  63739. }
  63740. return false;
  63741. default:
  63742. return false
  63743. }
  63744. },
  63745. _optionChanged: function(name, newValue, oldValue) {
  63746. var that = this;
  63747. if (that._handleValueChanged(name, newValue, oldValue))
  63748. return;
  63749. switch (name) {
  63750. case'scale':
  63751. that._setupDomain();
  63752. that._invalidate();
  63753. break;
  63754. default:
  63755. that.callBase.apply(that, arguments);
  63756. break
  63757. }
  63758. },
  63759. _optionValuesEqual: function(name, oldValue, newValue) {
  63760. switch (name) {
  63761. case OPTION_VALUE:
  63762. return oldValue === newValue;
  63763. case OPTION_SUBVALUES:
  63764. return compareArrays(oldValue, newValue);
  63765. default:
  63766. return this.callBase.apply(this, arguments)
  63767. }
  63768. },
  63769. _getDefaultContainerSize: null,
  63770. _applyMainLayout: null,
  63771. _updateElementPosition: null,
  63772. _createScale: null,
  63773. _createRangeContainer: null,
  63774. _createValueIndicator: null,
  63775. _createSubvalueIndicator: null,
  63776. _getApproximateScreenRange: null
  63777. });
  63778. DX.viz.gauges.Gauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  63779. DX.viz.gauges.Gauge.prototype._factory.createThemeManager = function() {
  63780. return new DX.viz.gauges.__internals.ThemeManager
  63781. };
  63782. function valueGetter(arg) {
  63783. return arg.value
  63784. }
  63785. function setupValues(that, fieldName, optionItems) {
  63786. var currentValues = that[fieldName],
  63787. newValues = _isArray(optionItems) ? _map(optionItems, valueGetter) : [],
  63788. i = 0,
  63789. ii = newValues.length,
  63790. list = [];
  63791. for (; i < ii; ++i)
  63792. list.push(that._processValue(newValues[i], currentValues[i]));
  63793. that[fieldName] = list
  63794. }
  63795. function disableDefaultMode(that) {
  63796. that.value = that.subvalues = _noop;
  63797. that._setupValue = that._setupSubvalues = that._updateValueIndicator = that._updateSubvalueIndicators = null
  63798. }
  63799. function selectObsoleteMode(that) {
  63800. that._needleValues = _map(that.option('needles') || [], valueGetter);
  63801. that._markerValues = _map(that.option('markers') || [], valueGetter);
  63802. that._rangeBarValues = _map(that.option('rangeBars') || [], valueGetter);
  63803. that._needles = [];
  63804. that._markers = [];
  63805. that._rangeBars = [];
  63806. that._setupValueState = function() {
  63807. var that = this;
  63808. setupValues(that, '_needleValues', that.option('needles'));
  63809. setupValues(that, '_markerValues', that.option('markers'));
  63810. setupValues(that, '_rangeBarValues', that.option('rangeBars'))
  63811. };
  63812. that._handleValueChanged = function(name, newv, oldv) {
  63813. var that = this,
  63814. result = false;
  63815. switch (name) {
  63816. case'needles':
  63817. setupValues(that, '_needleValues', newv);
  63818. result = true;
  63819. break;
  63820. case'markers':
  63821. setupValues(that, '_markerValues', newv);
  63822. result = true;
  63823. break;
  63824. case'rangeBars':
  63825. setupValues(that, '_rangeBarValues', newv);
  63826. result = true;
  63827. break
  63828. }
  63829. result && that._invalidate();
  63830. return result
  63831. };
  63832. that._updateActiveElements = function() {
  63833. var that = this;
  63834. _each(that._needles, function(_, needle) {
  63835. needle.value(that._needleValues[needle._index], that._noAnimation)
  63836. });
  63837. _each(that._markers, function(_, marker) {
  63838. marker.value(that._markerValues[marker._index], that._noAnimation)
  63839. });
  63840. _each(that._rangeBars, function(_, rangeBar) {
  63841. rangeBar.value(that._rangeBarValues[rangeBar._index], that._noAnimation)
  63842. });
  63843. that._resizing || that.hideLoadingIndicator()
  63844. };
  63845. that._prepareValueIndicators = function() {
  63846. return prepareObsoleteElements(this)
  63847. };
  63848. that._disposeValueIndicators = function() {
  63849. var that = this;
  63850. _each([].concat(that._needles, that._markers, that._rangeBars), function(_, pointer) {
  63851. pointer.dispose()
  63852. });
  63853. that._needles = that._markers = that._rangeBars = null
  63854. };
  63855. that._cleanValueIndicators = function() {
  63856. _each([].concat(this._needles, this._markers, this._rangeBars), function(_, pointer) {
  63857. pointer.clean()
  63858. })
  63859. };
  63860. that.needleValue = function(index, value) {
  63861. return accessPointerValue(this, this._needles, this._needleValues, index, value)
  63862. };
  63863. that.markerValue = function(index, value) {
  63864. return accessPointerValue(this, this._markers, this._markerValues, index, value)
  63865. };
  63866. that.rangeBarValue = function(index, value) {
  63867. return accessPointerValue(this, this._rangeBars, this._rangeBarValues, index, value)
  63868. }
  63869. }
  63870. function selectHardMode(that) {
  63871. that._indicatorValues = [];
  63872. that._valueIndicators = [];
  63873. that._setupValueState = function() {
  63874. setupValues(this, '_indicatorValues', this.option('valueIndicators'))
  63875. };
  63876. that._handleValueChagned = function(name, newv, oldv) {
  63877. if (name === 'valueIndicators') {
  63878. setupValues(this, '_indicatorValues', newv);
  63879. this._invalidate();
  63880. return true
  63881. }
  63882. return false
  63883. };
  63884. that._updateActiveElements = function() {
  63885. var that = this;
  63886. _each(that._valueIndicators, function(_, valueIndicator) {
  63887. valueIndicator.value(that._indicatorValues[valueIndicator._index], that._noAnimation)
  63888. });
  63889. that._resizing || that.hideLoadingIndicator()
  63890. };
  63891. that._prepareValueIndicators = function() {
  63892. return prepareValueIndicatorsInHardMode(this)
  63893. };
  63894. that._disposeValueIndicators = function() {
  63895. _each(this._valueIndicators, function(_, valueIndicator) {
  63896. valueIndicator.dispose()
  63897. });
  63898. this._valueIndicators = null
  63899. };
  63900. that._cleanValueIndicators = function() {
  63901. _each(this._valueIndicators, function(_, valueIndicator) {
  63902. valueIndicator.clean()
  63903. })
  63904. };
  63905. that.indicatorValue = function(index, value) {
  63906. return accessPointerValue(this, this._valueIndicators, this._indicatorValues, index, value)
  63907. }
  63908. }
  63909. function prepareValueIndicatorsInHardMode(that) {
  63910. var valueIndicators = that._valueIndicators || [],
  63911. userOptions = that.option('valueIndicators'),
  63912. optionList = [],
  63913. i = 0,
  63914. ii;
  63915. for (ii = _isArray(userOptions) ? userOptions.length : 0; i < ii; ++i)
  63916. optionList.push(userOptions[i]);
  63917. for (ii = valueIndicators.length; i < ii; ++i)
  63918. optionList.push(null);
  63919. var themeSettings = that._themeManager.theme().valueIndicators,
  63920. parameters = {
  63921. renderer: that._renderer,
  63922. owner: that._root,
  63923. translator: that._translator,
  63924. tracker: that._tracker
  63925. },
  63926. newValueIndicators = [];
  63927. _each(optionList, function(i, userSettings) {
  63928. var valueIndicator = valueIndicators[i];
  63929. if (!userSettings) {
  63930. valueIndicator && valueIndicator.dispose();
  63931. return
  63932. }
  63933. var type = _String(userSettings.type || themeSettings._type).toLowerCase();
  63934. if (valueIndicator && type !== valueIndicator.type) {
  63935. valueIndicator.dispose();
  63936. valueIndicator = null
  63937. }
  63938. if (!valueIndicator) {
  63939. valueIndicator = that._createValueIndicatorInHardMode(type);
  63940. valueIndicator && valueIndicator.setup(parameters)
  63941. }
  63942. if (valueIndicator) {
  63943. var settings = _extend(true, {}, themeSettings._default, themeSettings[type], userSettings, {
  63944. type: type,
  63945. animation: that._animationSettings,
  63946. containerBackgroundColor: that._containerBackgroundColor
  63947. });
  63948. that._updateIndicatorSettings(settings);
  63949. valueIndicator.render(settings);
  63950. valueIndicator._index = i;
  63951. valueIndicator._trackerInfo = {index: i};
  63952. newValueIndicators.push(valueIndicator)
  63953. }
  63954. });
  63955. that._valueIndicators = newValueIndicators;
  63956. return that._valueIndicators
  63957. }
  63958. function prepareObsoleteElements(that) {
  63959. var rangeBars = prepareObsoletePointers(that, '_rangeBars', '_createRangeBar', {
  63960. user: that.option('rangeBars'),
  63961. common: that.option('commonRangeBarSettings'),
  63962. theme: that._themeManager.theme().valueIndicator,
  63963. preset: {},
  63964. type: 'rangebar',
  63965. className: 'dxg-value-indicator'
  63966. });
  63967. var needles = prepareObsoletePointers(that, '_needles', '_createNeedle', {
  63968. user: that.option('needles'),
  63969. common: that.option('commonNeedleSettings'),
  63970. theme: that._themeManager.theme().valueIndicator,
  63971. preset: that._getPreset().commonNeedleSettings,
  63972. className: 'dxg-value-indicator'
  63973. });
  63974. var markers = prepareObsoletePointers(that, '_markers', '_createMarker', {
  63975. user: that.option('markers'),
  63976. common: that.option('commonMarkerSettings'),
  63977. theme: that._themeManager.theme().subvalueIndicator,
  63978. preset: that._getPreset().commonMarkerSettings,
  63979. className: 'dxg-subvalue-indicator'
  63980. });
  63981. var spindle = that._prepareObsoleteSpindle && that._prepareObsoleteSpindle();
  63982. return [].concat(rangeBars, needles, markers, [spindle])
  63983. }
  63984. function prepareObsoletePointers(that, fieldName, methodName, options) {
  63985. var pointers = that[fieldName],
  63986. userOptions = [],
  63987. i = 0,
  63988. ii;
  63989. for (ii = _isArray(options.user) ? options.user.length : 0; i < ii; ++i)
  63990. userOptions.push(options.user[i]);
  63991. for (ii = pointers.length; i < ii; ++i)
  63992. userOptions.push(null);
  63993. var themeOption = options.theme,
  63994. presetOption = options.preset,
  63995. commonOption = options.common || {},
  63996. parameters = {
  63997. renderer: that._renderer,
  63998. owner: that._root,
  63999. translator: that._translator,
  64000. tracker: that._tracker,
  64001. className: options.className
  64002. },
  64003. newPointers = [];
  64004. _each(userOptions, function(i, pointerOption) {
  64005. var pointer = pointers[i];
  64006. if (!pointerOption) {
  64007. pointer && pointer.dispose();
  64008. return
  64009. }
  64010. var type = _String(pointerOption.type || commonOption.type || presetOption.type || themeOption.type).toLowerCase(),
  64011. settings;
  64012. if (pointer && pointer.type !== type) {
  64013. pointer.dispose();
  64014. pointer = null
  64015. }
  64016. if (!pointer) {
  64017. pointer = that[methodName](type);
  64018. pointer.setup(parameters)
  64019. }
  64020. if (pointer) {
  64021. type = options.type || type;
  64022. settings = _extend(true, {}, themeOption._default, themeOption[type], commonOption, pointerOption),
  64023. settings.spindleSize = null;
  64024. settings.animation = that._animationSettings;
  64025. settings.containerBackgroundColor = that._containerBackgroundColor;
  64026. that._updateIndicatorSettings(settings);
  64027. pointer.render(settings);
  64028. pointer._index = i;
  64029. pointer._trackerInfo = {index: i};
  64030. newPointers.push(pointer)
  64031. }
  64032. });
  64033. that[fieldName] = newPointers;
  64034. return newPointers
  64035. }
  64036. function accessPointerValue(that, pointers, values, index, value) {
  64037. if (value !== undefined) {
  64038. if (values[index] !== undefined) {
  64039. values[index] = that._processValue(value, values[index]);
  64040. pointers[index] && pointers[index].value(values[index]);
  64041. that._resizing || that.hideLoadingIndicator()
  64042. }
  64043. return that
  64044. }
  64045. else
  64046. return values[index]
  64047. }
  64048. function compareArrays(array1, array2) {
  64049. if (array1 === array2)
  64050. return true;
  64051. if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
  64052. for (var i = 0, ii = array1.length; i < ii; ++i)
  64053. if (_abs(array1[i] - array2[i]) > 1E-8)
  64054. return false;
  64055. return true
  64056. }
  64057. return false
  64058. }
  64059. DX.viz.gauges.__internals.ValueIndicatorsSet = DX.Class.inherit({
  64060. ctor: function(parameters) {
  64061. var that = this;
  64062. that._parameters = parameters;
  64063. that._createIndicator = that._parameters.createIndicator || _noop;
  64064. that._root = that._parameters.renderer.createGroup({'class': that._parameters.className});
  64065. that._indicatorParameters = that._indicatorParameters || {
  64066. renderer: that._parameters.renderer,
  64067. translator: that._parameters.translator,
  64068. owner: that._root,
  64069. tracker: that._parameters.tracker,
  64070. className: that._parameters.indicatorClassName
  64071. };
  64072. that._indicators = []
  64073. },
  64074. dispose: function() {
  64075. var that = this;
  64076. _each(that._indicators, function(_, indicator) {
  64077. indicator.dispose()
  64078. });
  64079. that._parameters = that._createIndicator = that._root = that._options = that._indicators = that._colorPalette = that._palette = null;
  64080. return that
  64081. },
  64082. clean: function() {
  64083. var that = this;
  64084. that._root.detach();
  64085. that._sample && that._sample.clean().dispose();
  64086. _each(that._indicators, function(_, indicator) {
  64087. indicator.clean()
  64088. });
  64089. that._sample = that._options = that._palette = null;
  64090. return that
  64091. },
  64092. render: function(options, isRecreate) {
  64093. var that = this;
  64094. that._options = options;
  64095. that._sample = that._createIndicator();
  64096. that._sample && that._sample.setup(that._indicatorParameters).render(options);
  64097. that.enabled = that._sample && that._sample.enabled;
  64098. that._palette = _isDefined(options.palette) ? new DX.viz.core.Palette(options.palette) : null;
  64099. if (that.enabled) {
  64100. that._root.append(that._parameters.owner);
  64101. that._generatePalette(that._indicators.length);
  64102. that._indicators = _map(that._indicators, function(indicator, i) {
  64103. if (isRecreate) {
  64104. indicator.dispose();
  64105. indicator = that._createIndicator();
  64106. indicator.setup(that._indicatorParameters);
  64107. indicator._trackerInfo = {
  64108. type: that._parameters.trackerType,
  64109. index: i
  64110. }
  64111. }
  64112. indicator.render(that._getIndicatorOptions(i));
  64113. return indicator
  64114. })
  64115. }
  64116. return that
  64117. },
  64118. resize: function(layout) {
  64119. var that = this;
  64120. that._layout = layout;
  64121. _each(that._indicators, function(_, indicator) {
  64122. indicator.resize(layout)
  64123. });
  64124. return that
  64125. },
  64126. measure: function(layout) {
  64127. return this._sample.measure(layout)
  64128. },
  64129. _getIndicatorOptions: function(index) {
  64130. var result = this._options;
  64131. if (this._colorPalette)
  64132. result = _extend({}, result, {color: this._colorPalette[index]});
  64133. return result
  64134. },
  64135. _generatePalette: function(count) {
  64136. var that = this,
  64137. colors = null;
  64138. if (that._palette) {
  64139. colors = [];
  64140. that._palette.reset();
  64141. var i = 0;
  64142. for (; i < count; ++i)
  64143. colors.push(that._palette.getNextColor())
  64144. }
  64145. that._colorPalette = colors
  64146. },
  64147. _adjustIndicatorsCount: function(count) {
  64148. var that = this,
  64149. indicators = that._indicators,
  64150. i,
  64151. ii,
  64152. indicatorOptions,
  64153. indicator,
  64154. indicatorsLen = indicators.length,
  64155. palette = that._parameters.palette;
  64156. if (indicatorsLen > count) {
  64157. for (i = count, ii = indicatorsLen; i < ii; ++i)
  64158. indicators[i].clean().dispose();
  64159. that._indicators = indicators.slice(0, count);
  64160. that._generatePalette(indicators.length)
  64161. }
  64162. else if (indicatorsLen < count) {
  64163. that._generatePalette(count);
  64164. for (i = indicatorsLen, ii = count; i < ii; ++i) {
  64165. indicator = that._createIndicator();
  64166. indicator.setup(that._indicatorParameters);
  64167. indicator._trackerInfo = {
  64168. type: that._parameters.trackerType,
  64169. index: i
  64170. };
  64171. indicator.render(that._getIndicatorOptions(i)).resize(that._layout);
  64172. indicators.push(indicator)
  64173. }
  64174. }
  64175. },
  64176. values: function(arg, _noAnimation) {
  64177. var that = this;
  64178. if (!that.enabled)
  64179. return;
  64180. if (arg !== undefined) {
  64181. if (!_isArray(arg))
  64182. arg = _isFinite(arg) ? [Number(arg)] : null;
  64183. if (arg) {
  64184. that._adjustIndicatorsCount(arg.length);
  64185. _each(that._indicators, function(i, indicator) {
  64186. indicator.value(arg[i], _noAnimation)
  64187. })
  64188. }
  64189. return that
  64190. }
  64191. return _map(that._indicators, function(indicator) {
  64192. return indicator.value()
  64193. })
  64194. }
  64195. })
  64196. })(DevExpress, jQuery);
  64197. /*! Module viz-gauges, file circularGauge.js */
  64198. (function(DX, $, undefined) {
  64199. var factory = DX.viz.gauges.__factory;
  64200. var isFinite = window.isFinite,
  64201. Number = window.Number,
  64202. normalizeAngle = DX.utils.normalizeAngle,
  64203. getCosAndSin = DX.utils.getCosAndSin,
  64204. abs = Math.abs,
  64205. max = Math.max,
  64206. min = Math.min,
  64207. round = Math.round,
  64208. slice = Array.prototype.slice,
  64209. $extend = $.extend,
  64210. $each = $.each;
  64211. var PI = Math.PI;
  64212. function getSides(startAngle, endAngle) {
  64213. var startCosSin = getCosAndSin(startAngle),
  64214. endCosSin = getCosAndSin(endAngle),
  64215. startCos = startCosSin.cos,
  64216. startSin = startCosSin.sin,
  64217. endCos = endCosSin.cos,
  64218. endSin = endCosSin.sin;
  64219. return {
  64220. left: startSin <= 0 && endSin >= 0 || startSin <= 0 && endSin <= 0 && startCos <= endCos || startSin >= 0 && endSin >= 0 && startCos >= endCos ? -1 : min(startCos, endCos, 0),
  64221. right: startSin >= 0 && endSin <= 0 || startSin >= 0 && endSin >= 0 && startCos >= endCos || startSin <= 0 && endSin <= 0 && startCos <= endCos ? 1 : max(startCos, endCos, 0),
  64222. up: startCos <= 0 && endCos >= 0 || startCos <= 0 && endCos <= 0 && startSin >= endSin || startCos >= 0 && endCos >= 0 && startSin <= endSin ? -1 : -max(startSin, endSin, 0),
  64223. down: startCos >= 0 && endCos <= 0 || startCos >= 0 && endCos >= 0 && startSin <= endSin || startCos <= 0 && endCos <= 0 && startSin >= endSin ? 1 : -min(startSin, endSin, 0)
  64224. }
  64225. }
  64226. DX.viz.gauges.CircularGauge = DX.viz.gauges.Gauge.inherit({
  64227. _rootClass: 'dxg-circular-gauge',
  64228. _selectMode: function() {
  64229. this.callBase.apply(this, arguments);
  64230. if (typeof this.indicatorValue === 'function')
  64231. this._createValueIndicatorInHardMode = function(type) {
  64232. return factory.createCircularValueIndicatorInHardMode(type)
  64233. }
  64234. },
  64235. _setupCodomain: function() {
  64236. var that = this,
  64237. geometry = that.option('geometry') || {},
  64238. startAngle = geometry.startAngle,
  64239. endAngle = geometry.endAngle,
  64240. sides;
  64241. startAngle = isFinite(startAngle) ? normalizeAngle(startAngle) : 225;
  64242. endAngle = isFinite(endAngle) ? normalizeAngle(endAngle) : -45;
  64243. if (abs(startAngle - endAngle) < 1) {
  64244. endAngle -= 360;
  64245. sides = {
  64246. left: -1,
  64247. up: -1,
  64248. right: 1,
  64249. down: 1
  64250. }
  64251. }
  64252. else {
  64253. startAngle < endAngle && (endAngle -= 360);
  64254. sides = getSides(startAngle, endAngle)
  64255. }
  64256. that._area = {
  64257. x: 0,
  64258. y: 0,
  64259. radius: 100,
  64260. startCoord: startAngle,
  64261. endCoord: endAngle,
  64262. scaleRadius: geometry.scaleRadius > 0 ? Number(geometry.scaleRadius) : undefined,
  64263. sides: sides
  64264. };
  64265. that._translator.setCodomain(startAngle, endAngle)
  64266. },
  64267. _measureMainElements: function(elements) {
  64268. var that = this,
  64269. maxRadius = 0,
  64270. minRadius = Infinity,
  64271. maxHorizontalOffset = 0,
  64272. maxVerticalOffset = 0,
  64273. maxInverseHorizontalOffset = 0,
  64274. maxInverseVerticalOffset = 0;
  64275. $each(elements, function(_, element) {
  64276. var bounds = element.measure({radius: that._area.radius - (Number(element._options.offset) || 0)});
  64277. bounds.min > 0 && (minRadius = min(minRadius, bounds.min));
  64278. bounds.max > 0 && (maxRadius = max(maxRadius, bounds.max));
  64279. bounds.horizontalOffset > 0 && (maxHorizontalOffset = max(maxHorizontalOffset, bounds.max + bounds.horizontalOffset));
  64280. bounds.verticalOffset > 0 && (maxVerticalOffset = max(maxVerticalOffset, bounds.max + bounds.verticalOffset));
  64281. bounds.inverseHorizontalOffset > 0 && (maxInverseHorizontalOffset = max(maxInverseHorizontalOffset, bounds.inverseHorizontalOffset));
  64282. bounds.inverseVerticalOffset > 0 && (maxInverseVerticalOffset = max(maxInverseVerticalOffset, bounds.inverseVerticalOffset))
  64283. });
  64284. maxHorizontalOffset = max(maxHorizontalOffset - maxRadius, 0);
  64285. maxVerticalOffset = max(maxVerticalOffset - maxRadius, 0);
  64286. return {
  64287. minRadius: minRadius,
  64288. maxRadius: maxRadius,
  64289. horizontalMargin: maxHorizontalOffset,
  64290. verticalMargin: maxVerticalOffset,
  64291. inverseHorizontalMargin: maxInverseHorizontalOffset,
  64292. inverseVerticalMargin: maxInverseVerticalOffset
  64293. }
  64294. },
  64295. _applyMainLayout: function(elements) {
  64296. var that = this,
  64297. measurements = that._measureMainElements(elements),
  64298. area = that._area,
  64299. sides = area.sides,
  64300. margins = {
  64301. left: (sides.left < -0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
  64302. right: (sides.right > 0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
  64303. top: (sides.up < -0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0,
  64304. bottom: (sides.down > 0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0
  64305. },
  64306. rect = that._layoutManager.selectRectByAspectRatio((sides.down - sides.up) / (sides.right - sides.left), margins),
  64307. radius = min(rect.width() / (sides.right - sides.left), rect.height() / (sides.down - sides.up)),
  64308. x,
  64309. y;
  64310. var scaler = (measurements.maxRadius - area.radius + area.scaleRadius) / radius;
  64311. if (0 < scaler && scaler < 1) {
  64312. rect = rect.scale(scaler);
  64313. radius *= scaler
  64314. }
  64315. radius = radius - measurements.maxRadius + area.radius;
  64316. x = rect.left - rect.width() * sides.left / (sides.right - sides.left);
  64317. y = rect.top - rect.height() * sides.up / (sides.down - sides.up);
  64318. area.x = round(x);
  64319. area.y = round(y);
  64320. area.radius = radius;
  64321. rect.left -= margins.left;
  64322. rect.right += margins.right;
  64323. rect.top -= margins.top;
  64324. rect.bottom += margins.bottom;
  64325. that._layoutManager.setRect(rect)
  64326. },
  64327. _updateElementPosition: function(element) {
  64328. element.resize({
  64329. x: this._area.x,
  64330. y: this._area.y,
  64331. radius: round(this._area.radius - (Number(element._options.offset) || 0))
  64332. })
  64333. },
  64334. _createScale: function(parameters) {
  64335. return factory.createCircularScale(parameters)
  64336. },
  64337. _createRangeContainer: function(parameters) {
  64338. return factory.createCircularRangeContainer(parameters)
  64339. },
  64340. _createValueIndicator: function(type) {
  64341. return factory.createCircularValueIndicator(type)
  64342. },
  64343. _createSubvalueIndicator: function(type) {
  64344. return factory.createCircularSubvalueIndicator(type)
  64345. },
  64346. _getApproximateScreenRange: function() {
  64347. var that = this,
  64348. area = that._area,
  64349. r = min(that._width / (area.sides.right - area.sides.left), that._height / (area.sides.down - area.sides.up));
  64350. r > area.totalRadius && (r = area.totalRadius);
  64351. r = 0.8 * r;
  64352. return -that._translator.getCodomainRange() * r * PI / 180
  64353. },
  64354. _getDefaultContainerSize: function() {
  64355. return {
  64356. width: 300,
  64357. height: 300
  64358. }
  64359. },
  64360. _getPreset: function() {
  64361. var preset = this.option('preset'),
  64362. result;
  64363. if (preset === 'preset2')
  64364. result = {
  64365. commonNeedleSettings: {type: 'twocolorrectangle'},
  64366. commonMarkerSettings: {type: 'triangle'}
  64367. };
  64368. else if (preset === 'preset3')
  64369. result = {
  64370. commonNeedleSettings: {type: 'rectangle'},
  64371. commonMarkerSettings: {type: 'triangle'}
  64372. };
  64373. else
  64374. result = {
  64375. commonNeedleSettings: {type: 'rectangle'},
  64376. commonMarkerSettings: {type: 'textcloud'}
  64377. };
  64378. return result
  64379. },
  64380. _createNeedle: function(type) {
  64381. return factory.createCircularNeedle(type)
  64382. },
  64383. _createMarker: function(type) {
  64384. return factory.createCircularMarker(type)
  64385. },
  64386. _createRangeBar: function() {
  64387. return factory.createCircularRangeBar()
  64388. },
  64389. _prepareObsoleteSpindle: function() {
  64390. var that = this,
  64391. spindleOption = that.option('spindle') || {},
  64392. visible = that._needles && ('visible' in spindleOption ? !!spindleOption.visible : true);
  64393. if (visible) {
  64394. var themeOption = that._themeManager.theme().valueIndicator._default,
  64395. size = spindleOption.size || themeOption.spindleSize;
  64396. visible = size > 0
  64397. }
  64398. if (visible) {
  64399. var gapSize = spindleOption.gapSize || themeOption.spindleGapSize,
  64400. color = spindleOption.color || themeOption.color;
  64401. gapSize = gapSize <= size ? gapSize : size;
  64402. that._spindle = that._spindle || that._renderer.createGroup({'class': 'dxg-value-indicator'});
  64403. that._spindle.append(that._root);
  64404. that._spindleOuter = that._spindleOuter || that._renderer.createCircle(0, 0, 0, {
  64405. 'class': 'dxg-spindle-border',
  64406. stroke: 'none',
  64407. strokeWidth: 0
  64408. }).append(that._spindle);
  64409. that._spindleInner = that._spindleInner || that._renderer.createCircle(0, 0, 0, {
  64410. 'class': 'dxg-spindle-hole',
  64411. stroke: 'none',
  64412. strokeWidth: 0
  64413. }).append(that._spindle);
  64414. that._spindleOuter.applySettings({
  64415. cx: that._area.x,
  64416. cy: that._area.y,
  64417. r: size / 2,
  64418. fill: color
  64419. });
  64420. that._spindleInner.applySettings({
  64421. cx: that._area.x,
  64422. cy: that._area.y,
  64423. r: gapSize / 2,
  64424. fill: that._containerBackgroundColor
  64425. });
  64426. return {
  64427. enabled: true,
  64428. _options: {offset: 0},
  64429. measure: function(layout) {
  64430. return {}
  64431. },
  64432. resize: function(layout) {
  64433. that._spindleOuter.applySettings({
  64434. cx: layout.x,
  64435. cy: layout.y
  64436. });
  64437. that._spindleInner.applySettings({
  64438. cx: layout.x,
  64439. cy: layout.y
  64440. });
  64441. return that
  64442. }
  64443. }
  64444. }
  64445. else {
  64446. that._spindle && that._spindle.remove();
  64447. delete that._spindle;
  64448. delete that._spindleOuter;
  64449. delete that._spindleInner;
  64450. return null
  64451. }
  64452. }
  64453. });
  64454. DX.viz.gauges.CircularGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  64455. DX.viz.gauges.CircularGauge.prototype._factory.createThemeManager = function() {
  64456. var themeManager = new DX.viz.gauges.__internals.ThemeManager;
  64457. themeManager._subTheme = '_circular';
  64458. return themeManager
  64459. }
  64460. })(DevExpress, jQuery);
  64461. /*! Module viz-gauges, file linearGauge.js */
  64462. (function(DX, $, undefined) {
  64463. var factory = DX.viz.gauges.__factory;
  64464. var _String = String,
  64465. _Number = Number,
  64466. max = Math.max,
  64467. min = Math.min,
  64468. round = Math.round,
  64469. slice = Array.prototype.slice,
  64470. $extend = $.extend,
  64471. $each = $.each;
  64472. DX.viz.gauges.LinearGauge = DX.viz.gauges.Gauge.inherit({
  64473. _rootClass: 'dxg-linear-gauge',
  64474. _selectMode: function() {
  64475. this.callBase.apply(this, arguments);
  64476. if (typeof this.indicatorValue === 'function')
  64477. this._createValueIndicatorInHardMode = function(type) {
  64478. return factory.createLinearValueIndicatorInHardMode(type)
  64479. }
  64480. },
  64481. _setupCodomain: function() {
  64482. var that = this,
  64483. geometry = that.option('geometry') || {},
  64484. vertical = _String(geometry.orientation).toLowerCase() === 'vertical';
  64485. that._area = {
  64486. vertical: vertical,
  64487. x: 0,
  64488. y: 0,
  64489. startCoord: -100,
  64490. endCoord: 100,
  64491. scaleSize: geometry.scaleSize > 0 ? _Number(geometry.scaleSize) : undefined
  64492. };
  64493. that._scale.vertical = vertical;
  64494. that._rangeContainer.vertical = vertical
  64495. },
  64496. _measureMainElements: function(elements) {
  64497. var that = this,
  64498. minBound = 1000,
  64499. maxBound = 0,
  64500. indent = 0;
  64501. $each(elements, function(_, element) {
  64502. var bounds = element.measure({
  64503. x: that._area.x + (_Number(element._options.offset) || 0),
  64504. y: that._area.y + (_Number(element._options.offset) || 0)
  64505. });
  64506. maxBound = max(maxBound, bounds.max);
  64507. minBound = min(minBound, bounds.min);
  64508. bounds.indent > 0 && (indent = max(indent, bounds.indent))
  64509. });
  64510. return {
  64511. minBound: minBound,
  64512. maxBound: maxBound,
  64513. indent: indent
  64514. }
  64515. },
  64516. _applyMainLayout: function(elements) {
  64517. var that = this,
  64518. measurements = that._measureMainElements(elements),
  64519. area = that._area,
  64520. rect,
  64521. offset,
  64522. counterSize = area.scaleSize + 2 * measurements.indent;
  64523. if (area.vertical) {
  64524. rect = that._layoutManager.selectRectBySizes({
  64525. width: measurements.maxBound - measurements.minBound,
  64526. height: counterSize
  64527. });
  64528. offset = rect.horizontalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
  64529. area.startCoord = rect.bottom - measurements.indent;
  64530. area.endCoord = rect.top + measurements.indent;
  64531. area.x = round(area.x + offset)
  64532. }
  64533. else {
  64534. rect = that._layoutManager.selectRectBySizes({
  64535. height: measurements.maxBound - measurements.minBound,
  64536. width: counterSize
  64537. });
  64538. offset = rect.verticalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
  64539. area.startCoord = rect.left + measurements.indent;
  64540. area.endCoord = rect.right - measurements.indent;
  64541. area.y = round(area.y + offset)
  64542. }
  64543. that._translator.setCodomain(area.startCoord, area.endCoord);
  64544. that._layoutManager.setRect(rect)
  64545. },
  64546. _updateElementPosition: function(element) {
  64547. element.resize({
  64548. x: round(this._area.x + (_Number(element._options.offset) || 0)),
  64549. y: round(this._area.y + (_Number(element._options.offset) || 0))
  64550. })
  64551. },
  64552. _createScale: function(parameters) {
  64553. return factory.createLinearScale(parameters)
  64554. },
  64555. _createRangeContainer: function(parameters) {
  64556. return factory.createLinearRangeContainer(parameters)
  64557. },
  64558. _createValueIndicator: function(type) {
  64559. return factory.createLinearValueIndicator(type)
  64560. },
  64561. _createSubvalueIndicator: function(type) {
  64562. return factory.createLinearSubvalueIndicator(type)
  64563. },
  64564. _getApproximateScreenRange: function() {
  64565. var that = this,
  64566. area = that._area,
  64567. s = area.vertical ? that._height : that._width;
  64568. s > area.totalSize && (s = area.totalSize);
  64569. s = s * 0.8;
  64570. return s
  64571. },
  64572. _getDefaultContainerSize: function() {
  64573. var geometry = this.option('geometry') || {};
  64574. if (geometry.orientation === 'vertical')
  64575. return {
  64576. width: 100,
  64577. height: 300
  64578. };
  64579. else
  64580. return {
  64581. width: 300,
  64582. height: 100
  64583. }
  64584. },
  64585. _getPreset: function() {
  64586. var preset = this.option('preset'),
  64587. result;
  64588. if (preset === 'preset2')
  64589. result = {
  64590. commonNeedleSettings: {type: 'rhombus'},
  64591. commonMarkerSettings: {type: 'triangle'}
  64592. };
  64593. else
  64594. result = {
  64595. commonNeedleSettings: {type: 'circle'},
  64596. commonMarkerSettings: {type: 'textcloud'}
  64597. };
  64598. return result
  64599. },
  64600. _createNeedle: function(type) {
  64601. return factory.createLinearNeedle(type)
  64602. },
  64603. _createMarker: function(type) {
  64604. return factory.createLinearMarker(type)
  64605. },
  64606. _createRangeBar: function() {
  64607. return factory.createLinearRangeBar()
  64608. }
  64609. });
  64610. DX.viz.gauges.LinearGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  64611. DX.viz.gauges.LinearGauge.prototype._factory.createThemeManager = function() {
  64612. var themeManager = new DX.viz.gauges.__internals.ThemeManager;
  64613. themeManager._subTheme = '_linear';
  64614. return themeManager
  64615. }
  64616. })(DevExpress, jQuery);
  64617. /*! Module viz-gauges, file barGauge.js */
  64618. (function(DX, $, undefined) {
  64619. var PI = Math.PI;
  64620. var _Number = window.Number,
  64621. _isFinite = window.isFinite,
  64622. _abs = Math.abs,
  64623. _round = Math.round,
  64624. _floor = Math.floor,
  64625. _min = Math.min,
  64626. _max = Math.max,
  64627. _isArray = DX.utils.isArray,
  64628. _convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  64629. _getCosAndSin = DX.utils.getCosAndSin,
  64630. _noop = $.noop,
  64631. _extend = $.extend,
  64632. _getSampleText = DX.viz.gauges.__internals.getSampleText,
  64633. _formatValue = DX.viz.gauges.__internals.formatValue;
  64634. var _Rectangle = DX.viz.core.Rectangle,
  64635. _Palette = DX.viz.core.Palette;
  64636. DX.viz.gauges.BarGauge = DX.viz.gauges.__internals.BaseGauge.inherit({
  64637. _rootClass: 'dxbg-bar-gauge',
  64638. _init: function() {
  64639. var that = this;
  64640. that.callBase.apply(that, arguments);
  64641. that._barsGroup = that._renderer.createGroup({'class': 'dxbg-bars'});
  64642. that._values = [];
  64643. that._context = {
  64644. renderer: that._renderer,
  64645. translator: that._translator,
  64646. tracker: that._tracker,
  64647. group: that._barsGroup
  64648. };
  64649. that._animateStep = function(pos) {
  64650. var bars = that._bars,
  64651. i = 0,
  64652. ii = bars.length;
  64653. for (; i < ii; ++i)
  64654. bars[i].animate(pos)
  64655. };
  64656. that._animateComplete = function() {
  64657. var bars = that._bars,
  64658. i = 0,
  64659. ii = bars.length;
  64660. for (; i < ii; ++i)
  64661. bars[i].endAnimation()
  64662. }
  64663. },
  64664. _dispose: function() {
  64665. var that = this;
  64666. that.callBase.apply(that, arguments);
  64667. that._barsGroup = that._values = that._context = that._animateStep = that._animateComplete = null
  64668. },
  64669. _setupDomain: function() {
  64670. var that = this,
  64671. startValue = that.option('startValue'),
  64672. endValue = that.option('endValue');
  64673. _isFinite(startValue) || (startValue = 0);
  64674. _isFinite(endValue) || (endValue = 100);
  64675. that._translator.setDomain(startValue, endValue);
  64676. that._baseValue = that._translator.adjust(that.option('baseValue'));
  64677. _isFinite(that._baseValue) || (that._baseValue = startValue < endValue ? startValue : endValue)
  64678. },
  64679. _calculateSizeCore: function() {
  64680. var that = this,
  64681. size = that.option('size') || {};
  64682. if (_Number(size.width) === 0 || _Number(size.height) === 0) {
  64683. that._width = that._height = 0;
  64684. that._rootRect = new _Rectangle
  64685. }
  64686. else {
  64687. that._width = size.width > 0 ? _Number(size.width) : that._element().width() || 300;
  64688. that._height = size.height > 0 ? _Number(size.height) : that._element().height() || 300;
  64689. that._rootRect = new _Rectangle({
  64690. left: 0,
  64691. top: 0,
  64692. right: that._width,
  64693. bottom: that._height
  64694. })
  64695. }
  64696. },
  64697. _setupCodomain: DX.viz.gauges.CircularGauge.prototype._setupCodomain,
  64698. _getApproximateScreenRange: function() {
  64699. var that = this,
  64700. sides = that._area.sides,
  64701. width = that._width / (sides.right - sides.left),
  64702. height = that._height / (sides.down - sides.up),
  64703. r = width < height ? width : height;
  64704. return -that._translator.getCodomainRange() * r * PI / 180
  64705. },
  64706. _setupAnimationSettings: function() {
  64707. this.callBase();
  64708. if (this._animationSettings)
  64709. _extend(this._animationSettings, {
  64710. step: this._animateStep,
  64711. complete: this._animateComplete
  64712. })
  64713. },
  64714. _cleanContent: function() {
  64715. var that = this;
  64716. that._barsGroup.detach();
  64717. that._animationSettings && that._barsGroup.stopAnimation();
  64718. var i = 0,
  64719. ii = that._bars ? that._bars.length : 0;
  64720. for (; i < ii; ++i)
  64721. that._bars[i].dispose();
  64722. that._palette = that._bars = null
  64723. },
  64724. _renderContent: function() {
  64725. var that = this,
  64726. labelOptions = that.option('label');
  64727. that._barsGroup.append(that._root);
  64728. that._context.textEnabled = labelOptions === undefined || labelOptions && (!('visible' in labelOptions) || labelOptions.visible);
  64729. if (that._context.textEnabled) {
  64730. that._context.textColor = labelOptions && labelOptions.font && labelOptions.font.color || null;
  64731. labelOptions = _extend(true, {}, that._themeManager.theme().label, labelOptions);
  64732. that._context.formatOptions = {
  64733. format: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.format : that._defaultFormatOptions.format,
  64734. precision: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.precision : that._defaultFormatOptions.precision,
  64735. customizeText: labelOptions.customizeText
  64736. };
  64737. that._context.textOptions = {
  64738. font: _extend({}, that._themeManager.theme().label.font, labelOptions.font, {color: null}),
  64739. align: 'center'
  64740. };
  64741. that._textIndent = labelOptions.indent > 0 ? _Number(labelOptions.indent) : 0;
  64742. that._context.lineWidth = labelOptions.connectorWidth > 0 ? _Number(labelOptions.connectorWidth) : 0;
  64743. that._context.lineColor = labelOptions.connectorColor || null;
  64744. var text = that._renderer.createText(_getSampleText(that._translator, that._context.formatOptions), 0, 0, that._context.textOptions).append(that._barsGroup),
  64745. bbox = text.getBBox();
  64746. text.detach();
  64747. that._context.textVerticalOffset = -bbox.y - bbox.height / 2;
  64748. that._context.textWidth = bbox.width;
  64749. that._context.textHeight = bbox.height
  64750. }
  64751. DX.viz.gauges.CircularGauge.prototype._applyMainLayout.call(that);
  64752. that._renderBars()
  64753. },
  64754. _measureMainElements: function() {
  64755. var result = {maxRadius: this._area.radius};
  64756. if (this._context.textEnabled) {
  64757. result.horizontalMargin = this._context.textWidth;
  64758. result.verticalMargin = this._context.textHeight
  64759. }
  64760. return result
  64761. },
  64762. _renderBars: function() {
  64763. var that = this,
  64764. options = _extend({}, that._themeManager.theme(), that.option());
  64765. that._palette = new _Palette(options.palette, {
  64766. stepHighlight: 50,
  64767. theme: that._themeManager.themeName()
  64768. });
  64769. var relativeInnerRadius = options.relativeInnerRadius > 0 && options.relativeInnerRadius < 1 ? _Number(options.relativeInnerRadius) : 0.1,
  64770. radius = that._area.radius;
  64771. if (that._context.textEnabled) {
  64772. that._textIndent = _round(_min(that._textIndent, radius / 2));
  64773. radius -= that._textIndent
  64774. }
  64775. that._outerRadius = _round(radius);
  64776. that._innerRadius = _round(radius * relativeInnerRadius);
  64777. that._barSpacing = options.barSpacing > 0 ? _Number(options.barSpacing) : 0;
  64778. _extend(that._context, {
  64779. backgroundColor: options.backgroundColor,
  64780. x: that._area.x,
  64781. y: that._area.y,
  64782. startAngle: that._area.startCoord,
  64783. endAngle: that._area.endCoord,
  64784. baseAngle: that._translator.translate(that._baseValue)
  64785. });
  64786. that._bars = [];
  64787. that._updateValues(that.option('values'))
  64788. },
  64789. _arrangeBars: function(count) {
  64790. var that = this,
  64791. radius = that._outerRadius - that._innerRadius;
  64792. that._context.barSize = count > 0 ? _max((radius - (count - 1) * that._barSpacing) / count, 1) : 0;
  64793. var spacing = count > 1 ? _max(_min((radius - count * that._context.barSize) / (count - 1), that._barSpacing), 0) : 0,
  64794. _count = _min(_floor((radius + spacing) / that._context.barSize), count);
  64795. that._setBarsCount(_count);
  64796. radius = that._outerRadius;
  64797. that._context.textRadius = radius + that._textIndent;
  64798. that._palette.reset();
  64799. var unitOffset = that._context.barSize + spacing,
  64800. i = 0;
  64801. for (; i < _count; ++i, radius -= unitOffset)
  64802. that._bars[i].arrange({
  64803. radius: radius,
  64804. color: that._palette.getNextColor()
  64805. })
  64806. },
  64807. _setBarsCount: function(count) {
  64808. var that = this,
  64809. i,
  64810. ii;
  64811. if (that._bars.length > count) {
  64812. for (i = count, ii = that._bars.length; i < ii; ++i)
  64813. that._bars[i].dispose();
  64814. that._bars.splice(count, ii - count)
  64815. }
  64816. else if (that._bars.length < count)
  64817. for (i = that._bars.length, ii = count; i < ii; ++i)
  64818. that._bars.push(new BarWrapper(i, that._context));
  64819. if (that._bars.length > 0) {
  64820. if (that._dummyBackground) {
  64821. that._dummyBackground.detach();
  64822. that._dummyBackground = null
  64823. }
  64824. }
  64825. else {
  64826. if (!that._dummyBackground)
  64827. that._dummyBackground = that._renderer.createArc().append(that._barsGroup);
  64828. that._dummyBackground.applySettings({
  64829. x: that._context.x,
  64830. y: that._context.y,
  64831. outerRadius: that._outerRadius,
  64832. innerRadius: that._innerRadius,
  64833. startAngle: that._context.endAngle,
  64834. endAngle: that._context.startAngle,
  64835. fill: that._context.backgroundColor
  64836. })
  64837. }
  64838. },
  64839. _updateBars: function() {
  64840. var that = this,
  64841. i = 0,
  64842. ii = that._bars.length;
  64843. for (; i < ii; ++i)
  64844. that._bars[i].setValue(that._values[i])
  64845. },
  64846. _animateBars: function() {
  64847. var that = this,
  64848. i = 0,
  64849. ii = that._bars.length;
  64850. if (ii > 0) {
  64851. for (; i < ii; ++i)
  64852. that._bars[i].beginAnimation(that._values[i]);
  64853. that._barsGroup.animate({_: 0}, that._animationSettings)
  64854. }
  64855. },
  64856. _updateValues: function(values, noAnimation) {
  64857. var that = this,
  64858. list = _isArray(values) && values || _isFinite(values) && [values] || [],
  64859. i = 0,
  64860. ii = list.length,
  64861. value;
  64862. that._values = [];
  64863. for (; i < ii; ++i) {
  64864. value = that._translator.adjust(list[i]);
  64865. _isFinite(value) && that._values.push(value)
  64866. }
  64867. that._animationSettings && that._barsGroup.stopAnimation();
  64868. if (that._bars) {
  64869. that._arrangeBars(that._values.length);
  64870. if (that._animationSettings && !that._noAnimation)
  64871. that._animateBars();
  64872. else
  64873. that._updateBars()
  64874. }
  64875. if (!that._resizing) {
  64876. that.option('values', that._values);
  64877. that.hideLoadingIndicator()
  64878. }
  64879. },
  64880. values: function(arg) {
  64881. if (arg !== undefined) {
  64882. this._updateValues(arg);
  64883. return this
  64884. }
  64885. else
  64886. return this._values.slice(0)
  64887. },
  64888. _optionChanged: function(name, newValue, oldValue) {
  64889. switch (name) {
  64890. case'values':
  64891. this._updateValues(newValue);
  64892. break;
  64893. default:
  64894. this.callBase.apply(this, arguments);
  64895. break
  64896. }
  64897. },
  64898. _optionValuesEqual: function(name, oldValue, newValue) {
  64899. switch (name) {
  64900. case'values':
  64901. return compareArrays(oldValue, newValue);
  64902. default:
  64903. return this.callBase.apply(this, arguments)
  64904. }
  64905. }
  64906. });
  64907. var ThemeManager = DX.viz.gauges.__internals.ThemeManager.inherit({
  64908. _themeSection: 'barGauge',
  64909. _initializeTheme: function() {
  64910. var that = this;
  64911. that._initializeFont(that._theme.label.font);
  64912. that._initializeFont(that._theme.title.font);
  64913. that._initializeFont(that._theme.tooltip.font);
  64914. that._initializeFont(that._theme.loadingIndicator.font)
  64915. }
  64916. });
  64917. DX.viz.gauges.BarGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  64918. DX.viz.gauges.BarGauge.prototype._factory.createThemeManager = function() {
  64919. return new ThemeManager
  64920. };
  64921. function BarWrapper(index, context) {
  64922. var that = this;
  64923. that._context = context;
  64924. that._background = context.renderer.createArc().append(context.group);
  64925. that._background.applySettings({fill: context.backgroundColor});
  64926. that._bar = context.renderer.createArc().append(context.group);
  64927. if (context.textEnabled) {
  64928. that._line = context.renderer.createPath([], {strokeWidth: context.lineWidth}).append(context.group);
  64929. that._text = context.renderer.createText('', 0, 0, context.textOptions).append(context.group)
  64930. }
  64931. that._tracker = context.renderer.createArc();
  64932. context.tracker.attach(that._tracker, that, {index: index});
  64933. that._index = index;
  64934. that._angle = context.baseAngle;
  64935. that._settings = {
  64936. x: context.x,
  64937. y: context.y,
  64938. startAngle: context.baseAngle,
  64939. endAngle: context.baseAngle
  64940. }
  64941. }
  64942. _extend(BarWrapper.prototype, {
  64943. dispose: function() {
  64944. var that = this;
  64945. that._background.detach();
  64946. that._bar.detach();
  64947. if (that._context.textEnabled) {
  64948. that._line.detach();
  64949. that._text.detach()
  64950. }
  64951. that._context.tracker.detach(that._tracker);
  64952. that._context = that._settings = that._background = that._bar = that._line = that._text = that._tracker = null;
  64953. return that
  64954. },
  64955. arrange: function(options) {
  64956. var that = this;
  64957. that._settings.outerRadius = options.radius;
  64958. that._settings.innerRadius = options.radius - that._context.barSize;
  64959. that._background.applySettings(_extend({}, that._settings, {
  64960. startAngle: that._context.endAngle,
  64961. endAngle: that._context.startAngle
  64962. }));
  64963. that._bar.applySettings(that._settings);
  64964. that._tracker.applySettings(that._settings);
  64965. that._color = options.color;
  64966. that._bar.applySettings({fill: options.color});
  64967. if (that._context.textEnabled) {
  64968. that._line.applySettings({
  64969. points: [that._context.x, that._context.y - that._settings.innerRadius, that._context.x, that._context.y - that._context.textRadius],
  64970. stroke: that._context.lineColor || options.color
  64971. });
  64972. that._text.applySettings({font: {color: that._context.textColor || options.color}})
  64973. }
  64974. return that
  64975. },
  64976. getTooltipParameters: function() {
  64977. var that = this,
  64978. cossin = _getCosAndSin((that._angle + that._context.baseAngle) / 2);
  64979. return {
  64980. x: _round(that._context.x + (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.cos),
  64981. y: _round(that._context.y - (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.sin),
  64982. offset: 0,
  64983. color: that._color,
  64984. value: that._value
  64985. }
  64986. },
  64987. setAngle: function(angle) {
  64988. var that = this;
  64989. that._angle = angle;
  64990. setAngles(that._settings, that._context.baseAngle, that._angle);
  64991. that._bar.applySettings(that._settings);
  64992. that._tracker.applySettings(that._settings);
  64993. if (that._context.textEnabled) {
  64994. that._line.rotate(_convertAngleToRendererSpace(that._angle), that._context.x, that._context.y);
  64995. var cossin = _getCosAndSin(that._angle);
  64996. that._text.applySettings({
  64997. text: _formatValue(that._value, that._context.formatOptions, {index: that._index}),
  64998. x: that._context.x + (that._context.textRadius + that._context.textWidth * 0.6) * cossin.cos,
  64999. y: that._context.y - (that._context.textRadius + that._context.textHeight * 0.6) * cossin.sin + that._context.textVerticalOffset
  65000. })
  65001. }
  65002. return that
  65003. },
  65004. setValue: function(value) {
  65005. this._value = value;
  65006. return this.setAngle(this._context.translator.translate(value))
  65007. },
  65008. beginAnimation: function(value) {
  65009. var that = this;
  65010. that._value = value;
  65011. var angle = that._context.translator.translate(value);
  65012. if (!compareFloats(that._angle, angle)) {
  65013. that._start = that._angle;
  65014. that._delta = angle - that._angle;
  65015. that._tracker.applySettings({visibility: 'hidden'});
  65016. if (that._context.textEnabled) {
  65017. that._line.applySettings({visibility: 'hidden'});
  65018. that._text.applySettings({visibility: 'hidden'})
  65019. }
  65020. }
  65021. else
  65022. that.animate = _noop
  65023. },
  65024. animate: function(pos) {
  65025. var that = this;
  65026. that._angle = that._start + that._delta * pos;
  65027. setAngles(that._settings, that._context.baseAngle, that._angle);
  65028. that._bar.applySettings(that._settings)
  65029. },
  65030. endAnimation: function() {
  65031. var that = this;
  65032. if (that._delta !== undefined) {
  65033. if (compareFloats(that._angle, that._start + that._delta)) {
  65034. that._tracker.applySettings({visibility: null});
  65035. if (that._context.textEnabled) {
  65036. that._line.applySettings({visibility: null});
  65037. that._text.applySettings({visibility: null})
  65038. }
  65039. that.setAngle(that._angle)
  65040. }
  65041. }
  65042. else
  65043. delete that.animate;
  65044. delete that._start;
  65045. delete that._delta
  65046. }
  65047. });
  65048. function setAngles(target, angle1, angle2) {
  65049. target.startAngle = angle1 < angle2 ? angle1 : angle2;
  65050. target.endAngle = angle1 < angle2 ? angle2 : angle1
  65051. }
  65052. function compareFloats(value1, value2) {
  65053. return _abs(value1 - value2) < 0.0001
  65054. }
  65055. function compareArrays(array1, array2) {
  65056. if (array1 === array2)
  65057. return true;
  65058. if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
  65059. for (var i = 0, ii = array1.length; i < ii; ++i)
  65060. if (!compareFloats(array1[i], array2[i]))
  65061. return false;
  65062. return true
  65063. }
  65064. return false
  65065. }
  65066. var __BarWrapper = BarWrapper;
  65067. DX.viz.gauges.__tests.BarWrapper = __BarWrapper;
  65068. DX.viz.gauges.__tests.stubBarWrapper = function(barWrapperType) {
  65069. BarWrapper = barWrapperType
  65070. };
  65071. DX.viz.gauges.__tests.restoreBarWrapper = function() {
  65072. BarWrapper = __BarWrapper
  65073. };
  65074. DX.registerComponent('dxBarGauge', DX.viz.gauges.BarGauge)
  65075. })(DevExpress, jQuery);
  65076. /*! Module viz-gauges, file tracker.js */
  65077. (function(DX, $, undefined) {
  65078. var _setTimeout = window.setTimeout,
  65079. _clearTimeout = window.clearTimeout,
  65080. _extend = $.extend,
  65081. _abs = Math.abs;
  65082. var TOOLTIP_SHOW_DELAY = 300,
  65083. TOOLTIP_HIDE_DELAY = 300,
  65084. TOOLTIP_TOUCH_SHOW_DELAY = 400,
  65085. TOOLTIP_TOUCH_HIDE_DELAY = 300;
  65086. DX.viz.gauges.__internals.Tracker = DX.Class.inherit({
  65087. ctor: function(parameters) {
  65088. DX.utils.debug.assertParam(parameters, 'parameters');
  65089. DX.utils.debug.assertParam(parameters.renderer, 'parameters.renderer');
  65090. DX.utils.debug.assertParam(parameters.container, 'parameters.container');
  65091. var that = this;
  65092. that._container = parameters.container;
  65093. that._element = parameters.renderer.createGroup({
  65094. 'class': 'dxg-tracker',
  65095. stroke: 'none',
  65096. strokeWidth: 0,
  65097. fill: '#000000',
  65098. opacity: 0.0001
  65099. });
  65100. that._showTooltipCallback = function() {
  65101. that._showTooltipTimeout = null;
  65102. var target = that._tooltipEvent.target;
  65103. that._targetEvent = null;
  65104. if (that._tooltipTarget !== target) {
  65105. that._tooltipTarget = target;
  65106. that._callbacks['tooltip-show']()
  65107. }
  65108. };
  65109. that._hideTooltipCallback = function() {
  65110. that._hideTooltipTimeout = null;
  65111. that._targetEvent = null;
  65112. if (that._tooltipTarget) {
  65113. that._callbacks['tooltip-hide']();
  65114. that._tooltipTarget = null
  65115. }
  65116. };
  65117. that._dispose = function() {
  65118. that._showTooltipCallback = that._hideTooltipCallback = that._dispose = null
  65119. };
  65120. that._DEBUG_showTooltipTimeoutSet = that._DEBUG_showTooltipTimeoutCleared = that._DEBUG_hideTooltipTimeoutSet = that._DEBUG_hideTooltipTimeoutCleared = 0
  65121. },
  65122. dispose: function() {
  65123. var that = this;
  65124. that._dispose();
  65125. that.deactivate();
  65126. that._element.off();
  65127. that._container = that._element = that._context = that._callbacks = null;
  65128. return that
  65129. },
  65130. activate: function() {
  65131. this._element.append(this._container);
  65132. return this
  65133. },
  65134. deactivate: function() {
  65135. this._element.detach();
  65136. this._element.clear();
  65137. return this
  65138. },
  65139. attach: function(element, target, info) {
  65140. element.data({
  65141. target: target,
  65142. info: info
  65143. });
  65144. element.append(this._element);
  65145. return this
  65146. },
  65147. detach: function(element) {
  65148. element.detach();
  65149. element.removeData();
  65150. return this
  65151. },
  65152. setTooltipState: function(state) {
  65153. var that = this,
  65154. data;
  65155. that._element.off(tooltipMouseEvents).off(tooltipTouchEvents);
  65156. if (state) {
  65157. data = {tracker: that};
  65158. that._element.on(tooltipMouseEvents, data).on(tooltipTouchEvents, data)
  65159. }
  65160. return that
  65161. },
  65162. setCallbacks: function(callbacks) {
  65163. this._callbacks = callbacks;
  65164. return this
  65165. },
  65166. _showTooltip: function(event, delay) {
  65167. var that = this,
  65168. data = $(event.target).data();
  65169. if (that._tooltipTarget === event.target || that._callbacks['tooltip-prepare'](data.target, data.info)) {
  65170. that._hideTooltipTimeout && ++that._DEBUG_hideTooltipTimeoutCleared;
  65171. _clearTimeout(that._hideTooltipTimeout);
  65172. that._hideTooltipTimeout = null;
  65173. _clearTimeout(that._showTooltipTimeout);
  65174. that._tooltipEvent = event;
  65175. ++that._DEBUG_showTooltipTimeoutSet;
  65176. that._showTooltipTimeout = _setTimeout(that._showTooltipCallback, delay)
  65177. }
  65178. },
  65179. _hideTooltip: function(delay) {
  65180. var that = this;
  65181. that._showTooltipTimeout && ++that._DEBUG_showTooltipTimeoutCleared;
  65182. _clearTimeout(that._showTooltipTimeout);
  65183. that._showTooltipTimeout = null;
  65184. _clearTimeout(that._hideTooltipTimeout);
  65185. ++that._DEBUG_hideTooltipTimeoutSet;
  65186. that._hideTooltipTimeout = _setTimeout(that._hideTooltipCallback, delay)
  65187. }
  65188. });
  65189. var tooltipMouseEvents = {
  65190. 'mouseover.gauge-tooltip': handleTooltipMouseOver,
  65191. 'mouseout.gauge-tooltip': handleTooltipMouseOut
  65192. };
  65193. var tooltipMouseMoveEvents = {'mousemove.gauge-tooltip': handleTooltipMouseMove};
  65194. var tooltipTouchEvents = {'touchstart.gauge-tooltip': handleTooltipTouchStart};
  65195. function handleTooltipMouseOver(event) {
  65196. var tracker = event.data.tracker;
  65197. tracker._x = event.pageX;
  65198. tracker._y = event.pageY;
  65199. tracker._element.off(tooltipMouseMoveEvents).on(tooltipMouseMoveEvents, event.data);
  65200. tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
  65201. }
  65202. function handleTooltipMouseMove(event) {
  65203. var tracker = event.data.tracker;
  65204. if (tracker._showTooltipTimeout && _abs(event.pageX - tracker._x) > 4 || _abs(event.pageY - tracker._y) > 4) {
  65205. tracker._x = event.pageX;
  65206. tracker._y = event.pageY;
  65207. tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
  65208. }
  65209. }
  65210. function handleTooltipMouseOut(event) {
  65211. var tracker = event.data.tracker;
  65212. tracker._element.off(tooltipMouseMoveEvents);
  65213. tracker._hideTooltip(TOOLTIP_HIDE_DELAY)
  65214. }
  65215. var active_touch_tooltip_tracker = null;
  65216. DX.viz.gauges.__internals.Tracker._DEBUG_reset = function() {
  65217. active_touch_tooltip_tracker = null
  65218. };
  65219. function handleTooltipTouchStart(event) {
  65220. event.preventDefault();
  65221. var tracker = active_touch_tooltip_tracker;
  65222. if (tracker && tracker !== event.data.tracker)
  65223. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  65224. tracker = active_touch_tooltip_tracker = event.data.tracker;
  65225. tracker._showTooltip(event, TOOLTIP_TOUCH_SHOW_DELAY);
  65226. tracker._touch = true
  65227. }
  65228. function handleTooltipDocumentTouchStart(event) {
  65229. var tracker = active_touch_tooltip_tracker;
  65230. if (tracker) {
  65231. if (!tracker._touch) {
  65232. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  65233. active_touch_tooltip_tracker = null
  65234. }
  65235. tracker._touch = null
  65236. }
  65237. }
  65238. function handleTooltipDocumentTouchEnd(event) {
  65239. var tracker = active_touch_tooltip_tracker;
  65240. if (tracker)
  65241. if (tracker._showTooltipTimeout) {
  65242. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  65243. active_touch_tooltip_tracker = null
  65244. }
  65245. }
  65246. $(window.document).on({
  65247. 'touchstart.gauge-tooltip': handleTooltipDocumentTouchStart,
  65248. 'touchend.gauge-tooltip': handleTooltipDocumentTouchEnd
  65249. })
  65250. })(DevExpress, jQuery);
  65251. /*! Module viz-gauges, file dxCircularGauge.js */
  65252. (function(DX, undefined) {
  65253. DX.registerComponent("dxCircularGauge", DX.viz.gauges.CircularGauge)
  65254. })(DevExpress);
  65255. /*! Module viz-gauges, file dxLinearGauge.js */
  65256. (function(DX, undefined) {
  65257. DX.registerComponent("dxLinearGauge", DX.viz.gauges.LinearGauge)
  65258. })(DevExpress);
  65259. DevExpress.MOD_VIZ_GAUGES = true
  65260. }
  65261. if (!DevExpress.MOD_VIZ_RANGESELECTOR) {
  65262. if (!DevExpress.MOD_VIZ_CORE)
  65263. throw Error('Required module is not referenced: viz-core');
  65264. /*! Module viz-rangeselector, file namespaces.js */
  65265. (function(DevExpress) {
  65266. DevExpress.viz.rangeSelector = {utils: {}}
  65267. })(DevExpress);
  65268. /*! Module viz-rangeselector, file utils.js */
  65269. (function($, DX, undefined) {
  65270. var rangeSelector = DX.viz.rangeSelector,
  65271. utils = rangeSelector.utils,
  65272. dxUtils = DX.utils;
  65273. var INVISIBLE_POS = -1000;
  65274. var findLessOrEqualValueIndex = function(values, value) {
  65275. if (!values || values.length === 0)
  65276. return -1;
  65277. var minIndex = 0,
  65278. maxIndex = values.length - 1,
  65279. index = 0;
  65280. while (maxIndex - minIndex > 1) {
  65281. var index = minIndex + maxIndex >> 1;
  65282. if (values[index] > value)
  65283. maxIndex = index;
  65284. else
  65285. minIndex = index
  65286. }
  65287. return values[maxIndex] <= value ? maxIndex : minIndex
  65288. };
  65289. var findLessOrEqualValue = function(values, value) {
  65290. var index = findLessOrEqualValueIndex(values, value);
  65291. if (values && index >= 0 && index < values.length)
  65292. return values[index];
  65293. return value
  65294. };
  65295. var findNearValue = function(values, value) {
  65296. var index = findLessOrEqualValueIndex(values, value);
  65297. if (values && index >= 0 && index < values.length) {
  65298. if (index + 1 < values.length)
  65299. if (dxUtils.isDate(value)) {
  65300. if (values[index + 1].getTime() - value.getTime() < value.getTime() - values[index].getTime())
  65301. index++
  65302. }
  65303. else if (values[index + 1] - value < value - values[index])
  65304. index++;
  65305. return values[index]
  65306. }
  65307. return value
  65308. };
  65309. var findGreaterOrEqualValue = function(values, value) {
  65310. var index = findLessOrEqualValueIndex(values, value);
  65311. if (values && index >= 0 && index < values.length) {
  65312. if (values[index] < value && index + 1 < values.length)
  65313. index++;
  65314. return values[index]
  65315. }
  65316. return value
  65317. };
  65318. var getInterval = function(valueMin, valueMax, delta) {
  65319. var result,
  65320. minDateDaysCount,
  65321. maxDateDaysCount,
  65322. daysCount,
  65323. prevMaxDaysCount;
  65324. if (dxUtils.isDate(valueMin)) {
  65325. if (delta === 'year' || delta === 'quarter' || delta === 'month')
  65326. return {months: valueMax.getFullYear() * 12 + valueMax.getMonth() - valueMin.getFullYear() * 12 - valueMin.getMonth()};
  65327. else
  65328. return {milliseconds: valueMax.valueOf() - valueMin.valueOf()};
  65329. return result
  65330. }
  65331. else
  65332. return valueMax - valueMin
  65333. };
  65334. var getRootOffsetLeft = function(renderer) {
  65335. return dxUtils.getRootOffset(renderer).left || 0
  65336. };
  65337. var getEventPageX = function(eventArgs) {
  65338. var result = 0;
  65339. if (eventArgs.pageX)
  65340. result = eventArgs.pageX;
  65341. else if (eventArgs.originalEvent && eventArgs.originalEvent.pageX)
  65342. result = eventArgs.originalEvent.pageX;
  65343. if (eventArgs.originalEvent && eventArgs.originalEvent.touches)
  65344. if (eventArgs.originalEvent.touches.length > 0)
  65345. result = eventArgs.originalEvent.touches[0].pageX;
  65346. else if (eventArgs.originalEvent.changedTouches.length > 0)
  65347. result = eventArgs.originalEvent.changedTouches[0].pageX;
  65348. return result
  65349. };
  65350. var getTextBBox = function(renderer, text, fontOptions) {
  65351. var textElement = renderer.createText(text, INVISIBLE_POS, INVISIBLE_POS, {font: fontOptions}).append();
  65352. var textBBox = textElement.getBBox();
  65353. textElement.remove();
  65354. return textBBox
  65355. };
  65356. utils.findLessOrEqualValue = findLessOrEqualValue;
  65357. utils.findNearValue = findNearValue;
  65358. utils.findGreaterOrEqualValue = findGreaterOrEqualValue;
  65359. utils.getInterval = getInterval;
  65360. utils.getRootOffsetLeft = getRootOffsetLeft;
  65361. utils.getEventPageX = getEventPageX;
  65362. utils.getTextBBox = getTextBBox
  65363. })(jQuery, DevExpress);
  65364. /*! Module viz-rangeselector, file baseVisualElement.js */
  65365. (function(DX) {
  65366. DevExpress.viz.rangeSelector.BaseVisualElement = DX.Class.inherit({
  65367. ctor: function(renderer) {
  65368. this._renderer = renderer;
  65369. this._isDrawn = false
  65370. },
  65371. applyOptions: function(options) {
  65372. this._options = options || {};
  65373. this._applyOptions(this._options)
  65374. },
  65375. _applyOptions: function(options){},
  65376. redraw: function(group) {
  65377. var that = this;
  65378. if (!that._isDrawn) {
  65379. that._isDrawn = !(that._draw(group || that._group) === false);
  65380. if (group)
  65381. that._group = group
  65382. }
  65383. else
  65384. that._update(group || that._group)
  65385. },
  65386. isDrawn: function() {
  65387. return !!this._isDrawn
  65388. },
  65389. isInitialized: function() {
  65390. return !!this._options
  65391. },
  65392. _draw: function(group){},
  65393. _update: function(group) {
  65394. group.clear();
  65395. this._draw(group)
  65396. }
  65397. })
  65398. })(DevExpress);
  65399. /*! Module viz-rangeselector, file rangeSelector.js */
  65400. (function($, DX, undefined) {
  65401. var rangeSelector = DX.viz.rangeSelector,
  65402. utils = DX.utils,
  65403. dataUtils = DX.data.utils,
  65404. rangeSelectorUtils = rangeSelector.utils,
  65405. ParseUtils = DX.viz.core.ParseUtils,
  65406. formatHelper = DX.formatHelper,
  65407. core = DX.viz.core,
  65408. _max = Math.max,
  65409. _isDefined = utils.isDefined;
  65410. rangeSelector.consts = {
  65411. fontHeightRatio: 0.55,
  65412. emptySliderMarkerText: '. . .'
  65413. };
  65414. rangeSelector.formatValue = function(value, formatOptions) {
  65415. var formatObject = {
  65416. value: value,
  65417. valueText: formatHelper.format(value, formatOptions.format, formatOptions.precision)
  65418. };
  65419. return String(utils.isFunction(formatOptions.customizeText) ? formatOptions.customizeText.call(formatObject, formatObject) : formatObject.valueText)
  65420. };
  65421. rangeSelector.RangeSelector = core.BaseWidget.inherit(function() {
  65422. var SCALE_TEXT_SPACING = 5;
  65423. var defaultRangeSelectorOptions = {
  65424. size: undefined,
  65425. margin: {
  65426. left: 0,
  65427. top: 0,
  65428. right: 0,
  65429. bottom: 0
  65430. },
  65431. scale: {
  65432. showCustomBoundaryTicks: true,
  65433. showMinorTicks: true,
  65434. startValue: undefined,
  65435. endValue: undefined,
  65436. minorTickCount: undefined,
  65437. minorTickInterval: undefined,
  65438. majorTickInterval: undefined,
  65439. useTicksAutoArrangement: true,
  65440. setTicksAtUnitBeginning: true,
  65441. minRange: undefined,
  65442. maxRange: undefined,
  65443. placeholderHeight: undefined,
  65444. valueType: undefined,
  65445. label: {
  65446. visible: true,
  65447. format: undefined,
  65448. precision: undefined,
  65449. customizeText: undefined
  65450. },
  65451. marker: {
  65452. visible: true,
  65453. label: {
  65454. format: undefined,
  65455. precision: undefined,
  65456. customizeText: undefined
  65457. }
  65458. },
  65459. logarithmBase: 10
  65460. },
  65461. selectedRange: undefined,
  65462. sliderMarker: {
  65463. visible: true,
  65464. format: undefined,
  65465. precision: undefined,
  65466. customizeText: undefined,
  65467. placeholderSize: undefined
  65468. },
  65469. behavior: {
  65470. snapToTicks: true,
  65471. animationEnabled: true,
  65472. moveSelectedRangeByClick: true,
  65473. manualRangeSelectionEnabled: true,
  65474. allowSlidersSwap: true,
  65475. callSelectedRangeChanged: "onMovingComplete"
  65476. },
  65477. background: {
  65478. color: "#C0BAE1",
  65479. visible: true,
  65480. image: {
  65481. url: undefined,
  65482. location: 'full'
  65483. }
  65484. },
  65485. dataSource: undefined,
  65486. dataSourceField: 'arg',
  65487. redrawOnResize: true,
  65488. theme: undefined,
  65489. selectedRangeChanged: null
  65490. };
  65491. var calculateMarkerSize = function(renderer, value, sliderMarkerOptions) {
  65492. var formattedText = value === undefined ? rangeSelector.consts.emptySliderMarkerText : rangeSelector.formatValue(value, sliderMarkerOptions),
  65493. textBBox = rangeSelectorUtils.getTextBBox(renderer, formattedText, sliderMarkerOptions.font);
  65494. return {
  65495. width: Math.ceil(textBBox.width) + 2 * sliderMarkerOptions.padding,
  65496. height: Math.ceil(textBBox.height * rangeSelector.consts.fontHeightRatio) + 2 * sliderMarkerOptions.padding + sliderMarkerOptions.pointerSize
  65497. }
  65498. };
  65499. var calculateScaleLabelHalfWidth = function(renderer, value, scaleOptions) {
  65500. var formattedText = rangeSelector.formatValue(value, scaleOptions.label),
  65501. textBBox = rangeSelectorUtils.getTextBBox(renderer, formattedText, scaleOptions.label.font);
  65502. return Math.ceil(textBBox.width / 2)
  65503. };
  65504. var calculateRangeContainerCanvas = function(size, margin, sliderMarkerSpacing) {
  65505. var canvas = {
  65506. left: margin.left + sliderMarkerSpacing.left,
  65507. top: margin.top + sliderMarkerSpacing.top,
  65508. width: size.width - margin.left - margin.right - sliderMarkerSpacing.left - sliderMarkerSpacing.right,
  65509. height: size.height - margin.top - margin.bottom - sliderMarkerSpacing.top - sliderMarkerSpacing.bottom
  65510. };
  65511. if (canvas.width <= 0)
  65512. canvas.width = 1;
  65513. return canvas
  65514. };
  65515. var parseSliderMarkersPlaceholderSize = function(placeholderSize) {
  65516. var placeholderWidthLeft,
  65517. placeholderWidthRight,
  65518. placeholderHeight;
  65519. if (utils.isNumber(placeholderSize))
  65520. placeholderWidthLeft = placeholderWidthRight = placeholderHeight = placeholderSize;
  65521. else if (placeholderSize) {
  65522. if (utils.isNumber(placeholderSize.height))
  65523. placeholderHeight = placeholderSize.height;
  65524. if (utils.isNumber(placeholderSize.width))
  65525. placeholderWidthLeft = placeholderWidthRight = placeholderSize.width;
  65526. else if (placeholderSize.width) {
  65527. if (utils.isNumber(placeholderSize.width.left))
  65528. placeholderWidthLeft = placeholderSize.width.left;
  65529. if (utils.isNumber(placeholderSize.width.right))
  65530. placeholderWidthRight = placeholderSize.width.right
  65531. }
  65532. }
  65533. return {
  65534. widthLeft: placeholderWidthLeft,
  65535. widthRight: placeholderWidthRight,
  65536. height: placeholderHeight
  65537. }
  65538. };
  65539. var calculateSliderMarkersSpacing = function(renderer, size, scale, sliderMarkerOptions) {
  65540. var leftMarkerSize,
  65541. leftScaleLabelWidth = 0,
  65542. rightScaleLabelWidth = 0,
  65543. rightMarkerSize,
  65544. placeholderWidthLeft = 0,
  65545. placeholderWidthRight = 0,
  65546. placeholderHeight = 0,
  65547. parsedPlaceholderSize,
  65548. markerMaxWidth;
  65549. parsedPlaceholderSize = parseSliderMarkersPlaceholderSize(sliderMarkerOptions.placeholderSize);
  65550. placeholderWidthLeft = parsedPlaceholderSize.widthLeft || 0;
  65551. placeholderWidthRight = parsedPlaceholderSize.widthRight || 0;
  65552. placeholderHeight = parsedPlaceholderSize.height || 0;
  65553. if (sliderMarkerOptions.visible) {
  65554. leftMarkerSize = calculateMarkerSize(renderer, scale.startValue, sliderMarkerOptions);
  65555. rightMarkerSize = calculateMarkerSize(renderer, scale.endValue, sliderMarkerOptions);
  65556. markerMaxWidth = _max(leftMarkerSize.width, rightMarkerSize.width);
  65557. if (!placeholderWidthLeft)
  65558. placeholderWidthLeft = markerMaxWidth;
  65559. if (!placeholderWidthRight)
  65560. placeholderWidthRight = markerMaxWidth;
  65561. if (!placeholderHeight)
  65562. placeholderHeight = _max(leftMarkerSize.height, rightMarkerSize.height)
  65563. }
  65564. if (scale.label.visible) {
  65565. leftScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.startValue, scale);
  65566. rightScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.endValue, scale)
  65567. }
  65568. placeholderWidthLeft = _max(placeholderWidthLeft, leftScaleLabelWidth);
  65569. placeholderWidthRight = _max(placeholderWidthRight, rightScaleLabelWidth);
  65570. return {
  65571. left: placeholderWidthLeft,
  65572. right: placeholderWidthRight,
  65573. top: placeholderHeight,
  65574. bottom: 0
  65575. }
  65576. };
  65577. var clearContainer = function(container) {
  65578. if (container)
  65579. container.empty()
  65580. };
  65581. var getContainer = function(that) {
  65582. return that._element()
  65583. };
  65584. var createRangeContainer = function(rangeContainerOptions) {
  65585. return rangeSelector.rangeSelectorFactory.createRangeContainer(rangeContainerOptions)
  65586. };
  65587. var createTranslator = function(range, canvas) {
  65588. return {
  65589. x: core.CoreFactory.createTranslator2D(range.arg, canvas, {direction: "horizontal"}),
  65590. y: core.CoreFactory.createTranslator2D(range.val, canvas)
  65591. }
  65592. };
  65593. var createTranslatorCanvas = function(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight) {
  65594. return {
  65595. left: rangeContainerCanvas.left,
  65596. top: rangeContainerCanvas.top,
  65597. right: sizeOptions.width - rangeContainerCanvas.width - rangeContainerCanvas.left,
  65598. bottom: sizeOptions.height - rangeContainerCanvas.height - rangeContainerCanvas.top + scaleLabelsAreaHeight,
  65599. width: sizeOptions.width,
  65600. height: sizeOptions.height
  65601. }
  65602. };
  65603. var createRenderer = function(that) {
  65604. var renderer = that.option('renderer');
  65605. if (renderer)
  65606. return renderer;
  65607. return core.CoreFactory.createRenderer({
  65608. pathModified: that.option('pathModified'),
  65609. rtl: that.option('rtlEnabled')
  65610. })
  65611. };
  65612. var createThemeManager = function(theme) {
  65613. return rangeSelector.rangeSelectorFactory.createThemeManager(theme)
  65614. };
  65615. var calculateValueType = function(firstValue, secondValue) {
  65616. var types = [$.type(firstValue), $.type(secondValue)];
  65617. $.inArray();
  65618. return $.inArray('date', types) != -1 ? 'datetime' : $.inArray('number', types) != -1 ? 'numeric' : ''
  65619. };
  65620. var createSeriesDataSource = function(that) {
  65621. var seriesDataSource,
  65622. dataSource = that._dataSource && that._dataSource.items(),
  65623. scaleOptions = that.option('scale'),
  65624. chartOptions = that.option('chart') || {},
  65625. valueType = scaleOptions.valueType;
  65626. if (!valueType)
  65627. valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue);
  65628. if (dataSource || chartOptions.series) {
  65629. seriesDataSource = new rangeSelector.SeriesDataSource({
  65630. renderer: that.renderer,
  65631. dataSource: dataSource,
  65632. valueType: (valueType || '').toLowerCase(),
  65633. axisType: scaleOptions.type,
  65634. chart: chartOptions,
  65635. dataSourceField: that.option('dataSourceField'),
  65636. backgroundColor: that._userBackgroundColor,
  65637. incidentOccured: that._incidentOccured
  65638. });
  65639. checkLogarithmicOptions(chartOptions.valueAxis, seriesDataSource.themeManager.theme().valueAxis.logarithmBase, that._incidentOccured)
  65640. }
  65641. return seriesDataSource
  65642. };
  65643. var calculateTranslatorRange = function(that, seriesDataSource, scaleOptions) {
  65644. var translatorRange,
  65645. minValue,
  65646. maxValue,
  65647. inverted = false,
  65648. isEqualDates;
  65649. if (_isDefined(scaleOptions.startValue) && _isDefined(scaleOptions.endValue)) {
  65650. inverted = scaleOptions.inverted = scaleOptions.startValue > scaleOptions.endValue;
  65651. minValue = inverted ? scaleOptions.endValue : scaleOptions.startValue;
  65652. maxValue = inverted ? scaleOptions.startValue : scaleOptions.endValue
  65653. }
  65654. else if (_isDefined(scaleOptions.startValue) || _isDefined(scaleOptions.endValue)) {
  65655. minValue = scaleOptions.startValue;
  65656. maxValue = scaleOptions.endValue
  65657. }
  65658. translatorRange = seriesDataSource ? seriesDataSource.getBoundRange() : {
  65659. arg: new core.Range,
  65660. val: new core.Range({isValueRange: true})
  65661. };
  65662. isEqualDates = utils.isDate(minValue) && utils.isDate(maxValue) && minValue.getTime() === maxValue.getTime();
  65663. if (minValue !== maxValue && !isEqualDates)
  65664. translatorRange.arg.addRange({
  65665. invert: inverted,
  65666. min: minValue,
  65667. max: maxValue,
  65668. minVisible: minValue,
  65669. maxVisible: maxValue,
  65670. dataType: scaleOptions.valueType
  65671. });
  65672. translatorRange.arg.addRange({
  65673. base: scaleOptions.logarithmBase,
  65674. axisType: scaleOptions.type
  65675. });
  65676. if (!translatorRange.arg.isDefined()) {
  65677. if (isEqualDates)
  65678. scaleOptions.valueType = 'numeric';
  65679. translatorRange.arg.setStubData(scaleOptions.valueType)
  65680. }
  65681. return translatorRange
  65682. };
  65683. var calculateScaleAreaHeight = function(renderer, scaleOptions, visibleMarkers) {
  65684. var textBBox,
  65685. visibleLabels = scaleOptions.label.visible;
  65686. if (scaleOptions.placeholderHeight)
  65687. return scaleOptions.placeholderHeight;
  65688. else {
  65689. textBBox = rangeSelectorUtils.getTextBBox(renderer, '0', scaleOptions.label.font);
  65690. return (visibleLabels ? scaleOptions.label.topIndent + textBBox.height : 0) + (visibleMarkers ? scaleOptions.marker.topIndent + scaleOptions.marker.separatorHeight : 0)
  65691. }
  65692. };
  65693. var getTicksInfo = function(that, scaleOptions, translators, screenDelta) {
  65694. var isEmpty = scaleOptions.isEmpty,
  65695. tickProvider = core.CoreFactory.getTickProvider(),
  65696. minorTicksOptions,
  65697. majorTicksOptions,
  65698. startValue,
  65699. endValue,
  65700. businessRange = translators.x.getBusinessRange();
  65701. minorTicksOptions = {
  65702. tickInterval: isEmpty ? 0 : that.option('scale').minorTickInterval,
  65703. showCustomBoundaryTicks: scaleOptions.showCustomBoundaryTicks,
  65704. minorTickCount: scaleOptions.minorTickCount
  65705. };
  65706. majorTicksOptions = {
  65707. textOptions: {
  65708. align: 'center',
  65709. font: scaleOptions.label.font
  65710. },
  65711. renderer: that.renderer,
  65712. getText: function(value) {
  65713. return rangeSelector.formatValue(value, scaleOptions.label)
  65714. },
  65715. translator: translators.x,
  65716. isStartTickGenerated: !_isDefined(that.option('scale').majorTickInterval),
  65717. tickInterval: scaleOptions.majorTickInterval,
  65718. textSpacing: SCALE_TEXT_SPACING,
  65719. setTicksAtUnitBeginning: scaleOptions.setTicksAtUnitBeginning,
  65720. useTicksAutoArrangement: scaleOptions.useTicksAutoArrangement,
  65721. hideLabels: isEmpty
  65722. };
  65723. startValue = isEmpty ? businessRange.min : scaleOptions.startValue;
  65724. endValue = isEmpty ? businessRange.max : scaleOptions.endValue;
  65725. return tickProvider.getFullTicks(startValue, endValue, screenDelta, majorTicksOptions, minorTicksOptions, {
  65726. axisType: scaleOptions.type,
  65727. dataType: scaleOptions.valueType,
  65728. base: scaleOptions.logarithmBase
  65729. })
  65730. };
  65731. var updateTickIntervals = function(scaleOptions, screenDelta, incidentOccured) {
  65732. var tickProvider = core.CoreFactory.getTickProvider(),
  65733. tickIntervals = tickProvider.getTickIntervals(scaleOptions.startValue, scaleOptions.endValue, screenDelta, {
  65734. tickInterval: scaleOptions.majorTickInterval,
  65735. incidentOccured: incidentOccured
  65736. }, {
  65737. tickInterval: scaleOptions.minorTickInterval,
  65738. incidentOccured: incidentOccured
  65739. }, {
  65740. axisType: scaleOptions.type,
  65741. dataType: scaleOptions.valueType,
  65742. base: scaleOptions.logarithmBase
  65743. });
  65744. scaleOptions.minorTickInterval = tickIntervals.minorTickInterval;
  65745. scaleOptions.majorTickInterval = tickIntervals.majorTickInterval
  65746. };
  65747. var updateScaleOptions = function(that, seriesDataSource, translatorRange, screenDelta, scaleOptions) {
  65748. var minVisibleX = _isDefined(translatorRange.arg.minVisible) ? translatorRange.arg.minVisible : translatorRange.arg.min,
  65749. maxVisibleX = _isDefined(translatorRange.arg.maxVisible) ? translatorRange.arg.maxVisible : translatorRange.arg.max,
  65750. isEmptyInterval;
  65751. if (seriesDataSource && !seriesDataSource.isEmpty()) {
  65752. scaleOptions.startValue = scaleOptions.inverted ? maxVisibleX : minVisibleX;
  65753. scaleOptions.endValue = scaleOptions.inverted ? minVisibleX : maxVisibleX
  65754. }
  65755. isEmptyInterval = utils.isDate(scaleOptions.startValue) && utils.isDate(scaleOptions.endValue) && scaleOptions.startValue.getTime() === scaleOptions.endValue.getTime() || scaleOptions.startValue === scaleOptions.endValue;
  65756. scaleOptions.isEmpty = !_isDefined(scaleOptions.startValue) || !_isDefined(scaleOptions.endValue) || isEmptyInterval || scaleOptions.valueType === 'string';
  65757. if (scaleOptions.isEmpty)
  65758. scaleOptions.startValue = scaleOptions.endValue = undefined;
  65759. else {
  65760. updateTickIntervals(scaleOptions, screenDelta, that._incidentOccured);
  65761. if (scaleOptions.valueType === 'datetime' && !_isDefined(scaleOptions.label.format))
  65762. if (!scaleOptions.marker.visible)
  65763. scaleOptions.label.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.majorTickInterval);
  65764. else
  65765. scaleOptions.label.format = utils.getDateUnitInterval(scaleOptions.majorTickInterval)
  65766. }
  65767. };
  65768. var prepareSliderMarkersOptions = function(that, scaleOptions, screenDelta) {
  65769. var sliderMarkerOptions = $.extend(true, {}, that.option('sliderMarker')),
  65770. businessInterval;
  65771. if (!sliderMarkerOptions.format) {
  65772. if (!that.option('behavior').snapToTicks && utils.isNumber(scaleOptions.startValue)) {
  65773. businessInterval = Math.abs(scaleOptions.endValue - scaleOptions.startValue);
  65774. sliderMarkerOptions.format = 'fixedPoint';
  65775. sliderMarkerOptions.precision = utils.getSignificantDigitPosition(businessInterval / screenDelta)
  65776. }
  65777. if (scaleOptions.valueType === 'datetime')
  65778. if (!scaleOptions.marker.visible) {
  65779. if (_isDefined(scaleOptions.startValue) && _isDefined(scaleOptions.endValue))
  65780. sliderMarkerOptions.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.minorTickInterval !== 0 ? scaleOptions.minorTickInterval : scaleOptions.majorTickInterval)
  65781. }
  65782. else
  65783. sliderMarkerOptions.format = utils.getDateUnitInterval(_isDefined(scaleOptions.minorTickInterval) && scaleOptions.minorTickInterval !== 0 ? scaleOptions.minorTickInterval : scaleOptions.majorTickInterval)
  65784. }
  65785. return sliderMarkerOptions
  65786. };
  65787. var showScaleMarkers = function(scaleOptions) {
  65788. return scaleOptions.valueType == 'datetime' && scaleOptions.marker.visible
  65789. };
  65790. var updateTranslatorRangeInterval = function(translatorRange, scaleOptions) {
  65791. var intervalX = scaleOptions.minorTickInterval || scaleOptions.majorTickInterval;
  65792. translatorRange = translatorRange.arg.addRange({interval: intervalX})
  65793. };
  65794. var checkLogarithmicOptions = function(options, logarithmBase, incidentOccured) {
  65795. if (!options)
  65796. return;
  65797. if (options.type === 'logarithmic' && options.logarithmBase <= 0 || options.logarithmBase && !$.isNumeric(options.logarithmBase)) {
  65798. options.logarithmBase = logarithmBase;
  65799. incidentOccured('E2104')
  65800. }
  65801. else if (options.type !== 'logarithmic')
  65802. options.logarithmBase = undefined
  65803. };
  65804. var prepareScaleOptions = function(that, seriesDataSource) {
  65805. var scaleOptions = $.extend(true, {}, that.option('scale')),
  65806. incidentOccured = that._incidentOccured,
  65807. parsedValue = 0,
  65808. parseUtils = new ParseUtils({incidentOccured: incidentOccured}),
  65809. valueType = parseUtils.correctValueType((scaleOptions.valueType || '').toLowerCase());
  65810. if (seriesDataSource)
  65811. valueType = seriesDataSource.getCalculatedValueType() || valueType;
  65812. if (!valueType)
  65813. valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue) || 'numeric';
  65814. scaleOptions.valueType = valueType;
  65815. if (scaleOptions.valueType === 'string') {
  65816. that._incidentOccured("E2201");
  65817. return scaleOptions
  65818. }
  65819. var parser = parseUtils.getParser(valueType, 'scale');
  65820. if (_isDefined(scaleOptions.startValue)) {
  65821. parsedValue = parser(scaleOptions.startValue);
  65822. if (_isDefined(parsedValue))
  65823. scaleOptions.startValue = parsedValue;
  65824. else {
  65825. scaleOptions.startValue = undefined;
  65826. that._incidentOccured("E2202", ["start"])
  65827. }
  65828. }
  65829. if (_isDefined(scaleOptions.endValue)) {
  65830. parsedValue = parser(scaleOptions.endValue);
  65831. if (_isDefined(parsedValue))
  65832. scaleOptions.endValue = parsedValue;
  65833. else {
  65834. scaleOptions.endValue = undefined;
  65835. that._incidentOccured("E2202", ["end"])
  65836. }
  65837. }
  65838. checkLogarithmicOptions(scaleOptions, defaultRangeSelectorOptions.scale.logarithmBase, that._incidentOccured);
  65839. if (!scaleOptions.type)
  65840. scaleOptions.type = 'continuous';
  65841. scaleOptions.parser = parser;
  65842. return scaleOptions
  65843. };
  65844. var correctSizeOptions = function(that, sizeOptions, scaleOptions) {
  65845. var size = that.option('size') || {};
  65846. if (!sizeOptions.height && size.height !== 0)
  65847. if (scaleOptions.valueType === 'datetime' && scaleOptions.marker.visible !== false)
  65848. sizeOptions.height = 160;
  65849. else
  65850. sizeOptions.height = 120;
  65851. if (!sizeOptions.width && size.width !== 0)
  65852. sizeOptions.width = 400
  65853. };
  65854. var applyOptions = function(that) {
  65855. var rangeContainerCanvas,
  65856. seriesDataSource,
  65857. translatorRange,
  65858. scaleLabelsAreaHeight,
  65859. sizeOptions,
  65860. sliderMarkerSpacing,
  65861. sliderMarkerOptions,
  65862. selectedRange,
  65863. $container = that.container;
  65864. that._isUpdating = true;
  65865. sizeOptions = calculateSize(that);
  65866. that._actualSize = sizeOptions;
  65867. seriesDataSource = createSeriesDataSource(that);
  65868. that._scaleOptions = prepareScaleOptions(that, seriesDataSource);
  65869. correctSizeOptions(that, sizeOptions, that._scaleOptions);
  65870. if (!sizeOptions.width || !sizeOptions.height || !$container.is(':visible')) {
  65871. that.stopRedraw = true;
  65872. that._incidentOccured("W2001", [that.NAME]);
  65873. return
  65874. }
  65875. else
  65876. that.stopRedraw = false;
  65877. updateRendererSize(that, sizeOptions);
  65878. that._updateLoadIndicator(undefined, that.canvas.width, that.canvas.height);
  65879. translatorRange = calculateTranslatorRange(that, seriesDataSource, that._scaleOptions);
  65880. updateScaleOptions(that, seriesDataSource, translatorRange, sizeOptions.width, that._scaleOptions);
  65881. updateTranslatorRangeInterval(translatorRange, that._scaleOptions);
  65882. sliderMarkerOptions = prepareSliderMarkersOptions(that, that._scaleOptions, sizeOptions.width);
  65883. selectedRange = initSelection(that, that._scaleOptions);
  65884. sliderMarkerSpacing = calculateSliderMarkersSpacing(that.renderer, sizeOptions, that._scaleOptions, sliderMarkerOptions);
  65885. rangeContainerCanvas = calculateRangeContainerCanvas(sizeOptions, that.option('margin'), sliderMarkerSpacing);
  65886. scaleLabelsAreaHeight = calculateScaleAreaHeight(that.renderer, that._scaleOptions, showScaleMarkers(that._scaleOptions));
  65887. that.translators = createTranslator(translatorRange, createTranslatorCanvas(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight));
  65888. that._scaleOptions.ticksInfo = getTicksInfo(that, that._scaleOptions, that.translators, rangeContainerCanvas.width);
  65889. that._testTicksInfo = that._scaleOptions.ticksInfo;
  65890. that._selectedRange = selectedRange;
  65891. if (seriesDataSource)
  65892. seriesDataSource.adjustSeriesDimensions(that.translators);
  65893. that.rangeContainer.applyOptions({
  65894. canvas: rangeContainerCanvas,
  65895. scaleLabelsAreaHeight: scaleLabelsAreaHeight,
  65896. sliderMarkerSpacing: sliderMarkerSpacing,
  65897. translators: that.translators,
  65898. selectedRange: selectedRange,
  65899. scale: that._scaleOptions,
  65900. behavior: that.option('behavior'),
  65901. background: that.option('background'),
  65902. chart: that.option('chart'),
  65903. seriesDataSource: seriesDataSource,
  65904. sliderMarker: sliderMarkerOptions,
  65905. sliderHandle: that.option('sliderHandle'),
  65906. shutter: that.option('shutter'),
  65907. selectedRangeChanged: createSelectedRangeChangedFunction(that),
  65908. setSelectedRange: function(selectedRange) {
  65909. that.setSelectedRange(selectedRange)
  65910. }
  65911. });
  65912. that._isUpdating = false
  65913. };
  65914. var createSelectedRangeChangedFunction = function(that) {
  65915. return function(selectedRange, blockSelectedRangeChanged) {
  65916. var selectedRangeChanged = that.option('selectedRangeChanged');
  65917. that.option('selectedRange', selectedRange);
  65918. if (selectedRangeChanged && !blockSelectedRangeChanged)
  65919. setTimeout(function() {
  65920. selectedRangeChanged.call(null, selectedRange)
  65921. })
  65922. }
  65923. };
  65924. var calculateSize = function(that) {
  65925. var $container = that.container,
  65926. size = that.option('size') || {},
  65927. result = {
  65928. width: size.width,
  65929. height: size.height
  65930. };
  65931. if ($container) {
  65932. if (!result.width)
  65933. result.width = $container.width();
  65934. if (!result.height)
  65935. result.height = $container.height()
  65936. }
  65937. that.canvas = result;
  65938. return result
  65939. };
  65940. var updateRendererSize = function(that, size) {
  65941. var renderer = that.renderer;
  65942. if (renderer.isInitialized())
  65943. renderer.getRoot().applySettings({
  65944. width: size.width,
  65945. height: size.height
  65946. });
  65947. else {
  65948. renderer.recreateCanvas(size.width, size.height);
  65949. renderer.draw(that.container[0])
  65950. }
  65951. };
  65952. var prepareChartThemeOptions = function(that, options) {
  65953. var chartTheme,
  65954. chartOption = that.option('chart') || {};
  65955. if (!chartOption.theme && options && options.theme) {
  65956. chartTheme = options.theme;
  65957. if (chartTheme) {
  65958. if (typeof chartTheme === 'object') {
  65959. chartTheme = chartTheme.chart || {};
  65960. chartTheme.name = options.theme.name
  65961. }
  65962. chartOption.theme = chartTheme
  65963. }
  65964. }
  65965. };
  65966. var initSelection = function(that, scaleOptions) {
  65967. var selectedRangeOptions = that.option('selectedRange'),
  65968. startValue,
  65969. endValue,
  65970. parser = scaleOptions.parser || function() {
  65971. return null
  65972. },
  65973. parseValue = function(value, entity) {
  65974. var parsedValue,
  65975. result = scaleOptions[entity];
  65976. if (_isDefined(value))
  65977. parsedValue = parser(value);
  65978. if (!_isDefined(parsedValue))
  65979. that._incidentOccured("E2203", [entity]);
  65980. else
  65981. result = parsedValue;
  65982. return result
  65983. };
  65984. if (!selectedRangeOptions)
  65985. return {
  65986. startValue: scaleOptions.startValue,
  65987. endValue: scaleOptions.endValue
  65988. };
  65989. else {
  65990. startValue = parseValue(selectedRangeOptions.startValue, 'startValue');
  65991. startValue = that.rangeContainer.slidersContainer.truncateSelectedRange(startValue, scaleOptions);
  65992. endValue = parseValue(selectedRangeOptions.endValue, 'endValue');
  65993. endValue = that.rangeContainer.slidersContainer.truncateSelectedRange(endValue, scaleOptions);
  65994. return {
  65995. startValue: startValue,
  65996. endValue: endValue
  65997. }
  65998. }
  65999. };
  66000. var _isSizeChanged = function(that) {
  66001. var actualSize = that._actualSize,
  66002. newSize = calculateSize(that);
  66003. return actualSize && (actualSize.width !== newSize.width || actualSize.height !== newSize.height)
  66004. };
  66005. return {
  66006. isSizeChanged: function() {
  66007. return _isSizeChanged(this)
  66008. },
  66009. _setDefaultOptions: function() {
  66010. this.callBase();
  66011. this.option(defaultRangeSelectorOptions)
  66012. },
  66013. _dataSourceOptions: function() {
  66014. return {
  66015. paginate: false,
  66016. _preferSync: true
  66017. }
  66018. },
  66019. _init: function() {
  66020. var that = this;
  66021. that.container = getContainer(that);
  66022. clearContainer(that.container);
  66023. that.renderer = createRenderer(that);
  66024. that.rangeContainer = createRangeContainer(that.renderer);
  66025. that.callBase();
  66026. that._reinitDataSource()
  66027. },
  66028. _reinitDataSource: function() {
  66029. this._refreshDataSource()
  66030. },
  66031. _dispose: function() {
  66032. var that = this,
  66033. disposeObject = function(propName) {
  66034. that[propName] && that[propName].dispose(),
  66035. that[propName] = null
  66036. };
  66037. that.callBase();
  66038. disposeObject("renderer");
  66039. that.translators = null;
  66040. disposeObject("rangeContainer")
  66041. },
  66042. _initOptions: function(options) {
  66043. var that = this,
  66044. themeManager;
  66045. that._optionsInitializing = true;
  66046. options = options || {};
  66047. that._userOptions = $.extend(true, {}, options);
  66048. themeManager = createThemeManager(options.theme);
  66049. themeManager.setBackgroundColor(options.containerBackgroundColor);
  66050. that.option(themeManager.applyRangeSelectorTheme(options));
  66051. prepareChartThemeOptions(that, options);
  66052. if (options.background)
  66053. that._userBackgroundColor = options.background.color
  66054. },
  66055. _refresh: function() {
  66056. var that = this,
  66057. callBase = that.callBase;
  66058. that._endLoading(function() {
  66059. callBase.call(that)
  66060. })
  66061. },
  66062. _render: function(isResizing) {
  66063. var that = this,
  66064. currentAnimationEnabled,
  66065. behaviorOptions;
  66066. that._optionsInitializing = false;
  66067. applyOptions(that);
  66068. if (!that.stopRedraw) {
  66069. if (isResizing) {
  66070. behaviorOptions = that.option('behavior');
  66071. currentAnimationEnabled = behaviorOptions.animationEnabled;
  66072. behaviorOptions.animationEnabled = false;
  66073. that.rangeContainer.redraw();
  66074. behaviorOptions.animationEnabled = currentAnimationEnabled
  66075. }
  66076. else
  66077. that.rangeContainer.redraw();
  66078. !isResizing && (!that._dataSource || that._dataSource && that._dataSource.isLoaded()) && that.hideLoadingIndicator()
  66079. }
  66080. that._drawn();
  66081. that.__rendered && that.__rendered()
  66082. },
  66083. _optionChanged: function(name, value, prevValue) {
  66084. var that = this;
  66085. if (!that._optionsInitializing)
  66086. dataUtils.compileSetter(name)(that._userOptions, value, {
  66087. functionsAsIs: true,
  66088. merge: true
  66089. });
  66090. if (name === "dataSource") {
  66091. that._reinitDataSource();
  66092. that._invalidate()
  66093. }
  66094. else if (name === "selectedRange")
  66095. that.setSelectedRange(that.option('selectedRange'));
  66096. else if (name === "selectedRangeChanged")
  66097. that.rangeContainer.slidersContainer.selectedRangeChanged = createSelectedRangeChangedFunction(that);
  66098. else if (name === 'containerBackgroundColor' || name === 'theme') {
  66099. that._initOptions(that._userOptions);
  66100. that._invalidate()
  66101. }
  66102. else
  66103. that.callBase(name, value, prevValue)
  66104. },
  66105. _resize: function() {
  66106. if (_isSizeChanged(this))
  66107. this._render(true)
  66108. },
  66109. _handleDataSourceChanged: function() {
  66110. var that = this;
  66111. that._endLoading(function() {
  66112. if (that.renderer.isInitialized())
  66113. that._render()
  66114. })
  66115. },
  66116. getSelectedRange: function() {
  66117. var that = this;
  66118. var selectedRange = that.rangeContainer.slidersContainer.getSelectedRange();
  66119. return {
  66120. startValue: selectedRange.startValue,
  66121. endValue: selectedRange.endValue
  66122. }
  66123. },
  66124. setSelectedRange: function(selectedRange) {
  66125. var that = this;
  66126. if (that._isUpdating || !selectedRange)
  66127. return;
  66128. var oldSelectedRange = that.rangeContainer.slidersContainer.getSelectedRange();
  66129. if (oldSelectedRange && oldSelectedRange.startValue === selectedRange.startValue && oldSelectedRange.endValue === selectedRange.endValue)
  66130. return;
  66131. that.rangeContainer.slidersContainer.setSelectedRange(selectedRange)
  66132. },
  66133. resetSelectedRange: function(blockSelectedRangeChanged) {
  66134. var that = this;
  66135. that.setSelectedRange({
  66136. startValue: that._scaleOptions.startValue,
  66137. endValue: that._scaleOptions.endValue,
  66138. blockSelectedRangeChanged: blockSelectedRangeChanged
  66139. })
  66140. },
  66141. render: function(isResizing) {
  66142. this._render(isResizing);
  66143. return this
  66144. }
  66145. }
  66146. }()).include(DX.ui.DataHelperMixin)
  66147. })(jQuery, DevExpress);
  66148. /*! Module viz-rangeselector, file rangeContainer.js */
  66149. (function($, DX, undefined) {
  66150. var rangeSelector = DX.viz.rangeSelector;
  66151. rangeSelector.RangeContainer = rangeSelector.BaseVisualElement.inherit(function() {
  66152. var ctor = function(renderer) {
  66153. this.callBase(renderer);
  66154. this.slidersContainer = createSlidersContainer(renderer);
  66155. this.rangeView = createRangeView(renderer);
  66156. this.scale = createScale(renderer)
  66157. };
  66158. var _applyOptions = function(options) {
  66159. var that = this,
  66160. isEmpty = options.scale.isEmpty,
  66161. viewCanvas = {
  66162. left: options.canvas.left,
  66163. top: options.canvas.top,
  66164. width: options.canvas.width,
  66165. height: options.canvas.height >= options.scaleLabelsAreaHeight ? options.canvas.height - options.scaleLabelsAreaHeight : 0
  66166. };
  66167. that._viewCanvas = viewCanvas;
  66168. that.slidersContainer.applyOptions({
  66169. canvas: viewCanvas,
  66170. translator: options.translators.x,
  66171. scale: options.scale,
  66172. selectedRange: options.selectedRange,
  66173. sliderMarker: options.sliderMarker,
  66174. sliderHandle: options.sliderHandle,
  66175. shutter: options.shutter,
  66176. behavior: options.behavior,
  66177. selectedRangeChanged: options.selectedRangeChanged,
  66178. isEmpty: isEmpty
  66179. });
  66180. that.rangeView.applyOptions({
  66181. canvas: viewCanvas,
  66182. translators: options.translators,
  66183. background: options.background,
  66184. chart: options.chart,
  66185. seriesDataSource: options.seriesDataSource,
  66186. behavior: options.behavior,
  66187. isEmpty: isEmpty
  66188. });
  66189. that.scale.applyOptions({
  66190. canvas: options.canvas,
  66191. translator: options.translators.x,
  66192. scale: options.scale,
  66193. hideLabels: isEmpty,
  66194. scaleLabelsAreaHeight: options.scaleLabelsAreaHeight,
  66195. setSelectedRange: options.setSelectedRange
  66196. })
  66197. };
  66198. var createSlidersContainer = function(options) {
  66199. return rangeSelector.rangeSelectorFactory.createSlidersContainer(options)
  66200. };
  66201. var createScale = function(options) {
  66202. return rangeSelector.rangeSelectorFactory.createScale(options)
  66203. };
  66204. var createRangeView = function(options) {
  66205. return rangeSelector.rangeSelectorFactory.createRangeView(options)
  66206. };
  66207. var _createClipRectCanvas = function(canvas, sliderMarkerSpacing) {
  66208. return {
  66209. left: canvas.left - sliderMarkerSpacing.left,
  66210. top: canvas.top - sliderMarkerSpacing.top,
  66211. width: canvas.width + sliderMarkerSpacing.right + sliderMarkerSpacing.left,
  66212. height: canvas.height + sliderMarkerSpacing.bottom + sliderMarkerSpacing.top
  66213. }
  66214. };
  66215. var _draw = function() {
  66216. var that = this,
  66217. containerGroup,
  66218. rangeViewGroup,
  66219. slidersContainerGroup,
  66220. scaleGroup,
  66221. trackersGroup,
  66222. clipRectCanvas = _createClipRectCanvas(that._options.canvas, that._options.sliderMarkerSpacing),
  66223. viewCanvas = that._viewCanvas;
  66224. that._clipRect = that._renderer.createClipRect(clipRectCanvas.left, clipRectCanvas.top, clipRectCanvas.width, clipRectCanvas.height).append();
  66225. containerGroup = that._renderer.createGroup({
  66226. 'class': 'rangeContainer',
  66227. clipId: that._clipRect.id
  66228. }).append();
  66229. that._viewClipRect = that._renderer.createClipRect(viewCanvas.left, viewCanvas.top, viewCanvas.width, viewCanvas.height).append();
  66230. rangeViewGroup = that._renderer.createGroup({
  66231. 'class': 'view',
  66232. clipId: that._viewClipRect.id
  66233. });
  66234. rangeViewGroup.append(containerGroup);
  66235. that.rangeView.redraw(rangeViewGroup);
  66236. slidersContainerGroup = that._renderer.createGroup({'class': 'slidersContainer'});
  66237. slidersContainerGroup.append(containerGroup);
  66238. that.slidersContainer.redraw(slidersContainerGroup);
  66239. scaleGroup = that._renderer.createGroup({'class': 'scale'});
  66240. scaleGroup.append(containerGroup);
  66241. that.scale.redraw(scaleGroup);
  66242. trackersGroup = that._renderer.createGroup({'class': 'trackers'});
  66243. trackersGroup.append(containerGroup);
  66244. that._trackersGroup = trackersGroup;
  66245. that.slidersContainer.appendTrackers(trackersGroup)
  66246. };
  66247. var _update = function() {
  66248. var that = this,
  66249. clipRectCanvas = _createClipRectCanvas(that._options.canvas, that._options.sliderMarkerSpacing),
  66250. viewCanvas = that._viewCanvas;
  66251. that._clipRect.updateRectangle({
  66252. x: clipRectCanvas.left,
  66253. y: clipRectCanvas.top,
  66254. width: clipRectCanvas.width,
  66255. height: clipRectCanvas.height
  66256. });
  66257. that._viewClipRect.updateRectangle({
  66258. x: viewCanvas.left,
  66259. y: viewCanvas.top,
  66260. width: viewCanvas.width,
  66261. height: viewCanvas.height
  66262. });
  66263. that.rangeView.redraw();
  66264. that.slidersContainer.redraw();
  66265. that.slidersContainer.appendTrackers(that._trackersGroup);
  66266. that.scale.redraw()
  66267. };
  66268. var dispose = function() {
  66269. this.slidersContainer.dispose();
  66270. this.slidersContainer = null
  66271. };
  66272. var prototypeObject = {
  66273. createSlidersContainer: createSlidersContainer,
  66274. createScale: createScale,
  66275. ctor: ctor,
  66276. dispose: dispose,
  66277. _applyOptions: _applyOptions,
  66278. _draw: _draw,
  66279. _update: _update
  66280. };
  66281. return prototypeObject
  66282. }())
  66283. })(jQuery, DevExpress);
  66284. /*! Module viz-rangeselector, file scale.js */
  66285. (function($, DX, undefined) {
  66286. var rangeSelector = DX.viz.rangeSelector,
  66287. formatHelper = DX.formatHelper,
  66288. utils = DX.utils;
  66289. var SCALE_TEXT_SPACING = 5;
  66290. rangeSelector.Scale = rangeSelector.BaseVisualElement.inherit({
  66291. _setupDateUnitInterval: function(scaleOptions) {
  66292. var key,
  66293. hasObjectSingleField = function(object) {
  66294. var fieldsCounter = 0;
  66295. $.each(object, function() {
  66296. return ++fieldsCounter < 2
  66297. });
  66298. return fieldsCounter === 1
  66299. },
  66300. millisecTickInterval,
  66301. majorTickInterval = scaleOptions.ticksInfo.majorTickInterval,
  66302. majorTicks = scaleOptions.ticksInfo.majorTicks;
  66303. if (scaleOptions.valueType === 'datetime') {
  66304. if (utils.isObject(majorTickInterval) && !hasObjectSingleField(majorTickInterval))
  66305. utils.logger.warn('More than one field is specified within the object assigned to the "tickInterval" option. Assign an object with a single field specified (days, hours or a similar one).');
  66306. if (majorTicks && majorTicks.autoArrangementStep > 1) {
  66307. if (utils.isString(majorTickInterval))
  66308. majorTickInterval = utils.getDateIntervalByString(majorTickInterval);
  66309. for (key in majorTickInterval)
  66310. if (majorTickInterval.hasOwnProperty(key)) {
  66311. majorTickInterval[key] *= majorTicks.autoArrangementStep;
  66312. millisecTickInterval = utils.convertDateTickIntervalToMilliseconds(majorTickInterval)
  66313. }
  66314. majorTickInterval = utils.convertMillisecondsToDateUnits(millisecTickInterval)
  66315. }
  66316. this.dateUnitInterval = utils.getDateUnitInterval(majorTickInterval)
  66317. }
  66318. },
  66319. _prepareDatesDifferences: function(datesDifferences, tickInterval) {
  66320. var deleteDifferent = tickInterval,
  66321. dateUnitInterval,
  66322. i;
  66323. if (deleteDifferent === 'week')
  66324. deleteDifferent = 'day';
  66325. if (deleteDifferent === 'quarter')
  66326. deleteDifferent = 'month';
  66327. if (datesDifferences[deleteDifferent])
  66328. for (i = 0; i < utils.dateUnitIntervals.length; i++) {
  66329. dateUnitInterval = utils.dateUnitIntervals[i];
  66330. if (datesDifferences[dateUnitInterval]) {
  66331. datesDifferences[dateUnitInterval] = false;
  66332. datesDifferences.count--
  66333. }
  66334. if (dateUnitInterval === deleteDifferent)
  66335. break
  66336. }
  66337. },
  66338. _getMarkerDate: function(date, tickInterval) {
  66339. var markerDate = new Date(date.getTime()),
  66340. month = 0;
  66341. switch (tickInterval) {
  66342. case'quarter':
  66343. month = formatHelper.getFirstQuarterMonth(date.getMonth());
  66344. case'month':
  66345. markerDate.setMonth(month);
  66346. case'week':
  66347. case'day':
  66348. markerDate.setDate(1);
  66349. case'hour':
  66350. markerDate.setHours(0, 0, 0, 0);
  66351. break;
  66352. case'millisecond':
  66353. markerDate.setMilliseconds(0);
  66354. break;
  66355. case'second':
  66356. markerDate.setSeconds(0, 0);
  66357. break;
  66358. case'minute':
  66359. markerDate.setMinutes(0, 0, 0);
  66360. break
  66361. }
  66362. return markerDate
  66363. },
  66364. _drawDateMarker: function(date, options) {
  66365. var labelPosX,
  66366. labelPosY,
  66367. dateFormated,
  66368. scaleOptions,
  66369. textElement;
  66370. if (options.x === null)
  66371. return;
  66372. scaleOptions = this._options.scale;
  66373. this.lineOptions['class'] = 'dx-range-selector-date-marker';
  66374. this._renderer.createLine(options.x, options.y, options.x, options.y + scaleOptions.marker.separatorHeight, this.lineOptions).append(options.group);
  66375. dateFormated = this._getLabel(date, options.label);
  66376. labelPosX = options.x + scaleOptions.tick.width + scaleOptions.marker.textLeftIndent;
  66377. labelPosY = options.y + scaleOptions.marker.textTopIndent + scaleOptions.label.font.size;
  66378. this.textOptions.align = 'left';
  66379. textElement = this._renderer.createText(dateFormated, labelPosX, labelPosY, this.textOptions).append(options.group);
  66380. return labelPosX + textElement.getBBox().width
  66381. },
  66382. _drawDateMarkers: function(dates, group) {
  66383. var dateMarker,
  66384. i,
  66385. datesDifferences,
  66386. markerDate,
  66387. posX,
  66388. prevMarkerRightX = -1;
  66389. if (this._options.scale.valueType !== 'datetime' || !this.visibleMarkers)
  66390. return;
  66391. var markerDatePositions = [];
  66392. if (dates.length > 1) {
  66393. for (i = 1; i < dates.length; i++) {
  66394. datesDifferences = utils.getDatesDifferences(dates[i - 1], dates[i]);
  66395. this._prepareDatesDifferences(datesDifferences, this.dateUnitInterval);
  66396. if (datesDifferences.count > 0) {
  66397. markerDate = this._getMarkerDate(dates[i], this.dateUnitInterval);
  66398. this.markerDates = this.markerDates || [];
  66399. this.markerDates.push(markerDate);
  66400. posX = this.translator.translate(markerDate);
  66401. if (posX > prevMarkerRightX) {
  66402. posX !== null && markerDatePositions.push({
  66403. date: markerDate,
  66404. posX: posX
  66405. });
  66406. prevMarkerRightX = this._drawDateMarker(markerDate, {
  66407. group: group,
  66408. y: this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight + this._options.scale.marker.topIndent,
  66409. x: posX,
  66410. label: this._getLabelFormatOptions(formatHelper.getDateFormatByDifferences(datesDifferences))
  66411. })
  66412. }
  66413. }
  66414. }
  66415. this._initializeMarkersEvents(markerDatePositions, group)
  66416. }
  66417. },
  66418. _getLabelFormatOptions: function(formatString) {
  66419. if (!utils.isDefined(this._options.scale.marker.label.format))
  66420. return $.extend({}, this._options.scale.marker.label, {format: formatString});
  66421. return this._options.scale.marker.label
  66422. },
  66423. _calculateRangeByMarkerPosition: function(posX, markerDatePositions, scaleOptions) {
  66424. var selectedRange = {},
  66425. i,
  66426. position;
  66427. for (i = 0; i < markerDatePositions.length; i++) {
  66428. position = markerDatePositions[i];
  66429. if (!scaleOptions.inverted) {
  66430. if (posX >= position.posX)
  66431. selectedRange.startValue = position.date;
  66432. else if (!selectedRange.endValue)
  66433. selectedRange.endValue = position.date
  66434. }
  66435. else if (posX < position.posX)
  66436. selectedRange.endValue = position.date;
  66437. else if (!selectedRange.startValue)
  66438. selectedRange.startValue = position.date
  66439. }
  66440. selectedRange.startValue = selectedRange.startValue || scaleOptions.startValue;
  66441. selectedRange.endValue = selectedRange.endValue || scaleOptions.endValue;
  66442. return selectedRange
  66443. },
  66444. _initializeMarkersEvents: function(markerDatePositions, group) {
  66445. var that = this,
  66446. markersAreaTop = this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight + this._options.scale.marker.topIndent,
  66447. markersTracker,
  66448. svgOffsetLeft,
  66449. index,
  66450. posX,
  66451. selectedRange;
  66452. if (markerDatePositions.length > 0) {
  66453. markersTracker = that._renderer.createRect(that._options.canvas.left, markersAreaTop, that._options.canvas.width, that._options.scale.marker.separatorHeight, 0, {
  66454. fill: 'grey',
  66455. stroke: 'grey',
  66456. opacity: 0.0001
  66457. });
  66458. markersTracker.append(group);
  66459. markersTracker.on(rangeSelector.events.start, function(e) {
  66460. svgOffsetLeft = rangeSelector.utils.getRootOffsetLeft(that._renderer);
  66461. posX = rangeSelector.utils.getEventPageX(e) - svgOffsetLeft;
  66462. selectedRange = that._calculateRangeByMarkerPosition(posX, markerDatePositions, that._options.scale);
  66463. that._options.setSelectedRange(selectedRange)
  66464. });
  66465. that._markersTracker = markersTracker
  66466. }
  66467. },
  66468. _getLabel: function(value, options) {
  66469. var formatObject = {
  66470. value: value,
  66471. valueText: formatHelper.format(value, options.format, options.precision)
  66472. };
  66473. return String(utils.isFunction(options.customizeText) ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText)
  66474. },
  66475. _drawLabel: function(value, group) {
  66476. var textY = this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight,
  66477. textElement = this._renderer.createText(this._getLabel(value, this._options.scale.label), this.translator.translate(value), textY, this.textOptions);
  66478. textElement.append(group);
  66479. this.textElements = this.textElements || [];
  66480. this.textElements.push(textElement)
  66481. },
  66482. _drawTick: function(value, group) {
  66483. this.lineOptions['class'] = 'dx-range-selector-tick';
  66484. var secondY = this._options.canvas.top + this._options.canvas.height - this.scaleLabelsAreaHeight,
  66485. posX = this.translator.translate(value),
  66486. tickElement = this._renderer.createLine(posX, this._options.canvas.top, posX, secondY, this.lineOptions).append(group);
  66487. this.tickElements = this.tickElements || [];
  66488. this.tickElements.push(tickElement)
  66489. },
  66490. _redraw: function(group, isOptimize) {
  66491. var that = this,
  66492. scaleOptions = that._options.scale,
  66493. ticksGroup = that._renderer.createGroup(),
  66494. labelsGroup = that._renderer.createGroup().append(group),
  66495. majorTicks = scaleOptions.ticksInfo.majorTicks,
  66496. minorTicks = scaleOptions.ticksInfo.minorTicks,
  66497. customBoundaryTicks = scaleOptions.ticksInfo.customBoundaryTicks,
  66498. hideLabels = that._options.hideLabels || majorTicks.hideLabels || !scaleOptions.label.visible,
  66499. i;
  66500. for (i = 0; i < majorTicks.length; i++) {
  66501. if (!hideLabels)
  66502. that._drawLabel(majorTicks[i], labelsGroup);
  66503. that._drawTick(majorTicks[i], ticksGroup)
  66504. }
  66505. if (scaleOptions.showMinorTicks)
  66506. for (i = 0; i < minorTicks.length; i++)
  66507. that._drawTick(minorTicks[i], ticksGroup);
  66508. for (i = 0; i < customBoundaryTicks.length; i++)
  66509. that._drawTick(customBoundaryTicks[i], ticksGroup);
  66510. ticksGroup.append(group);
  66511. that._drawDateMarkers(majorTicks, labelsGroup)
  66512. },
  66513. _applyOptions: function(options) {
  66514. var scaleOptions = options.scale,
  66515. labelsAreaHeight;
  66516. this.textOptions = {
  66517. align: 'center',
  66518. 'class': 'dx-range-selector-scale',
  66519. font: scaleOptions.label.font,
  66520. style: {'-webkit-user-select': 'none'}
  66521. };
  66522. this.lineOptions = {
  66523. strokeWidth: scaleOptions.tick.width,
  66524. stroke: scaleOptions.tick.color,
  66525. strokeOpacity: scaleOptions.tick.opacity
  66526. };
  66527. this._setupDateUnitInterval(scaleOptions);
  66528. this.visibleMarkers = scaleOptions.marker.visible === undefined ? true : scaleOptions.marker.visible;
  66529. labelsAreaHeight = scaleOptions.label.visible ? scaleOptions.label.topIndent + scaleOptions.label.font.size : 0;
  66530. this.scaleLabelsAreaHeight = options.scaleLabelsAreaHeight;
  66531. this.markersAreaHeight = this.scaleLabelsAreaHeight - labelsAreaHeight;
  66532. this.translator = options.translator
  66533. },
  66534. _draw: function(group) {
  66535. this._redraw(group, false)
  66536. },
  66537. _update: function(group) {
  66538. var callBase = this.callBase;
  66539. if (this._markersTracker)
  66540. this._markersTracker.off(rangeSelector.events.start, '**');
  66541. this.callBase = callBase;
  66542. this.callBase(group)
  66543. }
  66544. })
  66545. })(jQuery, DevExpress);
  66546. /*! Module viz-rangeselector, file rangeFactory.js */
  66547. (function($, DX, undefined) {
  66548. var rangeSelector = DX.viz.rangeSelector,
  66549. renderers = DX.viz.renderers;
  66550. rangeSelector.rangeSelectorFactory = function() {
  66551. return {
  66552. createRangeContainer: function(rangeContainerOptions) {
  66553. return new rangeSelector.RangeContainer(rangeContainerOptions)
  66554. },
  66555. createSlidersContainer: function(options) {
  66556. return new rangeSelector.SlidersContainer(options)
  66557. },
  66558. createScale: function(options) {
  66559. return new rangeSelector.Scale(options)
  66560. },
  66561. createSliderMarker: function(options) {
  66562. return new rangeSelector.SliderMarker(options)
  66563. },
  66564. createRangeView: function(options) {
  66565. return new rangeSelector.RangeView(options)
  66566. },
  66567. createThemeManager: function(options) {
  66568. return new rangeSelector.ThemeManager(options)
  66569. },
  66570. createSlider: function(renderer, sliderIndex) {
  66571. return new rangeSelector.Slider(renderer, sliderIndex)
  66572. },
  66573. createSlidersEventsManager: function(renderer, slidersController, processSelectionChanged) {
  66574. return new rangeSelector.SlidersEventsManager(renderer, slidersController, processSelectionChanged)
  66575. },
  66576. createSlidersController: function(sliders) {
  66577. return new rangeSelector.SlidersController(sliders)
  66578. }
  66579. }
  66580. }()
  66581. })(jQuery, DevExpress);
  66582. /*! Module viz-rangeselector, file slidersContainer.js */
  66583. (function($, DX, undefined) {
  66584. var rangeSelector = DX.viz.rangeSelector,
  66585. utils = DX.utils;
  66586. var msPointerEnabled = window.navigator.msPointerEnabled || window.navigator.pointerEnabled;
  66587. var isNumber = DX.utils.isNumber;
  66588. var isDate = DX.utils.isDate;
  66589. var START_VALUE_INDEX = 0,
  66590. END_VALUE_INDEX = 1;
  66591. rangeSelector.SlidersContainer = rangeSelector.BaseVisualElement.inherit(function() {
  66592. var prototypeObject = {
  66593. getController: function() {
  66594. return this._controller
  66595. },
  66596. _drawAreaTracker: function(group) {
  66597. var that = this,
  66598. areaTracker,
  66599. selectedAreaTracker;
  66600. areaTracker = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0, {
  66601. fill: 'grey',
  66602. stroke: 'grey',
  66603. opacity: 0.0001
  66604. });
  66605. areaTracker.append(group);
  66606. selectedAreaTracker = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0, {
  66607. fill: 'grey',
  66608. stroke: 'grey',
  66609. opacity: 0.0001,
  66610. style: {cursor: 'pointer'}
  66611. });
  66612. selectedAreaTracker.append(group);
  66613. that._controller.setAreaTrackers(areaTracker, selectedAreaTracker)
  66614. },
  66615. dispose: function() {
  66616. this._eventsManager.dispose();
  66617. this._eventManager = null
  66618. },
  66619. _processSelectionChanged: function(moving, blockSelectedRangeChanged) {
  66620. var that = this,
  66621. equalLastSelectedRange = function(selectedRange) {
  66622. return selectedRange && that._lastSelectedRange.startValue === selectedRange.startValue && that._lastSelectedRange.endValue === selectedRange.endValue
  66623. },
  66624. selectedRange = that.getSelectedRange();
  66625. if ((!moving || (that._options.behavior.callSelectedRangeChanged || '').toLowerCase() === "onmoving") && that._options.selectedRangeChanged && !equalLastSelectedRange(selectedRange)) {
  66626. that._updateLastSelectedRange(selectedRange);
  66627. if (typeof that._options.selectedRangeChanged === 'function')
  66628. that._options.selectedRangeChanged.call(null, selectedRange, blockSelectedRangeChanged);
  66629. if (!moving && !equalLastSelectedRange(selectedRange))
  66630. that.setSelectedRange(selectedRange)
  66631. }
  66632. },
  66633. _updateLastSelectedRange: function(selectedRange) {
  66634. selectedRange = selectedRange || this._options.selectedRange;
  66635. this._lastSelectedRange = {
  66636. startValue: selectedRange.startValue,
  66637. endValue: selectedRange.endValue
  66638. }
  66639. },
  66640. _createSlider: function(sliderIndex) {
  66641. return rangeSelector.rangeSelectorFactory.createSlider(this._renderer, sliderIndex)
  66642. },
  66643. _createSlidersController: function(sliders) {
  66644. return rangeSelector.rangeSelectorFactory.createSlidersController(sliders)
  66645. },
  66646. _createSlidersEventsManager: function(controller) {
  66647. var that = this;
  66648. return rangeSelector.rangeSelectorFactory.createSlidersEventsManager(that._renderer, controller, function(moving) {
  66649. that._processSelectionChanged(moving)
  66650. })
  66651. },
  66652. ctor: function(renderer) {
  66653. var that = this,
  66654. sliders;
  66655. that.callBase(renderer);
  66656. sliders = [that._createSlider(START_VALUE_INDEX), that._createSlider(END_VALUE_INDEX)];
  66657. that._controller = that._createSlidersController(sliders);
  66658. that._eventsManager = that._createSlidersEventsManager(that._controller);
  66659. that._lastSelectedRange = {}
  66660. },
  66661. getSelectedRange: function() {
  66662. return this._controller.getSelectedRange()
  66663. },
  66664. truncateSelectedRange: function(value, scaleOptions) {
  66665. var min = scaleOptions.startValue > scaleOptions.endValue ? scaleOptions.endValue : scaleOptions.startValue,
  66666. max = scaleOptions.startValue > scaleOptions.endValue ? scaleOptions.startValue : scaleOptions.endValue;
  66667. if (value < min)
  66668. value = min;
  66669. if (value > max)
  66670. value = max;
  66671. return value
  66672. },
  66673. setSelectedRange: function(selectedRange) {
  66674. var that = this,
  66675. scale = that._options.scale,
  66676. startValue,
  66677. endValue,
  66678. currentSelectedRange = that._options.selectedRange;
  66679. if (selectedRange) {
  66680. startValue = selectedRange.startValue;
  66681. endValue = selectedRange.endValue
  66682. }
  66683. if (isNumber(scale.startValue) && isNumber(startValue) || isDate(scale.startValue) && isDate(startValue))
  66684. currentSelectedRange.startValue = startValue;
  66685. if (isNumber(scale.endValue) && isNumber(endValue) || isDate(scale.endValue) && isDate(endValue))
  66686. currentSelectedRange.endValue = endValue;
  66687. currentSelectedRange.startValue = that.truncateSelectedRange(currentSelectedRange.startValue, scale);
  66688. currentSelectedRange.endValue = that.truncateSelectedRange(currentSelectedRange.endValue, scale);
  66689. that._controller.applySelectedRange(currentSelectedRange);
  66690. that._controller.applyPosition();
  66691. that._processSelectionChanged(false, selectedRange && selectedRange.blockSelectedRangeChanged)
  66692. },
  66693. appendTrackers: function(group) {
  66694. this._controller.appendTrackers(group)
  66695. },
  66696. _applyOptions: function(options) {
  66697. var that = this;
  66698. that._controller.applyOptions({
  66699. translator: options.translator,
  66700. canvas: options.canvas,
  66701. sliderMarker: options.sliderMarker,
  66702. sliderHandle: options.sliderHandle,
  66703. shutter: options.shutter,
  66704. scale: options.scale,
  66705. behavior: options.behavior
  66706. });
  66707. that._eventsManager.applyOptions({behavior: options.behavior})
  66708. },
  66709. _draw: function(group) {
  66710. var that = this,
  66711. rootElement;
  66712. if (msPointerEnabled) {
  66713. rootElement = that._renderer.getRoot();
  66714. rootElement && (rootElement.element.style.msTouchAction = "pinch-zoom")
  66715. }
  66716. that._controller.redraw(group);
  66717. that._drawAreaTracker(group);
  66718. that._eventsManager.initialize();
  66719. that._update()
  66720. },
  66721. _update: function() {
  66722. var that = this,
  66723. isEmpty = that._options.isEmpty;
  66724. that._eventsManager.setEnabled(!isEmpty);
  66725. that._controller.applySelectedRange(isEmpty ? {} : that._options.selectedRange);
  66726. that._controller.applyPosition(that.isDrawn());
  66727. that._updateLastSelectedRange();
  66728. that._controller.redraw()
  66729. }
  66730. };
  66731. return prototypeObject
  66732. }())
  66733. })(jQuery, DevExpress);
  66734. /*! Module viz-rangeselector, file slidersController.js */
  66735. (function($, DX, undefined) {
  66736. var rangeSelector = DX.viz.rangeSelector,
  66737. utils = DX.utils;
  66738. var START_VALUE_INDEX = 0,
  66739. END_VALUE_INDEX = 1;
  66740. rangeSelector.SlidersController = DX.Class.inherit(function() {
  66741. return {
  66742. ctor: function(sliders) {
  66743. this._sliders = sliders;
  66744. sliders[START_VALUE_INDEX].setAnotherSlider(sliders[END_VALUE_INDEX]);
  66745. sliders[END_VALUE_INDEX].setAnotherSlider(sliders[START_VALUE_INDEX])
  66746. },
  66747. setAreaTrackers: function(areaTracker, selectedAreaTracker) {
  66748. this._areaTracker = areaTracker;
  66749. this._selectedAreaTracker = selectedAreaTracker
  66750. },
  66751. applyOptions: function(options) {
  66752. var that = this,
  66753. values = null;
  66754. that._options = options;
  66755. that.getSlider(START_VALUE_INDEX).applyOptions(options);
  66756. that.getSlider(END_VALUE_INDEX).applyOptions(options);
  66757. if (options.behavior.snapToTicks) {
  66758. values = options.scale.ticksInfo.fullTicks;
  66759. if (values.length > 1 && values[0] > values[values.length - 1])
  66760. values = values.reverse()
  66761. }
  66762. that.getSlider(START_VALUE_INDEX).setAvailableValues(values);
  66763. that.getSlider(END_VALUE_INDEX).setAvailableValues(values)
  66764. },
  66765. processDocking: function(sliderIndex) {
  66766. var that = this;
  66767. if (sliderIndex !== undefined)
  66768. that.getSlider(sliderIndex).processDocking();
  66769. else {
  66770. that.getSlider(START_VALUE_INDEX).processDocking();
  66771. that.getSlider(END_VALUE_INDEX).processDocking()
  66772. }
  66773. that.setTrackersCursorStyle('default');
  66774. that.applyAreaTrackersPosition()
  66775. },
  66776. getSelectedRangeInterval: function() {
  66777. var that = this,
  66778. type = that._options.scale.type,
  66779. base = that._options.scale.logarithmBase,
  66780. startValue = that.getSlider(START_VALUE_INDEX).getValue(),
  66781. endValue = that.getSlider(END_VALUE_INDEX).getValue();
  66782. if (type === 'logarithmic')
  66783. return rangeSelector.utils.getInterval(utils.getLog(startValue, base), utils.getLog(endValue, base));
  66784. else
  66785. return rangeSelector.utils.getInterval(startValue, endValue)
  66786. },
  66787. moveSliders: function(postitionDelta, selectedRangeInterval) {
  66788. var that = this;
  66789. that.getSlider(START_VALUE_INDEX).setPosition(that.getSlider(START_VALUE_INDEX).getPosition() + postitionDelta, false, selectedRangeInterval);
  66790. that.applyPosition(true)
  66791. },
  66792. moveSlider: function(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, startOffsetPositionChangedCallback) {
  66793. var that = this,
  66794. slider = that.getSlider(sliderIndex),
  66795. anotherSlider = slider.getAnotherSlider(),
  66796. anotherSliderIndex = anotherSlider.getIndex(),
  66797. doSwap;
  66798. if (slider.canSwap())
  66799. if (sliderIndex === START_VALUE_INDEX ? position > anotherSlider.getPosition() : position < anotherSlider.getPosition()) {
  66800. doSwap = fastSwap;
  66801. if (!fastSwap)
  66802. if (Math.abs(offsetPosition) >= Math.abs(startOffsetPosition) && offsetPosition * startOffsetPosition < 0) {
  66803. doSwap = true;
  66804. position += 2 * startOffsetPosition;
  66805. startOffsetPositionChangedCallback(-startOffsetPosition)
  66806. }
  66807. if (doSwap) {
  66808. that.swapSliders();
  66809. anotherSlider.applyPosition(true)
  66810. }
  66811. }
  66812. slider.setPosition(position, true);
  66813. slider.applyPosition(true);
  66814. that.applyAreaTrackersPosition();
  66815. that.setTrackersCursorStyle('w-resize')
  66816. },
  66817. applySelectedAreaCenterPosition: function(pos) {
  66818. var that = this,
  66819. slidersContainerHalfWidth = (that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition()) / 2,
  66820. selectedRangeInterval = that.getSelectedRangeInterval();
  66821. that.getSlider(START_VALUE_INDEX).setPosition(pos - slidersContainerHalfWidth, false, selectedRangeInterval);
  66822. that.applyPosition();
  66823. that.processDocking()
  66824. },
  66825. processManualSelection: function(startPosition, endPosition, eventArgs) {
  66826. var that = this,
  66827. animateSliderIndex,
  66828. movingSliderIndex,
  66829. positionRange = [Math.min(startPosition, endPosition), Math.max(startPosition, endPosition)];
  66830. animateSliderIndex = startPosition < endPosition ? START_VALUE_INDEX : END_VALUE_INDEX;
  66831. movingSliderIndex = startPosition < endPosition ? END_VALUE_INDEX : START_VALUE_INDEX;
  66832. that.getSlider(movingSliderIndex).setPosition(positionRange[movingSliderIndex]);
  66833. that.getSlider(animateSliderIndex).setPosition(positionRange[animateSliderIndex]);
  66834. that.getSlider(movingSliderIndex).setPosition(positionRange[movingSliderIndex], true);
  66835. that.getSlider(movingSliderIndex).startEventHandler(eventArgs);
  66836. that.getSlider(animateSliderIndex).processDocking();
  66837. that.getSlider(movingSliderIndex).applyPosition(true)
  66838. },
  66839. applySelectedRange: function(selectedRange) {
  66840. var that = this,
  66841. inverted = that._options.scale.inverted;
  66842. utils.debug.assertParam(selectedRange, 'selectedRange not passed');
  66843. if (!inverted && selectedRange.startValue > selectedRange.endValue || inverted && selectedRange.startValue < selectedRange.endValue) {
  66844. that.getSlider(START_VALUE_INDEX).setValue(selectedRange.endValue);
  66845. that.getSlider(END_VALUE_INDEX).setValue(selectedRange.startValue)
  66846. }
  66847. else {
  66848. that.getSlider(START_VALUE_INDEX).setValue(selectedRange.startValue);
  66849. that.getSlider(END_VALUE_INDEX).setValue(selectedRange.endValue)
  66850. }
  66851. },
  66852. getSelectedRange: function() {
  66853. var that = this;
  66854. return {
  66855. startValue: that.getSlider(START_VALUE_INDEX).getValue(),
  66856. endValue: that.getSlider(END_VALUE_INDEX).getValue()
  66857. }
  66858. },
  66859. swapSliders: function() {
  66860. var that = this;
  66861. that._sliders.reverse();
  66862. that.getSlider(START_VALUE_INDEX).changeLocation();
  66863. that.getSlider(END_VALUE_INDEX).changeLocation()
  66864. },
  66865. applyAreaTrackersPosition: function() {
  66866. var that = this,
  66867. selectedRange = that.getSelectedRange(),
  66868. scaleOptions = that._options.scale,
  66869. width = that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition(),
  66870. options = {
  66871. x: that.getSlider(START_VALUE_INDEX).getPosition(),
  66872. width: width < 0 ? 0 : width,
  66873. y: that._options.canvas.top,
  66874. height: that._options.canvas.height,
  66875. style: {cursor: scaleOptions.endValue - scaleOptions.startValue === selectedRange.endValue - selectedRange.startValue ? 'default' : 'pointer'}
  66876. };
  66877. that._selectedAreaTracker.applySettings(options);
  66878. that._areaTracker.applySettings({
  66879. x: that._options.canvas.left,
  66880. width: that._options.canvas.width,
  66881. y: that._options.canvas.top,
  66882. height: that._options.canvas.height
  66883. })
  66884. },
  66885. applyPosition: function(disableAnimation) {
  66886. var that = this;
  66887. that.getSlider(START_VALUE_INDEX).applyPosition(disableAnimation);
  66888. that.getSlider(END_VALUE_INDEX).applyPosition(disableAnimation);
  66889. that.applyAreaTrackersPosition()
  66890. },
  66891. redraw: function(group) {
  66892. var that = this;
  66893. that.getSlider(START_VALUE_INDEX).redraw(group);
  66894. that.getSlider(END_VALUE_INDEX).redraw(group)
  66895. },
  66896. appendTrackers: function(group) {
  66897. var that = this;
  66898. if (that._areaTracker && that._selectedAreaTracker) {
  66899. that._areaTracker.append(group);
  66900. that._selectedAreaTracker.append(group)
  66901. }
  66902. that.getSlider(START_VALUE_INDEX).appendTrackers(group);
  66903. that.getSlider(END_VALUE_INDEX).appendTrackers(group)
  66904. },
  66905. getSlider: function(sliderIndex) {
  66906. return this._sliders[sliderIndex]
  66907. },
  66908. getAreaTracker: function() {
  66909. return this._areaTracker
  66910. },
  66911. getSelectedAreaTracker: function() {
  66912. return this._selectedAreaTracker
  66913. },
  66914. setTrackersCursorStyle: function(style) {
  66915. var that = this;
  66916. that._selectedAreaTracker.applySettings({style: {cursor: style}});
  66917. that._areaTracker.applySettings({style: {cursor: style}})
  66918. }
  66919. }
  66920. }())
  66921. })(jQuery, DevExpress);
  66922. /*! Module viz-rangeselector, file slidersEventsManager.js */
  66923. (function($, DX, undefined) {
  66924. var rangeSelector = DX.viz.rangeSelector,
  66925. utils = DX.utils,
  66926. MIN_MANUAL_SELECTING_WIDTH = 10,
  66927. START_VALUE_INDEX = 0,
  66928. END_VALUE_INDEX = 1,
  66929. addNamespace = DX.ui.events.addNamespace,
  66930. setEvents = function() {
  66931. var win = window;
  66932. win = DX.viz.rangeSelector.mockWindow || window;
  66933. var touchSupport = "ontouchstart" in win,
  66934. msPointerEnabled = win.navigator.msPointerEnabled,
  66935. pointerEnabled = win.navigator.pointerEnabled;
  66936. rangeSelector.events = {
  66937. start: pointerEnabled ? "pointerdown" : msPointerEnabled ? "MSPointerDown" : touchSupport ? "touchstart mousedown" : "mousedown",
  66938. move: pointerEnabled ? "pointermove" : msPointerEnabled ? "MSPointerMove" : touchSupport ? "touchmove mousemove" : "mousemove",
  66939. end: pointerEnabled ? "pointerup pointercancel" : msPointerEnabled ? "MSPointerUp MSPointerCancel" : touchSupport ? "touchend mouseup" : "mouseup"
  66940. }
  66941. },
  66942. _SlidersEventManager,
  66943. getEventPageX = rangeSelector.utils.getEventPageX,
  66944. rangeSelectorCount = 0;
  66945. setEvents();
  66946. var isLeftButtonPressed = function(event) {
  66947. var e = event || window.event,
  66948. originalEvent = e.originalEvent,
  66949. touches = e.touches,
  66950. pointerType = originalEvent ? originalEvent.pointerType : false,
  66951. eventTouches = originalEvent ? originalEvent.touches : false,
  66952. isIE8LeftClick = e.which === undefined && e.button === 1,
  66953. isMSPointerLeftClick = originalEvent && pointerType !== undefined && (pointerType === (originalEvent.MSPOINTER_TYPE_TOUCH || 'touch') || pointerType === (originalEvent.MSPOINTER_TYPE_MOUSE || 'mouse') && originalEvent.buttons === 1),
  66954. isLeftClick = isIE8LeftClick || e.which === 1,
  66955. isTouches = touches && touches.length > 0 || eventTouches && eventTouches.length > 0;
  66956. return isLeftClick || isMSPointerLeftClick || isTouches
  66957. };
  66958. var isMultiTouches = function(event) {
  66959. var originalEvent = event.originalEvent,
  66960. touches = event.touches,
  66961. eventTouches = originalEvent ? originalEvent.touches : false;
  66962. return touches && touches.length > 1 || eventTouches && eventTouches.length > 1 || null
  66963. };
  66964. var isTouchEventArgs = function(e) {
  66965. return e && e.type && e.type.indexOf('touch') === 0
  66966. };
  66967. _SlidersEventManager = rangeSelector.SlidersEventsManager = function(renderer, slidersController, processSelectionChanged) {
  66968. var that = this,
  66969. uniqueNS = that._uniqueNS = 'dx-range-selector_' + rangeSelectorCount++,
  66970. rangeSelectorEvents = rangeSelector.events;
  66971. that._renderer = renderer;
  66972. that._slidersController = slidersController;
  66973. that._processSelectionChanged = processSelectionChanged;
  66974. that._enabled = true;
  66975. that._eventsNames = {
  66976. start: addNamespace(rangeSelectorEvents.start, uniqueNS),
  66977. move: addNamespace(rangeSelectorEvents.move, uniqueNS),
  66978. end: addNamespace(rangeSelectorEvents.end, uniqueNS)
  66979. }
  66980. };
  66981. _SlidersEventManager.prototype = {
  66982. constructor: _SlidersEventManager,
  66983. _getRootOffsetLeft: function() {
  66984. return rangeSelector.utils.getRootOffsetLeft(this._renderer)
  66985. },
  66986. _initializeSliderEvents: function(sliderIndex) {
  66987. var that = this,
  66988. renderer = that._renderer,
  66989. isTouchEvent,
  66990. slidersController = that._slidersController,
  66991. processSelectionChanged = that._processSelectionChanged,
  66992. slider = slidersController.getSlider(sliderIndex),
  66993. anotherSlider = slider.getAnotherSlider(),
  66994. fastSwap,
  66995. startOffsetPosition,
  66996. splitterMoving,
  66997. sliderEndHandler = function(e) {
  66998. if (splitterMoving) {
  66999. splitterMoving = false;
  67000. slidersController.processDocking();
  67001. processSelectionChanged(false)
  67002. }
  67003. },
  67004. sliderMoveHandler = function(e) {
  67005. var doSwap,
  67006. pageX,
  67007. offsetPosition,
  67008. svgOffsetLeft = that._getRootOffsetLeft(),
  67009. position,
  67010. sliderIndex = slider.getIndex();
  67011. if (isTouchEvent !== isTouchEventArgs(e))
  67012. return;
  67013. if (!isLeftButtonPressed(e, true) && splitterMoving) {
  67014. splitterMoving = false;
  67015. slidersController.processDocking();
  67016. processSelectionChanged(false)
  67017. }
  67018. else if (splitterMoving) {
  67019. if (!isMultiTouches(e)) {
  67020. this.preventedDefault = true;
  67021. e.preventDefault()
  67022. }
  67023. pageX = getEventPageX(e);
  67024. position = pageX - startOffsetPosition - svgOffsetLeft;
  67025. offsetPosition = pageX - slider.getPosition() - svgOffsetLeft;
  67026. slidersController.moveSlider(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, function(newStartOffsetPosition) {
  67027. startOffsetPosition = newStartOffsetPosition
  67028. });
  67029. processSelectionChanged(true)
  67030. }
  67031. },
  67032. eventsNames = that._eventsNames;
  67033. slider.startEventHandler = function(e) {
  67034. if (!that._enabled || !isLeftButtonPressed(e) || splitterMoving)
  67035. return;
  67036. fastSwap = this === slider.getSliderTracker().element;
  67037. splitterMoving = true;
  67038. isTouchEvent = isTouchEventArgs(e);
  67039. startOffsetPosition = getEventPageX(e) - slider.getPosition() - that._getRootOffsetLeft();
  67040. if (!isMultiTouches(e)) {
  67041. this.preventedDefault = true;
  67042. e.stopPropagation();
  67043. e.preventDefault()
  67044. }
  67045. };
  67046. slider.on(eventsNames.start, slider.startEventHandler);
  67047. $(document).on(eventsNames.end, sliderEndHandler).on(eventsNames.move, sliderMoveHandler);
  67048. slider.__moveEventHandler = sliderMoveHandler
  67049. },
  67050. _initializeAreaEvents: function() {
  67051. var that = this,
  67052. renderer = that._renderer,
  67053. isTouchEvent,
  67054. slidersController = that._slidersController,
  67055. processSelectionChanged = that._processSelectionChanged,
  67056. areaTracker = slidersController.getAreaTracker(),
  67057. unselectedAreaProcessing = false,
  67058. splitterMoving = false,
  67059. startPageX,
  67060. areaEndHandler = function(e) {
  67061. var pageX;
  67062. if (unselectedAreaProcessing) {
  67063. pageX = getEventPageX(e);
  67064. if (that._options.behavior.moveSelectedRangeByClick && Math.abs(startPageX - pageX) < MIN_MANUAL_SELECTING_WIDTH)
  67065. slidersController.applySelectedAreaCenterPosition(pageX - that._getRootOffsetLeft());
  67066. unselectedAreaProcessing = false;
  67067. processSelectionChanged(false)
  67068. }
  67069. },
  67070. areaMoveHandler = function(e) {
  67071. var pageX,
  67072. startPosition,
  67073. endPosition,
  67074. svgOffsetLeft = that._getRootOffsetLeft();
  67075. if (isTouchEvent !== isTouchEventArgs(e))
  67076. return;
  67077. if (unselectedAreaProcessing && !isLeftButtonPressed(e)) {
  67078. unselectedAreaProcessing = false;
  67079. processSelectionChanged(false)
  67080. }
  67081. if (unselectedAreaProcessing) {
  67082. pageX = getEventPageX(e);
  67083. if (that._options.behavior.manualRangeSelectionEnabled && Math.abs(startPageX - pageX) >= MIN_MANUAL_SELECTING_WIDTH) {
  67084. startPosition = startPageX - svgOffsetLeft;
  67085. endPosition = pageX - svgOffsetLeft;
  67086. slidersController.processManualSelection(startPosition, endPosition, e);
  67087. unselectedAreaProcessing = false;
  67088. processSelectionChanged(true)
  67089. }
  67090. }
  67091. },
  67092. eventsNames = that._eventsNames;
  67093. areaTracker.on(eventsNames.start, function(e) {
  67094. if (!that._enabled || !isLeftButtonPressed(e) || unselectedAreaProcessing)
  67095. return;
  67096. unselectedAreaProcessing = true;
  67097. isTouchEvent = isTouchEventArgs(e);
  67098. startPageX = getEventPageX(e)
  67099. });
  67100. $(document).on(eventsNames.end, areaEndHandler).on(eventsNames.move, areaMoveHandler);
  67101. that.__areaMoveEventHandler = areaMoveHandler
  67102. },
  67103. _initializeSelectedAreaEvents: function() {
  67104. var that = this,
  67105. renderer = that._renderer,
  67106. isTouchEvent,
  67107. slidersController = that._slidersController,
  67108. processSelectionChanged = that._processSelectionChanged,
  67109. selectedAreaTracker = slidersController.getSelectedAreaTracker(),
  67110. selectedAreaMoving = false,
  67111. offsetStartPosition,
  67112. selectedRangeInterval,
  67113. selectedAreaEndHandler = function(e) {
  67114. if (selectedAreaMoving) {
  67115. selectedAreaMoving = false;
  67116. slidersController.processDocking();
  67117. processSelectionChanged(false)
  67118. }
  67119. },
  67120. selectedAreaMoveHandler = function(e) {
  67121. var positionDelta,
  67122. pageX;
  67123. if (isTouchEvent !== isTouchEventArgs(e))
  67124. return;
  67125. if (selectedAreaMoving && !isLeftButtonPressed(e)) {
  67126. selectedAreaMoving = false;
  67127. slidersController.processDocking();
  67128. processSelectionChanged(false)
  67129. }
  67130. if (selectedAreaMoving) {
  67131. if (!isMultiTouches(e)) {
  67132. this.preventedDefault = true;
  67133. e.preventDefault()
  67134. }
  67135. pageX = getEventPageX(e);
  67136. positionDelta = pageX - slidersController.getSlider(START_VALUE_INDEX).getPosition() - offsetStartPosition;
  67137. slidersController.moveSliders(positionDelta, selectedRangeInterval);
  67138. processSelectionChanged(true)
  67139. }
  67140. },
  67141. eventsNames = that._eventsNames;
  67142. selectedAreaTracker.on(eventsNames.start, function(e) {
  67143. if (!that._enabled || !isLeftButtonPressed(e) || selectedAreaMoving)
  67144. return;
  67145. selectedAreaMoving = true;
  67146. isTouchEvent = isTouchEventArgs(e);
  67147. offsetStartPosition = getEventPageX(e) - slidersController.getSlider(START_VALUE_INDEX).getPosition();
  67148. selectedRangeInterval = slidersController.getSelectedRangeInterval();
  67149. if (!isMultiTouches(e)) {
  67150. this.preventedDefault = true;
  67151. e.stopPropagation();
  67152. e.preventDefault()
  67153. }
  67154. });
  67155. $(document).on(eventsNames.end, selectedAreaEndHandler).on(eventsNames.move, selectedAreaMoveHandler);
  67156. that.__selectedAreaMoveEventHandler = selectedAreaMoveHandler
  67157. },
  67158. applyOptions: function(options) {
  67159. this._options = options
  67160. },
  67161. dispose: function() {
  67162. $(document).off('.' + this._uniqueNS)
  67163. },
  67164. initialize: function() {
  67165. var that = this;
  67166. if (!that._renderer.isInitialized())
  67167. return;
  67168. that._initializeSelectedAreaEvents(that);
  67169. that._initializeAreaEvents();
  67170. that._initializeSliderEvents(START_VALUE_INDEX);
  67171. that._initializeSliderEvents(END_VALUE_INDEX)
  67172. },
  67173. setEnabled: function(enabled) {
  67174. this._enabled = enabled
  67175. }
  67176. };
  67177. rangeSelector.__setEvents = setEvents
  67178. })(jQuery, DevExpress);
  67179. /*! Module viz-rangeselector, file slider.js */
  67180. (function($, DX, undefined) {
  67181. var rangeSelector = DX.viz.rangeSelector,
  67182. utils = DX.utils;
  67183. var touchSupport = "ontouchstart" in window;
  67184. var msPointerEnabled = window.navigator.msPointerEnabled || window.navigator.pointerEnabled;
  67185. var animationOptions = {duration: 250};
  67186. var SPLITTER_WIDTH = 8,
  67187. TOUCH_SPLITTER_WIDTH = 20,
  67188. START_VALUE_INDEX = 0,
  67189. END_VALUE_INDEX = 1;
  67190. rangeSelector.Slider = rangeSelector.BaseVisualElement.inherit(function() {
  67191. return {
  67192. getText: function() {
  67193. if (this._marker)
  67194. return this._marker.getText()
  67195. },
  67196. getAvailableValues: function() {
  67197. return this._values
  67198. },
  67199. getShutter: function() {
  67200. return this._shutter
  67201. },
  67202. getMarker: function() {
  67203. return this._marker
  67204. },
  67205. _createSlider: function() {
  67206. var that = this,
  67207. sliderHandle,
  67208. sliderGroup,
  67209. sliderHandleOptions = that._options.sliderHandle;
  67210. sliderGroup = that._renderer.createGroup({'class': 'slider'});
  67211. sliderGroup.applySettings({
  67212. translateX: that._options.canvas.left,
  67213. translateY: that._options.canvas.top
  67214. });
  67215. sliderHandle = that._renderer.createLine(0, 0, 0, that._options.canvas.height, {
  67216. 'class': 'dx-range-selector-slider',
  67217. strokeWidth: sliderHandleOptions.width,
  67218. stroke: sliderHandleOptions.color,
  67219. strokeOpacity: sliderHandleOptions.opacity
  67220. });
  67221. sliderHandle.append(sliderGroup);
  67222. sliderGroup.setValid = function(correct) {
  67223. sliderHandle.applySettings({stroke: correct ? that._options.sliderHandle.color : that._options.sliderMarker.invalidRangeColor})
  67224. };
  67225. sliderGroup.updateHeight = function() {
  67226. sliderHandle.applySettings({points: [0, 0, 0, that._options.canvas.height]})
  67227. };
  67228. sliderGroup.applyOptions = function(options) {
  67229. sliderHandle.applySettings(options)
  67230. };
  67231. sliderGroup.__line = sliderHandle;
  67232. return sliderGroup
  67233. },
  67234. _createSliderTracker: function() {
  67235. var that = this,
  67236. sliderHandleWidth = that._options.sliderHandle.width,
  67237. splitterWidth = SPLITTER_WIDTH < sliderHandleWidth ? sliderHandleWidth : SPLITTER_WIDTH,
  67238. sliderWidth = touchSupport || msPointerEnabled ? TOUCH_SPLITTER_WIDTH : splitterWidth,
  67239. sliderTracker,
  67240. sliderTrackerGroup;
  67241. sliderTracker = that._renderer.createRect(-sliderWidth / 2, 0, sliderWidth, that._options.canvas.height, 0, {
  67242. fill: 'grey',
  67243. stroke: 'grey',
  67244. opacity: 0.0001,
  67245. style: {cursor: 'w-resize'}
  67246. });
  67247. sliderTrackerGroup = that._renderer.createGroup({'class': 'sliderTracker'});
  67248. sliderTrackerGroup.applySettings({
  67249. translateX: 0,
  67250. translateY: that._options.canvas.top
  67251. });
  67252. sliderTracker.append(sliderTrackerGroup);
  67253. sliderTrackerGroup.updateHeight = function() {
  67254. sliderTracker.applySettings({height: that._options.canvas.height})
  67255. };
  67256. sliderTrackerGroup.__rect = sliderTracker;
  67257. return sliderTrackerGroup
  67258. },
  67259. _drawSliderTracker: function(group) {
  67260. var that = this,
  67261. sliderTracker = that._createSliderTracker();
  67262. if (sliderTracker) {
  67263. sliderTracker.append(group);
  67264. that._sliderTracker = sliderTracker
  67265. }
  67266. },
  67267. _createSliderMarker: function(options) {
  67268. return rangeSelector.rangeSelectorFactory.createSliderMarker(options)
  67269. },
  67270. _setPosition: function(position, correctByMinMaxRange) {
  67271. var that = this,
  67272. correctedPosition = that._correctPosition(position),
  67273. value = that._options.translator.untranslate(correctedPosition);
  67274. that.setValue(value, correctByMinMaxRange, false);
  67275. that._position = correctedPosition
  67276. },
  67277. _setPositionForBothSliders: function(startPosition, interval) {
  67278. var that = this,
  67279. anotherSlider,
  67280. startValue,
  67281. endValue,
  67282. endPosition,
  67283. type = that._options.scale.type,
  67284. base = that._options.scale.logarithmBase,
  67285. inverted = that._options.scale.inverted;
  67286. var getNextValue = function(value, isNegative) {
  67287. var lgPower;
  67288. if (type === 'logarithmic') {
  67289. lgPower = utils.addInterval(utils.adjustValue(utils.getLog(value, base)), interval, isNegative);
  67290. return utils.raiseTo(lgPower, base)
  67291. }
  67292. else
  67293. return utils.addInterval(value, interval, isNegative)
  67294. };
  67295. anotherSlider = that.getAnotherSlider();
  67296. startPosition = that._correctBounds(startPosition);
  67297. startValue = that._options.translator.untranslate(startPosition);
  67298. endValue = getNextValue(startValue);
  67299. if (!inverted && endValue > that._options.scale.endValue || inverted && endValue < that._options.scale.endValue) {
  67300. endValue = that._options.scale.endValue;
  67301. endPosition = that._options.canvas.left + that._options.canvas.width;
  67302. startValue = getNextValue(endValue, true);
  67303. startPosition = that._options.translator.translate(startValue)
  67304. }
  67305. else
  67306. endPosition = that._options.translator.translate(endValue);
  67307. if (that._values)
  67308. if (!inverted ? startValue < that._values[0] : startValue > that._values[that._values.length - 1]) {
  67309. startValue = that._correctBusinessValueByAvailableValues(startValue, false);
  67310. endValue = getNextValue(startValue)
  67311. }
  67312. else {
  67313. endValue = that._correctBusinessValueByAvailableValues(endValue, false);
  67314. startValue = getNextValue(endValue, true)
  67315. }
  67316. anotherSlider.setValue(endValue, undefined, false);
  67317. that.setValue(startValue, undefined, false);
  67318. that._position = startPosition;
  67319. anotherSlider._position = endPosition
  67320. },
  67321. _correctPosition: function(position) {
  67322. var that = this,
  67323. correctedPosition = that._correctInversion(position);
  67324. correctedPosition = that._correctBounds(correctedPosition);
  67325. return correctedPosition
  67326. },
  67327. _correctInversion: function(position) {
  67328. var that = this,
  67329. correctedPosition = position,
  67330. anotherSliderPosition = that.getAnotherSlider().getPosition(),
  67331. slidersInverted = that.getIndex() === START_VALUE_INDEX ? position > anotherSliderPosition : position < anotherSliderPosition;
  67332. if (slidersInverted)
  67333. correctedPosition = anotherSliderPosition;
  67334. return correctedPosition
  67335. },
  67336. _correctBounds: function(position) {
  67337. var that = this,
  67338. correctedPosition = position,
  67339. canvas = that._options.canvas;
  67340. if (position < canvas.left)
  67341. correctedPosition = canvas.left;
  67342. if (position > canvas.left + canvas.width)
  67343. correctedPosition = canvas.left + canvas.width;
  67344. return correctedPosition
  67345. },
  67346. _correctBusinessValue: function(businessValue, correctByMinMaxRange, skipCorrection) {
  67347. var that = this,
  67348. result = that._correctBusinessValueByAvailableValues(businessValue, skipCorrection);
  67349. if (correctByMinMaxRange)
  67350. result = that._correctBusinessValueByMinMaxRangeFromAnotherSlider(result);
  67351. result = that._correctBusinessValueByMinRangeFromStartEndValues(result);
  67352. return result
  67353. },
  67354. _correctBusinessValueByAvailableValues: function(businessValue, skipCorrection) {
  67355. var values = this._values;
  67356. if (!skipCorrection && values)
  67357. return rangeSelector.utils.findNearValue(values, businessValue);
  67358. return businessValue
  67359. },
  67360. _correctBusinessValueByMinMaxRangeFromAnotherSlider: function(businessValue) {
  67361. var that = this,
  67362. result = businessValue,
  67363. scale = that._options.scale,
  67364. values = that._values,
  67365. sliderIndex = that.getIndex(),
  67366. anotherBusinessValue = that.getAnotherSlider().getValue(),
  67367. isValid = true,
  67368. minValue,
  67369. maxValue;
  67370. if (!scale.inverted && sliderIndex === START_VALUE_INDEX || scale.inverted && sliderIndex === END_VALUE_INDEX) {
  67371. if (scale.maxRange)
  67372. minValue = that._addInterval(anotherBusinessValue, scale.maxRange, true);
  67373. if (scale.minRange)
  67374. maxValue = that._addInterval(anotherBusinessValue, scale.minRange, true)
  67375. }
  67376. else {
  67377. if (scale.maxRange)
  67378. maxValue = that._addInterval(anotherBusinessValue, scale.maxRange);
  67379. if (scale.minRange)
  67380. minValue = that._addInterval(anotherBusinessValue, scale.minRange)
  67381. }
  67382. if (maxValue !== undefined && result > maxValue) {
  67383. result = values ? rangeSelector.utils.findLessOrEqualValue(values, maxValue) : maxValue;
  67384. isValid = false
  67385. }
  67386. else if (minValue !== undefined && result < minValue) {
  67387. result = values ? rangeSelector.utils.findGreaterOrEqualValue(values, minValue) : minValue;
  67388. isValid = false
  67389. }
  67390. that._setValid(isValid);
  67391. return result
  67392. },
  67393. _addInterval: function(value, interval, isNegative) {
  67394. var result,
  67395. type = this._options.scale.type,
  67396. base = type === "logarithmic" && this._options.scale.logarithmBase;
  67397. if (base) {
  67398. var power = utils.addInterval(utils.getLog(value, base), interval, isNegative);
  67399. result = Math.pow(base, power)
  67400. }
  67401. else
  67402. result = utils.addInterval(value, interval, isNegative);
  67403. return result
  67404. },
  67405. _correctBusinessValueByMinRangeFromStartEndValues: function(businessValue) {
  67406. var that = this,
  67407. values = that._values,
  67408. startValue,
  67409. endValue,
  67410. isValid = true,
  67411. scale = that._options.scale,
  67412. result = businessValue;
  67413. if (scale.minRange)
  67414. if (that.getIndex() === END_VALUE_INDEX) {
  67415. startValue = that._addInterval(scale.startValue, scale.minRange, scale.inverted);
  67416. if (!scale.inverted && result < startValue || scale.inverted && result > startValue)
  67417. result = startValue
  67418. }
  67419. else if (that.getIndex() === START_VALUE_INDEX) {
  67420. endValue = that._addInterval(scale.endValue, scale.minRange, !scale.inverted);
  67421. if (!scale.inverted && result > endValue || scale.inverted && result < endValue)
  67422. result = endValue
  67423. }
  67424. return result
  67425. },
  67426. _applySliderPosition: function(position, disableAnimation) {
  67427. var that = this,
  67428. isAnimation = that._options.behavior.animationEnabled && !disableAnimation,
  67429. top = that._options.canvas.top,
  67430. slider = that._slider;
  67431. if (isAnimation || slider.inAnimation) {
  67432. slider.inAnimation = true;
  67433. slider.animate({translate: {
  67434. x: position,
  67435. y: top
  67436. }}, isAnimation ? animationOptions : {duration: 0}, function() {
  67437. slider.inAnimation = false
  67438. });
  67439. that._sliderTracker.animate({translate: {
  67440. x: position,
  67441. y: top
  67442. }}, isAnimation ? animationOptions : {duration: 0})
  67443. }
  67444. else {
  67445. that._slider.applySettings({
  67446. translateX: position,
  67447. translateY: top
  67448. });
  67449. that._sliderTracker.applySettings({
  67450. translateX: position,
  67451. translateY: top
  67452. })
  67453. }
  67454. that._sliderTracker.updateHeight();
  67455. that._slider.updateHeight()
  67456. },
  67457. _applyShutterPosition: function(position, disableAnimation) {
  67458. var that = this,
  67459. shutterSettings,
  67460. shutter = that._shutter,
  67461. isAnimation = that._options.behavior.animationEnabled && !disableAnimation,
  67462. sliderIndex = that.getIndex();
  67463. if (sliderIndex == START_VALUE_INDEX)
  67464. shutterSettings = {
  67465. x: that._options.canvas.left,
  67466. y: that._options.canvas.top,
  67467. width: position - that._options.canvas.left,
  67468. height: that._options.canvas.height
  67469. };
  67470. else if (sliderIndex == END_VALUE_INDEX)
  67471. shutterSettings = {
  67472. x: position + 1,
  67473. y: that._options.canvas.top,
  67474. width: that._options.canvas.left + that._options.canvas.width - position,
  67475. height: that._options.canvas.height
  67476. };
  67477. if (shutterSettings)
  67478. if (isAnimation || shutter.inAnimation) {
  67479. shutter.inAnimation = true;
  67480. shutter.animate(shutterSettings, isAnimation ? animationOptions : {duration: 0}, function() {
  67481. shutter.inAnimation = false
  67482. })
  67483. }
  67484. else
  67485. shutter.applySettings(shutterSettings)
  67486. },
  67487. _setValid: function(isValid) {
  67488. var that = this;
  67489. if (that._marker)
  67490. that._marker.setValid(isValid);
  67491. that._slider.setValid(isValid)
  67492. },
  67493. _setText: function(text) {
  67494. var that = this;
  67495. if (that._marker)
  67496. that._marker.setText(text)
  67497. },
  67498. ctor: function(renderer, index) {
  67499. var that = this;
  67500. that.callBase(renderer);
  67501. that._index = index
  67502. },
  67503. getIndex: function() {
  67504. return this._index
  67505. },
  67506. setAvailableValues: function(values) {
  67507. this._values = values
  67508. },
  67509. setAnotherSlider: function(slider) {
  67510. this._anotherSlider = slider
  67511. },
  67512. getAnotherSlider: function(slider) {
  67513. return this._anotherSlider
  67514. },
  67515. appendTrackers: function(group) {
  67516. var that = this;
  67517. if (that._sliderTracker)
  67518. that._sliderTracker.append(group)
  67519. },
  67520. getSliderTracker: function() {
  67521. return this._sliderTracker
  67522. },
  67523. changeLocation: function() {
  67524. var that = this;
  67525. if (that._marker)
  67526. that._marker.changeLocation();
  67527. that._index = this._index === START_VALUE_INDEX ? END_VALUE_INDEX : START_VALUE_INDEX;
  67528. that._lastPosition = null
  67529. },
  67530. setPosition: function(position, correctByMinMaxRange, selectedRangeInterval) {
  67531. var that = this,
  67532. slider;
  67533. if (selectedRangeInterval !== undefined) {
  67534. slider = that.getIndex() === START_VALUE_INDEX ? that : that.getAnotherSlider();
  67535. slider._setPositionForBothSliders(position, selectedRangeInterval)
  67536. }
  67537. else
  67538. that._setPosition(position, correctByMinMaxRange)
  67539. },
  67540. getPosition: function() {
  67541. return this._position
  67542. },
  67543. _applyOptions: function(options) {
  67544. this._lastPosition = null
  67545. },
  67546. setValue: function(value, correctByMinMaxRange, skipCorrection) {
  67547. var that = this;
  67548. if (value === undefined) {
  67549. that._value = undefined;
  67550. that._valuePosition = that._position = that.getIndex() === START_VALUE_INDEX ? that._options.canvas.left : that._options.canvas.left + that._options.canvas.width;
  67551. that._setText(rangeSelector.consts.emptySliderMarkerText)
  67552. }
  67553. else {
  67554. that._value = that._correctBusinessValue(value, correctByMinMaxRange, utils.isDefined(skipCorrection) ? !!skipCorrection : true);
  67555. that._valuePosition = that._position = that._options.translator.translate(that._value);
  67556. that._setText(rangeSelector.formatValue(that._value, that._options.sliderMarker))
  67557. }
  67558. },
  67559. getValue: function() {
  67560. return this._value
  67561. },
  67562. canSwap: function() {
  67563. var that = this,
  67564. scale = that._options.scale,
  67565. startValue,
  67566. endValue,
  67567. anotherSliderValue;
  67568. if (that._options.behavior.allowSlidersSwap) {
  67569. if (scale.minRange) {
  67570. anotherSliderValue = that.getAnotherSlider().getValue();
  67571. if (that.getIndex() === START_VALUE_INDEX) {
  67572. endValue = utils.addInterval(scale.endValue, scale.minRange, !scale.inverted);
  67573. if (!scale.inverted && anotherSliderValue > endValue || scale.inverted && anotherSliderValue < endValue)
  67574. return false
  67575. }
  67576. else {
  67577. startValue = utils.addInterval(scale.startValue, scale.minRange, scale.inverted);
  67578. if (!scale.inverted && anotherSliderValue < startValue || scale.inverted && anotherSliderValue > startValue)
  67579. return false
  67580. }
  67581. }
  67582. return true
  67583. }
  67584. return false
  67585. },
  67586. processDocking: function() {
  67587. var that = this;
  67588. that._position = that._valuePosition;
  67589. that.applyPosition(false);
  67590. that._setValid(true)
  67591. },
  67592. applyPosition: function(disableAnimation) {
  67593. var that = this,
  67594. position = that.getPosition();
  67595. if (that._lastPosition !== position) {
  67596. that._applySliderPosition(position, disableAnimation);
  67597. that._applyShutterPosition(position, disableAnimation);
  67598. that._lastPosition = position
  67599. }
  67600. },
  67601. on: function(event, handler) {
  67602. var that = this;
  67603. that._sliderTracker.on(event, handler);
  67604. if (that._marker)
  67605. that._marker.getTracker().on(event, handler)
  67606. },
  67607. _update: function() {
  67608. var that = this;
  67609. that._marker && that._marker.applyOptions(that._options.sliderMarker);
  67610. that._shutter && that._shutter.applySettings({
  67611. fill: that._options.shutter.color,
  67612. fillOpacity: that._options.shutter.opacity
  67613. });
  67614. that._slider && that._slider.applyOptions({
  67615. strokeWidth: that._options.sliderHandle.width,
  67616. stroke: that._options.sliderHandle.color,
  67617. strokeOpacity: that._options.sliderHandle.opacity
  67618. })
  67619. },
  67620. _draw: function(group) {
  67621. var that = this,
  67622. slider,
  67623. marker,
  67624. sliderAreaGroup,
  67625. shutter,
  67626. startPos,
  67627. startWidth,
  67628. index = that.getIndex();
  67629. sliderAreaGroup = that._renderer.createGroup({'class': 'sliderArea'});
  67630. sliderAreaGroup.append(group);
  67631. if (index === START_VALUE_INDEX)
  67632. shutter = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, 0, that._options.canvas.height, 0);
  67633. else if (index === END_VALUE_INDEX)
  67634. shutter = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0);
  67635. if (shutter) {
  67636. shutter.append(sliderAreaGroup);
  67637. slider = that._createSlider();
  67638. if (slider)
  67639. slider.append(sliderAreaGroup);
  67640. if (that._options.sliderMarker.visible) {
  67641. marker = that._createSliderMarker({
  67642. renderer: that._renderer,
  67643. isLeftPointer: index === END_VALUE_INDEX,
  67644. sliderMarkerOptions: that._options.sliderMarker
  67645. });
  67646. marker.draw(slider)
  67647. }
  67648. that._shutter = shutter;
  67649. that._slider = slider;
  67650. that._marker = marker
  67651. }
  67652. that._drawSliderTracker(group)
  67653. }
  67654. }
  67655. }())
  67656. })(jQuery, DevExpress);
  67657. /*! Module viz-rangeselector, file sliderMarker.js */
  67658. (function($, DX, undefined) {
  67659. var rangeSelector = DX.viz.rangeSelector,
  67660. _SliderMarker;
  67661. _SliderMarker = rangeSelector.SliderMarker = function(options) {
  67662. var that = this;
  67663. that._renderer = options.renderer;
  67664. that._text = options.text;
  67665. that._isLeftPointer = options.isLeftPointer;
  67666. that._options = options.sliderMarkerOptions;
  67667. that._isValid = true;
  67668. initializeAreaPoints(that, {
  67669. width: 10,
  67670. height: 10
  67671. })
  67672. };
  67673. var applyOptions = function(options) {
  67674. this._options = options;
  67675. this.update()
  67676. };
  67677. var getRectSize = function(that, textSize) {
  67678. return {
  67679. width: Math.round(2 * that._options.padding + textSize.width),
  67680. height: Math.round(2 * that._options.padding + textSize.height * rangeSelector.consts.fontHeightRatio)
  67681. }
  67682. };
  67683. var initializeAreaPoints = function(that, textSize) {
  67684. var rectSize = getRectSize(that, textSize);
  67685. that._points = [];
  67686. if (that._isLeftPointer) {
  67687. that._points.push({
  67688. x: 0,
  67689. y: 0
  67690. });
  67691. that._points.push({
  67692. x: rectSize.width,
  67693. y: 0
  67694. });
  67695. that._points.push({
  67696. x: rectSize.width,
  67697. y: rectSize.height
  67698. });
  67699. that._points.push({
  67700. x: that._options.pointerSize,
  67701. y: rectSize.height
  67702. });
  67703. that._points.push({
  67704. x: 0,
  67705. y: rectSize.height + that._options.pointerSize
  67706. })
  67707. }
  67708. else {
  67709. that._points.push({
  67710. x: 0,
  67711. y: 0
  67712. });
  67713. that._points.push({
  67714. x: rectSize.width,
  67715. y: 0
  67716. });
  67717. that._points.push({
  67718. x: rectSize.width,
  67719. y: rectSize.height + that._options.pointerSize
  67720. });
  67721. that._points.push({
  67722. x: rectSize.width - that._options.pointerSize,
  67723. y: rectSize.height
  67724. });
  67725. that._points.push({
  67726. x: 0,
  67727. y: rectSize.height
  67728. })
  67729. }
  67730. };
  67731. var getPointerPosition = function(that, textSize) {
  67732. var rectSize = getRectSize(that, textSize);
  67733. if (that._isLeftPointer)
  67734. return {
  67735. x: 0,
  67736. y: rectSize.height + that._options.pointerSize
  67737. };
  67738. else
  67739. return {
  67740. x: rectSize.width - 1,
  67741. y: rectSize.height + that._options.pointerSize
  67742. }
  67743. };
  67744. var draw = function(group) {
  67745. var that = this;
  67746. var padding = that._options.padding;
  67747. that._sliderMarkerGroup = that._renderer.createGroup({'class': 'sliderMarker'});
  67748. that._sliderMarkerGroup.append(group);
  67749. that._area = that._renderer.createArea(that.points, {fill: that._options.color});
  67750. that._area.append(that._sliderMarkerGroup);
  67751. that._label = that._renderer.createText(that._text, padding, padding, {
  67752. font: that._options.font,
  67753. align: 'left',
  67754. style: {'-webkit-user-select': 'none'}
  67755. });
  67756. that._label.append(that._sliderMarkerGroup);
  67757. that._tracker = that._renderer.createRect(0, 0, 2 * padding, 2 * padding + that._options.pointerSize, 0, {
  67758. fill: 'grey',
  67759. stroke: 'grey',
  67760. opacity: 0.0001,
  67761. style: {cursor: 'pointer'}
  67762. });
  67763. that._tracker.append(that._sliderMarkerGroup);
  67764. that._drawn = true;
  67765. that.update()
  67766. };
  67767. var getTextSize = function(that) {
  67768. var textSize = that._label.getBBox();
  67769. if (!that._textHeight && isFinite(textSize.height))
  67770. that._textHeight = textSize.height;
  67771. return {
  67772. width: textSize.width,
  67773. height: that._textHeight
  67774. }
  67775. };
  67776. var update = function(stop) {
  67777. var that = this,
  67778. textSize,
  67779. rectSize,
  67780. pointerPosition;
  67781. that._interval && clearInterval(that._interval);
  67782. delete that._interval;
  67783. if (!that._drawn)
  67784. return;
  67785. that._label.updateText(that._text);
  67786. textSize = getTextSize(that);
  67787. if (!stop) {
  67788. that._textSize = that._textSize || textSize;
  67789. that._textSize = textSize.width > that._textSize.width || textSize.height > that._textSize.height ? textSize : that._textSize;
  67790. textSize = that._textSize;
  67791. that._interval = setInterval(function() {
  67792. update.call(that, [true])
  67793. }, 75)
  67794. }
  67795. else {
  67796. delete that._textSize;
  67797. that._textSize = textSize
  67798. }
  67799. rectSize = getRectSize(that, textSize);
  67800. pointerPosition = getPointerPosition(that, textSize);
  67801. that._sliderMarkerGroup.applySettings({
  67802. translateX: -pointerPosition.x,
  67803. translateY: -pointerPosition.y
  67804. });
  67805. initializeAreaPoints(that, textSize);
  67806. that._area.applySettings({
  67807. points: that._points,
  67808. fill: that._isValid ? that._options.color : that._options.invalidRangeColor
  67809. });
  67810. that._tracker.applySettings({
  67811. width: rectSize.width,
  67812. height: rectSize.height + that._options.pointerSize
  67813. });
  67814. that._label.applySettings({
  67815. x: that._options.padding,
  67816. y: rectSize.height - that._options.padding
  67817. })
  67818. };
  67819. var getText = function() {
  67820. var that = this;
  67821. return that._text
  67822. };
  67823. var setText = function(value) {
  67824. var that = this;
  67825. if (that._text !== value) {
  67826. that._text = value;
  67827. that.update()
  67828. }
  67829. };
  67830. var setValid = function(isValid) {
  67831. var that = this;
  67832. that._isValid = isValid;
  67833. that.update()
  67834. };
  67835. var changeLocation = function() {
  67836. var that = this;
  67837. that._isLeftPointer = !that._isLeftPointer;
  67838. that.update()
  67839. };
  67840. var getTracker = function() {
  67841. var that = this;
  67842. return that._tracker
  67843. };
  67844. _SliderMarker.prototype = {
  67845. constructor: _SliderMarker,
  67846. draw: draw,
  67847. update: update,
  67848. getText: getText,
  67849. setText: setText,
  67850. changeLocation: changeLocation,
  67851. applyOptions: applyOptions,
  67852. getTracker: getTracker,
  67853. setValid: setValid
  67854. }
  67855. })(jQuery, DevExpress);
  67856. /*! Module viz-rangeselector, file rangeView.js */
  67857. (function($, DX, undefined) {
  67858. var rangeSelector = DX.viz.rangeSelector;
  67859. rangeSelector.RangeView = rangeSelector.BaseVisualElement.inherit(function() {
  67860. return {_draw: function(group) {
  67861. var that = this,
  67862. viewRect,
  67863. viewImage,
  67864. backgroundColor,
  67865. series,
  67866. i,
  67867. showChart,
  67868. canvas,
  67869. options = that._options,
  67870. seriesOptions,
  67871. isEmpty = options.isEmpty;
  67872. showChart = options.seriesDataSource && options.seriesDataSource.isShowChart() && !isEmpty;
  67873. canvas = options.canvas;
  67874. if (showChart)
  67875. backgroundColor = options.seriesDataSource.getBackgroundColor();
  67876. else if (!isEmpty && options.background.visible)
  67877. backgroundColor = options.background.color;
  67878. if (options.background.visible && backgroundColor) {
  67879. viewRect = that._renderer.createRect(canvas.left, canvas.top, canvas.width + 1, canvas.height, 0, {
  67880. fill: backgroundColor,
  67881. 'class': 'dx-range-selector-background'
  67882. });
  67883. viewRect.append(group)
  67884. }
  67885. if (options.background.visible && options.background.image && options.background.image.url) {
  67886. viewImage = that._renderer.createImage(canvas.left, canvas.top, canvas.width + 1, canvas.height, options.background.image.url, {location: options.background.image.location});
  67887. viewImage.append(group)
  67888. }
  67889. if (showChart) {
  67890. series = options.seriesDataSource.getSeries();
  67891. options.seriesDataSource.adjustSeriesDimensions(options.translators, options.chart.useAggregation);
  67892. for (i = 0; i < series.length; i++) {
  67893. seriesOptions = series[i].getOptions();
  67894. seriesOptions.seriesGroup = group;
  67895. seriesOptions.labelsGroup = group;
  67896. series[i].draw(options.translators, options.behavior && options.behavior.animationEnabled && that._renderer.animationEnabled())
  67897. }
  67898. }
  67899. }}
  67900. }())
  67901. })(jQuery, DevExpress);
  67902. /*! Module viz-rangeselector, file seriesDataSource.js */
  67903. (function($, DX, undefined) {
  67904. var rangeSelector = DX.viz.rangeSelector,
  67905. charts = DX.viz.charts,
  67906. core = DX.viz.core,
  67907. coreFactory = core.CoreFactory,
  67908. utils = DX.utils;
  67909. rangeSelector.SeriesDataSource = DX.Class.inherit(function() {
  67910. var createThemeManager = function(chartOptions) {
  67911. return charts.factory.createThemeManager(chartOptions, 'rangeSelector.chart')
  67912. };
  67913. var isArrayOfSimpleTypes = function(data) {
  67914. return $.isArray(data) && data.length > 0 && (utils.isNumber(data[0]) || utils.isDate(data[0]))
  67915. };
  67916. var convertToArrayOfObjects = function(data) {
  67917. return $.map(data, function(item, i) {
  67918. return {
  67919. arg: item,
  67920. val: i
  67921. }
  67922. })
  67923. };
  67924. var calculateSeries = function(that, options, templatedSeries) {
  67925. var series = [],
  67926. particularSeriesOptions,
  67927. seriesTheme,
  67928. data,
  67929. parsedData,
  67930. chartThemeManager = that.themeManager,
  67931. hasSeriesTemplate = !!chartThemeManager.getOptions('seriesTemplate'),
  67932. allSeriesOptions = hasSeriesTemplate ? templatedSeries : options.chart.series,
  67933. seriesValueType = options.chart.valueAxis && options.chart.valueAxis.valueType,
  67934. dataSourceField,
  67935. i;
  67936. that.teamplateData = [];
  67937. if (options.dataSource && !allSeriesOptions) {
  67938. if (isArrayOfSimpleTypes(options.dataSource))
  67939. options.dataSource = convertToArrayOfObjects(options.dataSource);
  67940. dataSourceField = options.dataSourceField || 'arg';
  67941. allSeriesOptions = {
  67942. argumentField: dataSourceField,
  67943. valueField: dataSourceField
  67944. };
  67945. that._hideChart = true
  67946. }
  67947. allSeriesOptions = $.isArray(allSeriesOptions) ? allSeriesOptions : allSeriesOptions ? [allSeriesOptions] : [];
  67948. that._backgroundColor = options.backgroundColor !== undefined ? options.backgroundColor : chartThemeManager.getOptions("backgroundColor");
  67949. for (i = 0; i < allSeriesOptions.length; i++) {
  67950. particularSeriesOptions = $.extend(true, {
  67951. argumentType: options.valueType,
  67952. argumentAxisType: options.axisType,
  67953. valueType: dataSourceField ? options.valueType : seriesValueType,
  67954. incidentOccured: options.incidentOccured
  67955. }, allSeriesOptions[i]);
  67956. particularSeriesOptions.rotated = false;
  67957. data = particularSeriesOptions.data || options.dataSource;
  67958. seriesTheme = chartThemeManager.getOptions("series", particularSeriesOptions);
  67959. seriesTheme.argumentField = seriesTheme.argumentField || options.dataSourceField;
  67960. if (data && data.length > 0) {
  67961. var newSeries = coreFactory.createSeries(options.renderer, seriesTheme);
  67962. series.push(newSeries)
  67963. }
  67964. if (hasSeriesTemplate) {
  67965. $.each(data, function(_, data) {
  67966. $.each(newSeries.getTeamplatedFields(), function(_, field) {
  67967. data[field.teamplateField] = data[field.originalField]
  67968. });
  67969. that.teamplateData.push(data)
  67970. });
  67971. newSeries.updateTeamplateFieldNames()
  67972. }
  67973. }
  67974. data = hasSeriesTemplate ? that.teamplateData : data;
  67975. that._dataValidator = charts.factory.createDataValidator(data, [series], options.incidentOccured, chartThemeManager.getOptions("dataPrepareSettings"));
  67976. parsedData = that._dataValidator.validate();
  67977. for (i = 0; i < series.length; i++) {
  67978. var particularSeries = series[i];
  67979. particularSeries.updateData(parsedData)
  67980. }
  67981. return series
  67982. };
  67983. var processSeriesFamilies = function(series, equalBarWidth, minBubbleSize, maxBubbleSize) {
  67984. var families = [],
  67985. types = [];
  67986. $.each(series, function(i, item) {
  67987. if ($.inArray(item.type, types) === -1)
  67988. types.push(item.type)
  67989. });
  67990. $.each(types, function(_, type) {
  67991. var family = new coreFactory.createSeriesFamily({
  67992. type: type,
  67993. equalBarWidth: equalBarWidth,
  67994. minBubbleSize: minBubbleSize,
  67995. maxBubbleSize: maxBubbleSize
  67996. });
  67997. family.add(series);
  67998. family.adjustSeriesValues();
  67999. families.push(family)
  68000. });
  68001. return families
  68002. };
  68003. var prototypeObject = {
  68004. ctor: function(options) {
  68005. var that = this,
  68006. templatedSeries,
  68007. seriesTemplate,
  68008. themeManager = that.themeManager = createThemeManager(options.chart),
  68009. topIndent = themeManager.getOptions('topIndent'),
  68010. bottomIndent = themeManager.getOptions('bottomIndent');
  68011. that._indent = {
  68012. top: topIndent >= 0 && topIndent < 1 ? topIndent : 0,
  68013. bottom: bottomIndent >= 0 && bottomIndent < 1 ? bottomIndent : 0
  68014. };
  68015. that._valueAxis = themeManager.getOptions('valueAxisRangeSelector') || {};
  68016. that._hideChart = false;
  68017. seriesTemplate = themeManager.getOptions('seriesTemplate');
  68018. if (options.dataSource && seriesTemplate)
  68019. templatedSeries = utils.processSeriesTemplate(seriesTemplate, options.dataSource);
  68020. that._series = calculateSeries(that, options, templatedSeries);
  68021. that._seriesFamilies = processSeriesFamilies(that._series, themeManager.getOptions('equalBarWidth'), themeManager.getOptions('minBubbleSize'), themeManager.getOptions('maxBubbleSize'))
  68022. },
  68023. adjustSeriesDimensions: function(translators, useAggregation) {
  68024. var that = this;
  68025. if (useAggregation)
  68026. $.each(that._series || [], function(_, s) {
  68027. s.resamplePoints(translators)
  68028. });
  68029. $.each(that._seriesFamilies, function() {
  68030. this.adjustSeriesDimensions(translators)
  68031. })
  68032. },
  68033. getBoundRange: function() {
  68034. var that = this,
  68035. rangeData,
  68036. valueAxisMin = that._valueAxis.min,
  68037. valueAxisMax = that._valueAxis.max,
  68038. valRange = new core.Range({
  68039. isValueRange: true,
  68040. min: valueAxisMin,
  68041. minVisible: valueAxisMin,
  68042. max: valueAxisMax,
  68043. maxVisible: valueAxisMax,
  68044. axisType: that._valueAxis.type,
  68045. base: that._valueAxis.logarithmBase
  68046. }),
  68047. argRange = new core.Range({}),
  68048. rangeYSize,
  68049. rangeVisibleSizeY,
  68050. i,
  68051. minIndent,
  68052. maxIndent;
  68053. for (i = 0; i < that._series.length; i++) {
  68054. rangeData = that._series[i].getRangeData();
  68055. valRange.addRange(rangeData.val);
  68056. argRange.addRange(rangeData.arg)
  68057. }
  68058. if (valRange.isDefined() && argRange.isDefined()) {
  68059. minIndent = that._valueAxis.inverted ? that._indent.top : that._indent.bottom;
  68060. maxIndent = that._valueAxis.inverted ? that._indent.bottom : that._indent.top;
  68061. rangeYSize = valRange.max - valRange.min;
  68062. rangeVisibleSizeY = ($.isNumeric(valRange.maxVisible) ? valRange.maxVisible : valRange.max) - ($.isNumeric(valRange.minVisible) ? valRange.minVisible : valRange.min);
  68063. if (utils.isDate(valRange.min))
  68064. valRange.min = new Date(valRange.min.valueOf() - rangeYSize * minIndent);
  68065. else
  68066. valRange.min -= rangeYSize * minIndent;
  68067. if (utils.isDate(valRange.max))
  68068. valRange.max = new Date(valRange.max.valueOf() + rangeYSize * maxIndent);
  68069. else
  68070. valRange.max += rangeYSize * maxIndent;
  68071. if ($.isNumeric(rangeVisibleSizeY)) {
  68072. valRange.maxVisible = valRange.maxVisible ? valRange.maxVisible + rangeVisibleSizeY * maxIndent : undefined;
  68073. valRange.minVisible = valRange.minVisible ? valRange.minVisible - rangeVisibleSizeY * minIndent : undefined
  68074. }
  68075. valRange.invert = that._valueAxis.inverted
  68076. }
  68077. return {
  68078. arg: argRange,
  68079. val: valRange
  68080. }
  68081. },
  68082. getSeries: function() {
  68083. var that = this;
  68084. return that._series
  68085. },
  68086. getBackgroundColor: function() {
  68087. var that = this;
  68088. return that._backgroundColor
  68089. },
  68090. isEmpty: function() {
  68091. var that = this;
  68092. return that.getSeries().length === 0
  68093. },
  68094. isShowChart: function() {
  68095. var that = this;
  68096. return !that.isEmpty() && !that._hideChart
  68097. },
  68098. getCalculatedValueType: function() {
  68099. var that = this,
  68100. result;
  68101. if (that._series.length)
  68102. result = that._series[0].argumentType;
  68103. return result
  68104. }
  68105. };
  68106. return prototypeObject
  68107. }())
  68108. })(jQuery, DevExpress);
  68109. /*! Module viz-rangeselector, file themeManager.js */
  68110. (function($, DX, undefined) {
  68111. DX.viz.rangeSelector = DX.viz.rangeSelector;
  68112. DX.viz.rangeSelector.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  68113. _themeSection: 'rangeSelector',
  68114. ctor: function(userTheme) {
  68115. this.setTheme(userTheme)
  68116. },
  68117. _initializeTheme: function() {
  68118. this._initializeFont(this._theme.scale.label.font);
  68119. this._initializeFont(this._theme.sliderMarker.font);
  68120. this._initializeFont(this._theme.loadingIndicator.font)
  68121. },
  68122. applyRangeSelectorTheme: function(userOptions) {
  68123. var that = this,
  68124. chart = userOptions.chart,
  68125. dataSource = userOptions.dataSource,
  68126. result;
  68127. delete userOptions.dataSource;
  68128. delete userOptions.chart;
  68129. result = $.extend(true, {}, that._theme, userOptions);
  68130. result.dataSource = dataSource;
  68131. if (chart)
  68132. result.chart = chart;
  68133. return result
  68134. },
  68135. setBackgroundColor: function(containerBackgroundColor) {
  68136. var theme = this._theme;
  68137. if (containerBackgroundColor)
  68138. theme.containerBackgroundColor = containerBackgroundColor;
  68139. theme.shutter.color = theme.shutter.color || theme.containerBackgroundColor
  68140. }
  68141. })
  68142. })(jQuery, DevExpress);
  68143. /*! Module viz-rangeselector, file dxRangeSelector.js */
  68144. (function($, DX, undefined) {
  68145. var ui = DX.ui,
  68146. viz = DX.viz;
  68147. DX.registerComponent("dxRangeSelector", viz.rangeSelector.RangeSelector)
  68148. })(jQuery, DevExpress);
  68149. DevExpress.MOD_VIZ_RANGESELECTOR = true
  68150. }
  68151. if (!DevExpress.MOD_VIZ_VECTORMAP) {
  68152. if (!DevExpress.MOD_VIZ_CORE)
  68153. throw Error('Required module is not referenced: viz-core');
  68154. /*! Module viz-vectormap, file map.js */
  68155. (function(DX, $, undefined) {
  68156. DX.viz.map = {};
  68157. var _Number = window.Number,
  68158. _isFunction = DX.utils.isFunction,
  68159. _getRootOffset = DX.utils.getRootOffset;
  68160. var DEFAULT_WIDTH = 800,
  68161. DEFAULT_HEIGHT = 400;
  68162. var DATA_KEY = DX.viz.map.__DATA_KEY = 'vectormap-data';
  68163. DX.viz.map.Map = DX.viz.core.BaseWidget.inherit({
  68164. _init: function() {
  68165. var that = this;
  68166. that.callBase.apply(that, arguments);
  68167. that.renderer = that._renderer = that._factory.createRenderer({
  68168. width: 1,
  68169. height: 1,
  68170. pathModified: that.option('pathModified'),
  68171. rtl: that.option('rtlEnabled')
  68172. });
  68173. that.renderer.draw(that._element().get(0));
  68174. that._root = that._renderer.getRoot();
  68175. that._root.applySettings({
  68176. 'class': 'dxm',
  68177. stroke: 'none',
  68178. strokeWidth: 0,
  68179. fill: 'none',
  68180. align: 'center',
  68181. cursor: 'default',
  68182. style: {overflow: 'hidden'}
  68183. });
  68184. that._themeManager = that._factory.createThemeManager();
  68185. that._projection = that._factory.createProjection();
  68186. that._tracker = that._factory.createTracker({root: that._root});
  68187. that._background = that._renderer.createRect(0, 0, 0, 0, 0, {'class': 'dxm-background'}).data(DATA_KEY, {type: 'background'});
  68188. that._areasManager = that._factory.createAreasManager({
  68189. container: that._root,
  68190. renderer: that._renderer,
  68191. projection: that._projection,
  68192. themeManager: that._themeManager,
  68193. tracker: that._tracker,
  68194. ready: function() {
  68195. that.hideLoadingIndicator()
  68196. }
  68197. });
  68198. that._areasManager.setData(that.option('mapData'));
  68199. that._markersManager = that._factory.createMarkersManager({
  68200. container: that._root,
  68201. renderer: that._renderer,
  68202. projection: that._projection,
  68203. themeManager: that._themeManager,
  68204. tracker: that._tracker
  68205. });
  68206. that._markersManager.setData(that.option('markers'));
  68207. that._controlBar = that._factory.createControlBar({
  68208. container: that._root,
  68209. renderer: that._renderer,
  68210. context: that,
  68211. resetCallback: controlResetCallback,
  68212. beginMoveCallback: controlBeginMoveCallback,
  68213. endMoveCallback: controlEndMoveCallback,
  68214. moveCallback: controlMoveCallback,
  68215. zoomCallback: controlZoomCallback
  68216. });
  68217. that._legend = that._factory.createLegend({
  68218. container: that._root,
  68219. renderer: that._renderer,
  68220. themeManager: that._themeManager
  68221. });
  68222. that._tooltip = that._factory.createTooltip({
  68223. container: that._root,
  68224. renderer: that._renderer,
  68225. tracker: that._tracker
  68226. });
  68227. that._projection.setBounds(that.option('bounds')).setMaxZoom(that.option('maxZoomFactor')).setZoom(that.option('zoomFactor')).setCenter(that.option('center'));
  68228. that._themeManager.setTheme(that.option('theme'));
  68229. that._themeManager.patchRtlSettings(that.option('rtlEnabled'));
  68230. that._setClickCallback(that.option('click'));
  68231. that._setCenterChangedCallback(that.option('centerChanged'));
  68232. that._setZoomFactorChangedCallback(that.option('zoomFactorChanged'));
  68233. that._setTrackerCallbacks()
  68234. },
  68235. _dispose: function() {
  68236. var that = this;
  68237. that.callBase.apply(that, arguments);
  68238. that._resetTrackerCallbacks();
  68239. that._themeManager.dispose();
  68240. that._tracker.dispose();
  68241. that._areasManager.dispose();
  68242. that._markersManager.dispose();
  68243. that._controlBar.dispose();
  68244. that._legend.dispose();
  68245. that._tooltip.dispose();
  68246. that._renderer.dispose();
  68247. that._disposeLoadIndicator();
  68248. that._renderer = that._themeManager = that._projection = that._tracker = that._root = that._background = that._areasManager = that._markersManager = that._controlBar = that._legend = that._tooltip = that._centerChangedCallback = that._zoomFactorChangedCallback = null
  68249. },
  68250. _setTrackerCallbacks: function() {
  68251. var that = this,
  68252. renderer = that._renderer,
  68253. managers = {
  68254. area: that._areasManager,
  68255. marker: that._markersManager
  68256. },
  68257. projection = that._projection,
  68258. controlBar = that._controlBar,
  68259. tooltip = that._tooltip,
  68260. xdrag,
  68261. ydrag,
  68262. isControlDrag = false;
  68263. that._tracker.setCallbacks({
  68264. click: function(arg) {
  68265. var offset = _getRootOffset(renderer);
  68266. arg.$event.x = arg.x - offset.left;
  68267. arg.$event.y = arg.y - offset.top;
  68268. var manager = managers[arg.data.type];
  68269. if (manager)
  68270. manager.raiseClick(arg.data.index, arg.$event);
  68271. if (manager || arg.data.type === 'background')
  68272. that._raiseClick(arg.$event)
  68273. },
  68274. start: function(arg) {
  68275. isControlDrag = arg.data.type === 'control-bar';
  68276. if (isControlDrag) {
  68277. arg.data = arg.data.index;
  68278. controlBar.processStart(arg)
  68279. }
  68280. else {
  68281. xdrag = arg.x;
  68282. ydrag = arg.y;
  68283. projection.snapCenter()
  68284. }
  68285. },
  68286. move: function(arg) {
  68287. if (isControlDrag) {
  68288. arg.data = arg.data.index;
  68289. controlBar.processMove(arg)
  68290. }
  68291. else {
  68292. projection.moveCenter(xdrag - arg.x, ydrag - arg.y);
  68293. xdrag = arg.x;
  68294. ydrag = arg.y;
  68295. that._applyTranslate()
  68296. }
  68297. },
  68298. end: function(arg) {
  68299. if (isControlDrag) {
  68300. arg.data = arg.data.index;
  68301. controlBar.processEnd(arg)
  68302. }
  68303. else
  68304. projection.isCenterChanged() && that._raiseCenterChanged();
  68305. isControlDrag = false
  68306. },
  68307. zoom: function(arg) {
  68308. controlBar.processZoom(arg)
  68309. },
  68310. 'hover-on': function(arg) {
  68311. var manager = managers[arg.data.type];
  68312. if (manager)
  68313. manager.hoverItem(arg.data.index, true)
  68314. },
  68315. 'hover-off': function(arg) {
  68316. var manager = managers[arg.data.type];
  68317. if (manager)
  68318. manager.hoverItem(arg.data.index, false)
  68319. },
  68320. 'focus-on': function(arg, done) {
  68321. var result = false;
  68322. if (tooltip.enabled()) {
  68323. var proxy = managers[arg.data.type] ? managers[arg.data.type].getProxyItem(arg.data.index) : null;
  68324. if (!!proxy && tooltip.prepare(proxy, {offset: 12})) {
  68325. var offset = _getRootOffset(renderer);
  68326. tooltip.show().move(arg.x - offset.left, arg.y - offset.top);
  68327. result = true
  68328. }
  68329. }
  68330. done(result)
  68331. },
  68332. 'focus-move': function(arg) {
  68333. var offset = _getRootOffset(renderer);
  68334. tooltip.move(arg.x - offset.left, arg.y - offset.top)
  68335. },
  68336. 'focus-off': function(arg) {
  68337. tooltip.hide()
  68338. }
  68339. });
  68340. that._resetTrackerCallbacks = function() {
  68341. that._resetTrackerCallbacks = that = renderer = managers = projection = controlBar = tooltip = null
  68342. }
  68343. },
  68344. _adjustSize: function(force) {
  68345. var that = this,
  68346. size = that.option('size') || {},
  68347. width = size.width >= 0 ? _Number(size.width) : that._element().width(),
  68348. height = size.height >= 0 ? _Number(size.height) : that._element().height(),
  68349. hidden = false;
  68350. if (width === 0)
  68351. if (_Number(size.width) === 0)
  68352. hidden = true;
  68353. else
  68354. width = DEFAULT_WIDTH;
  68355. if (height === 0)
  68356. if (_Number(size.height) === 0)
  68357. hidden = true;
  68358. else
  68359. height = DEFAULT_HEIGHT;
  68360. if (hidden || !that._element().is(':visible')) {
  68361. that._incidentOccured("W2001", [that.NAME]);
  68362. that._width = that._height = 0;
  68363. return false
  68364. }
  68365. var needResize = that._width !== width || that._height !== height || force;
  68366. if (needResize) {
  68367. that._width = width;
  68368. that._height = height;
  68369. that._renderer.resize(width, height);
  68370. that._projection.setSize(width, height);
  68371. that._legend.applyLayout(width, height);
  68372. that._tooltip.setSize(width, height);
  68373. that._background.applySettings({
  68374. x: 0,
  68375. y: 0,
  68376. width: width,
  68377. height: height
  68378. });
  68379. that._applyTranslate();
  68380. that._updateLoadIndicator(undefined, width, height)
  68381. }
  68382. return needResize
  68383. },
  68384. _clean: function() {
  68385. var that = this;
  68386. that._tracker.clean();
  68387. that._background.detach();
  68388. that._areasManager.clean();
  68389. that._markersManager.clean();
  68390. that._controlBar.clean();
  68391. that._legend.clean();
  68392. that._tooltip.clean()
  68393. },
  68394. _render: function() {
  68395. var that = this;
  68396. if (!that._adjustSize(true))
  68397. return;
  68398. that._tooltip.update(that._themeManager.getTooltipSettings(that.option('tooltip')));
  68399. that._tracker.setOptions(that.option('interaction') || {});
  68400. that._controlBar.setZoomPartition(that._projection.getZoomScalePartition()).setZoom(that._projection.getScaledZoom()).setOptions(that._themeManager.getControlBarSettings(that.option('controlBar')), that.option('interaction'));
  68401. that._background.applySettings(that._themeManager.getBackgroundSettings(that.option('background')));
  68402. that._background.append(that._root);
  68403. that._areasManager.render(that.option('areaSettings'));
  68404. that._markersManager.render(that.option('markerSettings'));
  68405. that._controlBar.render();
  68406. that._legend.render(that._themeManager.getLegendSettings(that.option('legend')));
  68407. that._tooltip.render();
  68408. that._tracker.render();
  68409. that._drawn()
  68410. },
  68411. _optionChanged: function(name, value) {
  68412. var that = this;
  68413. switch (name) {
  68414. case'theme':
  68415. that._themeManager.setTheme(value);
  68416. that._themeManager.patchRtlSettings(that.option('rtlEnabled'));
  68417. that._invalidate();
  68418. break;
  68419. case'click':
  68420. that._setClickCallback(value);
  68421. break;
  68422. case'centerChanged':
  68423. that._setCenterChangedCallback(value);
  68424. break;
  68425. case'zoomFactorChanged':
  68426. that._setZoomFactorChangedCallback(value);
  68427. break;
  68428. case'mapData':
  68429. that._areasManager.setData(value);
  68430. break;
  68431. case'markers':
  68432. that._markersManager.setData(value);
  68433. break;
  68434. case'bounds':
  68435. that._projection.setBounds(value);
  68436. that._invalidate();
  68437. break;
  68438. case'maxZoomFactor':
  68439. that._projection.setMaxZoom(value);
  68440. that._invalidate();
  68441. break;
  68442. case'zoomFactor':
  68443. that._updateZoomFactor(value);
  68444. break;
  68445. case'center':
  68446. that._updateCenter(value);
  68447. break;
  68448. default:
  68449. that.callBase.apply(that, arguments);
  68450. break
  68451. }
  68452. },
  68453. _getLoadIndicatorOption: function() {
  68454. return this._themeManager.getLoadIndicatorSettings(this.option('loadingIndicator'))
  68455. },
  68456. _setClickCallback: function(callback) {
  68457. this._clickCallback = _isFunction(callback) ? callback : null
  68458. },
  68459. _setCenterChangedCallback: function(callback) {
  68460. var that = this;
  68461. that._centerChangedCallback = _isFunction(callback) ? function() {
  68462. that._centerChangedCallback && callback.call(that, that._projection.getCenter())
  68463. } : null
  68464. },
  68465. _setZoomFactorChangedCallback: function(callback) {
  68466. var that = this;
  68467. that._zoomFactorChangedCallback = _isFunction(callback) ? function() {
  68468. that._zoomFactorChangedCallback && callback.call(that, that._projection.getZoom())
  68469. } : null
  68470. },
  68471. _raiseClick: function(arg) {
  68472. var that = this;
  68473. that._clickCallback && setTimeout(function() {
  68474. that._clickCallback && that._clickCallback.call(that, arg)
  68475. }, 0)
  68476. },
  68477. _raiseCenterChanged: function() {
  68478. this._centerChangedCallback && setTimeout(this._centerChangedCallback, 0)
  68479. },
  68480. _raiseZoomFactorChanged: function() {
  68481. this._zoomFactorChangedCallback && setTimeout(this._zoomFactorChangedCallback, 0)
  68482. },
  68483. _updateCenter: function(center, _noEvent) {
  68484. this._projection.snapCenter().setCenter(center);
  68485. if (this._projection.isCenterChanged()) {
  68486. this._applyTransform();
  68487. _noEvent || this._raiseCenterChanged()
  68488. }
  68489. },
  68490. _updateZoomFactor: function(zoomFactor, _noEvent) {
  68491. var that = this;
  68492. that._projection.snapZoom().setZoom(zoomFactor);
  68493. if (that._projection.isZoomChanged()) {
  68494. that._controlBar.setZoom(that._projection.getScaledZoom());
  68495. that._applyTransform(true);
  68496. _noEvent || that._raiseZoomFactorChanged()
  68497. }
  68498. },
  68499. _updateViewport: function(viewport, _noEvent) {
  68500. var that = this;
  68501. that._projection.snapCenter().snapZoom().setViewport(viewport);
  68502. that._applyTransform(that._projection.isZoomChanged());
  68503. if (that._projection.isCenterChanged())
  68504. _noEvent || that._raiseCenterChanged();
  68505. if (that._projection.isZoomChanged()) {
  68506. that._controlBar.setZoom(that._projection.getScaledZoom());
  68507. _noEvent || that._raiseZoomFactorChanged()
  68508. }
  68509. },
  68510. _resize: function() {
  68511. if (this._adjustSize())
  68512. this._applyTransform(true)
  68513. },
  68514. _applyTranslate: function() {
  68515. var transform = this._projection.getTransform();
  68516. this._areasManager.transform(transform);
  68517. this._markersManager.transform(transform)
  68518. },
  68519. _applyTransform: function(redraw, _noTrackerReset) {
  68520. _noTrackerReset || this._tracker.reset();
  68521. this._applyTranslate();
  68522. if (redraw) {
  68523. this._areasManager.redraw();
  68524. this._markersManager.redraw()
  68525. }
  68526. },
  68527. _refresh: function() {
  68528. var that = this,
  68529. callBase = that.callBase;
  68530. that._endLoading(function() {
  68531. callBase.call(that)
  68532. })
  68533. },
  68534. render: function() {
  68535. var that = this;
  68536. if (that._width === 0 && that._height === 0)
  68537. that._refresh();
  68538. else
  68539. that._resize();
  68540. return that
  68541. },
  68542. getAreas: function() {
  68543. return this._areasManager.getProxyItems()
  68544. },
  68545. getMarkers: function() {
  68546. return this._markersManager.getProxyItems()
  68547. },
  68548. clearAreaSelection: function(_noEvent) {
  68549. this._areasManager.clearSelection(_noEvent);
  68550. return this
  68551. },
  68552. clearMarkerSelection: function(_noEvent) {
  68553. this._markersManager.clearSelection(_noEvent);
  68554. return this
  68555. },
  68556. clearSelection: function(_noEvent) {
  68557. return this.clearAreaSelection(_noEvent).clearMarkerSelection(_noEvent)
  68558. },
  68559. center: function(value, _noEvent) {
  68560. if (value === undefined)
  68561. return this._projection.getCenter();
  68562. else {
  68563. this._updateCenter(value, _noEvent);
  68564. return this
  68565. }
  68566. },
  68567. zoomFactor: function(value, _noEvent) {
  68568. if (value === undefined)
  68569. return this._projection.getZoom();
  68570. else {
  68571. this._updateZoomFactor(value, _noEvent);
  68572. return this
  68573. }
  68574. },
  68575. viewport: function(value, _noEvent) {
  68576. if (value === undefined)
  68577. return this._projection.getViewport();
  68578. else {
  68579. this._updateViewport(value, _noEvent);
  68580. return this
  68581. }
  68582. },
  68583. convertCoordinates: function(x, y) {
  68584. return this._projection.fromScreenPointStrict(x, y)
  68585. },
  68586. showLoadingIndicator: function() {
  68587. this._showLoadIndicator(this._themeManager.getLoadIndicatorSettings(this.option('loadingIndicator')), {
  68588. width: this._width,
  68589. height: this._height
  68590. })
  68591. },
  68592. _factory: {
  68593. createRenderer: function(options) {
  68594. return new DX.viz.renderers.Renderer(options)
  68595. },
  68596. createTooltip: function(parameters) {
  68597. return new Tooltip(parameters)
  68598. },
  68599. createLegend: function(parameters) {
  68600. return new Legend(parameters)
  68601. }
  68602. }
  68603. });
  68604. var Tooltip = DX.viz.core.Tooltip.inherit({
  68605. ctor: function(parameters) {
  68606. var that = this;
  68607. that._container = parameters.container;
  68608. that._root = parameters.renderer.createGroup({'class': 'dxm-tooltip'});
  68609. that.callBase(null, that._root, parameters.renderer);
  68610. that._tracker = parameters.tracker;
  68611. that._enabled = false
  68612. },
  68613. dispose: function() {
  68614. var that = this;
  68615. that._container = that._root = that._tracker = null;
  68616. return that.callBase.apply(that, arguments)
  68617. },
  68618. clean: function() {
  68619. this._root.detach();
  68620. return this
  68621. },
  68622. render: function() {
  68623. this._root.append(this._container);
  68624. return this
  68625. }
  68626. });
  68627. var Legend = DX.viz.core.Legend.inherit({
  68628. ctor: function(parameters) {
  68629. var that = this;
  68630. that._container = parameters.container;
  68631. that._root = parameters.renderer.createGroup({'class': 'dxm-legend'});
  68632. that._themeManager = parameters.themeManager;
  68633. that.callBase(null, null, parameters.renderer, that._root)
  68634. },
  68635. dispose: function() {
  68636. var that = this;
  68637. that._container = that._root = that._themeManager = null;
  68638. return that.callBase.apply(that, arguments)
  68639. },
  68640. clean: function() {
  68641. this._root.detach();
  68642. return this
  68643. },
  68644. render: function(options) {
  68645. var that = this,
  68646. items = [],
  68647. i = 0,
  68648. ii = options.items ? options.items.length : 0;
  68649. for (; i < ii; ++i)
  68650. items.push(that._themeManager.getLegendItemSettings(options.items[i] || {}));
  68651. that.update(items, options);
  68652. that._root.append(that._container);
  68653. return that.applyLayout(that._size.width, that._size.height)
  68654. },
  68655. applyLayout: function(width, height) {
  68656. var that = this,
  68657. layoutOptions;
  68658. that.setSize({
  68659. width: width,
  68660. height: height
  68661. });
  68662. that.draw();
  68663. layoutOptions = that.getLayoutOptions();
  68664. if (layoutOptions) {
  68665. var left,
  68666. top;
  68667. if (layoutOptions.horizontalAlignment === 'left')
  68668. left = 0;
  68669. else if (layoutOptions.horizontalAlignment === 'center')
  68670. left = width / 2 - layoutOptions.width / 2;
  68671. else
  68672. left = width - layoutOptions.width;
  68673. if (layoutOptions.verticalAlignment === 'top')
  68674. top = 0;
  68675. else
  68676. top = height - layoutOptions.height;
  68677. that.shift(left, top)
  68678. }
  68679. return that
  68680. }
  68681. });
  68682. function projectAreaDefault(dataItem) {
  68683. return this._projection.projectArea(dataItem.coordinates)
  68684. }
  68685. function projectAreaGeoJson(dataItem) {
  68686. if (dataItem.geometry) {
  68687. var type = dataItem.geometry.type,
  68688. coordinates = dataItem.geometry.coordinates;
  68689. if (coordinates && (type === 'Polygon' || type === 'MultiPolygon')) {
  68690. type === 'MultiPolygon' && (coordinates = [].concat.apply([], coordinates));
  68691. return this._projection.projectArea(coordinates)
  68692. }
  68693. }
  68694. return []
  68695. }
  68696. function controlResetCallback() {
  68697. var projection = this._projection,
  68698. isCenterChanged,
  68699. isZoomChanged;
  68700. projection.snapCenter().snapZoom().setCenter(null).setZoom(null);
  68701. isCenterChanged = projection.isCenterChanged();
  68702. isZoomChanged = projection.isZoomChanged();
  68703. if (isCenterChanged || isZoomChanged)
  68704. this._applyTransform(isZoomChanged, true);
  68705. isCenterChanged && this._raiseCenterChanged();
  68706. isZoomChanged && this._raiseZoomFactorChanged()
  68707. }
  68708. function controlBeginMoveCallback() {
  68709. this._projection.snapCenter()
  68710. }
  68711. function controlEndMoveCallback() {
  68712. this._projection.isCenterChanged() && this._raiseCenterChanged()
  68713. }
  68714. function controlMoveCallback(dx, dy) {
  68715. this._projection.moveCenter(dx, dy);
  68716. this._applyTranslate()
  68717. }
  68718. function controlZoomCallback(zoom, x, y) {
  68719. var that = this,
  68720. keepPosition = x !== undefined && y !== undefined,
  68721. coords,
  68722. screenPosition;
  68723. if (keepPosition) {
  68724. screenPosition = _getRootOffset(that._renderer);
  68725. screenPosition = [x - screenPosition.left, y - screenPosition.top];
  68726. coords = that._projection.fromScreenPoint(screenPosition[0], screenPosition[1])
  68727. }
  68728. that._projection.snapZoom().setScaledZoom(zoom);
  68729. if (that._projection.isZoomChanged()) {
  68730. keepPosition && that._projection.snapCenter().setCenterByPoint(coords, screenPosition);
  68731. that._applyTransform(true, true);
  68732. that._raiseZoomFactorChanged();
  68733. keepPosition && that._projection.isCenterChanged() && that._raiseCenterChanged()
  68734. }
  68735. }
  68736. DX.registerComponent('dxVectorMap', DX.viz.map.Map);
  68737. DX.viz.map._internal = {};
  68738. DX.viz.map.sources = {};
  68739. DX.viz.map._tests = {};
  68740. DX.viz.map._tests.Legend = Legend;
  68741. DX.viz.map._tests.Tooltip = Tooltip
  68742. })(DevExpress, jQuery);
  68743. /*! Module viz-vectormap, file projection.js */
  68744. (function(DX, $, undefined) {
  68745. var _Number = Number,
  68746. _isFinite = isFinite,
  68747. _min = Math.min,
  68748. _max = Math.max,
  68749. _abs = Math.abs,
  68750. _tan = Math.tan,
  68751. _atan = Math.atan,
  68752. _exp = Math.exp,
  68753. _round = Math.round,
  68754. _ln = Math.log,
  68755. _pow = Math.pow,
  68756. _isArray = DX.utils.isArray,
  68757. _buildPath = DX.viz.renderers.buildPath;
  68758. var PI = Math.PI,
  68759. QUARTER_PI = PI / 4,
  68760. PI_TO_360 = PI / 360,
  68761. TWO_TO_LN2 = 2 / Math.LN2;
  68762. var DEFAULT_MIN_ZOOM = 1,
  68763. DEFAULT_MAX_ZOOM = 1 << 8;
  68764. var MERCATOR_MIN_LON = -180,
  68765. MERCATOR_MAX_LON = 180,
  68766. MERCATOR_MIN_LAT = -85.0511,
  68767. MERCATOR_MAX_LAT = 85.0511;
  68768. var mercator = {
  68769. aspectRatio: 1,
  68770. project: function(coordinates) {
  68771. var lon = coordinates[0],
  68772. lat = coordinates[1];
  68773. 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]
  68774. },
  68775. unproject: function(coordinates) {
  68776. var x = coordinates[0],
  68777. y = coordinates[1];
  68778. 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]
  68779. }
  68780. };
  68781. function createProjectUnprojectMethods(p1, p2, delta) {
  68782. var x0 = (p1[0] + p2[0]) / 2 - delta / 2,
  68783. y0 = (p1[1] + p2[1]) / 2 - delta / 2,
  68784. k = 2 / delta;
  68785. return {
  68786. project: function(coordinates) {
  68787. var p = mercator.project(coordinates);
  68788. return [-1 + (p[0] - x0) * k, -1 + (p[1] - y0) * k]
  68789. },
  68790. unproject: function(coordinates) {
  68791. var p = [x0 + (coordinates[0] + 1) / k, y0 + (coordinates[1] + 1) / k];
  68792. return mercator.unproject(p)
  68793. }
  68794. }
  68795. }
  68796. function floatsEqual(f1, f2) {
  68797. return _abs(f1 - f2) < 1E-8
  68798. }
  68799. function truncate(value, min, max, fallback) {
  68800. var _value = _Number(value);
  68801. if (_value < min)
  68802. _value = min;
  68803. else if (_value > max)
  68804. _value = max;
  68805. else if (!(min <= _value && _value <= max))
  68806. _value = fallback;
  68807. return _value
  68808. }
  68809. function truncateQuad(quad, min, max) {
  68810. return {
  68811. lt: [truncate(quad[0], min[0], max[0], min[0]), truncate(quad[1], min[1], max[1], min[1])],
  68812. rb: [truncate(quad[2], min[0], max[0], max[0]), truncate(quad[3], min[1], max[1], max[1])]
  68813. }
  68814. }
  68815. function parseBounds(bounds) {
  68816. var p1 = mercator.unproject([-1, -1]),
  68817. p2 = mercator.unproject([+1, +1]),
  68818. min = [_min(p1[0], p2[0]), _min(p1[1], p2[1])],
  68819. max = [_max(p1[0], p2[0]), _max(p1[1], p2[1])],
  68820. quad = bounds;
  68821. if (quad && quad.minLon)
  68822. quad = [quad.minLon, quad.minLat, quad.maxLon, quad.maxLat];
  68823. if (quad)
  68824. quad = truncateQuad(quad, min, max);
  68825. return {
  68826. minBase: min,
  68827. maxBase: max,
  68828. min: quad ? [_min(quad.lt[0], quad.rb[0]), _min(quad.lt[1], quad.rb[1])] : min,
  68829. max: quad ? [_max(quad.lt[0], quad.rb[0]), _max(quad.lt[1], quad.rb[1])] : max
  68830. }
  68831. }
  68832. function selectCenterValue(value1, value2, center1, center2) {
  68833. var result;
  68834. if (value1 > -1 && value2 >= +1)
  68835. result = center1;
  68836. else if (value1 <= -1 && value2 < +1)
  68837. result = center2;
  68838. else
  68839. result = (center1 + center2) / 2;
  68840. return result
  68841. }
  68842. function Projection() {
  68843. this.setBounds(null)
  68844. }
  68845. Projection.prototype = {
  68846. constructor: Projection,
  68847. _minZoom: DEFAULT_MIN_ZOOM,
  68848. _maxZoom: DEFAULT_MAX_ZOOM,
  68849. _zoom: DEFAULT_MIN_ZOOM,
  68850. setSize: function(width, height) {
  68851. var that = this;
  68852. that._x0 = width / 2;
  68853. that._y0 = height / 2;
  68854. if (width / height <= mercator.aspectRatio) {
  68855. that._xradius = width / 2;
  68856. that._yradius = width / 2 / mercator.aspectRatio
  68857. }
  68858. else {
  68859. that._xradius = height / 2 * mercator.aspectRatio;
  68860. that._yradius = height / 2
  68861. }
  68862. return that
  68863. },
  68864. setBounds: function(bounds) {
  68865. var that = this,
  68866. _bounds = parseBounds(bounds);
  68867. that._minBase = _bounds.minBase;
  68868. that._maxBase = _bounds.maxBase;
  68869. that._minBound = _bounds.min;
  68870. that._maxBound = _bounds.max;
  68871. var p1 = mercator.project(_bounds.min),
  68872. p2 = mercator.project(_bounds.max),
  68873. delta = _min(truncate(_abs(p2[0] - p1[0]), 0.1, 2, 2), truncate(_abs(p2[1] - p1[1]), 0.1, 2, 2)),
  68874. methods = delta < 2 ? createProjectUnprojectMethods(p1, p2, delta) : mercator;
  68875. that._project = methods.project;
  68876. that._unproject = methods.unproject;
  68877. var minv = that._project(_bounds.minBase),
  68878. maxv = that._project(_bounds.maxBase);
  68879. that._minv = [_min(minv[0], maxv[0]), _min(minv[1], maxv[1])];
  68880. that._maxv = [_max(minv[0], maxv[0]), _max(minv[1], maxv[1])];
  68881. that._defaultCenter = that._unproject([0, 0]);
  68882. return that.setCenter(that._defaultCenter)
  68883. },
  68884. _toScreen: function(coordinates) {
  68885. return [this._x0 + this._xradius * coordinates[0], this._y0 + this._yradius * coordinates[1]]
  68886. },
  68887. _fromScreen: function(coordinates) {
  68888. return [(coordinates[0] - this._x0) / this._xradius, (coordinates[1] - this._y0) / this._yradius]
  68889. },
  68890. _toTransformed: function(coordinates) {
  68891. return [coordinates[0] * this._zoom + this._dxcenter, coordinates[1] * this._zoom + this._dycenter, ]
  68892. },
  68893. _toTransformedFast: function(coordinates) {
  68894. return [coordinates[0] * this._zoom, coordinates[1] * this._zoom]
  68895. },
  68896. _fromTransformed: function(coordinates) {
  68897. return [(coordinates[0] - this._dxcenter) / this._zoom, (coordinates[1] - this._dycenter) / this._zoom]
  68898. },
  68899. _adjustCenter: function() {
  68900. var that = this,
  68901. center = that._project(that._center);
  68902. that._dxcenter = -center[0] * that._zoom;
  68903. that._dycenter = -center[1] * that._zoom
  68904. },
  68905. projectArea: function(coordinates) {
  68906. var i = 0,
  68907. ii = _isArray(coordinates) ? coordinates.length : 0,
  68908. subcoords,
  68909. j,
  68910. jj,
  68911. subresult,
  68912. result = [];
  68913. for (; i < ii; ++i) {
  68914. subcoords = coordinates[i];
  68915. subresult = [];
  68916. for (j = 0, jj = _isArray(subcoords) ? subcoords.length : 0; j < jj; ++j)
  68917. subresult.push(this._project(subcoords[j]));
  68918. result.push(subresult)
  68919. }
  68920. return result
  68921. },
  68922. projectPoint: function(coordinates) {
  68923. return coordinates ? this._project(coordinates) : []
  68924. },
  68925. getAreaCoordinates: function(data) {
  68926. var k = 0,
  68927. kk = data.length,
  68928. partialData,
  68929. i,
  68930. ii,
  68931. list = [],
  68932. partialPath,
  68933. point;
  68934. for (; k < kk; ++k) {
  68935. partialData = data[k];
  68936. partialPath = [];
  68937. for (i = 0, ii = partialData.length; i < ii; ++i) {
  68938. point = this._toScreen(this._toTransformedFast(partialData[i]));
  68939. partialPath.push(point[0], point[1])
  68940. }
  68941. list.push(_buildPath(partialPath))
  68942. }
  68943. return list.join(' ')
  68944. },
  68945. getPointCoordinates: function(data) {
  68946. var point = this._toScreen(this._toTransformedFast(data));
  68947. return {
  68948. x: _round(point[0]),
  68949. y: _round(point[1])
  68950. }
  68951. },
  68952. getZoom: function() {
  68953. return this._zoom
  68954. },
  68955. setZoom: function(zoom) {
  68956. var that = this;
  68957. that._zoom = truncate(zoom, that._minZoom, that._maxZoom, that._minZoom);
  68958. that._adjustCenter();
  68959. return that
  68960. },
  68961. getScaledZoom: function() {
  68962. return _round((this._scale.length - 1) * _ln(this._zoom) / _ln(this._maxZoom))
  68963. },
  68964. setScaledZoom: function(scaledZoom) {
  68965. return this.setZoom(this._scale[_round(scaledZoom)])
  68966. },
  68967. getZoomScalePartition: function() {
  68968. return this._scale.length - 1
  68969. },
  68970. _setupScaling: function() {
  68971. var that = this,
  68972. k = _round(TWO_TO_LN2 * _ln(that._maxZoom));
  68973. k = k > 4 ? k : 4;
  68974. var step = _pow(that._maxZoom, 1 / k),
  68975. zoom = that._minZoom,
  68976. i = 1;
  68977. that._scale = [zoom];
  68978. for (; i <= k; ++i)
  68979. that._scale.push(zoom *= step)
  68980. },
  68981. setMaxZoom: function(maxZoom) {
  68982. var that = this;
  68983. that._minZoom = DEFAULT_MIN_ZOOM;
  68984. that._maxZoom = truncate(maxZoom, that._minZoom, _Number.MAX_VALUE, DEFAULT_MAX_ZOOM);
  68985. that._setupScaling();
  68986. if (that._zoom > that._maxZoom)
  68987. that.setZoom(that._maxZoom);
  68988. return that
  68989. },
  68990. getMinZoom: function() {
  68991. return this._minZoom
  68992. },
  68993. getMaxZoom: function() {
  68994. return this._maxZoom
  68995. },
  68996. getCenter: function() {
  68997. return [this._center[0], this._center[1]]
  68998. },
  68999. setCenter: function(center) {
  69000. var _center = _isArray(center) ? center : null;
  69001. _center = _center || center && (center.lon || center.lat) && [center.lon, center.lat] || [];
  69002. var that = this;
  69003. 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])];
  69004. that._adjustCenter();
  69005. return that
  69006. },
  69007. setCenterByPoint: function(coordinates, screenPosition) {
  69008. var that = this,
  69009. p = that._project(coordinates),
  69010. q = that._fromScreen(screenPosition);
  69011. return that.setCenter(that._unproject([-q[0] / that._zoom + p[0], -q[1] / that._zoom + p[1]]))
  69012. },
  69013. moveCenter: function(screenDx, screenDy) {
  69014. var that = this,
  69015. current = that._toScreen(that._toTransformed(that._project(that._center))),
  69016. center = that._unproject(that._fromTransformed(that._fromScreen([current[0] + screenDx, current[1] + screenDy])));
  69017. return that.setCenter(center)
  69018. },
  69019. getViewport: function() {
  69020. var p1 = this._unproject(this._fromTransformed([-1, -1])),
  69021. p2 = this._unproject(this._fromTransformed([+1, +1]));
  69022. return [p1[0], p1[1], p2[0], p2[1]]
  69023. },
  69024. setViewport: function(viewport) {
  69025. var that = this;
  69026. if (!_isArray(viewport))
  69027. return that.setZoom(that._minZoom).setCenter(that._defaultCenter);
  69028. var _viewport = truncateQuad(viewport, that._minBase, that._maxBase),
  69029. lt = that._project(_viewport.lt),
  69030. rb = that._project(_viewport.rb),
  69031. l = _min(lt[0], rb[0]),
  69032. t = _min(lt[1], rb[1]),
  69033. r = _max(lt[0], rb[0]),
  69034. b = _max(lt[1], rb[1]),
  69035. zoom = 2 / _max(r - l, b - t),
  69036. xc = selectCenterValue(l, r, -1 - zoom * l, +1 - zoom * r),
  69037. yc = selectCenterValue(t, b, -1 - zoom * t, +1 - zoom * b);
  69038. return that.setZoom(zoom).setCenter(that._unproject([-xc / zoom, -yc / zoom]))
  69039. },
  69040. getTransform: function() {
  69041. return {
  69042. translateX: this._dxcenter * this._xradius,
  69043. translateY: this._dycenter * this._yradius
  69044. }
  69045. },
  69046. fromScreenPoint: function(x, y) {
  69047. return this._unproject(this._fromTransformed(this._fromScreen([x, y])))
  69048. },
  69049. fromScreenPointStrict: function(x, y) {
  69050. var that = this,
  69051. p = that._fromTransformed(that._fromScreen([x, y])),
  69052. q = that._unproject(p);
  69053. return [p[0] >= that._minv[0] && p[0] <= that._maxv[0] ? q[0] : NaN, p[1] >= that._minv[1] && p[1] <= that._maxv[1] ? q[1] : NaN]
  69054. },
  69055. snapCenter: function() {
  69056. this._snappedCenter = this.getCenter();
  69057. return this
  69058. },
  69059. isCenterChanged: function() {
  69060. var center = this.getCenter();
  69061. return !floatsEqual(this._snappedCenter[0], center[0]) || !floatsEqual(this._snappedCenter[1], center[1])
  69062. },
  69063. snapZoom: function() {
  69064. this._snappedZoom = this.getZoom();
  69065. return this
  69066. },
  69067. isZoomChanged: function() {
  69068. return !floatsEqual(this._snappedZoom, this.getZoom())
  69069. }
  69070. };
  69071. DX.viz.map._tests.Projection = Projection;
  69072. DX.viz.map._tests.mercator = mercator;
  69073. DX.viz.map._tests._DEBUG_stubMercator = function(stub) {
  69074. mercator = stub
  69075. };
  69076. DX.viz.map._tests._DEBUG_restoreMercator = function() {
  69077. mercator = DX.viz.map._tests.mercator
  69078. };
  69079. DX.viz.map.Map.prototype._factory.createProjection = function() {
  69080. return new Projection
  69081. }
  69082. })(DevExpress, jQuery);
  69083. /*! Module viz-vectormap, file controlBar.js */
  69084. (function(DX, undefined) {
  69085. var _buildPath = DX.viz.renderers.buildPath,
  69086. _setTimeout = setTimeout,
  69087. _clearTimeout = clearTimeout,
  69088. _round = Math.round,
  69089. _pow = Math.pow,
  69090. _ln = Math.log;
  69091. var _LN2 = Math.LN2;
  69092. var COMMAND_RESET = 'command-reset',
  69093. COMMAND_MOVE_UP = 'command-move-up',
  69094. COMMAND_MOVE_RIGHT = 'command-move-right',
  69095. COMMAND_MOVE_DOWN = 'command-move-down',
  69096. COMMAND_MOVE_LEFT = 'command-move-left',
  69097. COMMAND_ZOOM_IN = 'command-zoom-in',
  69098. COMMAND_ZOOM_OUT = 'command-zoom-out',
  69099. COMMAND_ZOOM_DRAG = 'command-zoom-drag';
  69100. var _DATA_KEY = DX.viz.map.__DATA_KEY,
  69101. EVENT_TARGET_TYPE = 'control-bar';
  69102. var COMMAND_TO_TYPE_MAP = {};
  69103. COMMAND_TO_TYPE_MAP[COMMAND_RESET] = ResetCommand;
  69104. 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;
  69105. COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_IN] = COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_OUT] = ZoomCommand;
  69106. COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_DRAG] = ZoomDragCommand;
  69107. var ControlBar = DX.Class.inherit({
  69108. ctor: function(parameters) {
  69109. var that = this;
  69110. that._container = parameters.container;
  69111. that._createElements(parameters.renderer);
  69112. var context = parameters.context,
  69113. resetCallback = parameters.resetCallback,
  69114. beginMoveCallback = parameters.beginMoveCallback,
  69115. endMoveCallback = parameters.endMoveCallback,
  69116. moveCallback = parameters.moveCallback,
  69117. zoomCallback = parameters.zoomCallback;
  69118. parameters = null;
  69119. that._reset = function() {
  69120. resetCallback.call(context)
  69121. };
  69122. that._beginMove = function() {
  69123. beginMoveCallback.call(context)
  69124. };
  69125. that._endMove = function() {
  69126. endMoveCallback.call(context)
  69127. };
  69128. that._move = function(dx, dy) {
  69129. moveCallback.call(context, dx, dy)
  69130. };
  69131. that._zoom = function(zoom, x, y) {
  69132. zoomCallback.call(context, zoom, x, y)
  69133. };
  69134. that._dispose = function() {
  69135. this._reset = this._move = this._zoom = this._dispose = context = resetCallback = moveCallback = zoomCallback = null
  69136. }
  69137. },
  69138. _createElements: function(renderer) {
  69139. var that = this;
  69140. that._root = renderer.createGroup({'class': 'dxm-control-bar'});
  69141. that._buttonsGroup = renderer.createGroup({'class': 'dxm-control-buttons'}).append(that._root);
  69142. that._trackersGroup = renderer.createGroup({
  69143. stroke: 'none',
  69144. strokeWidth: 0,
  69145. fill: '#000000',
  69146. opacity: 0.0001,
  69147. cursor: 'pointer'
  69148. }).append(that._root);
  69149. var options = {
  69150. bigCircleSize: 58,
  69151. smallCircleSize: 28,
  69152. buttonSize: 10,
  69153. arrowButtonOffset: 20,
  69154. incdecButtonSize: 11,
  69155. incButtonOffset: 66,
  69156. decButtonOffset: 227,
  69157. sliderLineStartOffset: 88.5,
  69158. sliderLineEndOffset: 205.5,
  69159. sliderLength: 20,
  69160. sliderWidth: 8,
  69161. trackerGap: 4
  69162. };
  69163. that._createButtons(renderer, options);
  69164. that._createTrackers(renderer, options);
  69165. that._root.applySettings({
  69166. translateX: 50.5,
  69167. translateY: 50.5
  69168. })
  69169. },
  69170. _createButtons: function(renderer, options) {
  69171. var group = this._buttonsGroup,
  69172. size = options.buttonSize / 2,
  69173. offset1 = options.arrowButtonOffset - size,
  69174. offset2 = options.arrowButtonOffset,
  69175. incdecButtonSize = options.incdecButtonSize / 2;
  69176. renderer.createCircle(0, 0, options.bigCircleSize / 2).append(group);
  69177. renderer.createCircle(0, 0, size).append(group);
  69178. renderer.createPath([-size, -offset1, 0, -offset2, size, -offset1]).append(group);
  69179. renderer.createPath([offset1, -size, offset2, 0, offset1, size]).append(group);
  69180. renderer.createPath([size, offset1, 0, offset2, -size, offset1]).append(group);
  69181. renderer.createPath([-offset1, size, -offset2, 0, -offset1, -size]).append(group);
  69182. renderer.createCircle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group);
  69183. renderer.createSimplePath({d: _buildPath([-incdecButtonSize, options.incButtonOffset, incdecButtonSize, options.incButtonOffset]) + ' ' + _buildPath([0, options.incButtonOffset - incdecButtonSize, 0, options.incButtonOffset + incdecButtonSize])}).append(group);
  69184. renderer.createCircle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group);
  69185. renderer.createSimplePath({d: _buildPath([-incdecButtonSize, options.decButtonOffset, incdecButtonSize, options.decButtonOffset])}).append(group);
  69186. renderer.createSimplePath({d: _buildPath([0, options.sliderLineStartOffset, 0, options.sliderLineEndOffset])}).append(group);
  69187. this._zoomDrag = renderer.createRect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).append(group);
  69188. this._sliderLineLength = options.sliderLineEndOffset - options.sliderLineStartOffset
  69189. },
  69190. _createTrackers: function(renderer, options) {
  69191. var group = this._trackersGroup,
  69192. size = _round((options.arrowButtonOffset - options.trackerGap) / 2),
  69193. offset1 = options.arrowButtonOffset - size,
  69194. offset2 = _round(_pow(options.bigCircleSize * options.bigCircleSize / 4 - size * size, 0.5)),
  69195. size2 = offset2 - offset1,
  69196. element;
  69197. renderer.createRect(-size, -size, size * 2, size * 2).append(group).data(_DATA_KEY, {
  69198. index: COMMAND_RESET,
  69199. type: EVENT_TARGET_TYPE
  69200. });
  69201. renderer.createRect(-size, -offset2, size * 2, size2).append(group).data(_DATA_KEY, {
  69202. index: COMMAND_MOVE_UP,
  69203. type: EVENT_TARGET_TYPE
  69204. });
  69205. renderer.createRect(offset1, -size, size2, size * 2).append(group).data(_DATA_KEY, {
  69206. index: COMMAND_MOVE_RIGHT,
  69207. type: EVENT_TARGET_TYPE
  69208. });
  69209. renderer.createRect(-size, offset1, size * 2, size2).append(group).data(_DATA_KEY, {
  69210. index: COMMAND_MOVE_DOWN,
  69211. type: EVENT_TARGET_TYPE
  69212. });
  69213. renderer.createRect(-offset2, -size, size2, size * 2).append(group).data(_DATA_KEY, {
  69214. index: COMMAND_MOVE_LEFT,
  69215. type: EVENT_TARGET_TYPE
  69216. });
  69217. renderer.createCircle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group).data(_DATA_KEY, {
  69218. index: COMMAND_ZOOM_IN,
  69219. type: EVENT_TARGET_TYPE
  69220. });
  69221. renderer.createCircle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group).data(_DATA_KEY, {
  69222. index: COMMAND_ZOOM_OUT,
  69223. type: EVENT_TARGET_TYPE
  69224. });
  69225. this._zoomDragCover = renderer.createRect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).append(group).data(_DATA_KEY, {
  69226. index: COMMAND_ZOOM_DRAG,
  69227. type: EVENT_TARGET_TYPE
  69228. })
  69229. },
  69230. dispose: function() {
  69231. var that = this;
  69232. delete that._container;
  69233. that._dispose();
  69234. that._root.clear();
  69235. delete that._root;
  69236. delete that._buttonsGroup;
  69237. delete that._zoomDrag;
  69238. delete that._zoomDragCover;
  69239. return that
  69240. },
  69241. setZoomPartition: function(partition) {
  69242. this._zoomPartition = partition;
  69243. this._sliderUnitLength = this._sliderLineLength / partition;
  69244. return this
  69245. },
  69246. setZoom: function(zoom) {
  69247. this._adjustZoom(zoom);
  69248. return this
  69249. },
  69250. setOptions: function(options, interactionOptions) {
  69251. options = options || {};
  69252. interactionOptions = interactionOptions || {};
  69253. this._dragAndZoomEnabled = interactionOptions.dragAndZoomEnabled !== undefined ? !!interactionOptions.dragAndZoomEnabled : true;
  69254. this._enabled = this._dragAndZoomEnabled && (options.enabled !== undefined ? !!options.enabled : true);
  69255. this._buttonsGroup.applySettings(options.shape);
  69256. return this
  69257. },
  69258. clean: function() {
  69259. this._enabled && this._root.detach();
  69260. return this
  69261. },
  69262. render: function() {
  69263. this._enabled && this._root.append(this._container);
  69264. return this
  69265. },
  69266. _adjustZoom: function(zoom) {
  69267. var that = this;
  69268. that._zoomFactor = _round(zoom);
  69269. that._zoomFactor >= 0 || (that._zoomFactor = 0);
  69270. that._zoomFactor <= that._zoomPartition || (that._zoomFactor = that._zoomPartition);
  69271. var transform = {translateY: -that._zoomFactor * that._sliderUnitLength};
  69272. that._zoomDrag.applySettings(transform);
  69273. that._zoomDragCover.applySettings(transform)
  69274. },
  69275. _applyZoom: function(x, y) {
  69276. this._zoom(this._zoomFactor, x, y)
  69277. },
  69278. processStart: function(arg) {
  69279. if (this._dragAndZoomEnabled) {
  69280. var commandType = COMMAND_TO_TYPE_MAP[arg.data];
  69281. this._command = new commandType(this, arg)
  69282. }
  69283. return this
  69284. },
  69285. processMove: function(arg) {
  69286. if (this._dragAndZoomEnabled)
  69287. this._command.update(arg);
  69288. return this
  69289. },
  69290. processEnd: function(arg) {
  69291. if (this._dragAndZoomEnabled)
  69292. this._command.finish(arg);
  69293. return this
  69294. },
  69295. processZoom: function(arg) {
  69296. var that = this,
  69297. zoomFactor;
  69298. if (that._dragAndZoomEnabled) {
  69299. if (arg.delta)
  69300. zoomFactor = arg.delta;
  69301. else if (arg.ratio)
  69302. zoomFactor = _ln(arg.ratio) / _LN2;
  69303. that._adjustZoom(that._zoomFactor + zoomFactor);
  69304. that._applyZoom(arg.x, arg.y)
  69305. }
  69306. return that
  69307. }
  69308. });
  69309. function disposeCommand(command) {
  69310. delete command._owner;
  69311. command.update = function(){};
  69312. command.finish = function(){}
  69313. }
  69314. function ResetCommand(owner, arg) {
  69315. this._owner = owner;
  69316. this._command = arg.data
  69317. }
  69318. ResetCommand.prototype.update = function(arg) {
  69319. arg.data !== this._command && disposeCommand(this)
  69320. };
  69321. ResetCommand.prototype.finish = function() {
  69322. this._owner._reset();
  69323. this._owner._adjustZoom(0);
  69324. disposeCommand(this)
  69325. };
  69326. function MoveCommand(owner, arg) {
  69327. this._command = arg.data;
  69328. var timeout = null,
  69329. interval = 100,
  69330. dx = 0,
  69331. dy = 0;
  69332. switch (this._command) {
  69333. case COMMAND_MOVE_UP:
  69334. dy = -10;
  69335. break;
  69336. case COMMAND_MOVE_RIGHT:
  69337. dx = 10;
  69338. break;
  69339. case COMMAND_MOVE_DOWN:
  69340. dy = 10;
  69341. break;
  69342. case COMMAND_MOVE_LEFT:
  69343. dx = -10;
  69344. break
  69345. }
  69346. function callback() {
  69347. owner._move(dx, dy);
  69348. timeout = _setTimeout(callback, interval)
  69349. }
  69350. this._stop = function() {
  69351. _clearTimeout(timeout);
  69352. owner._endMove();
  69353. this._stop = owner = callback = null;
  69354. return this
  69355. };
  69356. arg = null;
  69357. owner._beginMove();
  69358. callback()
  69359. }
  69360. MoveCommand.prototype.update = function(arg) {
  69361. this._command !== arg.data && this.finish()
  69362. };
  69363. MoveCommand.prototype.finish = function() {
  69364. disposeCommand(this._stop())
  69365. };
  69366. function ZoomCommand(owner, arg) {
  69367. this._owner = owner;
  69368. this._command = arg.data;
  69369. var timeout = null,
  69370. interval = 150,
  69371. dzoom = this._command === COMMAND_ZOOM_IN ? 1 : -1;
  69372. function callback() {
  69373. owner._adjustZoom(owner._zoomFactor + dzoom);
  69374. timeout = _setTimeout(callback, interval)
  69375. }
  69376. this._stop = function() {
  69377. _clearTimeout(timeout);
  69378. this._stop = owner = callback = null;
  69379. return this
  69380. };
  69381. arg = null;
  69382. callback()
  69383. }
  69384. ZoomCommand.prototype.update = function(arg) {
  69385. this._command !== arg.data && this.finish()
  69386. };
  69387. ZoomCommand.prototype.finish = function() {
  69388. this._owner._applyZoom();
  69389. disposeCommand(this._stop())
  69390. };
  69391. function ZoomDragCommand(owner, arg) {
  69392. this._owner = owner;
  69393. this._zoomFactor = owner._zoomFactor;
  69394. this._pos = arg.y
  69395. }
  69396. ZoomDragCommand.prototype.update = function(arg) {
  69397. var owner = this._owner;
  69398. owner._adjustZoom(this._zoomFactor + owner._zoomPartition * (this._pos - arg.y) / owner._sliderLineLength)
  69399. };
  69400. ZoomDragCommand.prototype.finish = function() {
  69401. this._owner._applyZoom();
  69402. disposeCommand(this)
  69403. };
  69404. DX.viz.map._tests.ControlBar = ControlBar;
  69405. DX.viz.map.Map.prototype._factory.createControlBar = function(parameters) {
  69406. return new ControlBar(parameters)
  69407. }
  69408. })(DevExpress);
  69409. /*! Module viz-vectormap, file tracker.js */
  69410. (function(DX, $, undefined) {
  69411. var _addNamespace = DX.ui.events.addNamespace,
  69412. _abs = Math.abs,
  69413. _sqrt = Math.sqrt,
  69414. _round = Math.round,
  69415. _max = Math.max,
  69416. _min = Math.min,
  69417. _now = $.now,
  69418. _extend = $.extend;
  69419. var _NAME = DX.viz.map.Map.prototype.NAME,
  69420. _DATA_KEY = DX.viz.map.__DATA_KEY;
  69421. var $doc = $(document);
  69422. var EVENTS = {};
  69423. setupEvents();
  69424. var EVENT_START = 'start',
  69425. EVENT_MOVE = 'move',
  69426. EVENT_END = 'end',
  69427. EVENT_ZOOM = 'zoom',
  69428. EVENT_HOVER_ON = 'hover-on',
  69429. EVENT_HOVER_OFF = 'hover-off',
  69430. EVENT_CLICK = 'click',
  69431. EVENT_FOCUS_ON = 'focus-on',
  69432. EVENT_FOCUS_MOVE = 'focus-move',
  69433. EVENT_FOCUS_OFF = 'focus-off';
  69434. var CLICK_TIME_THRESHOLD = 500,
  69435. CLICK_COORD_THRESHOLD = 5,
  69436. DRAG_COORD_THRESHOLD_MOUSE = 5,
  69437. DRAG_COORD_THRESHOLD_TOUCH = 10,
  69438. FOCUS_ON_DELAY_MOUSE = 300,
  69439. FOCUS_OFF_DELAY_MOUSE = 300,
  69440. FOCUS_ON_DELAY_TOUCH = 300,
  69441. FOCUS_OFF_DELAY_TOUCH = 400,
  69442. FOCUS_COORD_THRESHOLD_MOUSE = 5;
  69443. function Tracker(parameters) {
  69444. this._root = parameters.root;
  69445. this._callbacks = {};
  69446. this._createEventHandlers();
  69447. this._focus = new Focus(this._callbacks)
  69448. }
  69449. _extend(Tracker.prototype, {
  69450. dispose: function() {
  69451. var that = this;
  69452. that._focus.dispose();
  69453. that._root = that._callbacks = that._focus = that._rootClickEvents = that._$docClickEvents = that._rootZoomEvents = that._$docZoomEvents = that._rootHoverEvents = that._$docHoverEvents = that._rootFocusEvents = that._$docFocusEvents = null;
  69454. return that
  69455. },
  69456. _createEventHandlers: function() {
  69457. var that = this;
  69458. that._rootClickEvents = {};
  69459. that._rootClickEvents[EVENTS.start] = function(event) {
  69460. var isTouch = isTouchEvent(event);
  69461. if (isTouch && !that._isTouchEnabled)
  69462. return;
  69463. event.preventDefault();
  69464. var coords = getEventCoords(event);
  69465. that._clickState = {
  69466. x: coords.x,
  69467. y: coords.y,
  69468. time: _now()
  69469. }
  69470. };
  69471. that._$docClickEvents = {};
  69472. that._$docClickEvents[EVENTS.end] = function(event) {
  69473. var state = that._clickState;
  69474. if (!state)
  69475. return;
  69476. var isTouch = isTouchEvent(event);
  69477. if (isTouch && !that._isTouchEnabled)
  69478. return;
  69479. if (_now() - state.time <= CLICK_TIME_THRESHOLD) {
  69480. var coords = getEventCoords(event);
  69481. if (_abs(coords.x - state.x) <= CLICK_COORD_THRESHOLD && _abs(coords.y - state.y) <= CLICK_COORD_THRESHOLD)
  69482. that._callbacks[EVENT_CLICK]({
  69483. data: $(event.target).data(_DATA_KEY) || {},
  69484. x: coords.x,
  69485. y: coords.y,
  69486. $event: event
  69487. })
  69488. }
  69489. that._clickState = null
  69490. };
  69491. that._rootDragEvents = {};
  69492. that._rootDragEvents[EVENTS.start] = function(event) {
  69493. var isTouch = isTouchEvent(event);
  69494. if (isTouch && !that._isTouchEnabled)
  69495. return;
  69496. var coords = getEventCoords(event);
  69497. that._dragState = {
  69498. x: coords.x,
  69499. y: coords.y,
  69500. data: $(event.target).data(_DATA_KEY) || {}
  69501. };
  69502. if (that._isDragEnabled)
  69503. that._callbacks[EVENT_START]({
  69504. data: that._dragState.data,
  69505. x: coords.x,
  69506. y: coords.y
  69507. })
  69508. };
  69509. that._$docDragEvents = {};
  69510. that._$docDragEvents[EVENTS.move] = function(event) {
  69511. var state = that._dragState;
  69512. if (!state)
  69513. return;
  69514. var isTouch = isTouchEvent(event);
  69515. if (isTouch && !that._isTouchEnabled)
  69516. return;
  69517. var coords = getEventCoords(event),
  69518. threshold = isTouch ? DRAG_COORD_THRESHOLD_TOUCH : DRAG_COORD_THRESHOLD_MOUSE;
  69519. if (state.active || _abs(coords.x - state.x) > threshold || _abs(coords.y - state.y) > threshold) {
  69520. state.x = coords.x;
  69521. state.y = coords.y;
  69522. state.active = true;
  69523. state.data = $(event.target).data(_DATA_KEY) || {};
  69524. if (that._isDragEnabled)
  69525. that._callbacks[EVENT_MOVE]({
  69526. data: state.data,
  69527. x: coords.x,
  69528. y: coords.y
  69529. })
  69530. }
  69531. };
  69532. that._$docDragEvents[EVENTS.end] = function(event) {
  69533. var state = that._dragState;
  69534. if (!state)
  69535. return;
  69536. var isTouch = isTouchEvent(event);
  69537. if (isTouch && !that._isTouchEnabled)
  69538. return;
  69539. that._endDragging()
  69540. };
  69541. that._rootZoomEvents = {};
  69542. that._rootZoomEvents[EVENTS.wheel] = function(event) {
  69543. if (!that._isWheelEnabled)
  69544. return;
  69545. event.preventDefault();
  69546. if (that._zoomState)
  69547. return;
  69548. var delta = event.originalEvent.wheelDelta / 120 || event.originalEvent.detail / -3 || 0;
  69549. if (delta === 0)
  69550. return;
  69551. delta = delta > 0 ? _min(_round(delta) || +1, +4) : _max(_round(delta) || -1, -4);
  69552. var coords = getEventCoords(event);
  69553. if (that._isZoomEnabled)
  69554. that._callbacks[EVENT_ZOOM]({
  69555. delta: delta,
  69556. x: coords.x,
  69557. y: coords.y
  69558. });
  69559. that._zoomState = setTimeout(function() {
  69560. that._zoomState = null
  69561. }, 50)
  69562. };
  69563. that._rootZoomEvents[EVENTS.start] = function(event) {
  69564. var isTouch = isTouchEvent(event);
  69565. if (!isTouch || !that._isTouchEnabled)
  69566. return;
  69567. var state = that._zoomState = that._zoomState || {};
  69568. if (state.pointer1 && state.pointer2)
  69569. return;
  69570. var coords;
  69571. if (state.pointer1 === undefined) {
  69572. state.pointer1 = getPointerId(event) || 0;
  69573. coords = getMultitouchEventCoords(event, state.pointer1);
  69574. state.x1 = state.x1_0 = coords.x;
  69575. state.y1 = state.y1_0 = coords.y
  69576. }
  69577. if (state.pointer2 === undefined) {
  69578. var pointer2 = getPointerId(event) || 1;
  69579. if (pointer2 !== state.pointer1) {
  69580. coords = getMultitouchEventCoords(event, pointer2);
  69581. if (coords) {
  69582. state.x2 = state.x2_0 = coords.x;
  69583. state.y2 = state.y2_0 = coords.y;
  69584. state.pointer2 = pointer2;
  69585. state.ready = true;
  69586. that._endDragging()
  69587. }
  69588. }
  69589. }
  69590. };
  69591. that._$docZoomEvents = {};
  69592. that._$docZoomEvents[EVENTS.move] = function(event) {
  69593. var state = that._zoomState;
  69594. if (!state)
  69595. return;
  69596. var isTouch = isTouchEvent(event);
  69597. if (!isTouch || !that._isTouchEnabled)
  69598. return;
  69599. var coords;
  69600. if (state.pointer1 !== undefined) {
  69601. coords = getMultitouchEventCoords(event, state.pointer1);
  69602. if (coords) {
  69603. state.x1 = coords.x;
  69604. state.y1 = coords.y
  69605. }
  69606. }
  69607. if (state.pointer2 !== undefined) {
  69608. coords = getMultitouchEventCoords(event, state.pointer2);
  69609. if (coords) {
  69610. state.x2 = coords.x;
  69611. state.y2 = coords.y
  69612. }
  69613. }
  69614. };
  69615. that._$docZoomEvents[EVENTS.end] = function(event) {
  69616. var state = that._zoomState;
  69617. if (!state)
  69618. return;
  69619. var isTouch = isTouchEvent(event);
  69620. if (!isTouch || !that._isTouchEnabled)
  69621. return;
  69622. if (state.ready) {
  69623. var startDistance = getDistance(state.x1_0, state.y1_0, state.x2_0, state.y2_0),
  69624. currentDistance = getDistance(state.x1, state.y1, state.x2, state.y2);
  69625. if (that._isZoomEnabled)
  69626. that._callbacks[EVENT_ZOOM]({
  69627. ratio: currentDistance / startDistance,
  69628. x: (state.x1_0 + state.x2_0) / 2,
  69629. y: (state.y1_0 + state.y2_0) / 2
  69630. })
  69631. }
  69632. that._zoomState = null
  69633. };
  69634. that._rootHoverEvents = {};
  69635. that._rootHoverEvents[EVENTS.over] = function(event) {
  69636. if (that._hoverTarget === event.target)
  69637. return;
  69638. var isTouch = isTouchEvent(event);
  69639. if (isTouch)
  69640. return;
  69641. var data = $(event.target).data(_DATA_KEY);
  69642. if (!data)
  69643. return;
  69644. that._hoverTarget && that._endHovering();
  69645. that._hoverTarget = event.target;
  69646. that._hoverState = {data: data};
  69647. that._callbacks[EVENT_HOVER_ON]({data: data})
  69648. };
  69649. that._$docHoverEvents = {};
  69650. that._$docHoverEvents[EVENTS.out] = function(event) {
  69651. var state = that._hoverState;
  69652. if (!state)
  69653. return;
  69654. var isTouch = isTouchEvent(event);
  69655. if (isTouch)
  69656. return;
  69657. var data = $(event.target).data(_DATA_KEY);
  69658. if (!data)
  69659. return;
  69660. that._endHovering()
  69661. };
  69662. that._rootFocusEvents = {};
  69663. that._rootFocusEvents[EVENTS.start] = function(event) {
  69664. var isTouch = isTouchEvent(event);
  69665. if (!isTouch || !that._isTouchEnabled)
  69666. return;
  69667. var data = $(event.target).data(_DATA_KEY);
  69668. if (!data)
  69669. return;
  69670. that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
  69671. that._focus.turnOn(event.target, data, getEventCoords(event), FOCUS_ON_DELAY_TOUCH);
  69672. that._skip$docEvent = true
  69673. };
  69674. that._rootFocusEvents[EVENTS.over] = function(event) {
  69675. if (that._focusTarget === event.target)
  69676. return;
  69677. that._focusTarget = event.target;
  69678. var isTouch = isTouchEvent(event);
  69679. if (isTouch)
  69680. return;
  69681. var data = $(event.target).data(_DATA_KEY);
  69682. if (!data)
  69683. return;
  69684. if (that._focusTarget)
  69685. that._focus.turnOff(FOCUS_OFF_DELAY_MOUSE);
  69686. var coords = getEventCoords(event);
  69687. if (that._focus.active)
  69688. that._focus.move(event.target, data, coords);
  69689. else
  69690. that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE)
  69691. };
  69692. that._$docFocusEvents = {};
  69693. that._$docFocusEvents[EVENTS.start] = function(event) {
  69694. that._focusTarget = event.target;
  69695. var isTouch = isTouchEvent(event);
  69696. if (!isTouch || !that._isTouchEnabled)
  69697. return;
  69698. if (!that._skip$docEvent)
  69699. that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
  69700. that._skip$docEvent = null
  69701. };
  69702. that._$docFocusEvents[EVENTS.move] = function(event) {
  69703. if (that._focus.disabled)
  69704. return;
  69705. if (that._focusTarget !== event.target)
  69706. return;
  69707. var isTouch = isTouchEvent(event);
  69708. if (isTouch && !that._isTouchEnabled)
  69709. return;
  69710. var data = $(event.target).data(_DATA_KEY);
  69711. if (!data)
  69712. return;
  69713. var coords = getEventCoords(event);
  69714. if (isTouch) {
  69715. if (that._dragState && that._dragState.active || that._zoomState && that._zoomState.ready)
  69716. that._focus.cancel()
  69717. }
  69718. else if (that._focus.active)
  69719. if (that._dragState && that._dragState.active) {
  69720. that._focus.cancel();
  69721. that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE * 4)
  69722. }
  69723. else
  69724. that._focus.move(event.target, data, coords);
  69725. else if (_abs(coords.x - that._focus.x) > FOCUS_COORD_THRESHOLD_MOUSE || _abs(coords.y - that._focus.y) > FOCUS_COORD_THRESHOLD_MOUSE)
  69726. that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE)
  69727. };
  69728. that._$docFocusEvents[EVENTS.end] = function(event) {
  69729. if (that._focus.disabled)
  69730. return;
  69731. var isTouch = isTouchEvent(event);
  69732. if (!isTouch || !that._isTouchEnabled)
  69733. return;
  69734. that._focusTarget = null;
  69735. if (!that._focus.active)
  69736. that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
  69737. else if (that._focus.changing)
  69738. that._focus.cancel()
  69739. };
  69740. that._$docFocusEvents[EVENTS.out] = function(event) {
  69741. if (that._focus.disabled)
  69742. return;
  69743. var isTouch = isTouchEvent(event);
  69744. if (isTouch)
  69745. return;
  69746. that._focusTarget = null;
  69747. var data = $(event.target).data(_DATA_KEY);
  69748. if (!data)
  69749. return;
  69750. that._focus.turnOff(FOCUS_OFF_DELAY_MOUSE)
  69751. }
  69752. },
  69753. _endDragging: function() {
  69754. var that = this,
  69755. state = that._dragState;
  69756. that._dragState = null;
  69757. if (state && that._isDragEnabled)
  69758. that._callbacks[EVENT_END]({
  69759. data: state.data,
  69760. x: state.x,
  69761. y: state.y
  69762. })
  69763. },
  69764. _endHovering: function() {
  69765. var that = this,
  69766. state = that._hoverState;
  69767. that._hoverState = that._hoverTarget = null;
  69768. if (state)
  69769. that._callbacks[EVENT_HOVER_OFF]({data: state.data})
  69770. },
  69771. reset: function() {
  69772. var that = this;
  69773. that._clickState = null;
  69774. that._endDragging();
  69775. that._endHovering();
  69776. that._focus.cancel();
  69777. that._focusTarget = null;
  69778. return that
  69779. },
  69780. setCallbacks: function(callbacks) {
  69781. _extend(this._callbacks, callbacks);
  69782. return this
  69783. },
  69784. setOptions: function(options) {
  69785. this._isTouchEnabled = options.touchEnabled === undefined || !!options.touchEnabled;
  69786. this._isWheelEnabled = options.wheelEnabled === undefined || !!options.wheelEnabled;
  69787. this._isDragEnabled = options.dragAndZoomEnabled === undefined || !!options.dragAndZoomEnabled;
  69788. this._isZoomEnabled = options.dragAndZoomEnabled === undefined || !!options.dragAndZoomEnabled;
  69789. return this
  69790. },
  69791. clean: function() {
  69792. var that = this;
  69793. if (that._isTouchEnabled) {
  69794. that._root.applySettings({style: {
  69795. 'touch-action': '',
  69796. '-ms-touch-action': '',
  69797. '-webkit-user-select': ''
  69798. }});
  69799. that._root.off(_addNamespace('MSHoldVisual', _NAME)).off(_addNamespace('contextmenu', _NAME))
  69800. }
  69801. that._detachEventHandlers();
  69802. that.reset();
  69803. return that
  69804. },
  69805. render: function() {
  69806. var that = this;
  69807. if (that._isTouchEnabled) {
  69808. that._root.applySettings({style: {
  69809. 'touch-action': 'none',
  69810. '-ms-touch-action': 'none',
  69811. '-webkit-user-select': 'none'
  69812. }});
  69813. that._root.on(_addNamespace('MSHoldVisual', _NAME), function(event) {
  69814. event.preventDefault()
  69815. }).on(_addNamespace('contextmenu', _NAME), function(event) {
  69816. isTouchEvent(event) && event.preventDefault()
  69817. })
  69818. }
  69819. that._attachEventHandlers();
  69820. return that
  69821. },
  69822. _attachEventHandlers: function() {
  69823. var that = this;
  69824. that._root.on(that._rootClickEvents).on(that._rootDragEvents).on(that._rootZoomEvents).on(that._rootHoverEvents).on(that._rootFocusEvents);
  69825. $doc.on(that._$docClickEvents).on(that._$docDragEvents).on(that._$docZoomEvents).on(that._$docHoverEvents).on(that._$docFocusEvents)
  69826. },
  69827. _detachEventHandlers: function() {
  69828. var that = this;
  69829. that._root.off(that._rootClickEvents).off(that._rootDragEvents).off(that._rootZoomEvents).off(that._rootHoverEvents).off(that._rootFocusEvents);
  69830. $doc.off(that._$docClickEvents).off(that._$docDragEvents).off(that._$docZoomEvents).off(that._$docHoverEvents).off(that._$docFocusEvents)
  69831. }
  69832. });
  69833. function Focus(callbacks) {
  69834. this._callbacks = callbacks;
  69835. this.disabled = true
  69836. }
  69837. _extend(Focus.prototype, {
  69838. dispose: function() {
  69839. var that = this;
  69840. clearTimeout(that._onTimer);
  69841. clearTimeout(that._offTimer);
  69842. that._callbacks = that._onTimer = that._offTimer = that.active = that._data = null
  69843. },
  69844. _createCallback: function(target, data, coords) {
  69845. var that = this;
  69846. return function() {
  69847. if (that.active === target) {
  69848. that._callbacks[EVENT_FOCUS_MOVE]({
  69849. data: that._data,
  69850. x: coords.x,
  69851. y: coords.y
  69852. });
  69853. onCheck(true)
  69854. }
  69855. else
  69856. that._callbacks[EVENT_FOCUS_ON]({
  69857. data: data,
  69858. x: coords.x,
  69859. y: coords.y
  69860. }, onCheck)
  69861. };
  69862. function onCheck(result) {
  69863. that.changing = null;
  69864. that.disabled = !result;
  69865. if (result) {
  69866. that._data = data;
  69867. that.active = target;
  69868. clearTimeout(that._offTimer);
  69869. that._offTimer = null
  69870. }
  69871. }
  69872. },
  69873. turnOn: function(target, data, coords, timeout) {
  69874. var that = this;
  69875. that.disabled = false;
  69876. that.x = coords.x;
  69877. that.y = coords.y;
  69878. clearTimeout(that._onTimer);
  69879. that.changing = true;
  69880. that._onTimer = setTimeout(that._createCallback(target, data, coords), timeout)
  69881. },
  69882. move: function(target, data, coords) {
  69883. this.x = coords.x;
  69884. this.y = coords.y;
  69885. this._createCallback(target, data, coords)()
  69886. },
  69887. turnOff: function(timeout) {
  69888. var that = this;
  69889. if (that.active)
  69890. that._offTimer = that._offTimer || setTimeout(function() {
  69891. that._offTimer = null;
  69892. that._callbacks[EVENT_FOCUS_OFF]({data: that._data});
  69893. that._data = that.active = null;
  69894. that.disabled = true
  69895. }, timeout);
  69896. else {
  69897. clearTimeout(that._onTimer);
  69898. that._onTimer = null;
  69899. that.disabled = true
  69900. }
  69901. },
  69902. cancel: function() {
  69903. var that = this;
  69904. if (that.active)
  69905. that._callbacks[EVENT_FOCUS_OFF]({data: that._data});
  69906. clearTimeout(that._onTimer);
  69907. clearTimeout(that._offTimer);
  69908. that._data = that.active = that._onTimer = that._offTimer = null;
  69909. that.disabled = true
  69910. }
  69911. });
  69912. DX.viz.map._tests.Tracker = Tracker;
  69913. DX.viz.map._tests._DEBUG_forceEventMode = function(mode) {
  69914. setupEvents(mode)
  69915. };
  69916. DX.viz.map._tests.Focus = Focus;
  69917. DX.viz.map._tests._DEBUG_stubFocusType = function(focusType) {
  69918. Focus = focusType
  69919. };
  69920. DX.viz.map._tests._DEBUG_restoreFocusType = function() {
  69921. Focus = DX.viz.map._tests.Focus
  69922. };
  69923. DX.viz.map.Map.prototype._factory.createTracker = function(parameters) {
  69924. return new Tracker(parameters)
  69925. };
  69926. function getDistance(x1, y1, x2, y2) {
  69927. return _sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
  69928. }
  69929. function isTouchEvent(event) {
  69930. var type = event.originalEvent.type,
  69931. pointerType = event.originalEvent.pointerType;
  69932. return /^touch/.test(type) || /^MSPointer/.test(type) && pointerType !== 4 || /^pointer/.test(type) && pointerType !== 'mouse'
  69933. }
  69934. function selectItem(flags, items) {
  69935. var i = 0,
  69936. ii = flags.length,
  69937. item;
  69938. for (; i < ii; ++i)
  69939. if (flags[i]) {
  69940. item = items[i];
  69941. break
  69942. }
  69943. return _addNamespace(item || items[i], _NAME)
  69944. }
  69945. function setupEvents() {
  69946. var flags = [navigator.pointerEnabled, navigator.msPointerEnabled, 'ontouchstart' in window];
  69947. if (arguments.length)
  69948. flags = [arguments[0] === 'pointer', arguments[0] === 'MSPointer', arguments[0] === 'touch'];
  69949. EVENTS = {
  69950. start: selectItem(flags, ['pointerdown', 'MSPointerDown', 'touchstart mousedown', 'mousedown']),
  69951. move: selectItem(flags, ['pointermove', 'MSPointerMove', 'touchmove mousemove', 'mousemove']),
  69952. end: selectItem(flags, ['pointerup', 'MSPointerUp', 'touchend mouseup', 'mouseup']),
  69953. over: selectItem(flags, ['pointerover', 'MSPointerOver', 'mouseover', 'mouseover']),
  69954. out: selectItem(flags, ['pointerout', 'MSPointerOut', 'mouseout', 'mouseout']),
  69955. wheel: selectItem([], ['mousewheel DOMMouseScroll'])
  69956. }
  69957. }
  69958. function getEventCoords(event) {
  69959. var originalEvent = event.originalEvent,
  69960. touch = originalEvent.touches && originalEvent.touches[0] || {};
  69961. return {
  69962. x: touch.pageX || originalEvent.pageX || event.pageX,
  69963. y: touch.pageY || originalEvent.pageY || event.pageY
  69964. }
  69965. }
  69966. function getPointerId(event) {
  69967. return event.originalEvent.pointerId
  69968. }
  69969. function getMultitouchEventCoords(event, pointerId) {
  69970. var originalEvent = event.originalEvent;
  69971. if (originalEvent.pointerId !== undefined)
  69972. originalEvent = originalEvent.pointerId === pointerId ? originalEvent : null;
  69973. else
  69974. originalEvent = originalEvent.touches[pointerId];
  69975. return originalEvent ? {
  69976. x: originalEvent.pageX || event.pageX,
  69977. y: originalEvent.pageY || event.pageY
  69978. } : null
  69979. }
  69980. })(DevExpress, jQuery);
  69981. /*! Module viz-vectormap, file themeManager.js */
  69982. (function(DX, $, undefined) {
  69983. var _Number = Number,
  69984. _extend = $.extend,
  69985. _each = $.each;
  69986. var ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  69987. _themeSection: 'map',
  69988. _initializeTheme: function() {
  69989. var that = this;
  69990. that._initializeFont(that._theme.marker.font);
  69991. that._initializeFont(that._theme.tooltip.font);
  69992. that._initializeFont(that._theme.legend.font);
  69993. that._initializeFont(that._theme.loadingIndicator.font)
  69994. },
  69995. dispose: function() {
  69996. var that = this;
  69997. that.callBase.apply(that, arguments);
  69998. that._areasPalette = that._markersPalette = null;
  69999. return that
  70000. },
  70001. getBackgroundSettings: function(options) {
  70002. var theme = this._theme.background,
  70003. merged = _extend({}, theme, options);
  70004. return {
  70005. strokeWidth: merged.borderWidth,
  70006. stroke: merged.borderColor,
  70007. fill: merged.color
  70008. }
  70009. },
  70010. getCommonAreaSettings: function(options) {
  70011. var settings = _extend({}, this._theme.area, options);
  70012. this._areasPalette = new DX.viz.core.GradientPalette(settings.palette, settings.paletteSize);
  70013. this._DEBUG_areasPalette = this._areasPalette;
  70014. return settings
  70015. },
  70016. getAreaSettings: function(commonSettings, options) {
  70017. options = options || {};
  70018. var settings = _extend({}, commonSettings, options);
  70019. settings.borderWidth = _Number(settings.borderWidth) || 0;
  70020. settings.borderColor = settings.borderColor || null;
  70021. if (options.color === undefined && options.paletteIndex >= 0)
  70022. settings.color = this._areasPalette.getColor(options.paletteIndex);
  70023. settings.color = settings.color || null;
  70024. settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
  70025. settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
  70026. settings.hoveredColor = settings.hoveredColor || settings.color;
  70027. settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
  70028. settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
  70029. settings.selectedColor = settings.selectedColor || settings.color;
  70030. return settings
  70031. },
  70032. getCommonMarkerSettings: function(options) {
  70033. options = options || {};
  70034. var theme = this._theme.marker,
  70035. allSettings = {};
  70036. _each(theme, function(name) {
  70037. if (name[0] === '_') {
  70038. var partialTheme = theme[name] || {},
  70039. partialOptions = options[name] || {},
  70040. settings = _extend({}, theme, partialTheme, options, partialOptions);
  70041. settings.font = _extend({}, theme.font, partialTheme.font, options.font, partialOptions.font);
  70042. allSettings[name.substr(1)] = settings
  70043. }
  70044. });
  70045. this._markersPalette = new DX.viz.core.Palette(options.palette || theme.palette, {
  70046. stepHighlight: 50,
  70047. theme: this.themeName()
  70048. });
  70049. this._DEBUG_markersPalette = this._markersPalette;
  70050. return allSettings
  70051. },
  70052. getMarkerSettings: function(commonSettings, options, type) {
  70053. options = options || {};
  70054. var common = commonSettings[type],
  70055. settings = _extend({}, common, options);
  70056. settings.font = _extend({}, common.font, options.font);
  70057. settings.borderWidth = _Number(settings.borderWidth) || 0;
  70058. settings.borderColor = settings.borderColor || null;
  70059. settings.color = settings.color || null;
  70060. settings.opacity = settings.opacity || null;
  70061. settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
  70062. settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
  70063. settings.hoveredColor = settings.hoveredColor || settings.color;
  70064. settings.hoveredOpacity = settings.hoveredOpacity || settings.opacity;
  70065. settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
  70066. settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
  70067. settings.selectedColor = settings.selectedColor || settings.color;
  70068. settings.selectedOpacity = settings.selectedOpacity || settings.opacity;
  70069. return settings
  70070. },
  70071. getMarkerColors: function(count) {
  70072. var i = 0,
  70073. colors = [];
  70074. for (; i < count; ++i)
  70075. colors.push(this._markersPalette.getNextColor());
  70076. this._markersPalette.reset();
  70077. return colors
  70078. },
  70079. getControlBarSettings: function(options) {
  70080. var theme = this._theme.controlBar,
  70081. merged = _extend({}, theme, options);
  70082. return _extend({}, options, {shape: {
  70083. strokeWidth: merged.borderWidth,
  70084. stroke: merged.borderColor,
  70085. fill: merged.color
  70086. }})
  70087. },
  70088. getLoadIndicatorSettings: function(options) {
  70089. var theme = this._theme.loadingIndicator;
  70090. return _extend(true, {}, theme, options)
  70091. },
  70092. getTooltipSettings: function(options) {
  70093. var theme = this._theme.tooltip,
  70094. merged = _extend({}, theme, options),
  70095. borderOptions = _extend({}, theme.border, options && options.border, options && !options.border && {color: options.borderColor});
  70096. return _extend({}, options, {
  70097. color: merged.color,
  70098. border: borderOptions,
  70099. text: {
  70100. strokeWidth: 0,
  70101. stroke: 'none',
  70102. fill: 'none',
  70103. font: _extend({}, theme.font, merged.font),
  70104. 'class': 'dxm-tooltip-text'
  70105. },
  70106. arrowLength: merged.arrowLength,
  70107. paddingLeftRight: merged.paddingLeftRight,
  70108. paddingTopBottom: merged.paddingTopBottom,
  70109. opacity: merged.opacity,
  70110. shadow: _extend({}, theme.shadow, merged.shadow)
  70111. })
  70112. },
  70113. getLegendSettings: function(options) {
  70114. return _extend(true, {}, this._theme.legend, options)
  70115. },
  70116. getLegendItemSettings: function(item) {
  70117. var color = item.color;
  70118. if (color === undefined && item.paletteIndex >= 0)
  70119. color = this._areasPalette.getColor(item.paletteIndex);
  70120. return {
  70121. text: item.text,
  70122. color: color
  70123. }
  70124. },
  70125. patchRtlSettings: function(rtlEnabledOption) {
  70126. var theme = this._theme;
  70127. if (rtlEnabledOption || theme.rtlEnabled && rtlEnabledOption !== false)
  70128. $.extend(true, theme, theme._rtl)
  70129. }
  70130. });
  70131. DX.viz.map._tests.ThemeManager = ThemeManager;
  70132. DX.viz.map.Map.prototype._factory.createThemeManager = function() {
  70133. return new ThemeManager
  70134. }
  70135. })(DevExpress, jQuery);
  70136. /*! Module viz-vectormap, file mapItemsManager.js */
  70137. (function(DX, $, undefined) {
  70138. var _String = String,
  70139. _isString = DX.utils.isString,
  70140. _isArray = DX.utils.isArray,
  70141. _isFunction = DX.utils.isFunction,
  70142. _extend = $.extend,
  70143. _each = $.each,
  70144. _map = $.map;
  70145. var SELECTION_MODE_NONE = 'none',
  70146. SELECTION_MODE_SINGLE = 'single',
  70147. SELECTION_MODE_MULTIPLE = 'multiple';
  70148. var MapItemsManager = DX.Class.inherit({
  70149. _rootClass: null,
  70150. ctor: function(parameters) {
  70151. var that = this;
  70152. that._container = parameters.container;
  70153. that._renderer = parameters.renderer;
  70154. that._projection = parameters.projection;
  70155. that._themeManager = parameters.themeManager;
  70156. that._tracker = parameters.tracker;
  70157. that._ready = parameters.ready;
  70158. that._root = that._renderer.createGroup({'class': that._rootClass});
  70159. that._items = [];
  70160. that._context = {
  70161. renderer: that._renderer,
  70162. root: that._root,
  70163. projection: that._projection,
  70164. selectItem: function(index, state, noCallback) {
  70165. that.selectItem(index, state, noCallback)
  70166. }
  70167. }
  70168. },
  70169. dispose: function() {
  70170. var that = this;
  70171. that._container = that._renderer = that._projection = that._themeManager = that._tracker = that._ready = that._root = that._source = that._context = null;
  70172. return that
  70173. },
  70174. clean: function() {
  70175. var that = this;
  70176. that._rendered = false;
  70177. that._root.detach();
  70178. that._customizeCallback = that._clickCallback = that._selectionChangedCallback = null;
  70179. that._destroyItems();
  70180. return that
  70181. },
  70182. render: function(options) {
  70183. options = options || {};
  70184. var that = this;
  70185. that._rendered = true;
  70186. that._customizeCallback = _isFunction(options.customize) ? options.customize : null;
  70187. that._clickCallback = _isFunction(options.click) ? options.click : null;
  70188. that._selectionChangedCallback = _isFunction(options.selectionChanged) ? options.selectionChanged : null;
  70189. that._hoverEnabled = 'hoverEnabled' in options ? !!options.hoverEnabled : true;
  70190. var selectionMode = _String(options.selectionMode).toLowerCase();
  70191. that._selectionMode = selectionMode === SELECTION_MODE_NONE || selectionMode === SELECTION_MODE_SINGLE || selectionMode === SELECTION_MODE_MULTIPLE ? selectionMode : SELECTION_MODE_SINGLE;
  70192. that._root.append(that._container);
  70193. if (that._source !== null)
  70194. that._createItems();
  70195. return that
  70196. },
  70197. _destroyItems: function() {
  70198. var that = this;
  70199. that._root.clear();
  70200. _each(that._items, function(_, item) {
  70201. item.clean().dispose()
  70202. });
  70203. that._items = [];
  70204. that._selectedItems = null
  70205. },
  70206. _getItemSettings: null,
  70207. _createItem: null,
  70208. _isItemSelected: null,
  70209. _arrangeItems: null,
  70210. _createItems: function() {
  70211. var that = this;
  70212. that._selectedItems = that._selectionMode === SELECTION_MODE_MULTIPLE ? {} : null;
  70213. var selectedList = [];
  70214. _each(_isArray(that._source) ? that._source : [], function(i, dataItem) {
  70215. dataItem = dataItem || {};
  70216. var settings = that._customizeCallback && that._customizeCallback.call(dataItem, dataItem) || {};
  70217. var source = {
  70218. item: dataItem,
  70219. coords: that._getItemCoordinates(dataItem),
  70220. attrs: that._getItemAttributes(dataItem)
  70221. };
  70222. settings = that._getItemSettings(source, settings);
  70223. var item = that._createItem(settings);
  70224. item.init(that._context, source, i).render(settings).locate();
  70225. that._items.push(item);
  70226. if (that._isItemSelected(source, settings))
  70227. selectedList.push(i)
  70228. });
  70229. if (that._selectionMode !== SELECTION_MODE_NONE && selectedList.length > 0) {
  70230. if (that._selectionMode === SELECTION_MODE_SINGLE)
  70231. selectedList = [selectedList[selectedList.length - 1]];
  70232. _each(selectedList, function(_, index) {
  70233. that.selectItem(index, true, true)
  70234. })
  70235. }
  70236. that._arrangeItems();
  70237. that._ready && that._ready()
  70238. },
  70239. _processSource: null,
  70240. setData: function(data) {
  70241. var that = this;
  70242. that._source = null;
  70243. if (_isString(data))
  70244. $.getJSON(data).done(updateSource).fail(function(_0, _1, error) {
  70245. updateSource(null)
  70246. });
  70247. else
  70248. updateSource(data);
  70249. return that;
  70250. function updateSource(source) {
  70251. that._source = that._processSource(source) || 0;
  70252. if (that._rendered) {
  70253. that._tracker.reset();
  70254. that._destroyItems();
  70255. that._createItems()
  70256. }
  70257. }
  70258. },
  70259. transform: function(transform) {
  70260. this._root.applySettings(transform);
  70261. return this
  70262. },
  70263. redraw: function() {
  70264. _each(this._items, function(_, item) {
  70265. item.locate()
  70266. });
  70267. return this
  70268. },
  70269. hoverItem: function(index, state) {
  70270. if (this._hoverEnabled)
  70271. this._items[index].setHovered(!!state);
  70272. return this
  70273. },
  70274. _raiseSelectionChanged: function(item) {
  70275. var that = this;
  70276. if (that._selectionChangedCallback)
  70277. setTimeout(function() {
  70278. that._selectionChangedCallback && that._selectionChangedCallback.call(item.proxy, item.proxy)
  70279. }, 0)
  70280. },
  70281. selectItem: function(index, state, noCallback) {
  70282. var that = this;
  70283. if (that._selectionMode === SELECTION_MODE_NONE)
  70284. return that;
  70285. var item = that._items[index],
  70286. previous = item.selected;
  70287. item.setSelected(!!state);
  70288. if (item.selected === previous)
  70289. return that;
  70290. if (!noCallback)
  70291. that._raiseSelectionChanged(item);
  70292. if (item.selected && that._selectionMode === SELECTION_MODE_SINGLE && that._selectedItems) {
  70293. that._selectedItems.setSelected(false);
  70294. if (!noCallback)
  70295. that._raiseSelectionChanged(that._selectedItems);
  70296. that._selectedItems = null
  70297. }
  70298. if (that._selectionMode === SELECTION_MODE_SINGLE)
  70299. that._selectedItems = item.selected ? item : null;
  70300. else if (item.selected)
  70301. that._selectedItems[index] = item;
  70302. else
  70303. delete that._selectedItems[index];
  70304. return that
  70305. },
  70306. clearSelection: function() {
  70307. var that = this;
  70308. if (that._selectionMode === SELECTION_MODE_NONE)
  70309. return that;
  70310. if (that._selectionMode === SELECTION_MODE_SINGLE) {
  70311. if (that._selectedItems) {
  70312. that._selectedItems.setSelected(false);
  70313. that._raiseSelectionChanged(that._selectedItems);
  70314. that._selectedItems = null
  70315. }
  70316. }
  70317. else
  70318. _each(that._selectedItems, function(i, item) {
  70319. item.setSelected(false);
  70320. that._raiseSelectionChanged(item);
  70321. delete that._selectedItems[i]
  70322. });
  70323. return that
  70324. },
  70325. raiseClick: function(index, $event) {
  70326. var that = this,
  70327. item = that._items[index];
  70328. if (that._clickCallback)
  70329. setTimeout(function() {
  70330. that._clickCallback && that._clickCallback.call(item.proxy, item.proxy, $event)
  70331. }, 0);
  70332. return that
  70333. },
  70334. getProxyItems: function() {
  70335. return _map(this._items, function(item) {
  70336. return item.proxy
  70337. })
  70338. },
  70339. getProxyItem: function(index) {
  70340. return this._items[index].proxy
  70341. }
  70342. });
  70343. DX.viz.map._internal.mapItemBehavior = {
  70344. init: function(ctx, src, index) {
  70345. var that = this;
  70346. that._ctx = ctx;
  70347. that._src = src;
  70348. that._coords = that._project(ctx.projection, src.coords);
  70349. that._data = {
  70350. index: index,
  70351. type: that._type
  70352. };
  70353. that.hovered = that.selected = false;
  70354. that.proxy = createProxy(that, src.attrs, ctx.selectItem);
  70355. that.proxy.type = that._type;
  70356. that._init();
  70357. return that
  70358. },
  70359. dispose: function() {
  70360. disposeItem(this.proxy);
  70361. disposeItem(this);
  70362. return this
  70363. },
  70364. locate: function() {
  70365. var that = this;
  70366. that._locate(that._transform(that._ctx.projection, that._coords));
  70367. return that
  70368. },
  70369. clean: function() {
  70370. this._root.detach();
  70371. return this
  70372. },
  70373. render: function(settings) {
  70374. var that = this;
  70375. that._root = that._createRoot().append(that._ctx.root);
  70376. that._render(settings);
  70377. return that
  70378. },
  70379. setHovered: function(state) {
  70380. var that = this;
  70381. that.hovered = !!state;
  70382. that._onHover();
  70383. if (!that.selected)
  70384. if (that.hovered)
  70385. that._setHoveredState();
  70386. else
  70387. that._setDefaultState();
  70388. return that
  70389. },
  70390. setSelected: function(state) {
  70391. var that = this;
  70392. that.selected = !!state;
  70393. if (that.selected)
  70394. that._setSelectedState();
  70395. else
  70396. that.setHovered(that.hovered);
  70397. return that
  70398. }
  70399. };
  70400. function createProxy(item, attributes, selectItem) {
  70401. attributes = attributes || {};
  70402. return {
  70403. attribute: function(name) {
  70404. return name !== undefined ? attributes[name] : _extend({}, attributes)
  70405. },
  70406. selected: function(state, _noEvent) {
  70407. if (state !== undefined) {
  70408. if (item.selected !== !!state)
  70409. selectItem(item._data.index, !!state, _noEvent);
  70410. return this
  70411. }
  70412. else
  70413. return item.selected
  70414. }
  70415. }
  70416. }
  70417. function disposeItem(item) {
  70418. _each(item, function(name) {
  70419. item[name] = null
  70420. })
  70421. }
  70422. DX.viz.map._tests.MapItemsManager = MapItemsManager;
  70423. DX.viz.map.Map.prototype._factory.MapItemsManager = MapItemsManager
  70424. })(DevExpress, jQuery);
  70425. /*! Module viz-vectormap, file areasManager.js */
  70426. (function(DX, $, undefined) {
  70427. var _DATA_KEY = DX.viz.map.__DATA_KEY;
  70428. var AreasManager = DX.viz.map.Map.prototype._factory.MapItemsManager.inherit({
  70429. _rootClass: 'dxm-areas',
  70430. _processSource: function(source) {
  70431. var isGeoJson = source && source.type === 'FeatureCollection';
  70432. this._getItemCoordinates = isGeoJson ? getCoordinatesGeoJson : getCoordinatesDefault;
  70433. this._getItemAttributes = isGeoJson ? getAttributesGeoJson : getAttributesDefault;
  70434. return isGeoJson ? source.features : source
  70435. },
  70436. clean: function() {
  70437. this._commonSettings = null;
  70438. return this.callBase.apply(this, arguments)
  70439. },
  70440. render: function(options) {
  70441. this._commonSettings = this._themeManager.getCommonAreaSettings(options || {});
  70442. return this.callBase.apply(this, arguments)
  70443. },
  70444. _getItemSettings: function(_, options) {
  70445. return this._themeManager.getAreaSettings(this._commonSettings, options)
  70446. },
  70447. _createItem: function() {
  70448. return new Area
  70449. },
  70450. _isItemSelected: function(source, settings) {
  70451. return source.attrs.isSelected || settings.isSelected
  70452. },
  70453. _arrangeItems: $.noop
  70454. });
  70455. function getCoordinatesDefault(dataItem) {
  70456. return dataItem.coordinates
  70457. }
  70458. function getCoordinatesGeoJson(dataItem) {
  70459. var coordinates;
  70460. if (dataItem.geometry) {
  70461. var type = dataItem.geometry.type;
  70462. coordinates = dataItem.geometry.coordinates;
  70463. if (coordinates && (type === 'Polygon' || type === 'MultiPolygon'))
  70464. type === 'MultiPolygon' && (coordinates = [].concat.apply([], coordinates));
  70465. else
  70466. coordinates = undefined
  70467. }
  70468. return coordinates
  70469. }
  70470. function getAttributesDefault(dataItem) {
  70471. return dataItem.attributes
  70472. }
  70473. function getAttributesGeoJson(dataItem) {
  70474. return dataItem.properties
  70475. }
  70476. function Area(){}
  70477. $.extend(Area.prototype, DX.viz.map._internal.mapItemBehavior, {
  70478. _type: 'area',
  70479. _project: function(projection, coords) {
  70480. return projection.projectArea(coords)
  70481. },
  70482. _init: $.noop,
  70483. _createRoot: function() {
  70484. return this._ctx.renderer.createSimplePath()
  70485. },
  70486. _render: function(settings) {
  70487. var that = this;
  70488. that._styles = {
  70489. normal: {
  70490. 'class': 'dxm-area',
  70491. stroke: settings.borderColor,
  70492. strokeWidth: settings.borderWidth,
  70493. fill: settings.color
  70494. },
  70495. hovered: {
  70496. 'class': 'dxm-area dxm-area-hovered',
  70497. stroke: settings.hoveredBorderColor,
  70498. strokeWidth: settings.hoveredBorderWidth,
  70499. fill: settings.hoveredColor
  70500. },
  70501. selected: {
  70502. 'class': 'dxm-area dxm-area-selected',
  70503. stroke: settings.selectedBorderColor,
  70504. strokeWidth: settings.selectedBorderWidth,
  70505. fill: settings.selectedColor
  70506. }
  70507. };
  70508. that._root.applySettings(that._styles.normal).data(_DATA_KEY, that._data);
  70509. return that
  70510. },
  70511. _transform: function(projection, coords) {
  70512. return projection.getAreaCoordinates(coords)
  70513. },
  70514. _locate: function(coords) {
  70515. this._root.applySettings({d: coords})
  70516. },
  70517. _onHover: $.noop,
  70518. _setDefaultState: function() {
  70519. this._root.applySettings(this._styles.normal).toBackground()
  70520. },
  70521. _setHoveredState: function() {
  70522. this._root.applySettings(this._styles.hovered).toForeground()
  70523. },
  70524. _setSelectedState: function() {
  70525. this._root.applySettings(this._styles.selected).toForeground()
  70526. }
  70527. });
  70528. DX.viz.map._tests.AreasManager = AreasManager;
  70529. DX.viz.map._tests.Area = Area;
  70530. DX.viz.map.Map.prototype._factory.createAreasManager = function(parameters) {
  70531. return new AreasManager(parameters)
  70532. }
  70533. })(DevExpress, jQuery);
  70534. /*! Module viz-vectormap, file markersManager.js */
  70535. (function(DX, $, undefined) {
  70536. var _Number = Number,
  70537. _String = String,
  70538. _isFinite = isFinite,
  70539. _round = Math.round,
  70540. _max = Math.max,
  70541. _min = Math.min,
  70542. _extend = $.extend,
  70543. _isArray = DX.utils.isArray,
  70544. _processCircleSettings = DX.viz.renderers.processCircleSettings;
  70545. var CLASS_DEFAULT = 'dxm-marker',
  70546. CLASS_HOVERED = 'dxm-marker dxm-marker-hovered',
  70547. CLASS_SELECTED = 'dxm-marker dxm-marker-selected',
  70548. TRACKER_SETTINGS = {
  70549. stroke: 'none',
  70550. strokeWidth: 0,
  70551. fill: '#000000',
  70552. opacity: 0.0001
  70553. };
  70554. var _DATA_KEY = DX.viz.map.__DATA_KEY;
  70555. var DEFAULT_MARKER_TYPE = 'dot',
  70556. MARKER_TYPES = {};
  70557. var MarkersManager = DX.viz.map.Map.prototype._factory.MapItemsManager.inherit({
  70558. _rootClass: 'dxm-markers',
  70559. ctor: function() {
  70560. var that = this;
  70561. that.callBase.apply(that, arguments);
  70562. that._context.getColors = function(count) {
  70563. return that._themeManager.getMarkerColors(count)
  70564. };
  70565. that._filter = that._renderer.createFilter('shadow').applySettings({
  70566. x: '-40%',
  70567. y: '-40%',
  70568. width: '180%',
  70569. height: '200%',
  70570. color: '#000000',
  70571. opacity: 0.2,
  70572. dx: 0,
  70573. dy: 1,
  70574. blur: 1
  70575. }).append()
  70576. },
  70577. dispose: function() {
  70578. this._filter.dispose();
  70579. this._filter = null;
  70580. return this.callBase.apply(this, arguments)
  70581. },
  70582. _getItemCoordinates: function(dataItem) {
  70583. return dataItem.coordinates
  70584. },
  70585. _getItemAttributes: function(dataItem) {
  70586. return dataItem.attributes
  70587. },
  70588. _processSource: function(source) {
  70589. return source
  70590. },
  70591. clean: function() {
  70592. var that = this;
  70593. that._commonSettings = null;
  70594. return that.callBase.apply(that, arguments)
  70595. },
  70596. render: function(options) {
  70597. var that = this;
  70598. that._commonSettings = that._themeManager.getCommonMarkerSettings(options);
  70599. that._commonSettings._filter = that._filter.ref;
  70600. that._commonType = parseMarkerType(options && options.type);
  70601. return that.callBase.apply(that, arguments)
  70602. },
  70603. _arrangeBubbles: function() {
  70604. var markers = this._items,
  70605. bubbles = [],
  70606. i,
  70607. ii = markers.length,
  70608. marker,
  70609. values = [];
  70610. for (i = 0; i < ii; ++i) {
  70611. marker = markers[i];
  70612. if (marker.type === 'bubble') {
  70613. bubbles.push(marker);
  70614. if (marker.value !== null)
  70615. values.push(marker.value)
  70616. }
  70617. }
  70618. var minValue = _min.apply(null, values),
  70619. maxValue = _max.apply(null, values),
  70620. deltaValue = maxValue - minValue || 1;
  70621. for (i = 0, ii = bubbles.length; i < ii; ++i) {
  70622. marker = bubbles[i];
  70623. marker.setSize(marker.value !== null ? (marker.value - minValue) / deltaValue : 0)
  70624. }
  70625. },
  70626. _getItemSettings: function(source, options) {
  70627. var type = parseMarkerType(source.item.type, this._commonType),
  70628. style = _extend(source.item.style, options);
  70629. style = this._themeManager.getMarkerSettings(this._commonSettings, style, type);
  70630. _extend(source.item, {text: source.item.text || style.text});
  70631. style._type = type;
  70632. return style
  70633. },
  70634. _createItem: function(settings) {
  70635. return new MARKER_TYPES[settings._type]
  70636. },
  70637. _isItemSelected: function(source, settings) {
  70638. return source.item.isSelected || settings.isSelected
  70639. },
  70640. _arrangeItems: function() {
  70641. this._arrangeBubbles()
  70642. },
  70643. addMarker: function(dataItem) {
  70644. var that = this,
  70645. index = that._items.length,
  70646. marker = that._createItem(dataItem, index);
  70647. that._items.push(marker);
  70648. if (marker._selected)
  70649. that.selectItem(index, true, true);
  70650. that._arrangeItems();
  70651. return that
  70652. }
  70653. });
  70654. var baseMarkerBehavior = _extend({}, DX.viz.map._internal.mapItemBehavior, {
  70655. _type: 'marker',
  70656. _project: function(projection, coords) {
  70657. return projection.projectPoint(coords)
  70658. },
  70659. _init: function() {
  70660. this.proxy.coordinates = createCoordinatesGetter(this._src.coords);
  70661. this.proxy.text = this._src.item.text
  70662. },
  70663. _createRoot: function() {
  70664. return this._ctx.renderer.createGroup()
  70665. },
  70666. _render: function(settings) {
  70667. var that = this;
  70668. that._root.applySettings({'class': CLASS_DEFAULT});
  70669. that._create(settings, that._ctx.renderer, that._root);
  70670. that._createText(settings, that._ctx.renderer, that._root);
  70671. return that
  70672. },
  70673. _createText: function(settings, renderer, root) {
  70674. var that = this;
  70675. if (!that._src.item.text)
  70676. return;
  70677. var rootbox = that._root.getBBox(),
  70678. text = renderer.createText(that._src.item.text, 0, 0, {
  70679. align: 'center',
  70680. font: settings.font
  70681. }).append(root),
  70682. textBox = text.getBBox(),
  70683. x = _round(-textBox.x + rootbox.width / 2) + 2,
  70684. y = _round(-textBox.y - textBox.height / 2) - 1;
  70685. text.applySettings({
  70686. x: x,
  70687. y: y
  70688. });
  70689. renderer.createRect(x + textBox.x - 1, y + textBox.y - 1, textBox.width + 2, textBox.height + 2, 0, TRACKER_SETTINGS).data(_DATA_KEY, that._data).append(root)
  70690. },
  70691. _transform: function(projection, coords) {
  70692. return projection.getPointCoordinates(coords)
  70693. },
  70694. _locate: function(coords) {
  70695. this._root.applySettings({
  70696. translateX: coords.x,
  70697. translateY: coords.y
  70698. })
  70699. },
  70700. _onHover: function() {
  70701. this.hovered && this._root.toForeground()
  70702. },
  70703. _setDefaultState: function() {
  70704. this._root.applySettings({'class': CLASS_DEFAULT}).toBackground();
  70705. this._applyDefault()
  70706. },
  70707. _setHoveredState: function() {
  70708. this._root.applySettings({'class': CLASS_HOVERED});
  70709. this._applyHovered()
  70710. },
  70711. _setSelectedState: function() {
  70712. this._root.applySettings({'class': CLASS_SELECTED}).toForeground();
  70713. this._applySelected()
  70714. }
  70715. });
  70716. function createCoordinatesGetter(coordinates) {
  70717. return function() {
  70718. return [_Number(coordinates[0]), _Number(coordinates[1])]
  70719. }
  70720. }
  70721. function DotMarker(){}
  70722. _extend(DotMarker.prototype, baseMarkerBehavior, {
  70723. type: 'dot',
  70724. _create: function(style, renderer, root) {
  70725. var that = this,
  70726. size = style.size > 0 ? _Number(style.size) : 0,
  70727. hoveredSize = size,
  70728. selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0),
  70729. hoveredBackSize = hoveredSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
  70730. selectedBackSize = selectedSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
  70731. settings = _processCircleSettings(0, 0, size, style.borderWidth);
  70732. that._dotDefault = {
  70733. cx: settings.cx,
  70734. cy: settings.cy,
  70735. r: settings.r,
  70736. stroke: style.borderColor,
  70737. strokeWidth: style.borderWidth,
  70738. fill: style.color,
  70739. filter: style.shadow ? style._filter : null
  70740. };
  70741. that._dotHovered = {
  70742. cx: settings.cx,
  70743. cy: settings.cy,
  70744. r: hoveredSize / 2,
  70745. stroke: style.hoveredBorderColor,
  70746. strokeWidth: style.hoveredBorderWidth,
  70747. fill: style.hoveredColor
  70748. };
  70749. that._dotSelected = {
  70750. cx: settings.cx,
  70751. cy: settings.cy,
  70752. r: selectedSize / 2,
  70753. stroke: style.selectedBorderColor,
  70754. strokeWidth: style.selectedBorderWidth,
  70755. fill: style.selectedColor
  70756. };
  70757. that._backDefault = {
  70758. cx: settings.cx,
  70759. cy: settings.cy,
  70760. r: settings.r,
  70761. stroke: 'none',
  70762. strokeWidth: 0,
  70763. fill: style.backColor,
  70764. opacity: style.backOpacity
  70765. };
  70766. that._backHovered = {
  70767. cx: settings.cx,
  70768. cy: settings.cy,
  70769. r: hoveredBackSize / 2,
  70770. stroke: 'none',
  70771. strokeWidth: 0,
  70772. fill: style.backColor,
  70773. opacity: style.backOpacity
  70774. };
  70775. that._backSelected = {
  70776. cx: settings.cx,
  70777. cy: settings.cy,
  70778. r: selectedBackSize / 2,
  70779. stroke: 'none',
  70780. strokeWidth: 0,
  70781. fill: style.backColor,
  70782. opacity: style.backOpacity
  70783. };
  70784. that._back = renderer.createCircle().applySettings(that._backDefault).data(_DATA_KEY, that._data).append(root);
  70785. that._dot = renderer.createCircle().applySettings(that._dotDefault).data(_DATA_KEY, that._data).append(root)
  70786. },
  70787. _destroy: function() {
  70788. this._back = this._dot = null
  70789. },
  70790. _applyDefault: function() {
  70791. this._back.applySettings(this._backDefault);
  70792. this._dot.applySettings(this._dotDefault)
  70793. },
  70794. _applyHovered: function() {
  70795. this._back.applySettings(this._backHovered);
  70796. this._dot.applySettings(this._dotHovered)
  70797. },
  70798. _applySelected: function() {
  70799. this._back.applySettings(this._backSelected);
  70800. this._dot.applySettings(this._dotSelected)
  70801. }
  70802. });
  70803. function BubbleMarker(){}
  70804. _extend(BubbleMarker.prototype, baseMarkerBehavior, {
  70805. type: 'bubble',
  70806. _create: function(style, renderer, root) {
  70807. var that = this;
  70808. that._minSize = style.minSize > 0 ? _Number(style.minSize) : 0;
  70809. that._maxSize = style.maxSize > that._minSize ? _Number(style.maxSize) : that._minSize;
  70810. that.value = _isFinite(that._src.item.value) ? _Number(that._src.item.value) : null;
  70811. that._default = {
  70812. stroke: style.borderColor,
  70813. strokeWidth: style.borderWidth,
  70814. fill: style.color,
  70815. opacity: style.opacity
  70816. };
  70817. that._hovered = {
  70818. stroke: style.hoveredBorderColor,
  70819. strokeWidth: style.hoveredBorderWidth,
  70820. fill: style.hoveredColor,
  70821. opacity: style.hoveredOpacity
  70822. };
  70823. that._selected = {
  70824. stroke: style.selectedBorderColor,
  70825. strokeWidth: style.selectedBorderWidth,
  70826. fill: style.selectedColor,
  70827. opacity: style.selectedOpacity
  70828. };
  70829. that._bubble = renderer.createCircle(0, 0, style.maxSize / 2).applySettings(that._default).data(_DATA_KEY, that._data).append(root)
  70830. },
  70831. _destroy: function() {
  70832. this._bubble = null
  70833. },
  70834. _applyDefault: function() {
  70835. this._bubble.applySettings(this._default)
  70836. },
  70837. _applyHovered: function() {
  70838. this._bubble.applySettings(this._hovered)
  70839. },
  70840. _applySelected: function() {
  70841. this._bubble.applySettings(this._selected)
  70842. },
  70843. setSize: function(ratio) {
  70844. var that = this,
  70845. settings = _processCircleSettings(0, 0, that._minSize + ratio * (that._maxSize - that._minSize), that._default.strokeWidth);
  70846. that._default.cx = that._hovered.cx = that._selected.cx = settings.cx;
  70847. that._default.cy = that._hovered.cy = that._selected.cy = settings.cy;
  70848. that._default.r = that._hovered.r = that._selected.r = settings.r;
  70849. that._bubble.applySettings(settings);
  70850. return that
  70851. }
  70852. });
  70853. function PieMarker(){}
  70854. _extend(PieMarker.prototype, baseMarkerBehavior, {
  70855. type: 'pie',
  70856. _create: function(style, renderer, root) {
  70857. var that = this,
  70858. settings = _processCircleSettings(0, 0, style.size > 0 ? _Number(style.size) : 0, style.borderWidth);
  70859. that._pieDefault = {opacity: style.opacity};
  70860. that._pieHovered = {opacity: style.hoveredOpacity};
  70861. that._pieSelected = {opacity: style.selectedOpacity};
  70862. that._borderDefault = {
  70863. stroke: style.borderColor,
  70864. strokeWidth: style.borderWidth
  70865. };
  70866. that._borderHovered = {
  70867. stroke: style.hoveredBorderColor,
  70868. strokeWidth: style.hoveredBorderWidth
  70869. };
  70870. that._borderSelected = {
  70871. stroke: style.selectedBorderColor,
  70872. strokeWidth: style.selectedBorderWidth
  70873. };
  70874. var srcValues = that._src.item.values,
  70875. i = 0,
  70876. ii = _isArray(srcValues) ? srcValues.length : 0,
  70877. values = [],
  70878. value,
  70879. sum = 0;
  70880. for (; i < ii; ++i) {
  70881. value = _Number(srcValues[i]);
  70882. if (_isFinite(value)) {
  70883. values.push(value);
  70884. sum += value
  70885. }
  70886. }
  70887. that._pie = renderer.createGroup(that._pieDefault);
  70888. var translator = new DX.viz.core.Translator1D(0, sum, 90, 450),
  70889. startAngle = translator.translate(0),
  70890. endAngle,
  70891. colors = that._ctx.getColors(values.length);
  70892. for (value = 0, i = 0, ii = values.length; i < ii; ++i) {
  70893. value += values[i];
  70894. endAngle = translator.translate(value);
  70895. renderer.createArc(settings.cx, settings.cy, settings.r, 0, startAngle, endAngle, {fill: colors[i]}).data(_DATA_KEY, that._data).append(that._pie);
  70896. startAngle = endAngle
  70897. }
  70898. that._pie.append(root);
  70899. that._border = renderer.createCircle(settings.cx, settings.cy, settings.r, that._borderDefault).data(_DATA_KEY, that._data).append(root)
  70900. },
  70901. _destroy: function() {
  70902. this._pie = this._border = null
  70903. },
  70904. _applyDefault: function() {
  70905. this._pie.applySettings(this._pieDefault);
  70906. this._border.applySettings(this._borderDefault)
  70907. },
  70908. _applyHovered: function() {
  70909. this._pie.applySettings(this._pieHovered);
  70910. this._border.applySettings(this._borderHovered)
  70911. },
  70912. _applySelected: function() {
  70913. this._pie.applySettings(this._pieSelected);
  70914. this._border.applySettings(this._borderSelected)
  70915. }
  70916. });
  70917. function ImageMarker(){}
  70918. _extend(ImageMarker.prototype, baseMarkerBehavior, {
  70919. type: 'image',
  70920. _create: function(style, renderer, root) {
  70921. var that = this,
  70922. size = style.size > 0 ? _Number(style.size) : 0,
  70923. hoveredSize = size + (style.hoveredStep > 0 ? _Number(style.hoveredStep) : 0),
  70924. selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0);
  70925. that._default = {
  70926. x: -size / 2,
  70927. y: -size / 2,
  70928. width: size,
  70929. height: size
  70930. };
  70931. that._hovered = {
  70932. x: -hoveredSize / 2,
  70933. y: -hoveredSize / 2,
  70934. width: hoveredSize,
  70935. height: hoveredSize
  70936. };
  70937. that._selected = {
  70938. x: -selectedSize / 2,
  70939. y: -selectedSize / 2,
  70940. width: selectedSize,
  70941. height: selectedSize
  70942. };
  70943. that._image = renderer.createImage().applySettings(that._default).applySettings({
  70944. href: that._src.item.url,
  70945. location: 'center'
  70946. }).append(root);
  70947. that._tracker = renderer.createRect().applySettings(that._default).applySettings(TRACKER_SETTINGS).data(_DATA_KEY, that._data).append(root)
  70948. },
  70949. _destroy: function() {
  70950. this._image = this._tracker = null
  70951. },
  70952. _applyDefault: function() {
  70953. this._image.applySettings(this._default);
  70954. this._tracker.applySettings(this._default)
  70955. },
  70956. _applyHovered: function() {
  70957. this._image.applySettings(this._hovered);
  70958. this._tracker.applySettings(this._hovered)
  70959. },
  70960. _applySelected: function() {
  70961. this._image.applySettings(this._selected);
  70962. this._tracker.applySettings(this._selected)
  70963. }
  70964. });
  70965. MARKER_TYPES['dot'] = DotMarker;
  70966. MARKER_TYPES['bubble'] = BubbleMarker;
  70967. MARKER_TYPES['pie'] = PieMarker;
  70968. MARKER_TYPES['image'] = ImageMarker;
  70969. function parseMarkerType(type, defaultType) {
  70970. return MARKER_TYPES[type] && type || defaultType || DEFAULT_MARKER_TYPE
  70971. }
  70972. var __originalDefaultMarkerType = DEFAULT_MARKER_TYPE,
  70973. __originalMarkerTypes = $.extend({}, MARKER_TYPES);
  70974. DX.viz.map._tests.stubMarkerTypes = function(markerTypes, defaultMarkerType) {
  70975. DEFAULT_MARKER_TYPE = defaultMarkerType;
  70976. MARKER_TYPES = markerTypes
  70977. };
  70978. DX.viz.map._tests.restoreMarkerTypes = function() {
  70979. DEFAULT_MARKER_TYPE = __originalDefaultMarkerType;
  70980. MARKER_TYPES = __originalMarkerTypes
  70981. };
  70982. DX.viz.map._tests.baseMarkerBehavior = baseMarkerBehavior;
  70983. DX.viz.map._tests.MarkersManager = MarkersManager;
  70984. DX.viz.map._tests.DotMarker = DotMarker;
  70985. DX.viz.map._tests.BubbleMarker = BubbleMarker;
  70986. DX.viz.map._tests.PieMarker = PieMarker;
  70987. DX.viz.map._tests.ImageMarker = ImageMarker;
  70988. DX.viz.map.Map.prototype._factory.createMarkersManager = function(parameters) {
  70989. return new MarkersManager(parameters)
  70990. }
  70991. })(DevExpress, jQuery);
  70992. DevExpress.MOD_VIZ_VECTORMAP = true
  70993. }
  70994. if (!DevExpress.MOD_VIZ_SPARKLINES) {
  70995. if (!DevExpress.MOD_VIZ_CORE)
  70996. throw Error('Required module is not referenced: viz-core');
  70997. /*! Module viz-sparklines, file baseSparkline.js */
  70998. (function($, DX) {
  70999. var TOOLTIP_MARGIN = 100,
  71000. TOOLTIP_ARROW_MARGIN = 10,
  71001. DEFAULT_LINE_SPACING = 6,
  71002. DEFAULT_EVENTS_DELAY = 200,
  71003. TOUCH_EVENTS_DELAY = 1000,
  71004. _extend = $.extend,
  71005. _abs = Math.abs,
  71006. _Number = Number,
  71007. _round = Math.round,
  71008. core = DX.viz.core,
  71009. CoreFactory = core.CoreFactory;
  71010. function DEFAULT_CUSTOMIZE_TOOLTIP(customizeObject) {
  71011. return {text: customizeObject.valueText.join('<br/>')}
  71012. }
  71013. DX.viz.sparklines = {};
  71014. DX.viz.sparklines.DEFAULT_CUSTOMIZE_TOOLTIP = DEFAULT_CUSTOMIZE_TOOLTIP;
  71015. DX.viz.sparklines.BaseSparkline = core.BaseWidget.inherit({
  71016. render: function() {
  71017. this._refresh();
  71018. return this
  71019. },
  71020. _rendererType: DX.viz.renderers.Renderer,
  71021. _clean: function() {
  71022. if (this._tooltipShown) {
  71023. this._tooltip.dispose();
  71024. this._tooltip = null;
  71025. this._tooltipShown = null;
  71026. this._tooltipGroup.clear()
  71027. }
  71028. this._tooltipContainer.detach();
  71029. this._cleanWidgetElements()
  71030. },
  71031. _optionChanged: function(optionName, value) {
  71032. if (optionName === 'size' && this._allOptions) {
  71033. this._clean();
  71034. this._canvas = this._calculateCanvas();
  71035. this._renderer.resize(this._canvas.width, this._canvas.height);
  71036. if (!this._isContainerVisible())
  71037. return;
  71038. this._allOptions.size = value;
  71039. this._redrawWidgetElements();
  71040. this._prepareTooltipContainer()
  71041. }
  71042. else if (optionName === 'dataSource' && this._allOptions)
  71043. this._refreshDataSource();
  71044. else
  71045. this.callBase.apply(this, arguments)
  71046. },
  71047. _init: function() {
  71048. this.callBase();
  71049. this._canvas = this._calculateCanvas();
  71050. this._renderer = new this._rendererType({
  71051. cssClass: this._widgetClass + ' ' + this._widgetClass + '-' + this._widgetType,
  71052. pathModified: this.option('pathModified'),
  71053. rtl: this.option('rtlEnabled')
  71054. });
  71055. this._renderer.recreateCanvas(this._canvas.width, this._canvas.height);
  71056. this._createHtmlElements();
  71057. this._createTooltipGroups();
  71058. this._initTooltipEvents();
  71059. this._drawContainer()
  71060. },
  71061. _dispose: function() {
  71062. var that = this;
  71063. that.callBase();
  71064. that._disposeWidgetElements();
  71065. that._disposeTooltipEvents();
  71066. that._renderer.dispose();
  71067. that._tooltipRenderer.dispose();
  71068. that._translatorX = null;
  71069. that._translatorY = null;
  71070. delete that._renderer;
  71071. delete that._tooltipRenderer;
  71072. delete that._tooltipTrackerGroup;
  71073. delete that._tooltipGroup;
  71074. delete that._tooltipContainer
  71075. },
  71076. _render: function() {
  71077. var that = this;
  71078. that._canvas = that._calculateCanvas();
  71079. that._renderer.resize(that._canvas.width, that._canvas.height);
  71080. if (!that._isContainerVisible()) {
  71081. that._incidentOccured('W2001', [that.NAME]);
  71082. return
  71083. }
  71084. that._prepareOptions();
  71085. that._createWidgetElements();
  71086. that._drawWidgetElements();
  71087. that._drawn()
  71088. },
  71089. _isContainerVisible: function() {
  71090. var that = this,
  71091. canvas = that._canvas,
  71092. enoughWidth = canvas.width - canvas.left - canvas.right > 0,
  71093. enoughHeight = canvas.height - canvas.top - canvas.bottom > 0;
  71094. return canvas.height && canvas.width && enoughHeight && enoughWidth
  71095. },
  71096. _createWidgetElements: function() {
  71097. this._createRange();
  71098. this._createTranslator()
  71099. },
  71100. _prepareOptions: function(defaultOptions) {
  71101. var that = this,
  71102. userOptions = that.option() || {},
  71103. options,
  71104. defaultTheme,
  71105. theme;
  71106. defaultTheme = core.findTheme('default');
  71107. defaultTheme = defaultTheme[this._widgetType];
  71108. options = _extend(true, {}, defaultOptions, userOptions);
  71109. if (typeof options.theme === 'string') {
  71110. theme = core.findTheme(options.theme);
  71111. theme = theme[this._widgetType]
  71112. }
  71113. else
  71114. theme = options.theme;
  71115. return _extend(true, {}, defaultTheme, theme, options)
  71116. },
  71117. _calculateCanvas: function() {
  71118. var that = this,
  71119. canvas = {},
  71120. sizeOptions = that.option('size') || {},
  71121. marginOptions = that.option('margin') || {},
  71122. defaultSize = that._defaultSize,
  71123. container = that._element(),
  71124. width = sizeOptions.width >= 0 ? _Number(sizeOptions.width) : container.width(),
  71125. height = sizeOptions.height >= 0 ? _Number(sizeOptions.height) : container.height();
  71126. if (!width && _Number(sizeOptions.width) !== 0)
  71127. width = defaultSize.width;
  71128. if (!height && _Number(sizeOptions.height) !== 0)
  71129. height = defaultSize.height;
  71130. return {
  71131. width: width,
  71132. height: height,
  71133. top: _Number(marginOptions.top) || defaultSize.top,
  71134. bottom: _Number(marginOptions.bottom) || defaultSize.bottom,
  71135. left: _Number(marginOptions.left) || defaultSize.left,
  71136. right: _Number(marginOptions.right) || defaultSize.right
  71137. }
  71138. },
  71139. _createTooltipGroups: function() {
  71140. var that = this,
  71141. renderer,
  71142. root,
  71143. widgetClass = that._widgetClass;
  71144. that._tooltipRenderer = renderer = new that._rendererType({
  71145. cssClass: widgetClass + ' ' + widgetClass + '-tooltip',
  71146. pathModified: this.option('pathModified'),
  71147. rtl: this.option('rtlEnabled')
  71148. });
  71149. renderer.recreateCanvas(1, 1);
  71150. that._tooltipContainer = $('<div style="position: relative">');
  71151. renderer.draw(that._tooltipContainer[0]);
  71152. root = renderer.getRoot();
  71153. that._tooltipGroup = renderer.createGroup({
  71154. 'class': widgetClass + '-tooltip-group',
  71155. style: {'z-index': '1'}
  71156. }).append(root);
  71157. that._tooltipTrackerGroup = renderer.createGroup({'class': widgetClass + '-tooltip-tracker-group'}).append(root);
  71158. that._tooltipTracker = that._createTooltipTracker().append(that._tooltipTrackerGroup)
  71159. },
  71160. _createTooltipTracker: function() {
  71161. return this._tooltipRenderer.createRect(0, 0, 0, 0, 0, {
  71162. fill: 'grey',
  71163. opacity: 0
  71164. })
  71165. },
  71166. _initTooltipEvents: function() {
  71167. var that = this,
  71168. data = {
  71169. widget: that,
  71170. container: that._tooltipTracker
  71171. };
  71172. that._showTooltipCallback = function() {
  71173. that._showTooltipTimeout = null;
  71174. if (!that._tooltipShown) {
  71175. that._tooltipShown = true;
  71176. that._showTooltip()
  71177. }
  71178. that._DEBUG_showCallback && that._DEBUG_showCallback()
  71179. };
  71180. that._hideTooltipCallback = function() {
  71181. that._hideTooltipTimeout = null;
  71182. if (that._tooltipShown) {
  71183. that._tooltipShown = false;
  71184. that._hideTooltip()
  71185. }
  71186. that._DEBUG_hideCallback && that._DEBUG_hideCallback()
  71187. };
  71188. that._disposeCallbacks = function() {
  71189. that = that._showTooltipCallback = that._hideTooltipCallback = that._disposeCallbacks = null
  71190. };
  71191. that._tooltipTracker.on(mouseEvents, data).on(touchEvents, data);
  71192. that._tooltipTracker.on(menuEvents)
  71193. },
  71194. _disposeTooltipEvents: function() {
  71195. clearTimeout(this._showTooltipTimeout);
  71196. clearTimeout(this._hideTooltipTimeout);
  71197. this._showTooltipTimeout = this._showTooltipTimeout = null;
  71198. this._tooltipTracker.off();
  71199. this._disposeCallbacks()
  71200. },
  71201. _drawContainer: function() {
  71202. this._renderer.draw(this._element()[0])
  71203. },
  71204. _createTranslator: function() {
  71205. this._translatorX = CoreFactory.createTranslator2D(this._ranges.arg, this._canvas, {direction: "horizontal"});
  71206. this._translatorY = CoreFactory.createTranslator2D(this._ranges.val, this._canvas)
  71207. },
  71208. _prepareTooltipOptions: function() {
  71209. var that = this,
  71210. canvas = that._canvas,
  71211. tooltipOpt = that._allOptions.tooltip,
  71212. size = that._getTooltipSize(true),
  71213. defaultOptions = {
  71214. canvasWidth: size.width,
  71215. canvasHeight: size.height,
  71216. paddingLeftRight: tooltipOpt.paddingLeftRight,
  71217. paddingTopBottom: tooltipOpt.paddingTopBottom,
  71218. arrowLength: tooltipOpt.arrowLength,
  71219. cloudHorizontalPosition: tooltipOpt.horizontalAlignment,
  71220. cloudVerticalPosition: tooltipOpt.verticalAlignment,
  71221. lineSpacing: tooltipOpt.font.lineSpacing !== undefined && tooltipOpt.font.lineSpacing !== null ? tooltipOpt.font.lineSpacing : DEFAULT_LINE_SPACING
  71222. },
  71223. autoJustify = !$.isFunction(that._allOptions.tooltip.customizeText) && !$.isFunction(that._allOptions.tooltip.customizeTooltip),
  71224. options = $.extend(defaultOptions, that._allOptions.tooltip, {
  71225. customizeTooltip: autoJustify ? DEFAULT_CUSTOMIZE_TOOLTIP : that._allOptions.tooltip.customizeTooltip,
  71226. _justify: that._allOptions.tooltip._justify || autoJustify,
  71227. _rtl: that.option('rtlEnabled')
  71228. });
  71229. that._tooltipOptions = {
  71230. size: size,
  71231. options: options
  71232. };
  71233. return options
  71234. },
  71235. _prepareTooltipContainer: function() {
  71236. var that = this,
  71237. canvas = that._canvas,
  71238. width = canvas.width,
  71239. height = canvas.height,
  71240. renderer = that._tooltipRenderer;
  71241. that._updateTooltipSizeToNormal();
  71242. that._tooltipTracker.applySettings({
  71243. width: width,
  71244. height: height
  71245. });
  71246. that._tooltipContainer.appendTo(that._element());
  71247. that._tooltipInitializated = false;
  71248. that._canShowTooltip = that._allOptions.tooltip.enabled
  71249. },
  71250. _isTooltipVisible: function() {
  71251. return this._tooltip.enabled() && this._tooltip.prepare(this._getTooltipData(), {offset: 0})
  71252. },
  71253. _createTooltip: function() {
  71254. var that = this;
  71255. that._tooltip = CoreFactory.createTooltip(that._prepareTooltipOptions(), that._tooltipGroup, that._tooltipRenderer);
  71256. if (that._isTooltipVisible()) {
  71257. that._tooltip.show();
  71258. that._updateTooltipSizeToWide();
  71259. that._checkTooltipSize();
  71260. that._updateTooltipSizeToNormal()
  71261. }
  71262. else
  71263. that._canShowTooltip = false
  71264. },
  71265. _doShowTooltip: function(delay) {
  71266. var that = this;
  71267. if (!that._canShowTooltip)
  71268. return;
  71269. ++that._DEBUG_clearHideTooltipTimeout;
  71270. clearTimeout(that._hideTooltipTimeout);
  71271. that._hideTooltipTimeout = null;
  71272. clearTimeout(that._showTooltipTimeout);
  71273. ++that._DEBUG_showTooltipTimeoutSet;
  71274. that._showTooltipTimeout = setTimeout(that._showTooltipCallback, delay)
  71275. },
  71276. _doHideTooltip: function(delay) {
  71277. var that = this;
  71278. if (!that._canShowTooltip)
  71279. return;
  71280. ++that._DEBUG_clearShowTooltipTimeout;
  71281. clearTimeout(that._showTooltipTimeout);
  71282. that._showTooltipTimeout = null;
  71283. clearTimeout(that._hideTooltipTimeout);
  71284. ++that._DEBUG_hideTooltipTimeoutSet;
  71285. that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)
  71286. },
  71287. _getNormalTooltipSize: function() {
  71288. var size = {};
  71289. size.width = this._canvas.width;
  71290. size.left = 0;
  71291. size.tooltipLeft = _round(size.width / 2);
  71292. return size
  71293. },
  71294. _getWideTooltipSize: function(leftWidthDelta, rightWidthDelta) {
  71295. var that = this,
  71296. canvas = that._canvas,
  71297. horizontalPos = that._allOptions.tooltip.horizontalAlignment,
  71298. widthDelta = leftWidthDelta + rightWidthDelta,
  71299. size = {};
  71300. size.width = canvas.width + widthDelta;
  71301. size.left = -leftWidthDelta;
  71302. if (horizontalPos === 'right')
  71303. size.tooltipLeft = _round(canvas.width / 2);
  71304. else if (horizontalPos === 'left')
  71305. size.tooltipLeft = _round(canvas.width / 2) + widthDelta;
  71306. else
  71307. size.tooltipLeft = _round(size.width / 2);
  71308. return size
  71309. },
  71310. _getTooltipSize: function(isNormal, leftWidthDelta, rightWidthDelta, heightDelta) {
  71311. var that = this,
  71312. canvas = that._canvas,
  71313. isVerticalPosTop = !(that._allOptions.tooltip.verticalAlignment === 'bottom'),
  71314. size = !isNormal && (leftWidthDelta || rightWidthDelta) ? that._getWideTooltipSize(leftWidthDelta, rightWidthDelta) : that._getNormalTooltipSize(),
  71315. yDelta = heightDelta > 0 ? heightDelta + TOOLTIP_MARGIN : TOOLTIP_MARGIN;
  71316. size.height = canvas.height + yDelta;
  71317. size.top = isVerticalPosTop ? -size.height : -canvas.height;
  71318. size.trackerY = isVerticalPosTop ? yDelta : 0;
  71319. size.tooltipY = isVerticalPosTop ? _round(canvas.height / 2) + yDelta - TOOLTIP_ARROW_MARGIN : _round(canvas.height / 2);
  71320. return size
  71321. },
  71322. _checkTooltipSize: function() {
  71323. var that = this,
  71324. tooltip = that._tooltip,
  71325. options = that._tooltipOptions.options,
  71326. tooltipBBox = tooltip.getBBox(),
  71327. getWide = that._allOptions.tooltip.allowContainerResizing,
  71328. leftDelta = -tooltipBBox.x,
  71329. rightDelta = tooltipBBox.x + tooltipBBox.width - that._canvas.width,
  71330. topDelta = tooltipBBox.height - TOOLTIP_MARGIN,
  71331. size;
  71332. if (leftDelta > 0 || rightDelta > 0 || topDelta > 0)
  71333. if (getWide) {
  71334. that._tooltipOptions.size = size = that._getTooltipSize(false, leftDelta > 0 ? leftDelta : 0, rightDelta > 0 ? rightDelta : 0, topDelta > 0 ? topDelta : 0);
  71335. tooltip.setSize(size.width, size.height);
  71336. that._updateTooltipSizeToWide()
  71337. }
  71338. else {
  71339. that._canShowTooltip = false;
  71340. tooltip.hide()
  71341. }
  71342. },
  71343. _updateTooltipSizeToWide: function() {
  71344. var that = this,
  71345. size = that._tooltipOptions.size,
  71346. renderer = that._tooltipRenderer;
  71347. renderer.resize(size.width, size.height);
  71348. renderer.getRoot().applySettings({style: {
  71349. left: size.left,
  71350. top: size.top,
  71351. position: 'absolute',
  71352. overflow: 'hidden'
  71353. }});
  71354. that._tooltipTracker.applySettings({
  71355. y: size.trackerY,
  71356. x: -size.left
  71357. });
  71358. that._tooltip.move(size.tooltipLeft, size.tooltipY)
  71359. },
  71360. _updateTooltipSizeToNormal: function() {
  71361. var that = this,
  71362. renderer = that._tooltipRenderer,
  71363. canvas = that._canvas;
  71364. renderer.resize(canvas.width, canvas.height);
  71365. renderer.getRoot().applySettings({style: {
  71366. left: 0,
  71367. top: -canvas.height,
  71368. position: 'absolute'
  71369. }});
  71370. that._tooltipTracker.applySettings({
  71371. y: 0,
  71372. x: 0
  71373. })
  71374. },
  71375. _showTooltip: function() {
  71376. if (!this._tooltipInitializated) {
  71377. this._createTooltip();
  71378. this._tooltipInitializated = true;
  71379. if (!this._canShowTooltip)
  71380. return
  71381. }
  71382. this._updateTooltipSizeToWide();
  71383. this._tooltip.show()
  71384. },
  71385. _hideTooltip: function() {
  71386. this._updateTooltipSizeToNormal();
  71387. this._tooltip.hide()
  71388. },
  71389. showLoadingIndicator: $.noop
  71390. });
  71391. var menuEvents = {
  71392. 'contextmenu.sparkline-tooltip': function(event) {
  71393. if (DX.ui.events.isTouchEvent(event) || DX.ui.events.isPointerEvent(event))
  71394. event.preventDefault()
  71395. },
  71396. 'MSHoldVisual.sparkline-tooltip': function(event) {
  71397. event.preventDefault()
  71398. }
  71399. };
  71400. var mouseEvents = {
  71401. 'mouseover.sparkline-tooltip': function(event) {
  71402. isPointerDownCalled = false;
  71403. var widget = event.data.widget;
  71404. widget._x = event.pageX;
  71405. widget._y = event.pageY;
  71406. widget._tooltipTracker.off(mouseMoveEvents).on(mouseMoveEvents, event.data);
  71407. widget._doShowTooltip(DEFAULT_EVENTS_DELAY)
  71408. },
  71409. 'mouseout.sparkline-tooltip': function(event) {
  71410. if (isPointerDownCalled)
  71411. return;
  71412. var widget = event.data.widget;
  71413. widget._tooltipTracker.off(mouseMoveEvents);
  71414. widget._doHideTooltip(DEFAULT_EVENTS_DELAY)
  71415. }
  71416. };
  71417. var mouseMoveEvents = {'mousemove.sparkline-tooltip': function(event) {
  71418. var widget = event.data.widget;
  71419. if (widget._showTooltipTimeout && (_abs(widget._x - event.pageX) > 3 || _abs(widget._y - event.pageY) > 3)) {
  71420. widget._x = event.pageX;
  71421. widget._y = event.pageY;
  71422. widget._doShowTooltip(DEFAULT_EVENTS_DELAY)
  71423. }
  71424. }};
  71425. var active_touch_tooltip_widget = null,
  71426. touchstartTooltipProcessing = function(event) {
  71427. event.preventDefault();
  71428. var widget = active_touch_tooltip_widget;
  71429. if (widget && widget !== event.data.widget)
  71430. widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
  71431. widget = active_touch_tooltip_widget = event.data.widget;
  71432. widget._doShowTooltip(TOUCH_EVENTS_DELAY);
  71433. widget._touch = true
  71434. },
  71435. touchstartDocumentProcessing = function() {
  71436. var widget = active_touch_tooltip_widget;
  71437. if (widget) {
  71438. if (!widget._touch) {
  71439. widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
  71440. active_touch_tooltip_widget = null
  71441. }
  71442. widget._touch = null
  71443. }
  71444. },
  71445. touchendDocumentProcessing = function() {
  71446. var widget = active_touch_tooltip_widget;
  71447. if (widget)
  71448. if (widget._showTooltipTimeout) {
  71449. widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
  71450. active_touch_tooltip_widget = null
  71451. }
  71452. },
  71453. isPointerDownCalled = false;
  71454. var touchEvents = {
  71455. 'pointerdown.sparkline-tooltip': function(event) {
  71456. touchstartTooltipProcessing(event)
  71457. },
  71458. 'touchstart.sparkline-tooltip': function(event) {
  71459. touchstartTooltipProcessing(event)
  71460. }
  71461. };
  71462. $(document).on({
  71463. 'pointerdown.sparkline-tooltip': function() {
  71464. isPointerDownCalled = true;
  71465. touchstartDocumentProcessing()
  71466. },
  71467. 'touchstart.sparkline-tooltip': function() {
  71468. touchstartDocumentProcessing()
  71469. },
  71470. 'pointerup.sparkline-tooltip': function() {
  71471. touchendDocumentProcessing()
  71472. },
  71473. 'touchend.sparkline-tooltip': function() {
  71474. touchendDocumentProcessing()
  71475. }
  71476. });
  71477. DX.viz.sparklines.BaseSparkline._DEBUG_reset = function() {
  71478. active_touch_tooltip_widget = null
  71479. }
  71480. })(jQuery, DevExpress);
  71481. /*! Module viz-sparklines, file sparkline.js */
  71482. (function($, DX) {
  71483. var viz = DX.viz,
  71484. charts = viz.charts,
  71485. core = viz.core,
  71486. MIN_BAR_WIDTH = 1,
  71487. MAX_BAR_WIDTH = 50,
  71488. DEFAULT_BAR_INTERVAL = 4,
  71489. DEFAULT_CANVAS_WIDTH = 250,
  71490. DEFAULT_CANVAS_HEIGHT = 30,
  71491. DEFAULT_HORIZONTAL_MARGIN = 5,
  71492. DEFAULT_VERTICAL_MARGIN = 3,
  71493. DEFAULT_OPTIONS = {
  71494. disabled: false,
  71495. theme: 'default',
  71496. dataSource: [],
  71497. size: {},
  71498. margin: {},
  71499. type: 'line',
  71500. argumentField: 'arg',
  71501. valueField: 'val',
  71502. winlossThreshold: 0,
  71503. showFirstLast: true,
  71504. showMinMax: false,
  71505. redrawOnResize: false
  71506. },
  71507. ALLOWED_TYPES = {
  71508. line: true,
  71509. spline: true,
  71510. stepline: true,
  71511. area: true,
  71512. steparea: true,
  71513. splinearea: true,
  71514. bar: true,
  71515. winloss: true
  71516. },
  71517. _map = $.map,
  71518. _extend = $.extend,
  71519. _abs = Math.abs,
  71520. _round = Math.round,
  71521. _isFinite = isFinite,
  71522. _Number = Number,
  71523. _String = String;
  71524. viz.sparklines.Sparkline = viz.sparklines.BaseSparkline.inherit({
  71525. _widgetType: 'sparkline',
  71526. _widgetClass: 'dxsl',
  71527. _defaultSize: {
  71528. width: DEFAULT_CANVAS_WIDTH,
  71529. height: DEFAULT_CANVAS_HEIGHT,
  71530. left: DEFAULT_HORIZONTAL_MARGIN,
  71531. right: DEFAULT_HORIZONTAL_MARGIN,
  71532. top: DEFAULT_VERTICAL_MARGIN,
  71533. bottom: DEFAULT_VERTICAL_MARGIN
  71534. },
  71535. _init: function() {
  71536. this.callBase();
  71537. this._refreshDataSource()
  71538. },
  71539. _handleDataSourceChanged: function() {
  71540. if (this._initialized) {
  71541. this._clean();
  71542. this._createWidgetElements();
  71543. this._drawWidgetElements()
  71544. }
  71545. },
  71546. _dataSourceOptions: function() {
  71547. return {
  71548. paginate: false,
  71549. _preferSync: true
  71550. }
  71551. },
  71552. _redrawWidgetElements: function() {
  71553. this._createTranslator();
  71554. this._correctPoints();
  71555. this._series.draw({
  71556. x: this._translatorX,
  71557. y: this._translatorY
  71558. });
  71559. this._seriesGroup.append(this._renderer.getRoot())
  71560. },
  71561. _disposeWidgetElements: function() {
  71562. delete this._seriesGroup;
  71563. delete this._seriesLabelGroup
  71564. },
  71565. _cleanWidgetElements: function() {
  71566. this._seriesGroup.detach();
  71567. this._seriesLabelGroup.detach();
  71568. this._seriesGroup.clear();
  71569. this._seriesLabelGroup.clear()
  71570. },
  71571. _createWidgetElements: function() {
  71572. this._createSeries();
  71573. this.callBase()
  71574. },
  71575. _drawWidgetElements: function() {
  71576. if (this._dataSource && this._dataSource.isLoaded())
  71577. this._drawSeries()
  71578. },
  71579. _prepareOptions: function() {
  71580. this._allOptions = this.callBase(DEFAULT_OPTIONS);
  71581. this._allOptions.type = _String(this._allOptions.type).toLowerCase();
  71582. if (!ALLOWED_TYPES[this._allOptions.type])
  71583. this._allOptions.type = 'line'
  71584. },
  71585. _createHtmlElements: function() {
  71586. this._seriesGroup = this._renderer.createGroup({'class': 'dxsl-series'});
  71587. this._seriesLabelGroup = this._renderer.createGroup({'class': 'dxsl-series-labels'})
  71588. },
  71589. _createSeries: function() {
  71590. var that = this,
  71591. renderer = that._renderer,
  71592. dataValidator;
  71593. that._prepareDataSource();
  71594. that._prepareSeriesOptions();
  71595. that._series = core.CoreFactory.createSeries(renderer, that._seriesOptions);
  71596. dataValidator = charts.factory.createDataValidator(that._simpleDataSource, [[that._series]], that._incidentOccured, {
  71597. checkTypeForAllData: false,
  71598. convertToAxisDataType: true,
  71599. sortingMethod: true
  71600. });
  71601. that._simpleDataSource = dataValidator.validate();
  71602. that._series._options.customizePoint = that._getCustomizeFunction();
  71603. that._series.updateData(that._simpleDataSource)
  71604. },
  71605. _parseNumericDataSource: function(data, argField, valField) {
  71606. var ignoreEmptyPoints = this.option('ignoreEmptyPoints');
  71607. return _map(data, function(dataItem, index) {
  71608. var item = null,
  71609. isDataNumber,
  71610. value;
  71611. if (dataItem !== undefined) {
  71612. item = {};
  71613. isDataNumber = _isFinite(dataItem);
  71614. item[argField] = isDataNumber ? _String(index) : dataItem[argField];
  71615. value = isDataNumber ? dataItem : dataItem[valField];
  71616. item[valField] = value === null ? ignoreEmptyPoints ? undefined : value : _Number(value);
  71617. item = item[argField] !== undefined && item[valField] !== undefined ? item : null
  71618. }
  71619. return item
  71620. })
  71621. },
  71622. _parseWinlossDataSource: function(data, argField, valField) {
  71623. var lowBarValue = -1,
  71624. zeroBarValue = 0,
  71625. highBarValue = 1,
  71626. delta = 0.0001,
  71627. target = this._allOptions.winlossThreshold;
  71628. return _map(data, function(dataItem) {
  71629. var item = {};
  71630. item[argField] = dataItem[argField];
  71631. if (_abs(dataItem[valField] - target) < delta)
  71632. item[valField] = zeroBarValue;
  71633. else if (dataItem[valField] > target)
  71634. item[valField] = highBarValue;
  71635. else
  71636. item[valField] = lowBarValue;
  71637. return item
  71638. })
  71639. },
  71640. _prepareDataSource: function() {
  71641. var that = this,
  71642. options = that._allOptions,
  71643. argField = options.argumentField,
  71644. valField = options.valueField,
  71645. dataSource = that._dataSource ? that._dataSource.items() : [],
  71646. data = that._parseNumericDataSource(dataSource, argField, valField);
  71647. if (options.type === 'winloss') {
  71648. that._winlossDataSource = data;
  71649. that._simpleDataSource = that._parseWinlossDataSource(data, argField, valField)
  71650. }
  71651. else
  71652. that._simpleDataSource = data
  71653. },
  71654. _prepareSeriesOptions: function() {
  71655. var that = this,
  71656. options = that._allOptions,
  71657. defaultPointOptions = {
  71658. border: {},
  71659. hoverStyle: {border: {}},
  71660. selectionStyle: {border: {}}
  71661. },
  71662. customPointOptions = {
  71663. size: options.pointSize,
  71664. symbol: options.pointSymbol,
  71665. border: {
  71666. visible: true,
  71667. width: 2
  71668. },
  71669. color: options.pointColor
  71670. };
  71671. that._seriesOptions = {
  71672. visible: true,
  71673. argumentField: options.argumentField,
  71674. valueField: options.valueField,
  71675. color: options.lineColor,
  71676. width: options.lineWidth,
  71677. widgetType: "chart"
  71678. };
  71679. that._seriesOptions.border = {
  71680. color: that._seriesOptions.color,
  71681. width: that._seriesOptions.width,
  71682. visible: true
  71683. };
  71684. that._seriesOptions.type = options.type === 'winloss' ? 'bar' : options.type;
  71685. if (options.type === 'winloss' || options.type === 'bar') {
  71686. that._seriesOptions.argumentAxisType = 'discrete';
  71687. that._seriesOptions.border.visible = false
  71688. }
  71689. if (~~options.type.indexOf('area') !== -1)
  71690. that._seriesOptions.opacity = that._allOptions.areaOpacity;
  71691. that._seriesOptions.seriesGroup = that._seriesGroup;
  71692. that._seriesOptions.seriesLabelsGroup = that._seriesLabelGroup;
  71693. that._seriesOptions.point = _extend(defaultPointOptions, customPointOptions);
  71694. that._seriesOptions.point.visible = false
  71695. },
  71696. _createBarCustomizeFunction: function(pointIndexes) {
  71697. var that = this,
  71698. options = that._allOptions,
  71699. winlossData = that._winlossDataSource;
  71700. return function() {
  71701. var index = this.index,
  71702. isWinloss = options.type === 'winloss',
  71703. target = isWinloss ? options.winlossThreshold : 0,
  71704. value = isWinloss ? winlossData[index][options.valueField] : this.value,
  71705. positiveColor = isWinloss ? options.winColor : options.barPositiveColor,
  71706. negativeColor = isWinloss ? options.lossColor : options.barNegativeColor,
  71707. color;
  71708. if (value >= target)
  71709. color = positiveColor;
  71710. else
  71711. color = negativeColor;
  71712. if (index === pointIndexes.first || index === pointIndexes.last)
  71713. color = options.firstLastColor;
  71714. if (index === pointIndexes.min)
  71715. color = options.minColor;
  71716. if (index === pointIndexes.max)
  71717. color = options.maxColor;
  71718. return {color: color}
  71719. }
  71720. },
  71721. _createLineCustomizeFunction: function(pointIndexes) {
  71722. var that = this,
  71723. options = that._allOptions;
  71724. return function() {
  71725. var color,
  71726. index = this.index;
  71727. if (index === pointIndexes.first || index === pointIndexes.last)
  71728. color = options.firstLastColor;
  71729. if (index === pointIndexes.min)
  71730. color = options.minColor;
  71731. if (index === pointIndexes.max)
  71732. color = options.maxColor;
  71733. return color ? {
  71734. visible: true,
  71735. border: {color: color}
  71736. } : {}
  71737. }
  71738. },
  71739. _getCustomizeFunction: function() {
  71740. var that = this,
  71741. options = that._allOptions,
  71742. dataSource = that._winlossDataSource || that._simpleDataSource,
  71743. drawnPointIndexes = that._getExtremumPointsIndexes(dataSource),
  71744. customizeFunction;
  71745. if (options.type === 'winloss' || options.type === 'bar')
  71746. customizeFunction = that._createBarCustomizeFunction(drawnPointIndexes);
  71747. else
  71748. customizeFunction = that._createLineCustomizeFunction(drawnPointIndexes);
  71749. return customizeFunction
  71750. },
  71751. _getExtremumPointsIndexes: function(data) {
  71752. var that = this,
  71753. options = that._allOptions,
  71754. lastIndex = data.length - 1,
  71755. indexes = {};
  71756. that._minMaxIndexes = that._findMinMax(data);
  71757. if (options.showFirstLast) {
  71758. indexes.first = 0;
  71759. indexes.last = lastIndex
  71760. }
  71761. if (options.showMinMax) {
  71762. indexes.min = that._minMaxIndexes.minIndex;
  71763. indexes.max = that._minMaxIndexes.maxIndex
  71764. }
  71765. return indexes
  71766. },
  71767. _findMinMax: function(data) {
  71768. var that = this,
  71769. valField = that._allOptions.valueField,
  71770. firstItem = data[0] || {},
  71771. firstValue = firstItem[valField] || 0,
  71772. min = firstValue,
  71773. max = firstValue,
  71774. minIndex = 0,
  71775. maxIndex = 0,
  71776. dataLength = data.length,
  71777. value,
  71778. i;
  71779. for (i = 1; i < dataLength; i++) {
  71780. value = data[i][valField];
  71781. if (value < min) {
  71782. min = value;
  71783. minIndex = i
  71784. }
  71785. if (value > max) {
  71786. max = value;
  71787. maxIndex = i
  71788. }
  71789. }
  71790. return {
  71791. minIndex: minIndex,
  71792. maxIndex: maxIndex
  71793. }
  71794. },
  71795. _createRange: function() {
  71796. var that = this,
  71797. series = that._series,
  71798. isBarType = series.type === 'bar',
  71799. DEFAULT_VALUE_RANGE_MARGIN = 0.15,
  71800. DEFAULT_ARGUMENT_RANGE_MARGIN = isBarType ? 0.1 : 0,
  71801. rangeData = series.getRangeData();
  71802. that._ranges = {
  71803. arg: new core.Range({
  71804. stick: !isBarType && series.getPoints().length > 1,
  71805. minValueMargin: DEFAULT_ARGUMENT_RANGE_MARGIN,
  71806. maxValueMargin: DEFAULT_ARGUMENT_RANGE_MARGIN
  71807. }),
  71808. val: new core.Range({
  71809. isValueRange: true,
  71810. keepValueMargins: true,
  71811. minValueMargin: DEFAULT_VALUE_RANGE_MARGIN,
  71812. maxValueMargin: DEFAULT_VALUE_RANGE_MARGIN
  71813. })
  71814. };
  71815. that._ranges.arg.addRange(rangeData.arg);
  71816. that._ranges.val.addRange(rangeData.val);
  71817. that._ranges.arg.applyValueMargins();
  71818. that._ranges.val.applyValueMargins()
  71819. },
  71820. _getBarWidth: function(pointsCount) {
  71821. var that = this,
  71822. canvas = that._canvas,
  71823. intervalWidth = pointsCount * DEFAULT_BAR_INTERVAL,
  71824. rangeWidth = canvas.width - canvas.left - canvas.right - intervalWidth,
  71825. width = _round(rangeWidth / pointsCount);
  71826. if (width < MIN_BAR_WIDTH)
  71827. width = MIN_BAR_WIDTH;
  71828. if (width > MAX_BAR_WIDTH)
  71829. width = MAX_BAR_WIDTH;
  71830. return width
  71831. },
  71832. _correctPoints: function() {
  71833. var that = this,
  71834. seriesType = that._allOptions.type,
  71835. seriesPoints = that._series.getPoints(),
  71836. pointsLength = seriesPoints.length,
  71837. barWidth,
  71838. i;
  71839. if (seriesType === 'bar' || seriesType === 'winloss') {
  71840. barWidth = that._getBarWidth(pointsLength);
  71841. for (i = 0; i < pointsLength; i++)
  71842. seriesPoints[i].correctCoordinates({
  71843. width: barWidth,
  71844. offset: 0
  71845. })
  71846. }
  71847. },
  71848. _drawSeries: function() {
  71849. var that = this;
  71850. if (that._simpleDataSource.length !== 0) {
  71851. that._correctPoints();
  71852. that._series.draw({
  71853. x: that._translatorX,
  71854. y: that._translatorY
  71855. });
  71856. that._seriesGroup.append(that._renderer.getRoot());
  71857. that._prepareTooltipContainer()
  71858. }
  71859. },
  71860. _isTooltipVisible: function() {
  71861. return this.callBase() && this._dataSource.length !== 0
  71862. },
  71863. _getTooltipData: function() {
  71864. var that = this,
  71865. options = that._allOptions,
  71866. dataSource = that._winlossDataSource || that._simpleDataSource,
  71867. tooltip = that._tooltip;
  71868. if (dataSource.length === 0)
  71869. return {};
  71870. var minMax = that._minMaxIndexes,
  71871. valueField = options.valueField,
  71872. first = dataSource[0][valueField],
  71873. last = dataSource[dataSource.length - 1][valueField],
  71874. min = dataSource[minMax.minIndex][valueField],
  71875. max = dataSource[minMax.maxIndex][valueField],
  71876. formattedFirst = tooltip.formatValue(first),
  71877. formattedLast = tooltip.formatValue(last),
  71878. formattedMin = tooltip.formatValue(min),
  71879. formattedMax = tooltip.formatValue(max),
  71880. customizeObject = {
  71881. firstValue: formattedFirst,
  71882. lastValue: formattedLast,
  71883. minValue: formattedMin,
  71884. maxValue: formattedMax,
  71885. originalFirstValue: first,
  71886. originalLastValue: last,
  71887. originalMinValue: min,
  71888. originalMaxValue: max,
  71889. valueText: ['Start:', formattedFirst, 'End:', formattedLast, 'Min:', formattedMin, 'Max:', formattedMax]
  71890. };
  71891. if (options.type === 'winloss') {
  71892. customizeObject.originalThresholdValue = options.winlossThreshold;
  71893. customizeObject.thresholdValue = tooltip.formatValue(options.winlossThreshold)
  71894. }
  71895. return customizeObject
  71896. }
  71897. }).include(DX.ui.DataHelperMixin)
  71898. })(jQuery, DevExpress);
  71899. /*! Module viz-sparklines, file bullet.js */
  71900. (function($, DX) {
  71901. var charts = DX.viz.charts,
  71902. TARGET_MIN_Y = 0.02,
  71903. TARGET_MAX_Y = 0.98,
  71904. BAR_VALUE_MIN_Y = 0.1,
  71905. BAR_VALUE_MAX_Y = 0.9,
  71906. DEFAULT_CANVAS_WIDTH = 300,
  71907. DEFAULT_CANVAS_HEIGHT = 30,
  71908. DEFAULT_HORIZONTAL_MARGIN = 1,
  71909. DEFAULT_VERTICAL_MARGIN = 2,
  71910. DEFAULT_OPTIONS = {
  71911. disabled: false,
  71912. theme: 'default',
  71913. size: {},
  71914. margin: {}
  71915. },
  71916. _String = String,
  71917. _Number = Number,
  71918. _round = Math.round,
  71919. _isFinite = isFinite;
  71920. DX.viz.sparklines.Bullet = DX.viz.sparklines.BaseSparkline.inherit({
  71921. _widgetType: 'bullet',
  71922. _widgetClass: 'dxb',
  71923. _defaultSize: {
  71924. width: DEFAULT_CANVAS_WIDTH,
  71925. height: DEFAULT_CANVAS_HEIGHT,
  71926. left: DEFAULT_HORIZONTAL_MARGIN,
  71927. right: DEFAULT_HORIZONTAL_MARGIN,
  71928. top: DEFAULT_VERTICAL_MARGIN,
  71929. bottom: DEFAULT_VERTICAL_MARGIN
  71930. },
  71931. _disposeWidgetElements: function() {
  71932. delete this._zeroLevelPath;
  71933. delete this._targetPath;
  71934. delete this._barValuePath
  71935. },
  71936. _redrawWidgetElements: function() {
  71937. this._createTranslator();
  71938. this._drawBarValue();
  71939. this._drawTarget();
  71940. this._drawZeroLevel()
  71941. },
  71942. _cleanWidgetElements: function() {
  71943. this._zeroLevelPath.detach();
  71944. this._targetPath.detach();
  71945. this._barValuePath.detach()
  71946. },
  71947. _drawWidgetElements: function() {
  71948. this._drawBullet()
  71949. },
  71950. _createHtmlElements: function() {
  71951. var renderer = this._renderer;
  71952. this._zeroLevelPath = renderer.createPath(undefined, {'class': 'dxb-zero-level'});
  71953. this._targetPath = renderer.createPath(undefined, {'class': 'dxb-target'});
  71954. this._barValuePath = renderer.createPath(undefined, {'class': 'dxb-bar-value'})
  71955. },
  71956. _prepareOptions: function() {
  71957. var that = this,
  71958. options,
  71959. startScaleValue,
  71960. endScaleValue,
  71961. level,
  71962. value,
  71963. target;
  71964. that._allOptions = options = that.callBase(DEFAULT_OPTIONS);
  71965. if (that._allOptions.value === undefined)
  71966. that._allOptions.value = 0;
  71967. if (that._allOptions.target === undefined)
  71968. that._allOptions.target = 0;
  71969. options.value = value = _Number(options.value);
  71970. options.target = target = _Number(options.target);
  71971. if (that._allOptions.startScaleValue === undefined) {
  71972. that._allOptions.startScaleValue = target < value ? target : value;
  71973. that._allOptions.startScaleValue = that._allOptions.startScaleValue < 0 ? that._allOptions.startScaleValue : 0
  71974. }
  71975. if (that._allOptions.endScaleValue === undefined)
  71976. that._allOptions.endScaleValue = target > value ? target : value;
  71977. options.startScaleValue = startScaleValue = _Number(options.startScaleValue);
  71978. options.endScaleValue = endScaleValue = _Number(options.endScaleValue);
  71979. if (endScaleValue < startScaleValue) {
  71980. level = endScaleValue;
  71981. that._allOptions.endScaleValue = startScaleValue;
  71982. that._allOptions.startScaleValue = level;
  71983. that._allOptions.inverted = true
  71984. }
  71985. },
  71986. _createRange: function() {
  71987. var that = this,
  71988. options = that._allOptions;
  71989. that._ranges = {
  71990. arg: {
  71991. invert: options.inverted,
  71992. min: options.startScaleValue,
  71993. max: options.endScaleValue,
  71994. axisType: "continuous",
  71995. dataType: "numeric"
  71996. },
  71997. val: {
  71998. min: 0,
  71999. max: 1,
  72000. axisType: "continuous",
  72001. dataType: "numeric"
  72002. }
  72003. }
  72004. },
  72005. _drawBullet: function() {
  72006. var that = this,
  72007. options = that._allOptions,
  72008. isValidBounds = options.startScaleValue !== options.endScaleValue,
  72009. isValidMin = _isFinite(options.startScaleValue),
  72010. isValidMax = _isFinite(options.endScaleValue),
  72011. isValidValue = _isFinite(options.value),
  72012. isValidTarget = _isFinite(options.target);
  72013. if (isValidBounds && isValidMax && isValidMin && isValidTarget && isValidValue) {
  72014. this._drawBarValue();
  72015. this._drawTarget();
  72016. this._drawZeroLevel();
  72017. this._prepareTooltipContainer()
  72018. }
  72019. },
  72020. _getTargetParams: function() {
  72021. var that = this,
  72022. options = that._allOptions,
  72023. translatorX = that._translatorX,
  72024. translatorY = that._translatorY,
  72025. minY = translatorY.translate(TARGET_MIN_Y),
  72026. maxY = translatorY.translate(TARGET_MAX_Y),
  72027. x = translatorX.translate(options.target),
  72028. points = [{
  72029. x: x,
  72030. y: minY
  72031. }, {
  72032. x: x,
  72033. y: maxY
  72034. }];
  72035. return {
  72036. points: points,
  72037. stroke: options.targetColor,
  72038. strokeWidth: options.targetWidth
  72039. }
  72040. },
  72041. _getBarValueParams: function() {
  72042. var that = this,
  72043. options = that._allOptions,
  72044. translatorX = that._translatorX,
  72045. translatorY = that._translatorY,
  72046. startLevel = options.startScaleValue,
  72047. endLevel = options.endScaleValue,
  72048. value = options.value,
  72049. y2 = translatorY.translate(BAR_VALUE_MIN_Y),
  72050. y1 = translatorY.translate(BAR_VALUE_MAX_Y),
  72051. x1,
  72052. x2;
  72053. if (value > 0) {
  72054. x1 = startLevel <= 0 ? 0 : startLevel;
  72055. x2 = value >= endLevel ? endLevel : value
  72056. }
  72057. else {
  72058. x1 = endLevel >= 0 ? 0 : endLevel;
  72059. x2 = value >= startLevel ? value : startLevel
  72060. }
  72061. x1 = translatorX.translate(x1);
  72062. x2 = translatorX.translate(x2);
  72063. return {
  72064. points: [{
  72065. x: x1,
  72066. y: y1
  72067. }, {
  72068. x: x2,
  72069. y: y1
  72070. }, {
  72071. x: x2,
  72072. y: y2
  72073. }, {
  72074. x: x1,
  72075. y: y2
  72076. }],
  72077. fill: options.color
  72078. }
  72079. },
  72080. _getZeroLevelParams: function() {
  72081. var that = this,
  72082. options = that._allOptions,
  72083. translatorX = that._translatorX,
  72084. translatorY = that._translatorY,
  72085. minY = translatorY.translate(TARGET_MIN_Y),
  72086. maxY = translatorY.translate(TARGET_MAX_Y),
  72087. x = translatorX.translate(0);
  72088. return {
  72089. points: [{
  72090. x: x,
  72091. y: minY
  72092. }, {
  72093. x: x,
  72094. y: maxY
  72095. }],
  72096. stroke: options.targetColor,
  72097. strokeWidth: 1
  72098. }
  72099. },
  72100. _drawZeroLevel: function() {
  72101. var that = this,
  72102. options = that._allOptions,
  72103. params;
  72104. if (0 > options.endScaleValue || 0 < options.startScaleValue || !options.showZeroLevel)
  72105. return;
  72106. params = that._getZeroLevelParams();
  72107. that._zeroLevelPath.applySettings(params);
  72108. that._zeroLevelPath.append(that._renderer.getRoot())
  72109. },
  72110. _drawTarget: function() {
  72111. var that = this,
  72112. options = that._allOptions,
  72113. target = options.target,
  72114. startLevel = options.startScaleValue,
  72115. endLevel = options.endScaleValue,
  72116. params;
  72117. if (target > endLevel || target < startLevel || !options.showTarget)
  72118. return;
  72119. params = that._getTargetParams();
  72120. that._targetPath.applySettings(params);
  72121. that._targetPath.append(that._renderer.getRoot())
  72122. },
  72123. _drawBarValue: function() {
  72124. var that = this,
  72125. params = that._getBarValueParams();
  72126. that._barValuePath.applySettings(params);
  72127. that._barValuePath.append(that._renderer.getRoot())
  72128. },
  72129. _getTooltipData: function() {
  72130. var that = this,
  72131. tooltip = that._tooltip,
  72132. options = that._allOptions,
  72133. value = options.value,
  72134. target = options.target;
  72135. return {
  72136. originalValue: value,
  72137. originalTarget: target,
  72138. value: tooltip.formatValue(value),
  72139. target: tooltip.formatValue(target),
  72140. valueText: ['Actual Value:', value, 'Target Value:', target]
  72141. }
  72142. },
  72143. _getNormalTooltipSize: function() {
  72144. var size = {},
  72145. bbox = this._barValuePath.getBBox();
  72146. size.width = this._canvas.width;
  72147. size.left = 0;
  72148. size.tooltipLeft = bbox.x + _round(bbox.width / 2);
  72149. return size
  72150. },
  72151. _getWideTooltipSize: function(leftWidthDelta, rightWidthDelta) {
  72152. var that = this,
  72153. bbox = that._barValuePath.getBBox(),
  72154. horizontalPos = that._allOptions.tooltip.horizontalAlignment,
  72155. size = {};
  72156. size.width = leftWidthDelta + rightWidthDelta + that._canvas.width;
  72157. size.left = -leftWidthDelta;
  72158. if (horizontalPos === 'right')
  72159. size.tooltipLeft = bbox.x + _round(bbox.width / 2);
  72160. else if (horizontalPos === 'left')
  72161. size.tooltipLeft = _round(bbox.width / 2) + leftWidthDelta + rightWidthDelta + bbox.x;
  72162. else
  72163. size.tooltipLeft = _round(bbox.width / 2) + bbox.x + leftWidthDelta;
  72164. return size
  72165. }
  72166. })
  72167. })(jQuery, DevExpress);
  72168. /*! Module viz-sparklines, file dxSparkline.js */
  72169. (function($, DX, undefined) {
  72170. var ui = DX.ui,
  72171. viz = DX.viz;
  72172. DX.registerComponent("dxSparkline", viz.sparklines.Sparkline)
  72173. })(jQuery, DevExpress);
  72174. /*! Module viz-sparklines, file dxBullet.js */
  72175. (function($, DX, undefined) {
  72176. var ui = DX.ui,
  72177. viz = DX.viz;
  72178. DX.registerComponent("dxBullet", viz.sparklines.Bullet)
  72179. })(jQuery, DevExpress);
  72180. DevExpress.MOD_VIZ_SPARKLINES = true
  72181. }