dx.chartjs.debug.js.bak 1.9 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999
  1. /*!
  2. * DevExtreme Web
  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. };
  4754. var formattersV2 = $.extend({}, formatters, {
  4755. contains: createStringFuncFormatter("substringof", true),
  4756. notcontains: createStringFuncFormatter("not substringof", true)
  4757. });
  4758. var formattersV4 = $.extend({}, formatters, {
  4759. contains: createStringFuncFormatter("contains"),
  4760. notcontains: createStringFuncFormatter("not contains")
  4761. });
  4762. var compileBinary = function(criteria, bag, protocolVersion) {
  4763. criteria = data.utils.normalizeBinaryCriterion(criteria);
  4764. var op = criteria[1],
  4765. formatters = protocolVersion === 4 ? formattersV4 : formattersV2,
  4766. formatter = formatters[op.toLowerCase()];
  4767. if (!formatter)
  4768. throw Error("Unknown filter operation: " + op);
  4769. formatter(serializePropName(criteria[0]), serializeValue(criteria[2], protocolVersion), bag)
  4770. };
  4771. var compileGroup = function(criteria, bag, protocolVersion) {
  4772. var pushAnd = false;
  4773. $.each(criteria, function() {
  4774. if ($.isArray(this)) {
  4775. if (pushAnd)
  4776. bag.push(" and ");
  4777. bag.push("(");
  4778. compileCore(this, bag, protocolVersion);
  4779. bag.push(")");
  4780. pushAnd = true
  4781. }
  4782. else {
  4783. bag.push(/and|&/i.test(this) ? " and " : " or ");
  4784. pushAnd = false
  4785. }
  4786. })
  4787. };
  4788. var compileCore = function(criteria, bag, protocolVersion) {
  4789. if ($.isArray(criteria[0]))
  4790. compileGroup(criteria, bag, protocolVersion);
  4791. else
  4792. compileBinary(criteria, bag, protocolVersion)
  4793. };
  4794. return function(criteria, protocolVersion) {
  4795. var bag = [];
  4796. compileCore(criteria, bag, protocolVersion);
  4797. return bag.join("")
  4798. }
  4799. }();
  4800. var createODataQueryAdapter = function(queryOptions) {
  4801. var sorting = [],
  4802. criteria = [],
  4803. select,
  4804. skip,
  4805. take,
  4806. countQuery;
  4807. var hasSlice = function() {
  4808. return skip || take !== undefined
  4809. };
  4810. var sortCore = function(getter, desc, reset) {
  4811. if (hasSlice() || typeof getter !== "string")
  4812. return false;
  4813. if (reset)
  4814. sorting = [];
  4815. var rule = serializePropName(getter);
  4816. if (desc)
  4817. rule += " desc";
  4818. sorting.push(rule)
  4819. };
  4820. var generateExpand = function() {
  4821. var hash = {};
  4822. if (queryOptions.expand)
  4823. $.each($.makeArray(queryOptions.expand), function() {
  4824. hash[serializePropName(this)] = 1
  4825. });
  4826. if (select)
  4827. $.each(select, function() {
  4828. var path = this.split(".");
  4829. if (path.length < 2)
  4830. return;
  4831. path.pop();
  4832. hash[serializePropName(path.join("."))] = 1
  4833. });
  4834. return $.map(hash, function(k, v) {
  4835. return v
  4836. }).join() || undefined
  4837. };
  4838. var requestData = function() {
  4839. var result = {};
  4840. if (!countQuery) {
  4841. if (sorting.length)
  4842. result["$orderby"] = sorting.join(",");
  4843. if (skip)
  4844. result["$skip"] = skip;
  4845. if (take !== undefined)
  4846. result["$top"] = take;
  4847. if (select)
  4848. result["$select"] = serializePropName(select.join());
  4849. result["$expand"] = generateExpand()
  4850. }
  4851. if (criteria.length)
  4852. result["$filter"] = compileCriteria(criteria.length < 2 ? criteria[0] : criteria, queryOptions.version);
  4853. if (countQuery)
  4854. result["$top"] = 0;
  4855. if (queryOptions.requireTotalCount || countQuery)
  4856. if (queryOptions.version !== 4)
  4857. result["$inlinecount"] = "allpages";
  4858. else
  4859. result["$count"] = "true";
  4860. return result
  4861. };
  4862. return {
  4863. exec: function(url) {
  4864. return sendRequest({
  4865. url: url,
  4866. params: $.extend(requestData(), queryOptions && queryOptions.params)
  4867. }, {
  4868. beforeSend: queryOptions.beforeSend,
  4869. jsonp: queryOptions.jsonp,
  4870. withCredentials: queryOptions.withCredentials,
  4871. countOnly: countQuery
  4872. })
  4873. },
  4874. sortBy: function(getter, desc) {
  4875. return sortCore(getter, desc, true)
  4876. },
  4877. thenBy: function(getter, desc) {
  4878. return sortCore(getter, desc, false)
  4879. },
  4880. slice: function(skipCount, takeCount) {
  4881. if (hasSlice())
  4882. return false;
  4883. skip = skipCount;
  4884. take = takeCount
  4885. },
  4886. filter: function(criterion) {
  4887. if (hasSlice() || $.isFunction(criterion))
  4888. return false;
  4889. if (!$.isArray(criterion))
  4890. criterion = $.makeArray(arguments);
  4891. if (criteria.length)
  4892. criteria.push("and");
  4893. criteria.push(criterion)
  4894. },
  4895. select: function(expr) {
  4896. if (select || $.isFunction(expr))
  4897. return false;
  4898. if (!$.isArray(expr))
  4899. expr = $.makeArray(arguments);
  4900. select = expr
  4901. },
  4902. count: function() {
  4903. countQuery = true
  4904. }
  4905. }
  4906. };
  4907. $.extend(true, data, {
  4908. EdmLiteral: EdmLiteral,
  4909. utils: {odata: {
  4910. sendRequest: sendRequest,
  4911. serializePropName: serializePropName,
  4912. serializeValue: serializeValue,
  4913. serializeKey: serializeKey,
  4914. keyConverters: keyConverters
  4915. }},
  4916. queryAdapters: {odata: createODataQueryAdapter}
  4917. });
  4918. data.OData__internals = {interpretJsonFormat: interpretJsonFormat}
  4919. })(jQuery, DevExpress);
  4920. /*! Module core, file data.store.abstract.js */
  4921. (function($, DX, undefined) {
  4922. var Class = DX.Class,
  4923. abstract = DX.abstract,
  4924. data = DX.data,
  4925. normalizeSortingInfo = data.utils.normalizeSortingInfo;
  4926. var STORE_CALLBACK_NAMES = ["loading", "loaded", "modifying", "modified", "inserting", "inserted", "updating", "updated", "removing", "removed"];
  4927. function multiLevelGroup(query, groupInfo) {
  4928. query = query.groupBy(groupInfo[0].selector);
  4929. if (groupInfo.length > 1)
  4930. query = query.select(function(g) {
  4931. return $.extend({}, g, {items: multiLevelGroup(data.query(g.items), groupInfo.slice(1)).toArray()})
  4932. });
  4933. return query
  4934. }
  4935. data.utils.multiLevelGroup = multiLevelGroup;
  4936. function arrangeSortingInfo(groupInfo, sortInfo) {
  4937. var filteredGroup = [];
  4938. $.each(groupInfo, function(_, group) {
  4939. var collision = $.grep(sortInfo, function(sort) {
  4940. return group.selector == sort.selector
  4941. });
  4942. if (collision.length < 1)
  4943. filteredGroup.push(group)
  4944. });
  4945. return filteredGroup.concat(sortInfo)
  4946. }
  4947. data.Store = Class.inherit({
  4948. ctor: function(options) {
  4949. var that = this;
  4950. options = options || {};
  4951. $.each(STORE_CALLBACK_NAMES, function() {
  4952. var callbacks = that[this] = $.Callbacks();
  4953. if (this in options)
  4954. callbacks.add(options[this])
  4955. });
  4956. this._key = options.key;
  4957. this._errorHandler = options.errorHandler;
  4958. this._useDefaultSearch = true
  4959. },
  4960. _customLoadOptions: function() {
  4961. return null
  4962. },
  4963. key: function() {
  4964. return this._key
  4965. },
  4966. keyOf: function(obj) {
  4967. if (!this._keyGetter)
  4968. this._keyGetter = data.utils.compileGetter(this.key());
  4969. return this._keyGetter(obj)
  4970. },
  4971. _requireKey: function() {
  4972. if (!this.key())
  4973. throw Error("Key expression is required for this operation");
  4974. },
  4975. load: function(options) {
  4976. var that = this;
  4977. options = options || {};
  4978. this.loading.fire(options);
  4979. return this._loadImpl(options).done(function(result, extra) {
  4980. that.loaded.fire(result, extra)
  4981. })
  4982. },
  4983. _loadImpl: function(options) {
  4984. var filter = options.filter,
  4985. sort = options.sort,
  4986. select = options.select,
  4987. group = options.group,
  4988. skip = options.skip,
  4989. take = options.take,
  4990. q = this.createQuery(options);
  4991. if (filter)
  4992. q = q.filter(filter);
  4993. if (group)
  4994. group = normalizeSortingInfo(group);
  4995. if (sort || group) {
  4996. sort = normalizeSortingInfo(sort || []);
  4997. if (group)
  4998. sort = arrangeSortingInfo(group, sort);
  4999. $.each(sort, function(index) {
  5000. q = q[index ? "thenBy" : "sortBy"](this.selector, this.desc)
  5001. })
  5002. }
  5003. if (select)
  5004. q = q.select(select);
  5005. if (group)
  5006. q = multiLevelGroup(q, group);
  5007. if (take || skip)
  5008. q = q.slice(skip || 0, take);
  5009. return q.enumerate()
  5010. },
  5011. createQuery: abstract,
  5012. totalCount: function(options) {
  5013. return this._addFailHandlers(this._totalCountImpl(options))
  5014. },
  5015. _totalCountImpl: function(options) {
  5016. options = options || {};
  5017. var q = this.createQuery(),
  5018. group = options.group,
  5019. filter = options.filter;
  5020. if (filter)
  5021. q = q.filter(filter);
  5022. if (group) {
  5023. group = normalizeSortingInfo(group);
  5024. q = multiLevelGroup(q, group)
  5025. }
  5026. return q.count()
  5027. },
  5028. byKey: function(key, extraOptions) {
  5029. return this._addFailHandlers(this._byKeyImpl(key, extraOptions))
  5030. },
  5031. _byKeyImpl: abstract,
  5032. insert: function(values) {
  5033. var that = this;
  5034. that.modifying.fire();
  5035. that.inserting.fire(values);
  5036. return that._addFailHandlers(that._insertImpl(values).done(function(callbackValues, callbackKey) {
  5037. that.inserted.fire(callbackValues, callbackKey);
  5038. that.modified.fire()
  5039. }))
  5040. },
  5041. _insertImpl: abstract,
  5042. update: function(key, values) {
  5043. var that = this;
  5044. that.modifying.fire();
  5045. that.updating.fire(key, values);
  5046. return that._addFailHandlers(that._updateImpl(key, values).done(function(callbackKey, callbackValues) {
  5047. that.updated.fire(callbackKey, callbackValues);
  5048. that.modified.fire()
  5049. }))
  5050. },
  5051. _updateImpl: abstract,
  5052. remove: function(key) {
  5053. var that = this;
  5054. that.modifying.fire();
  5055. that.removing.fire(key);
  5056. return that._addFailHandlers(that._removeImpl(key).done(function(callbackKey) {
  5057. that.removed.fire(callbackKey);
  5058. that.modified.fire()
  5059. }))
  5060. },
  5061. _removeImpl: abstract,
  5062. _addFailHandlers: function(deferred) {
  5063. return deferred.fail(this._errorHandler, data._handleError)
  5064. }
  5065. })
  5066. })(jQuery, DevExpress);
  5067. /*! Module core, file data.store.array.js */
  5068. (function($, DX, undefined) {
  5069. var data = DX.data,
  5070. Guid = data.Guid;
  5071. var trivialPromise = function(_) {
  5072. var d = $.Deferred();
  5073. return d.resolve.apply(d, arguments).promise()
  5074. };
  5075. var rejectedPromise = function(_) {
  5076. var d = $.Deferred();
  5077. return d.reject.apply(d, arguments).promise()
  5078. };
  5079. data.ArrayStore = data.Store.inherit({
  5080. ctor: function(options) {
  5081. if ($.isArray(options))
  5082. options = {data: options};
  5083. else
  5084. options = options || {};
  5085. this.callBase(options);
  5086. var initialArray = options.data;
  5087. if (initialArray && !$.isArray(initialArray))
  5088. throw Error("Invalid 'data' option value");
  5089. this._array = initialArray || []
  5090. },
  5091. createQuery: function() {
  5092. return data.query(this._array, {errorHandler: this._errorHandler})
  5093. },
  5094. _byKeyImpl: function(key) {
  5095. return trivialPromise(this._array[this._indexByKey(key)])
  5096. },
  5097. _insertImpl: function(values) {
  5098. var keyExpr = this.key(),
  5099. keyValue,
  5100. obj = {};
  5101. $.extend(obj, values);
  5102. if (keyExpr) {
  5103. keyValue = this.keyOf(obj);
  5104. if (keyValue === undefined || typeof keyValue === "object" && $.isEmptyObject(keyValue)) {
  5105. if ($.isArray(keyExpr))
  5106. throw Error("Compound keys cannot be auto-generated");
  5107. keyValue = obj[keyExpr] = String(new Guid)
  5108. }
  5109. else if (this._array[this._indexByKey(keyValue)] !== undefined)
  5110. return rejectedPromise(Error("Attempt to insert an item with the duplicate key"))
  5111. }
  5112. else
  5113. keyValue = obj;
  5114. this._array.push(obj);
  5115. return trivialPromise(values, keyValue)
  5116. },
  5117. _updateImpl: function(key, values) {
  5118. var target;
  5119. if (this.key()) {
  5120. var index = this._indexByKey(key);
  5121. if (index < 0)
  5122. return rejectedPromise(Error("Data item not found"));
  5123. target = this._array[index]
  5124. }
  5125. else
  5126. target = key;
  5127. DX.utils.deepExtendArraySafe(target, values);
  5128. return trivialPromise(key, values)
  5129. },
  5130. _removeImpl: function(key) {
  5131. var index = this._indexByKey(key);
  5132. if (index > -1)
  5133. this._array.splice(index, 1);
  5134. return trivialPromise(key)
  5135. },
  5136. _indexByKey: function(key) {
  5137. for (var i = 0, arrayLength = this._array.length; i < arrayLength; i++)
  5138. if (data.utils.keysEqual(this.key(), this.keyOf(this._array[i]), key))
  5139. return i;
  5140. return -1
  5141. },
  5142. clear: function() {
  5143. this._array = []
  5144. }
  5145. })
  5146. })(jQuery, DevExpress);
  5147. /*! Module core, file data.store.local.js */
  5148. (function($, DX, undefined) {
  5149. var Class = DX.Class,
  5150. abstract = DX.abstract,
  5151. data = DX.data;
  5152. var LocalStoreBackend = Class.inherit({
  5153. ctor: function(store, storeOptions) {
  5154. this._store = store;
  5155. this._dirty = false;
  5156. var immediate = this._immediate = storeOptions.immediate;
  5157. var flushInterval = Math.max(100, storeOptions.flushInterval || 10 * 1000);
  5158. if (!immediate) {
  5159. var saveProxy = $.proxy(this.save, this);
  5160. setInterval(saveProxy, flushInterval);
  5161. $(window).on("beforeunload", saveProxy);
  5162. if (window.cordova)
  5163. document.addEventListener("pause", saveProxy, false)
  5164. }
  5165. },
  5166. notifyChanged: function() {
  5167. this._dirty = true;
  5168. if (this._immediate)
  5169. this.save()
  5170. },
  5171. load: function() {
  5172. this._store._array = this._loadImpl();
  5173. this._dirty = false
  5174. },
  5175. save: function() {
  5176. if (!this._dirty)
  5177. return;
  5178. this._saveImpl(this._store._array);
  5179. this._dirty = false
  5180. },
  5181. _loadImpl: abstract,
  5182. _saveImpl: abstract
  5183. });
  5184. var DomLocalStoreBackend = LocalStoreBackend.inherit({
  5185. ctor: function(store, storeOptions) {
  5186. this.callBase(store, storeOptions);
  5187. var name = storeOptions.name;
  5188. if (!name)
  5189. throw Error("Name is required");
  5190. this._key = "dx-data-localStore-" + name
  5191. },
  5192. _loadImpl: function() {
  5193. var raw = localStorage.getItem(this._key);
  5194. if (raw)
  5195. return JSON.parse(raw);
  5196. return []
  5197. },
  5198. _saveImpl: function(array) {
  5199. if (!array.length)
  5200. localStorage.removeItem(this._key);
  5201. else
  5202. localStorage.setItem(this._key, JSON.stringify(array))
  5203. }
  5204. });
  5205. var localStoreBackends = {dom: DomLocalStoreBackend};
  5206. data.LocalStore = data.ArrayStore.inherit({
  5207. ctor: function(options) {
  5208. if (typeof options === "string")
  5209. options = {name: options};
  5210. else
  5211. options = options || {};
  5212. this.callBase(options);
  5213. this._backend = new localStoreBackends[options.backend || "dom"](this, options);
  5214. this._backend.load()
  5215. },
  5216. clear: function() {
  5217. this.callBase();
  5218. this._backend.notifyChanged()
  5219. },
  5220. _insertImpl: function(values) {
  5221. var b = this._backend;
  5222. return this.callBase(values).done($.proxy(b.notifyChanged, b))
  5223. },
  5224. _updateImpl: function(key, values) {
  5225. var b = this._backend;
  5226. return this.callBase(key, values).done($.proxy(b.notifyChanged, b))
  5227. },
  5228. _removeImpl: function(key) {
  5229. var b = this._backend;
  5230. return this.callBase(key).done($.proxy(b.notifyChanged, b))
  5231. }
  5232. })
  5233. })(jQuery, DevExpress);
  5234. /*! Module core, file data.store.odata.js */
  5235. (function($, DX, undefined) {
  5236. var Class = DX.Class,
  5237. data = DX.data,
  5238. utils = DX.utils,
  5239. odataUtils = data.utils.odata;
  5240. var escapeServiceOperationParams = function(params, version) {
  5241. if (!params)
  5242. return params;
  5243. var result = {};
  5244. $.each(params, function(k, v) {
  5245. result[k] = odataUtils.serializeValue(v, version)
  5246. });
  5247. return result
  5248. };
  5249. var convertSimpleKey = function(keyType, keyValue) {
  5250. var converter = odataUtils.keyConverters[keyType];
  5251. if (!converter)
  5252. throw Error("Unknown key type: " + keyType);
  5253. return converter(keyValue)
  5254. };
  5255. var SharedMethods = {
  5256. _extractServiceOptions: function(options) {
  5257. options = options || {};
  5258. this._url = String(options.url).replace(/\/+$/, "");
  5259. this._beforeSend = options.beforeSend;
  5260. this._jsonp = options.jsonp;
  5261. this._version = options.version;
  5262. this._withCredentials = options.withCredentials
  5263. },
  5264. _sendRequest: function(url, method, params, payload) {
  5265. return odataUtils.sendRequest({
  5266. url: url,
  5267. method: method,
  5268. params: params || {},
  5269. payload: payload
  5270. }, {
  5271. beforeSend: this._beforeSend,
  5272. jsonp: this._jsonp,
  5273. withCredentials: this._withCredentials
  5274. })
  5275. },
  5276. version: function() {
  5277. return this._version
  5278. }
  5279. };
  5280. var ODataStore = data.Store.inherit({
  5281. ctor: function(options) {
  5282. this.callBase(options);
  5283. this._extractServiceOptions(options);
  5284. this._keyType = options.keyType
  5285. },
  5286. _customLoadOptions: function() {
  5287. return ["expand", "customQueryParams"]
  5288. },
  5289. _byKeyImpl: function(key, extraOptions) {
  5290. var params = {};
  5291. if (extraOptions)
  5292. if (extraOptions.expand)
  5293. params["$expand"] = $.map($.makeArray(extraOptions.expand), odataUtils.serializePropName).join();
  5294. return this._sendRequest(this._byKeyUrl(key), "GET", params)
  5295. },
  5296. createQuery: function(loadOptions) {
  5297. loadOptions = loadOptions || {};
  5298. return data.query(this._url, {
  5299. beforeSend: this._beforeSend,
  5300. errorHandler: this._errorHandler,
  5301. jsonp: this._jsonp,
  5302. version: this._version,
  5303. withCredentials: this._withCredentials,
  5304. params: escapeServiceOperationParams(loadOptions.customQueryParams, this._version),
  5305. expand: loadOptions.expand,
  5306. requireTotalCount: loadOptions.requireTotalCount
  5307. })
  5308. },
  5309. _insertImpl: function(values) {
  5310. this._requireKey();
  5311. var that = this,
  5312. d = $.Deferred();
  5313. $.when(this._sendRequest(this._url, "POST", null, values)).done(function(serverResponse) {
  5314. d.resolve(values, that.keyOf(serverResponse))
  5315. }).fail($.proxy(d.reject, d));
  5316. return d.promise()
  5317. },
  5318. _updateImpl: function(key, values) {
  5319. var d = $.Deferred();
  5320. $.when(this._sendRequest(this._byKeyUrl(key), "MERGE", null, values)).done(function() {
  5321. d.resolve(key, values)
  5322. }).fail($.proxy(d.reject, d));
  5323. return d.promise()
  5324. },
  5325. _removeImpl: function(key) {
  5326. var d = $.Deferred();
  5327. $.when(this._sendRequest(this._byKeyUrl(key), "DELETE")).done(function() {
  5328. d.resolve(key)
  5329. }).fail($.proxy(d.reject, d));
  5330. return d.promise()
  5331. },
  5332. _byKeyUrl: function(key) {
  5333. var keyType = this._keyType;
  5334. if ($.isPlainObject(keyType))
  5335. $.each(keyType, function(subKeyName, subKeyType) {
  5336. key[subKeyName] = convertSimpleKey(subKeyType, key[subKeyName])
  5337. });
  5338. else if (keyType)
  5339. key = convertSimpleKey(keyType, key);
  5340. return this._url + "(" + encodeURIComponent(odataUtils.serializeKey(key, this._version)) + ")"
  5341. }
  5342. }).include(SharedMethods);
  5343. var ODataContext = Class.inherit({
  5344. ctor: function(options) {
  5345. var that = this;
  5346. that._extractServiceOptions(options);
  5347. that._errorHandler = options.errorHandler;
  5348. $.each(options.entities || [], function(entityAlias, entityOptions) {
  5349. that[entityAlias] = new ODataStore($.extend({}, options, {url: that._url + "/" + encodeURIComponent(entityOptions.name || entityAlias)}, entityOptions))
  5350. })
  5351. },
  5352. get: function(operationName, params) {
  5353. return this.invoke(operationName, params, "GET")
  5354. },
  5355. invoke: function(operationName, params, httpMethod) {
  5356. httpMethod = httpMethod || "POST";
  5357. var d = $.Deferred();
  5358. $.when(this._sendRequest(this._url + "/" + encodeURIComponent(operationName), httpMethod, escapeServiceOperationParams(params, this._version))).done(function(r) {
  5359. if (r && operationName in r)
  5360. r = r[operationName];
  5361. d.resolve(r)
  5362. }).fail([this._errorHandler, data._handleError, $.proxy(d.reject, d)]);
  5363. return d.promise()
  5364. },
  5365. objectLink: function(entityAlias, key) {
  5366. var store = this[entityAlias];
  5367. if (!store)
  5368. throw Error("Unknown entity name or alias: " + entityAlias);
  5369. if (!utils.isDefined(key))
  5370. return null;
  5371. return {__metadata: {uri: store._byKeyUrl(key)}}
  5372. }
  5373. }).include(SharedMethods);
  5374. $.extend(data, {
  5375. ODataStore: ODataStore,
  5376. ODataContext: ODataContext
  5377. })
  5378. })(jQuery, DevExpress);
  5379. /*! Module core, file data.store.rest.js */
  5380. (function($, DX, undefined) {
  5381. var data = DX.data;
  5382. function createAjaxFailureHandler(deferred) {
  5383. return function(xhr, textStatus) {
  5384. if (!xhr || !xhr.getResponseHeader)
  5385. deferred.reject.apply(deferred, arguments);
  5386. else
  5387. deferred.reject(Error(data.utils.errorMessageFromXhr(xhr, textStatus)))
  5388. }
  5389. }
  5390. function operationCustomizerPropName(operationName) {
  5391. return "_customize" + DX.inflector.camelize(operationName, true)
  5392. }
  5393. function pathPropName(operationName) {
  5394. return "_" + operationName + "Path"
  5395. }
  5396. data.RestStore = data.Store.inherit({
  5397. ctor: function(options) {
  5398. DX.utils.logger.warn("RestStore is deprecated, use CustomStore instead");
  5399. var that = this;
  5400. that.callBase(options);
  5401. options = options || {};
  5402. that._url = String(options.url).replace(/\/+$/, "");
  5403. that._jsonp = options.jsonp;
  5404. that._withCredentials = options.withCredentials;
  5405. $.each(["Load", "Insert", "Update", "Remove", "ByKey", "Operation"], function() {
  5406. var value = options["customize" + this];
  5407. if (value)
  5408. that[operationCustomizerPropName(this)] = value
  5409. });
  5410. $.each(["load", "insert", "update", "remove", "byKey"], function() {
  5411. var value = options[this + "Path"];
  5412. if (value)
  5413. that[pathPropName(this)] = value
  5414. })
  5415. },
  5416. _loadImpl: function(options) {
  5417. var d = $.Deferred(),
  5418. ajaxOptions = {
  5419. url: this._formatUrlNoKey("load"),
  5420. type: "GET"
  5421. };
  5422. $.when(this._createAjax(ajaxOptions, "load", options)).done($.proxy(d.resolve, d)).fail(createAjaxFailureHandler(d));
  5423. return this._addFailHandlers(d.promise())
  5424. },
  5425. createQuery: function() {
  5426. throw Error("Not supported");
  5427. },
  5428. _insertImpl: function(values) {
  5429. var d = $.Deferred(),
  5430. that = this,
  5431. ajaxOptions = {
  5432. url: this._formatUrlNoKey("insert"),
  5433. type: "POST",
  5434. contentType: "application/json",
  5435. data: JSON.stringify(values)
  5436. };
  5437. $.when(this._createAjax(ajaxOptions, "insert")).done(function(serverResponse) {
  5438. d.resolve(values, that.key() && that.keyOf(serverResponse))
  5439. }).fail(createAjaxFailureHandler(d));
  5440. return d.promise()
  5441. },
  5442. _updateImpl: function(key, values) {
  5443. var d = $.Deferred(),
  5444. ajaxOptions = {
  5445. url: this._formatUrlWithKey("update", key),
  5446. type: "PUT",
  5447. contentType: "application/json",
  5448. data: JSON.stringify(values)
  5449. };
  5450. $.when(this._createAjax(ajaxOptions, "update")).done(function() {
  5451. d.resolve(key, values)
  5452. }).fail(createAjaxFailureHandler(d));
  5453. return d.promise()
  5454. },
  5455. _removeImpl: function(key) {
  5456. var d = $.Deferred(),
  5457. ajaxOptions = {
  5458. url: this._formatUrlWithKey("remove", key),
  5459. type: "DELETE"
  5460. };
  5461. $.when(this._createAjax(ajaxOptions, "remove")).done(function() {
  5462. d.resolve(key)
  5463. }).fail(createAjaxFailureHandler(d));
  5464. return d.promise()
  5465. },
  5466. _byKeyImpl: function(key) {
  5467. var d = $.Deferred(),
  5468. ajaxOptions = {
  5469. url: this._formatUrlWithKey("byKey", key),
  5470. type: "GET"
  5471. };
  5472. $.when(this._createAjax(ajaxOptions, "byKey")).done(function(data) {
  5473. d.resolve(data)
  5474. }).fail(createAjaxFailureHandler(d));
  5475. return d.promise()
  5476. },
  5477. _createAjax: function(ajaxOptions, operationName, extra) {
  5478. var customizationFunc,
  5479. customizationResult;
  5480. function isDeferred(obj) {
  5481. return "done" in obj && "fail" in obj
  5482. }
  5483. if (this._jsonp && ajaxOptions.type === "GET")
  5484. ajaxOptions.dataType = "jsonp";
  5485. else
  5486. $.extend(true, ajaxOptions, {xhrFields: {withCredentials: this._withCredentials}});
  5487. customizationFunc = this[operationCustomizerPropName("operation")];
  5488. if (customizationFunc) {
  5489. customizationResult = customizationFunc(ajaxOptions, operationName, extra);
  5490. if (customizationResult) {
  5491. if (isDeferred(customizationResult))
  5492. return customizationResult;
  5493. ajaxOptions = customizationResult
  5494. }
  5495. }
  5496. customizationFunc = this[operationCustomizerPropName(operationName)];
  5497. if (customizationFunc) {
  5498. customizationResult = customizationFunc(ajaxOptions, extra);
  5499. if (customizationResult) {
  5500. if (isDeferred(customizationResult))
  5501. return customizationResult;
  5502. ajaxOptions = customizationResult
  5503. }
  5504. }
  5505. return $.ajax(ajaxOptions)
  5506. },
  5507. _formatUrlNoKey: function(operationName) {
  5508. var url = this._url,
  5509. path = this[pathPropName(operationName)];
  5510. if (!path)
  5511. return url;
  5512. if ($.isFunction(path))
  5513. return path(url);
  5514. return url + "/" + path
  5515. },
  5516. _formatUrlWithKey: function(operationName, key) {
  5517. var url = this._url,
  5518. path = this[pathPropName(operationName)];
  5519. if (!path)
  5520. return url + "/" + encodeURIComponent(key);
  5521. if ($.isFunction(path))
  5522. return path(url, key);
  5523. return url + "/" + path + "/" + encodeURIComponent(key)
  5524. }
  5525. })
  5526. })(jQuery, DevExpress);
  5527. /*! Module core, file data.store.custom.js */
  5528. (function($, DX, undefined) {
  5529. var data = DX.data;
  5530. var ERROR_QUERY_NOT_SUPPORTED = "CustomStore does not support creating queries",
  5531. ERROR_MISSING_USER_FUNC = "Required option is not specified or is not a function: ",
  5532. ERROR_INVALID_RETURN = "Invalid return value: ";
  5533. var TOTAL_COUNT = "totalCount",
  5534. LOAD = "load",
  5535. BY_KEY = "byKey",
  5536. INSERT = "insert",
  5537. UPDATE = "update",
  5538. REMOVE = "remove";
  5539. function isPromise(obj) {
  5540. return obj && $.isFunction(obj.done) && $.isFunction(obj.fail) && $.isFunction(obj.promise)
  5541. }
  5542. function trivialPromise(value) {
  5543. return $.Deferred().resolve(value).promise()
  5544. }
  5545. function ensureRequiredFuncOption(name, obj) {
  5546. if (!$.isFunction(obj))
  5547. throw Error(ERROR_MISSING_USER_FUNC + name);
  5548. }
  5549. function throwInvalidUserFuncResult(name) {
  5550. throw Error(ERROR_INVALID_RETURN + name);
  5551. }
  5552. function createUserFuncFailureHandler(pendingDeferred) {
  5553. function errorMessageFromXhr(promiseArguments) {
  5554. var xhr = promiseArguments[0],
  5555. textStatus = promiseArguments[1];
  5556. if (!xhr || !xhr.getResponseHeader)
  5557. return null;
  5558. return data.utils.errorMessageFromXhr(xhr, textStatus)
  5559. }
  5560. return function(arg) {
  5561. var error;
  5562. if (arg instanceof Error)
  5563. error = arg;
  5564. else
  5565. error = Error(errorMessageFromXhr(arguments) || arg && String(arg) || "Unknown error");
  5566. pendingDeferred.reject(error)
  5567. }
  5568. }
  5569. data.CustomStore = data.Store.inherit({
  5570. ctor: function(options) {
  5571. options = options || {};
  5572. this.callBase(options);
  5573. this._useDefaultSearch = false;
  5574. this._loadFunc = options[LOAD];
  5575. this._totalCountFunc = options[TOTAL_COUNT];
  5576. this._byKeyFunc = options[BY_KEY] || options.lookup;
  5577. this._insertFunc = options[INSERT];
  5578. this._updateFunc = options[UPDATE];
  5579. this._removeFunc = options[REMOVE]
  5580. },
  5581. createQuery: function() {
  5582. throw Error(ERROR_QUERY_NOT_SUPPORTED);
  5583. },
  5584. _totalCountImpl: function(options) {
  5585. var userFunc = this._totalCountFunc,
  5586. userResult,
  5587. d = $.Deferred();
  5588. ensureRequiredFuncOption(TOTAL_COUNT, userFunc);
  5589. userResult = userFunc(options);
  5590. if (!isPromise(userResult)) {
  5591. userResult = Number(userResult);
  5592. if (!isFinite(userResult))
  5593. throwInvalidUserFuncResult(TOTAL_COUNT);
  5594. userResult = trivialPromise(userResult)
  5595. }
  5596. userResult.done(function(count) {
  5597. d.resolve(Number(count))
  5598. }).fail(createUserFuncFailureHandler(d));
  5599. return d.promise()
  5600. },
  5601. _loadImpl: function(options) {
  5602. var userFunc = this._loadFunc,
  5603. userResult,
  5604. d = $.Deferred();
  5605. ensureRequiredFuncOption(LOAD, userFunc);
  5606. userResult = userFunc(options);
  5607. if ($.isArray(userResult))
  5608. userResult = trivialPromise(userResult);
  5609. else if (userResult === null || userResult === undefined)
  5610. userResult = trivialPromise([]);
  5611. else if (!isPromise(userResult))
  5612. throwInvalidUserFuncResult(LOAD);
  5613. userResult.done(function(data, extra) {
  5614. d.resolve(data, extra)
  5615. }).fail(createUserFuncFailureHandler(d));
  5616. return this._addFailHandlers(d.promise())
  5617. },
  5618. _byKeyImpl: function(key) {
  5619. var userFunc = this._byKeyFunc,
  5620. userResult,
  5621. d = $.Deferred();
  5622. ensureRequiredFuncOption(BY_KEY, userFunc);
  5623. userResult = userFunc(key);
  5624. if (!isPromise(userResult))
  5625. userResult = trivialPromise(userResult);
  5626. userResult.done(function(obj) {
  5627. d.resolve(obj)
  5628. }).fail(createUserFuncFailureHandler(d));
  5629. return d.promise()
  5630. },
  5631. _insertImpl: function(values) {
  5632. var userFunc = this._insertFunc,
  5633. userResult,
  5634. d = $.Deferred();
  5635. ensureRequiredFuncOption(INSERT, userFunc);
  5636. userResult = userFunc(values);
  5637. if (!isPromise(userResult))
  5638. userResult = trivialPromise(userResult);
  5639. userResult.done(function(newKey) {
  5640. d.resolve(values, newKey)
  5641. }).fail(createUserFuncFailureHandler(d));
  5642. return d.promise()
  5643. },
  5644. _updateImpl: function(key, values) {
  5645. var userFunc = this._updateFunc,
  5646. userResult,
  5647. d = $.Deferred();
  5648. ensureRequiredFuncOption(UPDATE, userFunc);
  5649. userResult = userFunc(key, values);
  5650. if (!isPromise(userResult))
  5651. userResult = trivialPromise();
  5652. userResult.done(function() {
  5653. d.resolve(key, values)
  5654. }).fail(createUserFuncFailureHandler(d));
  5655. return d.promise()
  5656. },
  5657. _removeImpl: function(key) {
  5658. var userFunc = this._removeFunc,
  5659. userResult,
  5660. d = $.Deferred();
  5661. ensureRequiredFuncOption(REMOVE, userFunc);
  5662. userResult = userFunc(key);
  5663. if (!isPromise(userResult))
  5664. userResult = trivialPromise();
  5665. userResult.done(function() {
  5666. d.resolve(key)
  5667. }).fail(createUserFuncFailureHandler(d));
  5668. return d.promise()
  5669. }
  5670. });
  5671. data.CustomStore_internals = {ERRORS: {
  5672. QUERY_NOT_SUPPORTED: ERROR_QUERY_NOT_SUPPORTED,
  5673. MISSING_USER_FUNC: ERROR_MISSING_USER_FUNC,
  5674. INVALID_RETURN: ERROR_INVALID_RETURN
  5675. }}
  5676. })(jQuery, DevExpress);
  5677. /*! Module core, file data.dataSource.js */
  5678. (function($, DX, undefined) {
  5679. var data = DX.data,
  5680. CustomStore = data.CustomStore,
  5681. Class = DX.Class;
  5682. var storeTypeRegistry = {
  5683. jaydata: "JayDataStore",
  5684. breeze: "BreezeStore",
  5685. odata: "ODataStore",
  5686. local: "LocalStore",
  5687. array: "ArrayStore"
  5688. };
  5689. function normalizeDataSourceOptions(options) {
  5690. var store;
  5691. function createCustomStoreFromLoadFunc() {
  5692. var storeConfig = {};
  5693. $.each(["key", "load", "byKey", "lookup", "totalCount", "insert", "update", "remove"], function() {
  5694. storeConfig[this] = options[this];
  5695. delete options[this]
  5696. });
  5697. return new CustomStore(storeConfig)
  5698. }
  5699. function createStoreFromConfig(storeConfig) {
  5700. var storeCtor = data[storeTypeRegistry[storeConfig.type]];
  5701. delete storeConfig.type;
  5702. return new storeCtor(storeConfig)
  5703. }
  5704. function createCustomStoreFromUrl(url) {
  5705. return new CustomStore({load: function() {
  5706. return $.getJSON(url)
  5707. }})
  5708. }
  5709. if (typeof options === "string")
  5710. options = createCustomStoreFromUrl(options);
  5711. if (options === undefined)
  5712. options = [];
  5713. if ($.isArray(options) || options instanceof data.Store)
  5714. options = {store: options};
  5715. else
  5716. options = $.extend({}, options);
  5717. if (options.store === undefined)
  5718. options.store = [];
  5719. store = options.store;
  5720. if ("load" in options)
  5721. store = createCustomStoreFromLoadFunc();
  5722. else if ($.isArray(store))
  5723. store = new data.ArrayStore(store);
  5724. else if ($.isPlainObject(store))
  5725. store = createStoreFromConfig($.extend({}, store));
  5726. options.store = store;
  5727. return options
  5728. }
  5729. function normalizeStoreLoadOptionAccessorArguments(originalArguments) {
  5730. switch (originalArguments.length) {
  5731. case 0:
  5732. return undefined;
  5733. case 1:
  5734. return originalArguments[0]
  5735. }
  5736. return $.makeArray(originalArguments)
  5737. }
  5738. function generateStoreLoadOptionAccessor(optionName) {
  5739. return function() {
  5740. var args = normalizeStoreLoadOptionAccessorArguments(arguments);
  5741. if (args !== undefined)
  5742. this._storeLoadOptions[optionName] = args;
  5743. return this._storeLoadOptions[optionName]
  5744. }
  5745. }
  5746. function addOldUserDataSourceBackwardCompatibilityOptions(dataSource, storeLoadOptions) {
  5747. storeLoadOptions.refresh = !dataSource._paginate || dataSource._pageIndex === 0;
  5748. if (storeLoadOptions.searchValue !== null)
  5749. storeLoadOptions.searchString = storeLoadOptions.searchValue
  5750. }
  5751. var DataSource = Class.inherit({
  5752. ctor: function(options) {
  5753. options = normalizeDataSourceOptions(options);
  5754. this._store = options.store;
  5755. this._storeLoadOptions = this._extractLoadOptions(options);
  5756. this._mapFunc = options.map;
  5757. this._postProcessFunc = options.postProcess;
  5758. this._pageIndex = 0;
  5759. this._pageSize = options.pageSize !== undefined ? options.pageSize : 20;
  5760. this._items = [];
  5761. this._totalCount = -1;
  5762. this._isLoaded = false;
  5763. this._loadingCount = 0;
  5764. this._preferSync = options._preferSync;
  5765. this._loadQueue = this._createLoadQueue();
  5766. this._searchValue = "searchValue" in options ? options.searchValue : null;
  5767. this._searchOperation = options.searchOperation || "contains";
  5768. this._searchExpr = options.searchExpr;
  5769. this._paginate = options.paginate;
  5770. if (this._paginate === undefined)
  5771. this._paginate = !this.group();
  5772. this._isLastPage = !this._paginate;
  5773. this._userData = {};
  5774. this.changed = $.Callbacks();
  5775. this.loadError = $.Callbacks();
  5776. this.loadingChanged = $.Callbacks()
  5777. },
  5778. dispose: function() {
  5779. this.changed.empty();
  5780. this.loadError.empty();
  5781. this.loadingChanged.empty();
  5782. delete this._store;
  5783. this._disposed = true
  5784. },
  5785. _extractLoadOptions: function(options) {
  5786. var result = {},
  5787. names = ["sort", "filter", "select", "group", "requireTotalCount"],
  5788. customNames = this._store._customLoadOptions();
  5789. if (customNames)
  5790. names = names.concat(customNames);
  5791. $.each(names, function() {
  5792. result[this] = options[this]
  5793. });
  5794. return result
  5795. },
  5796. loadOptions: function() {
  5797. return this._storeLoadOptions
  5798. },
  5799. items: function() {
  5800. return this._items
  5801. },
  5802. pageIndex: function(newIndex) {
  5803. if (newIndex !== undefined) {
  5804. this._pageIndex = newIndex;
  5805. this._isLastPage = !this._paginate
  5806. }
  5807. return this._pageIndex
  5808. },
  5809. paginate: function(value) {
  5810. if (arguments.length < 1)
  5811. return this._paginate;
  5812. value = !!value;
  5813. if (this._paginate !== value) {
  5814. this._paginate = value;
  5815. this.pageIndex(0)
  5816. }
  5817. },
  5818. isLastPage: function() {
  5819. return this._isLastPage
  5820. },
  5821. sort: generateStoreLoadOptionAccessor("sort"),
  5822. filter: function() {
  5823. var newFilter = normalizeStoreLoadOptionAccessorArguments(arguments);
  5824. if (newFilter !== undefined) {
  5825. this._storeLoadOptions.filter = newFilter;
  5826. this.pageIndex(0)
  5827. }
  5828. return this._storeLoadOptions.filter
  5829. },
  5830. group: generateStoreLoadOptionAccessor("group"),
  5831. select: generateStoreLoadOptionAccessor("select"),
  5832. searchValue: function(value) {
  5833. if (value !== undefined) {
  5834. this.pageIndex(0);
  5835. this._searchValue = value
  5836. }
  5837. return this._searchValue
  5838. },
  5839. searchOperation: function(op) {
  5840. if (op !== undefined) {
  5841. this.pageIndex(0);
  5842. this._searchOperation = op
  5843. }
  5844. return this._searchOperation
  5845. },
  5846. searchExpr: function(expr) {
  5847. var argc = arguments.length;
  5848. if (argc) {
  5849. if (argc > 1)
  5850. expr = $.makeArray(arguments);
  5851. this.pageIndex(0);
  5852. this._searchExpr = expr
  5853. }
  5854. return this._searchExpr
  5855. },
  5856. store: function() {
  5857. return this._store
  5858. },
  5859. key: function() {
  5860. return this._store && this._store.key()
  5861. },
  5862. totalCount: function() {
  5863. return this._totalCount
  5864. },
  5865. isLoaded: function() {
  5866. return this._isLoaded
  5867. },
  5868. isLoading: function() {
  5869. return this._loadingCount > 0
  5870. },
  5871. _createLoadQueue: function() {
  5872. return DX.createQueue()
  5873. },
  5874. _changeLoadingCount: function(increment) {
  5875. var oldLoading = this.isLoading(),
  5876. newLoading;
  5877. this._loadingCount += increment;
  5878. newLoading = this.isLoading();
  5879. if (oldLoading ^ newLoading)
  5880. this.loadingChanged.fire(newLoading)
  5881. },
  5882. _scheduleLoadCallbacks: function(deferred) {
  5883. var thisSource = this;
  5884. thisSource._changeLoadingCount(1);
  5885. deferred.always(function() {
  5886. thisSource._changeLoadingCount(-1)
  5887. })
  5888. },
  5889. _scheduleChangedCallbacks: function(deferred) {
  5890. var that = this;
  5891. deferred.done(function() {
  5892. that.changed.fire()
  5893. })
  5894. },
  5895. loadSingle: function(propName, propValue) {
  5896. var that = this;
  5897. var d = $.Deferred().fail(this.loadError.fire),
  5898. key = this.key(),
  5899. store = this._store,
  5900. loadOptions = this._createStoreLoadOptions();
  5901. function handleSuccess(data) {
  5902. d.resolve(that._transformLoadedData(data)[0])
  5903. }
  5904. if (arguments.length < 2) {
  5905. propValue = propName;
  5906. propName = key
  5907. }
  5908. delete loadOptions.skip;
  5909. delete loadOptions.group;
  5910. delete loadOptions.refresh;
  5911. delete loadOptions.pageIndex;
  5912. delete loadOptions.searchString;
  5913. if (propName === key || store instanceof data.CustomStore)
  5914. store.byKey(propValue, loadOptions).done(handleSuccess).fail(d.reject);
  5915. else {
  5916. loadOptions.take = 1;
  5917. loadOptions._preferSync = true;
  5918. loadOptions.filter = loadOptions.filter ? [loadOptions.filter, [propName, propValue]] : [propName, propValue];
  5919. store.load(loadOptions).done(handleSuccess).fail(d.reject)
  5920. }
  5921. return d.promise()
  5922. },
  5923. load: function() {
  5924. var thisSource = this,
  5925. d = $.Deferred(),
  5926. errorCallback = this.loadError,
  5927. storeLoadOptions;
  5928. this._scheduleLoadCallbacks(d);
  5929. this._scheduleChangedCallbacks(d);
  5930. storeLoadOptions = this._createStoreLoadOptions();
  5931. function loadTask() {
  5932. if (thisSource._disposed)
  5933. return undefined;
  5934. return thisSource._loadFromStore(storeLoadOptions, d)
  5935. }
  5936. this._loadQueue.add(function() {
  5937. loadTask();
  5938. return d.promise()
  5939. }, function() {
  5940. thisSource._changeLoadingCount(-1)
  5941. });
  5942. return d.promise().fail($.proxy(errorCallback.fire, errorCallback))
  5943. },
  5944. _addSearchOptions: function(storeLoadOptions) {
  5945. if (this._disposed)
  5946. return;
  5947. if (this.store()._useDefaultSearch)
  5948. this._addSearchFilter(storeLoadOptions);
  5949. else {
  5950. storeLoadOptions.searchValue = this._searchValue;
  5951. storeLoadOptions.searchExpr = this._searchExpr
  5952. }
  5953. },
  5954. _createStoreLoadOptions: function() {
  5955. var result = $.extend({}, this._storeLoadOptions);
  5956. this._addSearchOptions(result);
  5957. if (this._paginate) {
  5958. result.pageIndex = this._pageIndex;
  5959. if (this._pageSize) {
  5960. result.skip = this._pageIndex * this._pageSize;
  5961. result.take = this._pageSize
  5962. }
  5963. }
  5964. result.userData = this._userData;
  5965. addOldUserDataSourceBackwardCompatibilityOptions(this, result);
  5966. return result
  5967. },
  5968. _addSearchFilter: function(storeLoadOptions) {
  5969. var value = this._searchValue,
  5970. op = this._searchOperation,
  5971. selector = this._searchExpr,
  5972. searchFilter = [];
  5973. if (!value)
  5974. return;
  5975. if (!selector)
  5976. selector = "this";
  5977. if (!$.isArray(selector))
  5978. selector = [selector];
  5979. $.each(selector, function(i, item) {
  5980. if (searchFilter.length)
  5981. searchFilter.push("or");
  5982. searchFilter.push([item, op, value])
  5983. });
  5984. if (storeLoadOptions.filter)
  5985. storeLoadOptions.filter = [searchFilter, storeLoadOptions.filter];
  5986. else
  5987. storeLoadOptions.filter = searchFilter
  5988. },
  5989. _loadFromStore: function(storeLoadOptions, pendingDeferred) {
  5990. var thisSource = this;
  5991. function handleSuccess(data, extra) {
  5992. function processResult() {
  5993. thisSource._processStoreLoadResult(data, extra, storeLoadOptions, pendingDeferred)
  5994. }
  5995. if (thisSource._preferSync)
  5996. processResult();
  5997. else
  5998. DX.utils.executeAsync(processResult)
  5999. }
  6000. return this.store().load(storeLoadOptions).done(handleSuccess).fail($.proxy(pendingDeferred.reject, pendingDeferred))
  6001. },
  6002. _processStoreLoadResult: function(data, extra, storeLoadOptions, pendingDeferred) {
  6003. var thisSource = this;
  6004. function resolvePendingDeferred() {
  6005. thisSource._isLoaded = true;
  6006. thisSource._totalCount = isFinite(extra.totalCount) ? extra.totalCount : -1;
  6007. return pendingDeferred.resolve(data, extra)
  6008. }
  6009. function proceedLoadingTotalCount() {
  6010. thisSource.store().totalCount(storeLoadOptions).done(function(count) {
  6011. extra.totalCount = count;
  6012. resolvePendingDeferred()
  6013. }).fail(function(){})
  6014. }
  6015. if (thisSource._disposed)
  6016. return;
  6017. data = thisSource._transformLoadedData(data);
  6018. if (!$.isPlainObject(extra))
  6019. extra = {};
  6020. thisSource._items = data;
  6021. if (!data.length || !thisSource._paginate || thisSource._pageSize && data.length < thisSource._pageSize)
  6022. thisSource._isLastPage = true;
  6023. if (storeLoadOptions.requireTotalCount && !isFinite(extra.totalCount))
  6024. proceedLoadingTotalCount();
  6025. else
  6026. resolvePendingDeferred()
  6027. },
  6028. _transformLoadedData: function(data) {
  6029. var result = $.makeArray(data);
  6030. if (this._mapFunc)
  6031. result = $.map(result, this._mapFunc);
  6032. if (this._postProcessFunc)
  6033. result = this._postProcessFunc(result);
  6034. return result
  6035. }
  6036. });
  6037. data.Store.redefine({toDataSource: function(options) {
  6038. DX.utils.logger.warn("toDataSource() method is deprecated, use 'new DevExpress.data.DataSource(...)' instead");
  6039. return new DataSource($.extend({store: this}, options))
  6040. }});
  6041. $.extend(true, data, {
  6042. DataSource: DataSource,
  6043. createDataSource: function(options) {
  6044. DX.utils.logger.warn("createDataSource() method is deprecated, use 'new DevExpress.data.DataSource(...)' instead");
  6045. return new DataSource(options)
  6046. },
  6047. utils: {
  6048. storeTypeRegistry: storeTypeRegistry,
  6049. normalizeDataSourceOptions: normalizeDataSourceOptions
  6050. }
  6051. })
  6052. })(jQuery, DevExpress);
  6053. /*! Module core, file ko.js */
  6054. (function($, DX, undefined) {
  6055. if (!DX.support.hasKo)
  6056. return;
  6057. var ko = window.ko;
  6058. (function checkKnockoutVersion(version) {
  6059. version = version.split(".");
  6060. if (version[0] < 2 || version[0] == 2 && version[1] < 3)
  6061. throw Error("Your version of KnockoutJS is too old. Please upgrade KnockoutJS to 2.3.0 or later.");
  6062. })(ko.version)
  6063. })(jQuery, DevExpress);
  6064. /*! Module core, file ng.js */
  6065. (function($, DX, undefined) {
  6066. if (!DX.support.hasNg)
  6067. return;
  6068. DX.ng = {module: window.angular.module("dx", ["ngSanitize"])}
  6069. })(jQuery, DevExpress);
  6070. /*! Module core, file component.js */
  6071. (function($, DX, undefined) {
  6072. var ui = DX.ui,
  6073. utils = DX.utils,
  6074. dataUtils = DX.data.utils;
  6075. var Component = DX.Class.inherit({
  6076. NAME: "Component",
  6077. _deprecatedOptions: {},
  6078. _optionAliases: {},
  6079. _setDefaultOptions: function(){},
  6080. _defaultOptionsRules: function() {
  6081. return []
  6082. },
  6083. _setOptionsByDevice: function() {
  6084. var rules = this._defaultOptionsRules(),
  6085. currentDevice = DX.devices.current(),
  6086. result = {};
  6087. if (this._customRules)
  6088. rules = rules.concat(this._customRules);
  6089. var deviceMatch = function(device, filter) {
  6090. filter = $.makeArray(filter);
  6091. return filter.length === 1 && $.isEmptyObject(filter[0]) || utils.findBestMatches(device, filter).length > 0
  6092. };
  6093. $.each(rules, function(index, rule) {
  6094. var deviceFilter = rule.device || {},
  6095. match;
  6096. if ($.isFunction(deviceFilter))
  6097. match = deviceFilter(currentDevice);
  6098. else
  6099. match = deviceMatch(currentDevice, deviceFilter);
  6100. if (match)
  6101. $.extend(result, rule.options)
  6102. });
  6103. this.option(result)
  6104. },
  6105. _optionsByReference: function() {
  6106. return {}
  6107. },
  6108. ctor: function(options) {
  6109. if (!this.NAME)
  6110. throw Error("NAME is not specified");
  6111. this._options = {};
  6112. this._updateLockCount = 0;
  6113. this.optionChanged = $.Callbacks();
  6114. this.beginUpdate();
  6115. try {
  6116. this._suppressDeprecatedWarnings();
  6117. this._setDefaultOptions();
  6118. this._setOptionsByDevice();
  6119. this._resumeDeprecatedWarnings();
  6120. this._initialOptions = $.extend({}, this.option());
  6121. this._initOptions(options || {})
  6122. }
  6123. finally {
  6124. this.endUpdate()
  6125. }
  6126. },
  6127. _initOptions: function(options) {
  6128. this.option(options)
  6129. },
  6130. _optionValuesEqual: function(name, oldValue, newValue) {
  6131. oldValue = dataUtils.toComparable(oldValue, true);
  6132. newValue = dataUtils.toComparable(newValue, true);
  6133. if (oldValue && newValue && oldValue.jquery && newValue.jquery)
  6134. return newValue.is(oldValue);
  6135. if (oldValue === null || typeof oldValue !== "object")
  6136. return oldValue === newValue;
  6137. return false
  6138. },
  6139. _init: $.noop,
  6140. _optionChanged: $.noop,
  6141. instance: function() {
  6142. return this
  6143. },
  6144. beginUpdate: function() {
  6145. this._updateLockCount++
  6146. },
  6147. endUpdate: function() {
  6148. this._updateLockCount--;
  6149. if (!this._updateLockCount)
  6150. if (!this._initializing && !this._initialized) {
  6151. this._initializing = true;
  6152. try {
  6153. this._init()
  6154. }
  6155. finally {
  6156. this._initializing = false;
  6157. this._initialized = true
  6158. }
  6159. }
  6160. },
  6161. _logWarningIfDeprecated: function(option) {
  6162. var info = this._deprecatedOptions[option];
  6163. if (info && !this._deprecatedOptionsSuppressed)
  6164. this._logDeprecatedWarning(option, info)
  6165. },
  6166. _logDeprecatedWarningCount: 0,
  6167. _logDeprecatedWarning: function(option, info) {
  6168. utils.logger.warn("'" + option + "' option is deprecated since " + info.since + ". " + info.message);
  6169. ++this._logDeprecatedWarningCount
  6170. },
  6171. _suppressDeprecatedWarnings: function() {
  6172. this._deprecatedOptionsSuppressed = true
  6173. },
  6174. _resumeDeprecatedWarnings: function() {
  6175. this._deprecatedOptionsSuppressed = false
  6176. },
  6177. _getOptionAliases: function(option) {
  6178. return $.map(this._optionAliases, function(aliasedOption, alias) {
  6179. return option === aliasedOption ? alias : undefined
  6180. })
  6181. },
  6182. _notifyOptionChanged: function(option, value, previousValue) {
  6183. var that = this,
  6184. optionWithAliases;
  6185. if (this._initialized) {
  6186. optionWithAliases = this._getOptionAliases(option);
  6187. optionWithAliases.push(option);
  6188. $.each(optionWithAliases, function(index, name) {
  6189. var topLevelName = name.split(/[.\[]/)[0];
  6190. that.optionChanged.fireWith(that, [topLevelName, value, previousValue]);
  6191. that._optionChanged(topLevelName, value, previousValue)
  6192. })
  6193. }
  6194. },
  6195. initialOption: function(optionName) {
  6196. var options = this._initialOptions;
  6197. return options[optionName]
  6198. },
  6199. option: function(options) {
  6200. var that = this,
  6201. name = options,
  6202. value = arguments[1];
  6203. if (arguments.length < 2 && $.type(name) !== "object") {
  6204. if (name) {
  6205. this._logWarningIfDeprecated(name);
  6206. if (this._optionAliases[name])
  6207. name = this._optionAliases[name]
  6208. }
  6209. $.each(this._optionAliases, function(alias, option) {
  6210. that._options[alias] = dataUtils.compileGetter(option)(that._options, {functionsAsIs: true})
  6211. });
  6212. return dataUtils.compileGetter(name)(that._options, {functionsAsIs: true})
  6213. }
  6214. if (typeof name === "string") {
  6215. options = {};
  6216. options[name] = value
  6217. }
  6218. that.beginUpdate();
  6219. try {
  6220. $.each(options, function(name, value) {
  6221. that._logWarningIfDeprecated(name);
  6222. if (that._optionAliases[name])
  6223. name = that._optionAliases[name];
  6224. var prevValue = dataUtils.compileGetter(name)(that._options, {functionsAsIs: true});
  6225. if (that._optionValuesEqual(name, prevValue, value))
  6226. return;
  6227. dataUtils.compileSetter(name)(that._options, value, {
  6228. functionsAsIs: true,
  6229. merge: !that._optionsByReference()[name]
  6230. });
  6231. that._notifyOptionChanged(name, value, prevValue)
  6232. })
  6233. }
  6234. finally {
  6235. that.endUpdate()
  6236. }
  6237. }
  6238. });
  6239. $.extend(DX, {Component: Component})
  6240. })(jQuery, DevExpress);
  6241. /*! Module core, file DOMComponent.js */
  6242. (function($, DX, undefined) {
  6243. var windowResizeCallbacks = DX.utils.windowResizeCallbacks;
  6244. var RTL_DIRECTION_CLASS = "dx-rtl",
  6245. COMPONENT_NAMES_DATA_KEY = "dxComponents",
  6246. VISIBILITY_CHANGE_CLASS = "dx-visibility-change-handler",
  6247. VISIBILITY_CHANGE_EVENTNAMESPACE = "dxVisibilityChange";
  6248. var DOMComponent = DX.Component.inherit({
  6249. NAME: "DOMComponent",
  6250. NAMESPACE: DX,
  6251. _setDefaultOptions: function() {
  6252. this.callBase();
  6253. this.option({rtlEnabled: DX.rtlEnabled})
  6254. },
  6255. ctor: function(element, options) {
  6256. this._$element = $(element);
  6257. this._element().data(this.NAME, this);
  6258. this._attachInstanceToElement(this._$element);
  6259. this.disposing = $.Callbacks();
  6260. this.callBase(options)
  6261. },
  6262. _attachInstanceToElement: $.noop,
  6263. _visibilityChanged: DX.abstract,
  6264. _dimensionChanged: DX.abstract,
  6265. _init: function() {
  6266. this.callBase();
  6267. this._attachWindowResizeCallback()
  6268. },
  6269. _attachWindowResizeCallback: function() {
  6270. if (this._isDimensionChangeSupported()) {
  6271. var windowResizeCallBack = this._windowResizeCallBack = $.proxy(this._dimensionChanged, this);
  6272. windowResizeCallbacks.add(windowResizeCallBack)
  6273. }
  6274. },
  6275. _isDimensionChangeSupported: function() {
  6276. return this._dimensionChanged !== DX.abstract
  6277. },
  6278. _render: function() {
  6279. this._toggleRTLDirection(this.option("rtlEnabled"));
  6280. this._renderVisiblityChange()
  6281. },
  6282. _renderVisiblityChange: function() {
  6283. if (!this._isVisibilityChangeSupported())
  6284. return;
  6285. this._element().addClass(VISIBILITY_CHANGE_CLASS);
  6286. this._attachVisiblityChangeHandlers()
  6287. },
  6288. _attachVisiblityChangeHandlers: function() {
  6289. var that = this;
  6290. that._element().off("." + VISIBILITY_CHANGE_EVENTNAMESPACE).on("dxhiding." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
  6291. that._visibilityChanged(false)
  6292. }).on("dxshown." + VISIBILITY_CHANGE_EVENTNAMESPACE, function() {
  6293. that._visibilityChanged(true)
  6294. })
  6295. },
  6296. _isVisibilityChangeSupported: function() {
  6297. return this._visibilityChanged !== DX.abstract
  6298. },
  6299. _clean: $.noop,
  6300. _modelByElement: $.noop,
  6301. _invalidate: function() {
  6302. if (!this._updateLockCount)
  6303. throw Error("Invalidate called outside update transaction");
  6304. this._requireRefresh = true
  6305. },
  6306. _refresh: function() {
  6307. this._clean();
  6308. this._render()
  6309. },
  6310. _dispose: function() {
  6311. this._clean();
  6312. this._detachWindowResizeCallback();
  6313. this.optionChanged.empty();
  6314. this.disposing.fireWith(this).empty()
  6315. },
  6316. _detachWindowResizeCallback: function() {
  6317. if (this._isDimensionChangeSupported())
  6318. windowResizeCallbacks.remove(this._windowResizeCallBack)
  6319. },
  6320. _toggleRTLDirection: function(rtl) {
  6321. this._element().toggleClass(RTL_DIRECTION_CLASS, rtl)
  6322. },
  6323. _createAction: function(actionSource, config) {
  6324. var that = this;
  6325. config = $.extend({}, config);
  6326. var element = config.element || that._element(),
  6327. model = that._modelByElement(element);
  6328. config.context = model || that;
  6329. config.component = that;
  6330. var action = new DX.Action(actionSource, config);
  6331. return function(e) {
  6332. if (!arguments.length)
  6333. e = {};
  6334. if (e instanceof $.Event)
  6335. throw Error("Action must be executed with jQuery.Event like action({ jQueryEvent: event })");
  6336. if (!$.isPlainObject(e))
  6337. e = {actionValue: e};
  6338. return action.execute.call(action, $.extend(e, {
  6339. component: that,
  6340. element: element,
  6341. model: model
  6342. }))
  6343. }
  6344. },
  6345. _createActionByOption: function(optionName, config) {
  6346. if (typeof optionName !== "string")
  6347. throw Error("Option name type is unexpected");
  6348. this._suppressDeprecatedWarnings();
  6349. var action = this._createAction(this.option(optionName), config);
  6350. this._resumeDeprecatedWarnings();
  6351. return action
  6352. },
  6353. _optionChanged: function(name, value, prevValue) {
  6354. if (name === "rtlEnabled")
  6355. this._invalidate()
  6356. },
  6357. _element: function() {
  6358. return this._$element
  6359. },
  6360. endUpdate: function() {
  6361. var requireRender = !this._initializing && !this._initialized;
  6362. this.callBase.apply(this, arguments);
  6363. if (!this._updateLockCount)
  6364. if (requireRender)
  6365. this._render();
  6366. else if (this._requireRefresh) {
  6367. this._requireRefresh = false;
  6368. this._refresh()
  6369. }
  6370. }
  6371. });
  6372. var registerComponent = function(name, componentClass) {
  6373. componentClass.redefine({_attachInstanceToElement: function($element) {
  6374. $element.data(name, this);
  6375. if (!$element.data(COMPONENT_NAMES_DATA_KEY))
  6376. $element.data(COMPONENT_NAMES_DATA_KEY, []);
  6377. $element.data(COMPONENT_NAMES_DATA_KEY).push(name)
  6378. }});
  6379. componentClass.prototype.NAMESPACE[name] = componentClass;
  6380. componentClass.prototype.NAME = name;
  6381. componentClass.defaultOptions = function(rule) {
  6382. componentClass.prototype._customRules = componentClass.prototype._customRules || [];
  6383. componentClass.prototype._customRules.push(rule)
  6384. };
  6385. $.fn[name] = function(options) {
  6386. var isMemberInvoke = typeof options === "string",
  6387. result;
  6388. if (isMemberInvoke) {
  6389. var memberName = options,
  6390. memberArgs = $.makeArray(arguments).slice(1);
  6391. this.each(function() {
  6392. var instance = $(this).data(name);
  6393. if (!instance)
  6394. throw Error(DX.utils.stringFormat("Component {0} has not been initialized on this element", name));
  6395. var member = instance[memberName],
  6396. memberValue = member.apply(instance, memberArgs);
  6397. if (result === undefined)
  6398. result = memberValue
  6399. })
  6400. }
  6401. else {
  6402. this.each(function() {
  6403. var instance = $(this).data(name);
  6404. if (instance)
  6405. instance.option(options);
  6406. else
  6407. new componentClass(this, options)
  6408. });
  6409. result = this
  6410. }
  6411. return result
  6412. }
  6413. };
  6414. var getComponents = function(element) {
  6415. element = $(element);
  6416. var names = element.data(COMPONENT_NAMES_DATA_KEY);
  6417. if (!names)
  6418. return [];
  6419. return $.map(names, function(name) {
  6420. return element.data(name)
  6421. })
  6422. };
  6423. var disposeComponents = function() {
  6424. $.each(getComponents(this), function() {
  6425. this._dispose()
  6426. })
  6427. };
  6428. var originalCleanData = $.cleanData;
  6429. $.cleanData = function(element) {
  6430. $.each(element, disposeComponents);
  6431. return originalCleanData.apply(this, arguments)
  6432. };
  6433. registerComponent("DOMComponent", DOMComponent);
  6434. DX.registerComponent = registerComponent
  6435. })(jQuery, DevExpress);
  6436. /*! Module core, file social.js */
  6437. DevExpress.social = {};
  6438. /*! Module core, file facebook.js */
  6439. (function($, DX, undefined) {
  6440. function notifyDeprecated() {
  6441. DX.utils.logger.warn("DevExpress.social API is deprecated. Use official Facebook library instead")
  6442. }
  6443. var social = DX.social;
  6444. var location = window.location,
  6445. navigator = window.navigator,
  6446. encodeURIComponent = window.encodeURIComponent,
  6447. decodeURIComponent = window.decodeURIComponent,
  6448. iosStandaloneMode = navigator.standalone,
  6449. cordovaMode = false;
  6450. if (window.cordova)
  6451. $(document).on("deviceready", function() {
  6452. cordovaMode = true
  6453. });
  6454. var ACCESS_TOKEN_KEY = "dx-facebook-access-token",
  6455. IOS_STANDALONE_STEP1_KEY = "dx-facebook-step1",
  6456. IOS_STANDALONE_STEP2_KEY = "dx-facebook-step2";
  6457. var accessToken = null,
  6458. expires = null,
  6459. connectionChanged = $.Callbacks();
  6460. var pendingLoginRedirectUrl;
  6461. var isConnected = function() {
  6462. return !!accessToken
  6463. };
  6464. var getAccessTokenObject = function() {
  6465. return {
  6466. accessToken: accessToken,
  6467. expiresIn: accessToken ? expires : 0
  6468. }
  6469. };
  6470. var FB = social.Facebook = {
  6471. loginRedirectUrl: "FacebookLoginCallback.html",
  6472. connectionChanged: connectionChanged,
  6473. isConnected: isConnected,
  6474. getAccessTokenObject: getAccessTokenObject,
  6475. jsonp: false
  6476. };
  6477. var login = function(appId, options) {
  6478. notifyDeprecated();
  6479. options = options || {};
  6480. if (cordovaMode)
  6481. pendingLoginRedirectUrl = "https://www.facebook.com/connect/login_success.html";
  6482. else
  6483. pendingLoginRedirectUrl = formatLoginRedirectUrl();
  6484. var scope = (options.permissions || []).join(),
  6485. url = "https://www.facebook.com/dialog/oauth?display=popup&client_id=" + appId + "&redirect_uri=" + encodeURIComponent(pendingLoginRedirectUrl) + "&scope=" + encodeURIComponent(scope) + "&response_type=token";
  6486. if (iosStandaloneMode)
  6487. putData(IOS_STANDALONE_STEP1_KEY, location.href);
  6488. if (cordovaMode)
  6489. startLogin_cordova(url);
  6490. else
  6491. startLogin_browser(url)
  6492. };
  6493. var formatLoginRedirectUrl = function() {
  6494. var pathSegments = location.pathname.split(/\//g);
  6495. pathSegments.pop();
  6496. pathSegments.push(FB.loginRedirectUrl);
  6497. return location.protocol + "//" + location.host + pathSegments.join("/")
  6498. };
  6499. var startLogin_browser = function(loginUrl) {
  6500. var width = 512,
  6501. height = 320,
  6502. left = (screen.width - width) / 2,
  6503. top = (screen.height - height) / 2;
  6504. window.open(loginUrl, null, "width=" + width + ",height=" + height + ",toolbar=0,scrollbars=0,status=0,resizable=0,menuBar=0,left=" + left + ",top=" + top)
  6505. };
  6506. var startLogin_cordova = function(loginUrl) {
  6507. var ref = window.open(loginUrl, "_blank");
  6508. ref.addEventListener('exit', function(event) {
  6509. pendingLoginRedirectUrl = null
  6510. });
  6511. ref.addEventListener('loadstop', function(event) {
  6512. var url = unescape(event.url);
  6513. if (url.indexOf(pendingLoginRedirectUrl) === 0) {
  6514. ref.close();
  6515. _processLoginRedirectUrl(url)
  6516. }
  6517. })
  6518. };
  6519. var handleLoginRedirect = function() {
  6520. var opener = window.opener;
  6521. if (iosStandaloneMode) {
  6522. putData(IOS_STANDALONE_STEP2_KEY, location.href);
  6523. location.href = getData(IOS_STANDALONE_STEP1_KEY)
  6524. }
  6525. else if (opener && opener.DevExpress) {
  6526. opener.DevExpress.social.Facebook._processLoginRedirectUrl(location.href);
  6527. window.close()
  6528. }
  6529. };
  6530. var _processLoginRedirectUrl = function(url) {
  6531. var params = parseUrlFragment(url);
  6532. expires = params.expires_in;
  6533. changeToken(params.access_token);
  6534. pendingLoginRedirectUrl = null
  6535. };
  6536. var parseUrlFragment = function(url) {
  6537. var hash = url.split("#")[1];
  6538. if (!hash)
  6539. return {};
  6540. var pairs = hash.split(/&/g),
  6541. result = {};
  6542. $.each(pairs, function(i) {
  6543. var splitPair = this.split("=");
  6544. result[splitPair[0]] = decodeURIComponent(splitPair[1])
  6545. });
  6546. return result
  6547. };
  6548. var logout = function() {
  6549. notifyDeprecated();
  6550. changeToken(null)
  6551. };
  6552. var changeToken = function(value) {
  6553. if (value === accessToken)
  6554. return;
  6555. accessToken = value;
  6556. putData(ACCESS_TOKEN_KEY, value);
  6557. connectionChanged.fire(!!value)
  6558. };
  6559. var api = function(resource, method, params) {
  6560. notifyDeprecated();
  6561. if (!isConnected())
  6562. throw Error("Not connected");
  6563. if (typeof method !== "string") {
  6564. params = method;
  6565. method = undefined
  6566. }
  6567. method = (method || "get").toLowerCase();
  6568. var d = $.Deferred();
  6569. var args = arguments;
  6570. $.ajax({
  6571. url: "https://graph.facebook.com/" + resource,
  6572. type: method,
  6573. data: $.extend({access_token: accessToken}, params),
  6574. dataType: FB.jsonp && method === "get" ? "jsonp" : "json"
  6575. }).done(function(response) {
  6576. response = response || simulateErrorResponse();
  6577. if (response.error)
  6578. d.reject(response.error);
  6579. else
  6580. d.resolve(response)
  6581. }).fail(function(xhr) {
  6582. var response;
  6583. try {
  6584. response = $.parseJSON(xhr.responseText);
  6585. var tries = args[3] || 0;
  6586. if (tries++ < 3 && response.error.code == 190 && response.error.error_subcode == 466) {
  6587. setTimeout(function() {
  6588. api(resource, method, params, tries).done(function(result) {
  6589. d.resolve(result)
  6590. }).fail(function(error) {
  6591. d.reject(error)
  6592. })
  6593. }, 500);
  6594. return
  6595. }
  6596. }
  6597. catch(x) {
  6598. response = simulateErrorResponse()
  6599. }
  6600. d.reject(response.error)
  6601. });
  6602. return d.promise()
  6603. };
  6604. var simulateErrorResponse = function() {
  6605. return {error: {message: "Unknown error"}}
  6606. };
  6607. var ensureStorageBackend = function() {
  6608. if (!hasStorageBackend())
  6609. throw Error("HTML5 sessionStorage or jQuery.cookie plugin is required");
  6610. };
  6611. var hasStorageBackend = function() {
  6612. return !!($.cookie || window.sessionStorage)
  6613. };
  6614. var putData = function(key, data) {
  6615. ensureStorageBackend();
  6616. data = JSON.stringify(data);
  6617. if (window.sessionStorage)
  6618. if (data === null)
  6619. sess.removeItem(key);
  6620. else
  6621. sessionStorage.setItem(key, data);
  6622. else
  6623. $.cookie(key, data)
  6624. };
  6625. var getData = function(key) {
  6626. ensureStorageBackend();
  6627. try {
  6628. return JSON.parse(window.sessionStorage ? sessionStorage.getItem(key) : $.cookie(key))
  6629. }
  6630. catch(x) {
  6631. return null
  6632. }
  6633. };
  6634. if (hasStorageBackend())
  6635. accessToken = getData(ACCESS_TOKEN_KEY);
  6636. if (iosStandaloneMode) {
  6637. var url = getData(IOS_STANDALONE_STEP2_KEY);
  6638. if (url) {
  6639. _processLoginRedirectUrl(url);
  6640. putData(IOS_STANDALONE_STEP1_KEY, null);
  6641. putData(IOS_STANDALONE_STEP2_KEY, null)
  6642. }
  6643. }
  6644. $.extend(FB, {
  6645. login: login,
  6646. logout: logout,
  6647. handleLoginRedirect: handleLoginRedirect,
  6648. _processLoginRedirectUrl: _processLoginRedirectUrl,
  6649. api: api
  6650. })
  6651. })(jQuery, DevExpress);
  6652. /*! Module core, file ui.js */
  6653. (function($, DX, undefined) {
  6654. var ui = DX.ui = {};
  6655. var TemplateProvider = DX.Class.inherit({
  6656. getTemplateClass: function() {
  6657. return Template
  6658. },
  6659. supportDefaultTemplate: function() {
  6660. return false
  6661. },
  6662. getDefaultTemplate: function() {
  6663. return null
  6664. }
  6665. });
  6666. var Template = DX.Class.inherit({
  6667. ctor: function(element, owner) {
  6668. this._template = this._element = $(element).detach();
  6669. this._owner = owner
  6670. },
  6671. render: function(container) {
  6672. var renderedTemplate = this._template.clone();
  6673. container.append(renderedTemplate);
  6674. return renderedTemplate
  6675. },
  6676. dispose: function() {
  6677. this._owner = null
  6678. },
  6679. owner: function() {
  6680. return this._owner
  6681. }
  6682. });
  6683. var GESTURE_LOCK_KEY = "dxGestureLock";
  6684. DX.registerActionExecutor({
  6685. designMode: {validate: function(e) {
  6686. if (DX.designMode)
  6687. e.cancel = true
  6688. }},
  6689. gesture: {validate: function(e) {
  6690. if (!e.args.length)
  6691. return;
  6692. var args = e.args[0],
  6693. element = args[e.validatingTargetName] || args.element;
  6694. while (element && element.length) {
  6695. if (element.data(GESTURE_LOCK_KEY)) {
  6696. e.cancel = true;
  6697. break
  6698. }
  6699. element = element.parent()
  6700. }
  6701. }},
  6702. disabled: {validate: function(e) {
  6703. if (!e.args.length)
  6704. return;
  6705. var args = e.args[0],
  6706. element = args[e.validatingTargetName] || args.element;
  6707. if (element && element.is(".dx-state-disabled, .dx-state-disabled *"))
  6708. e.cancel = true
  6709. }}
  6710. });
  6711. $.extend(ui, {
  6712. TemplateProvider: TemplateProvider,
  6713. Template: Template,
  6714. initViewport: function() {
  6715. DX.utils.logger.warn("DevExpress.ui.initViewport is deprecated. Use DX.utils.initMobileViewport instead");
  6716. DX.utils.initMobileViewport()
  6717. }
  6718. });
  6719. ui.__internals = ui.__internals || {};
  6720. $.extend(ui.__internals, {Template: Template})
  6721. })(jQuery, DevExpress);
  6722. /*! Module core, file ko.components.js */
  6723. (function($, DX, undefined) {
  6724. if (!DX.support.hasKo)
  6725. return;
  6726. var ko = window.ko,
  6727. ui = DX.ui,
  6728. LOCKS_DATA_KEY = "dxKoLocks",
  6729. CREATED_WITH_KO_DATA_KEY = "dxKoCreation";
  6730. var Locks = function() {
  6731. var info = {};
  6732. var currentCount = function(lockName) {
  6733. return info[lockName] || 0
  6734. };
  6735. return {
  6736. obtain: function(lockName) {
  6737. info[lockName] = currentCount(lockName) + 1
  6738. },
  6739. release: function(lockName) {
  6740. var count = currentCount(lockName);
  6741. if (count < 1)
  6742. throw Error("Not locked");
  6743. if (count === 1)
  6744. delete info[lockName];
  6745. else
  6746. info[lockName] = count - 1
  6747. },
  6748. locked: function(lockName) {
  6749. return currentCount(lockName) > 0
  6750. }
  6751. }
  6752. };
  6753. var registerComponentKoBinding = function(componentName) {
  6754. ko.bindingHandlers[componentName] = {init: function(domNode, valueAccessor) {
  6755. var element = $(domNode),
  6756. ctorOptions = {},
  6757. optionNameToModelMap = {};
  6758. var applyModelValueToOption = function(optionName, modelValue) {
  6759. var component = element.data(componentName),
  6760. locks = element.data(LOCKS_DATA_KEY),
  6761. optionValue = ko.utils.unwrapObservable(modelValue);
  6762. if (ko.isWriteableObservable(modelValue))
  6763. optionNameToModelMap[optionName] = modelValue;
  6764. if (component) {
  6765. if (locks.locked(optionName))
  6766. return;
  6767. locks.obtain(optionName);
  6768. try {
  6769. component.option(optionName, optionValue)
  6770. }
  6771. finally {
  6772. locks.release(optionName)
  6773. }
  6774. }
  6775. else
  6776. ctorOptions[optionName] = optionValue
  6777. };
  6778. var handleOptionChanged = function(optionName, optionValue) {
  6779. if (!(optionName in optionNameToModelMap))
  6780. return;
  6781. var element = this._$element,
  6782. locks = element.data(LOCKS_DATA_KEY);
  6783. if (locks.locked(optionName))
  6784. return;
  6785. locks.obtain(optionName);
  6786. try {
  6787. optionNameToModelMap[optionName](optionValue)
  6788. }
  6789. finally {
  6790. locks.release(optionName)
  6791. }
  6792. };
  6793. var createComponent = function() {
  6794. element.data(CREATED_WITH_KO_DATA_KEY, true);
  6795. element[componentName](ctorOptions);
  6796. ctorOptions = null;
  6797. element.data(LOCKS_DATA_KEY, new Locks);
  6798. element.data(componentName).optionChanged.add(handleOptionChanged)
  6799. };
  6800. ko.computed(function() {
  6801. var component = element.data(componentName);
  6802. if (component)
  6803. component.beginUpdate();
  6804. $.each(ko.unwrap(valueAccessor()), function(modelName, modelValueExpr) {
  6805. ko.computed(function() {
  6806. applyModelValueToOption(modelName, modelValueExpr)
  6807. }, null, {disposeWhenNodeIsRemoved: domNode})
  6808. });
  6809. if (component)
  6810. component.endUpdate();
  6811. else
  6812. createComponent()
  6813. }, null, {disposeWhenNodeIsRemoved: domNode});
  6814. return {controlsDescendantBindings: ui[componentName] && ui[componentName].subclassOf(ui.Widget)}
  6815. }}
  6816. };
  6817. var KoComponent = DX.DOMComponent.inherit({_modelByElement: function(element) {
  6818. if (element.length)
  6819. return ko.dataFor(element.get(0))
  6820. }});
  6821. var originalRegisterComponent = DX.registerComponent;
  6822. var registerKoComponent = function(name, componentClass) {
  6823. originalRegisterComponent(name, componentClass);
  6824. registerComponentKoBinding(name)
  6825. };
  6826. ko.bindingHandlers.dxAction = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
  6827. var $element = $(element);
  6828. var unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
  6829. actionSource = unwrappedValue,
  6830. actionOptions = {context: element};
  6831. if (unwrappedValue.execute) {
  6832. actionSource = unwrappedValue.execute;
  6833. $.extend(actionOptions, unwrappedValue)
  6834. }
  6835. var action = new DX.Action(actionSource, actionOptions);
  6836. $element.off(".dxActionBinding").on("dxclick.dxActionBinding", function(e) {
  6837. action.execute({
  6838. element: $element,
  6839. model: viewModel,
  6840. evaluate: function(expression) {
  6841. var context = viewModel;
  6842. if (expression.length > 0 && expression[0] === "$")
  6843. context = ko.contextFor(element);
  6844. var getter = DX.data.utils.compileGetter(expression);
  6845. return getter(context)
  6846. },
  6847. jQueryEvent: e
  6848. });
  6849. if (!actionOptions.bubbling)
  6850. e.stopPropagation()
  6851. })
  6852. }};
  6853. var cleanKoData = function(element, andSelf) {
  6854. var cleanNode = function() {
  6855. ko.cleanNode(this)
  6856. };
  6857. if (andSelf)
  6858. element.each(cleanNode);
  6859. else
  6860. element.find("*").each(cleanNode)
  6861. };
  6862. var originalEmpty = $.fn.empty;
  6863. $.fn.empty = function() {
  6864. cleanKoData(this, false);
  6865. return originalEmpty.apply(this, arguments)
  6866. };
  6867. var originalRemove = $.fn.remove;
  6868. $.fn.remove = function(selector, keepData) {
  6869. if (!keepData) {
  6870. var subject = this;
  6871. if (selector)
  6872. subject = subject.filter(selector);
  6873. cleanKoData(subject, true)
  6874. }
  6875. return originalRemove.call(this, selector, keepData)
  6876. };
  6877. var originalHtml = $.fn.html;
  6878. $.fn.html = function(value) {
  6879. if (typeof value === "string")
  6880. cleanKoData(this, false);
  6881. return originalHtml.apply(this, arguments)
  6882. };
  6883. DX.registerComponent = registerKoComponent;
  6884. registerKoComponent("DOMComponent", KoComponent)
  6885. })(jQuery, DevExpress);
  6886. /*! Module core, file ng.components.js */
  6887. (function($, DX, undefined) {
  6888. if (!DX.support.hasNg)
  6889. return;
  6890. var ui = DX.ui,
  6891. compileSetter = DX.data.utils.compileSetter,
  6892. compileGetter = DX.data.utils.compileGetter;
  6893. var CREATED_WITH_NG_DATA_KEY = "dxNgCreation",
  6894. TEMPLATES_DATA_KEY = "dxTemplates",
  6895. COMPILER_DATA_KEY = "dxNgCompiler",
  6896. DEFAULT_COMPILER_DATA_KEY = "dxDefaultCompilerGetter",
  6897. ANONYMOUS_TEMPLATE_NAME = "template";
  6898. var phoneJsModule = DX.ng.module;
  6899. var ComponentBuilder = DX.Class.inherit({
  6900. ctor: function(options) {
  6901. this._componentName = options.componentName;
  6902. this._$element = options.$element;
  6903. this._$templates = options.$templates;
  6904. this._scope = options.scope;
  6905. this._compile = options.compile;
  6906. this._ngOptions = options.ngOptions;
  6907. this._componentDisposing = $.Callbacks();
  6908. this._$element.data(CREATED_WITH_NG_DATA_KEY, true);
  6909. if (options.ngOptions.data)
  6910. this._initDataScope(options.ngOptions.data)
  6911. },
  6912. initDefaultCompilerGetter: function() {
  6913. var that = this;
  6914. that._$element.data(DEFAULT_COMPILER_DATA_KEY, function($template) {
  6915. return that._compilerByTemplate($template)
  6916. })
  6917. },
  6918. initTemplateCompilers: function() {
  6919. var that = this;
  6920. if (this._$templates)
  6921. this._$templates.each(function(i, template) {
  6922. $(template).data(COMPILER_DATA_KEY, that._compilerByTemplate(template))
  6923. })
  6924. },
  6925. initComponentWithBindings: function() {
  6926. this._initComponent(this._scope);
  6927. this._initComponentBindings()
  6928. },
  6929. _initDataScope: function(data) {
  6930. if (typeof data === "string") {
  6931. var dataStr = data,
  6932. rootScope = this._scope;
  6933. data = rootScope.$eval(data);
  6934. this._scope = rootScope.$new();
  6935. this._synchronizeDataScopes(rootScope, this._scope, data, dataStr)
  6936. }
  6937. $.extend(this._scope, data)
  6938. },
  6939. _synchronizeDataScopes: function(parentScope, childScope, data, parentPrefix) {
  6940. var that = this;
  6941. $.each(data, function(fieldPath) {
  6942. that._synchronizeScopeField({
  6943. parentScope: parentScope,
  6944. childScope: childScope,
  6945. fieldPath: fieldPath,
  6946. parentPrefix: parentPrefix
  6947. })
  6948. })
  6949. },
  6950. _initComponent: function(scope) {
  6951. this._component = this._$element[this._componentName](this._evalOptions(scope)).data(this._componentName)
  6952. },
  6953. _initComponentBindings: function() {
  6954. var that = this,
  6955. optionDependencies = {};
  6956. if (that._ngOptions.bindingOptions)
  6957. $.each(that._ngOptions.bindingOptions, function(optionPath, valuePath) {
  6958. var separatorIndex = optionPath.search(/\[|\./),
  6959. optionForSubscribe = separatorIndex > -1 ? optionPath.substring(0, separatorIndex) : optionPath,
  6960. prevWatchMethod,
  6961. clearWatcher;
  6962. if (!optionDependencies[optionForSubscribe])
  6963. optionDependencies[optionForSubscribe] = {};
  6964. optionDependencies[optionForSubscribe][optionPath] = valuePath;
  6965. var watchCallback = function(newValue, oldValue) {
  6966. if (newValue !== oldValue) {
  6967. that._component.option(optionPath, newValue);
  6968. updateWatcher()
  6969. }
  6970. };
  6971. var updateWatcher = function() {
  6972. var watchMethod = $.isArray(that._scope.$eval(valuePath)) ? "$watchCollection" : "$watch";
  6973. if (prevWatchMethod !== watchMethod) {
  6974. if (clearWatcher)
  6975. clearWatcher();
  6976. clearWatcher = that._scope[watchMethod](valuePath, watchCallback, true);
  6977. prevWatchMethod = watchMethod
  6978. }
  6979. };
  6980. updateWatcher();
  6981. that._component.disposing.add(function() {
  6982. clearWatcher();
  6983. that._componentDisposing.fire()
  6984. })
  6985. });
  6986. that._component.optionChanged.add(function(optionName, optionValue) {
  6987. if (that._scope.$root.$$phase === "$digest" || !optionDependencies || !optionDependencies[optionName])
  6988. return;
  6989. safeApply(function(scope) {
  6990. $.each(optionDependencies[optionName], function(optionPath, valuePath) {
  6991. var setter = compileSetter(valuePath),
  6992. getter = compileGetter(optionPath);
  6993. var tmpData = {};
  6994. tmpData[optionName] = optionValue;
  6995. setter(scope, getter(tmpData))
  6996. })
  6997. }, that._scope)
  6998. })
  6999. },
  7000. _compilerByTemplate: function(template) {
  7001. var that = this,
  7002. scopeItemsPath = this._getScopeItemsPath();
  7003. return function(data, index) {
  7004. var $resultMarkup = $(template).clone(),
  7005. templateScope;
  7006. if (data !== undefined) {
  7007. var dataIsScope = data.$id,
  7008. templateScope = dataIsScope ? data : that._createScopeWithData(data);
  7009. $resultMarkup.on("$destroy", function() {
  7010. var destroyAlreadyCalled = !templateScope.$parent;
  7011. if (destroyAlreadyCalled)
  7012. return;
  7013. templateScope.$destroy()
  7014. })
  7015. }
  7016. else
  7017. templateScope = that._scope;
  7018. if (scopeItemsPath)
  7019. that._synchronizeScopes(templateScope, scopeItemsPath, index);
  7020. safeApply(that._compile($resultMarkup), templateScope);
  7021. return $resultMarkup
  7022. }
  7023. },
  7024. _getScopeItemsPath: function() {
  7025. if (ui[this._componentName].subclassOf(ui.CollectionContainerWidget) && this._ngOptions.bindingOptions)
  7026. return this._ngOptions.bindingOptions.items
  7027. },
  7028. _createScopeWithData: function(data) {
  7029. var newScope = this._scope.$new(true);
  7030. if (typeof data === "object")
  7031. $.extend(newScope, data);
  7032. else
  7033. newScope.scopeValue = data;
  7034. return newScope
  7035. },
  7036. _synchronizeScopes: function(itemScope, parentPrefix, itemIndex) {
  7037. var that = this,
  7038. item = compileGetter(parentPrefix + "[" + itemIndex + "]")(this._scope);
  7039. if (!$.isPlainObject(item))
  7040. item = {scopeValue: item};
  7041. $.each(item, function(itemPath) {
  7042. that._synchronizeScopeField({
  7043. parentScope: that._scope,
  7044. childScope: itemScope,
  7045. fieldPath: itemPath,
  7046. parentPrefix: parentPrefix,
  7047. itemIndex: itemIndex
  7048. })
  7049. })
  7050. },
  7051. _synchronizeScopeField: function(args) {
  7052. var parentScope = args.parentScope,
  7053. childScope = args.childScope,
  7054. fieldPath = args.fieldPath,
  7055. parentPrefix = args.parentPrefix,
  7056. itemIndex = args.itemIndex;
  7057. var innerPathSuffix = fieldPath === "scopeValue" ? "" : "." + fieldPath,
  7058. collectionField = itemIndex !== undefined,
  7059. optionOuterBag = [parentPrefix],
  7060. optionOuterPath;
  7061. if (collectionField)
  7062. optionOuterBag.push("[", itemIndex, "]");
  7063. optionOuterBag.push(innerPathSuffix);
  7064. optionOuterPath = optionOuterBag.join("");
  7065. var clearParentWatcher = parentScope.$watch(optionOuterPath, function(newValue, oldValue) {
  7066. if (newValue !== oldValue)
  7067. compileSetter(fieldPath)(childScope, newValue)
  7068. });
  7069. var clearItemWatcher = childScope.$watch(fieldPath, function(newValue, oldValue) {
  7070. if (newValue !== oldValue) {
  7071. if (collectionField && !compileGetter(parentPrefix)(parentScope)[itemIndex]) {
  7072. clearItemWatcher();
  7073. return
  7074. }
  7075. compileSetter(optionOuterPath)(parentScope, newValue)
  7076. }
  7077. });
  7078. this._componentDisposing.add([clearParentWatcher, clearItemWatcher])
  7079. },
  7080. _evalOptions: function(scope) {
  7081. var result = $.extend({}, this._ngOptions);
  7082. delete result.data;
  7083. delete result.bindingOptions;
  7084. if (this._ngOptions.bindingOptions)
  7085. $.each(this._ngOptions.bindingOptions, function(key, value) {
  7086. result[key] = scope.$eval(value)
  7087. });
  7088. return result
  7089. }
  7090. });
  7091. var safeApply = function(func, scope) {
  7092. if (scope.$root.$$phase)
  7093. func(scope);
  7094. else
  7095. scope.$apply(function() {
  7096. func(scope)
  7097. })
  7098. };
  7099. var extractTemplates = function($element, componentName) {
  7100. if ($element.data(TEMPLATES_DATA_KEY))
  7101. return $element.data(TEMPLATES_DATA_KEY);
  7102. var $templates;
  7103. if (ui[componentName] && ui[componentName].subclassOf(ui.Widget) && $.trim($element.html())) {
  7104. var isAnonymousTemplate = !$element.children().first().attr("data-options");
  7105. if (isAnonymousTemplate)
  7106. $templates = $("<div/>").attr("data-options", "dxTemplate: { name: '" + ANONYMOUS_TEMPLATE_NAME + "' }").append($element.contents());
  7107. else
  7108. $templates = $element.children().detach();
  7109. $element.data(TEMPLATES_DATA_KEY, $templates)
  7110. }
  7111. return $templates
  7112. };
  7113. var NgComponent = DX.DOMComponent.inherit({
  7114. _modelByElement: function(element) {
  7115. if (element.length)
  7116. return element.scope()
  7117. },
  7118. _createAction: function() {
  7119. var action = this.callBase.apply(this, arguments);
  7120. var component = this,
  7121. wrappedAction = function() {
  7122. var that = this,
  7123. scope = component._modelByElement(component._element()),
  7124. args = arguments;
  7125. if (!scope || scope.$root.$$phase)
  7126. return action.apply(that, args);
  7127. return scope.$apply(function() {
  7128. return action.apply(that, args)
  7129. })
  7130. };
  7131. return wrappedAction
  7132. }
  7133. });
  7134. var originalRegisterComponent = DX.registerComponent;
  7135. var registerNgComponent = function(componentName, componentClass) {
  7136. originalRegisterComponent(componentName, componentClass);
  7137. phoneJsModule.directive(componentName, ["$compile", function(compile) {
  7138. return {
  7139. restrict: "A",
  7140. compile: function($element) {
  7141. var $templates = extractTemplates($element, componentName);
  7142. return function(scope, $element, attrs) {
  7143. var componentBuilder = new ComponentBuilder({
  7144. componentName: componentName,
  7145. compile: compile,
  7146. $element: $element,
  7147. scope: scope,
  7148. ngOptions: attrs[componentName] ? scope.$eval(attrs[componentName]) : {},
  7149. $templates: $templates
  7150. });
  7151. componentBuilder.initTemplateCompilers();
  7152. componentBuilder.initDefaultCompilerGetter();
  7153. componentBuilder.initComponentWithBindings()
  7154. }
  7155. }
  7156. }
  7157. }])
  7158. };
  7159. DX.registerComponent = registerNgComponent;
  7160. registerNgComponent("DOMComponent", NgComponent)
  7161. })(jQuery, DevExpress);
  7162. /*! Module core, file ko.templates.js */
  7163. (function($, DX, undefined) {
  7164. if (!DX.support.hasKo)
  7165. return;
  7166. var ko = window.ko,
  7167. ui = DX.ui,
  7168. CREATED_WITH_KO_DATA_KEY = "dxKoCreation";
  7169. var KoTemplate = ui.Template.inherit({
  7170. ctor: function(element) {
  7171. this.callBase.apply(this, arguments);
  7172. this._template = $("<div>").append(element);
  7173. this._registerKoTemplate()
  7174. },
  7175. _cleanTemplateElement: function() {
  7176. this._element.each(function() {
  7177. ko.cleanNode(this)
  7178. })
  7179. },
  7180. _registerKoTemplate: function() {
  7181. var template = this._template.get(0);
  7182. new ko.templateSources.anonymousTemplate(template)['nodes'](template)
  7183. },
  7184. render: function(container, data) {
  7185. data = data !== undefined ? data : ko.dataFor(container.get(0)) || {};
  7186. var containerBindingContext = ko.contextFor(container[0]);
  7187. var bindingContext = containerBindingContext ? containerBindingContext.createChildContext(data) : data;
  7188. var renderBag = $("<div />").appendTo(container);
  7189. ko.renderTemplate(this._template.get(0), bindingContext, null, renderBag.get(0));
  7190. var result = renderBag.contents();
  7191. container.append(result);
  7192. renderBag.remove();
  7193. return result
  7194. },
  7195. dispose: function() {
  7196. this.callBase();
  7197. this._template.remove()
  7198. }
  7199. });
  7200. var KoTemplateProvider = ui.TemplateProvider.inherit({
  7201. getTemplateClass: function(widget) {
  7202. return this._createdWithKo(widget) ? KoTemplate : this.callBase(widget)
  7203. },
  7204. supportDefaultTemplate: function(widget) {
  7205. return this._createdWithKo(widget) ? true : this.callBase(widget)
  7206. },
  7207. getDefaultTemplate: function(widget) {
  7208. if (this._createdWithKo(widget))
  7209. return defaultKoTemplate(widget.NAME)
  7210. },
  7211. _createdWithKo: function(widget) {
  7212. return !!widget._element().data(CREATED_WITH_KO_DATA_KEY)
  7213. }
  7214. });
  7215. var defaultKoTemplate = function() {
  7216. var cache = {};
  7217. return function(widgetName) {
  7218. if (!DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName])
  7219. widgetName = "base";
  7220. if (!cache[widgetName]) {
  7221. var html = DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName](),
  7222. markup = DX.utils.createMarkupFromString(html);
  7223. cache[widgetName] = new KoTemplate(markup)
  7224. }
  7225. return cache[widgetName]
  7226. }
  7227. }();
  7228. var createElementWithBindAttr = function(tagName, bindings, closeTag, additionalProperties) {
  7229. closeTag = closeTag === undefined ? true : closeTag;
  7230. var bindAttr = $.map(bindings, function(value, key) {
  7231. return key + ":" + value
  7232. }).join(",");
  7233. additionalProperties = additionalProperties || "";
  7234. return "<" + tagName + " data-bind=\"" + bindAttr + "\" " + additionalProperties + ">" + (closeTag ? "</" + tagName + ">" : "")
  7235. };
  7236. var defaultKoTemplateBasicBindings = {css: "{ 'dx-state-disabled': $data.disabled, 'dx-state-invisible': !($data.visible === undefined || ko.unwrap($data.visible)) }"};
  7237. var DEFAULT_ITEM_TEMPLATE_GENERATORS = {base: function() {
  7238. var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)],
  7239. htmlBinding = createElementWithBindAttr("div", {html: "html"}),
  7240. textBinding = createElementWithBindAttr("div", {text: "text"}),
  7241. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"});
  7242. 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>");
  7243. return template.join("")
  7244. }};
  7245. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxPivotTabs = function() {
  7246. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7247. titleBinding = createElementWithBindAttr("span", {text: "title"});
  7248. var divInnerStart = template.indexOf(">") + 1,
  7249. divInnerFinish = template.length - 6;
  7250. template = [template.substring(0, divInnerStart), titleBinding, template.substring(divInnerFinish, template.length)];
  7251. return template.join("")
  7252. };
  7253. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxPanorama = function() {
  7254. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7255. headerBinding = createElementWithBindAttr("div", {text: "header"}, true, 'class="dx-panorama-item-header"');
  7256. var divInnerStart = template.indexOf(">") + 1;
  7257. template = [template.substring(0, divInnerStart), "<!-- ko if: $data.header -->", headerBinding, "<!-- /ko -->", template.substring(divInnerStart, template.length)];
  7258. return template.join("")
  7259. };
  7260. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxList = function() {
  7261. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7262. keyBinding = createElementWithBindAttr("div", {text: "key"});
  7263. template = [template.substring(0, template.length - 6), "<!-- ko if: $data.key -->" + keyBinding + "<!-- /ko -->", "</div>"];
  7264. return template.join("")
  7265. };
  7266. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxToolbar = function() {
  7267. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base();
  7268. template = [template.substring(0, template.length - 6), "<!-- ko if: $data.widget -->"];
  7269. $.each(["button", "tabs", "dropDownMenu"], function() {
  7270. var bindingName = DX.inflector.camelize(["dx", "-", this].join("")),
  7271. bindingObj = {};
  7272. bindingObj[bindingName] = "$data.options";
  7273. template.push("<!-- ko if: $data.widget === '", this, "' -->", createElementWithBindAttr("div", bindingObj), "<!-- /ko -->")
  7274. });
  7275. template.push("<!-- /ko -->");
  7276. return template.join("")
  7277. };
  7278. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxGallery = function() {
  7279. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7280. primitiveBinding = createElementWithBindAttr("div", {text: "String($data)"}),
  7281. imgBinding = createElementWithBindAttr("img", {attr: "{ src: String($data) }"}, false);
  7282. template = template.replace(primitiveBinding, imgBinding);
  7283. return template
  7284. };
  7285. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs = function() {
  7286. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base(),
  7287. baseTextBinding = createElementWithBindAttr("div", {text: "text"}),
  7288. iconBinding = createElementWithBindAttr("span", {
  7289. attr: "{ 'class': 'dx-icon-' + $data.icon }",
  7290. css: "{ 'dx-icon': true }"
  7291. }),
  7292. iconSrcBinding = createElementWithBindAttr("img", {
  7293. attr: "{ src: $data.iconSrc }",
  7294. css: "{ 'dx-icon': true }"
  7295. }, false),
  7296. 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>";
  7297. template = template.replace("<!-- ko if: !$data.html && $data.text -->", "<!-- ko if: !$data.html && ($data.text || $data.icon || $data.iconSrc) -->").replace(baseTextBinding, textBinding);
  7298. return template
  7299. };
  7300. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxActionSheet = function() {
  7301. return createElementWithBindAttr("div", {dxButton: "{ text: $data.text, clickAction: $data.clickAction, type: $data.type, disabled: !!ko.unwrap($data.disabled) }"})
  7302. };
  7303. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxNavBar = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs;
  7304. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu = function() {
  7305. var template = [createElementWithBindAttr("div", defaultKoTemplateBasicBindings, false)],
  7306. iconBinding = createElementWithBindAttr("span", {
  7307. attr: "{ 'class': 'dx-icon-' + $data.icon }",
  7308. css: "{ 'dx-icon': true }"
  7309. }),
  7310. iconSrcBinding = createElementWithBindAttr("img", {
  7311. attr: "{ src: $data.iconSrc }",
  7312. css: "{ 'dx-icon': true }"
  7313. }),
  7314. textBinding = createElementWithBindAttr("span", {
  7315. text: "text",
  7316. css: "{ 'dx-menu-item-text': true }"
  7317. }),
  7318. primitiveBinding = createElementWithBindAttr("span", {
  7319. text: "String($data)",
  7320. css: "{ 'dx-menu-item-text': true }"
  7321. }),
  7322. popout = '<span class="dx-menu-item-popout-container"><div class="dx-menu-item-popout"></div></span>';
  7323. 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>');
  7324. return template.join("")
  7325. };
  7326. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxContextMenu = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu;
  7327. $.extend(ui, {
  7328. TemplateProvider: KoTemplateProvider,
  7329. Template: KoTemplate,
  7330. defaultTemplate: defaultKoTemplate
  7331. });
  7332. ui.__internals = ui.__internals || {};
  7333. $.extend(ui.__internals, {KoTemplate: KoTemplate})
  7334. })(jQuery, DevExpress);
  7335. /*! Module core, file ng.templates.js */
  7336. (function($, DX, undefined) {
  7337. if (!DX.support.hasNg)
  7338. return;
  7339. var ui = DX.ui;
  7340. var CREATED_WITH_NG_DATA_KEY = "dxNgCreation",
  7341. COMPILER_DATA_KEY = "dxNgCompiler",
  7342. DEFAULT_COMPILER_DATA_KEY = "dxDefaultCompilerGetter";
  7343. var NgTemplate = ui.Template.inherit({
  7344. ctor: function() {
  7345. this.callBase.apply(this, arguments);
  7346. this._compiler = this._template.data(COMPILER_DATA_KEY)
  7347. },
  7348. render: function(container, data, index) {
  7349. var compiler = this._compiler,
  7350. result = $.isFunction(compiler) ? compiler(data, index) : compiler;
  7351. container.append(result);
  7352. return result
  7353. },
  7354. setCompiler: function(compilerGetter) {
  7355. this._compiler = compilerGetter(this._element)
  7356. }
  7357. });
  7358. var NgTemplateProvider = ui.TemplateProvider.inherit({
  7359. getTemplateClass: function(widget) {
  7360. if (this._createdWithNg(widget))
  7361. return NgTemplate;
  7362. return this.callBase(widget)
  7363. },
  7364. supportDefaultTemplate: function(widget) {
  7365. return this._createdWithNg(widget) ? true : this.callBase(widget)
  7366. },
  7367. getDefaultTemplate: function(widget) {
  7368. if (this._createdWithNg(widget)) {
  7369. var compilerGetter = widget._element().data(DEFAULT_COMPILER_DATA_KEY),
  7370. template = defaultNgTemplate(widget.NAME);
  7371. template.setCompiler(compilerGetter);
  7372. return template
  7373. }
  7374. },
  7375. _createdWithNg: function(widget) {
  7376. return !!widget._element().data(CREATED_WITH_NG_DATA_KEY)
  7377. }
  7378. });
  7379. var defaultNgTemplate = function() {
  7380. var cache = {};
  7381. return function(widgetName) {
  7382. if (!DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName])
  7383. widgetName = "base";
  7384. if (!cache[widgetName])
  7385. cache[widgetName] = DEFAULT_ITEM_TEMPLATE_GENERATORS[widgetName]();
  7386. return new NgTemplate(cache[widgetName])
  7387. }
  7388. }();
  7389. var baseElements = {
  7390. container: function() {
  7391. return $("<div>").attr("ng-class", "{ 'dx-state-invisible': !visible && visible != undefined, 'dx-state-disabled': !!disabled }")
  7392. },
  7393. html: function() {
  7394. return $("<div>").attr("ng-if", "html").attr("ng-bind-html", "html")
  7395. },
  7396. text: function() {
  7397. return $("<div>").attr("ng-if", "text").attr("ng-bind", "text")
  7398. },
  7399. primitive: function() {
  7400. return $("<div>").attr("ng-if", "scopeValue").attr("ng-bind-html", "'' + scopeValue")
  7401. }
  7402. };
  7403. var DEFAULT_ITEM_TEMPLATE_GENERATORS = {base: function() {
  7404. return baseElements.container().append(baseElements.html()).append(baseElements.text()).append(baseElements.primitive())
  7405. }};
  7406. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxList = function() {
  7407. return DEFAULT_ITEM_TEMPLATE_GENERATORS.base().append($("<div>").attr("ng-if", "key").attr("ng-bind", "key"))
  7408. };
  7409. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxToolbar = function() {
  7410. var template = DEFAULT_ITEM_TEMPLATE_GENERATORS.base();
  7411. $.each(["button", "tabs", "dropDownMenu"], function(i, widgetName) {
  7412. var bindingName = "dx-" + DX.inflector.dasherize(this);
  7413. $("<div>").attr("ng-if", "widget === '" + widgetName + "'").attr(bindingName, "options").appendTo(template)
  7414. });
  7415. return template
  7416. };
  7417. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxGallery = function() {
  7418. return baseElements.container().append(baseElements.html()).append(baseElements.text()).append($("<img>").attr("ng-if", "scopeValue").attr("ng-src", "{{'' + scopeValue}}"))
  7419. };
  7420. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs = function() {
  7421. var container = baseElements.container();
  7422. var text = $("<span>").addClass("dx-tab-text").attr("ng-bind", "text").attr("ng-if", "text"),
  7423. icon = $("<span>").attr("ng-if", "icon").addClass("dx-icon").attr("ng-class", "'dx-icon-' + icon"),
  7424. iconSrc = $("<img>").attr("ng-if", "iconSrc").addClass("dx-icon").attr("ng-src", "{{iconSrc}}");
  7425. return container.append(baseElements.html()).append(icon).append(iconSrc).append(text).append(baseElements.primitive())
  7426. };
  7427. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxMenu = function() {
  7428. var container = baseElements.container();
  7429. var content = $("<div>").addClass("dx-menu-item-content"),
  7430. text = $("<span>").attr("ng-if", "text").addClass("dx-menu-item-text").attr("ng-bind", "text"),
  7431. icon = $("<span>").attr("ng-if", "icon").addClass("dx-icon").attr("ng-class", "'dx-icon-' + icon"),
  7432. iconSrc = $("<img>").attr("ng-if", "iconSrc").addClass("dx-icon").attr("ng-src", "{{iconSrc}}"),
  7433. popout = $("<span>").addClass("dx-menu-item-popout-container").attr("ng-if", "items").append($("<div>").addClass("dx-menu-item-popout"));
  7434. content.append(baseElements.html()).append(icon).append(iconSrc).append(text).append(popout).append(baseElements.primitive()).appendTo(container);
  7435. return container
  7436. },
  7437. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxActionSheet = function() {
  7438. return $("<div>").attr("dx-button", "{ bindingOptions: { text: 'text', clickAction: 'clickAction', type: 'type', disabled: 'disabled' } }")
  7439. };
  7440. DEFAULT_ITEM_TEMPLATE_GENERATORS.dxNavBar = DEFAULT_ITEM_TEMPLATE_GENERATORS.dxTabs;
  7441. $.extend(ui, {
  7442. Template: NgTemplate,
  7443. TemplateProvider: NgTemplateProvider
  7444. })
  7445. })(jQuery, DevExpress);
  7446. /*! Module core, file ui.themes.js */
  7447. (function($, DX, undefined) {
  7448. var DX_LINK_SELECTOR = "link[rel=dx-theme]",
  7449. THEME_ATTR = "data-theme",
  7450. ACTIVE_ATTR = "data-active";
  7451. var context,
  7452. $activeThemeLink,
  7453. knownThemes,
  7454. currentThemeName,
  7455. pendingThemeName;
  7456. var THEME_MARKER_PREFIX = "dx.";
  7457. function readThemeMarker() {
  7458. var element = $("<div></div>", context).addClass("dx-theme-marker").appendTo(context.documentElement),
  7459. result;
  7460. try {
  7461. result = element.css("font-family");
  7462. if (!result)
  7463. return null;
  7464. result = result.replace(/["']/g, "");
  7465. if (result.substr(0, THEME_MARKER_PREFIX.length) !== THEME_MARKER_PREFIX)
  7466. return null;
  7467. return result.substr(THEME_MARKER_PREFIX.length)
  7468. }
  7469. finally {
  7470. element.remove()
  7471. }
  7472. }
  7473. function waitForThemeLoad(themeName, callback) {
  7474. var timerId,
  7475. waitStartTime;
  7476. pendingThemeName = themeName;
  7477. function handleLoaded() {
  7478. pendingThemeName = null;
  7479. callback()
  7480. }
  7481. if (isPendingThemeLoaded())
  7482. handleLoaded();
  7483. else {
  7484. waitStartTime = $.now();
  7485. timerId = setInterval(function() {
  7486. var isLoaded = isPendingThemeLoaded(),
  7487. isTimeout = !isLoaded && $.now() - waitStartTime > 15 * 1000;
  7488. if (isTimeout)
  7489. DX.utils.logger.warn("Theme loading timed out: " + pendingThemeName);
  7490. if (isLoaded || isTimeout) {
  7491. clearInterval(timerId);
  7492. handleLoaded()
  7493. }
  7494. }, 10)
  7495. }
  7496. }
  7497. function isPendingThemeLoaded() {
  7498. return !pendingThemeName || readThemeMarker() === pendingThemeName
  7499. }
  7500. function processMarkup() {
  7501. var $allThemeLinks = $(DX_LINK_SELECTOR, context);
  7502. if (!$allThemeLinks.length)
  7503. return;
  7504. knownThemes = {};
  7505. $activeThemeLink = $(DX.utils.createMarkupFromString("<link rel=stylesheet>"), context);
  7506. $allThemeLinks.each(function() {
  7507. var link = $(this, context),
  7508. fullThemeName = link.attr(THEME_ATTR),
  7509. url = link.attr("href"),
  7510. isActive = link.attr(ACTIVE_ATTR) === "true";
  7511. knownThemes[fullThemeName] = {
  7512. url: url,
  7513. isActive: isActive
  7514. }
  7515. });
  7516. $allThemeLinks.last().after($activeThemeLink);
  7517. $allThemeLinks.remove()
  7518. }
  7519. function resolveFullThemeName(desiredThemeName) {
  7520. var desiredThemeParts = desiredThemeName.split("."),
  7521. result = null;
  7522. if (knownThemes)
  7523. $.each(knownThemes, function(knownThemeName, themeData) {
  7524. var knownThemeParts = knownThemeName.split(".");
  7525. if (knownThemeParts[0] !== desiredThemeParts[0])
  7526. return;
  7527. if (desiredThemeParts[1] && desiredThemeParts[1] !== knownThemeParts[1])
  7528. return;
  7529. if (!result || themeData.isActive)
  7530. result = knownThemeName;
  7531. if (themeData.isActive)
  7532. return false
  7533. });
  7534. return result
  7535. }
  7536. function initContext(newContext) {
  7537. try {
  7538. if (newContext !== context)
  7539. knownThemes = null
  7540. }
  7541. catch(x) {
  7542. knownThemes = null
  7543. }
  7544. context = newContext
  7545. }
  7546. function init(options) {
  7547. options = options || {};
  7548. initContext(options.context || document);
  7549. processMarkup();
  7550. currentThemeName = undefined;
  7551. current(options)
  7552. }
  7553. function current(options) {
  7554. if (!arguments.length)
  7555. return currentThemeName || readThemeMarker();
  7556. options = options || {};
  7557. if (typeof options === "string")
  7558. options = {theme: options};
  7559. var isAutoInit = options._autoInit,
  7560. loadCallback = options.loadCallback,
  7561. currentThemeData;
  7562. currentThemeName = options.theme || currentThemeName;
  7563. if (isAutoInit && !currentThemeName)
  7564. currentThemeName = themeNameFromDevice(DX.devices.current());
  7565. currentThemeName = resolveFullThemeName(currentThemeName);
  7566. if (currentThemeName)
  7567. currentThemeData = knownThemes[currentThemeName];
  7568. if (currentThemeData) {
  7569. $activeThemeLink.removeAttr("href");
  7570. $activeThemeLink.attr("href", knownThemes[currentThemeName].url);
  7571. if (loadCallback)
  7572. waitForThemeLoad(currentThemeName, loadCallback);
  7573. else if (pendingThemeName)
  7574. pendingThemeName = currentThemeName
  7575. }
  7576. else if (isAutoInit) {
  7577. if (loadCallback)
  7578. loadCallback()
  7579. }
  7580. else
  7581. throw Error("Unknown theme: " + currentThemeName);
  7582. }
  7583. function themeNameFromDevice(device) {
  7584. var themeName = device.platform,
  7585. majorVersion = device.version && device.version[0];
  7586. if (themeName === "ios" && (!majorVersion || majorVersion > 6))
  7587. themeName += "7";
  7588. return themeName
  7589. }
  7590. function getCssClasses(themeName) {
  7591. themeName = themeName || current();
  7592. var result = [],
  7593. themeNameParts = themeName && themeName.split(".");
  7594. if (themeNameParts) {
  7595. result.push("dx-theme-" + themeNameParts[0], "dx-theme-" + themeNameParts[0] + "-typography");
  7596. if (themeNameParts.length > 1)
  7597. result.push("dx-color-scheme-" + themeNameParts[1])
  7598. }
  7599. return result
  7600. }
  7601. function attachCssClasses(element, themeName) {
  7602. $(element).addClass(getCssClasses(themeName).join(" "))
  7603. }
  7604. function detachCssClasses(element, themeName) {
  7605. $(element).removeClass(getCssClasses(themeName).join(" "))
  7606. }
  7607. $.holdReady(true);
  7608. init({
  7609. _autoInit: true,
  7610. loadCallback: function() {
  7611. $.holdReady(false)
  7612. }
  7613. });
  7614. $(function() {
  7615. if ($(DX_LINK_SELECTOR, context).length)
  7616. throw Error("LINK[rel=dx-theme] tags must go before DevExpress included scripts");
  7617. });
  7618. DX.ui.themes = {
  7619. init: init,
  7620. current: current,
  7621. attachCssClasses: attachCssClasses,
  7622. detachCssClasses: detachCssClasses
  7623. };
  7624. DX.ui.themes.__internals = {
  7625. themeNameFromDevice: themeNameFromDevice,
  7626. waitForThemeLoad: waitForThemeLoad,
  7627. resetTheme: function() {
  7628. $activeThemeLink.attr("href", "about:blank");
  7629. currentThemeName = null;
  7630. pendingThemeName = null
  7631. }
  7632. }
  7633. })(jQuery, DevExpress);
  7634. /*! Module core, file ui.events.js */
  7635. (function($, DX, undefined) {
  7636. var ui = DX.ui,
  7637. eventNS = $.event,
  7638. specialNS = eventNS.special,
  7639. EVENT_SOURCES_REGEX = {
  7640. mouse: /(mouse|wheel|click)/i,
  7641. wheel: /wheel/i,
  7642. touch: /^touch/i,
  7643. keyboard: /^key/i,
  7644. pointer: /pointer/i
  7645. };
  7646. var eventSource = function(e) {
  7647. var result = "other";
  7648. $.each(EVENT_SOURCES_REGEX, function(key) {
  7649. if (this.test(e.type)) {
  7650. result = key;
  7651. return false
  7652. }
  7653. });
  7654. return result
  7655. };
  7656. var isPointerEvent = function(e) {
  7657. return eventSource(e) === "pointer"
  7658. };
  7659. var isMouseEvent = function(e) {
  7660. return eventSource(e) === "mouse" || isPointerEvent(e) && e.pointerType === "mouse"
  7661. };
  7662. var isTouchEvent = function(e) {
  7663. return eventSource(e) === "touch" || isPointerEvent(e) && e.pointerType === "touch"
  7664. };
  7665. var isKeyboardEvent = function(e) {
  7666. return eventSource(e) === "keyboard"
  7667. };
  7668. var isMouseWheelEvent = function(e) {
  7669. return EVENT_SOURCES_REGEX["wheel"].test(e.type)
  7670. };
  7671. var addNamespace = function(eventNames, namespace) {
  7672. if (!namespace)
  7673. throw Error("Namespace is not defined");
  7674. if (typeof eventNames === "string")
  7675. return addNamespace(eventNames.split(/\s+/g), namespace);
  7676. $.each(eventNames, function(index, eventName) {
  7677. eventNames[index] = eventName + "." + namespace
  7678. });
  7679. return eventNames.join(" ")
  7680. };
  7681. var eventData = function(e) {
  7682. if (isPointerEvent(e) && isTouchEvent(e)) {
  7683. var touch = (e.originalEvent.originalEvent || e.originalEvent).changedTouches[0];
  7684. return {
  7685. x: touch.pageX,
  7686. y: touch.pageY,
  7687. time: e.timeStamp
  7688. }
  7689. }
  7690. if (isMouseEvent(e))
  7691. return {
  7692. x: e.pageX,
  7693. y: e.pageY,
  7694. time: e.timeStamp
  7695. };
  7696. if (isTouchEvent(e)) {
  7697. var touch = (e.changedTouches || e.originalEvent.changedTouches)[0];
  7698. return {
  7699. x: touch.pageX,
  7700. y: touch.pageY,
  7701. time: e.timeStamp
  7702. }
  7703. }
  7704. };
  7705. var eventDelta = function(from, to) {
  7706. return {
  7707. x: to.x - from.x,
  7708. y: to.y - from.y,
  7709. time: to.time - from.time || 1
  7710. }
  7711. };
  7712. var hasTouches = function(e) {
  7713. if (isTouchEvent(e))
  7714. return (e.originalEvent.touches || []).length;
  7715. return 0
  7716. };
  7717. var needSkipEvent = function(e) {
  7718. var $target = $(e.target),
  7719. touchInInput = $target.is("input, textarea, select");
  7720. if (isMouseWheelEvent(e) && touchInInput)
  7721. return false;
  7722. if (isMouseEvent(e))
  7723. return touchInInput || e.which > 1;
  7724. if (isTouchEvent(e))
  7725. return touchInInput && $target.is(":focus") || (e.originalEvent.changedTouches || e.originalEvent.originalEvent.changedTouches).length !== 1
  7726. };
  7727. var createEvent = function(sourceEvent, props) {
  7728. var event = $.Event(sourceEvent),
  7729. originalEvent = event.originalEvent,
  7730. propNames = $.event.props.slice();
  7731. if (isMouseEvent(sourceEvent) || isTouchEvent(sourceEvent))
  7732. $.merge(propNames, $.event.mouseHooks.props);
  7733. if (isKeyboardEvent(sourceEvent))
  7734. $.merge(propNames, $.event.keyHooks.props);
  7735. if (originalEvent)
  7736. $.each(propNames, function() {
  7737. event[this] = originalEvent[this]
  7738. });
  7739. if (props)
  7740. $.extend(event, props);
  7741. return event
  7742. };
  7743. var fireEvent = function(props) {
  7744. var event = createEvent(props.originalEvent, props);
  7745. $.event.trigger(event, null, props.target || event.target);
  7746. return event
  7747. };
  7748. var handleGestureEvent = function(e, type) {
  7749. var gestureEvent = $(e.target).data("dxGestureEvent");
  7750. if (!gestureEvent || gestureEvent === type) {
  7751. $(e.target).data("dxGestureEvent", type);
  7752. return true
  7753. }
  7754. return false
  7755. };
  7756. var registerEvent = function(eventName, eventObject) {
  7757. var strategy = {};
  7758. if ("noBubble" in eventObject)
  7759. strategy.noBubble = eventObject.noBubble;
  7760. if ("bindType" in eventObject)
  7761. strategy.bindType = eventObject.bindType;
  7762. if ("delegateType" in eventObject)
  7763. strategy.delegateType = eventObject.delegateType;
  7764. $.each(["setup", "teardown", "add", "remove", "trigger", "handle", "_default", "dispose"], function(_, methodName) {
  7765. if (!eventObject[methodName])
  7766. return;
  7767. strategy[methodName] = function() {
  7768. var args = $.makeArray(arguments);
  7769. args.unshift(this);
  7770. return eventObject[methodName].apply(eventObject, args)
  7771. }
  7772. });
  7773. specialNS[eventName] = strategy
  7774. };
  7775. ui.events = {
  7776. eventSource: eventSource,
  7777. isPointerEvent: isPointerEvent,
  7778. isMouseEvent: isMouseEvent,
  7779. isTouchEvent: isTouchEvent,
  7780. isKeyboardEvent: isKeyboardEvent,
  7781. addNamespace: addNamespace,
  7782. hasTouches: hasTouches,
  7783. eventData: eventData,
  7784. eventDelta: eventDelta,
  7785. needSkipEvent: needSkipEvent,
  7786. createEvent: createEvent,
  7787. fireEvent: fireEvent,
  7788. handleGestureEvent: handleGestureEvent,
  7789. registerEvent: registerEvent
  7790. }
  7791. })(jQuery, DevExpress);
  7792. /*! Module core, file ko.events.js */
  7793. (function($, DX, undefined) {
  7794. if (!DX.support.hasKo)
  7795. return;
  7796. var ko = window.ko,
  7797. events = DX.ui.events;
  7798. var originalRegisterEvent = events.registerEvent;
  7799. var registerKoEvent = function(eventName, eventObject) {
  7800. originalRegisterEvent(eventName, eventObject);
  7801. var koBindingEventName = events.addNamespace(eventName, eventName + "Binding");
  7802. ko.bindingHandlers[eventName] = {update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
  7803. var $element = $(element),
  7804. unwrappedValue = ko.utils.unwrapObservable(valueAccessor()),
  7805. eventSource = unwrappedValue.execute ? unwrappedValue.execute : unwrappedValue;
  7806. $element.off(koBindingEventName).on(koBindingEventName, $.isPlainObject(unwrappedValue) ? unwrappedValue : {}, function(e) {
  7807. eventSource(viewModel, e)
  7808. })
  7809. }}
  7810. };
  7811. $.extend(events, {registerEvent: registerKoEvent})
  7812. })(jQuery, DevExpress);
  7813. /*! Module core, file ng.events.js */
  7814. (function($, DX, undefined) {
  7815. if (!DX.support.hasNg)
  7816. return;
  7817. var events = DX.ui.events;
  7818. var originalRegisterEvent = events.registerEvent;
  7819. var registerNgEvent = function(eventName, eventObject) {
  7820. originalRegisterEvent(eventName, eventObject);
  7821. var ngEventName = eventName.slice(0, 2) + eventName.charAt(2).toUpperCase() + eventName.slice(3);
  7822. DX.ng.module.directive(ngEventName, ['$parse', function($parse) {
  7823. return function(scope, element, attr) {
  7824. var attrValue = $.trim(attr[ngEventName]),
  7825. handler,
  7826. eventOptions = {};
  7827. if (attrValue.charAt(0) === "{") {
  7828. eventOptions = scope.$eval(attrValue);
  7829. handler = $parse(eventOptions.execute)
  7830. }
  7831. else
  7832. handler = $parse(attr[ngEventName]);
  7833. element.on(eventName, eventOptions, function(e) {
  7834. scope.$apply(function() {
  7835. handler(scope, {$event: e})
  7836. })
  7837. })
  7838. }
  7839. }])
  7840. };
  7841. $.extend(events, {registerEvent: registerNgEvent})
  7842. })(jQuery, DevExpress);
  7843. /*! Module core, file ui.hierarchicalKeyDownProcessor.js */
  7844. (function($, DX, undefined) {
  7845. var ui = DX.ui,
  7846. events = ui.events;
  7847. ui.HierarchicalKeyDownProcessor = DX.Class.inherit({
  7848. _keydown: events.addNamespace("keydown", "HierarchicalKeyDownProcessor"),
  7849. codes: {
  7850. "9": "tab",
  7851. "13": "enter",
  7852. "27": "escape",
  7853. "33": "pageUp",
  7854. "34": "pageDown",
  7855. "37": "leftArrow",
  7856. "38": "upArrow",
  7857. "39": "rightArrow",
  7858. "40": "downArrow",
  7859. "32": "space",
  7860. "70": "F",
  7861. "65": "A"
  7862. },
  7863. ctor: function(options) {
  7864. var _this = this;
  7865. options = options || {};
  7866. if (options.element)
  7867. this._element = $(options.element);
  7868. this._handler = options.handler;
  7869. this._context = options.context;
  7870. this._childProcessors = [];
  7871. if (this._element)
  7872. this._element.on(this._keydown, function(e) {
  7873. _this.process(e)
  7874. })
  7875. },
  7876. dispose: function() {
  7877. if (this._element)
  7878. this._element.off(this._keydown);
  7879. this._element = undefined;
  7880. this._handler = undefined;
  7881. this._context = undefined;
  7882. this._childProcessors = undefined
  7883. },
  7884. attachChildProcessor: function() {
  7885. var childProcessor = new ui.HierarchicalKeyDownProcessor;
  7886. this._childProcessors.push(childProcessor);
  7887. return childProcessor
  7888. },
  7889. reinitialize: function(childHandler, childContext) {
  7890. this._context = childContext;
  7891. this._handler = childHandler;
  7892. return this
  7893. },
  7894. process: function(e) {
  7895. var args = {
  7896. key: this.codes[e.which],
  7897. ctrl: e.ctrlKey,
  7898. shift: e.shiftKey,
  7899. originalEvent: e
  7900. };
  7901. if (this.codes[e.which] && this._handler && this._handler.call(this._context, args))
  7902. $.each(this._childProcessors, function(index, childProcessor) {
  7903. childProcessor.process(e)
  7904. })
  7905. }
  7906. })
  7907. })(jQuery, DevExpress);
  7908. /*! Module core, file ui.dialog.js */
  7909. (function($, DX, undefined) {
  7910. var ui = DX.ui,
  7911. utils = DX.utils;
  7912. var DEFAULT_BUTTON = {
  7913. text: "OK",
  7914. clickAction: function() {
  7915. return true
  7916. }
  7917. };
  7918. var DX_DIALOG_CLASSNAME = "dx-dialog",
  7919. DX_DIALOG_WRAPPER_CLASSNAME = DX_DIALOG_CLASSNAME + "-wrapper",
  7920. DX_DIALOG_ROOT_CLASSNAME = DX_DIALOG_CLASSNAME + "-root",
  7921. DX_DIALOG_CONTENT_CLASSNAME = DX_DIALOG_CLASSNAME + "-content",
  7922. DX_DIALOG_MESSAGE_CLASSNAME = DX_DIALOG_CLASSNAME + "-message",
  7923. DX_DIALOG_BUTTONS_CLASSNAME = DX_DIALOG_CLASSNAME + "-buttons",
  7924. DX_DIALOG_BUTTON_CLASSNAME = DX_DIALOG_CLASSNAME + "-button";
  7925. var FakeDialogComponent = DX.Component.inherit({
  7926. NAME: "dxDialog",
  7927. ctor: function(element, options) {
  7928. this.callBase(options)
  7929. },
  7930. _defaultOptionsRules: function() {
  7931. return this.callBase().slice(0).concat([{
  7932. device: [{platform: "ios"}, {platform: "ios7"}],
  7933. options: {width: 276}
  7934. }, {
  7935. device: {platform: "android"},
  7936. options: {
  7937. lWidth: "60%",
  7938. pWidth: "80%"
  7939. }
  7940. }, {
  7941. device: {
  7942. platform: "win8",
  7943. phone: false
  7944. },
  7945. options: {width: function() {
  7946. return $(window).width()
  7947. }}
  7948. }, {
  7949. device: {
  7950. platform: "win8",
  7951. phone: true
  7952. },
  7953. options: {position: {
  7954. my: "top center",
  7955. at: "top center",
  7956. of: window,
  7957. offset: "0 0"
  7958. }}
  7959. }])
  7960. }
  7961. });
  7962. var dialog = function(options) {
  7963. var that = this,
  7964. result;
  7965. if (!ui.dxPopup)
  7966. throw new Error("DevExpress.ui.dxPopup required");
  7967. var deferred = $.Deferred();
  7968. var defaultOptions = (new FakeDialogComponent).option();
  7969. options = $.extend(defaultOptions, options);
  7970. var $holder = $(DX.overlayTargetContainer());
  7971. var $element = $("<div>").addClass(DX_DIALOG_CLASSNAME).appendTo($holder);
  7972. var $message = $("<div>").addClass(DX_DIALOG_MESSAGE_CLASSNAME).html(String(options.message));
  7973. var $buttons = $("<div>").addClass(DX_DIALOG_BUTTONS_CLASSNAME);
  7974. var popupInstance = $element.dxPopup({
  7975. title: options.title || that.title,
  7976. height: "auto",
  7977. width: function() {
  7978. var isPortrait = $(window).height() > $(window).width(),
  7979. key = (isPortrait ? "p" : "l") + "Width",
  7980. widthOption = options.hasOwnProperty(key) ? options[key] : options["width"];
  7981. return $.isFunction(widthOption) ? widthOption() : widthOption
  7982. },
  7983. contentReadyAction: function() {
  7984. popupInstance.content().addClass(DX_DIALOG_CONTENT_CLASSNAME).append($message).append($buttons)
  7985. },
  7986. animation: {
  7987. show: {
  7988. type: "pop",
  7989. duration: 400
  7990. },
  7991. hide: {
  7992. type: "pop",
  7993. duration: 400,
  7994. to: {
  7995. opacity: 0,
  7996. scale: 0
  7997. },
  7998. from: {
  7999. opacity: 1,
  8000. scale: 1
  8001. }
  8002. }
  8003. },
  8004. rtlEnabled: DX.rtlEnabled
  8005. }).data("dxPopup");
  8006. popupInstance._wrapper().addClass(DX_DIALOG_WRAPPER_CLASSNAME);
  8007. if (options.position)
  8008. popupInstance.option("position", options.position);
  8009. $.each(options.buttons || [DEFAULT_BUTTON], function() {
  8010. var button = $("<div>").addClass(DX_DIALOG_BUTTON_CLASSNAME).appendTo($buttons);
  8011. var action = new DX.Action(this.clickAction, {context: popupInstance});
  8012. button.dxButton($.extend(this, {clickAction: function() {
  8013. result = action.execute(arguments);
  8014. hide()
  8015. }}))
  8016. });
  8017. popupInstance._wrapper().addClass(DX_DIALOG_ROOT_CLASSNAME);
  8018. function show() {
  8019. popupInstance.show();
  8020. utils.resetActiveElement();
  8021. return deferred.promise()
  8022. }
  8023. function hide(value) {
  8024. popupInstance.hide().done(function() {
  8025. popupInstance._element().remove()
  8026. });
  8027. deferred.resolve(result || value)
  8028. }
  8029. return {
  8030. show: show,
  8031. hide: hide
  8032. }
  8033. };
  8034. var alert = function(message, title) {
  8035. var dialogInstance,
  8036. options = $.isPlainObject(message) ? message : {
  8037. title: title,
  8038. message: message
  8039. };
  8040. dialogInstance = ui.dialog.custom(options);
  8041. return dialogInstance.show()
  8042. };
  8043. var confirm = function(message, title) {
  8044. var dialogInstance,
  8045. options = $.isPlainObject(message) ? message : {
  8046. title: title,
  8047. message: message,
  8048. buttons: [{
  8049. text: Globalize.localize("Yes"),
  8050. clickAction: function() {
  8051. return true
  8052. }
  8053. }, {
  8054. text: Globalize.localize("No"),
  8055. clickAction: function() {
  8056. return false
  8057. }
  8058. }]
  8059. };
  8060. dialogInstance = ui.dialog.custom(options);
  8061. return dialogInstance.show()
  8062. };
  8063. var notify = function(message, type, displayTime) {
  8064. var options = $.isPlainObject(message) ? message : {message: message};
  8065. if (!ui.dxToast) {
  8066. alert(options.message);
  8067. return
  8068. }
  8069. var userHiddenAction = options.hiddenAction;
  8070. $.extend(options, {
  8071. type: type,
  8072. displayTime: displayTime,
  8073. hiddenAction: function(args) {
  8074. args.element.remove();
  8075. new DX.Action(userHiddenAction, {context: args.model}).execute(arguments)
  8076. }
  8077. });
  8078. $("<div>").appendTo(DX.overlayTargetContainer()).dxToast(options).dxToast("instance").show()
  8079. };
  8080. $.extend(ui, {
  8081. notify: notify,
  8082. dialog: {
  8083. custom: dialog,
  8084. alert: alert,
  8085. confirm: confirm,
  8086. FakeDialogComponent: FakeDialogComponent
  8087. }
  8088. })
  8089. })(jQuery, DevExpress);
  8090. /*! Module core, file ui.dataHelper.js */
  8091. (function($, DX, undefined) {
  8092. var data = DX.data;
  8093. var DATA_SOURCE_OPTIONS_METHOD = "_dataSourceOptions",
  8094. DATA_SOURCE_CHANGED_METHOD = "_handleDataSourceChanged",
  8095. DATA_SOURCE_LOAD_ERROR_METHOD = "_handleDataSourceLoadError",
  8096. DATA_SOURCE_LOADING_CHANGED_METHOD = "_handleDataSourceLoadingChanged";
  8097. DX.ui.DataHelperMixin = {
  8098. ctor: function() {
  8099. this.disposing.add(function() {
  8100. this._disposeDataSource()
  8101. })
  8102. },
  8103. _refreshDataSource: function() {
  8104. this._initDataSource();
  8105. this._loadDataSource()
  8106. },
  8107. _initDataSource: function() {
  8108. var dataSourceOptions = this.option("dataSource"),
  8109. widgetDataSourceOptions,
  8110. dataSourceType;
  8111. this._disposeDataSource();
  8112. if (dataSourceOptions) {
  8113. if (dataSourceOptions instanceof data.DataSource) {
  8114. this._isSharedDataSource = true;
  8115. this._dataSource = dataSourceOptions
  8116. }
  8117. else {
  8118. widgetDataSourceOptions = DATA_SOURCE_OPTIONS_METHOD in this ? this[DATA_SOURCE_OPTIONS_METHOD]() : {};
  8119. dataSourceType = this._dataSourceType ? this._dataSourceType() : data.DataSource;
  8120. this._dataSource = new dataSourceType($.extend(true, {}, widgetDataSourceOptions, data.utils.normalizeDataSourceOptions(dataSourceOptions)))
  8121. }
  8122. this._addDataSourceHandlers()
  8123. }
  8124. },
  8125. _addDataSourceHandlers: function() {
  8126. if (DATA_SOURCE_CHANGED_METHOD in this)
  8127. this._addDataSourceChangeHandler();
  8128. if (DATA_SOURCE_LOAD_ERROR_METHOD in this)
  8129. this._addDataSourceLoadErrorHandler();
  8130. if (DATA_SOURCE_LOADING_CHANGED_METHOD in this)
  8131. this._addDataSourceLoadingChangedHandler()
  8132. },
  8133. _addDataSourceChangeHandler: function() {
  8134. var that = this,
  8135. dataSource = this._dataSource;
  8136. this._dataSourceChangedHandler = function() {
  8137. that[DATA_SOURCE_CHANGED_METHOD](dataSource.items())
  8138. };
  8139. dataSource.changed.add(this._dataSourceChangedHandler)
  8140. },
  8141. _addDataSourceLoadErrorHandler: function() {
  8142. this._dataSourceLoadErrorHandler = $.proxy(this[DATA_SOURCE_LOAD_ERROR_METHOD], this);
  8143. this._dataSource.loadError.add(this._dataSourceLoadErrorHandler)
  8144. },
  8145. _addDataSourceLoadingChangedHandler: function() {
  8146. this._dataSourceLoadingChangedHandler = $.proxy(this[DATA_SOURCE_LOADING_CHANGED_METHOD], this);
  8147. this._dataSource.loadingChanged.add(this._dataSourceLoadingChangedHandler)
  8148. },
  8149. _loadDataSource: function() {
  8150. if (this._dataSource) {
  8151. var dataSource = this._dataSource;
  8152. if (dataSource.isLoaded())
  8153. this._dataSourceChangedHandler();
  8154. else
  8155. dataSource.load()
  8156. }
  8157. },
  8158. _loadSingle: function(key, value) {
  8159. key = key === "this" ? this._dataSource.key() || "this" : key;
  8160. return this._dataSource.loadSingle(key, value)
  8161. },
  8162. _disposeDataSource: function() {
  8163. if (this._dataSource) {
  8164. if (this._isSharedDataSource) {
  8165. delete this._isSharedDataSource;
  8166. this._dataSource.changed.remove(this._dataSourceChangedHandler);
  8167. this._dataSource.loadError.remove(this._dataSourceLoadErrorHandler);
  8168. this._dataSource.loadingChanged.remove(this._dataSourceLoadingChangedHandler)
  8169. }
  8170. else
  8171. this._dataSource.dispose();
  8172. delete this._dataSource;
  8173. delete this._dataSourceChangedHandler;
  8174. delete this._dataSourceLoadErrorHandler;
  8175. delete this._dataSourceLoadingChangedHandler
  8176. }
  8177. }
  8178. }
  8179. })(jQuery, DevExpress);
  8180. /*! Module core, file ui.events.mspointer.js */
  8181. (function($, DX, undefined) {
  8182. var POINTER_TYPE_MAP = {
  8183. 2: "touch",
  8184. 3: "pen",
  8185. 4: "mouse"
  8186. };
  8187. var pointerEventHook = {
  8188. filter: function(event, originalEvent) {
  8189. var pointerType = originalEvent.pointerType;
  8190. if ($.isNumeric(pointerType))
  8191. event.pointerType = POINTER_TYPE_MAP[pointerType];
  8192. return event
  8193. },
  8194. props: $.event.mouseHooks.props.concat(["pointerId", "originalTarget", "namespace", "width", "height", "pressure", "result", "tiltX", "charCode", "tiltY", "detail", "isPrimary", "prevValue"])
  8195. };
  8196. $.each(["MSPointerDown", "MSPointerMove", "MSPointerUp", "MSPointerCancel", "MSPointerOver", "MSPointerOut", "MSPointerEnter", "MSPointerLeave", "pointerdown", "pointermove", "pointerup", "pointercancel", "pointerover", "pointerout", "pointerenter", "pointerleave"], function() {
  8197. $.event.fixHooks[this] = pointerEventHook
  8198. })
  8199. })(jQuery, DevExpress);
  8200. /*! Module core, file ui.events.touch.js */
  8201. (function($, DX, undefined) {
  8202. var touchEventHook = {
  8203. filter: function(event, originalEvent) {
  8204. if (originalEvent.changedTouches.length)
  8205. $.each(["pageX", "pageY", "screenX", "screenY", "clientX", "clientY"], function() {
  8206. event[this] = originalEvent.changedTouches[0][this]
  8207. });
  8208. return event
  8209. },
  8210. props: $.event.mouseHooks.props.concat(["touches", "changedTouches", "targetTouches", "detail", "result", "namespace", "originalTarget", "charCode", "prevValue"])
  8211. };
  8212. $.each(["touchstart", "touchmove", "touchend", "touchcancel"], function() {
  8213. $.event.fixHooks[this] = touchEventHook
  8214. })
  8215. })(jQuery, DevExpress);
  8216. /*! Module core, file ui.events.pointer.js */
  8217. (function($, DX, undefined) {
  8218. var ui = DX.ui,
  8219. support = DX.support,
  8220. device = $.proxy(DX.devices.real, DX.devices),
  8221. events = ui.events;
  8222. var POINTER_EVENTS_NAMESPACE = "dxPointerEvents",
  8223. MouseStrategyEventMap = {
  8224. dxpointerdown: "mousedown",
  8225. dxpointermove: "mousemove",
  8226. dxpointerup: "mouseup",
  8227. dxpointercancel: ""
  8228. },
  8229. TouchStrategyEventMap = {
  8230. dxpointerdown: "touchstart",
  8231. dxpointermove: "touchmove",
  8232. dxpointerup: "touchend",
  8233. dxpointercancel: "touchcancel"
  8234. },
  8235. PointerStrategyEventMap = {
  8236. dxpointerdown: "pointerdown",
  8237. dxpointermove: "pointermove",
  8238. dxpointerup: "pointerup",
  8239. dxpointercancel: "pointercancel"
  8240. },
  8241. MouseAndTouchStrategyEventMap = {
  8242. dxpointerdown: "touchstart mousedown",
  8243. dxpointermove: "touchmove mousemove",
  8244. dxpointerup: "touchend mouseup",
  8245. dxpointercancel: "touchcancel"
  8246. };
  8247. var eventMap = function() {
  8248. if (support.touch && !(device().tablet || device().phone))
  8249. return MouseAndTouchStrategyEventMap;
  8250. if (support.pointer)
  8251. return MouseStrategyEventMap;
  8252. if (support.touch)
  8253. return TouchStrategyEventMap;
  8254. return MouseStrategyEventMap
  8255. }();
  8256. var skipTouchWithSameIdentifier = function(pointerEvent) {
  8257. return device().platform === "ios" && (pointerEvent === "dxpointerdown" || pointerEvent === "dxpointerup")
  8258. };
  8259. var SingleEventStrategy = DX.Class.inherit({
  8260. ctor: function(eventName, originalEvents) {
  8261. this._eventName = eventName;
  8262. this._eventNamespace = [POINTER_EVENTS_NAMESPACE, ".", this._eventName].join("");
  8263. this._originalEvents = originalEvents;
  8264. this._pointerId = 0;
  8265. this._handlerCount = 0
  8266. },
  8267. _handler: function(e) {
  8268. if (this._eventName === "dxpointerdown")
  8269. $(e.target).data("dxGestureEvent", null);
  8270. if (events.isTouchEvent(e) && skipTouchWithSameIdentifier(this._eventName)) {
  8271. var touch = e.changedTouches[0];
  8272. if (this._pointerId === touch.identifier && this._pointerId !== 0)
  8273. return;
  8274. this._pointerId = touch.identifier
  8275. }
  8276. return events.fireEvent({
  8277. type: this._eventName,
  8278. pointerType: events.eventSource(e),
  8279. originalEvent: e
  8280. })
  8281. },
  8282. setup: function() {
  8283. if (this._handlerCount > 0)
  8284. return;
  8285. $(document).on(events.addNamespace(this._originalEvents, this._eventNamespace), $.proxy(this._handler, this))
  8286. },
  8287. add: function() {
  8288. this._handlerCount++
  8289. },
  8290. remove: function() {
  8291. this._handlerCount--
  8292. },
  8293. teardown: function() {
  8294. if (this._handlerCount)
  8295. return;
  8296. $(document).off("." + this._eventNamespace)
  8297. },
  8298. dispose: function() {
  8299. $(document).off("." + this._eventNamespace)
  8300. }
  8301. });
  8302. var MultiEventStrategy = SingleEventStrategy.inherit({
  8303. EVENT_LOCK_TIMEOUT: 100,
  8304. _handler: function(e) {
  8305. if (events.isTouchEvent(e))
  8306. this._skipNextEvents = true;
  8307. if (events.isMouseEvent(e) && this._mouseLocked)
  8308. return;
  8309. if (events.isMouseEvent(e) && this._skipNextEvents) {
  8310. this._skipNextEvents = false;
  8311. this._mouseLocked = true;
  8312. clearTimeout(this._unlockMouseTimer);
  8313. this._unlockMouseTimer = setTimeout($.proxy(function() {
  8314. this._mouseLocked = false
  8315. }, this), this.EVENT_LOCK_TIMEOUT);
  8316. return
  8317. }
  8318. return this.callBase(e)
  8319. },
  8320. dispose: function() {
  8321. this.callBase();
  8322. this._skipNextEvents = false;
  8323. this._mouseLocked = false;
  8324. clearTimeout(this._unlockMouseTimer)
  8325. }
  8326. });
  8327. var getStrategy = function() {
  8328. return eventMap === MouseAndTouchStrategyEventMap ? MultiEventStrategy : SingleEventStrategy
  8329. };
  8330. $.each(eventMap, function(pointerEvent, originalEvents) {
  8331. var Strategy = getStrategy();
  8332. events.registerEvent(pointerEvent, new Strategy(pointerEvent, originalEvents))
  8333. });
  8334. DX.ui.events.__internals = DX.ui.events.__internals || {};
  8335. $.extend(DX.ui.events.__internals, {
  8336. SingleEventStrategy: SingleEventStrategy,
  8337. MultiEventStrategy: MultiEventStrategy,
  8338. MouseStrategyEventMap: MouseStrategyEventMap,
  8339. TouchStrategyEventMap: TouchStrategyEventMap,
  8340. PointerStrategyEventMap: PointerStrategyEventMap,
  8341. MouseAndTouchStrategyEventMap: MouseAndTouchStrategyEventMap,
  8342. eventMap: eventMap
  8343. })
  8344. })(jQuery, DevExpress);
  8345. /*! Module core, file ui.events.click.js */
  8346. (function($, DX, wnd, undefined) {
  8347. var ua = navigator.userAgent,
  8348. screen = wnd.screen,
  8349. ui = DX.ui,
  8350. utils = DX.utils,
  8351. events = ui.events,
  8352. support = DX.support,
  8353. device = $.proxy(DX.devices.real, DX.devices),
  8354. EVENTS_NAME_SPACE = "dxSpecialEvents",
  8355. CLICK_NAME_SPACE = "dxClick" + EVENTS_NAME_SPACE,
  8356. CLICK_EVENT_NAME = "dxclick",
  8357. SCROLLABLE_PARENT_DATA_KEY = "dxClickScrollableParent",
  8358. SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY = "dxClickScrollableParentOffset",
  8359. preferNativeClick = function() {
  8360. var iPhone4SAndElder = device().deviceType === "phone" && screen.height <= 480,
  8361. iPad2AndElder = device().deviceType === "tablet" && wnd.devicePixelRatio < 2,
  8362. IOS7AndNewer = device().platform === "ios" && device().version[0] > 6;
  8363. return IOS7AndNewer && (iPhone4SAndElder || iPad2AndElder)
  8364. }(),
  8365. useNativeClick = function() {
  8366. if (!support.touch)
  8367. return true;
  8368. var chromeInfo = ua.match(/Chrome\/([0-9]+)/) || [],
  8369. chrome = !!chromeInfo[0],
  8370. chromeVersion = ~~chromeInfo[1],
  8371. android = device().platform === "android";
  8372. if (chrome)
  8373. if (android) {
  8374. if ($("meta[name=viewport][content*='width=device-width']").length)
  8375. return false;
  8376. if (chromeVersion > 31 && wnd.innerWidth <= screen.width)
  8377. return true;
  8378. if ($("meta[name=viewport][content*='user-scalable=no']").length)
  8379. return true
  8380. }
  8381. else
  8382. return true;
  8383. return false
  8384. }();
  8385. var SimulatedStrategy = DX.Class.inherit({
  8386. TOUCH_BOUNDARY: 10,
  8387. ctor: function() {
  8388. this._startX = 0;
  8389. this._startY = 0;
  8390. this._handlerCount = 0;
  8391. this._target = null
  8392. },
  8393. _touchWasMoved: function(e) {
  8394. var boundary = this.TOUCH_BOUNDARY;
  8395. return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary
  8396. },
  8397. _getClosestScrollable: function($element) {
  8398. var $scrollParent = $();
  8399. if ($element.data(SCROLLABLE_PARENT_DATA_KEY))
  8400. $scrollParent = $element.data(SCROLLABLE_PARENT_DATA_KEY);
  8401. else {
  8402. var $current = $element;
  8403. while ($current.length) {
  8404. if ($current[0].scrollHeight - $current[0].offsetHeight > 1) {
  8405. $scrollParent = $current;
  8406. $element.data(SCROLLABLE_PARENT_DATA_KEY, $scrollParent);
  8407. break
  8408. }
  8409. $current = $current.parent()
  8410. }
  8411. }
  8412. return $scrollParent
  8413. },
  8414. _saveClosestScrollableOffset: function($element) {
  8415. var $scrollable = this._getClosestScrollable($element);
  8416. if ($scrollable.length)
  8417. $element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY, $scrollable.scrollTop())
  8418. },
  8419. _closestScrollableWasMoved: function($element) {
  8420. var $scrollable = $element.data(SCROLLABLE_PARENT_DATA_KEY);
  8421. return $scrollable && $scrollable.scrollTop() !== $element.data(SCROLLABLE_PARENT_SCROLL_OFFSET_DATA_KEY)
  8422. },
  8423. _hasClosestScrollable: function($element) {
  8424. var $scrollable = this._getClosestScrollable($element);
  8425. if (!$scrollable.length)
  8426. return false;
  8427. if ($scrollable.is("body"))
  8428. return false;
  8429. if ($scrollable === window)
  8430. return false;
  8431. if ($scrollable.css("overflow") === "hidden")
  8432. return false;
  8433. return true
  8434. },
  8435. _handleStart: function(e) {
  8436. this._reset();
  8437. if (events.isMouseEvent(e) && e.which !== 1)
  8438. return;
  8439. this._saveClosestScrollableOffset($(e.target));
  8440. this._target = e.target;
  8441. this._startX = e.pageX;
  8442. this._startY = e.pageY
  8443. },
  8444. _handleEnd: function(e) {
  8445. var $target = $(e.target);
  8446. if (!$target.is(this._target) || this._touchWasMoved(e))
  8447. return;
  8448. if (this._nativeClickShouldBeUsed($target) || this._closestScrollableWasMoved($target))
  8449. return;
  8450. var targetIsInput = $target.is("input, textarea");
  8451. if (!targetIsInput && !e.dxPreventBlur)
  8452. utils.resetActiveElement();
  8453. this._fireClickEvent(e)
  8454. },
  8455. _handleCancel: function(e) {
  8456. this._reset()
  8457. },
  8458. _reset: function() {
  8459. this._target = null
  8460. },
  8461. _handleClick: function(e) {
  8462. var $target = $(e.target);
  8463. if ($target.is(this._target)) {
  8464. if (this._nativeClickShouldBeUsed($target))
  8465. this._fireClickEvent(e)
  8466. }
  8467. else if ($target.is("input, textarea"))
  8468. utils.resetActiveElement()
  8469. },
  8470. _nativeClickShouldBeUsed: function($target) {
  8471. return preferNativeClick && this._hasClosestScrollable($target)
  8472. },
  8473. _fireClickEvent: function(e) {
  8474. if (events.handleGestureEvent(e, CLICK_EVENT_NAME))
  8475. events.fireEvent({
  8476. type: CLICK_EVENT_NAME,
  8477. originalEvent: e
  8478. })
  8479. },
  8480. _makeElementClickable: function($element) {
  8481. if (!$element.attr("onclick"))
  8482. $element.attr("onclick", "void(0)")
  8483. },
  8484. setup: function(element) {
  8485. var $element = $(element);
  8486. this._makeElementClickable($element);
  8487. if (this._handlerCount > 0)
  8488. return;
  8489. 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))
  8490. },
  8491. add: function() {
  8492. this._handlerCount++
  8493. },
  8494. remove: function() {
  8495. this._handlerCount--
  8496. },
  8497. teardown: function(element) {
  8498. if (this._handlerCount)
  8499. return;
  8500. $(element).off("." + CLICK_NAME_SPACE);
  8501. this.dispose()
  8502. },
  8503. dispose: function() {
  8504. $(document).off("." + CLICK_NAME_SPACE)
  8505. }
  8506. });
  8507. var NativeStrategy = DX.Class.inherit({
  8508. bindType: "click",
  8509. delegateType: "click",
  8510. handle: function(element, event) {
  8511. event.type = "dxclick";
  8512. if (events.handleGestureEvent(event, CLICK_EVENT_NAME))
  8513. return event.handleObj.handler.call(element, event)
  8514. }
  8515. });
  8516. events.registerEvent(CLICK_EVENT_NAME, new(useNativeClick ? NativeStrategy : SimulatedStrategy));
  8517. DX.ui.events.__internals = DX.ui.events.__internals || {};
  8518. $.extend(DX.ui.events.__internals, {
  8519. NativeClickStrategy: NativeStrategy,
  8520. SimulatedClickStrategy: SimulatedStrategy,
  8521. preferNativeClickAccessor: function(value) {
  8522. if (!arguments.length)
  8523. return preferNativeClick;
  8524. preferNativeClick = value
  8525. }
  8526. })
  8527. })(jQuery, DevExpress, window);
  8528. /*! Module core, file ui.events.hold.js */
  8529. (function($, DX, undefined) {
  8530. var ui = DX.ui,
  8531. events = ui.events,
  8532. jqSpecialEvent = $.event.special,
  8533. EVENTS_NAME_SPACE = "dxSpecialEvents",
  8534. HOLD_NAME_SPACE = "dxHold",
  8535. HOLD_EVENT_NAME = "dxhold",
  8536. HOLD_TIMER_DATA_KEY = EVENTS_NAME_SPACE + "HoldTimer";
  8537. var Hold = DX.Class.inherit({
  8538. HOLD_TIMEOUT: 750,
  8539. TOUCH_BOUNDARY: 5,
  8540. _startX: 0,
  8541. _startY: 0,
  8542. _touchWasMoved: function(e) {
  8543. var boundary = this.TOUCH_BOUNDARY;
  8544. return Math.abs(e.pageX - this._startX) > boundary || Math.abs(e.pageY - this._startY) > boundary
  8545. },
  8546. setup: function(element, data) {
  8547. var $target,
  8548. holdInited = false;
  8549. var handleStart = function(e) {
  8550. if (holdInited)
  8551. return;
  8552. $target = $(e.target);
  8553. holdInited = true;
  8554. if ($target.data(HOLD_TIMER_DATA_KEY))
  8555. return;
  8556. this._startX = e.pageX;
  8557. this._startY = e.pageY;
  8558. var holdTimeout = data && "timeout" in data ? data.timeout : this.HOLD_TIMEOUT;
  8559. var holdTimer = setTimeout(function() {
  8560. $target.removeData(HOLD_TIMER_DATA_KEY);
  8561. if (events.handleGestureEvent(e, HOLD_EVENT_NAME))
  8562. events.fireEvent({
  8563. type: HOLD_EVENT_NAME,
  8564. originalEvent: e
  8565. })
  8566. }, holdTimeout);
  8567. $target.data(HOLD_TIMER_DATA_KEY, holdTimer)
  8568. };
  8569. var handleMove = function(e) {
  8570. if (!this._touchWasMoved(e))
  8571. return;
  8572. handleEnd()
  8573. };
  8574. var handleEnd = function() {
  8575. if ($target) {
  8576. clearTimeout($target.data(HOLD_TIMER_DATA_KEY));
  8577. $target.removeData(HOLD_TIMER_DATA_KEY);
  8578. $target = null;
  8579. holdInited = false
  8580. }
  8581. };
  8582. $(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))
  8583. },
  8584. teardown: function(element) {
  8585. element = $(element);
  8586. clearTimeout(element.data(HOLD_TIMER_DATA_KEY));
  8587. element.removeData(HOLD_TIMER_DATA_KEY).off("." + HOLD_NAME_SPACE)
  8588. }
  8589. });
  8590. events.registerEvent(HOLD_EVENT_NAME, new Hold)
  8591. })(jQuery, DevExpress);
  8592. /*! Module core, file ui.events.hover.js */
  8593. (function($, DX, undefined) {
  8594. var ui = DX.ui,
  8595. events = ui.events;
  8596. var HOVER_EVENTS_NAMESPACE = "dxSpecialEvents",
  8597. HOVER_START = "dxhoverstart",
  8598. HOVER_END = "dxhoverend",
  8599. MOUSE_ENTER = "mouseenter",
  8600. MOUSE_LEAVE = "mouseleave",
  8601. TOUCH_START = "dxpointerdown";
  8602. var HoverStart = DX.Class.inherit({
  8603. ctor: function() {
  8604. this._wasTouch = false;
  8605. this._selector = undefined
  8606. },
  8607. setup: function(element, data) {
  8608. var $element = $(element);
  8609. this._selector = data ? data.selector : undefined;
  8610. if (!!$element.data("dxHoverStart"))
  8611. return;
  8612. $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))
  8613. },
  8614. _handleEnter: function(e) {
  8615. if (!this._wasTouch)
  8616. events.fireEvent({
  8617. type: HOVER_START,
  8618. originalEvent: e
  8619. })
  8620. },
  8621. _handleTouchStart: function(e) {
  8622. this._wasTouch = events.isTouchEvent(e)
  8623. },
  8624. teardown: function(element) {
  8625. $(element).data("dxHoverStart", false).off(events.addNamespace(MOUSE_ENTER, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE))
  8626. }
  8627. });
  8628. var HoverEnd = DX.Class.inherit({
  8629. ctor: function() {
  8630. this._wasTouch = false;
  8631. this._selector = undefined
  8632. },
  8633. setup: function(element, data) {
  8634. var $element = $(element);
  8635. this._selector = data ? data.selector : undefined;
  8636. if (!!$element.data("dxHoverEnd"))
  8637. return;
  8638. $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))
  8639. },
  8640. _handleLeave: function(e) {
  8641. if (!this._wasTouch)
  8642. events.fireEvent({
  8643. type: HOVER_END,
  8644. originalEvent: e
  8645. })
  8646. },
  8647. _handleTouchStart: function(e) {
  8648. this._wasTouch = events.isTouchEvent(e)
  8649. },
  8650. teardown: function(element) {
  8651. $(element).data("dxHoverEnd", false).off(events.addNamespace(MOUSE_LEAVE, HOVER_EVENTS_NAMESPACE), this._selector).off(events.addNamespace(TOUCH_START, HOVER_EVENTS_NAMESPACE))
  8652. }
  8653. });
  8654. events.registerEvent(HOVER_START, new HoverStart);
  8655. events.registerEvent(HOVER_END, new HoverEnd)
  8656. })(jQuery, DevExpress);
  8657. /*! Module core, file ui.events.wheel.js */
  8658. (function($, DX, undefined) {
  8659. var ui = DX.ui,
  8660. events = ui.events;
  8661. var EVENT_NAME = "dxmousewheel",
  8662. EVENT_NAMESPACE = "dxWheel";
  8663. var WHEEL_DISTANCE = 10;
  8664. $.event.fixHooks["wheel"] = $.event.mouseHooks;
  8665. var wheelEvent = document.onmousewheel !== undefined ? "mousewheel" : "wheel";
  8666. var wheel = {
  8667. setup: function(element, data) {
  8668. var $element = $(element);
  8669. $element.on(events.addNamespace(wheelEvent, EVENT_NAMESPACE), $.proxy(wheel._handleWheel, wheel))
  8670. },
  8671. teardown: function(element) {
  8672. var $element = $(element);
  8673. $element.off("." + EVENT_NAMESPACE)
  8674. },
  8675. _handleWheel: function(e) {
  8676. $(e.target).data("dxGestureEvent", null);
  8677. var delta = this._getWheelDelta(e.originalEvent);
  8678. events.fireEvent({
  8679. type: EVENT_NAME,
  8680. originalEvent: e,
  8681. delta: delta
  8682. });
  8683. e.stopPropagation()
  8684. },
  8685. _getWheelDelta: function(event) {
  8686. return event.wheelDelta / 60 || -event.deltaY
  8687. }
  8688. };
  8689. events.registerEvent(EVENT_NAME, wheel)
  8690. })(jQuery, DevExpress);
  8691. /*! Module core, file ui.gestureEmitter.js */
  8692. (function($, DX, undefined) {
  8693. var ui = DX.ui,
  8694. events = ui.events;
  8695. var GestureEmitter = DX.Class.inherit({
  8696. ctor: function(element) {
  8697. this._$element = $(element);
  8698. this._cancelCallback = $.Callbacks()
  8699. },
  8700. getElement: function() {
  8701. return this._$element
  8702. },
  8703. getDirection: function() {
  8704. return this.direction
  8705. },
  8706. validate: function(e) {
  8707. return e.type !== "dxmousewheel"
  8708. },
  8709. configurate: function(data) {
  8710. $.extend(this, data)
  8711. },
  8712. addCancelCallback: function(callback) {
  8713. this._cancelCallback.add(callback)
  8714. },
  8715. removeCancelCallback: function() {
  8716. this._cancelCallback.empty()
  8717. },
  8718. init: $.noop,
  8719. start: $.noop,
  8720. move: $.noop,
  8721. end: $.noop,
  8722. cancel: $.noop,
  8723. wheel: $.noop,
  8724. _fireEvent: function(eventName, event, params) {
  8725. var eventData = {
  8726. type: eventName,
  8727. originalEvent: event,
  8728. target: this.getElement().get(0)
  8729. };
  8730. event = events.fireEvent($.extend(eventData, params));
  8731. if (event.cancel)
  8732. this._cancel(event);
  8733. return event
  8734. },
  8735. _cancel: function(e) {
  8736. this._cancelCallback.fire()
  8737. }
  8738. });
  8739. var gestureEmitters = [];
  8740. $.extend(ui, {
  8741. GestureEmitter: GestureEmitter,
  8742. gestureEmitters: gestureEmitters
  8743. })
  8744. })(jQuery, DevExpress);
  8745. /*! Module core, file ui.scrollEmitter.js */
  8746. (function($, DX, undefined) {
  8747. var ui = DX.ui,
  8748. events = ui.events;
  8749. var SCROLL_INIT_EVENT = "dxscrollinit",
  8750. SCROLL_START_EVENT = "dxscrollstart",
  8751. SCROLL_MOVE_EVENT = "dxscroll",
  8752. SCROLL_END_EVENT = "dxscrollend",
  8753. SCROLL_STOP_EVENT = "dxscrollstop",
  8754. SCROLL_CANCEL_EVENT = "dxscrollcancel",
  8755. SCROLL_WHEEL_EVENT = "dxscrollwheel",
  8756. INERTIA_TIMEOUT = 100,
  8757. VELOCITY_CALC_TIMEOUT = 200,
  8758. FRAME_DURATION = Math.round(1000 / 60);
  8759. var ScrollEmitter = ui.GestureEmitter.inherit({
  8760. ctor: function(element) {
  8761. this.callBase(element);
  8762. this.direction = "vertical"
  8763. },
  8764. init: function(e) {
  8765. this._savedEventData = this._prevEventData = events.eventData(e);
  8766. this._fireEvent(SCROLL_INIT_EVENT, e)
  8767. },
  8768. start: function(e) {
  8769. this._fireEvent(SCROLL_START_EVENT, e, {delta: events.eventDelta(this._prevEventData, events.eventData(e))})
  8770. },
  8771. move: function(e) {
  8772. var currentEventData = events.eventData(e);
  8773. this._fireEvent(SCROLL_MOVE_EVENT, e, {delta: events.eventDelta(this._prevEventData, currentEventData)});
  8774. var eventDelta = events.eventDelta(this._savedEventData, currentEventData);
  8775. if (eventDelta.time > VELOCITY_CALC_TIMEOUT)
  8776. this._savedEventData = this._prevEventData;
  8777. this._prevEventData = currentEventData
  8778. },
  8779. end: function(e) {
  8780. var endEventDelta = events.eventDelta(this._prevEventData, events.eventData(e));
  8781. var velocity = {
  8782. x: 0,
  8783. y: 0
  8784. };
  8785. if (endEventDelta.time < INERTIA_TIMEOUT) {
  8786. var deltaEventData = events.eventDelta(this._savedEventData, this._prevEventData);
  8787. velocity = {
  8788. x: deltaEventData.x * FRAME_DURATION / deltaEventData.time,
  8789. y: deltaEventData.y * FRAME_DURATION / deltaEventData.time
  8790. }
  8791. }
  8792. this._fireEvent(SCROLL_END_EVENT, e, {velocity: velocity})
  8793. },
  8794. stop: function(e) {
  8795. this._fireEvent(SCROLL_STOP_EVENT, e)
  8796. },
  8797. cancel: function(e) {
  8798. this._fireEvent(SCROLL_CANCEL_EVENT, e)
  8799. },
  8800. wheel: function(e) {
  8801. this._fireEvent(SCROLL_WHEEL_EVENT, e, {delta: e.delta})
  8802. }
  8803. });
  8804. ui.gestureEmitters.push({
  8805. emitter: ScrollEmitter,
  8806. events: [SCROLL_INIT_EVENT, SCROLL_START_EVENT, SCROLL_MOVE_EVENT, SCROLL_END_EVENT, SCROLL_STOP_EVENT, SCROLL_CANCEL_EVENT, SCROLL_WHEEL_EVENT]
  8807. })
  8808. })(jQuery, DevExpress);
  8809. /*! Module core, file ui.swipeEmitter.js */
  8810. (function($, DX, undefined) {
  8811. var ui = DX.ui,
  8812. utils = DX.utils,
  8813. events = ui.events,
  8814. SWIPE_START_EVENT = "dxswipestart",
  8815. SWIPE_EVENT = "dxswipe",
  8816. SWIPE_END_EVENT = "dxswipeend";
  8817. var HorizontalStrategy = {
  8818. defaultItemSizeFunc: function() {
  8819. return this.getElement().width()
  8820. },
  8821. getBounds: function() {
  8822. return [this._maxLeftOffset, this._maxRightOffset]
  8823. },
  8824. calcOffsetRatio: function(e) {
  8825. var endEventData = events.eventData(e);
  8826. return (endEventData.x - (this._startEventData && this._startEventData.x || 0)) / this._itemSizeFunc().call(this, e)
  8827. },
  8828. isFastSwipe: function(e) {
  8829. var endEventData = events.eventData(e);
  8830. return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.x - this._tickData.x) >= endEventData.time - this._tickData.time
  8831. }
  8832. };
  8833. var VerticalStrategy = {
  8834. defaultItemSizeFunc: function() {
  8835. return this.getElement().height()
  8836. },
  8837. getBounds: function() {
  8838. return [this._maxTopOffset, this._maxBottomOffset]
  8839. },
  8840. calcOffsetRatio: function(e) {
  8841. var endEventData = events.eventData(e);
  8842. return (endEventData.y - (this._startEventData && this._startEventData.y || 0)) / this._itemSizeFunc().call(this, e)
  8843. },
  8844. isFastSwipe: function(e) {
  8845. var endEventData = events.eventData(e);
  8846. return this.FAST_SWIPE_SPEED_LIMIT * Math.abs(endEventData.y - this._tickData.y) >= endEventData.time - this._tickData.time
  8847. }
  8848. };
  8849. var STRATEGIES = {
  8850. horizontal: HorizontalStrategy,
  8851. vertical: VerticalStrategy
  8852. };
  8853. var SwipeEmitter = ui.GestureEmitter.inherit({
  8854. TICK_INTERVAL: 300,
  8855. FAST_SWIPE_SPEED_LIMIT: 5,
  8856. ctor: function(element) {
  8857. this.callBase(element);
  8858. this.direction = "horizontal";
  8859. this.elastic = true
  8860. },
  8861. _getStrategy: function() {
  8862. return STRATEGIES[this.direction]
  8863. },
  8864. _defaultItemSizeFunc: function() {
  8865. return this._getStrategy().defaultItemSizeFunc.call(this)
  8866. },
  8867. _itemSizeFunc: function() {
  8868. return this.itemSizeFunc || this._defaultItemSizeFunc
  8869. },
  8870. init: function(e) {
  8871. this._startEventData = events.eventData(e);
  8872. this._tickData = {time: 0}
  8873. },
  8874. start: function(e) {
  8875. e = this._fireEvent(SWIPE_START_EVENT, e);
  8876. if (!e.cancel) {
  8877. this._maxLeftOffset = e.maxLeftOffset;
  8878. this._maxRightOffset = e.maxRightOffset;
  8879. this._maxTopOffset = e.maxTopOffset;
  8880. this._maxBottomOffset = e.maxBottomOffset
  8881. }
  8882. },
  8883. move: function(e) {
  8884. var strategy = this._getStrategy(),
  8885. moveEventData = events.eventData(e),
  8886. offset = strategy.calcOffsetRatio.call(this, e);
  8887. offset = this._fitOffset(offset, this.elastic);
  8888. if (moveEventData.time - this._tickData.time > this.TICK_INTERVAL)
  8889. this._tickData = moveEventData;
  8890. this._fireEvent(SWIPE_EVENT, e, {offset: offset});
  8891. e.preventDefault()
  8892. },
  8893. end: function(e) {
  8894. var strategy = this._getStrategy(),
  8895. offsetRatio = strategy.calcOffsetRatio.call(this, e),
  8896. isFast = strategy.isFastSwipe.call(this, e),
  8897. startOffset = offsetRatio,
  8898. targetOffset = this._calcTargetOffset(offsetRatio, isFast);
  8899. startOffset = this._fitOffset(startOffset, this.elastic);
  8900. targetOffset = this._fitOffset(targetOffset, false);
  8901. this._fireEvent(SWIPE_END_EVENT, e, {
  8902. offset: startOffset,
  8903. targetOffset: targetOffset
  8904. })
  8905. },
  8906. _fitOffset: function(offset, elastic) {
  8907. var strategy = this._getStrategy(),
  8908. bounds = strategy.getBounds.call(this);
  8909. if (offset < -bounds[0])
  8910. return elastic ? (-2 * bounds[0] + offset) / 3 : -bounds[0];
  8911. if (offset > bounds[1])
  8912. return elastic ? (2 * bounds[1] + offset) / 3 : bounds[1];
  8913. return offset
  8914. },
  8915. _calcTargetOffset: function(offsetRatio, isFast) {
  8916. var result;
  8917. if (isFast) {
  8918. result = Math.ceil(Math.abs(offsetRatio));
  8919. if (offsetRatio < 0)
  8920. result = -result
  8921. }
  8922. else
  8923. result = Math.round(offsetRatio);
  8924. return result
  8925. }
  8926. });
  8927. ui.gestureEmitters.push({
  8928. emitter: SwipeEmitter,
  8929. events: [SWIPE_START_EVENT, SWIPE_EVENT, SWIPE_END_EVENT]
  8930. })
  8931. })(jQuery, DevExpress);
  8932. /*! Module core, file ui.dragEmitter.js */
  8933. (function($, DX, undefined) {
  8934. var ui = DX.ui,
  8935. utils = DX.utils,
  8936. events = ui.events,
  8937. wrapToArray = utils.wrapToArray;
  8938. var DRAG_START_EVENT = "dxdragstart",
  8939. DRAG_EVENT = "dxdrag",
  8940. DRAG_END_EVENT = "dxdragend",
  8941. DRAG_ENTER_EVENT = "dxdragenter",
  8942. DRAG_LEAVE_EVENT = "dxdragleave",
  8943. DROP_EVENT = "dxdrop";
  8944. var knownDropTargets = [],
  8945. knownDropTargetConfigs = [];
  8946. var dropTargetRegistration = {
  8947. setup: function(element, data) {
  8948. var knownDropTarget = $.inArray(element, knownDropTargets) !== -1;
  8949. if (!knownDropTarget) {
  8950. knownDropTargets.push(element);
  8951. knownDropTargetConfigs.push(data || {})
  8952. }
  8953. },
  8954. teardown: function(element, data) {
  8955. var elementEvents = $._data(element, "events"),
  8956. handlersCount = 0;
  8957. $.each([DRAG_ENTER_EVENT, DRAG_LEAVE_EVENT, DROP_EVENT], function(_, eventName) {
  8958. var eventHandlers = elementEvents[eventName];
  8959. if (eventHandlers)
  8960. handlersCount += eventHandlers.length
  8961. });
  8962. if (!handlersCount) {
  8963. var index = $.inArray(element, knownDropTargets);
  8964. knownDropTargets.splice(index, 1);
  8965. knownDropTargetConfigs.splice(index, 1)
  8966. }
  8967. }
  8968. };
  8969. events.registerEvent(DRAG_ENTER_EVENT, dropTargetRegistration);
  8970. events.registerEvent(DRAG_LEAVE_EVENT, dropTargetRegistration);
  8971. events.registerEvent(DROP_EVENT, dropTargetRegistration);
  8972. var getItemConfig = function($element) {
  8973. var dropTargetIndex = $.inArray($element.get(0), knownDropTargets);
  8974. return knownDropTargetConfigs[dropTargetIndex]
  8975. };
  8976. var getItemPosition = function($element) {
  8977. var dropTargetConfig = getItemConfig($element);
  8978. if (dropTargetConfig.itemPositionFunc)
  8979. return dropTargetConfig.itemPositionFunc();
  8980. else
  8981. return $element.offset()
  8982. };
  8983. var getItemSize = function($element) {
  8984. var dropTargetConfig = getItemConfig($element);
  8985. if (dropTargetConfig.itemSizeFunc)
  8986. return dropTargetConfig.itemSizeFunc();
  8987. else
  8988. return {
  8989. width: $element.width(),
  8990. height: $element.height()
  8991. }
  8992. };
  8993. var DragEmitter = ui.GestureEmitter.inherit({
  8994. ctor: function(element) {
  8995. this.callBase(element);
  8996. this.direction = "both"
  8997. },
  8998. init: function(e) {
  8999. var eventData = events.eventData(e);
  9000. this._startEventData = eventData
  9001. },
  9002. start: function(e) {
  9003. e = this._fireEvent(DRAG_START_EVENT, e);
  9004. this._maxLeftOffset = e.maxLeftOffset;
  9005. this._maxRightOffset = e.maxRightOffset;
  9006. this._maxTopOffset = e.maxTopOffset;
  9007. this._maxBottomOffset = e.maxBottomOffset;
  9008. var dropTargets = wrapToArray(e.targetElements || knownDropTargets);
  9009. this._$dropTargetElements = $.map(dropTargets, function(element) {
  9010. return $(element)
  9011. })
  9012. },
  9013. move: function(e) {
  9014. var eventData = events.eventData(e),
  9015. dragOffset = this._calculateOffset(eventData);
  9016. this._fireEvent(DRAG_EVENT, e, {offset: dragOffset});
  9017. this._processDropTargets(e, dragOffset);
  9018. e.preventDefault()
  9019. },
  9020. _calculateOffset: function(eventData) {
  9021. return {
  9022. x: this._calculateXOffset(eventData),
  9023. y: this._calculateYOffset(eventData)
  9024. }
  9025. },
  9026. _calculateXOffset: function(eventData) {
  9027. if (this.direction !== "vertical") {
  9028. var offset = eventData.x - this._startEventData.x;
  9029. return this._fitOffset(offset, this._maxLeftOffset, this._maxRightOffset)
  9030. }
  9031. return 0
  9032. },
  9033. _calculateYOffset: function(eventData) {
  9034. if (this.direction !== "horizontal") {
  9035. var offset = eventData.y - this._startEventData.y;
  9036. return this._fitOffset(offset, this._maxTopOffset, this._maxBottomOffset)
  9037. }
  9038. return 0
  9039. },
  9040. _fitOffset: function(offset, minOffset, maxOffset) {
  9041. if (minOffset != null)
  9042. offset = Math.max(offset, -minOffset);
  9043. if (maxOffset != null)
  9044. offset = Math.min(offset, maxOffset);
  9045. return offset
  9046. },
  9047. _processDropTargets: function(e, dragOffset) {
  9048. var target = this._findDropTarget(e),
  9049. sameTarget = target === this._$currentDropTarget;
  9050. if (!sameTarget) {
  9051. this._fireDropTargetEvent(e, DRAG_LEAVE_EVENT);
  9052. this._$currentDropTarget = target;
  9053. this._fireDropTargetEvent(e, DRAG_ENTER_EVENT)
  9054. }
  9055. },
  9056. _fireDropTargetEvent: function(event, eventName) {
  9057. if (!this._$currentDropTarget)
  9058. return;
  9059. var eventData = {
  9060. type: eventName,
  9061. originalEvent: event,
  9062. draggingElement: this._$element.get(0),
  9063. target: this._$currentDropTarget.get(0)
  9064. };
  9065. events.fireEvent(eventData)
  9066. },
  9067. _findDropTarget: function(e) {
  9068. var that = this,
  9069. $result;
  9070. $.each(this._$dropTargetElements, function(_, $target) {
  9071. if (that._checkDropTarget($target, e)) {
  9072. $result = $target;
  9073. return false
  9074. }
  9075. });
  9076. return $result
  9077. },
  9078. _checkDropTarget: function($target, e) {
  9079. var isDraggingElement = $target.get(0) === this._$element.get(0);
  9080. if (isDraggingElement)
  9081. return false;
  9082. var targetPosition = getItemPosition($target);
  9083. if (e.pageX < targetPosition.left)
  9084. return false;
  9085. if (e.pageY < targetPosition.top)
  9086. return false;
  9087. var targetSize = getItemSize($target);
  9088. if (e.pageX > targetPosition.left + targetSize.width)
  9089. return false;
  9090. if (e.pageY > targetPosition.top + targetSize.height)
  9091. return false;
  9092. return $target
  9093. },
  9094. end: function(e) {
  9095. var eventData = events.eventData(e);
  9096. this._fireEvent(DRAG_END_EVENT, e, {offset: this._calculateOffset(eventData)});
  9097. this._fireDropTargetEvent(e, DROP_EVENT);
  9098. delete this._$currentDropTarget
  9099. }
  9100. });
  9101. ui.gestureEmitters.push({
  9102. emitter: DragEmitter,
  9103. events: [DRAG_START_EVENT, DRAG_EVENT, DRAG_END_EVENT]
  9104. });
  9105. DX.ui.events.__internals = DX.ui.events.__internals || {};
  9106. $.extend(DX.ui.events.__internals, {dropTargets: knownDropTargets})
  9107. })(jQuery, DevExpress);
  9108. /*! Module core, file ui.events.gesture.js */
  9109. (function($, DX, undefined) {
  9110. var ui = DX.ui,
  9111. events = ui.events,
  9112. utils = DX.utils;
  9113. var abs = Math.abs;
  9114. var GESTURE_EVENT = "dxGesture",
  9115. GESTURE_EVENT_DATA = "dxGestureEmitter",
  9116. GESTURE_LOCK_KEY = "dxGestureLock",
  9117. GESTURE_UNLOCK_TIMEOUT = 400,
  9118. TOUCH_BOUNDARY = 10,
  9119. HORIZONTAL = "horizontal",
  9120. VERTICAL = "vertical",
  9121. BOTH = "both";
  9122. var GestureEventManager = DX.Class.inherit({
  9123. SLEEP: 0,
  9124. INITED: 1,
  9125. STARTED: 2,
  9126. ctor: function() {
  9127. this._attachHandlers();
  9128. this.reset()
  9129. },
  9130. _attachHandlers: function() {
  9131. $(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))
  9132. },
  9133. _eachEmitter: function(callback) {
  9134. $.each(this._activeEmitters || {}, function(direction, emitter) {
  9135. return callback(emitter, direction)
  9136. })
  9137. },
  9138. _noEmitters: function() {
  9139. return $.isEmptyObject(this._activeEmitters)
  9140. },
  9141. reset: function() {
  9142. this._eachEmitter(function(emitter) {
  9143. emitter.removeCancelCallback()
  9144. });
  9145. this._forgetGesture();
  9146. this._stage = this.SLEEP;
  9147. this._activeEmitters = {}
  9148. },
  9149. _handlePointerDown: function(e) {
  9150. if (events.needSkipEvent(e) || events.hasTouches(e) > 1)
  9151. return;
  9152. this.reset();
  9153. this._activeEmitters = this._closestEmitter(e);
  9154. if (this._noEmitters())
  9155. return;
  9156. this._startEvent = e;
  9157. this._startEventData = events.eventData(e);
  9158. this._stage = this.INITED;
  9159. this._applyToActive("init", e)
  9160. },
  9161. _applyToActive: function(method) {
  9162. var args = $.makeArray(arguments).slice(1);
  9163. this._eachEmitter(function(emitter) {
  9164. if (method in emitter)
  9165. emitter[method].apply(emitter, args)
  9166. })
  9167. },
  9168. _closestEmitter: function(e) {
  9169. var result = {},
  9170. foundForAllDirections = false,
  9171. $element = $(e.target);
  9172. while ($element.length && !foundForAllDirections) {
  9173. var emitter = $element.data(GESTURE_EVENT_DATA);
  9174. if (emitter && emitter.validate(e)) {
  9175. var direction = emitter.getDirection(e);
  9176. if (direction) {
  9177. emitter.addCancelCallback($.proxy(this._handleCancel, this, emitter, e));
  9178. result[direction] = result[direction] || emitter
  9179. }
  9180. }
  9181. foundForAllDirections = result[HORIZONTAL] && result[VERTICAL] || result[BOTH];
  9182. $element = $element.parent()
  9183. }
  9184. return result
  9185. },
  9186. _handleCancel: function(canceledEmitter, e) {
  9187. var canceledDirection;
  9188. this._eachEmitter(function(emitter, direction) {
  9189. if (emitter === canceledEmitter) {
  9190. canceledDirection = direction;
  9191. emitter.removeCancelCallback()
  9192. }
  9193. });
  9194. this._forgetGesture([canceledEmitter]);
  9195. this._cancelEmitter(canceledEmitter, e);
  9196. if (this._noEmitters())
  9197. this.reset()
  9198. },
  9199. _handlePointerMove: function(e) {
  9200. if (this._stage === this.INITED && this._directionDetected(e))
  9201. this._handleStart(e);
  9202. if (this._stage === this.STARTED)
  9203. this._handleMove(e)
  9204. },
  9205. _directionDetected: function(e) {
  9206. var delta = events.eventDelta(this._startEventData, events.eventData(e));
  9207. return delta.x || delta.y
  9208. },
  9209. _handleStart: function(e) {
  9210. this._filterEmitters(e);
  9211. if (this._noEmitters())
  9212. return;
  9213. this._resetActiveElement();
  9214. this._applyToActive("start", this._startEvent);
  9215. this._stage = this.STARTED
  9216. },
  9217. _resetActiveElement: function() {
  9218. if (DX.devices.real().platform !== "ios")
  9219. return;
  9220. this._eachEmitter(function(emitter) {
  9221. if ($(":focus", emitter.getElement()).length)
  9222. utils.resetActiveElement()
  9223. })
  9224. },
  9225. _filterEmitters: function(e) {
  9226. this._filterByDirection(e);
  9227. if (this._emitersAmount() > 1)
  9228. this._takeFirstEmitter()
  9229. },
  9230. _emitersAmount: function() {
  9231. var result = 0;
  9232. this._eachEmitter(function() {
  9233. result++
  9234. });
  9235. return result
  9236. },
  9237. _filterByDirection: function(e) {
  9238. var delta = events.eventDelta(this._startEventData, events.eventData(e)),
  9239. horizontalMove = abs(delta.y) < abs(delta.x),
  9240. verticalMove = abs(delta.y) > abs(delta.x),
  9241. horizontalEmmiter = this._activeEmitters[HORIZONTAL],
  9242. verticalEmmiter = this._activeEmitters[VERTICAL],
  9243. bothEmitter = this._activeEmitters[BOTH],
  9244. existsHorizontalEmitter = horizontalEmmiter || bothEmitter,
  9245. existsVerticalEmitter = verticalEmmiter || bothEmitter;
  9246. if (horizontalMove && existsHorizontalEmitter)
  9247. this._cancelEmitter(verticalEmmiter, e);
  9248. else if (verticalMove && existsVerticalEmitter)
  9249. this._cancelEmitter(horizontalEmmiter, e)
  9250. },
  9251. _cancelEmitter: function(canceledEmmiter, e) {
  9252. if (!canceledEmmiter)
  9253. return;
  9254. canceledEmmiter.cancel(e);
  9255. delete this._activeEmitters[canceledEmmiter.getDirection(e)]
  9256. },
  9257. _takeFirstEmitter: function() {
  9258. var activeEmitters = {};
  9259. this._eachEmitter(function(emitter, direction) {
  9260. activeEmitters[direction] = emitter;
  9261. return false
  9262. });
  9263. this._activeEmitters = activeEmitters
  9264. },
  9265. _prepareGesture: function() {
  9266. this._gestureLocked = true;
  9267. clearTimeout(this._gestureEndTimer);
  9268. this._eachEmitter(function(emitter) {
  9269. emitter.getElement().data(GESTURE_LOCK_KEY, true)
  9270. });
  9271. ui.feedback.reset()
  9272. },
  9273. _handleMove: function(e) {
  9274. if (!this._gestureLocked) {
  9275. var delta = events.eventDelta(this._startEventData, events.eventData(e));
  9276. if (abs(delta.x) > TOUCH_BOUNDARY || abs(delta.y) > TOUCH_BOUNDARY) {
  9277. events.handleGestureEvent(e, GESTURE_EVENT);
  9278. this._prepareGesture()
  9279. }
  9280. }
  9281. this._applyToActive("move", e)
  9282. },
  9283. _forgetGesture: function(activeEmitters) {
  9284. activeEmitters = activeEmitters || this._activeEmitters;
  9285. if (this._noEmitters())
  9286. return;
  9287. this._gestureLocked = false;
  9288. this._gestureEndTimer = setTimeout(function() {
  9289. $.each(activeEmitters, function(_, emitter) {
  9290. emitter.getElement().data(GESTURE_LOCK_KEY, false)
  9291. })
  9292. }, GESTURE_UNLOCK_TIMEOUT)
  9293. },
  9294. _handlePointerUp: function(e) {
  9295. if (!DX.devices.isRippleEmulator() && events.hasTouches(e))
  9296. return;
  9297. if (this._stage === this.STARTED)
  9298. this._applyToActive("end", e);
  9299. else if (this._stage === this.INITED)
  9300. this._applyToActive("stop", e);
  9301. this.reset()
  9302. },
  9303. _handleMouseWheel: function(e) {
  9304. this._handlePointerDown(e);
  9305. if (this._stage !== this.INITED)
  9306. return;
  9307. this._takeFirstEmitter();
  9308. this._eachEmitter(function(emitter, direction) {
  9309. var prop = direction !== "horizontal" ? "pageY" : "pageX";
  9310. e[prop] += e.delta
  9311. });
  9312. this._handlePointerMove(e);
  9313. this._handlePointerUp(e)
  9314. },
  9315. isActive: function(element) {
  9316. var result = false;
  9317. this._eachEmitter(function(emitter) {
  9318. result = result || emitter.getElement().is(element)
  9319. });
  9320. return result
  9321. }
  9322. });
  9323. var gestureEventManager = new GestureEventManager;
  9324. var registerEmitter = function(emitterConfig) {
  9325. var emitterClass = emitterConfig.emitter;
  9326. $.each(emitterConfig.events, function(_, eventName) {
  9327. events.registerEvent(eventName, {
  9328. noBubble: true,
  9329. setup: function(element, data) {
  9330. var emitter = $(element).data(GESTURE_EVENT_DATA) || new emitterClass(element);
  9331. emitter.configurate(data);
  9332. $(element).data(GESTURE_EVENT_DATA, emitter)
  9333. },
  9334. teardown: function(element) {
  9335. if (gestureEventManager.isActive(element))
  9336. gestureEventManager.reset();
  9337. $(element).removeData(GESTURE_EVENT_DATA)
  9338. }
  9339. })
  9340. })
  9341. };
  9342. $.each(ui.gestureEmitters, function(_, emitterConfig) {
  9343. registerEmitter(emitterConfig)
  9344. });
  9345. events.__internals = events.__internals || {};
  9346. $.extend(events.__internals, {registerEmitter: registerEmitter})
  9347. })(jQuery, DevExpress);
  9348. /*! Module core, file ui.widget.js */
  9349. (function($, DX, undefined) {
  9350. var ui = DX.ui,
  9351. UI_FEEDBACK = "UIFeedback",
  9352. UI_FEEDBACK_CLASS = "dx-feedback",
  9353. ACTIVE_STATE_CLASS = "dx-state-active",
  9354. DISABLED_STATE_CLASS = "dx-state-disabled",
  9355. INVISIBLE_STATE_CLASS = "dx-state-invisible",
  9356. HOVER_STATE_CLASS = "dx-state-hover",
  9357. FEEDBACK_SHOW_TIMEOUT = 30,
  9358. FEEDBACK_HIDE_TIMEOUT = 400,
  9359. HOVER_START = "dxhoverstart",
  9360. HOVER_END = "dxhoverend",
  9361. ANONYMOUS_TEMPLATE_NAME = "template",
  9362. TEMPLATE_SELECTOR = "[data-options*='dxTemplate']",
  9363. TEMPLATES_DATA_KEY = "dxTemplates";
  9364. var getTemplateOptions = function(element) {
  9365. var options = $(element).data("options");
  9366. if ($.trim(options).charAt(0) !== "{")
  9367. options = "{" + options + "}";
  9368. return new Function("return " + options)().dxTemplate
  9369. };
  9370. var activeElement,
  9371. events = ui.events;
  9372. ui.feedback = {reset: function() {
  9373. handleEnd(true)
  9374. }};
  9375. ui.Widget = DX.DOMComponent.inherit({
  9376. NAME: "Widget",
  9377. NAMESPACE: ui,
  9378. _setDefaultOptions: function() {
  9379. this.callBase();
  9380. this.option({
  9381. disabled: false,
  9382. visible: true,
  9383. activeStateEnabled: true,
  9384. width: undefined,
  9385. height: undefined,
  9386. contentReadyAction: null,
  9387. hoverStateEnabled: false
  9388. })
  9389. },
  9390. _init: function() {
  9391. this.callBase();
  9392. this._feedbackShowTimeout = FEEDBACK_SHOW_TIMEOUT;
  9393. this._feedbackHideTimeout = FEEDBACK_HIDE_TIMEOUT;
  9394. if (this._templatesSupported()) {
  9395. this._initTemplates();
  9396. this._initContentReadyAction()
  9397. }
  9398. },
  9399. _templatesSupported: function() {
  9400. return this._renderContentImpl !== DX.abstract
  9401. },
  9402. _initTemplates: function() {
  9403. var that = this,
  9404. templates = {},
  9405. dataTemplateElements = this._element().data(TEMPLATES_DATA_KEY),
  9406. templateElements = dataTemplateElements ? dataTemplateElements : this._element().contents().filter(TEMPLATE_SELECTOR);
  9407. this._templateProvider = new ui.TemplateProvider;
  9408. this._templateClass = this._templateProvider.getTemplateClass(this);
  9409. if (templateElements.length) {
  9410. var templatesMap = {};
  9411. templateElements.each(function() {
  9412. var templateOptions = getTemplateOptions(this);
  9413. if (!templateOptions)
  9414. return;
  9415. if (!templateOptions.name)
  9416. throw Error("Template name was not specified");
  9417. templatesMap[templateOptions.name] = templatesMap[templateOptions.name] || [];
  9418. templatesMap[templateOptions.name].push(this)
  9419. });
  9420. $.each(templatesMap, function(templateName, value) {
  9421. var deviceTemplate = that._findTemplateByDevice(value);
  9422. if (deviceTemplate)
  9423. templates[templateName] = that._createTemplate(deviceTemplate)
  9424. })
  9425. }
  9426. else
  9427. templates[ANONYMOUS_TEMPLATE_NAME] = that._createTemplate(that._element().contents());
  9428. this.option("_templates", templates)
  9429. },
  9430. _getTemplateByOption: function(optionName) {
  9431. return this._getTemplate(this.option(optionName))
  9432. },
  9433. _getTemplate: function(templateName) {
  9434. var result = this._acquireTemplate.apply(this, arguments);
  9435. if (!result && this._templateProvider.supportDefaultTemplate(this)) {
  9436. result = this._templateProvider.getDefaultTemplate(this);
  9437. if (!result)
  9438. throw Error(DX.utils.stringFormat("Template \"{0}\" was not found and no default template specified!", templateName));
  9439. }
  9440. return result
  9441. },
  9442. _acquireTemplate: function(templateSource) {
  9443. if (templateSource == null)
  9444. return templateSource;
  9445. if (templateSource instanceof this._templateClass)
  9446. return templateSource;
  9447. if (templateSource.nodeType || templateSource.jquery) {
  9448. templateSource = $(templateSource);
  9449. if (templateSource.is("script"))
  9450. templateSource = templateSource.html();
  9451. return this._createTemplate(templateSource)
  9452. }
  9453. if (typeof templateSource === "string")
  9454. return this.option("_templates")[templateSource];
  9455. if ($.isFunction(templateSource)) {
  9456. var args = $.makeArray(arguments).slice(1);
  9457. return this._acquireTemplate(templateSource.apply(this, args))
  9458. }
  9459. return this._acquireTemplate(templateSource.toString())
  9460. },
  9461. _createTemplate: function(element) {
  9462. return new this._templateClass(element, this)
  9463. },
  9464. _findTemplateByDevice: function(templates) {
  9465. var suitableTemplate = DX.utils.findBestMatches(DX.devices.current(), templates, function(template) {
  9466. return getTemplateOptions(template)
  9467. })[0];
  9468. $.each(templates, function(index, template) {
  9469. if (template !== suitableTemplate)
  9470. $(template).remove()
  9471. });
  9472. return suitableTemplate
  9473. },
  9474. _cleanTemplates: function() {
  9475. var that = this;
  9476. $.each(this.option("_templates"), function(templateName, template) {
  9477. if (that === template.owner())
  9478. template.dispose()
  9479. })
  9480. },
  9481. _initContentReadyAction: function() {
  9482. this._contentReadyAction = this._createActionByOption("contentReadyAction", {excludeValidators: ["gesture", "designMode", "disabled"]})
  9483. },
  9484. _render: function() {
  9485. this.callBase();
  9486. this._element().addClass("dx-widget");
  9487. this._toggleDisabledState(this.option("disabled"));
  9488. this._toggleVisibility(this.option("visible"));
  9489. this._refreshFeedback();
  9490. this._renderDimensions();
  9491. if (this._templatesSupported())
  9492. this._renderContent();
  9493. this._attachHoverEvents()
  9494. },
  9495. _renderContent: function() {
  9496. this._renderContentImpl();
  9497. this._fireContentReadyAction()
  9498. },
  9499. _renderContentImpl: DX.abstract,
  9500. _fireContentReadyAction: function() {
  9501. this._contentReadyAction({excludeValidators: ["disabled", "gesture"]})
  9502. },
  9503. _dispose: function() {
  9504. if (this._templatesSupported())
  9505. this._cleanTemplates();
  9506. this._contentReadyAction = null;
  9507. this._clearTimers();
  9508. if (activeElement && activeElement.closest(this._element()).length)
  9509. activeElement = null;
  9510. this.callBase()
  9511. },
  9512. _clean: function() {
  9513. this.callBase();
  9514. this._element().empty()
  9515. },
  9516. _clearTimers: function() {
  9517. clearTimeout(this._feedbackHideTimer);
  9518. clearTimeout(this._feedbackShowTimer)
  9519. },
  9520. _toggleVisibility: function(visible) {
  9521. this._element().toggleClass(INVISIBLE_STATE_CLASS, !visible)
  9522. },
  9523. _attachHoverEvents: function() {
  9524. var that = this,
  9525. hoverableSelector = that._activeStateUnit,
  9526. nameStart = events.addNamespace(HOVER_START, UI_FEEDBACK),
  9527. nameEnd = events.addNamespace(HOVER_END, UI_FEEDBACK);
  9528. that._element().off(nameStart, hoverableSelector).off(nameEnd, hoverableSelector);
  9529. if (this.option("hoverStateEnabled")) {
  9530. var startAction = new DX.Action(function(args) {
  9531. var $target = args.element;
  9532. that._refreshHoveredElement($target)
  9533. });
  9534. that._element().on(nameStart, hoverableSelector, {selector: hoverableSelector}, function(e) {
  9535. startAction.execute({element: $(e.target)})
  9536. }).on(nameEnd, hoverableSelector, {selector: hoverableSelector}, function(e) {
  9537. e.stopImmediatePropagation();
  9538. that._forgetHoveredElement()
  9539. })
  9540. }
  9541. else
  9542. this._toggleHoverClass(false)
  9543. },
  9544. _refreshHoveredElement: function(hoveredElement) {
  9545. var selector = this._activeStateUnit || this._element();
  9546. this._forgetHoveredElement();
  9547. this._hoveredElement = hoveredElement.closest(selector);
  9548. this._toggleHoverClass(true)
  9549. },
  9550. _forgetHoveredElement: function() {
  9551. this._toggleHoverClass(false);
  9552. delete this._hoveredElement
  9553. },
  9554. _toggleHoverClass: function(value) {
  9555. if (this._hoveredElement)
  9556. this._hoveredElement.toggleClass(HOVER_STATE_CLASS, value && this.option("hoverStateEnabled"))
  9557. },
  9558. _renderDimensions: function() {
  9559. var width = this.option("width"),
  9560. height = this.option("height");
  9561. this._setDimension(width, "width");
  9562. this._setDimension(height, "height")
  9563. },
  9564. _setDimension: function(dimensionSize, dimension) {
  9565. var $element = this._element();
  9566. dimensionSize = $.isFunction(dimensionSize) ? dimensionSize() : dimensionSize;
  9567. if ($.isNumeric(dimensionSize))
  9568. dimensionSize = dimensionSize + "px";
  9569. if (!dimensionSize && dimension === "width")
  9570. dimensionSize = this._calculateWidth();
  9571. $element.css(dimension, dimensionSize)
  9572. },
  9573. _calculateWidth: function() {
  9574. var $element = this._element(),
  9575. explicitWidth = $element[0].style.width,
  9576. calculatedWidth;
  9577. if (explicitWidth[explicitWidth.length - 1] === "%" && !this.option("width"))
  9578. return explicitWidth;
  9579. else
  9580. calculatedWidth = explicitWidth && explicitWidth !== "auto" && explicitWidth !== "inherit" ? $element.outerWidth() : this.option("width");
  9581. return calculatedWidth
  9582. },
  9583. _refreshFeedback: function() {
  9584. if (this._feedbackDisabled()) {
  9585. this._feedbackOff(true);
  9586. this._element().removeClass(UI_FEEDBACK_CLASS)
  9587. }
  9588. else
  9589. this._element().addClass(UI_FEEDBACK_CLASS)
  9590. },
  9591. _feedbackDisabled: function() {
  9592. return !this.option("activeStateEnabled") || this.option("disabled")
  9593. },
  9594. _feedbackOn: function(element, immediate) {
  9595. if (this._feedbackDisabled())
  9596. return;
  9597. this._clearTimers();
  9598. if (immediate)
  9599. this._feedbackShow(element);
  9600. else
  9601. this._feedbackShowTimer = window.setTimeout($.proxy(this._feedbackShow, this, element), this._feedbackShowTimeout);
  9602. this._saveActiveElement()
  9603. },
  9604. _feedbackShow: function(element) {
  9605. var activeStateElement = this._element();
  9606. if (this._activeStateUnit)
  9607. activeStateElement = $(element).closest(this._activeStateUnit);
  9608. if (!activeStateElement.hasClass(DISABLED_STATE_CLASS)) {
  9609. activeStateElement.addClass(ACTIVE_STATE_CLASS);
  9610. this._toggleHoverClass(false)
  9611. }
  9612. },
  9613. _saveActiveElement: function() {
  9614. activeElement = this._element()
  9615. },
  9616. _feedbackOff: function(immediate) {
  9617. this._clearTimers();
  9618. if (immediate)
  9619. this._feedbackHide();
  9620. else
  9621. this._feedbackHideTimer = window.setTimeout($.proxy(this._feedbackHide, this), this._feedbackHideTimeout)
  9622. },
  9623. _feedbackHide: function() {
  9624. var activeStateElement = this._element();
  9625. if (this._activeStateUnit)
  9626. activeStateElement = activeStateElement.find(this._activeStateUnit);
  9627. activeStateElement.removeClass(ACTIVE_STATE_CLASS);
  9628. this._toggleHoverClass(!this.option("disabled"));
  9629. this._clearActiveElement()
  9630. },
  9631. _clearActiveElement: function() {
  9632. var rootDomElement = this._element().get(0),
  9633. activeDomElement = activeElement && activeElement.get(0);
  9634. if (activeDomElement && (activeDomElement === rootDomElement || $.contains(rootDomElement, activeDomElement)))
  9635. activeElement = null
  9636. },
  9637. _toggleDisabledState: function(value) {
  9638. this._element().toggleClass(DISABLED_STATE_CLASS, Boolean(value));
  9639. this._toggleHoverClass(!value)
  9640. },
  9641. _optionChanged: function(name, value) {
  9642. switch (name) {
  9643. case"disabled":
  9644. this._toggleDisabledState(value);
  9645. this._refreshFeedback();
  9646. break;
  9647. case"activeStateEnabled":
  9648. this._refreshFeedback();
  9649. break;
  9650. case"hoverStateEnabled":
  9651. this._attachHoverEvents();
  9652. break;
  9653. case"visible":
  9654. this._toggleVisibility(value);
  9655. break;
  9656. case"width":
  9657. case"height":
  9658. this._renderDimensions();
  9659. break;
  9660. case"contentReadyAction":
  9661. this._initContentReadyAction();
  9662. break;
  9663. case"_templates":
  9664. this._refresh();
  9665. break;
  9666. default:
  9667. this.callBase.apply(this, arguments)
  9668. }
  9669. },
  9670. repaint: function() {
  9671. this._refresh()
  9672. }
  9673. });
  9674. var handleStart = function(args, immediate) {
  9675. var e = args.jQueryEvent,
  9676. $target = args.element,
  9677. widget;
  9678. if (events.needSkipEvent(e))
  9679. return;
  9680. if (activeElement) {
  9681. widget = getWidget(activeElement);
  9682. if (widget)
  9683. widget._feedbackOff(true)
  9684. }
  9685. var closestFeedbackElement = $target.closest("." + UI_FEEDBACK_CLASS);
  9686. if (closestFeedbackElement.length) {
  9687. widget = getWidget(closestFeedbackElement);
  9688. if (!widget)
  9689. return;
  9690. widget._feedbackOn($target, immediate);
  9691. if (immediate)
  9692. widget._feedbackOff()
  9693. }
  9694. };
  9695. var handleEnd = function(immediate) {
  9696. if (!activeElement)
  9697. return;
  9698. var widget = getWidget(activeElement);
  9699. if (widget)
  9700. widget._feedbackOff(immediate)
  9701. };
  9702. var getWidget = function(widgetElement) {
  9703. var result;
  9704. $.each(widgetElement.data("dxComponents") || [], function(index, componentName) {
  9705. if (ui[componentName] && ui[componentName].subclassOf(ui.Widget)) {
  9706. result = widgetElement.data(componentName);
  9707. return false
  9708. }
  9709. });
  9710. return result
  9711. };
  9712. $(function() {
  9713. var startAction = new DX.Action(handleStart);
  9714. $(document).on(events.addNamespace("dxpointerdown", UI_FEEDBACK), function(e) {
  9715. startAction.execute({
  9716. jQueryEvent: e,
  9717. element: $(e.target)
  9718. })
  9719. }).on(events.addNamespace("dxpointerup dxpointercancel", UI_FEEDBACK), function(e) {
  9720. var activeElementClicked = activeElement && $(e.target).closest("." + UI_FEEDBACK_CLASS).get(0) === activeElement.get(0);
  9721. if (activeElementClicked)
  9722. startAction.execute({
  9723. jQueryEvent: e,
  9724. element: $(e.target)
  9725. }, true);
  9726. handleEnd()
  9727. })
  9728. })
  9729. })(jQuery, DevExpress);
  9730. /*! Module core, file ui.editor.js */
  9731. (function($, DX, undefined) {
  9732. var ui = DX.ui;
  9733. DX.registerComponent("dxEditor", ui.Widget.inherit({
  9734. _setDefaultOptions: function() {
  9735. this.callBase();
  9736. this.option({
  9737. value: undefined,
  9738. valueChangeAction: undefined
  9739. })
  9740. },
  9741. _recreateValueChangeAction: function() {
  9742. this._valueChangeAction = this._createActionByOption("valueChangeAction")
  9743. },
  9744. _suppressValueChangeAction: function() {
  9745. this._valueChangeActionSuppressed = true
  9746. },
  9747. _resumeValueChangeAction: function() {
  9748. this._valueChangeActionSuppressed = false
  9749. },
  9750. _render: function() {
  9751. this._recreateValueChangeAction();
  9752. this.callBase()
  9753. },
  9754. _raiseValueChangeAction: function(value, previousValue, extraArguments) {
  9755. var args = {
  9756. value: value,
  9757. previousValue: previousValue,
  9758. jQueryEvent: this._valueChangeEventInstance
  9759. };
  9760. if (extraArguments)
  9761. args = $.extend(args, extraArguments);
  9762. this._valueChangeAction(args)
  9763. },
  9764. _optionChanged: function(name, value, previousValue) {
  9765. switch (name) {
  9766. case"valueChangeAction":
  9767. this._recreateValueChangeAction();
  9768. break;
  9769. case"value":
  9770. if (!this._valueChangeActionSuppressed)
  9771. this._raiseValueChangeAction(value, previousValue);
  9772. this._valueChangeEventInstance = undefined;
  9773. break;
  9774. default:
  9775. this.callBase.apply(this, arguments)
  9776. }
  9777. }
  9778. }))
  9779. })(jQuery, DevExpress);
  9780. /*! Module core, file ui.template.js */
  9781. (function($, DX, undefined) {
  9782. var isString = DX.utils.isString;
  9783. var currentTemplateEngine;
  9784. var templateEngines = [];
  9785. var BaseTemplate = DevExpress.Class.inherit({
  9786. _compile: function(html, element) {
  9787. return element
  9788. },
  9789. _render: function(template, data) {
  9790. return template
  9791. },
  9792. ctor: function(element) {
  9793. this._element = $(element);
  9794. if (this._element.length === 1) {
  9795. if (this._element[0].nodeName.toLowerCase() !== "script")
  9796. this._element = $("<div />").append(this._element);
  9797. this._template = this._compile(this._element.html() || "", this._element)
  9798. }
  9799. },
  9800. render: function(container, data) {
  9801. var result;
  9802. if (this._template) {
  9803. result = this._render(this._template, data);
  9804. if (isString(result))
  9805. result = $.parseHTML(result);
  9806. result = $(result);
  9807. if (container)
  9808. container.append(result);
  9809. return result
  9810. }
  9811. },
  9812. owner: $.noop,
  9813. dispose: $.noop
  9814. });
  9815. var createTemplateEngine = function(options) {
  9816. if (options && options.compile && options.render)
  9817. return BaseTemplate.inherit({
  9818. allowRenderToDetachedContainer: options.allowRenderToDetachedContainer !== false,
  9819. _compile: options.compile,
  9820. _render: options.render
  9821. });
  9822. else
  9823. throw Error("Template Engine must contains compile and render methods");
  9824. };
  9825. if (window.ko) {
  9826. var koCustomTemplateEngine = function(){};
  9827. koCustomTemplateEngine.prototype = ko.utils.extend(new ko.templateEngine, {
  9828. renderTemplateSource: function(templateSource, bindingContext, options) {
  9829. var precompiledTemplate = templateSource["data"]("precompiledTemplate");
  9830. if (!precompiledTemplate) {
  9831. precompiledTemplate = new currentTemplateEngine(templateSource.domElement);
  9832. templateSource["data"]("precompiledTemplate", precompiledTemplate)
  9833. }
  9834. return precompiledTemplate.render(null, bindingContext.$data)
  9835. },
  9836. allowTemplateRewriting: false
  9837. })
  9838. }
  9839. DevExpress.ui.setTemplateEngine = function(templateEngine) {
  9840. if (isString(templateEngine)) {
  9841. currentTemplateEngine = templateEngines && templateEngines[templateEngine];
  9842. if (!currentTemplateEngine && templateEngine !== "default")
  9843. throw Error(DX.utils.stringFormat("Template Engine \"{0}\" is not supported", templateEngine));
  9844. }
  9845. else
  9846. currentTemplateEngine = createTemplateEngine(templateEngine) || currentTemplateEngine;
  9847. if (window.ko)
  9848. ko.setTemplateEngine(currentTemplateEngine ? new koCustomTemplateEngine : new ko.nativeTemplateEngine)
  9849. };
  9850. DevExpress.ui.TemplateProvider = DevExpress.ui.TemplateProvider.inherit({getTemplateClass: function() {
  9851. if (currentTemplateEngine)
  9852. return currentTemplateEngine;
  9853. return this.callBase.apply(this, arguments)
  9854. }});
  9855. var registerTemplateEngine = function(name, templateOptions) {
  9856. templateEngines[name] = createTemplateEngine(templateOptions)
  9857. };
  9858. registerTemplateEngine("jquery-tmpl", {
  9859. compile: function(html, element) {
  9860. return element
  9861. },
  9862. render: function(template, data) {
  9863. return template.tmpl(data)
  9864. }
  9865. });
  9866. registerTemplateEngine("jsrender", {
  9867. compile: function(html) {
  9868. return $.templates(html)
  9869. },
  9870. render: function(template, data) {
  9871. return template.render(data)
  9872. }
  9873. });
  9874. registerTemplateEngine("mustache", {
  9875. compile: function(html) {
  9876. return Mustache.compile(html)
  9877. },
  9878. render: function(template, data) {
  9879. return template(data)
  9880. }
  9881. });
  9882. registerTemplateEngine("hogan", {
  9883. compile: function(html) {
  9884. return Hogan.compile(html)
  9885. },
  9886. render: function(template, data) {
  9887. return template.render(data)
  9888. }
  9889. });
  9890. registerTemplateEngine("underscore", {
  9891. compile: function(html) {
  9892. return _.template(html)
  9893. },
  9894. render: function(template, data) {
  9895. return template(data)
  9896. }
  9897. });
  9898. registerTemplateEngine("handlebars", {
  9899. compile: function(html) {
  9900. return Handlebars.compile(html)
  9901. },
  9902. render: function(template, data) {
  9903. return template(data)
  9904. }
  9905. });
  9906. registerTemplateEngine("doT", {
  9907. compile: function(html) {
  9908. return doT.template(html)
  9909. },
  9910. render: function(template, data) {
  9911. return template(data)
  9912. }
  9913. })
  9914. })(jQuery, DevExpress);
  9915. /*! Module core, file ui.collectionContainerWidget.js */
  9916. (function($, DX, undefined) {
  9917. var ui = DX.ui,
  9918. events = ui.events;
  9919. var CollectionContainerWidget = ui.Widget.inherit({
  9920. _setDefaultOptions: function() {
  9921. this.callBase();
  9922. this.option({
  9923. items: [],
  9924. itemTemplate: "item",
  9925. itemRender: null,
  9926. itemRenderedAction: null,
  9927. itemClickAction: null,
  9928. itemHoldAction: null,
  9929. itemHoldTimeout: 750,
  9930. noDataText: Globalize.localize("dxCollectionContainerWidget-noDataText"),
  9931. dataSource: null,
  9932. selectedIndex: -1,
  9933. itemSelectAction: null,
  9934. itemTemplateProperty: "template"
  9935. })
  9936. },
  9937. _init: function() {
  9938. this.callBase();
  9939. this._cleanRenderedItems();
  9940. this._refreshDataSource()
  9941. },
  9942. _dataSourceOptions: function() {
  9943. var options = {
  9944. paginate: false,
  9945. _preferSync: false
  9946. };
  9947. if ($.isArray(this.option("dataSource")))
  9948. options._preferSync = true;
  9949. return options
  9950. },
  9951. _cleanRenderedItems: function() {
  9952. this._renderedItemsCount = 0
  9953. },
  9954. _fireSelectItemEvent: function(index, prevIndex) {
  9955. if (this._selectionEnabled()) {
  9956. this._updateSelectedIndex(index, prevIndex);
  9957. this._handleItemEvent(this._selectedItemElement(index), "itemSelectAction", {
  9958. selectedIndex: index,
  9959. previousIndex: prevIndex
  9960. }, {excludeValidators: ["gesture", "disabled"]})
  9961. }
  9962. },
  9963. _optionChanged: function(name, value, prevValue) {
  9964. switch (name) {
  9965. case"items":
  9966. case"itemTemplateProperty":
  9967. if (this._selectionEnabled()) {
  9968. var itemsCount = value && value.length || 0,
  9969. maxIndex = Math.max(itemsCount - 1, 0);
  9970. if (maxIndex < this.option("selectedIndex"))
  9971. this.option("selectedIndex", 0)
  9972. }
  9973. this._cleanRenderedItems();
  9974. this._invalidate();
  9975. break;
  9976. case"dataSource":
  9977. this._refreshDataSource();
  9978. if (!this._dataSource)
  9979. this.option("items", []);
  9980. this._renderEmptyMessage();
  9981. break;
  9982. case"noDataText":
  9983. this._renderEmptyMessage();
  9984. break;
  9985. case"itemTemplate":
  9986. this._invalidate();
  9987. break;
  9988. case"itemRender":
  9989. this._itemRender = null;
  9990. this._invalidate();
  9991. break;
  9992. case"itemRenderedAction":
  9993. this._createItemRenderAction();
  9994. break;
  9995. case"itemClickAction":
  9996. break;
  9997. case"itemHoldAction":
  9998. case"itemHoldTimeout":
  9999. this._attachHoldEvent();
  10000. break;
  10001. case"selectedIndex":
  10002. this._fireSelectItemEvent(value, prevValue);
  10003. break;
  10004. case"itemSelectAction":
  10005. break;
  10006. default:
  10007. this.callBase(name, value, prevValue)
  10008. }
  10009. },
  10010. _expectNextPageLoading: function() {
  10011. this._startIndexForAppendedItems = 0
  10012. },
  10013. _expectLastItemLoading: function() {
  10014. this._startIndexForAppendedItems = -1
  10015. },
  10016. _forgetNextPageLoading: function() {
  10017. this._startIndexForAppendedItems = null
  10018. },
  10019. _handleDataSourceChanged: function(newItems) {
  10020. var items = this.option("items");
  10021. if (this._initialized && items && this._shouldAppendItems()) {
  10022. this._renderedItemsCount = items.length;
  10023. if (!this._dataSource.isLastPage() || this._startIndexForAppendedItems !== -1)
  10024. this.option().items = items.concat(newItems.slice(this._startIndexForAppendedItems));
  10025. this._renderContent();
  10026. this._forgetNextPageLoading()
  10027. }
  10028. else
  10029. this.option("items", newItems)
  10030. },
  10031. _handleDataSourceLoadError: function() {
  10032. this._forgetNextPageLoading()
  10033. },
  10034. _shouldAppendItems: function() {
  10035. return this._startIndexForAppendedItems != null && this._allowDinamicItemsAppend()
  10036. },
  10037. _allowDinamicItemsAppend: function() {
  10038. return false
  10039. },
  10040. _clean: function() {
  10041. this._itemContainer().empty()
  10042. },
  10043. _refresh: function() {
  10044. this._cleanRenderedItems();
  10045. this.callBase.apply(this, arguments)
  10046. },
  10047. _itemContainer: function() {
  10048. return this._element()
  10049. },
  10050. _itemClass: DX.abstract,
  10051. _itemSelector: function() {
  10052. return "." + this._itemClass()
  10053. },
  10054. _itemDataKey: DX.abstract,
  10055. _itemElements: function() {
  10056. return this._itemContainer().find(this._itemSelector())
  10057. },
  10058. _render: function() {
  10059. this.callBase();
  10060. this._attachClickEvent();
  10061. this._attachHoldEvent();
  10062. if (this._selectionEnabled()) {
  10063. this._renderSelectedIndex(this.option("selectedIndex"));
  10064. this._attachSelectedEvent()
  10065. }
  10066. },
  10067. _selectionEnabled: function() {
  10068. return this._renderSelectedIndex !== DX.abstract
  10069. },
  10070. _selectionByClickEnabled: function() {
  10071. return true
  10072. },
  10073. _renderSelectedIndex: DX.abstract,
  10074. _attachSelectedEvent: function() {
  10075. if (!this._selectionByClickEnabled())
  10076. return;
  10077. var itemSelector = this._itemSelector(),
  10078. itemSelectHandler = this._createAction($.proxy(function(e) {
  10079. this._handleItemSelect(e.jQueryEvent)
  10080. }, this), {validatingTargetName: "itemElement"}),
  10081. eventName = events.addNamespace("dxclick", this.NAME);
  10082. this._element().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(function(e) {
  10083. var $itemElement = $(e.target).closest(itemSelector);
  10084. itemSelectHandler({
  10085. itemElement: $itemElement,
  10086. jQueryEvent: e
  10087. });
  10088. this._handleItemClick(e)
  10089. }, this))
  10090. },
  10091. _handleItemSelect: function(e) {
  10092. if (events.needSkipEvent(e))
  10093. return;
  10094. var items = this.option("items"),
  10095. selectedItem = $(e.currentTarget).data(this._itemDataKey()),
  10096. selectedItemIndex = $.inArray(selectedItem, items);
  10097. this.option("selectedIndex", selectedItemIndex)
  10098. },
  10099. _updateSelectedIndex: function() {
  10100. this._renderSelectedIndex.apply(this, arguments)
  10101. },
  10102. _selectedItemElement: function(index) {
  10103. return this._itemElements().eq(index)
  10104. },
  10105. _attachClickEvent: function() {
  10106. if (this._selectionEnabled() && this._selectionByClickEnabled())
  10107. return;
  10108. var itemSelector = this._itemSelector(),
  10109. eventName = events.addNamespace("dxclick", this.NAME);
  10110. this._itemContainer().off(eventName, itemSelector).on(eventName, itemSelector, $.proxy(this._handleItemClick, this))
  10111. },
  10112. _handleItemClick: function(e) {
  10113. this._handleItemJQueryEvent(e, "itemClickAction")
  10114. },
  10115. _attachHoldEvent: function() {
  10116. var $itemContainer = this._itemContainer(),
  10117. itemSelector = this._itemSelector(),
  10118. eventName = events.addNamespace("dxhold", this.NAME);
  10119. $itemContainer.off(eventName, itemSelector);
  10120. if (this._shouldAttachHoldEvent())
  10121. $itemContainer.on(eventName, itemSelector, {timeout: this.option("itemHoldTimeout")}, $.proxy(this._handleItemHold, this))
  10122. },
  10123. _shouldAttachHoldEvent: function() {
  10124. return this.option("itemHoldAction")
  10125. },
  10126. _handleItemHold: function(e) {
  10127. this._handleItemJQueryEvent(e, "itemHoldAction")
  10128. },
  10129. _renderContentImpl: function() {
  10130. var items = this.option("items") || [];
  10131. if (this._renderedItemsCount)
  10132. this._renderItems(items.slice(this._renderedItemsCount));
  10133. else
  10134. this._renderItems(items)
  10135. },
  10136. _renderItems: function(items) {
  10137. if (items.length)
  10138. $.each(items, $.proxy(this._renderItem, this));
  10139. this._renderEmptyMessage()
  10140. },
  10141. _renderItem: function(index, itemData, container) {
  10142. container = container || this._itemContainer();
  10143. var itemRenderer = this._getItemRenderer(),
  10144. itemTemplateName = this._getItemTemplateName(itemData),
  10145. itemTemplate = this._getTemplate(itemTemplateName, index, itemData),
  10146. itemElement,
  10147. renderArgs = {
  10148. index: index,
  10149. item: itemData,
  10150. container: container
  10151. };
  10152. if (itemRenderer)
  10153. itemElement = this._createItemByRenderer(itemRenderer, renderArgs);
  10154. else if (itemTemplate)
  10155. itemElement = this._createItemByTemplate(itemTemplate, renderArgs);
  10156. else
  10157. itemElement = this._createItemByRenderer(this._itemRenderDefault, renderArgs);
  10158. itemElement.addClass(this._itemClass()).data(this._itemDataKey(), itemData);
  10159. var postprocessRenderArgs = {
  10160. itemElement: itemElement,
  10161. itemData: itemData,
  10162. itemIndex: index
  10163. };
  10164. this._postprocessRenderItem(postprocessRenderArgs);
  10165. this._getItemRenderAction()({
  10166. itemElement: itemElement,
  10167. itemData: itemData
  10168. });
  10169. return itemElement
  10170. },
  10171. _createItemRenderAction: function() {
  10172. return this._itemRenderAction = this._createActionByOption("itemRenderedAction", {
  10173. element: this._element(),
  10174. excludeValidators: ["gesture", "designMode", "disabled"]
  10175. })
  10176. },
  10177. _getItemRenderAction: function() {
  10178. return this._itemRenderAction || this._createItemRenderAction()
  10179. },
  10180. _getItemRenderer: function() {
  10181. this._itemRender = this._itemRender || this.option("itemRender");
  10182. return this._itemRender
  10183. },
  10184. _createItemByRenderer: function(itemRenderer, renderArgs) {
  10185. var itemElement = $("<div />").appendTo(renderArgs.container);
  10186. var rendererResult = itemRenderer.call(this, renderArgs.item, renderArgs.index, itemElement);
  10187. if (rendererResult != null && itemElement[0] !== rendererResult[0])
  10188. itemElement.append(rendererResult);
  10189. return itemElement
  10190. },
  10191. _getItemTemplateName: function(itemData) {
  10192. var templateProperty = this.option("itemTemplateProperty");
  10193. return itemData && itemData[templateProperty] || this.option("itemTemplate")
  10194. },
  10195. _createItemByTemplate: function(itemTemplate, renderArgs) {
  10196. return itemTemplate.render(renderArgs.container, renderArgs.item, renderArgs.index, "ignoreTarget")
  10197. },
  10198. _itemRenderDefault: function(item, index, itemElement) {
  10199. if ($.isPlainObject(item)) {
  10200. if (item.visible !== undefined && !item.visible)
  10201. itemElement.hide();
  10202. if (item.disabled)
  10203. itemElement.addClass("dx-state-disabled");
  10204. if (item.text)
  10205. itemElement.text(item.text);
  10206. if (item.html)
  10207. itemElement.html(item.html)
  10208. }
  10209. else
  10210. itemElement.html(String(item))
  10211. },
  10212. _postprocessRenderItem: $.noop,
  10213. _renderEmptyMessage: function() {
  10214. if (!this._selectionEnabled()) {
  10215. var noDataText = this.option("noDataText"),
  10216. items = this.option("items"),
  10217. dataSourceLoading = this._dataSource && this._dataSource.isLoading(),
  10218. hideNoData = !noDataText || items && items.length || dataSourceLoading;
  10219. if (hideNoData && this._$nodata) {
  10220. this._$nodata.remove();
  10221. this._$nodata = null
  10222. }
  10223. if (!hideNoData) {
  10224. this._$nodata = this._$nodata || $("<div />").addClass("dx-empty-message");
  10225. this._$nodata.appendTo(this._itemContainer()).text(noDataText)
  10226. }
  10227. }
  10228. },
  10229. _handleItemJQueryEvent: function(jQueryEvent, handlerOptionName, actionArgs, actionConfig) {
  10230. this._handleItemEvent(jQueryEvent.target, handlerOptionName, $.extend(actionArgs, {jQueryEvent: jQueryEvent}), actionConfig)
  10231. },
  10232. _handleItemEvent: function(initiator, handlerOptionName, actionArgs, actionConfig) {
  10233. var action = this._createActionByOption(handlerOptionName, $.extend({validatingTargetName: "itemElement"}, actionConfig));
  10234. return this._handleItemEventImpl(initiator, action, actionArgs)
  10235. },
  10236. _handleItemEventByHandler: function(initiator, handler, actionArgs, actionConfig) {
  10237. var action = this._createAction(handler, $.extend({validatingTargetName: "itemElement"}, actionConfig));
  10238. return this._handleItemEventImpl(initiator, action, actionArgs)
  10239. },
  10240. _handleItemEventImpl: function(initiator, action, actionArgs) {
  10241. var $itemElement = this._closestItemElement($(initiator));
  10242. actionArgs = $.extend({
  10243. itemElement: $itemElement,
  10244. itemData: this._getItemData($itemElement)
  10245. }, actionArgs);
  10246. return action(actionArgs)
  10247. },
  10248. _closestItemElement: function($element) {
  10249. return $($element).closest(this._itemSelector())
  10250. },
  10251. _getItemData: function($itemElement) {
  10252. return $itemElement.data(this._itemDataKey())
  10253. },
  10254. itemElements: function() {
  10255. return this._itemElements()
  10256. },
  10257. itemsContainer: function() {
  10258. return this._itemContainer()
  10259. }
  10260. }).include(ui.DataHelperMixin);
  10261. ui.CollectionContainerWidget = CollectionContainerWidget
  10262. })(jQuery, DevExpress);
  10263. /*! Module core, file ui.tooltip.js */
  10264. (function($, DX, undefined) {
  10265. var $tooltip = null;
  10266. var createTooltip = function(options) {
  10267. options = $.extend({position: "top"}, options);
  10268. var content = options.content;
  10269. delete options.content;
  10270. return $("<div />").html(content).appendTo(DX.overlayTargetContainer()).dxTooltip(options)
  10271. };
  10272. var removeTooltip = function() {
  10273. if (!$tooltip)
  10274. return;
  10275. $tooltip.remove();
  10276. $tooltip = null
  10277. };
  10278. var tooltip = {
  10279. show: function(options) {
  10280. removeTooltip();
  10281. $tooltip = createTooltip(options);
  10282. return $tooltip.dxTooltip("show")
  10283. },
  10284. hide: function() {
  10285. if (!$tooltip)
  10286. return $.when();
  10287. return $tooltip.dxTooltip("hide").done(removeTooltip).promise()
  10288. }
  10289. };
  10290. DX.ui.tooltip = tooltip
  10291. })(jQuery, DevExpress)
  10292. }
  10293. if (!DevExpress.MOD_VIZ_CORE) {
  10294. if (!window.DevExpress)
  10295. throw Error('Required module is not referenced: core');
  10296. /*! Module viz-core, file namespaces.js */
  10297. (function(DevExpress) {
  10298. DevExpress.viz = {}
  10299. })(DevExpress);
  10300. /*! Module viz-core, file namespaces.js */
  10301. (function(DevExpress) {
  10302. DevExpress.viz.core = {}
  10303. })(DevExpress);
  10304. /*! Module viz-core, file errorsWarnings.js */
  10305. (function(DevExpress) {
  10306. DevExpress.viz.core.errorsWarnings = {
  10307. E2001: "Invalid data source",
  10308. E2002: "Axis type and data type are incompatible",
  10309. E2003: "\"{0}\" data source field contains data of unsupported type",
  10310. E2004: "\"{0}\" data source field is inconsistent",
  10311. E2101: "Unknown series type was specified: {0}",
  10312. E2102: "Ambiguity occurred between two value axes with the same name",
  10313. E2103: "\"{0}\" option must be a function",
  10314. E2104: "Invalid logarithm base",
  10315. E2105: "Invalid value of a \"{0}\"",
  10316. E2106: "Invalid visible range",
  10317. E2201: "Invalid type of data source field",
  10318. E2202: "Invalid scale {0} value",
  10319. E2203: "The \"{0}\" field of the \"selectedRange\" configuration object is not valid",
  10320. W2001: "{0} cannot be drawn because its container is invisible",
  10321. W2002: "The {0} data field is absent",
  10322. W2003: "Tick interval is too small",
  10323. W2101: "\"{0}\" pane does not exist; \"{1}\" pane is used instead",
  10324. W2102: "Value axis with the \"{0}\" name was created automatically",
  10325. W2103: "Chart title was hidden due to container size",
  10326. W2104: "Legend was hidden due to container size",
  10327. W2105: "Title of \"{0}\" axis was hidden due to container size",
  10328. W2106: "Labels of \"{0}\" axis were hidden due to container size",
  10329. W2301: "Invalid value range"
  10330. }
  10331. })(DevExpress);
  10332. /*! Module viz-core, file tickProvider.js */
  10333. (function($, DX, undefined) {
  10334. var utils = DX.utils,
  10335. math = Math,
  10336. mathCeil = math.ceil,
  10337. mathFloor = math.floor,
  10338. mathAbs = math.abs,
  10339. mathRound = math.round,
  10340. core = DX.viz.core;
  10341. var TICKS_COUNT_LIMIT = 2000;
  10342. core.outOfScreen = {
  10343. x: -1000,
  10344. y: -1000
  10345. };
  10346. core.tickIntervalCalculator = {
  10347. _defaultNumberMultipliers: [1, 2, 3, 5],
  10348. _defaultGridSpacingFactor: 30,
  10349. _getCommonTickInterval: function(deltaCoef, numberMultipliers) {
  10350. var factor,
  10351. result = 0,
  10352. hasResult = false,
  10353. i;
  10354. for (factor = 1; !hasResult; factor *= 10)
  10355. for (i = 0; i < numberMultipliers.length; i++) {
  10356. result = numberMultipliers[i] * factor;
  10357. if (deltaCoef <= result) {
  10358. hasResult = true;
  10359. break
  10360. }
  10361. }
  10362. return result
  10363. },
  10364. _getNumericTickInterval: function(deltaCoef, numberMultipliers) {
  10365. var factor,
  10366. result = 0,
  10367. newResult,
  10368. hasResult = false,
  10369. i;
  10370. if (deltaCoef > 1.0)
  10371. result = this._getCommonTickInterval(deltaCoef, numberMultipliers);
  10372. else if (deltaCoef > 0) {
  10373. result = 1;
  10374. for (factor = 0.1; !hasResult; factor /= 10)
  10375. for (i = numberMultipliers.length - 1; i >= 0; i--) {
  10376. newResult = numberMultipliers[i] * factor;
  10377. if (deltaCoef > newResult) {
  10378. hasResult = true;
  10379. break
  10380. }
  10381. result = newResult
  10382. }
  10383. }
  10384. return utils.adjustValue(result)
  10385. },
  10386. _getLogarithmicTickInterval: function(deltaCoef, numberMultipliers) {
  10387. var result = 0;
  10388. if (deltaCoef !== 0)
  10389. result = this._getCommonTickInterval(deltaCoef, numberMultipliers);
  10390. return utils.adjustValue(result)
  10391. },
  10392. _getDateTimeTickInterval: function(deltaCoef, numberMultipliers) {
  10393. var dateTimeMultipliers = {
  10394. millisecond: [1, 2, 5, 10, 25, 100, 250, 300, 500],
  10395. second: [1, 2, 3, 5, 10, 15, 20, 30],
  10396. minute: [1, 2, 3, 5, 10, 15, 20, 30],
  10397. hour: [1, 2, 3, 4, 6, 8, 12],
  10398. day: [1, 2, 3, 5, 7, 10, 14],
  10399. month: [1, 2, 3, 6]
  10400. },
  10401. result = {},
  10402. factor,
  10403. key,
  10404. specificMultipliers,
  10405. yearsCount,
  10406. i;
  10407. if (deltaCoef > 0 && deltaCoef < 1.0)
  10408. return {milliseconds: 1};
  10409. else if (deltaCoef === 0)
  10410. return 0;
  10411. for (key in dateTimeMultipliers)
  10412. if (dateTimeMultipliers.hasOwnProperty(key)) {
  10413. specificMultipliers = dateTimeMultipliers[key];
  10414. for (i = 0; i < specificMultipliers.length; i++)
  10415. if (deltaCoef <= utils.convertDateUnitToMilliseconds(key, specificMultipliers[i])) {
  10416. result[key + 's'] = specificMultipliers[i];
  10417. return result
  10418. }
  10419. }
  10420. for (factor = 1; ; factor *= 10)
  10421. for (i = 0; i < numberMultipliers.length; i++) {
  10422. yearsCount = factor * numberMultipliers[i];
  10423. if (deltaCoef <= utils.convertDateUnitToMilliseconds('year', yearsCount))
  10424. return {years: yearsCount}
  10425. }
  10426. return null
  10427. },
  10428. getTickInterval: function(options) {
  10429. var that = this,
  10430. gridSpacingFactor = options.gridSpacingFactor || that._defaultGridSpacingFactor,
  10431. numberMultipliers = options.numberMultipliers || that._defaultNumberMultipliers,
  10432. businessDelta = options.businessDelta,
  10433. screenDelta = options.screenDelta,
  10434. deltaCoef = screenDelta > 0 && gridSpacingFactor < screenDelta ? gridSpacingFactor * businessDelta / screenDelta : 0;
  10435. that._testNumberMultipliers = numberMultipliers;
  10436. if (options.axisType === 'logarithmic')
  10437. return that._getLogarithmicTickInterval(deltaCoef, numberMultipliers);
  10438. else
  10439. switch (options.dataType) {
  10440. case'numeric':
  10441. return that._getNumericTickInterval(deltaCoef, numberMultipliers);
  10442. break;
  10443. case'datetime':
  10444. return that._getDateTimeTickInterval(deltaCoef, numberMultipliers);
  10445. break
  10446. }
  10447. return null
  10448. }
  10449. };
  10450. core.minorTickIntervalCalculator = {
  10451. _defaultNumberMultipliers: [2, 4, 5, 8, 10],
  10452. _defaultGridSpacingFactor: 15,
  10453. _getDateTimeTickInterval: function(businessDelta, deltaCoef, numberMultipliers) {
  10454. var result,
  10455. i;
  10456. for (i = numberMultipliers.length - 1; i >= 0; i--) {
  10457. this.testResultNumberMultiplier = numberMultipliers[i];
  10458. result = mathFloor(businessDelta / numberMultipliers[i]);
  10459. if (deltaCoef <= result)
  10460. return utils.convertMillisecondsToDateUnits(result)
  10461. }
  10462. return 0
  10463. },
  10464. _getCommonTickInterval: function(businessDelta, deltaCoef, numberMultipliers) {
  10465. var result,
  10466. i;
  10467. for (i = numberMultipliers.length - 1; i >= 0; i--) {
  10468. this.testResultNumberMultiplier = numberMultipliers[i];
  10469. result = businessDelta / numberMultipliers[i];
  10470. if (deltaCoef <= result)
  10471. return utils.adjustValue(result)
  10472. }
  10473. return 0
  10474. },
  10475. getTickInterval: function(options) {
  10476. var that = this,
  10477. gridSpacingFactor = !utils.isDefined(options.gridSpacingFactor) ? that._defaultGridSpacingFactor : options.gridSpacingFactor,
  10478. numberMultipliers = options.numberMultipliers || that._defaultNumberMultipliers,
  10479. businessDelta = options.businessDelta,
  10480. deltaCoef = gridSpacingFactor * businessDelta / options.screenDelta;
  10481. if (options.axisType === 'logarithmic')
  10482. return that._getCommonTickInterval(businessDelta, deltaCoef, numberMultipliers);
  10483. else
  10484. switch (options.dataType) {
  10485. case'numeric':
  10486. return that._getCommonTickInterval(businessDelta, deltaCoef, numberMultipliers);
  10487. case'datetime':
  10488. return that._getDateTimeTickInterval(businessDelta, deltaCoef, numberMultipliers)
  10489. }
  10490. return 0
  10491. }
  10492. };
  10493. core.tickProvider = {
  10494. _appendFakeSVGElement: function(value, text, options) {
  10495. var textOptions = $.extend({}, options.textOptions, {rotate: 0});
  10496. return options.renderer.createText(text, core.outOfScreen.x + (options.translator.translate(value) || 0), core.outOfScreen.y, textOptions).append()
  10497. },
  10498. _getDistanceByAngle: function(elementHeight, rotationAngle) {
  10499. return elementHeight / mathAbs(math.sin(rotationAngle * (math.PI / 180)))
  10500. },
  10501. _areDisplayValuesValid: function(value1, value2, options) {
  10502. var that = this,
  10503. getText = that._getTextFunc(options),
  10504. rotationAngle = options.textOptions && utils.isNumber(options.textOptions.rotate) ? options.textOptions.rotate : 0,
  10505. svgElement1 = that._appendFakeSVGElement(value1, getText(value1), options),
  10506. svgElement2 = that._appendFakeSVGElement(value2, getText(value2), options),
  10507. bBox1 = svgElement1.getBBox(),
  10508. bBox2 = svgElement2.getBBox(),
  10509. result,
  10510. translator = options.translator;
  10511. if (rotationAngle !== 0)
  10512. result = that._getDistanceByAngle(bBox1.height, rotationAngle) <= mathAbs(bBox2.x - bBox1.x);
  10513. else if (options.isHorizontal)
  10514. result = !translator.getBusinessRange().invert ? bBox1.x + bBox1.width < bBox2.x : bBox2.x + bBox2.width < bBox1.x;
  10515. else
  10516. result = mathAbs(translator.translate(value1) - translator.translate(value2)) > bBox1.height;
  10517. svgElement1.remove();
  10518. svgElement2.remove();
  10519. return result
  10520. },
  10521. _removeInvalidDatesWithUnitBegining: function(dates, options) {
  10522. if (dates.length <= 1 || !options.setTicksAtUnitBeginning || !utils.isDate(options.min))
  10523. return;
  10524. if (!this._areDisplayValuesValid(dates[0], dates[1], options))
  10525. dates.splice(1, 1)
  10526. },
  10527. _getValueSize: function(values, options) {
  10528. var that = this,
  10529. value,
  10530. rotationAngle = options.textOptions ? options.textOptions.rotate : 0,
  10531. svgElement,
  10532. bBox,
  10533. result,
  10534. getText = that._getTextFunc(options),
  10535. i;
  10536. if (values.length === 0)
  10537. return 0;
  10538. options.isRotate = utils.isNumber(rotationAngle) && rotationAngle !== 0;
  10539. if (options.isRotate || !options.isHorizontal)
  10540. value = getText(values[0]);
  10541. else {
  10542. value = [];
  10543. for (i = 0; i < values.length; i++)
  10544. value.push(getText(values[i]));
  10545. value = value.join('\n')
  10546. }
  10547. svgElement = that._appendFakeSVGElement(value, value, options);
  10548. bBox = svgElement.getBBox();
  10549. if (options.isRotate)
  10550. result = that._getDistanceByAngle(bBox.height, rotationAngle);
  10551. else
  10552. result = options.isHorizontal ? bBox.width : bBox.height;
  10553. svgElement.remove();
  10554. return mathCeil(result)
  10555. },
  10556. _adjustNumericTickValue: function(value, interval, min) {
  10557. return utils.isExponential(value) ? utils.adjustValue(value) : utils.applyPrecisionByMinDelta(min, interval, value)
  10558. },
  10559. _generateStartTick: function(tickInterval, options) {
  10560. var that = this,
  10561. milliseconds = 0,
  10562. boundedRule = options.min - options.max < 0,
  10563. startTick = options.min,
  10564. isDate = utils.isDate(options.min),
  10565. currentTickInterval = isDate ? utils.convertDateTickIntervalToMilliseconds(tickInterval) : tickInterval,
  10566. nextTick;
  10567. if (options.axisType === 'logarithmic')
  10568. startTick = utils.raiseTo(mathFloor(utils.adjustValue(utils.getLog(options.min, options.base)) / currentTickInterval * currentTickInterval), options.base);
  10569. else {
  10570. startTick = mathFloor(options.min / currentTickInterval) * currentTickInterval;
  10571. startTick = isDate ? new Date(startTick) : that._adjustNumericTickValue(startTick, currentTickInterval, options.min)
  10572. }
  10573. while (boundedRule === startTick - options.min < 0 && startTick !== options.min) {
  10574. nextTick = that._nextTick(startTick, tickInterval, options);
  10575. if (nextTick !== startTick)
  10576. startTick = nextTick;
  10577. else
  10578. return nextTick
  10579. }
  10580. return startTick
  10581. },
  10582. _nextTick: function(tick, tickInterval, options) {
  10583. var nextTick,
  10584. lgPower,
  10585. that = this;
  10586. if (options.axisType === 'logarithmic') {
  10587. lgPower = utils.addInterval(utils.adjustValue(utils.getLog(tick, options.base)), tickInterval, options.min > options.max);
  10588. nextTick = utils.raiseTo(lgPower, options.base);
  10589. nextTick = that._adjustNumericTickValue(nextTick, tickInterval, math.min(options.min, options.max))
  10590. }
  10591. else {
  10592. nextTick = utils.addInterval(tick, tickInterval, options.min > options.max);
  10593. if (options.dataType === 'numeric')
  10594. nextTick = that._adjustNumericTickValue(nextTick, tickInterval, options.min);
  10595. if (options.dataType === 'datetime' && options.setTicksAtUnitBeginning)
  10596. utils.correctDateWithUnitBeginning(nextTick, tickInterval)
  10597. }
  10598. return nextTick
  10599. },
  10600. _addMinorTicks: function(majorTick1, majorTick2, ticksInfo, options, isReverse) {
  10601. var that = this,
  10602. i,
  10603. dataType = options.dataType,
  10604. businessDelta,
  10605. minorTicks = [],
  10606. interval = 0,
  10607. minorTickIntervalsCount = options.minorTickCount + 1,
  10608. intervalsCount,
  10609. tickInterval;
  10610. options.min = majorTick1;
  10611. options.max = majorTick2;
  10612. if (!utils.isDefined(options.tickInterval)) {
  10613. options.businessDelta = businessDelta = mathAbs(options.max - options.min);
  10614. options.screenDelta = businessDelta * options.deltaCoef;
  10615. if (utils.isDefined(options.minorTickCount)) {
  10616. if (!ticksInfo.majorTicks.autoArrangementStep || ticksInfo.majorTicks.autoArrangementStep <= 1) {
  10617. intervalsCount = options.minorTickCount + 1;
  10618. interval = dataType === 'datetime' ? utils.convertDateTickIntervalToMilliseconds(ticksInfo.majorTickInterval) : ticksInfo.majorTickInterval;
  10619. minorTickIntervalsCount = mathRound(businessDelta / interval * intervalsCount) || 1
  10620. }
  10621. tickInterval = dataType === 'datetime' ? utils.convertMillisecondsToDateUnits(businessDelta / minorTickIntervalsCount) : businessDelta / minorTickIntervalsCount;
  10622. if ($.isNumeric(tickInterval))
  10623. tickInterval = utils.adjustValue(tickInterval)
  10624. }
  10625. else if (utils.isDate(majorTick1))
  10626. tickInterval = core.minorTickIntervalCalculator.getTickInterval(options)
  10627. }
  10628. options = $.extend(true, {}, options, {tickInterval: tickInterval});
  10629. minorTicks = that.getTicks(options);
  10630. if (isReverse)
  10631. minorTicks.reverse();
  10632. if (minorTicks.length > 0)
  10633. if (mathCeil(mathAbs(majorTick2 - minorTicks[minorTicks.length - 1]) * options.deltaCoef) < 2)
  10634. minorTicks.pop();
  10635. for (i = 0; i < minorTicks.length; i++) {
  10636. ticksInfo.minorTicks.push(minorTicks[i]);
  10637. ticksInfo.fullTicks.push(minorTicks[i])
  10638. }
  10639. },
  10640. _addLeftBoudedTicks: function(ticksInfo, min, minorTicksOptions) {
  10641. if (utils.isDefined(min) && ticksInfo.majorTicks[0].valueOf() !== min.valueOf()) {
  10642. minorTicksOptions.addMinMax.max = true;
  10643. this._addMinorTicks(ticksInfo.majorTicks[0], min, ticksInfo, minorTicksOptions, true);
  10644. minorTicksOptions.addMinMax.max = false;
  10645. if (minorTicksOptions.showCustomBoundaryTicks) {
  10646. if (ticksInfo.minorTicks.length > 0 && ticksInfo.minorTicks[0].valueOf() === min.valueOf())
  10647. ticksInfo.minorTicks.shift(min);
  10648. ticksInfo.customBoundaryTicks.push(min);
  10649. ticksInfo.fullTicks.unshift(min)
  10650. }
  10651. }
  10652. },
  10653. _addRightBoudedTicks: function(ticksInfo, max, minorTicksOptions) {
  10654. var lastMajorTick = ticksInfo.majorTicks[ticksInfo.majorTicks.length - 1];
  10655. ticksInfo.fullTicks.push(lastMajorTick);
  10656. if (utils.isDefined(max) && lastMajorTick.valueOf() !== max.valueOf()) {
  10657. minorTicksOptions.addMinMax.min = false;
  10658. minorTicksOptions.addMinMax.max = true;
  10659. this._addMinorTicks(lastMajorTick, max, ticksInfo, minorTicksOptions);
  10660. if (minorTicksOptions.showCustomBoundaryTicks) {
  10661. if (ticksInfo.minorTicks.length > 0 && ticksInfo.minorTicks[ticksInfo.minorTicks.length - 1].valueOf() === max.valueOf())
  10662. ticksInfo.minorTicks.pop(max);
  10663. ticksInfo.customBoundaryTicks.push(max);
  10664. ticksInfo.fullTicks.push(max)
  10665. }
  10666. }
  10667. },
  10668. _correctBoundedTicks: function(min, max, ticks, addMinMax) {
  10669. addMinMax = $.extend({}, {
  10670. min: true,
  10671. max: true
  10672. }, addMinMax);
  10673. if (ticks.length > 0) {
  10674. if (!addMinMax.min && ticks[0].valueOf() === min.valueOf())
  10675. ticks.shift();
  10676. if (!addMinMax.max || ticks[ticks.length - 1].valueOf() !== max.valueOf())
  10677. ticks.pop()
  10678. }
  10679. },
  10680. _initializeMinorTicksOptions: function(min, max, screenDelta, ticksInfo, options) {
  10681. var that = this,
  10682. businessDelta,
  10683. hasMinorsCount = utils.isDefined(options.minorTickCount);
  10684. $.extend(true, options, {
  10685. addMinMax: {
  10686. min: false,
  10687. max: false
  10688. },
  10689. deltaCoef: that._getDeltaCoef(screenDelta, max, min, options.axisType, options.base)
  10690. }, options);
  10691. options.numberMultipliers = hasMinorsCount ? [options.minorTickCount + 1] : options.numberMultipliers;
  10692. options.gridSpacingFactor = hasMinorsCount ? 0 : options.gridSpacingFactor;
  10693. if (!hasMinorsCount && ticksInfo.majorTicks.length > 1) {
  10694. options.businessDelta = businessDelta = that._getBusinessDelta(options.axisType, ticksInfo.majorTicks[0], ticksInfo.majorTicks[1], options.base);
  10695. if (that.needTickIntervalCalculation(businessDelta, ticksInfo.minorTickInterval, options.incidentOccured)) {
  10696. options.screenDelta = businessDelta * options.deltaCoef;
  10697. ticksInfo.minorTickInterval = core.minorTickIntervalCalculator.getTickInterval(options);
  10698. if (utils.isNumber(min))
  10699. options.tickInterval = ticksInfo.minorTickInterval;
  10700. else
  10701. options.tickInterval = undefined
  10702. }
  10703. }
  10704. },
  10705. _getDataType: function(value) {
  10706. return utils.isDate(value) ? 'datetime' : 'numeric'
  10707. },
  10708. _getBusinessDelta: function(type, min, max, base) {
  10709. return type === 'logarithmic' ? mathRound(mathAbs(utils.getLog(min, base) - utils.getLog(max, base))) : mathAbs(min - max)
  10710. },
  10711. _getDeltaCoef: function(screenDelta, max, min, type, base) {
  10712. return screenDelta / this._getBusinessDelta(type, min, max, base)
  10713. },
  10714. _initializeMajorTicksOptions: function(min, max, screenDelta, ticksInfo, options) {
  10715. var businessDelta;
  10716. options.screenDelta = screenDelta;
  10717. $.extend(true, options, {
  10718. min: min,
  10719. max: max,
  10720. screenDelta: screenDelta,
  10721. isHorizontal: true
  10722. });
  10723. if (utils.isDefined(min) && utils.isDefined(max)) {
  10724. options.businessDelta = businessDelta = this._getBusinessDelta(options.axisType, min, max, options.base);
  10725. if (this.needTickIntervalCalculation(businessDelta, ticksInfo.majorTickInterval, options.incidentOccured)) {
  10726. options.isStartTickGenerated = true;
  10727. ticksInfo.majorTickInterval = core.tickIntervalCalculator.getTickInterval(options);
  10728. options.tickInterval = ticksInfo.majorTickInterval
  10729. }
  10730. }
  10731. },
  10732. _getTextFunc: function(options) {
  10733. return options.getText || function(value) {
  10734. return value.toString()
  10735. }
  10736. },
  10737. _generateTicks: function(options) {
  10738. var that = this,
  10739. ticks = [],
  10740. tick,
  10741. boundedRule = options.max - options.min > 0,
  10742. leftBound,
  10743. rightBound,
  10744. tickInterval,
  10745. isStartTickGenerated = options.isStartTickGenerated,
  10746. businessDelta,
  10747. useTicksAutoArrangement = options.useTicksAutoArrangement;
  10748. options.dataType = options.dataType || that._getDataType(options.min);
  10749. options.businessDelta = businessDelta = that._getBusinessDelta(options.axisType, options.min, options.max, options.base);
  10750. if (!utils.isDefined(options.min) || !utils.isDefined(options.max) || isNaN(options.min) || isNaN(options.max)) {
  10751. ticks = options.isHorizontal ? ['canvas_position_left', 'canvas_position_center', 'canvas_position_right'] : ['canvas_position_bottom', 'canvas_position_middle', 'canvas_position_top'];
  10752. useTicksAutoArrangement = false;
  10753. ticks.hideLabels = true
  10754. }
  10755. else {
  10756. tickInterval = $.isNumeric(options.min) && $.isNumeric(options.max) && !$.isNumeric(options.tickInterval) ? undefined : options.tickInterval;
  10757. if (this.needTickIntervalCalculation(businessDelta, tickInterval, options.incidentOccured)) {
  10758. isStartTickGenerated = utils.isDefined(isStartTickGenerated) ? isStartTickGenerated : true;
  10759. tickInterval = core.tickIntervalCalculator.getTickInterval(options)
  10760. }
  10761. ticks.tickInterval = tickInterval;
  10762. that.isTestStartTickGenerated = isStartTickGenerated;
  10763. that.isTestTickInterval = tickInterval;
  10764. that.testGridSpacingFactor = options.gridSpacingFactor;
  10765. if (tickInterval && tickInterval.valueOf() !== 0 && options.min.valueOf() !== options.max.valueOf()) {
  10766. tick = isStartTickGenerated ? that._generateStartTick(tickInterval, options) : options.min;
  10767. do {
  10768. ticks.push(tick);
  10769. tick = that._nextTick(tick, tickInterval, options);
  10770. if (ticks[ticks.length - 1].valueOf() === tick.valueOf())
  10771. break;
  10772. leftBound = tick - options.min > 0;
  10773. rightBound = options.max - tick > 0
  10774. } while (boundedRule === leftBound && boundedRule === rightBound);
  10775. ticks.push(tick);
  10776. that._correctBoundedTicks(options.min, options.max, ticks, options.addMinMax)
  10777. }
  10778. if (options.min.valueOf() === options.max.valueOf()) {
  10779. tick = options.min;
  10780. ticks.push(tick)
  10781. }
  10782. }
  10783. return ticks
  10784. },
  10785. _getAutoArrangementStep: function(ticks, options) {
  10786. var that = this,
  10787. requiredValuesCount,
  10788. addedSpacing = options.isHorizontal ? options.textSpacing : 0;
  10789. if (options.getCustomAutoArrangementStep)
  10790. return options.getCustomAutoArrangementStep(ticks, options);
  10791. if (options.maxDisplayValueSize > 0) {
  10792. requiredValuesCount = mathFloor((options.screenDelta + options.textSpacing) / (options.maxDisplayValueSize + addedSpacing));
  10793. return mathCeil((options.ticksCount || ticks.length) / requiredValuesCount)
  10794. }
  10795. return 1
  10796. },
  10797. _getAutoArrangementTicks: function(ticks, options, step) {
  10798. var that = this,
  10799. resultTicks = ticks,
  10800. i;
  10801. if (step > 1) {
  10802. resultTicks = [];
  10803. for (i = 0; i < ticks.length; i += step)
  10804. resultTicks.push(ticks[i]);
  10805. resultTicks.tickInterval = ticks.tickInterval * step
  10806. }
  10807. return resultTicks
  10808. },
  10809. isOverlappedTicks: function(ticks, options) {
  10810. options.maxDisplayValueSize = this._getValueSize(ticks, options);
  10811. return this._getAutoArrangementStep(ticks, options) > 1
  10812. },
  10813. getCorrectedTicks: function(ticks, ticksOptions) {
  10814. var step = Math.ceil(core.tickIntervalCalculator.getTickInterval({
  10815. screenDelta: ticksOptions.screenDelta * 4,
  10816. businessDelta: ticks.length,
  10817. gridSpacingFactor: ticksOptions.gridSpacingFactor,
  10818. numberMultipliers: ticksOptions.numberMultipliers,
  10819. dataType: "numeric"
  10820. })) || ticks.length;
  10821. return this._getAutoArrangementTicks(ticks, ticksOptions, step)
  10822. },
  10823. needTickIntervalCalculation: function(businessDelta, tickInterval, incidentOccured) {
  10824. var date;
  10825. if (utils.isDefined(tickInterval)) {
  10826. if (!utils.isNumber(tickInterval)) {
  10827. date = new Date;
  10828. tickInterval = utils.addInterval(date, tickInterval) - date;
  10829. if (!tickInterval)
  10830. return true
  10831. }
  10832. if (utils.isNumber(tickInterval))
  10833. if (tickInterval > 0 && businessDelta / tickInterval > TICKS_COUNT_LIMIT) {
  10834. if (incidentOccured)
  10835. incidentOccured('W2003')
  10836. }
  10837. else
  10838. return false
  10839. }
  10840. return true
  10841. },
  10842. getTickIntervals: function(min, max, screenDelta, majorTicksOptions, minorTicksOptions, options) {
  10843. var that = this,
  10844. i,
  10845. options = options || {},
  10846. ticksInfo = {
  10847. majorTickInterval: majorTicksOptions.tickInterval,
  10848. minorTickInterval: minorTicksOptions.tickInterval,
  10849. majorTicks: []
  10850. };
  10851. majorTicksOptions.base = minorTicksOptions.base = options.base;
  10852. majorTicksOptions.axisType = minorTicksOptions.axisType = options.axisType;
  10853. majorTicksOptions.dataType = minorTicksOptions.dataType = options.dataType;
  10854. that._initializeMajorTicksOptions(min, max, screenDelta, ticksInfo, majorTicksOptions);
  10855. if (utils.isDefined(min) && utils.isDefined(max)) {
  10856. ticksInfo.majorTicks.push(min);
  10857. ticksInfo.majorTicks.push(that._nextTick(min, ticksInfo.majorTickInterval, {
  10858. min: min,
  10859. max: max,
  10860. setTicksAtUnitBeginning: majorTicksOptions.setTicksAtUnitBeginning,
  10861. dataType: options.dataType,
  10862. axisType: options.axisType,
  10863. base: options.base
  10864. }));
  10865. that._initializeMinorTicksOptions(min, max, screenDelta, ticksInfo, minorTicksOptions)
  10866. }
  10867. return ticksInfo
  10868. },
  10869. getFullTicks: function(min, max, screenDelta, majorTicksOptions, minorTicksOptions, options) {
  10870. var that = this,
  10871. i,
  10872. options = options || {},
  10873. ticksInfo = {
  10874. customBoundaryTicks: [],
  10875. fullTicks: [],
  10876. majorTickInterval: majorTicksOptions.tickInterval,
  10877. majorTicks: [],
  10878. minorTickInterval: minorTicksOptions.tickInterval,
  10879. minorTicks: []
  10880. };
  10881. majorTicksOptions.base = minorTicksOptions.base = options.base;
  10882. majorTicksOptions.axisType = minorTicksOptions.axisType = options.axisType;
  10883. majorTicksOptions.dataType = minorTicksOptions.dataType = options.dataType || that._getDataType(min);
  10884. that._initializeMajorTicksOptions(min, max, screenDelta, ticksInfo, majorTicksOptions);
  10885. ticksInfo.majorTicks = that.getTicks(majorTicksOptions);
  10886. if (utils.isDefined(min) && utils.isDefined(max) && ticksInfo.majorTicks.length > 0) {
  10887. if (ticksInfo.majorTicks.autoArrangementStep && ticksInfo.majorTicks.autoArrangementStep > 1 && !utils.isDefined(minorTicksOptions.tickInterval) && !utils.isDefined(minorTicksOptions.minorTickCount))
  10888. minorTicksOptions.tickInterval = ticksInfo.minorTickInterval = majorTicksOptions.tickInterval;
  10889. that._initializeMinorTicksOptions(min, max, screenDelta, ticksInfo, minorTicksOptions);
  10890. that._addLeftBoudedTicks(ticksInfo, min, minorTicksOptions);
  10891. for (i = 0; i < ticksInfo.majorTicks.length - 1; i++) {
  10892. ticksInfo.fullTicks.push(ticksInfo.majorTicks[i]);
  10893. that._addMinorTicks(ticksInfo.majorTicks[i], ticksInfo.majorTicks[i + 1], ticksInfo, minorTicksOptions)
  10894. }
  10895. that._addRightBoudedTicks(ticksInfo, max, minorTicksOptions)
  10896. }
  10897. return ticksInfo
  10898. },
  10899. getTicks: function(options) {
  10900. var that = this,
  10901. step,
  10902. maxDisplayValue,
  10903. ticks = options.customTicks ? options.customTicks : that._generateTicks(options);
  10904. if (options.useTicksAutoArrangement) {
  10905. options.maxDisplayValueSize = that._getValueSize(ticks, options);
  10906. step = that._getAutoArrangementStep(ticks, options);
  10907. if (step > 1) {
  10908. if (utils.isDefined(options.tickInterval) || utils.isDefined(options.customTicks)) {
  10909. utils.isDefined(options.customTicks) && (ticks.tickInterval = options.tickInterval);
  10910. ticks = that._getAutoArrangementTicks(ticks, options, step)
  10911. }
  10912. else
  10913. ticks = that._generateTicks($.extend({}, options, {gridSpacingFactor: options.maxDisplayValueSize}));
  10914. ticks.autoArrangementStep = step
  10915. }
  10916. that._removeInvalidDatesWithUnitBegining(ticks, options)
  10917. }
  10918. return ticks
  10919. }
  10920. }
  10921. })(jQuery, DevExpress);
  10922. /*! Module viz-core, file numericTranslator.js */
  10923. (function($, DX, undefined) {
  10924. var utils = DX.utils,
  10925. isDefined = utils.isDefined,
  10926. getPower = utils.getPower,
  10927. round = Math.round;
  10928. DX.viz.core.numericTranslatorFunctions = {
  10929. translate: function(bp) {
  10930. var that = this,
  10931. canvasOptions = that._canvasOptions,
  10932. doubleError = canvasOptions.rangeDoubleError,
  10933. specialValue = that.translateSpecialCase(bp);
  10934. if (isDefined(specialValue))
  10935. return specialValue;
  10936. if (isNaN(bp) || bp.valueOf() + doubleError < canvasOptions.rangeMin || bp.valueOf() - doubleError > canvasOptions.rangeMax)
  10937. return null;
  10938. return round(that._calculateProjection((bp - canvasOptions.rangeMinVisible) * canvasOptions.ratioOfCanvasRange))
  10939. },
  10940. untranslate: function(pos) {
  10941. var canvasOptions = this._canvasOptions,
  10942. startPoint = canvasOptions.startPoint;
  10943. if (pos < startPoint || pos > canvasOptions.endPoint)
  10944. return null;
  10945. return this._calculateUnProjection((pos - startPoint) / canvasOptions.ratioOfCanvasRange)
  10946. },
  10947. getInterval: function() {
  10948. return round(this._canvasOptions.ratioOfCanvasRange * (this._businessRange.interval || Math.abs(this._canvasOptions.rangeMax - this._canvasOptions.rangeMin)))
  10949. }
  10950. }
  10951. })(jQuery, DevExpress);
  10952. /*! Module viz-core, file datetimeTranslator.js */
  10953. (function($, DX, undefined) {
  10954. var core = DX.viz.core,
  10955. numericTranslator = core.numericTranslatorFunctions;
  10956. core.datetimeTranslatorFunctions = {
  10957. translate: numericTranslator.translate,
  10958. untranslate: function(pos) {
  10959. var result = numericTranslator.untranslate.call(this, pos);
  10960. return result === null ? result : new Date(result)
  10961. },
  10962. getInterval: numericTranslator.getInterval
  10963. }
  10964. })(jQuery, DevExpress);
  10965. /*! Module viz-core, file categoryTranslator.js */
  10966. (function($, DX, undefined) {
  10967. var isDefined = DX.utils.isDefined,
  10968. round = Math.round;
  10969. function doubleRound(value) {
  10970. return round(round(value * 10) / 10)
  10971. }
  10972. DX.viz.core.categoryTranslatorFunctions = {
  10973. translate: function(category) {
  10974. var that = this,
  10975. canvasOptions = that._canvasOptions,
  10976. categoryRecord = that._categoriesToPoints[category],
  10977. stickDelta,
  10978. specialValue = that.translateSpecialCase(category);
  10979. if (isDefined(specialValue))
  10980. return specialValue;
  10981. if (!categoryRecord)
  10982. return 0;
  10983. stickDelta = that._businessRange.stick ? categoryRecord.index : categoryRecord.index + 0.5;
  10984. return round(canvasOptions.startPoint + canvasOptions.interval * stickDelta)
  10985. },
  10986. untranslate: function(pos) {
  10987. var that = this,
  10988. canvasOptions = that._canvasOptions,
  10989. startPoint = canvasOptions.startPoint,
  10990. categoriesLength = that._categories.length,
  10991. result = 0;
  10992. if (pos < startPoint || pos > canvasOptions.endPoint)
  10993. return null;
  10994. result = doubleRound((pos - startPoint) / canvasOptions.interval + (that._businessRange.stick ? 0.5 : 0) - 0.5);
  10995. if (categoriesLength === result)
  10996. result--;
  10997. if (canvasOptions.invert)
  10998. result = categoriesLength - result - 1;
  10999. return that._categories[result]
  11000. },
  11001. getInterval: function() {
  11002. return this._canvasOptions.interval
  11003. }
  11004. }
  11005. })(jQuery, DevExpress);
  11006. /*! Module viz-core, file logarithmicTranslator.js */
  11007. (function($, DX, undefined) {
  11008. var core = DX.viz.core,
  11009. numericTranslator = core.numericTranslatorFunctions,
  11010. utils = DX.utils,
  11011. raiseTo = utils.raiseTo,
  11012. getLog = utils.getLog;
  11013. core.logarithmicTranslatorFunctions = {
  11014. translate: function(bp) {
  11015. var that = this,
  11016. specialValue = that.translateSpecialCase(bp);
  11017. if (utils.isDefined(specialValue))
  11018. return specialValue;
  11019. return numericTranslator.translate.call(that, getLog(bp, that._businessRange.base))
  11020. },
  11021. untranslate: function(pos) {
  11022. var result = numericTranslator.untranslate.call(this, pos);
  11023. return result === null ? result : raiseTo(result, this._businessRange.base)
  11024. },
  11025. getInterval: numericTranslator.getInterval
  11026. }
  11027. })(jQuery, DevExpress);
  11028. /*! Module viz-core, file translator1D.js */
  11029. (function(DX, undefined) {
  11030. var _Number = Number;
  11031. function Translator1D() {
  11032. this.setDomain(arguments[0], arguments[1]).setCodomain(arguments[2], arguments[3])
  11033. }
  11034. Translator1D.prototype = {
  11035. constructor: Translator1D,
  11036. setDomain: function(domain1, domain2) {
  11037. var that = this;
  11038. that._domain1 = _Number(domain1);
  11039. that._domain2 = _Number(domain2);
  11040. that._domainDelta = that._domain2 - that._domain1;
  11041. return that
  11042. },
  11043. setCodomain: function(codomain1, codomain2) {
  11044. var that = this;
  11045. that._codomain1 = _Number(codomain1);
  11046. that._codomain2 = _Number(codomain2);
  11047. that._codomainDelta = that._codomain2 - that._codomain1;
  11048. return that
  11049. },
  11050. getDomain: function() {
  11051. return [this._domain1, this._domain2]
  11052. },
  11053. getCodomain: function() {
  11054. return [this._codomain1, this._codomain2]
  11055. },
  11056. getDomainStart: function() {
  11057. return this._domain1
  11058. },
  11059. getDomainEnd: function() {
  11060. return this._domain2
  11061. },
  11062. getCodomainStart: function() {
  11063. return this._codomain1
  11064. },
  11065. getCodomainEnd: function() {
  11066. return this._codomain2
  11067. },
  11068. getDomainRange: function() {
  11069. return this._domainDelta
  11070. },
  11071. getCodomainRange: function() {
  11072. return this._codomainDelta
  11073. },
  11074. translate: function(value) {
  11075. var ratio = (_Number(value) - this._domain1) / this._domainDelta;
  11076. return 0 <= ratio && ratio <= 1 ? this._codomain1 + ratio * this._codomainDelta : NaN
  11077. },
  11078. adjust: function(value) {
  11079. var ratio = (_Number(value) - this._domain1) / this._domainDelta,
  11080. result = NaN;
  11081. if (ratio < 0)
  11082. result = this._domain1;
  11083. else if (ratio > 1)
  11084. result = this._domain2;
  11085. else if (0 <= ratio && ratio <= 1)
  11086. result = _Number(value);
  11087. return result
  11088. }
  11089. };
  11090. DX.viz.core.Translator1D = Translator1D
  11091. })(DevExpress);
  11092. /*! Module viz-core, file translator2D.js */
  11093. (function($, DX, undefined) {
  11094. var core = DX.viz.core,
  11095. utils = DX.utils,
  11096. getLog = utils.getLog,
  11097. getPower = utils.getPower,
  11098. raiseTo = utils.raiseTo,
  11099. isDefined = utils.isDefined,
  11100. CANVAS_PROP = ["width", "height", "left", "top", "bottom", "right"],
  11101. NUMBER_EQUALITY_CORRECTION = 1,
  11102. DATETIME_EQUALITY_CORRECTION = 60000;
  11103. var validateCanvas = function(canvas) {
  11104. $.each(CANVAS_PROP, function(_, prop) {
  11105. canvas[prop] = parseInt(canvas[prop]) || 0
  11106. });
  11107. return canvas
  11108. };
  11109. var raiseToFlooredLog = function(value, base, correction) {
  11110. return raiseTo(Math.floor(getLog(value, base)) + (correction || 0), base)
  11111. };
  11112. var makeCategoriesToPoints = function(categories, invert) {
  11113. var categoriesToPoints = {},
  11114. category,
  11115. length = categories.length,
  11116. i;
  11117. for (i = 0; i < length; i++) {
  11118. category = categories[i];
  11119. categoriesToPoints[category] = {
  11120. name: category,
  11121. index: invert ? length - 1 - i : i
  11122. }
  11123. }
  11124. return categoriesToPoints
  11125. };
  11126. var validateBusinessRange = function(businessRange) {
  11127. function validate(valueSelector, baseValueSeletor) {
  11128. if (!isDefined(businessRange[valueSelector]) && isDefined(businessRange[baseValueSeletor]))
  11129. businessRange[valueSelector] = businessRange[baseValueSeletor]
  11130. }
  11131. validate("minVisible", "min");
  11132. validate("maxVisible", "max");
  11133. return businessRange
  11134. };
  11135. core.Translator2D = function(businessRange, canvas, options) {
  11136. var that = this;
  11137. that._options = $.extend(that._options || {}, options);
  11138. that._canvas = validateCanvas(canvas);
  11139. that.updateBusinessRange(businessRange)
  11140. };
  11141. $.extend(core.Translator2D.prototype, {
  11142. reinit: function() {
  11143. var that = this,
  11144. range = that._businessRange,
  11145. categories = range.categories || [],
  11146. script = {},
  11147. canvasOptions = that._prepareCanvasOptions(),
  11148. interval,
  11149. correctedCategoriesCount;
  11150. switch (range.axisType) {
  11151. case"logarithmic":
  11152. script = core.logarithmicTranslatorFunctions;
  11153. break;
  11154. case"discrete":
  11155. script = core.categoryTranslatorFunctions;
  11156. that._categories = categories;
  11157. correctedCategoriesCount = categories.length - (range.stick ? 1 : 0);
  11158. if (correctedCategoriesCount > 0)
  11159. interval = canvasOptions.canvasLength / correctedCategoriesCount;
  11160. else
  11161. interval = canvasOptions.canvasLength;
  11162. canvasOptions.interval = interval;
  11163. that._categoriesToPoints = makeCategoriesToPoints(categories, canvasOptions.invert);
  11164. break;
  11165. default:
  11166. if (range.dataType === "datetime")
  11167. script = core.datetimeTranslatorFunctions;
  11168. else
  11169. script = core.numericTranslatorFunctions
  11170. }
  11171. that.translate = script.translate;
  11172. that.untranslate = script.untranslate;
  11173. that.getInterval = script.getInterval
  11174. },
  11175. _getCanvasBounds: function(range) {
  11176. var min = range.min,
  11177. max = range.max,
  11178. minVisible = range.minVisible,
  11179. maxVisible = range.maxVisible,
  11180. newMin,
  11181. newMax,
  11182. base = range.base,
  11183. isDateTime = utils.isDate(max) || utils.isDate(min),
  11184. correction = isDateTime ? DATETIME_EQUALITY_CORRECTION : NUMBER_EQUALITY_CORRECTION;
  11185. if (isDefined(min) && isDefined(max) && min.valueOf() === max.valueOf()) {
  11186. newMin = min.valueOf() - correction;
  11187. newMax = max.valueOf() + correction;
  11188. if (isDateTime) {
  11189. min = new Date(newMin);
  11190. max = new Date(newMax)
  11191. }
  11192. else {
  11193. min = min !== 0 ? newMin : 0;
  11194. max = newMax
  11195. }
  11196. }
  11197. if (isDefined(minVisible) && isDefined(maxVisible) && minVisible.valueOf() === maxVisible.valueOf()) {
  11198. newMin = minVisible.valueOf() - correction;
  11199. newMax = maxVisible.valueOf() + correction;
  11200. if (isDateTime) {
  11201. minVisible = newMin < min.valueOf() ? min : new Date(newMin);
  11202. maxVisible = newMax > max.valueOf() ? max : new Date(newMax)
  11203. }
  11204. else {
  11205. if (minVisible !== 0)
  11206. minVisible = newMin < min ? min : newMin;
  11207. maxVisible = newMax > max ? max : newMax
  11208. }
  11209. }
  11210. if (range.axisType === 'logarithmic') {
  11211. maxVisible = getLog(maxVisible, base);
  11212. minVisible = getLog(minVisible, base);
  11213. min = getLog(min, base);
  11214. max = getLog(max, base)
  11215. }
  11216. return {
  11217. base: base,
  11218. rangeMin: min,
  11219. rangeMax: max,
  11220. rangeMinVisible: minVisible,
  11221. rangeMaxVisible: maxVisible
  11222. }
  11223. },
  11224. _prepareCanvasOptions: function() {
  11225. var that = this,
  11226. rangeMin,
  11227. rangeMax,
  11228. rangeMinVisible,
  11229. rangeMaxVisible,
  11230. businessRange = that._businessRange,
  11231. canvasOptions = that._canvasOptions = that._getCanvasBounds(businessRange),
  11232. length;
  11233. if (that._options.direction === "horizontal") {
  11234. canvasOptions.startPoint = that._canvas.left;
  11235. length = that._canvas.width;
  11236. canvasOptions.endPoint = that._canvas.width - that._canvas.right;
  11237. canvasOptions.invert = businessRange.invert
  11238. }
  11239. else {
  11240. canvasOptions.startPoint = that._canvas.top;
  11241. length = that._canvas.height;
  11242. canvasOptions.endPoint = that._canvas.height - that._canvas.bottom;
  11243. canvasOptions.invert = !businessRange.invert
  11244. }
  11245. that.canvasLength = canvasOptions.canvasLength = canvasOptions.endPoint - canvasOptions.startPoint;
  11246. canvasOptions.rangeDoubleError = Math.pow(10, getPower(canvasOptions.rangeMax - canvasOptions.rangeMin) - getPower(length) - 2);
  11247. canvasOptions.ratioOfCanvasRange = canvasOptions.canvasLength / (canvasOptions.rangeMaxVisible - canvasOptions.rangeMinVisible);
  11248. return canvasOptions
  11249. },
  11250. updateBusinessRange: function(businessRange) {
  11251. this._businessRange = validateBusinessRange(businessRange);
  11252. this.reinit()
  11253. },
  11254. getBusinessRange: function() {
  11255. return this._businessRange
  11256. },
  11257. getCanvasVisibleArea: function() {
  11258. return {
  11259. min: this._canvasOptions.startPoint,
  11260. max: this._canvasOptions.endPoint
  11261. }
  11262. },
  11263. translateSpecialCase: function(value) {
  11264. var that = this,
  11265. canvasOptions = that._canvasOptions,
  11266. startPoint = canvasOptions.startPoint,
  11267. endPoint = canvasOptions.endPoint,
  11268. range = that._businessRange,
  11269. minVisible = range.minVisible,
  11270. maxVisible = range.maxVisible,
  11271. invert,
  11272. result = null;
  11273. switch (value) {
  11274. case"canvas_position_default":
  11275. if (minVisible <= 0 && maxVisible >= 0)
  11276. result = that.translate(0);
  11277. else {
  11278. invert = range.invert ^ (minVisible <= 0 && maxVisible <= 0);
  11279. if (that._options.direction === "horizontal")
  11280. result = invert ? endPoint : startPoint;
  11281. else
  11282. result = invert ? startPoint : endPoint
  11283. }
  11284. break;
  11285. case"canvas_position_left":
  11286. case"canvas_position_top":
  11287. result = startPoint;
  11288. break;
  11289. case"canvas_position_center":
  11290. case"canvas_position_middle":
  11291. result = startPoint + canvasOptions.canvasLength / 2;
  11292. break;
  11293. case"canvas_position_right":
  11294. case"canvas_position_bottom":
  11295. result = endPoint;
  11296. break;
  11297. case"canvas_position_start":
  11298. result = range.invert ? endPoint : startPoint;
  11299. break;
  11300. case"canvas_position_end":
  11301. result = range.invert ? startPoint : endPoint;
  11302. break
  11303. }
  11304. return result
  11305. },
  11306. _calculateProjection: function(distance) {
  11307. var canvasOptions = this._canvasOptions;
  11308. return canvasOptions.invert ? canvasOptions.endPoint - distance : canvasOptions.startPoint + distance
  11309. },
  11310. _calculateUnProjection: function(distance) {
  11311. var canvasOptions = this._canvasOptions;
  11312. return canvasOptions.invert ? canvasOptions.rangeMaxVisible.valueOf() - distance : canvasOptions.rangeMinVisible.valueOf() + distance
  11313. }
  11314. })
  11315. })(jQuery, DevExpress);
  11316. /*! Module viz-core, file rectangle.js */
  11317. (function(DX, undefined) {
  11318. var isFinite = window.isFinite;
  11319. DX.viz.core.Rectangle = DX.Class.inherit({
  11320. ctor: function(options) {
  11321. var that = this;
  11322. options = options || {};
  11323. that.left = Number(options.left) || 0;
  11324. that.right = Number(options.right) || 0;
  11325. that.top = Number(options.top) || 0;
  11326. that.bottom = Number(options.bottom) || 0
  11327. },
  11328. width: function() {
  11329. return this.right - this.left
  11330. },
  11331. height: function() {
  11332. return this.bottom - this.top
  11333. },
  11334. horizontalMiddle: function() {
  11335. return (this.left + this.right) / 2
  11336. },
  11337. verticalMiddle: function() {
  11338. return (this.top + this.bottom) / 2
  11339. },
  11340. raw: function() {
  11341. var that = this;
  11342. return {
  11343. left: that.left,
  11344. top: that.top,
  11345. right: that.right,
  11346. bottom: that.bottom
  11347. }
  11348. },
  11349. clone: function() {
  11350. return new this.constructor(this.raw())
  11351. },
  11352. move: function(dx, dy) {
  11353. var result = this.clone();
  11354. if (isFinite(dx) && isFinite(dy)) {
  11355. result.left += Number(dx);
  11356. result.right += Number(dx);
  11357. result.top += Number(dy);
  11358. result.bottom += Number(dy)
  11359. }
  11360. return result
  11361. },
  11362. inflate: function(dx, dy) {
  11363. var result = this.clone();
  11364. if (isFinite(dx) && isFinite(dy)) {
  11365. result.left -= Number(dx);
  11366. result.right += Number(dx);
  11367. result.top -= Number(dy);
  11368. result.bottom += Number(dy)
  11369. }
  11370. return result
  11371. },
  11372. scale: function(factor) {
  11373. var that = this;
  11374. if (factor > 0)
  11375. return that.inflate(that.width() * (factor - 1) / 2, that.height() * (factor - 1) / 2);
  11376. return that.clone()
  11377. }
  11378. })
  11379. })(DevExpress);
  11380. /*! Module viz-core, file themes.js */
  11381. (function($, DX, undefined) {
  11382. var viz = DX.viz,
  11383. core = viz.core;
  11384. var currentThemeId = 0;
  11385. var findThemeId = function(themeName) {
  11386. var themeId,
  11387. themes = viz.themes;
  11388. for (themeId = 0; themeId < themes.length; themeId++)
  11389. if (themes[themeId].name === themeName)
  11390. return themeId;
  11391. return -1
  11392. };
  11393. core.findTheme = function(themeName) {
  11394. var themeId = findThemeId(themeName),
  11395. themes = viz.themes;
  11396. if (themeId < 0)
  11397. themeId = currentThemeId;
  11398. return themes[themeId]
  11399. };
  11400. core.currentTheme = function(themeName, colorScheme, version) {
  11401. var themeId = -1,
  11402. themes = viz.themes;
  11403. if (themeName === undefined)
  11404. return themes[currentThemeId].name;
  11405. else {
  11406. if (version && colorScheme)
  11407. themeId = findThemeId(themeName + ':' + version + '-' + colorScheme);
  11408. if (themeId < 0 && version)
  11409. themeId = findThemeId(themeName + ':' + version);
  11410. if (colorScheme && themeId < 0)
  11411. themeId = findThemeId(themeName + '-' + colorScheme);
  11412. if (themeId < 0)
  11413. themeId = findThemeId(themeName);
  11414. currentThemeId = themeId >= 0 ? themeId : 0
  11415. }
  11416. };
  11417. core.registerTheme = function(theme, basedOnThemeName) {
  11418. var baseTheme,
  11419. extendedTheme,
  11420. themes = viz.themes;
  11421. if (!theme || !theme.name || !core.findTheme(theme.name))
  11422. return;
  11423. baseTheme = core.findTheme(basedOnThemeName);
  11424. if (baseTheme) {
  11425. extendedTheme = $.extend(true, {}, baseTheme, theme);
  11426. themes.push(extendedTheme)
  11427. }
  11428. else
  11429. themes.push(theme)
  11430. }
  11431. })(jQuery, DevExpress);
  11432. /*! Module viz-core, file palette.js */
  11433. (function(DX, $, undefined) {
  11434. var _String = window.String,
  11435. _Color = DX.Color,
  11436. _isArray = DX.utils.isArray,
  11437. _isString = DX.utils.isString,
  11438. _extend = $.extend;
  11439. var palettes = {
  11440. 'default': {
  11441. simpleSet: ['#5f8b95', '#ba4d51', '#af8a53', '#955f71', '#859666', '#7e688c'],
  11442. indicatingSet: ['#a3b97c', '#e1b676', '#ec7f83'],
  11443. gradientSet: ['#5f8b95', '#ba4d51']
  11444. },
  11445. 'harmony light': {
  11446. simpleSet: ['#fcb65e', '#679ec5', '#ad79ce', '#7abd5c', '#e18e92', '#b6d623', '#b7abea', '#85dbd5'],
  11447. indicatingSet: ['#b6d623', '#fcb65e', '#e18e92'],
  11448. gradientSet: ['#7abd5c', '#fcb65e']
  11449. },
  11450. 'soft pastel': {
  11451. simpleSet: ['#60a69f', '#78b6d9', '#6682bb', '#a37182', '#eeba69', '#90ba58', '#456c68', '#7565a4'],
  11452. indicatingSet: ['#90ba58', '#eeba69', '#a37182'],
  11453. gradientSet: ['#78b6d9', '#eeba69']
  11454. },
  11455. pastel: {
  11456. simpleSet: ['#bb7862', '#70b3a1', '#bb626a', '#057d85', '#ab394b', '#dac599', '#153459', '#b1d2c6'],
  11457. indicatingSet: ['#70b3a1', '#dac599', '#bb626a'],
  11458. gradientSet: ['#bb7862', '#70b3a1']
  11459. },
  11460. bright: {
  11461. simpleSet: ['#70c92f', '#f8ca00', '#bd1550', '#e97f02', '#9d419c', '#7e4452', '#9ab57e', '#36a3a6'],
  11462. indicatingSet: ['#70c92f', '#f8ca00', '#bd1550'],
  11463. gradientSet: ['#e97f02', '#f8ca00']
  11464. },
  11465. soft: {
  11466. simpleSet: ['#cbc87b', '#9ab57e', '#e55253', '#7e4452', '#e8c267', '#565077', '#6babac', '#ad6082'],
  11467. indicatingSet: ['#9ab57e', '#e8c267', '#e55253'],
  11468. gradientSet: ['#9ab57e', '#e8c267']
  11469. },
  11470. ocean: {
  11471. simpleSet: ['#75c099', '#acc371', '#378a8a', '#5fa26a', '#064970', '#38c5d2', '#00a7c6', '#6f84bb'],
  11472. indicatingSet: ['#c8e394', '#7bc59d', '#397c8b'],
  11473. gradientSet: ['#acc371', '#38c5d2']
  11474. },
  11475. vintage: {
  11476. simpleSet: ['#dea484', '#efc59c', '#cb715e', '#eb9692', '#a85c4c', '#f2c0b5', '#c96374', '#dd956c'],
  11477. indicatingSet: ['#ffe5c6', '#f4bb9d', '#e57660'],
  11478. gradientSet: ['#efc59c', '#cb715e']
  11479. },
  11480. violet: {
  11481. simpleSet: ['#d1a1d1', '#eeacc5', '#7b5685', '#7e7cad', '#a13d73', '#5b41ab', '#e287e2', '#689cc1'],
  11482. indicatingSet: ['#d8e2f6', '#d0b2da', '#d56a8a'],
  11483. gradientSet: ['#eeacc5', '#7b5685']
  11484. }
  11485. };
  11486. var currentPaletteName = 'default';
  11487. function currentPalette(name) {
  11488. if (name === undefined)
  11489. return currentPaletteName;
  11490. else {
  11491. name = String(name).toLowerCase();
  11492. currentPaletteName = name in palettes ? name : 'default'
  11493. }
  11494. }
  11495. function getPalette(palette, parameters) {
  11496. var result;
  11497. if (_isArray(palette))
  11498. result = palette;
  11499. else {
  11500. parameters = parameters || {};
  11501. var type = parameters.type || 'simpleSet';
  11502. if (_isString(palette)) {
  11503. var name = palette.toLowerCase(),
  11504. baseContainer = palettes[name],
  11505. themedContainer = parameters.theme && palettes[name + '_' + _String(parameters.theme).toLowerCase()];
  11506. result = themedContainer && themedContainer[type] || baseContainer && baseContainer[type]
  11507. }
  11508. if (!result)
  11509. result = palettes[currentPaletteName][type]
  11510. }
  11511. return result ? result.slice(0) : null
  11512. }
  11513. function registerPalette(name, palette, theme) {
  11514. var item = {};
  11515. if (_isArray(palette))
  11516. item.simpleSet = palette.slice(0);
  11517. else if (palette) {
  11518. item.simpleSet = _isArray(palette.simpleSet) ? palette.simpleSet.slice(0) : undefined;
  11519. item.indicatingSet = _isArray(palette.indicatingSet) ? palette.indicatingSet.slice(0) : undefined;
  11520. item.gradientSet = _isArray(palette.gradientSet) ? palette.gradientSet.slice(0) : undefined
  11521. }
  11522. if (item.simpleSet || item.indicatingSet || item.gradientSet) {
  11523. var paletteName = _String(name).toLowerCase();
  11524. if (theme)
  11525. paletteName = paletteName + '_' + _String(theme).toLowerCase();
  11526. _extend(palettes[paletteName] = palettes[paletteName] || {}, item)
  11527. }
  11528. }
  11529. function RingBuf(buf) {
  11530. var ind = 0;
  11531. this.next = function() {
  11532. var res = buf[ind++];
  11533. if (ind == buf.length)
  11534. this.reset();
  11535. return res
  11536. };
  11537. this.reset = function() {
  11538. ind = 0
  11539. }
  11540. }
  11541. function Palette(palette, parameters) {
  11542. parameters = parameters || {};
  11543. this._originalPalette = getPalette(palette, parameters);
  11544. var stepHighlight = parameters ? parameters.stepHighlight || 0 : 0;
  11545. this._paletteSteps = new RingBuf([0, stepHighlight, -stepHighlight]);
  11546. this._resetPalette()
  11547. }
  11548. _extend(Palette.prototype, {
  11549. dispose: function() {
  11550. this._originalPalette = this._palette = this._paletteSteps = null;
  11551. return this
  11552. },
  11553. getNextColor: function() {
  11554. var that = this;
  11555. if (that._currentColor >= that._palette.length)
  11556. that._resetPalette();
  11557. return that._palette[that._currentColor++]
  11558. },
  11559. _resetPalette: function() {
  11560. var that = this;
  11561. that._currentColor = 0;
  11562. var step = that._paletteSteps.next(),
  11563. originalPalette = that._originalPalette;
  11564. if (step) {
  11565. var palette = that._palette = [],
  11566. i = 0,
  11567. ii = originalPalette.length;
  11568. for (; i < ii; ++i)
  11569. palette[i] = getNewColor(originalPalette[i], step)
  11570. }
  11571. else
  11572. that._palette = originalPalette.slice(0)
  11573. },
  11574. reset: function() {
  11575. this._paletteSteps.reset();
  11576. this._resetPalette();
  11577. return this
  11578. }
  11579. });
  11580. function getNewColor(currentColor, step) {
  11581. var newColor = new _Color(currentColor).alter(step),
  11582. lightness = getLightness(newColor);
  11583. if (lightness > 200 || lightness < 55)
  11584. newColor = new _Color(currentColor).alter(-step / 2);
  11585. return newColor.toHex()
  11586. }
  11587. function getLightness(color) {
  11588. return color.r * 0.3 + color.g * 0.59 + color.b * 0.11
  11589. }
  11590. function GradientPalette(source, size) {
  11591. var palette = getPalette(source, {type: 'gradientSet'});
  11592. palette = size > 0 ? createGradientColors(palette[0], palette[1], size) : [];
  11593. this.getColor = function(index) {
  11594. return palette[index] || null
  11595. };
  11596. this._DEBUG_source = source;
  11597. this._DEBUG_size = size
  11598. }
  11599. function createGradientColors(start, end, count) {
  11600. var startColor = new _Color(start),
  11601. endColor = new _Color(end);
  11602. if (count === 1)
  11603. return [startColor.blend(endColor, 0.5).toHex()];
  11604. else {
  11605. var list = [],
  11606. step = 1 / (count - 1),
  11607. i,
  11608. ii = count;
  11609. list.push(0);
  11610. for (i = 1; i < ii - 1; ++i)
  11611. list.push(step * i);
  11612. list.push(1);
  11613. for (i = 0; i < ii; ++i)
  11614. list[i] = startColor.blend(endColor, list[i]).toHex();
  11615. return list
  11616. }
  11617. }
  11618. _extend(DX.viz.core, {
  11619. registerPalette: registerPalette,
  11620. getPalette: getPalette,
  11621. Palette: Palette,
  11622. GradientPalette: GradientPalette,
  11623. currentPalette: currentPalette
  11624. });
  11625. DX.viz.core._DEBUG_palettes = palettes
  11626. })(DevExpress, jQuery);
  11627. /*! Module viz-core, file baseThemeManager.js */
  11628. (function(DX, $, undefined) {
  11629. var _isString = DX.utils.isString,
  11630. _findTheme = DX.viz.core.findTheme,
  11631. _extend = $.extend,
  11632. _each = $.each;
  11633. DX.viz.core.BaseThemeManager = DX.Class.inherit({
  11634. dispose: function() {
  11635. this._theme = this._font = null;
  11636. return this
  11637. },
  11638. setTheme: function(theme) {
  11639. theme = theme || {};
  11640. var that = this,
  11641. themeObj = _findTheme(_isString(theme) ? theme : theme.name);
  11642. that._themeName = themeObj.name;
  11643. that._font = _extend({}, themeObj.font, theme.font);
  11644. that._themeSection && _each(that._themeSection.split('.'), function(_, path) {
  11645. themeObj = _extend(true, {}, themeObj[path], that._IE8 ? themeObj[path + 'IE8'] : {})
  11646. });
  11647. that._theme = _extend(true, {}, themeObj, _isString(theme) ? {} : theme);
  11648. that._initializeTheme();
  11649. return that
  11650. },
  11651. theme: function() {
  11652. return this._theme
  11653. },
  11654. themeName: function() {
  11655. return this._themeName
  11656. },
  11657. _initializeTheme: function(){},
  11658. _initializeFont: function(font) {
  11659. _extend(font, this._font, _extend({}, font))
  11660. }
  11661. })
  11662. })(DevExpress, jQuery);
  11663. /*! Module viz-core, file textCloud.js */
  11664. (function(DX, undefined) {
  11665. var min = Math.min;
  11666. DX.viz.core.TextCloud = DX.Class.inherit(function() {
  11667. var DEFAULT_OPTIONS = {
  11668. horMargin: 8,
  11669. verMargin: 4,
  11670. tailLength: 10
  11671. };
  11672. var COEFFICIENTS_MAP = {};
  11673. COEFFICIENTS_MAP['right-bottom'] = COEFFICIENTS_MAP['rb'] = [0, -1, -1, 0, 0, 1, 1, 0];
  11674. COEFFICIENTS_MAP['bottom-right'] = COEFFICIENTS_MAP['br'] = [-1, 0, 0, -1, 1, 0, 0, 1];
  11675. COEFFICIENTS_MAP['left-bottom'] = COEFFICIENTS_MAP['lb'] = [0, -1, 1, 0, 0, 1, -1, 0];
  11676. COEFFICIENTS_MAP['bottom-left'] = COEFFICIENTS_MAP['bl'] = [1, 0, 0, -1, -1, 0, 0, 1];
  11677. COEFFICIENTS_MAP['left-top'] = COEFFICIENTS_MAP['lt'] = [0, 1, 1, 0, 0, -1, -1, 0];
  11678. COEFFICIENTS_MAP['top-left'] = COEFFICIENTS_MAP['tl'] = [1, 0, 0, 1, -1, 0, 0, -1];
  11679. COEFFICIENTS_MAP['right-top'] = COEFFICIENTS_MAP['rt'] = [0, 1, -1, 0, 0, -1, 1, 0];
  11680. COEFFICIENTS_MAP['top-right'] = COEFFICIENTS_MAP['tr'] = [-1, 0, 0, 1, 1, 0, 0, -1];
  11681. return {
  11682. setup: function(options) {
  11683. var that = this,
  11684. ops = $.extend({}, DEFAULT_OPTIONS, options),
  11685. x = ops.x,
  11686. y = ops.y,
  11687. type = COEFFICIENTS_MAP[ops.type],
  11688. cloudWidth = ops.textWidth + 2 * ops.horMargin,
  11689. cloudHeight = ops.textHeight + 2 * ops.verMargin,
  11690. tailWidth = ops.tailLength,
  11691. tailHeight = tailWidth,
  11692. cx = x,
  11693. cy = y;
  11694. if (type[0] & 1)
  11695. tailHeight = min(tailHeight, cloudHeight / 3);
  11696. else
  11697. tailWidth = min(tailWidth, cloudWidth / 3);
  11698. 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)];
  11699. that._cx = cx + type[0] * tailWidth + (type[0] + type[2]) * cloudWidth / 2;
  11700. that._cy = cy + type[1] * tailHeight + (type[1] + type[3]) * cloudHeight / 2;
  11701. that._cloudWidth = cloudWidth;
  11702. that._cloudHeight = cloudHeight;
  11703. that._tailLength = ops.tailLength;
  11704. return that
  11705. },
  11706. points: function() {
  11707. return this._points.slice(0)
  11708. },
  11709. cx: function() {
  11710. return this._cx
  11711. },
  11712. cy: function() {
  11713. return this._cy
  11714. },
  11715. width: function() {
  11716. return this._cloudWidth
  11717. },
  11718. height: function() {
  11719. return this._cloudHeight
  11720. },
  11721. tailLength: function() {
  11722. return this._tailLength
  11723. }
  11724. }
  11725. }())
  11726. })(DevExpress);
  11727. /*! Module viz-core, file parseUtils.js */
  11728. (function($, DX) {
  11729. var viz = DX.viz,
  11730. core = viz.core,
  11731. Class = DX.Class,
  11732. isDefined = DX.utils.isDefined;
  11733. var parseUtils = Class.inherit({
  11734. ctor: function(options) {
  11735. options = options || {};
  11736. this._incidentOccured = $.isFunction(options.incidentOccured) ? options.incidentOccured : $.noop
  11737. },
  11738. correctValueType: function(type) {
  11739. return type === 'numeric' || type === 'datetime' || type === 'string' ? type : ''
  11740. },
  11741. _parsers: {
  11742. string: function(val) {
  11743. return isDefined(val) ? '' + val : val
  11744. },
  11745. numeric: function(val) {
  11746. if (!isDefined(val))
  11747. return val;
  11748. var parsedVal = Number(val);
  11749. if (isNaN(parsedVal))
  11750. parsedVal = undefined;
  11751. return parsedVal
  11752. },
  11753. datetime: function(val) {
  11754. if (!isDefined(val))
  11755. return val;
  11756. var parsedVal,
  11757. numVal = Number(val);
  11758. if (!isNaN(numVal))
  11759. parsedVal = new Date(numVal);
  11760. else
  11761. parsedVal = new Date(val);
  11762. if (isNaN(Number(parsedVal)))
  11763. parsedVal = undefined;
  11764. return parsedVal
  11765. }
  11766. },
  11767. getParser: function(valueType, entity) {
  11768. var that = this,
  11769. parser,
  11770. message = 'valueType is unknown.';
  11771. if (entity)
  11772. message = 'The type specified as the "valueType" field of the ' + entity + ' configuration object is unknown.';
  11773. valueType = that.correctValueType(valueType);
  11774. parser = that._parsers[valueType];
  11775. if (!parser)
  11776. this._incidentOccured.call(null, message);
  11777. return parser || $.noop
  11778. }
  11779. });
  11780. core.ParseUtils = parseUtils
  11781. })(jQuery, DevExpress);
  11782. /*! Module viz-core, file utils.js */
  11783. (function($, DX) {
  11784. var core = DX.viz.core,
  11785. math = Math;
  11786. core.utils = {decreaseGaps: function(object, keys, decrease) {
  11787. var arrayGaps,
  11788. eachDecrease,
  11789. middleValue;
  11790. do {
  11791. arrayGaps = $.map(keys, function(key) {
  11792. return object[key] ? object[key] : null
  11793. });
  11794. middleValue = math.ceil(decrease / arrayGaps.length);
  11795. arrayGaps.push(middleValue);
  11796. eachDecrease = math.min.apply(null, arrayGaps);
  11797. $.each(keys, function(_, key) {
  11798. if (object[key]) {
  11799. object[key] -= eachDecrease;
  11800. decrease -= eachDecrease
  11801. }
  11802. })
  11803. } while (decrease > 0 && arrayGaps.length > 1);
  11804. return decrease
  11805. }}
  11806. })(jQuery, DevExpress);
  11807. /*! Module viz-core, file loadIndicator.js */
  11808. (function($, DX) {
  11809. var viz = DX.viz,
  11810. core = viz.core,
  11811. ANIMATION_SETTINGS = {
  11812. easing: 'linear',
  11813. duration: 150
  11814. },
  11815. INVISIBLE_POINT = {
  11816. x: -10000,
  11817. y: -10000
  11818. };
  11819. var applySettings = function(element, settings, animate, complete) {
  11820. var prevAnimation = element.animation;
  11821. if (prevAnimation) {
  11822. prevAnimation.options.complete = null;
  11823. prevAnimation.stop()
  11824. }
  11825. if (animate)
  11826. element.animate(settings, {complete: complete});
  11827. else {
  11828. element.applySettings(settings);
  11829. complete && complete()
  11830. }
  11831. };
  11832. core.LoadIndicator = DX.Class.inherit({
  11833. ctor: function(options, widgetContainer) {
  11834. var that = this;
  11835. that._$widgetContainer = $(widgetContainer);
  11836. that._$container = $('<div>', {css: {
  11837. position: 'relative',
  11838. height: 0,
  11839. padding: 0,
  11840. margin: 0,
  11841. border: 0
  11842. }}).appendTo(that._$widgetContainer);
  11843. that._updateContainer();
  11844. that.applyOptions(options);
  11845. that._endLoadingCompleteHandler = function() {
  11846. that._endLoad = false;
  11847. that._externalComplete && that._externalComplete();
  11848. that._externalComplete = null;
  11849. that._onCompleteAction && that[that._onCompleteAction]();
  11850. that._onCompleteAction = null
  11851. };
  11852. that._$container.hide()
  11853. },
  11854. _updateRenderer: function(width, height, top) {
  11855. if (this._renderer)
  11856. this._renderer.recreateCanvas(width, height);
  11857. else if (this._$container.get(0)) {
  11858. this._renderer = new viz.renderers.Renderer({
  11859. width: width,
  11860. height: height,
  11861. animation: ANIMATION_SETTINGS
  11862. });
  11863. this._renderer.draw(this._$container[0])
  11864. }
  11865. this._renderer && this._renderer.getRoot().applySettings({style: {
  11866. position: 'absolute',
  11867. top: top,
  11868. left: 0
  11869. }});
  11870. return this._renderer
  11871. },
  11872. applyOptions: function(options, width, height) {
  11873. var pane = this._pane;
  11874. if (pane && options) {
  11875. pane.rect.applySettings({fill: options.backgroundColor});
  11876. pane.text.applySettings({
  11877. font: options.font,
  11878. text: options.text
  11879. })
  11880. }
  11881. if (this.isShown && (width || height))
  11882. this._updateContainer(width, height)
  11883. },
  11884. _draw: function() {
  11885. var pane,
  11886. renderer = this._renderer;
  11887. if (renderer) {
  11888. pane = this._pane = {};
  11889. pane.rect = renderer.createRect(0, 0, 0, 0, 0, {opacity: 0}).append();
  11890. pane.text = renderer.createText('', 0, 0, {
  11891. align: 'center',
  11892. translateX: INVISIBLE_POINT.x,
  11893. translateY: INVISIBLE_POINT.y
  11894. }).append()
  11895. }
  11896. },
  11897. _updateContainer: function(width, height) {
  11898. var that = this,
  11899. $widgetContainer = that._$widgetContainer,
  11900. canvasTop;
  11901. width = width || $widgetContainer.width();
  11902. height = height || $widgetContainer.height();
  11903. if ($widgetContainer.get(0))
  11904. canvasTop = $widgetContainer.offset().top - that._$container.offset().top;
  11905. else
  11906. canvasTop = -height;
  11907. that._updateRenderer(width, height, canvasTop);
  11908. if (!that._pane)
  11909. that._draw();
  11910. else {
  11911. that._pane.rect.applySettings({
  11912. width: width,
  11913. height: height
  11914. });
  11915. that._pane.text.move(width / 2, height / 2)
  11916. }
  11917. },
  11918. dispose: function() {
  11919. this._$widgetContainer = null;
  11920. this._$container.remove().detach();
  11921. this._$container = null;
  11922. this._renderer.dispose();
  11923. this._renderer = null;
  11924. this._pane = null
  11925. },
  11926. toForeground: function() {
  11927. this._$container.appendTo(this._$widgetContainer)
  11928. },
  11929. show: function(width, height) {
  11930. if (this._endLoad) {
  11931. this._onCompleteAction = 'show';
  11932. return
  11933. }
  11934. this._$container.show();
  11935. this._updateContainer(width, height);
  11936. applySettings(this._pane.rect, {opacity: 0.85}, true);
  11937. this.isShown = true
  11938. },
  11939. endLoading: function(complete, disableAnimation) {
  11940. this._externalComplete = complete;
  11941. if (this._endLoad)
  11942. return;
  11943. if (this.isShown) {
  11944. this._endLoad = true;
  11945. applySettings(this._pane.rect, {opacity: 1}, !disableAnimation, this._endLoadingCompleteHandler)
  11946. }
  11947. else
  11948. complete && complete()
  11949. },
  11950. hide: function() {
  11951. var that = this;
  11952. if (this._endLoad) {
  11953. this._onCompleteAction = 'hide';
  11954. return
  11955. }
  11956. if (this.isShown) {
  11957. this._pane.text.move(INVISIBLE_POINT.x, INVISIBLE_POINT.y);
  11958. applySettings(that._pane.rect, {opacity: 0}, true, function() {
  11959. that._$container.hide()
  11960. });
  11961. this.isShown = false
  11962. }
  11963. }
  11964. })
  11965. })(jQuery, DevExpress);
  11966. /*! Module viz-core, file tooltip.js */
  11967. (function($, DX, undefined) {
  11968. var ARROW_WIDTH = 20,
  11969. MAX_SHADOW_SIZE = 10,
  11970. formatHelper = DX.formatHelper,
  11971. X_INTERVAL = 15,
  11972. _max = Math.max,
  11973. _round = Math.round,
  11974. _isFunction = DX.utils.isFunction,
  11975. _isDefined = DX.utils.isDefined,
  11976. _extend = $.extend,
  11977. FORMAT_PRECISION = {
  11978. argument: ['argumentFormat', 'argumentPrecision'],
  11979. percent: ['percent', 'percentPrecision'],
  11980. value: ['format', 'precision']
  11981. },
  11982. VISIBLE = {visibility: 'visible'},
  11983. HIDDEN = {visibility: 'hidden'},
  11984. LEFT = 'left',
  11985. RIGHT = 'right';
  11986. DX.viz.core.Tooltip = DX.Class.inherit({
  11987. ctor: function(options, group, renderer) {
  11988. this._state = {};
  11989. this._options = {};
  11990. this._renderer = renderer;
  11991. this._group = group;
  11992. this._cloud = renderer.createArea();
  11993. this._textGroup = renderer.createGroup();
  11994. if (!$.isEmptyObject(options))
  11995. this.update(options);
  11996. this._createTextContent()
  11997. },
  11998. dispose: function() {
  11999. this._shadow.dispose();
  12000. this._shadow = null;
  12001. this._cloud = null;
  12002. this._text = null;
  12003. this._group = null;
  12004. this._options = null;
  12005. this._renderer = null;
  12006. this._tooltipTextArray = null;
  12007. this._textGroup = null;
  12008. return this
  12009. },
  12010. update: function(options) {
  12011. options = options || {};
  12012. var that = this,
  12013. group = that._group,
  12014. shadowOptions = options.shadow || {},
  12015. shadow = that._shadow = that._shadow || that._renderer.createFilter('shadow').applySettings({
  12016. width: '200%',
  12017. height: '200%',
  12018. color: shadowOptions.color,
  12019. opacity: shadowOptions.opacity,
  12020. dx: shadowOptions.offsetX,
  12021. dy: shadowOptions.offsetY,
  12022. blur: shadowOptions.blur,
  12023. x: '-50%',
  12024. y: '-50%'
  12025. }),
  12026. borderSettings = options.border,
  12027. shapeSettings = _extend({
  12028. opacity: options.opacity,
  12029. filter: shadow.append().ref
  12030. }, borderSettings && borderSettings.visible ? {
  12031. strokeWidth: borderSettings.width,
  12032. stroke: borderSettings.color,
  12033. strokeOpacity: borderSettings.opacity,
  12034. dashStyle: borderSettings.dashStyle
  12035. } : {
  12036. strokeWidth: null,
  12037. stroke: null
  12038. }),
  12039. textSettings = _extend({}, {
  12040. align: 'center',
  12041. font: options.font
  12042. }, options.text);
  12043. that._options = options;
  12044. that.setSize(options.canvasWidth, options.canvasHeight);
  12045. that._customizeTooltip = _isFunction(options.customizeTooltip) ? options.customizeTooltip : null;
  12046. if (!that._customizeTooltip && _isFunction(options.customizeText))
  12047. that._customizeTooltip = function() {
  12048. return {text: options.customizeText.apply(this, arguments)}
  12049. };
  12050. that._cloud.applySettings(shapeSettings).append(group);
  12051. that._text && options.font && that._text.applySettings({font: {size: options.font.size}});
  12052. that._textGroup.applySettings(textSettings).append(group);
  12053. that.hide();
  12054. return that
  12055. },
  12056. formatValue: function(value, specialFormat) {
  12057. var formatObj = FORMAT_PRECISION[specialFormat || 'value'],
  12058. format = formatObj[0] in this._options ? this._options[formatObj[0]] : specialFormat;
  12059. return formatHelper.format(value, format, this._options[formatObj[1]] || 0)
  12060. },
  12061. prepare: function(formatObject, params, defaultTextValueField) {
  12062. this._state = this._state || {};
  12063. defaultTextValueField = defaultTextValueField || 'valueText';
  12064. var defaultText = formatObject[defaultTextValueField] || '';
  12065. _extend(this._state, params);
  12066. if (this._customizeTooltip) {
  12067. var customize = this._customizeTooltip.call(formatObject, formatObject);
  12068. customize = $.isPlainObject(customize) ? customize : {};
  12069. if ('text' in customize)
  12070. this._state.text = _isDefined(customize.text) ? String(customize.text) : '';
  12071. else {
  12072. if ($.isArray(defaultText)) {
  12073. this._options._justify = true;
  12074. this._createTextContent();
  12075. defaultText = defaultText.join('<br/>')
  12076. }
  12077. this._state.text = defaultText
  12078. }
  12079. this._state.color = customize.color || this._options.color
  12080. }
  12081. else {
  12082. this._state.text = defaultText;
  12083. this._state.color = this._options.color
  12084. }
  12085. if (this._options._justify)
  12086. this._state.text = this._state.text.split('<br/>');
  12087. if (this._state.visibility == VISIBLE && !!this._state.text)
  12088. this.show();
  12089. return !!this._state.text
  12090. },
  12091. enabled: function() {
  12092. return !!this._options.enabled
  12093. },
  12094. formatColorTooltip: function(that) {
  12095. return that._customizeTooltip && that._customizeTooltip.call(this, this)
  12096. },
  12097. _getData: function() {
  12098. var that = this,
  12099. x = that._state.x,
  12100. y = that._state.y,
  12101. xt = x,
  12102. yt = y,
  12103. align = 'center',
  12104. points = [],
  12105. bbox = that._state.textBBox,
  12106. options = that._options,
  12107. paddingLeftRight = options.paddingLeftRight,
  12108. paddingTopBottom = options.paddingTopBottom,
  12109. arrowLength = options.arrowLength > 0 ? options.arrowLength : 0,
  12110. horPosition = options.cloudHorizontalPosition,
  12111. verPosition = options.cloudVerticalPosition,
  12112. isHorPositionDefined = horPosition !== undefined && horPosition !== null,
  12113. isVerPositionDefined = verPosition !== undefined && verPosition !== null,
  12114. cloudWidth = bbox.width + paddingLeftRight * 2,
  12115. cloudHeight = bbox.height + paddingTopBottom * 2,
  12116. updatedText;
  12117. updatedText = that._checkWidthText(cloudWidth, cloudHeight);
  12118. if (updatedText) {
  12119. that._state.textBBox = bbox = updatedText.bbox;
  12120. cloudWidth = updatedText.cloudWidth;
  12121. cloudHeight = updatedText.cloudHeight;
  12122. paddingLeftRight = updatedText.paddingLeftRight;
  12123. paddingTopBottom = updatedText.paddingTopBottom
  12124. }
  12125. if (isHorPositionDefined ? horPosition === RIGHT : cloudWidth / 2 > x) {
  12126. points = that._setArrowLeft(cloudWidth, cloudHeight, arrowLength, x, y);
  12127. align = LEFT;
  12128. xt += paddingLeftRight
  12129. }
  12130. else if (isHorPositionDefined ? horPosition === LEFT : x + cloudWidth / 2 > that._canvasWidth) {
  12131. points = that._setArrowRight(cloudWidth, cloudHeight, arrowLength, x, y);
  12132. align = RIGHT;
  12133. xt -= paddingLeftRight
  12134. }
  12135. else
  12136. points = that._setArrowCenter(cloudWidth, cloudHeight, arrowLength, x, y);
  12137. if (isVerPositionDefined ? verPosition === 'top' : cloudHeight + arrowLength < y) {
  12138. yt -= arrowLength + cloudHeight / 2 - bbox.height / 2 + that._state.offset;
  12139. that.tooltipInverted = false
  12140. }
  12141. else {
  12142. yt += arrowLength + cloudHeight / 2 + bbox.height / 2 + that._state.offset;
  12143. that.tooltipInverted = true
  12144. }
  12145. yt = that._correctYTextContent(yt);
  12146. return {
  12147. points: points,
  12148. text: {
  12149. x: xt,
  12150. y: yt,
  12151. align: align
  12152. }
  12153. }
  12154. },
  12155. _updateTextContent: function() {
  12156. if (this._options._justify) {
  12157. this._textGroup.clear();
  12158. this._calculateTextContent();
  12159. this._locateTextContent(0, 0, 'center')
  12160. }
  12161. else
  12162. this._text.updateText(this._state.text);
  12163. this._state.textBBox = this._textGroup.getBBox()
  12164. },
  12165. _correctYTextContent: function(y) {
  12166. var bbox;
  12167. if (this._options._justify) {
  12168. this._locateTextContent(0, y, 'center');
  12169. bbox = this._textGroup.getBBox()
  12170. }
  12171. else {
  12172. this._text.applySettings({y: y});
  12173. bbox = this._text.getBBox()
  12174. }
  12175. return y - (bbox.y + bbox.height - y)
  12176. },
  12177. _adjustTextContent: function(data) {
  12178. if (this._options._justify)
  12179. this._locateTextContent(data.text.x, data.text.y, data.text.align);
  12180. else
  12181. this._text.applySettings({
  12182. x: data.text.x,
  12183. y: data.text.y,
  12184. align: data.text.align
  12185. })
  12186. },
  12187. _updateTooltip: function() {
  12188. var that = this,
  12189. box,
  12190. data,
  12191. scale;
  12192. data = that._getData();
  12193. that._cloud.applySettings({
  12194. points: data.points,
  12195. fill: that._state.color,
  12196. 'class': that._state.className
  12197. });
  12198. that._adjustTextContent(data);
  12199. box = that._group.getBBox();
  12200. if (box.y + box.height > that._canvasHeight) {
  12201. scale = (that._canvasHeight - box.y) / box.height;
  12202. that._group.applySettings({
  12203. scale: scale,
  12204. translateX: that._state.x * (1 - scale),
  12205. translateY: that._state.y * (1 - scale)
  12206. })
  12207. }
  12208. else
  12209. that._group.applySettings({
  12210. scale: 1,
  12211. translateX: 0,
  12212. translateY: 0
  12213. })
  12214. },
  12215. _createTextContent: function() {
  12216. var that = this,
  12217. options = that._options,
  12218. fontSize;
  12219. that._textGroup.clear();
  12220. that._text = null;
  12221. if (!options._justify) {
  12222. fontSize = options.font && options.font.size;
  12223. that._text = that._renderer.createText(undefined, 0, 0, {font: {size: fontSize}}).append(that._textGroup)
  12224. }
  12225. },
  12226. _getTextContentParams: function() {
  12227. var that = this,
  12228. i,
  12229. text,
  12230. textBBox,
  12231. textArray = that._state.text,
  12232. textArrayLength = textArray.length,
  12233. textParams = {
  12234. width: [],
  12235. height: []
  12236. };
  12237. that._tooltipTextArray = [];
  12238. for (i = 0; i < textArrayLength; i++) {
  12239. text = that._renderer.createText(textArray[i], 0, 0, {}).append(this._textGroup);
  12240. that._tooltipTextArray.push(text);
  12241. textBBox = text.getBBox();
  12242. textParams.width.push(textBBox.width)
  12243. }
  12244. that._lineHeight = -2 * textBBox.y - textBBox.height;
  12245. return textParams
  12246. },
  12247. _locateTextContent: function(x, y, alignment) {
  12248. var that = this,
  12249. tooltipTextArray = that._tooltipTextArray,
  12250. textWidth = that._textContentWidth,
  12251. lineSpacing = that._options.lineSpacing,
  12252. yDelta = (lineSpacing > 0 ? lineSpacing : 0) + that._lineHeight,
  12253. leftXCoord,
  12254. rightXCoord,
  12255. i,
  12256. rtl = that._options._rtl;
  12257. if (alignment === LEFT)
  12258. leftXCoord = x;
  12259. else if (alignment === RIGHT)
  12260. leftXCoord = x - textWidth;
  12261. else
  12262. leftXCoord = _round(x - textWidth / 2);
  12263. rightXCoord = leftXCoord + textWidth;
  12264. for (i = tooltipTextArray.length - 1; i >= 0; i -= 2) {
  12265. tooltipTextArray[i].applySettings({
  12266. x: !rtl ? rightXCoord : leftXCoord,
  12267. y: y,
  12268. align: !rtl ? RIGHT : LEFT
  12269. });
  12270. if (tooltipTextArray[i - 1])
  12271. tooltipTextArray[i - 1].applySettings({
  12272. x: !rtl ? leftXCoord : rightXCoord,
  12273. y: y,
  12274. align: !rtl ? LEFT : RIGHT
  12275. });
  12276. y -= yDelta
  12277. }
  12278. },
  12279. _calculateTextContent: function() {
  12280. var that = this,
  12281. textArray = that._state.text,
  12282. textArrayLength = textArray.length,
  12283. textParams,
  12284. width,
  12285. stringWidthArray = [],
  12286. i;
  12287. textParams = that._getTextContentParams();
  12288. for (i = 0; i < textArrayLength; i += 2) {
  12289. if (textParams.width[i + 1])
  12290. width = textParams.width[i] + X_INTERVAL + textParams.width[i + 1];
  12291. else
  12292. width = textParams.width[i];
  12293. stringWidthArray.push(width)
  12294. }
  12295. that._textContentWidth = _max.apply(null, stringWidthArray)
  12296. },
  12297. setSize: function(width, height) {
  12298. this._canvasWidth = _isDefined(width) ? width : this._canvasWidth;
  12299. this._canvasHeight = _isDefined(height) ? height : this._canvasHeight;
  12300. return this
  12301. },
  12302. getBBox: function() {
  12303. var that = this,
  12304. options = that._options,
  12305. paddingLeftRight = options.paddingLeftRight || 0,
  12306. paddingTopBottom = options.paddingTopBottom || 0,
  12307. borderWidth = options.border.visible && options.border.width || 0,
  12308. tooltipBBox = that._textGroup.getBBox();
  12309. return tooltipBBox.isEmpty ? tooltipBBox : {
  12310. x: tooltipBBox.x - paddingLeftRight - borderWidth / 2 - MAX_SHADOW_SIZE,
  12311. y: tooltipBBox.y - paddingTopBottom - borderWidth / 2 - MAX_SHADOW_SIZE,
  12312. height: tooltipBBox.height + 2 * paddingTopBottom + borderWidth + MAX_SHADOW_SIZE * 2,
  12313. width: tooltipBBox.width + 2 * paddingLeftRight + borderWidth + MAX_SHADOW_SIZE * 2,
  12314. isEmpty: false
  12315. }
  12316. },
  12317. show: function() {
  12318. this._state.visibility = VISIBLE;
  12319. this._updateTextContent();
  12320. this.move(this._state.x, this._state.y, this._state.offset);
  12321. this._cloud.applySettings(VISIBLE);
  12322. this._textGroup.applySettings(VISIBLE);
  12323. return this
  12324. },
  12325. hide: function() {
  12326. this._state.visibility = HIDDEN;
  12327. this._cloud.applySettings(HIDDEN);
  12328. this._textGroup.applySettings(HIDDEN);
  12329. return this
  12330. },
  12331. move: function(x, y, offset) {
  12332. this._state.x = _isDefined(x) ? x : this._state.x || 0;
  12333. this._state.y = _isDefined(y) ? y : this._state.y || 0;
  12334. this._state.offset = _isDefined(offset) ? offset : this._state.offset || 0;
  12335. this._updateTooltip();
  12336. return this
  12337. },
  12338. _setArrowCenter: function(cloudWidth, cloudHeight, arrowLength, x, y) {
  12339. var that = this,
  12340. position = that._options.cloudVerticalPosition,
  12341. isPosDefined = position !== undefined && position !== null,
  12342. verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
  12343. x0 = x,
  12344. y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
  12345. x1 = x0 + ARROW_WIDTH / 2,
  12346. y1 = verticalInvert ? y0 + arrowLength : y0 - arrowLength,
  12347. x2 = x1 + cloudWidth / 2 - ARROW_WIDTH / 2,
  12348. y2 = y1,
  12349. x3 = x2,
  12350. y3 = verticalInvert ? y2 + cloudHeight : y2 - cloudHeight,
  12351. x4 = x3 - cloudWidth,
  12352. y4 = y3,
  12353. x5 = x4,
  12354. y5 = verticalInvert ? y4 - cloudHeight : y4 + cloudHeight,
  12355. x6 = x5 + cloudWidth / 2 - ARROW_WIDTH / 2,
  12356. y6 = y5;
  12357. return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5, x6, y6]
  12358. },
  12359. _setArrowLeft: function(cloudWidth, cloudHeight, arrowLength, x, y) {
  12360. var that = this,
  12361. position = that._options.cloudVerticalPosition,
  12362. isPosDefined = position !== undefined && position !== null,
  12363. verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
  12364. x0 = x,
  12365. y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
  12366. x1 = x0 + ARROW_WIDTH,
  12367. y1 = verticalInvert ? y0 + arrowLength : y0 - arrowLength,
  12368. x2 = x1 + cloudWidth - ARROW_WIDTH,
  12369. y2 = y1,
  12370. x3 = x2,
  12371. y3 = verticalInvert ? y2 + cloudHeight : y2 - cloudHeight,
  12372. x4 = x3 - cloudWidth,
  12373. y4 = y3,
  12374. x5 = x4,
  12375. y5 = verticalInvert ? y4 - cloudHeight - arrowLength : y4 + cloudHeight + arrowLength;
  12376. return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5]
  12377. },
  12378. _setArrowRight: function(cloudWidth, cloudHeight, arrowLength, x, y) {
  12379. var that = this,
  12380. position = that._options.cloudVerticalPosition,
  12381. isPosDefined = position !== undefined && position !== null,
  12382. verticalInvert = !(isPosDefined ? position === 'top' : cloudHeight + arrowLength < y),
  12383. x0 = x,
  12384. y0 = verticalInvert ? y + that._state.offset : y - that._state.offset,
  12385. x1 = x0,
  12386. y1 = verticalInvert ? y0 + arrowLength + cloudHeight : y0 - arrowLength - cloudHeight,
  12387. x2 = x1 - cloudWidth,
  12388. y2 = y1,
  12389. x3 = x2,
  12390. y3 = verticalInvert ? y2 - cloudHeight : y2 + cloudHeight,
  12391. x4 = x3 + cloudWidth - ARROW_WIDTH,
  12392. y4 = y3,
  12393. x5 = x4 + ARROW_WIDTH,
  12394. y5 = verticalInvert ? y4 - arrowLength : y4 + arrowLength;
  12395. return [x0, y0, x1, y1, x2, y2, x3, y3, x4, y4, x5, y5]
  12396. },
  12397. _checkWidthText: function(cloudWidth, cloudHeight) {
  12398. if (this._options._justify)
  12399. return;
  12400. var x = this._state.x,
  12401. text = this._state.text,
  12402. index,
  12403. paddingLeftRight = this._options.paddingLeftRight,
  12404. paddingTopBottom = this._options.paddingTopBottom,
  12405. textLength,
  12406. maxTooltipWidth,
  12407. remainLength,
  12408. newIndex,
  12409. bbox = this._state.textBBox;
  12410. if (cloudWidth < x || x + cloudWidth < this._canvasWidth || cloudWidth / 2 < x && x + cloudWidth / 2 < this._canvasWidth)
  12411. return false;
  12412. if (text.indexOf("<br/>") === -1 && text.indexOf(" ") !== -1) {
  12413. maxTooltipWidth = _max(x, this._canvasWidth - x, 2 * Math.min(x, this._canvasWidth - x));
  12414. textLength = text.length * maxTooltipWidth / bbox.width;
  12415. index = text.substr(0, ~~textLength).lastIndexOf(" ");
  12416. if (index === -1)
  12417. index = text.substr(0).indexOf(" ");
  12418. remainLength = text.substr(index + 1).length;
  12419. this._state.text = text.substr(0, index) + "<br/>";
  12420. while (textLength <= remainLength) {
  12421. newIndex = text.substr(index + 1, ~~textLength).lastIndexOf(" ");
  12422. if (newIndex === -1)
  12423. newIndex = text.substr(index + 1).indexOf(" ");
  12424. if (newIndex !== -1) {
  12425. this._state.text += text.substr(index + 1, newIndex) + "<br/>";
  12426. remainLength = text.substr(index + 1 + newIndex).length;
  12427. index += newIndex + 1
  12428. }
  12429. else
  12430. break
  12431. }
  12432. this._state.text += text.substr(index + 1);
  12433. this._text.updateText(this._state.text);
  12434. bbox = this._text.getBBox();
  12435. cloudWidth = bbox.width + paddingLeftRight * 2;
  12436. cloudHeight = bbox.height + paddingTopBottom * 2
  12437. }
  12438. if (cloudWidth > x && x + cloudWidth > this._canvasWidth && (cloudWidth / 2 > x || x + cloudWidth / 2 > this._canvasWidth)) {
  12439. paddingLeftRight = 5;
  12440. paddingTopBottom = 5;
  12441. cloudWidth = bbox.width + 2 * paddingLeftRight;
  12442. cloudHeight = bbox.height + 2 * paddingTopBottom
  12443. }
  12444. return {
  12445. bbox: bbox,
  12446. cloudWidth: cloudWidth,
  12447. cloudHeight: cloudHeight,
  12448. paddingTopBottom: paddingTopBottom,
  12449. paddingLeftRight: paddingLeftRight
  12450. }
  12451. }
  12452. })
  12453. })(jQuery, DevExpress);
  12454. /*! Module viz-core, file legend.js */
  12455. (function(DX, $, undefined) {
  12456. var DEFAULT_MARGIN = 10,
  12457. _math = Math,
  12458. _round = _math.round,
  12459. _ceil = _math.ceil,
  12460. _floor = _math.floor,
  12461. CENTER = 'center',
  12462. RIGHT = 'right',
  12463. LEFT = 'left',
  12464. TOP = 'top',
  12465. BOTTOM = 'bottom',
  12466. HORIZONTAL = 'horizontal',
  12467. VERTICAL = 'vertical',
  12468. INSIDE = 'inside',
  12469. OUTSIDE = 'outside',
  12470. NONE = 'none',
  12471. decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
  12472. DEFAULT_MARKER_HATCHING_WIDTH = 2,
  12473. DEFAULT_MARKER_HATCHING_STEP = 5;
  12474. function getPatternId(renderer, states, action, color) {
  12475. if (!states)
  12476. return;
  12477. var direction = states[action].hatching.direction,
  12478. hatching,
  12479. colorFromAction = states[action].fill;
  12480. color = colorFromAction === NONE ? color : colorFromAction;
  12481. direction = !direction || direction === NONE ? RIGHT : direction;
  12482. hatching = $.extend({}, states[action].hatching, {
  12483. direction: direction,
  12484. step: DEFAULT_MARKER_HATCHING_STEP,
  12485. width: DEFAULT_MARKER_HATCHING_WIDTH
  12486. });
  12487. return renderer.createPattern(color, hatching).append().id
  12488. }
  12489. function getMaxBBox(groups) {
  12490. var maxWidth = 0,
  12491. maxHeight = 0,
  12492. bbox;
  12493. $.each(groups, function(_, group) {
  12494. bbox = group.getBBox();
  12495. if (bbox.width > maxWidth)
  12496. maxWidth = bbox.width;
  12497. if (bbox.height > maxHeight)
  12498. maxHeight = bbox.height
  12499. });
  12500. return {
  12501. width: maxWidth,
  12502. height: maxHeight
  12503. }
  12504. }
  12505. DX.viz.core.Legend = DX.Class.inherit({
  12506. ctor: function(data, options, renderer, group) {
  12507. var that = this;
  12508. that._renderer = renderer;
  12509. that._legendGroup = group;
  12510. that._markersPatternsIds = [];
  12511. that._data = data;
  12512. that._init(options)
  12513. },
  12514. _init: function(options) {
  12515. if (!options)
  12516. return;
  12517. var debug = DX.utils.debug;
  12518. debug.assertParam(options.visible, 'Visibility was not passed');
  12519. debug.assertParam(options.markerSize, 'markerSize was not passed');
  12520. debug.assertParam(options.font.color, 'fontColor was not passed');
  12521. debug.assertParam(options.font.family, 'fontFamily was not passed');
  12522. debug.assertParam(options.font.size, 'fontSize was not passed');
  12523. debug.assertParam(options.paddingLeftRight, 'paddingLeftRight was not passed');
  12524. debug.assertParam(options.paddingTopBottom, 'paddingTopBottom was not passed');
  12525. debug.assertParam(options.columnItemSpacing, 'columnItemSpacing was not passed');
  12526. debug.assertParam(options.rowItemSpacing, 'rowItemSpacing was not passed');
  12527. debug.assertParam(options.equalColumnWidth, 'equalColumnWidth was not passed');
  12528. var that = this,
  12529. i;
  12530. that._parseMargins(options);
  12531. that._parseAlignments(options);
  12532. options.orientation = (options.orientation || '').toLowerCase();
  12533. if (options.orientation !== VERTICAL && options.orientation !== HORIZONTAL) {
  12534. if (options.horizontalAlignment === CENTER)
  12535. options.orientation = HORIZONTAL;
  12536. if (options.horizontalAlignment === RIGHT || options.horizontalAlignment === LEFT)
  12537. options.orientation = VERTICAL
  12538. }
  12539. if (!options.itemTextPosition)
  12540. options.itemTextPosition = options.orientation === HORIZONTAL ? BOTTOM : RIGHT;
  12541. else
  12542. options.itemTextPosition = options.itemTextPosition;
  12543. options.position = (options.position || '').toLowerCase();
  12544. if (options.position !== OUTSIDE && options.position !== INSIDE)
  12545. options.position = OUTSIDE;
  12546. options.hoverMode = (options.hoverMode || '').toLowerCase();
  12547. options.customizeText = $.isFunction(options.customizeText) ? options.customizeText : function() {
  12548. return this.seriesName
  12549. };
  12550. that._options = options;
  12551. !that._trackerGroup && (that._trackerGroup = that._renderer.createGroup({
  12552. 'class': 'dxc-legend-trackers',
  12553. stroke: NONE,
  12554. fill: 'grey',
  12555. opacity: 0.0001
  12556. }));
  12557. that.__initialized = true
  12558. },
  12559. _parseMargins: function(options) {
  12560. if (options.margin >= 0) {
  12561. options.margin = Number(options.margin);
  12562. options.margin = {
  12563. top: options.margin,
  12564. bottom: options.margin,
  12565. left: options.margin,
  12566. right: options.margin
  12567. }
  12568. }
  12569. else
  12570. options.margin = {
  12571. top: options.margin.top >= 0 ? Number(options.margin.top) : DEFAULT_MARGIN,
  12572. bottom: options.margin.bottom >= 0 ? Number(options.margin.bottom) : DEFAULT_MARGIN,
  12573. left: options.margin.left >= 0 ? Number(options.margin.left) : DEFAULT_MARGIN,
  12574. right: options.margin.right >= 0 ? Number(options.margin.right) : DEFAULT_MARGIN
  12575. }
  12576. },
  12577. _parseAlignments: function(options) {
  12578. options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();
  12579. if (options.horizontalAlignment !== CENTER && options.horizontalAlignment !== RIGHT && options.horizontalAlignment !== LEFT)
  12580. options.horizontalAlignment = RIGHT;
  12581. options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();
  12582. if (options.verticalAlignment !== TOP && options.verticalAlignment !== BOTTOM) {
  12583. if (options.horizontalAlignment === CENTER)
  12584. options.verticalAlignment = BOTTOM;
  12585. if (options.horizontalAlignment === RIGHT || options.horizontalAlignment === LEFT)
  12586. options.verticalAlignment = TOP
  12587. }
  12588. },
  12589. update: function(data, options) {
  12590. this._data = data;
  12591. this.boundingRect = {
  12592. width: 0,
  12593. height: 0,
  12594. x: 0,
  12595. y: 0
  12596. };
  12597. this._init(options);
  12598. return this
  12599. },
  12600. setSize: function(size) {
  12601. this._size = size;
  12602. return this
  12603. },
  12604. draw: function() {
  12605. if (!this._options)
  12606. return this;
  12607. var that = this,
  12608. renderer = that._renderer,
  12609. options = that._options,
  12610. items = that._data,
  12611. itemsLength = items.length,
  12612. seriesGroups = [],
  12613. i,
  12614. label,
  12615. marker,
  12616. singleSeriesGroup,
  12617. trackers = [],
  12618. insideLegendGroup,
  12619. markersId = new Array(itemsLength),
  12620. passedId,
  12621. border = options.border,
  12622. borderVisible = border.visible && border.width && border.color && border.color !== NONE,
  12623. markers = new Array(itemsLength);
  12624. if (!(options.visible && items && itemsLength)) {
  12625. that._disposeTrackers();
  12626. return that
  12627. }
  12628. that._cleanLegendGroups();
  12629. insideLegendGroup = that._insideLegendGroup = renderer.createGroup().append(that._legendGroup);
  12630. that._createBackground(borderVisible);
  12631. for (i = 0; i < itemsLength; i++) {
  12632. singleSeriesGroup = renderer.createGroup({'class': 'dxc-item'}).append(insideLegendGroup);
  12633. marker = that._createMarker(items[i], singleSeriesGroup, i);
  12634. passedId = items[i].id;
  12635. label = that._createLabel(items[i], passedId, singleSeriesGroup);
  12636. markersId[i] = passedId;
  12637. that._locateLabelAndMarker(label, marker);
  12638. markers[i] = marker;
  12639. trackers.push({
  12640. rect: renderer.createRect(0, 0, 0, 0, 0, {
  12641. stroke: NONE,
  12642. fill: 'grey',
  12643. opacity: 0.0001,
  12644. inh: true
  12645. }),
  12646. id: passedId
  12647. });
  12648. seriesGroups.push(singleSeriesGroup)
  12649. }
  12650. that._seriesGroups = seriesGroups;
  12651. that._trackers = trackers;
  12652. that.drawTrackers();
  12653. that._markers = markers;
  12654. that._markersId = markersId;
  12655. that._locateElements(options);
  12656. return that
  12657. },
  12658. _locateElements: function(options) {
  12659. var that = this,
  12660. border = options.border,
  12661. borderVisible = border.visible && border.width && border.color && border.color !== NONE;
  12662. that._moveInInitialValues();
  12663. that._locateRowsColumns(that._seriesGroups, that._trackers, that._data.length, that._background, options);
  12664. if (that._background)
  12665. that._adjustBackgroundSettings(that._background, borderVisible, options);
  12666. that._setBoundingRect(options)
  12667. },
  12668. _moveInInitialValues: function() {
  12669. var that = this;
  12670. that._legendGroup && that._legendGroup.move(0, 0);
  12671. that._trackerGroup && that._trackerGroup.move(0, 0);
  12672. that._background && that._background.applySettings({
  12673. x: 0,
  12674. y: 0,
  12675. width: 0,
  12676. height: 0
  12677. })
  12678. },
  12679. _applyMarkerOptions: function(marker, options) {
  12680. if (marker)
  12681. marker.applySettings(options)
  12682. },
  12683. applySelected: function(id) {
  12684. var index = this._getIndexById(id);
  12685. if (index !== null)
  12686. this._applyMarkerOptions(this._markers[index], {fill: this._markersPatternsIds[index].selectedPatternId});
  12687. return this
  12688. },
  12689. applyHover: function(id) {
  12690. var index = this._getIndexById(id);
  12691. if (index !== null)
  12692. this._applyMarkerOptions(this._markers[index], {fill: this._markersPatternsIds[index].hoverPatternId});
  12693. return this
  12694. },
  12695. resetItem: function(id) {
  12696. var index = this._getIndexById(id);
  12697. if (index !== null)
  12698. this._applyMarkerOptions(this._markers[index], {fill: this._data[index].color || this._data[index].states.normal.fill})
  12699. },
  12700. _getIndexById: function(id) {
  12701. var i,
  12702. markersId = this._markersId,
  12703. markersIdLen = markersId.length;
  12704. for (i = 0; i < markersIdLen; i++)
  12705. if (markersId[i] === id)
  12706. return i;
  12707. return null
  12708. },
  12709. drawTrackers: function() {
  12710. if (!this._options.visible || !this._insideLegendGroup)
  12711. return;
  12712. var that = this,
  12713. trackerGroup = that._trackerGroup.append(that._legendGroup);
  12714. $.each(that._trackers || [], function(i, tracker) {
  12715. var trackerRect = tracker.rect;
  12716. trackerRect.data({
  12717. itemIndex: tracker.id,
  12718. mode: that._options.hoverMode
  12719. });
  12720. trackerRect.append(trackerGroup)
  12721. });
  12722. return that
  12723. },
  12724. _disposeTrackers: function() {
  12725. var that = this;
  12726. $.each(that._trackers || [], function(_, tracker) {
  12727. tracker.rect.removeData()
  12728. });
  12729. that._trackers = null
  12730. },
  12731. _createMarker: function(data, group, markerIndex) {
  12732. var that = this,
  12733. renderer = that._renderer,
  12734. markersPatternsIds = that._markersPatternsIds,
  12735. size = that._options.markerSize,
  12736. states = data.states,
  12737. marker;
  12738. marker = renderer.createRect(0, 0, size, size, 0, {fill: data.color}).append(group);
  12739. markersPatternsIds[markerIndex] = {
  12740. hoverPatternId: getPatternId(renderer, states, 'hover', data.color),
  12741. selectedPatternId: getPatternId(renderer, states, 'selection', data.color)
  12742. };
  12743. return marker
  12744. },
  12745. _createLabel: function(data, index, group) {
  12746. var that = this,
  12747. options = that._options,
  12748. position = options.itemTextPosition,
  12749. align = position === TOP || position === BOTTOM ? CENTER : LEFT,
  12750. text,
  12751. label,
  12752. labelFormatObject = {
  12753. seriesName: data.text,
  12754. seriesNumber: index,
  12755. seriesColor: data.color
  12756. };
  12757. text = that._formatLabel.call(labelFormatObject, options);
  12758. label = that._renderer.createText(text, 0, 0, {
  12759. font: options.font,
  12760. align: align
  12761. }).append(group);
  12762. return label
  12763. },
  12764. _cleanLegendGroups: function() {
  12765. var that = this,
  12766. trackerGroup = that._trackerGroup,
  12767. legendGroup = that._legendGroup;
  12768. if (legendGroup) {
  12769. legendGroup.clear();
  12770. that._insideLegendGroup && that._insideLegendGroup.dispose();
  12771. that._insideLegendGroup = null
  12772. }
  12773. if (trackerGroup)
  12774. trackerGroup.clear()
  12775. },
  12776. _createBackground: function(borderVisible) {
  12777. var that = this,
  12778. options = that._options,
  12779. isInside = options.position === INSIDE,
  12780. color = options.backgroundColor,
  12781. fill = color || (isInside ? options.containerBackgroundColor : NONE);
  12782. if (isInside || color || borderVisible)
  12783. that._background = that._renderer.createRect(0, 0, 0, 0, 0, {
  12784. fill: fill,
  12785. 'class': 'dxc-border'
  12786. }).append(that._insideLegendGroup)
  12787. },
  12788. _formatLabel: function(options) {
  12789. return options.customizeText.call(this, this)
  12790. },
  12791. _locateLabelAndMarker: function(label, marker) {
  12792. var that = this,
  12793. defaultXMargin = 7,
  12794. defaultTopMargin = 4,
  12795. defaultBottomMargin = 2,
  12796. labelX = 0,
  12797. labelY = 0,
  12798. markerX,
  12799. markerY,
  12800. labelBox = label.getBBox(),
  12801. markerWidth = that._options.markerSize,
  12802. markerHeight = markerWidth,
  12803. approximateLabelY = markerHeight / 2 - (labelBox.y + labelBox.height / 2),
  12804. approximateLabelX = markerWidth / 2 - (labelBox.x + labelBox.width / 2);
  12805. switch (that._options.itemTextPosition) {
  12806. case LEFT:
  12807. labelY = _round(approximateLabelY);
  12808. markerX = labelBox.width + defaultXMargin;
  12809. break;
  12810. case RIGHT:
  12811. labelX = markerWidth + defaultXMargin;
  12812. labelY = _round(approximateLabelY);
  12813. break;
  12814. case TOP:
  12815. labelX = _round(approximateLabelX);
  12816. markerY = defaultTopMargin;
  12817. break;
  12818. case BOTTOM:
  12819. labelX = _round(approximateLabelX);
  12820. labelY = markerHeight + defaultBottomMargin - labelBox.y;
  12821. break
  12822. }
  12823. label.applySettings({
  12824. x: labelX,
  12825. y: labelY
  12826. });
  12827. marker.applySettings({
  12828. x: markerX,
  12829. y: markerY
  12830. })
  12831. },
  12832. _locateRowsColumns: function(groups, trackers, count, background, options) {
  12833. var that = this,
  12834. itemTextPosition = options.itemTextPosition,
  12835. size = that._size,
  12836. legendBox,
  12837. rowsColumns = that._getRowsColumns(count),
  12838. rows = rowsColumns.rows,
  12839. columns = rowsColumns.columns,
  12840. margin = options.margin,
  12841. paddingLeftRight = background ? options.paddingLeftRight : 0,
  12842. paddingTopBottom = background ? options.paddingTopBottom : 0,
  12843. placeholderWidth = size.width - margin.left - margin.right - 2 * paddingLeftRight,
  12844. placeholderHeight = size.height - margin.top - margin.bottom - 2 * paddingTopBottom,
  12845. rowsColumnsData,
  12846. condition,
  12847. maxBBox = getMaxBBox(groups);
  12848. var moveRowsColumns = function(rows, columns) {
  12849. rowsColumnsData = that._getDataRowsColumns(groups, columns, rows);
  12850. that._moveItems(rowsColumnsData, groups, itemTextPosition, trackers, options)
  12851. };
  12852. moveRowsColumns(rows, columns);
  12853. legendBox = that._insideLegendGroup ? that._insideLegendGroup.getBBox() : {};
  12854. if (rowsColumns.autoEdit)
  12855. if (rows === 1) {
  12856. if (legendBox.width > placeholderWidth && columns > 1) {
  12857. columns = _floor(placeholderWidth / (maxBBox.width + options.columnItemSpacing)) || 1;
  12858. columns = validate(columns, count);
  12859. rows = _ceil(count / columns);
  12860. moveRowsColumns(rows, columns)
  12861. }
  12862. }
  12863. else if (columns === 1)
  12864. if (legendBox.height > placeholderHeight && rows > 1) {
  12865. rows = _floor(placeholderHeight / (maxBBox.height + options.rowItemSpacing)) || 1;
  12866. rows = validate(rows, count);
  12867. columns = _ceil(count / rows);
  12868. moveRowsColumns(rows, columns)
  12869. }
  12870. that._rowsCountDrawed = rows;
  12871. that._columnsCountDrawed = columns;
  12872. function validate(rowsOrColumns, count) {
  12873. if (rowsOrColumns > count || rowsOrColumns < 1)
  12874. rowsOrColumns = count;
  12875. return rowsOrColumns
  12876. }
  12877. },
  12878. _moveItems: function(data, seriesGroups, horizontalTextPosition, trackers, options) {
  12879. var that = this,
  12880. i,
  12881. j,
  12882. rows,
  12883. cols,
  12884. number,
  12885. group,
  12886. box,
  12887. xShift = 0,
  12888. yShift = 0,
  12889. widthColumn,
  12890. xPadding = options.columnItemSpacing,
  12891. yPadding = options.rowItemSpacing,
  12892. equalColumnWidth = options.equalColumnWidth,
  12893. renderer = that._renderer,
  12894. maxWidthPerColumn = [],
  12895. maxWidthColumn = 0,
  12896. maxHeightRow = 0;
  12897. rows = data.rows;
  12898. cols = data.cols;
  12899. maxHeightRow = data.maxHeightRow;
  12900. maxWidthColumn = data.maxWidthColumn;
  12901. maxWidthPerColumn = data.maxWidthPerColumn;
  12902. for (i = 0; i < rows; i++) {
  12903. for (j = 0; j < cols; j++) {
  12904. if (rows < cols)
  12905. number = i * cols + j;
  12906. else
  12907. number = i + j * rows;
  12908. group = seriesGroups[number];
  12909. if (!group)
  12910. break;
  12911. box = group.getBBox();
  12912. widthColumn = !equalColumnWidth ? maxWidthPerColumn[j] : maxWidthColumn;
  12913. if (horizontalTextPosition === RIGHT) {
  12914. group.move(xShift - box.x, yShift);
  12915. trackers[number].rect.applySettings({
  12916. x: xShift - xPadding / 2,
  12917. y: yShift + box.y - yPadding / 2,
  12918. height: maxHeightRow + yPadding,
  12919. width: widthColumn + xPadding
  12920. })
  12921. }
  12922. else if (horizontalTextPosition === LEFT) {
  12923. group.move(box.x + widthColumn - box.width + xShift - xPadding / 2, yShift);
  12924. trackers[number].rect.applySettings({
  12925. x: box.x + widthColumn - box.width + xShift - xPadding / 2,
  12926. y: yShift + box.y - yPadding / 2,
  12927. height: maxHeightRow + yPadding,
  12928. width: widthColumn + xPadding
  12929. })
  12930. }
  12931. else {
  12932. group.move(xShift - box.x - box.width / 2 + widthColumn / 2, yShift);
  12933. trackers[number].rect.applySettings({
  12934. x: xShift - xPadding / 2,
  12935. y: yShift + box.y - yPadding / 2,
  12936. height: maxHeightRow + yPadding,
  12937. width: widthColumn + xPadding
  12938. })
  12939. }
  12940. xShift = xShift + widthColumn + xPadding
  12941. }
  12942. yShift = yShift + maxHeightRow + yPadding;
  12943. xShift = 0
  12944. }
  12945. },
  12946. _getDataRowsColumns: function(seriesGroups, cols, rows) {
  12947. var that = this,
  12948. i,
  12949. j,
  12950. options = that._options,
  12951. equalColumnWidth = options.equalColumnWidth,
  12952. series = that.series || {},
  12953. maxWidthPerColumn = [],
  12954. maxWidthColumn = 0,
  12955. maxHeightRow = 0,
  12956. group,
  12957. box;
  12958. for (i = 0; i < cols; i++)
  12959. maxWidthPerColumn[i] = 0;
  12960. for (i = 0; i < rows; i++)
  12961. for (j = 0; j < cols; j++) {
  12962. if (rows < cols)
  12963. group = seriesGroups[i * cols + j];
  12964. else
  12965. group = seriesGroups[i + j * rows];
  12966. if (!group)
  12967. break;
  12968. box = group.getBBox();
  12969. if (maxHeightRow < box.height)
  12970. maxHeightRow = box.height;
  12971. if (!equalColumnWidth) {
  12972. if (maxWidthPerColumn[j] < box.width)
  12973. maxWidthPerColumn[j] = box.width
  12974. }
  12975. else if (maxWidthColumn < box.width)
  12976. maxWidthColumn = box.width
  12977. }
  12978. return {
  12979. rows: rows,
  12980. cols: cols,
  12981. maxWidthPerColumn: maxWidthPerColumn,
  12982. maxWidthColumn: maxWidthColumn,
  12983. maxHeightRow: maxHeightRow
  12984. }
  12985. },
  12986. _getRowsColumns: function(count) {
  12987. var that = this,
  12988. options = that._options,
  12989. isHorizontal = options.orientation === HORIZONTAL,
  12990. rows = options.rowCount,
  12991. onRows = _ceil(count / rows),
  12992. columns = options.columnCount,
  12993. onColumns = _ceil(count / columns),
  12994. autoEdit;
  12995. if (columns && !rows)
  12996. rows = onColumns;
  12997. else if (!columns && rows)
  12998. columns = onRows;
  12999. else if (columns && rows) {
  13000. if (isHorizontal && columns < onRows)
  13001. columns = onRows;
  13002. else if (!isHorizontal && rows < onColumns)
  13003. rows = onColumns
  13004. }
  13005. else {
  13006. autoEdit = true;
  13007. if (isHorizontal) {
  13008. rows = 1;
  13009. columns = count
  13010. }
  13011. else {
  13012. columns = 1;
  13013. rows = count
  13014. }
  13015. }
  13016. return {
  13017. rows: rows,
  13018. columns: columns,
  13019. autoEdit: autoEdit
  13020. }
  13021. },
  13022. _adjustBackgroundSettings: function(background, borderVisible, options) {
  13023. var that = this,
  13024. border = options.border,
  13025. legendBox = that._insideLegendGroup.getBBox(),
  13026. backgroundSettings = {
  13027. x: _round(legendBox.x - options.paddingLeftRight),
  13028. y: _round(legendBox.y - options.paddingTopBottom),
  13029. width: _round(legendBox.width) + 2 * options.paddingLeftRight,
  13030. height: _round(legendBox.height) + 2 * options.paddingTopBottom,
  13031. opacity: options.backgroundOpacity
  13032. };
  13033. if (borderVisible) {
  13034. backgroundSettings.strokeWidth = border.width;
  13035. backgroundSettings.stroke = border.color;
  13036. backgroundSettings.strokeOpacity = border.opacity;
  13037. backgroundSettings.dashStyle = border.dashStyle;
  13038. backgroundSettings.rx = border.cornerRadius || 0;
  13039. backgroundSettings.ry = border.cornerRadius || 0
  13040. }
  13041. background.applySettings(backgroundSettings)
  13042. },
  13043. _setBoundingRect: function(options) {
  13044. var that = this,
  13045. box,
  13046. margin = options.margin;
  13047. if (!that._insideLegendGroup)
  13048. return;
  13049. box = that._insideLegendGroup.getBBox();
  13050. box.height += margin.top + margin.bottom;
  13051. box.width += margin.left + margin.right;
  13052. box.x -= margin.left;
  13053. box.y -= margin.top;
  13054. that.boundingRect = box
  13055. },
  13056. changeSize: function(size) {
  13057. var that = this,
  13058. options = $.extend(true, {}, that._options),
  13059. margin = options.margin;
  13060. if (size.height >= 0) {
  13061. size.height = decreaseGaps(margin, ["top", "bottom"], size.height);
  13062. if (options.border.visible)
  13063. size.height = 2 * decreaseGaps(options, ["paddingTopBottom"], size.height / 2);
  13064. if (that._rowsCountDrawed - 1)
  13065. size.height = (that._rowsCountDrawed - 1) * decreaseGaps(options, ["rowItemSpacing"], size.height / (that._rowsCountDrawed - 1))
  13066. }
  13067. if (size.width >= 0) {
  13068. size.width = decreaseGaps(margin, ["left", "right"], size.width);
  13069. if (options.border.visible)
  13070. size.width = 2 * decreaseGaps(options, ["paddingLeftRight"], size.width / 2);
  13071. if (that._columnsCountDrawed - 1)
  13072. size.width = (that._columnsCountDrawed - 1) * decreaseGaps(options, ["columnItemSpacing"], size.width / (that._columnsCountDrawed - 1))
  13073. }
  13074. if (that._insideLegendGroup)
  13075. if (size.height > 0 || size.width > 0) {
  13076. that._options._incidentOccured("W2104");
  13077. that._insideLegendGroup.remove();
  13078. that._insideLegendGroup = null;
  13079. that._trackerGroup && that._trackerGroup.clear()
  13080. }
  13081. else
  13082. that._locateElements(options)
  13083. },
  13084. getTrackerGroup: function() {
  13085. return this._trackerGroup
  13086. },
  13087. getActionCallback: function(point) {
  13088. var that = this;
  13089. if (that._options.visible)
  13090. return function(act) {
  13091. var pointType = point.type,
  13092. isSeries = pointType ? true : false,
  13093. seriesType = pointType || point.series.type;
  13094. if (isSeries || seriesType === 'pie' || seriesType === 'doughnut' || seriesType === 'donut')
  13095. that[act] && that[act](point.index)
  13096. };
  13097. else
  13098. return $.noop
  13099. },
  13100. getLayoutOptions: function() {
  13101. var options = this._options,
  13102. boundingRect = this._insideLegendGroup ? this.boundingRect : {
  13103. width: 0,
  13104. height: 0,
  13105. x: 0,
  13106. y: 0
  13107. };
  13108. if (options) {
  13109. boundingRect.verticalAlignment = options.verticalAlignment;
  13110. boundingRect.horizontalAlignment = options.horizontalAlignment;
  13111. if (options.orientation === 'horizontal')
  13112. boundingRect.cutLayoutSide = options.verticalAlignment;
  13113. else
  13114. boundingRect.cutLayoutSide = options.horizontalAlignment === 'center' ? options.verticalAlignment : options.horizontalAlignment;
  13115. return boundingRect
  13116. }
  13117. return null
  13118. },
  13119. shift: function(x, y) {
  13120. var that = this,
  13121. settings = {},
  13122. box = that.getLayoutOptions();
  13123. settings.translateX = x - box.x;
  13124. settings.translateY = y - box.y;
  13125. that._insideLegendGroup && that._insideLegendGroup.applySettings(settings);
  13126. that._trackerGroup && that._trackerGroup.applySettings(settings)
  13127. },
  13128. getPosition: function() {
  13129. return this._options.position
  13130. },
  13131. dispose: function() {
  13132. var that = this;
  13133. that._disposeTrackers();
  13134. that._legendGroup = null;
  13135. that._trackerGroup = null;
  13136. that._insideLegendGroup = null;
  13137. that._renderer = null;
  13138. that._options = null;
  13139. that._data = null;
  13140. return that
  13141. }
  13142. })
  13143. })(DevExpress, jQuery);
  13144. /*! Module viz-core, file range.js */
  13145. (function($, DX, undefined) {
  13146. var core = DX.viz.core,
  13147. utils = DX.utils,
  13148. isDefinedUtils = utils.isDefined,
  13149. isDateUtils = utils.isDate,
  13150. getLogUtils = utils.getLog,
  13151. raiseToUtils = utils.raiseTo;
  13152. var NUMBER_EQUALITY_CORRECTION = 1,
  13153. DATETIME_EQUALITY_CORRECTION = 60000;
  13154. var minSelector = 'min',
  13155. maxSelector = 'max',
  13156. minVisibleSelector = 'minVisible',
  13157. maxVisibleSelector = 'maxVisible',
  13158. minValueMarginSelector = 'minValueMargin',
  13159. maxValueMarginSelector = 'maxValueMargin',
  13160. categoriesSelector = 'categories',
  13161. keepValueMarginsSelector = 'keepValueMargins',
  13162. baseSelector = 'base',
  13163. axisTypeSelector = 'axisType';
  13164. var raiseToFlooredLog = function(value, base, correction) {
  13165. return raiseToUtils(Math.floor(getLogUtils(value, base)) + (correction || 0), base)
  13166. };
  13167. var otherLessThan = function(thisValue, otherValue) {
  13168. return otherValue < thisValue
  13169. };
  13170. var otherGreaterThan = function(thisValue, otherValue) {
  13171. return otherValue > thisValue
  13172. };
  13173. var compareAndReplace = function(thisValue, otherValue, setValue, compare) {
  13174. var otherValueDefined = isDefinedUtils(otherValue);
  13175. if (isDefinedUtils(thisValue)) {
  13176. if (otherValueDefined && compare(thisValue, otherValue))
  13177. setValue(otherValue)
  13178. }
  13179. else if (otherValueDefined)
  13180. setValue(otherValue)
  13181. };
  13182. var applyMargin = function(value, margin, rangeLength, coef, isDateTime) {
  13183. value = value.valueOf() + coef * rangeLength * margin;
  13184. return isDateTime ? new Date(value) : value
  13185. };
  13186. DX.viz.core.__NUMBER_EQUALITY_CORRECTION = NUMBER_EQUALITY_CORRECTION;
  13187. DX.viz.core.__DATETIME_EQUALITY_CORRECTION = DATETIME_EQUALITY_CORRECTION;
  13188. core.Range = function(range) {
  13189. range && $.extend(this, range)
  13190. };
  13191. $.extend(core.Range.prototype, {
  13192. dispose: function() {
  13193. this[categoriesSelector] = null
  13194. },
  13195. addRange: function(otherRange) {
  13196. var that = this,
  13197. categories = that[categoriesSelector],
  13198. categoriesValues,
  13199. otherCategories = otherRange[categoriesSelector],
  13200. i,
  13201. j,
  13202. length,
  13203. found;
  13204. var setIndentByPriority = function(prefix) {
  13205. var prioritySelector = prefix + 'Priority',
  13206. priorityRelation = (that[prioritySelector] || 0) - (otherRange[prioritySelector] || 0);
  13207. if ((that[prefix] || 0) < otherRange[prefix] && priorityRelation === 0 || priorityRelation < 0) {
  13208. that[prefix] = otherRange[prefix];
  13209. that[prioritySelector] = otherRange[prioritySelector]
  13210. }
  13211. };
  13212. var compareAndReplaceByField = function(field, compare) {
  13213. compareAndReplace(that[field], otherRange[field], function(value) {
  13214. that[field] = value
  13215. }, compare)
  13216. };
  13217. var controlValuesByVisibleBounds = function(valueField, visibleValueField, compare) {
  13218. compareAndReplace(that[valueField], that[visibleValueField], function(value) {
  13219. isDefinedUtils(that[valueField]) && (that[valueField] = value)
  13220. }, compare)
  13221. };
  13222. var checkField = function(field) {
  13223. that[field] = that[field] || otherRange[field]
  13224. };
  13225. if (utils.isDefined(otherRange["stick"]))
  13226. that["stick"] = otherRange["stick"];
  13227. checkField('invert');
  13228. checkField(axisTypeSelector);
  13229. checkField('dataType');
  13230. checkField(keepValueMarginsSelector);
  13231. if (that[axisTypeSelector] === 'logarithmic')
  13232. checkField(baseSelector);
  13233. else
  13234. that[baseSelector] = undefined;
  13235. compareAndReplaceByField(minSelector, otherLessThan);
  13236. compareAndReplaceByField(maxSelector, otherGreaterThan);
  13237. compareAndReplaceByField(minVisibleSelector, otherLessThan);
  13238. compareAndReplaceByField(maxVisibleSelector, otherGreaterThan);
  13239. compareAndReplaceByField('interval', otherLessThan);
  13240. setIndentByPriority(minValueMarginSelector);
  13241. setIndentByPriority(maxValueMarginSelector);
  13242. controlValuesByVisibleBounds(minSelector, minVisibleSelector, otherLessThan);
  13243. controlValuesByVisibleBounds(minSelector, maxVisibleSelector, otherLessThan);
  13244. controlValuesByVisibleBounds(maxSelector, maxVisibleSelector, otherGreaterThan);
  13245. controlValuesByVisibleBounds(maxSelector, minVisibleSelector, otherGreaterThan);
  13246. if (categories === undefined)
  13247. that[categoriesSelector] = otherCategories;
  13248. else {
  13249. length = categories.length;
  13250. if (otherCategories && otherCategories.length)
  13251. for (i = 0; i < otherCategories.length; i++) {
  13252. for (j = 0, found = false; j < length; j++)
  13253. if (categories[j].valueOf() === otherCategories[i].valueOf()) {
  13254. found = true;
  13255. break
  13256. }
  13257. !found && categories.push(otherCategories[i])
  13258. }
  13259. }
  13260. return this
  13261. },
  13262. isDefined: function() {
  13263. return isDefinedUtils(this[minSelector]) && isDefinedUtils(this[maxSelector]) || isDefinedUtils(this[categoriesSelector])
  13264. },
  13265. setStubData: function(dataType) {
  13266. var that = this,
  13267. year = (new Date).getYear() - 1,
  13268. isDate = dataType === 'datetime',
  13269. isCategories = that.axisType === 'discrete';
  13270. if (isCategories)
  13271. that.categories = ['0', '1', '2'];
  13272. else {
  13273. that[minSelector] = isDate ? new Date(year, 0, 1) : 0;
  13274. that[maxSelector] = isDate ? new Date(year, 11, 31) : 10
  13275. }
  13276. that.stubData = true;
  13277. return that
  13278. },
  13279. applyValueMargins: function() {
  13280. var that = this,
  13281. base = that[baseSelector],
  13282. isDateTime = isDateUtils(that[maxSelector]) || isDateUtils(that[minSelector]);
  13283. var applyMarginWithZeroCorrection = function(min, max, rangeLength) {
  13284. var minValue = that[min],
  13285. maxValue = that[max],
  13286. minMargin = that[minValueMarginSelector],
  13287. maxMargin = that[maxValueMarginSelector],
  13288. minCorrected = false,
  13289. maxCorrected = false;
  13290. if (rangeLength && !isDateTime && !that[keepValueMarginsSelector]) {
  13291. if (minValue <= 0 && maxValue <= 0 && maxMargin > maxValue / (minValue - maxValue)) {
  13292. that[max] = 0;
  13293. maxCorrected = true
  13294. }
  13295. if (minValue >= 0 && maxValue >= 0 && minMargin > minValue / (maxValue - minValue)) {
  13296. that[min] = 0;
  13297. minCorrected = true
  13298. }
  13299. }
  13300. if (isDefinedUtils(maxValue) && !maxCorrected && maxMargin)
  13301. that[max] = applyMargin(maxValue, maxMargin, rangeLength, 1, isDateTime);
  13302. if (isDefinedUtils(minValue) && !minCorrected && minMargin)
  13303. that[min] = applyMargin(minValue, minMargin, rangeLength, -1, isDateTime)
  13304. };
  13305. var correctValueByBoundaries = function(visibleSelector, valueSelector) {
  13306. that[visibleSelector] = isDefinedUtils(that[visibleSelector]) ? that[visibleSelector] : that[valueSelector]
  13307. };
  13308. var processLogarithmicMinValue = function(valueField) {
  13309. if (isDefinedUtils(that[valueField])) {
  13310. var intermediateValue = raiseToFlooredLog(that[valueField], base);
  13311. if (getLogUtils(that[valueField] / intermediateValue, base) < 0.1 && that.alwaysCorrectMin && !that[keepValueMarginsSelector])
  13312. that[valueField] = raiseToFlooredLog(that[valueField], base, -1);
  13313. else if (that.alwaysCorrectMin && !that[keepValueMarginsSelector])
  13314. that[valueField] = intermediateValue;
  13315. else if (getLogUtils(that[valueField] / intermediateValue, base) < 0.5)
  13316. that[valueField] = intermediateValue
  13317. }
  13318. };
  13319. var processLogarithmicMaxValue = function(valueField) {
  13320. if (isDefinedUtils(that[valueField])) {
  13321. var intermediateValue = raiseToFlooredLog(that[valueField], base);
  13322. if (getLogUtils(that[valueField] / intermediateValue, base) > 0.5)
  13323. that[valueField] = raiseToUtils(Math.ceil(getLogUtils(that[valueField], base)), base)
  13324. }
  13325. };
  13326. var correctLogVisibleValue = function(visibleValueSelector, valueSelector, compare) {
  13327. if (!isDefinedUtils(that[visibleValueSelector]) || compare)
  13328. that[visibleValueSelector] = that[valueSelector]
  13329. };
  13330. if (that[axisTypeSelector] === 'logarithmic' && that[minSelector] !== that[maxSelector]) {
  13331. processLogarithmicMinValue(minSelector);
  13332. processLogarithmicMaxValue(maxSelector);
  13333. if (that.isValueRange && that[minVisibleSelector] !== that[maxVisibleSelector]) {
  13334. processLogarithmicMinValue(minVisibleSelector);
  13335. processLogarithmicMaxValue(maxVisibleSelector)
  13336. }
  13337. correctLogVisibleValue(minVisibleSelector, minSelector, that[minVisibleSelector] < that[minSelector]);
  13338. correctLogVisibleValue(maxVisibleSelector, maxSelector, that[maxVisibleSelector] > that[maxSelector])
  13339. }
  13340. else {
  13341. correctValueByBoundaries(minVisibleSelector, minSelector);
  13342. correctValueByBoundaries(maxVisibleSelector, maxSelector);
  13343. applyMarginWithZeroCorrection(minSelector, maxSelector, that[maxSelector] - that[minSelector]);
  13344. applyMarginWithZeroCorrection(minVisibleSelector, maxVisibleSelector, that[maxVisibleSelector] - that[minVisibleSelector])
  13345. }
  13346. return this
  13347. },
  13348. correctValueZeroLevel: function() {
  13349. var that = this;
  13350. if (isDateUtils(that[maxSelector]) || isDateUtils(that[minSelector]))
  13351. return that;
  13352. function setZeroLevel(min, max) {
  13353. that[min] < 0 && that[max] < 0 && (that[max] = 0);
  13354. that[min] > 0 && that[max] > 0 && (that[min] = 0)
  13355. }
  13356. setZeroLevel(minSelector, maxSelector);
  13357. setZeroLevel(minVisibleSelector, maxVisibleSelector);
  13358. return that
  13359. }
  13360. })
  13361. })(jQuery, DevExpress);
  13362. /*! Module viz-core, file seriesConsts.js */
  13363. (function(DX) {
  13364. DX.viz.core.series = DX.viz.core.series || {};
  13365. DX.viz.core.series.helpers = DX.viz.core.series.helpers || {};
  13366. DX.viz.core.series.helpers.consts = {
  13367. events: {
  13368. mouseover: "mouseover",
  13369. mouseout: "mouseout",
  13370. mousemove: "mousemove",
  13371. touchstart: "touchstart",
  13372. touchmove: "touchmove",
  13373. touchend: "touchend",
  13374. mousedown: "mousedown",
  13375. mouseup: "mouseup",
  13376. click: "click",
  13377. selectSeries: "selectseries",
  13378. deselectSeries: "deselectseries",
  13379. selectPoint: "selectpoint",
  13380. deselectPoint: "deselectpoint",
  13381. showPointTooltip: "showpointtooltip",
  13382. hidePointTooltip: "hidepointtooltip"
  13383. },
  13384. states: {
  13385. hover: "hover",
  13386. normal: "normal",
  13387. selected: "selected",
  13388. normalMark: 0,
  13389. hoverMark: 1,
  13390. selectedMark: 2
  13391. },
  13392. animations: {
  13393. showDuration: {duration: 400},
  13394. hideGroup: {opacity: 0.0001},
  13395. showGroup: {opacity: 1}
  13396. }
  13397. }
  13398. })(DevExpress);
  13399. /*! Module viz-core, file seriesFamily.js */
  13400. (function($, DX, undefined) {
  13401. var utils = DX.utils,
  13402. _round = Math.round,
  13403. _abs = Math.abs,
  13404. _pow = Math.pow;
  13405. DX.viz.core.series.helpers.SeriesFamily = DX.Class.inherit(function() {
  13406. var ctor = function(options) {
  13407. var debug = DX.utils.debug;
  13408. debug.assert(options.type, "type was not passed or empty");
  13409. var that = this,
  13410. stubFunction = $.noop;
  13411. $.extend(that, options);
  13412. that.type = that.type.toLowerCase();
  13413. that.series = [];
  13414. switch (that.type) {
  13415. case"bar":
  13416. that.adjustSeriesDimensions = adjustBarSeriesDimensions;
  13417. that.adjustSeriesValues = stubFunction;
  13418. that.updateSeriesValues = updateBarSeriesValues;
  13419. break;
  13420. case"rangebar":
  13421. that.adjustSeriesDimensions = adjustBarSeriesDimensions;
  13422. that.adjustSeriesValues = stubFunction;
  13423. that.updateSeriesValues = stubFunction;
  13424. break;
  13425. case"fullstackedbar":
  13426. that.fullStacked = true;
  13427. that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
  13428. that.adjustSeriesValues = adjustStackedSeriesValues;
  13429. that.updateSeriesValues = updateStackedSeriesValues;
  13430. break;
  13431. case"stackedbar":
  13432. that.adjustSeriesDimensions = adjustStackedBarSeriesDimensions;
  13433. that.adjustSeriesValues = adjustStackedSeriesValues;
  13434. that.updateSeriesValues = updateStackedSeriesValues;
  13435. break;
  13436. case"fullstackedarea":
  13437. case"fullstackedline":
  13438. that.fullStacked = true;
  13439. that.adjustSeriesDimensions = stubFunction;
  13440. that.adjustSeriesValues = adjustStackedSeriesValues;
  13441. that.updateSeriesValues = stubFunction;
  13442. break;
  13443. case"stackedarea":
  13444. case"stackedline":
  13445. that.adjustSeriesDimensions = stubFunction;
  13446. that.adjustSeriesValues = adjustStackedSeriesValues;
  13447. that.updateSeriesValues = stubFunction;
  13448. break;
  13449. case"candlestick":
  13450. case"stock":
  13451. that.adjustSeriesDimensions = adjustCandlestickSeriesDimensions;
  13452. that.adjustSeriesValues = stubFunction;
  13453. that.updateSeriesValues = stubFunction;
  13454. break;
  13455. case"bubble":
  13456. that.adjustSeriesDimensions = adjustBubbleSeriesDimensions;
  13457. that.adjustSeriesValues = stubFunction;
  13458. that.updateSeriesValues = stubFunction;
  13459. break;
  13460. default:
  13461. that.adjustSeriesDimensions = stubFunction;
  13462. that.adjustSeriesValues = stubFunction;
  13463. that.updateSeriesValues = stubFunction;
  13464. break
  13465. }
  13466. };
  13467. var dispose = function() {
  13468. this.series = null;
  13469. this.translators = null
  13470. };
  13471. var add = function(series) {
  13472. var that = this,
  13473. singleSeries,
  13474. i;
  13475. if (!$.isArray(series))
  13476. series = [series];
  13477. for (i = 0; i < series.length; i++) {
  13478. singleSeries = series[i];
  13479. if (singleSeries.type.toLowerCase() === that.type)
  13480. that.series.push(singleSeries)
  13481. }
  13482. };
  13483. var adjustBarSeriesDimensionsCore = function(series, interval, stackCount, equalBarWidth, seriesStackIndexCallback) {
  13484. var spacing,
  13485. width,
  13486. maxWidth,
  13487. middleIndex,
  13488. stackIndex,
  13489. i,
  13490. point,
  13491. points,
  13492. seriesOffset,
  13493. stackName,
  13494. argumentsKeeper = {},
  13495. stackKeepers = {},
  13496. stacksWithArgument,
  13497. count;
  13498. if (equalBarWidth) {
  13499. width = equalBarWidth.width && equalBarWidth.width < 0 ? 0 : equalBarWidth.width;
  13500. spacing = equalBarWidth.spacing && equalBarWidth.spacing < 0 ? 0 : equalBarWidth.spacing;
  13501. if (width && !spacing)
  13502. if (stackCount > 1) {
  13503. spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));
  13504. if (spacing < 1)
  13505. spacing = 1
  13506. }
  13507. else
  13508. spacing = 0;
  13509. else if (spacing && !width) {
  13510. width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);
  13511. if (width < 2)
  13512. width = 2
  13513. }
  13514. else if (!spacing && !width) {
  13515. if (stackCount > 1) {
  13516. spacing = _round(interval * 0.7 / stackCount * 0.2);
  13517. if (spacing < 1)
  13518. spacing = 1
  13519. }
  13520. else
  13521. spacing = 0;
  13522. width = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount);
  13523. if (width < 2)
  13524. width = 2
  13525. }
  13526. if (width * stackCount + spacing * (stackCount - 1) > interval) {
  13527. spacing = _round((interval * 0.7 - width * stackCount) / (stackCount - 1));
  13528. if (spacing < 1) {
  13529. spacing = 1;
  13530. maxWidth = _round((interval * 0.7 - spacing * (stackCount - 1)) / stackCount)
  13531. }
  13532. }
  13533. middleIndex = stackCount / 2;
  13534. for (i = 0; i < series.length; i++) {
  13535. stackIndex = seriesStackIndexCallback(i);
  13536. points = series[i].getPoints();
  13537. seriesOffset = (stackIndex - middleIndex + 0.5) * (maxWidth || width) - (middleIndex - stackIndex - 0.5) * spacing;
  13538. $.each(points, function(_, point) {
  13539. point.correctCoordinates({
  13540. width: width,
  13541. offset: seriesOffset
  13542. })
  13543. })
  13544. }
  13545. }
  13546. else {
  13547. $.each(series, function(i, singleSeries) {
  13548. stackName = singleSeries.getStackName && singleSeries.getStackName();
  13549. stackName = stackName || i.toString();
  13550. if (!stackKeepers[stackName])
  13551. stackKeepers[stackName] = [];
  13552. stackKeepers[stackName].push(singleSeries)
  13553. });
  13554. $.each(series, function(i, singleSeries) {
  13555. $.each(singleSeries.getPoints(), function(_, point) {
  13556. var argument = point.argument;
  13557. if (!argumentsKeeper.hasOwnProperty(argument))
  13558. argumentsKeeper[argument.valueOf()] = 1
  13559. })
  13560. });
  13561. for (var argument in argumentsKeeper) {
  13562. if (!argumentsKeeper.hasOwnProperty(argument))
  13563. continue;
  13564. stacksWithArgument = [];
  13565. $.each(stackKeepers, function(stackName, seriesInStack) {
  13566. $.each(seriesInStack, function(i, singleSeries) {
  13567. point = singleSeries.getPointByArg(argument);
  13568. if (point && point.value) {
  13569. stacksWithArgument.push(stackName);
  13570. return false
  13571. }
  13572. })
  13573. });
  13574. count = stacksWithArgument.length;
  13575. spacing = _round(interval * 0.7 / count * 0.2);
  13576. if (spacing < 1)
  13577. spacing = 1;
  13578. width = _round((interval * 0.7 - spacing * (count - 1)) / count);
  13579. if (width < 2)
  13580. width = 2;
  13581. middleIndex = count / 2;
  13582. $.each(stackKeepers, function(stackName, seriesInStack) {
  13583. stackIndex = $.inArray(stackName, stacksWithArgument);
  13584. if (stackIndex === -1)
  13585. return;
  13586. seriesOffset = (stackIndex - middleIndex + 0.5) * width - (middleIndex - stackIndex - 0.5) * spacing;
  13587. $.each(seriesInStack, function(i, singleSeries) {
  13588. var point = singleSeries.getPointByArg(argument);
  13589. if (point && point.value)
  13590. point.correctCoordinates({
  13591. width: width,
  13592. offset: seriesOffset
  13593. })
  13594. })
  13595. })
  13596. }
  13597. }
  13598. };
  13599. var getVisibleSeries = function(that) {
  13600. return $.map(that.series, function(s) {
  13601. return s.isVisible() ? s : null
  13602. })
  13603. };
  13604. var adjustBarSeriesDimensions = function(translators) {
  13605. var debug = DX.utils.debug;
  13606. debug.assert(translators, "translator was not passed or empty");
  13607. var that = this,
  13608. equalBarWidth = that.equalBarWidth,
  13609. series = getVisibleSeries(that);
  13610. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, equalBarWidth, function(seriesIndex) {
  13611. return seriesIndex
  13612. })
  13613. };
  13614. var adjustStackedBarSeriesDimensions = function(translators) {
  13615. var debug = DX.utils.debug;
  13616. debug.assert(translators, "translators was not passed or empty");
  13617. var that = this,
  13618. interval,
  13619. series = getVisibleSeries(that),
  13620. stackIndexes = {},
  13621. stackCount = 0,
  13622. equalBarWidth = that.equalBarWidth;
  13623. $.each(series, function() {
  13624. var stackName = this.getStackName();
  13625. if (!stackIndexes.hasOwnProperty(stackName))
  13626. stackIndexes[stackName] = stackCount++
  13627. });
  13628. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), stackCount, equalBarWidth, function(seriesIndex) {
  13629. return stackIndexes[series[seriesIndex].getStackName()]
  13630. })
  13631. };
  13632. var adjustStackedSeriesValues = function() {
  13633. var that = this,
  13634. series = getVisibleSeries(that),
  13635. stackKeepers = {
  13636. positive: {},
  13637. negative: {}
  13638. };
  13639. $.each(series, function(_, singleSeries) {
  13640. var points = singleSeries.getPoints();
  13641. $.each(points, function(index, point) {
  13642. var value = point.initialValue,
  13643. argument = point.argument,
  13644. stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  13645. valueType = value >= 0 ? "positive" : "negative",
  13646. currentStack;
  13647. stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  13648. currentStack = stackKeepers[valueType][stackName];
  13649. if (currentStack[argument.valueOf()]) {
  13650. points[index].correctValue(currentStack[argument.valueOf()]);
  13651. currentStack[argument.valueOf()] += value
  13652. }
  13653. else {
  13654. currentStack[argument.valueOf()] = value;
  13655. points[index].resetCorrection()
  13656. }
  13657. })
  13658. });
  13659. setPercentStackedValues(series, stackKeepers, that.fullStacked)
  13660. };
  13661. var setPercentStackedValues = function(series, stackKeepers, fullStacked) {
  13662. $.each(series, function(_, singleSeries) {
  13663. var points = singleSeries.getPoints();
  13664. $.each(points, function(index, point) {
  13665. var value = point.value,
  13666. stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  13667. valueType = value >= 0 ? "positive" : "negative",
  13668. currentStack;
  13669. stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  13670. currentStack = stackKeepers[valueType][stackName];
  13671. points[index].setPercentValue(currentStack[point.argument.valueOf()], fullStacked)
  13672. })
  13673. })
  13674. };
  13675. var getMinShownBusinessValue = function(that, translators, minBarSize) {
  13676. var rotated = that.rotated,
  13677. valTranslator = rotated ? translators.x : translators.y,
  13678. canvas = valTranslator.getCanvasVisibleArea();
  13679. if (minBarSize)
  13680. return _abs(valTranslator.untranslate(canvas.min) - valTranslator.untranslate(canvas.min + minBarSize))
  13681. };
  13682. var updateStackedSeriesValues = function(translators) {
  13683. var that = this,
  13684. series = getVisibleSeries(that),
  13685. stackKeepers = {
  13686. positive: {},
  13687. negative: {}
  13688. };
  13689. $.each(series, function(_, singleSeries) {
  13690. var points = singleSeries.getPoints(),
  13691. minBarSize = singleSeries.getOptions().minBarSize;
  13692. $.each(points, function(index, point) {
  13693. var value = point.value,
  13694. minValue = point.minValue,
  13695. argument = point.argument,
  13696. updateValue,
  13697. pointSize,
  13698. minShownBusinessValue,
  13699. stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  13700. valueType = value >= 0 ? "positive" : "negative",
  13701. currentStack;
  13702. minShownBusinessValue = getMinShownBusinessValue(that, translators, minBarSize);
  13703. currentStack = stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  13704. if (currentStack[argument.valueOf()]) {
  13705. minValue = utils.isNumber(minValue) ? minValue : 0,
  13706. pointSize = _abs(minValue - value);
  13707. if (minShownBusinessValue && pointSize < minShownBusinessValue)
  13708. updateValue = minShownBusinessValue;
  13709. else
  13710. updateValue = value - minValue;
  13711. points[index].minValue = currentStack[argument.valueOf()];
  13712. points[index].value = currentStack[argument.valueOf()] + updateValue;
  13713. currentStack[argument.valueOf()] += updateValue
  13714. }
  13715. else {
  13716. pointSize = value;
  13717. if (minShownBusinessValue && pointSize < minShownBusinessValue)
  13718. updateValue = minShownBusinessValue;
  13719. else
  13720. updateValue = value;
  13721. points[index].value = updateValue;
  13722. currentStack[argument.valueOf()] = updateValue
  13723. }
  13724. })
  13725. });
  13726. if (that.fullStacked)
  13727. updateFullStackedSeriesValues(series, stackKeepers)
  13728. };
  13729. var updateFullStackedSeriesValues = function(series, stackKeepers) {
  13730. $.each(series, function(_, singleSeries) {
  13731. var stackName = singleSeries.getStackName ? singleSeries.getStackName() : "default",
  13732. points = singleSeries.getPoints();
  13733. $.each(points, function(index, point) {
  13734. var value = point.value,
  13735. argument = point.argument,
  13736. valueType = value >= 0 ? "positive" : "negative",
  13737. currentStack;
  13738. stackKeepers[valueType][stackName] = stackKeepers[valueType][stackName] || {};
  13739. currentStack = stackKeepers[valueType][stackName];
  13740. points[index].value = points[index].value / currentStack[argument.valueOf()] || 0;
  13741. if (DX.utils.isNumber(points[index].minValue))
  13742. points[index].minValue = points[index].minValue / currentStack[argument.valueOf()] || 0
  13743. })
  13744. })
  13745. };
  13746. var updateBarSeriesValues = function(translators) {
  13747. var that = this;
  13748. $.each(that.series, function(_, singleSeries) {
  13749. var points = singleSeries.getPoints(),
  13750. minBarSize = singleSeries.getOptions().minBarSize;
  13751. $.each(points, function(index, point) {
  13752. var value = point.value,
  13753. updateValue,
  13754. pointSize,
  13755. minShownBusinessValue;
  13756. minShownBusinessValue = getMinShownBusinessValue(that, translators, minBarSize);
  13757. pointSize = _abs(value);
  13758. if (minShownBusinessValue && pointSize < minShownBusinessValue)
  13759. updateValue = value >= 0 ? minShownBusinessValue : -minShownBusinessValue;
  13760. else
  13761. updateValue = value;
  13762. points[index].value = updateValue
  13763. })
  13764. })
  13765. };
  13766. var adjustCandlestickSeriesDimensions = function(translators) {
  13767. var debug = DX.utils.debug;
  13768. debug.assert(translators, "translator was not passed or empty");
  13769. var that = this,
  13770. series = getVisibleSeries(that);
  13771. adjustBarSeriesDimensionsCore(series, getInterval(that, translators), series.length, true, function(seriesIndex) {
  13772. return seriesIndex
  13773. })
  13774. };
  13775. var getInterval = function(that, translators) {
  13776. var argTranslator = !that.rotated ? translators.x : translators.y;
  13777. return that.interval = argTranslator.getInterval()
  13778. };
  13779. var adjustBubbleSeriesDimensions = function(translators) {
  13780. var debug = DX.utils.debug;
  13781. debug.assert(translators, "translator was not passed or empty");
  13782. var that = this,
  13783. series = getVisibleSeries(that),
  13784. points,
  13785. i,
  13786. visibleAreaX = translators.x.getCanvasVisibleArea(),
  13787. visibleAreaY = translators.y.getCanvasVisibleArea(),
  13788. min = Math.min(visibleAreaX.max - visibleAreaX.min, visibleAreaY.max - visibleAreaY.min),
  13789. minBubbleArea = _pow(that.minBubbleSize, 2),
  13790. maxBubbleArea = _pow(min * that.maxBubbleSize, 2),
  13791. equalBubbleSize = (min * that.maxBubbleSize + that.minBubbleSize) / 2,
  13792. minPointSize = Infinity,
  13793. maxPointSize = 0,
  13794. pointSize,
  13795. bubbleArea,
  13796. sizeProportion,
  13797. sizeDispersion,
  13798. areaDispersion;
  13799. for (i = 0; i < series.length; i++) {
  13800. points = series[i].getPoints();
  13801. $.each(points, function(_, point) {
  13802. maxPointSize = maxPointSize > point.size ? maxPointSize : point.size;
  13803. minPointSize = minPointSize < point.size ? minPointSize : point.size
  13804. })
  13805. }
  13806. sizeDispersion = maxPointSize - minPointSize;
  13807. areaDispersion = _abs(maxBubbleArea - minBubbleArea);
  13808. minPointSize = minPointSize < 0 ? 0 : minPointSize;
  13809. for (i = 0; i < series.length; i++) {
  13810. points = series[i].getPoints();
  13811. $.each(points, function(_, point) {
  13812. if (maxPointSize === minPointSize)
  13813. pointSize = _round(equalBubbleSize);
  13814. else {
  13815. sizeProportion = _abs(point.size - minPointSize) / sizeDispersion;
  13816. bubbleArea = areaDispersion * sizeProportion + minBubbleArea;
  13817. pointSize = _round(Math.sqrt(bubbleArea))
  13818. }
  13819. point.correctCoordinates(pointSize)
  13820. })
  13821. }
  13822. };
  13823. return {
  13824. ctor: ctor,
  13825. dispose: dispose,
  13826. add: add
  13827. }
  13828. }())
  13829. })(jQuery, DevExpress);
  13830. /*! Module viz-core, file baseSeries.js */
  13831. (function($, DX) {
  13832. var viz = DX.viz,
  13833. utils = DX.utils,
  13834. _isDefined = utils.isDefined,
  13835. _each = $.each,
  13836. _extend = $.extend,
  13837. _isEmptyObject = $.isEmptyObject,
  13838. _Event = $.Event,
  13839. _noop = $.noop,
  13840. SELECTED_STATE = 2,
  13841. HOVER_STATE = 1,
  13842. NONE_MODE = "none",
  13843. INCLUDE_POINTS = "includepoints",
  13844. EXLUDE_POINTS = "excludepoints",
  13845. ALL_SERIES_POINTS_MODE = "allseriespoints",
  13846. APPLY_SELECTED = "applySelected",
  13847. APPLY_HOVER = "applyHover",
  13848. getEmptyBusinessRange = function() {
  13849. return {
  13850. arg: {},
  13851. val: {}
  13852. }
  13853. };
  13854. viz.core.series.mixins = {
  13855. chart: {},
  13856. pieChart: {}
  13857. };
  13858. viz.core.series.Series = DX.Class.inherit({
  13859. ctor: function(renderer, options) {
  13860. this.fullState = 0;
  13861. this._renderer = renderer;
  13862. this._group = renderer.createGroup({"class": "dxc-series"});
  13863. this.updateOptions(options)
  13864. },
  13865. update: function(data, options) {
  13866. this.updateOptions(options);
  13867. this.updateData(data)
  13868. },
  13869. _createLegendState: function(styleOptions, defaultColor) {
  13870. return {
  13871. fill: styleOptions.color || defaultColor,
  13872. hatching: styleOptions.hatching
  13873. }
  13874. },
  13875. getLegendStyles: function() {
  13876. return this._styles.legendStyles
  13877. },
  13878. _createStyles: function(options) {
  13879. var mainSeriesColor = options.mainSeriesColor,
  13880. specialMainColor = this._getSpecialColor(mainSeriesColor);
  13881. this._styles = {
  13882. normal: this._parseStyle(options, mainSeriesColor, mainSeriesColor),
  13883. hover: this._parseStyle(options.hoverStyle || {}, specialMainColor, mainSeriesColor),
  13884. selection: this._parseStyle(options.selectionStyle || {}, specialMainColor, mainSeriesColor),
  13885. legendStyles: {
  13886. normal: this._createLegendState(options, mainSeriesColor),
  13887. hover: this._createLegendState(options.hoverStyle || {}, specialMainColor),
  13888. selection: this._createLegendState(options.selectionStyle || {}, specialMainColor)
  13889. }
  13890. }
  13891. },
  13892. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  13893. _each(this._points || [], function(_, point) {
  13894. point.setAdjustSeriesLabels(adjustSeriesLabels)
  13895. })
  13896. },
  13897. setClippingParams: function(id, forceClipping) {
  13898. this._paneClipRectID = id;
  13899. this._forceClipping = forceClipping
  13900. },
  13901. getTagField: function() {
  13902. return this._options.tagField || "tag"
  13903. },
  13904. getValueFields: _noop,
  13905. getArgumentField: _noop,
  13906. getPoints: function() {
  13907. return this._points
  13908. },
  13909. _createPoint: function(data, pointsArray, index) {
  13910. data.index = index;
  13911. if (this._checkData(data)) {
  13912. var point = pointsArray[index],
  13913. options = this._customizePoint(data) || this._getCreatingPointOptions();
  13914. if (point)
  13915. point.update(data, options);
  13916. else {
  13917. point = viz.core.CoreFactory.createPoint(data, options);
  13918. pointsArray.push(point)
  13919. }
  13920. this.pointsByArgument[point.argument.valueOf()] = this.pointsByArgument[point.argument.valueOf()] || point;
  13921. return true
  13922. }
  13923. },
  13924. getRangeData: function(zoomArgs, calcIntervalFunction) {
  13925. return this._visible ? _extend(true, {}, this._getRangeData(zoomArgs, calcIntervalFunction)) : getEmptyBusinessRange()
  13926. },
  13927. _deleteElementsGroup: function() {
  13928. if (this._elementsGroup) {
  13929. this._elementsGroup.detach();
  13930. this._elementsGroup = null
  13931. }
  13932. },
  13933. _deleteBordersGroup: function() {
  13934. if (this._bordersGroup) {
  13935. this._bordersGroup.detach();
  13936. this._bordersGroup = null
  13937. }
  13938. },
  13939. _saveOldAnimationMethods: function() {
  13940. this._oldClearingAnimation = this._clearingAnimation;
  13941. this._oldUpdateElement = this._updateElement
  13942. },
  13943. _deleteOldAnimationMethods: function() {
  13944. this._oldClearingAnimation = null;
  13945. this._oldUpdateElement = null
  13946. },
  13947. updateOptions: function(newOptions) {
  13948. var that = this,
  13949. widgetType = newOptions.widgetType,
  13950. oldType = that.type,
  13951. newType = newOptions.type;
  13952. that.type = newType && newType.toString().toLowerCase();
  13953. if (!that._checkType(widgetType)) {
  13954. that.dispose();
  13955. that.isUpdated = false;
  13956. return
  13957. }
  13958. if (oldType !== that.type) {
  13959. that._firstDrawing = true;
  13960. that._saveOldAnimationMethods();
  13961. that._resetType(oldType, widgetType);
  13962. that._setType(that.type, widgetType)
  13963. }
  13964. that._options = newOptions;
  13965. that._pointOptions = null;
  13966. that._deletePatterns();
  13967. that._patterns = [];
  13968. that.name = newOptions.name;
  13969. that.pane = newOptions.pane;
  13970. that.axis = newOptions.axis;
  13971. that.tag = newOptions.tag;
  13972. that._createStyles(newOptions);
  13973. that._updateOptions(newOptions);
  13974. that._visible = newOptions.visible;
  13975. that.isUpdated = true
  13976. },
  13977. _disposePoints: function(points) {
  13978. $.each(points || [], function(_, p) {
  13979. p.dispose()
  13980. })
  13981. },
  13982. _correctPointsLength: function(length, points) {
  13983. this._disposePoints(this._oldPoints);
  13984. this._oldPoints = points.splice(length, points.length)
  13985. },
  13986. _getTicksForAggregation: function(min, max, screenDelta, pointSize) {
  13987. return viz.core.tickProvider.getTicks({
  13988. min: min,
  13989. max: max,
  13990. screenDelta: screenDelta,
  13991. gridSpacingFactor: pointSize
  13992. })
  13993. },
  13994. updateDataType: function(settings) {
  13995. var that = this;
  13996. that.argumentType = settings.argumentType;
  13997. that.valueType = settings.valueType;
  13998. that.argumentAxisType = settings.argumentAxisType;
  13999. that.valueAxisType = settings.valueAxisType
  14000. },
  14001. getValueCategories: function() {
  14002. return this._options.valueCategories || []
  14003. },
  14004. getOptions: function() {
  14005. return this._options
  14006. },
  14007. getArgumentCategories: function() {
  14008. return this._options.argumentCategories || []
  14009. },
  14010. updateData: function(data) {
  14011. var that = this,
  14012. points,
  14013. lastPointIndex = 0,
  14014. options = that._options,
  14015. pointData;
  14016. that.pointsByArgument = {};
  14017. points = that._originalPoints || [];
  14018. that._rangeData = getEmptyBusinessRange();
  14019. if (data && data.length)
  14020. that._canRenderCompleteHandle = true;
  14021. that._beginUpdateData();
  14022. _each(data, function(index, dataItem) {
  14023. pointData = that._getPointData(dataItem, options);
  14024. if (that._createPoint(pointData, points, lastPointIndex)) {
  14025. that._processRange(points[lastPointIndex], lastPointIndex > 0 ? points[lastPointIndex - 1] : null);
  14026. lastPointIndex++
  14027. }
  14028. });
  14029. that._points = that._originalPoints = points;
  14030. that._correctPointsLength(lastPointIndex, points);
  14031. that._endUpdateData()
  14032. },
  14033. getTeamplatedFields: function() {
  14034. var that = this,
  14035. fields = that.getValueFields(),
  14036. teampleteFields = [];
  14037. fields.push(that.getTagField());
  14038. _each(fields, function(_, field) {
  14039. var fieldsObject = {};
  14040. fieldsObject.teamplateField = field + that.name;
  14041. fieldsObject.originalField = field;
  14042. teampleteFields.push(fieldsObject)
  14043. });
  14044. return teampleteFields
  14045. },
  14046. resamplePoints: function(translators, min, max) {
  14047. var that = this,
  14048. originalPoints = that.getAllPoints(),
  14049. argTranslator = that._options.rotated ? translators.y : translators.x,
  14050. minI,
  14051. maxI,
  14052. sizePoint,
  14053. ticks;
  14054. if (originalPoints.length) {
  14055. _each(originalPoints, function(i, point) {
  14056. minI = point.argument - min <= 0 ? i : minI;
  14057. if (!maxI)
  14058. maxI = point.argument - max > 0 ? i : null
  14059. });
  14060. minI = minI ? minI : 1;
  14061. maxI = utils.isDefined(maxI) ? maxI : originalPoints.length - 1;
  14062. min = originalPoints[minI - 1].argument;
  14063. max = originalPoints[maxI].argument;
  14064. sizePoint = that._getPointSize();
  14065. if (that.argumentAxisType !== "discrete" && that.valueAxisType !== "discrete")
  14066. ticks = that._getTicksForAggregation(min, max, argTranslator.canvasLength, sizePoint);
  14067. else
  14068. ticks = argTranslator.canvasLength / sizePoint;
  14069. that._points = that._resample(ticks, ticks.tickInterval)
  14070. }
  14071. },
  14072. _removeOldSegments: function(startIndex) {
  14073. var that = this;
  14074. _each(that._graphics.splice(startIndex, that._graphics.length) || [], function(_, elem) {
  14075. that._removeElement(elem)
  14076. });
  14077. if (that._trackers)
  14078. _each(that._trackers.splice(startIndex, that._trackers.length) || [], function(_, elem) {
  14079. elem.remove()
  14080. })
  14081. },
  14082. draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
  14083. var that = this;
  14084. if (that._oldClearingAnimation && animationEnabled && that._firstDrawing) {
  14085. var drawComplete = function() {
  14086. that._draw(translators, true, hideLayoutLabels)
  14087. };
  14088. that._oldClearingAnimation(translators, drawComplete)
  14089. }
  14090. else
  14091. that._draw(translators, animationEnabled, hideLayoutLabels, legendCallback)
  14092. },
  14093. _clearSeries: function() {
  14094. this._deleteElementsGroup();
  14095. this._deleteBordersGroup();
  14096. this._deleteTrackers();
  14097. this._graphics = [];
  14098. this._trackers = []
  14099. },
  14100. _draw: function(translators, animationEnabled, hideLayoutLabels, legendCallback) {
  14101. var that = this,
  14102. points = that._points || [],
  14103. segment = [],
  14104. segmentCount = 0,
  14105. firstDrawing = that._firstDrawing,
  14106. markersGroup,
  14107. labelsGroup;
  14108. that._graphics = that._graphics || [],
  14109. that._graphics = that._graphics || [];
  14110. that._prepareSeriesToDrawing();
  14111. if (!that._visible) {
  14112. animationEnabled = false;
  14113. this._group.detach();
  14114. return
  14115. }
  14116. else
  14117. that._group.append(that._options.seriesGroup);
  14118. that.translators = translators;
  14119. that._createGroups(animationEnabled, undefined, firstDrawing);
  14120. that._segments = [];
  14121. markersGroup = that._markersGroup;
  14122. labelsGroup = that._labelsGroup;
  14123. that._drawedPoints = [];
  14124. that._firstDrawing = points.length ? false : true;
  14125. _each(this._patterns || [], function(_, pattern) {
  14126. pattern.append()
  14127. });
  14128. _each(points, function(i, p) {
  14129. p.translate(translators);
  14130. if (p.hasValue()) {
  14131. that._drawPoint(p, markersGroup, labelsGroup, animationEnabled, firstDrawing);
  14132. segment.push(p)
  14133. }
  14134. else if (segment.length) {
  14135. that._drawSegment(segment, animationEnabled, segmentCount++);
  14136. segment = []
  14137. }
  14138. });
  14139. segment.length && that._drawSegment(segment, animationEnabled, segmentCount++);
  14140. that._removeOldSegments(segmentCount);
  14141. that._defaultSegments = that._generateDefaultSegments();
  14142. that._adjustLabels(firstDrawing);
  14143. hideLayoutLabels && that.hideLabels();
  14144. animationEnabled && that._animate(firstDrawing);
  14145. if (that.isSelected())
  14146. that._changeStyle(legendCallback, APPLY_SELECTED);
  14147. else if (this.isHovered())
  14148. this._changeStyle(legendCallback, APPLY_HOVER)
  14149. },
  14150. drawTrackers: function() {
  14151. var that = this,
  14152. trackers = that._trackers = that._trackers || [],
  14153. trackersGroup = that._trackersGroup = that._trackersGroup || that._renderer.createGroup(),
  14154. markerTrackerGroup = that._markerTrackerGroup = that._markerTrackerGroup || that._renderer.createGroup();
  14155. if (!that.isVisible()) {
  14156. trackersGroup.detach();
  14157. markerTrackerGroup.detach();
  14158. return
  14159. }
  14160. else {
  14161. trackersGroup.append(that._options.trackersGroup);
  14162. markerTrackerGroup.append(that._options.markerTrackerGroup)
  14163. }
  14164. _each(that._segments || [], function(i, segment) {
  14165. if (!trackers[i]) {
  14166. trackers[i] = that._drawTrackerElement(segment).append(trackersGroup);
  14167. trackers[i].data({series: that})
  14168. }
  14169. else
  14170. that._updateTrackerElement(segment, trackers[i])
  14171. });
  14172. _each(that.getVisiblePoints(), function(_, p) {
  14173. p.drawTracker(that._renderer, markerTrackerGroup)
  14174. });
  14175. that._applyTrackersClippings()
  14176. },
  14177. _checkType: function(widgetType) {
  14178. return !!viz.core.series.mixins[widgetType][this.type]
  14179. },
  14180. _resetType: function(seriesType, widgetType) {
  14181. var that = this;
  14182. if (seriesType)
  14183. _each(viz.core.series.mixins[widgetType][seriesType], function(methodName) {
  14184. delete that[methodName]
  14185. })
  14186. },
  14187. _setType: function(seriesType, widgetType) {
  14188. var that = this;
  14189. _each(viz.core.series.mixins[widgetType][seriesType], function(methodName, method) {
  14190. that[methodName] = method
  14191. })
  14192. },
  14193. _setSelectedState: function(state, mode, legendCallback) {
  14194. this.lastSelectionMode = mode = (mode || this._options.selectionMode).toLowerCase();
  14195. if (state && !this.isSelected()) {
  14196. this.fullState = this.fullState | SELECTED_STATE;
  14197. this._changeStyle(legendCallback, APPLY_SELECTED)
  14198. }
  14199. else if (!state && this.isSelected()) {
  14200. this.fullState = this.fullState & ~SELECTED_STATE;
  14201. if (this.isHovered())
  14202. this._changeStyle(legendCallback, APPLY_HOVER);
  14203. else
  14204. this._changeStyle(legendCallback, "resetItem")
  14205. }
  14206. },
  14207. _setHoverState: function(state, mode, legendCallback) {
  14208. this.lastHoverMode = mode = (mode || this._options.hoverMode).toLowerCase();
  14209. if (state && !this.isHovered()) {
  14210. this.fullState = this.fullState | HOVER_STATE;
  14211. !this.isSelected() && this._changeStyle(legendCallback, APPLY_HOVER)
  14212. }
  14213. else if (!state && this.isHovered()) {
  14214. this.fullState = this.fullState & ~HOVER_STATE;
  14215. !this.isSelected() && this._changeStyle(legendCallback, "resetItem")
  14216. }
  14217. },
  14218. setHoverState: function(mode, legendCallback) {
  14219. this._setHoverState(true, mode, legendCallback)
  14220. },
  14221. releaseHoverState: function(mode, legendCallback) {
  14222. this._setHoverState(false, mode, legendCallback)
  14223. },
  14224. setSelectedState: function(mode, legendCallback) {
  14225. this._setSelectedState(true, mode, legendCallback)
  14226. },
  14227. releaseSelectedState: function(mode, legendCallback) {
  14228. this._setSelectedState(false, mode, legendCallback)
  14229. },
  14230. isFullStackedSeries: function() {
  14231. return this.type.indexOf("fullstacked") === 0
  14232. },
  14233. isStackedSeries: function() {
  14234. return this.type.indexOf("stacked") === 0
  14235. },
  14236. isFinancialSeries: function() {
  14237. return this.type === "stock" || this.type === "candlestick"
  14238. },
  14239. _changeStyle: function(legendCallBack, legendAction) {
  14240. var style = this._calcStyle(),
  14241. pointStyle;
  14242. if (style.mode === NONE_MODE)
  14243. return;
  14244. legendCallBack && legendCallBack(legendAction);
  14245. if (style.mode === INCLUDE_POINTS || style.mode === ALL_SERIES_POINTS_MODE) {
  14246. pointStyle = style.pointStyle;
  14247. _each(this._points || [], function(_, p) {
  14248. !p.isSelected() && p.applyStyle(pointStyle)
  14249. })
  14250. }
  14251. this._applyStyle(style.series)
  14252. },
  14253. _calcStyle: function() {
  14254. var styles = this._styles,
  14255. isHoverIncludeModeAndSeriesExcludeMode = false,
  14256. result;
  14257. switch (this.fullState & 3) {
  14258. case 0:
  14259. result = {
  14260. pointStyle: "normal",
  14261. mode: INCLUDE_POINTS,
  14262. series: styles.normal
  14263. };
  14264. break;
  14265. case 1:
  14266. result = {
  14267. pointStyle: "hover",
  14268. mode: this.lastHoverMode,
  14269. series: styles.hover
  14270. };
  14271. break;
  14272. case 2:
  14273. result = {
  14274. pointStyle: "selection",
  14275. mode: this.lastSelectionMode,
  14276. series: styles.selection
  14277. };
  14278. break;
  14279. case 3:
  14280. isHoverIncludeModeAndSeriesExcludeMode = this.lastSelectionMode === EXLUDE_POINTS && (this.lastHoverMode === INCLUDE_POINTS || this.lastHoverMode === ALL_SERIES_POINTS_MODE);
  14281. result = {
  14282. pointStyle: isHoverIncludeModeAndSeriesExcludeMode ? "normal" : "selection",
  14283. mode: isHoverIncludeModeAndSeriesExcludeMode ? INCLUDE_POINTS : this.lastSelectionMode,
  14284. series: styles.selection
  14285. }
  14286. }
  14287. return result
  14288. },
  14289. _getMainAxisName: function() {
  14290. return this._options.rotated ? "X" : "Y"
  14291. },
  14292. areLabelsVisible: function() {
  14293. return !_isDefined(this._options.maxLabelCount) || this._points.length <= this._options.maxLabelCount
  14294. },
  14295. getLabelVisibility: function() {
  14296. return this.areLabelsVisible() && this._options.label && this._options.label.visible
  14297. },
  14298. _customizePoint: function(pointData) {
  14299. var that = this,
  14300. options = that._options,
  14301. customizePoint = that._options.customizePoint,
  14302. customizeObject,
  14303. pointOptions,
  14304. customLabelOptions,
  14305. customOptions,
  14306. customizeLabel = that._options.customizeLabel,
  14307. useLabelCustomOptions,
  14308. usePointCustomOptions;
  14309. if (customizeLabel && customizeLabel.call) {
  14310. customizeObject = _extend({
  14311. seriesName: that.name,
  14312. series: that
  14313. }, pointData);
  14314. customLabelOptions = customizeLabel.call(customizeObject, customizeObject);
  14315. useLabelCustomOptions = customLabelOptions && !_isEmptyObject(customLabelOptions);
  14316. customLabelOptions = useLabelCustomOptions ? _extend(true, {}, options.label, customLabelOptions) : null
  14317. }
  14318. if (customizePoint && customizePoint.call) {
  14319. customizeObject = customizeObject || _extend({
  14320. seriesName: that.name,
  14321. series: that
  14322. }, pointData);
  14323. customOptions = customizePoint.call(customizeObject, customizeObject);
  14324. usePointCustomOptions = customOptions && !_isEmptyObject(customOptions)
  14325. }
  14326. if (useLabelCustomOptions || usePointCustomOptions) {
  14327. pointOptions = that._parsePointOptions(that._preparePointOptions(customOptions), customLabelOptions || options.label);
  14328. pointOptions.styles.useLabelCustomOptions = useLabelCustomOptions;
  14329. pointOptions.styles.usePointCustomOptions = usePointCustomOptions
  14330. }
  14331. return pointOptions
  14332. },
  14333. _getLabelOptions: function(labelOptions, defaultColor) {
  14334. var opt = labelOptions || {},
  14335. labelFont = opt.font || {},
  14336. labelBorder = opt.border || {},
  14337. labelConnector = opt.connector || {},
  14338. labelAttributes = {
  14339. align: opt.alignment,
  14340. font: {
  14341. color: opt.backgroundColor === "none" && labelFont.color.toLowerCase() === "#ffffff" && opt.position !== "inside" ? defaultColor : labelFont.color,
  14342. family: labelFont.family,
  14343. weight: labelFont.weight,
  14344. size: labelFont.size,
  14345. opacity: labelFont.opacity
  14346. },
  14347. style: opt.style
  14348. },
  14349. backgroundAttr = {
  14350. fill: opt.backgroundColor || defaultColor,
  14351. strokeWidth: labelBorder.visible ? labelBorder.width || 0 : 0,
  14352. stroke: labelBorder.visible && labelBorder.width ? labelBorder.color : "none",
  14353. dashStyle: labelBorder.dashStyle
  14354. },
  14355. connectorAttr = {
  14356. stroke: labelConnector.visible && labelConnector.width ? labelConnector.color || defaultColor : "none",
  14357. strokeWidth: labelConnector.visible ? labelConnector.width || 0 : 0
  14358. };
  14359. return {
  14360. format: opt.format,
  14361. argumentFormat: opt.argumentFormat,
  14362. precision: opt.precision,
  14363. argumentPrecision: opt.argumentPrecision,
  14364. percentPrecision: opt.percentPrecision,
  14365. customizeText: $.isFunction(opt.customizeText) ? opt.customizeText : undefined,
  14366. attributes: labelAttributes,
  14367. visible: labelFont.size !== 0 ? opt.visible : false,
  14368. showForZeroValues: opt.showForZeroValues,
  14369. horizontalOffset: opt.horizontalOffset,
  14370. verticalOffset: opt.verticalOffset,
  14371. radialOffset: opt.radialOffset,
  14372. background: backgroundAttr,
  14373. position: opt.position,
  14374. connector: connectorAttr,
  14375. rotationAngle: opt.rotationAngle,
  14376. resolveLabelsOverlapping: this._options.resolveLabelsOverlapping
  14377. }
  14378. },
  14379. show: function() {
  14380. if (!this._visible) {
  14381. this._visible = true;
  14382. this.hidePointTooltip();
  14383. this._options.visibilityChanged()
  14384. }
  14385. },
  14386. hide: function() {
  14387. if (this._visible) {
  14388. this._visible = false;
  14389. this.hidePointTooltip();
  14390. this._options.visibilityChanged()
  14391. }
  14392. },
  14393. hideLabels: function() {
  14394. _each(this._points, function(_, point) {
  14395. point._label.hide()
  14396. })
  14397. },
  14398. _parsePointOptions: function(pointOptions, labelOptions) {
  14399. var options = this._options,
  14400. styles = this._createPointStyles(pointOptions),
  14401. parsedOptions;
  14402. parsedOptions = _extend(true, {}, pointOptions, {
  14403. type: options.type,
  14404. tag: this.tag,
  14405. rotated: options.rotated,
  14406. series: this,
  14407. styles: styles,
  14408. visibilityChanged: options.visibilityChanged
  14409. });
  14410. parsedOptions.label = this._getLabelOptions(labelOptions, styles.normal.fill);
  14411. return parsedOptions
  14412. },
  14413. _resample: function(ticks, ticksInterval) {
  14414. var that = this,
  14415. fusPoints = [],
  14416. arrayFusPoints,
  14417. nowIndexTicks = 0,
  14418. lastPointIndex = 0,
  14419. originalPoints = that.getAllPoints();
  14420. if (that.argumentAxisType === "discrete" || that.valueAxisType === "discrete") {
  14421. ticksInterval = originalPoints.length / ticks;
  14422. arrayFusPoints = $.map(originalPoints, function(point, index) {
  14423. if (Math.floor(nowIndexTicks) <= index) {
  14424. nowIndexTicks += ticksInterval;
  14425. return point
  14426. }
  14427. point.setInvisibility();
  14428. return null
  14429. });
  14430. return arrayFusPoints
  14431. }
  14432. that._aggregatedPoints = that._aggregatedPoints || [];
  14433. _each(originalPoints, function(_, point) {
  14434. switch (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval)) {
  14435. case true:
  14436. fusPoints.push(point);
  14437. break;
  14438. case"nextInterval":
  14439. var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
  14440. while (that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === "nextInterval")
  14441. nowIndexTicks++;
  14442. fusPoints = [];
  14443. that._isInInterval(point.argument, ticks, nowIndexTicks, ticksInterval) === true && fusPoints.push(point);
  14444. if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
  14445. lastPointIndex++
  14446. }
  14447. });
  14448. if (fusPoints.length) {
  14449. var pointData = that._fusionPoints(fusPoints, ticks[nowIndexTicks], nowIndexTicks);
  14450. if (that._createPoint(pointData, that._aggregatedPoints, lastPointIndex))
  14451. lastPointIndex++
  14452. }
  14453. that._correctPointsLength(lastPointIndex, that._aggregatedPoints);
  14454. that._endUpdateData();
  14455. return that._aggregatedPoints
  14456. },
  14457. _isInInterval: function(argument, ticks, nowIndexTicks, ticksInterval) {
  14458. var minTick = ticks[nowIndexTicks],
  14459. maxTick = ticks[nowIndexTicks + 1],
  14460. sumMinTickTicksInterval;
  14461. ticksInterval = $.isNumeric(ticksInterval) ? ticksInterval : utils.convertDateTickIntervalToMilliseconds(ticksInterval);
  14462. sumMinTickTicksInterval = utils.isDate(minTick) ? new Date(minTick.getTime() + ticksInterval) : minTick + ticksInterval;
  14463. if (argument >= minTick && argument < sumMinTickTicksInterval)
  14464. return true;
  14465. if (argument < minTick || maxTick === undefined)
  14466. return false;
  14467. return "nextInterval"
  14468. },
  14469. canRenderCompleteHandle: function() {
  14470. var result = this._canRenderCompleteHandle;
  14471. delete this._canRenderCompleteHandle;
  14472. return !!result
  14473. },
  14474. isHovered: function() {
  14475. return !!(this.fullState & 1)
  14476. },
  14477. isSelected: function() {
  14478. return !!(this.fullState & 2)
  14479. },
  14480. isVisible: function() {
  14481. return this._visible
  14482. },
  14483. getAllPoints: function() {
  14484. return (this._originalPoints || []).slice()
  14485. },
  14486. getPointByPos: function(pos) {
  14487. return (this._points || [])[pos]
  14488. },
  14489. getVisiblePoints: function() {
  14490. return (this._drawedPoints || []).slice()
  14491. },
  14492. setPointHoverState: function(point, legendCallback) {
  14493. point.fullState = point.fullState | HOVER_STATE;
  14494. if (!(this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) && !point.isSelected()) {
  14495. point.applyStyle("hover");
  14496. legendCallback && legendCallback("applyHover")
  14497. }
  14498. },
  14499. releasePointHoverState: function(point, legendCallback) {
  14500. point.fullState = point.fullState & ~HOVER_STATE;
  14501. if (!(this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) && !point.isSelected())
  14502. if (!(this.isHovered() && (this.lastHoverMode === ALL_SERIES_POINTS_MODE || this.lastHoverMode === INCLUDE_POINTS))) {
  14503. point.applyStyle("normal");
  14504. legendCallback && legendCallback("resetItem")
  14505. }
  14506. },
  14507. setPointSelectedState: function(point, legendCallback) {
  14508. point.fullState = point.fullState | SELECTED_STATE;
  14509. point.applyStyle("selection");
  14510. legendCallback && legendCallback("applySelected")
  14511. },
  14512. releasePointSelectedState: function(point, legendCallback) {
  14513. point.fullState = point.fullState & ~SELECTED_STATE;
  14514. if (this.isHovered() && (this.lastHoverMode === ALL_SERIES_POINTS_MODE || this.lastHoverMode === INCLUDE_POINTS) || point.isHovered()) {
  14515. point.applyStyle("hover");
  14516. legendCallback && legendCallback("applyHover")
  14517. }
  14518. else if (this.isSelected() && (this.lastSelectionMode === ALL_SERIES_POINTS_MODE || this.lastSelectionMode === INCLUDE_POINTS)) {
  14519. point.applyStyle("selection");
  14520. legendCallback && legendCallback("applySelected")
  14521. }
  14522. else {
  14523. point.applyStyle("normal");
  14524. legendCallback && legendCallback("resetItem")
  14525. }
  14526. },
  14527. selectPoint: function(point) {
  14528. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("selectpoint"), point)
  14529. },
  14530. deselectPoint: function(point) {
  14531. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("deselectpoint"), point)
  14532. },
  14533. showPointTooltip: function(point) {
  14534. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("showpointtooltip"), point)
  14535. },
  14536. hidePointTooltip: function(point) {
  14537. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("hidepointtooltip"), point)
  14538. },
  14539. select: function() {
  14540. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("selectseries", {target: this}), this._options.selectionMode);
  14541. this._group.toForeground();
  14542. this._trackersGroup && this._trackersGroup.toBackground()
  14543. },
  14544. clearSelection: function clearSelection() {
  14545. this._options.seriesGroup && this._options.seriesGroup.trigger(new _Event("deselectseries", {target: this}), this._options.selectionMode)
  14546. },
  14547. getPointByArg: function(arg) {
  14548. return this.pointsByArgument[arg.valueOf()] || null
  14549. },
  14550. _deletePoints: function() {
  14551. this._disposePoints(this._originalPoints);
  14552. this._disposePoints(this._aggregatedPoints);
  14553. this._disposePoints(this._oldPoints);
  14554. this._points = null;
  14555. this._oldPoints = null;
  14556. this._aggregatedPoints = null;
  14557. this._originalPoints = null;
  14558. this._drawedPoint = null
  14559. },
  14560. _deletePatterns: function() {
  14561. _each(this._patterns || [], function(_, pattern) {
  14562. pattern && pattern.dispose()
  14563. });
  14564. this._patterns = null
  14565. },
  14566. _deleteTrackers: function() {
  14567. var that = this;
  14568. _each(that._trackers || [], function(_, tracker) {
  14569. tracker.remove()
  14570. });
  14571. that._trackersGroup && that._trackersGroup.detach();
  14572. that._markerTrackerGroup && that._markerTrackerGroup.detach();
  14573. that._trackers = that._trackersGroup = that._markerTrackerGroup = null
  14574. },
  14575. dispose: function() {
  14576. this._deletePoints();
  14577. this._group.detach();
  14578. this._labelsGroup && this._labelsGroup.detach();
  14579. this._deletePatterns();
  14580. this._deleteTrackers();
  14581. this._group = null;
  14582. this._markersGroup = null;
  14583. this._elementsGroup = null;
  14584. this._bordersGroup = null;
  14585. this._labelsGroup = null;
  14586. this._graphics = null;
  14587. this._rangeData = null;
  14588. this._renderer = null;
  14589. this.translators = null;
  14590. this._styles = null;
  14591. this._options = null;
  14592. this._pointOptions = null;
  14593. this._drawedPoints = null;
  14594. this._aggregatedPoints = null;
  14595. this.pointsByArgument = null;
  14596. this._segments = null
  14597. },
  14598. correctPosition: _noop,
  14599. getColor: function() {
  14600. return this.getLegendStyles().normal.fill
  14601. },
  14602. getStackName: function() {
  14603. return this.type === "stackedbar" || this.type === "fullstackedbar" ? this._stackName : null
  14604. }
  14605. })
  14606. })(jQuery, DevExpress);
  14607. /*! Module viz-core, file rangeDataCalculator.js */
  14608. (function($, DX) {
  14609. var _math = Math,
  14610. _abs = _math.abs,
  14611. _min = _math.min,
  14612. _each = $.each,
  14613. _isEmptyObject = $.isEmptyObject,
  14614. _isDefined = DevExpress.utils.isDefined,
  14615. FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY = 15,
  14616. BAR_ZERO_VALUE_MARGIN_PRIORITY = 20,
  14617. SERIES_VALUE_MARGIN_PRIORITY = 20,
  14618. SERIES_LABEL_VALUE_MARGIN = 0.3,
  14619. CATEGORIES_SELECTOR = "categories",
  14620. INTERVAL_SELECTOR = "interval",
  14621. MIN_VALUE_MARGIN_SELECTOR = "minValueMargin",
  14622. MAX_VALUE_MARGIN_SELECTOR = "maxValueMargin",
  14623. MIN = "min",
  14624. MAX = "max",
  14625. MIN_VISIBLE = "minVisible",
  14626. MAX_VISIBLE = "maxVisible";
  14627. DevExpress.viz.core.series.helpers.rangeDataCalculator = function() {
  14628. var _truncateValue = function(data, minField, maxField, value) {
  14629. var min = data[minField],
  14630. max = data[maxField];
  14631. data[minField] = value < min || !_isDefined(min) ? value : data[minField];
  14632. data[maxField] = value > max || !_isDefined(max) ? value : data[maxField]
  14633. };
  14634. var _processTwoValues = function(series, point, prevPoint, highValueName, lowValueName) {
  14635. var val = point[highValueName],
  14636. minVal = point[lowValueName],
  14637. arg = point.argument,
  14638. prevVal = prevPoint && prevPoint[highValueName],
  14639. prevMinVal = prevPoint && prevPoint[lowValueName],
  14640. prevArg = prevPoint && prevPoint.argument;
  14641. point.hasValue() && _processRangeValue(series, val, minVal, prevVal, prevMinVal);
  14642. _processValue(series, "arg", arg, prevArg)
  14643. };
  14644. var _processValue = function(series, type, value, prevValue, calcInterval) {
  14645. var axis = type === "arg" ? "argument" : "value",
  14646. data = series._rangeData[type],
  14647. minInterval = data[INTERVAL_SELECTOR],
  14648. interval;
  14649. if (series[axis + "AxisType"] === "discrete") {
  14650. data[CATEGORIES_SELECTOR] = data[CATEGORIES_SELECTOR] || [];
  14651. data[CATEGORIES_SELECTOR].push(value)
  14652. }
  14653. else {
  14654. _truncateValue(data, "min", "max", value);
  14655. if (type === "arg") {
  14656. interval = (_isDefined(prevValue) ? _abs(calcInterval ? calcInterval(value, prevValue) : value - prevValue) : interval) || minInterval;
  14657. data[INTERVAL_SELECTOR] = _isDefined(interval) && (interval < minInterval || !_isDefined(minInterval)) ? interval : minInterval
  14658. }
  14659. }
  14660. };
  14661. var _addToVisibleRange = function(series, value) {
  14662. var data = series._rangeData.val,
  14663. isDiscrete = series.valueAxisType === "discrete";
  14664. if (isDiscrete) {
  14665. data.visibleCategories = data.visibleCategories || [];
  14666. data.visibleCategories.push(value)
  14667. }
  14668. else {
  14669. if (value < data.minVisible || !_isDefined(data.minVisible))
  14670. data.minVisible = value;
  14671. if (value > data.maxVisible || !_isDefined(data.maxVisible))
  14672. data.maxVisible = value
  14673. }
  14674. };
  14675. var _processRangeValue = function(series, val, minVal, prevVal, prevMinVal) {
  14676. var data = series._rangeData.val,
  14677. interval,
  14678. currentInterval = data[INTERVAL_SELECTOR];
  14679. if (series.valueAxisType === "discrete") {
  14680. data.categories = data.categories || [];
  14681. data.categories.push(val, minVal)
  14682. }
  14683. else {
  14684. _truncateValue(data, MIN, MAX, val);
  14685. _truncateValue(data, MIN, MAX, minVal)
  14686. }
  14687. };
  14688. var _unique = function(array) {
  14689. var values = {};
  14690. return $.map(array, function(item) {
  14691. var result = !values[item] ? item : null;
  14692. values[item] = true;
  14693. return result
  14694. })
  14695. };
  14696. var _processZoomArgument = function(series, zoomArgs) {
  14697. var data = series._rangeData.arg,
  14698. minArg,
  14699. maxArg;
  14700. minArg = zoomArgs.minArg < zoomArgs.maxArg ? zoomArgs.minArg : zoomArgs.maxArg;
  14701. maxArg = zoomArgs.maxArg > zoomArgs.minArg ? zoomArgs.maxArg : zoomArgs.minArg;
  14702. data.min = minArg < data.min ? minArg : data.min;
  14703. data.max = maxArg > data.max ? maxArg : data.max;
  14704. data.minVisible = minArg;
  14705. data.maxVisible = maxArg
  14706. };
  14707. var _correctZoomValue = function(series, zoomArgs) {
  14708. var minVal,
  14709. maxVal;
  14710. if (_isDefined(zoomArgs.minVal) && _isDefined(zoomArgs.maxVal)) {
  14711. minVal = zoomArgs.minVal < zoomArgs.maxVal ? zoomArgs.minVal : zoomArgs.maxVal;
  14712. maxVal = zoomArgs.maxVal > zoomArgs.minVal ? zoomArgs.maxVal : zoomArgs.minVal
  14713. }
  14714. if (_isDefined(zoomArgs.minVal)) {
  14715. series._rangeData.val.min = minVal < series._rangeData.val.min ? minVal : series._rangeData.val.min;
  14716. series._rangeData.val.minVisible = minVal
  14717. }
  14718. if (_isDefined(zoomArgs.maxVal)) {
  14719. series._rangeData.val.max = maxVal > series._rangeData.val.max ? maxVal : series._rangeData.val.max;
  14720. series._rangeData.val.maxVisible = maxVal
  14721. }
  14722. };
  14723. var _processZoomValue = function(series, zoomArgs) {
  14724. var adjustOnZoom = zoomArgs.adjustOnZoom,
  14725. points = series._points || [],
  14726. lastVisibleIndex,
  14727. prevPointAdded = false;
  14728. _each(points, function(index, point) {
  14729. var arg = point.argument,
  14730. prevPoint = index > 0 ? points[index - 1] : null;
  14731. if (adjustOnZoom && arg >= series._rangeData.arg.minVisible && arg <= series._rangeData.arg.maxVisible) {
  14732. if (!prevPointAdded) {
  14733. prevPoint && prevPoint.hasValue() && _addToVisibleRange(series, prevPoint.value);
  14734. prevPointAdded = true
  14735. }
  14736. point.hasValue() && _addToVisibleRange(series, point.value);
  14737. lastVisibleIndex = index
  14738. }
  14739. });
  14740. if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
  14741. _addToVisibleRange(series, points[lastVisibleIndex + 1].value);
  14742. _correctZoomValue(series, zoomArgs)
  14743. };
  14744. var _processZoomRangeValue = function(series, zoomArgs, maxValueName, minValueName) {
  14745. var adjustOnZoom = zoomArgs.adjustOnZoom,
  14746. points = series._points || [],
  14747. lastVisibleIndex,
  14748. prevPointAdded = false;
  14749. _each(points, function(index, point) {
  14750. var arg = point.argument,
  14751. prevPoint = index > 0 ? points[index - 1] : null;
  14752. if (adjustOnZoom && arg >= series._rangeData.arg.minVisible && arg <= series._rangeData.arg.maxVisible) {
  14753. if (!prevPointAdded) {
  14754. if (prevPoint && prevPoint.hasValue()) {
  14755. _addToVisibleRange(series, prevPoint[maxValueName]);
  14756. _addToVisibleRange(series, prevPoint[minValueName])
  14757. }
  14758. prevPointAdded = true
  14759. }
  14760. if (point.hasValue()) {
  14761. _addToVisibleRange(series, point[maxValueName]);
  14762. _addToVisibleRange(series, point[minValueName])
  14763. }
  14764. lastVisibleIndex = index
  14765. }
  14766. });
  14767. if (_isDefined(lastVisibleIndex) && lastVisibleIndex < points.length - 1 && points[lastVisibleIndex + 1].hasValue())
  14768. _addToVisibleRange(series, points[lastVisibleIndex + 1].value);
  14769. _correctZoomValue(series, zoomArgs)
  14770. };
  14771. var _processNewInterval = function(series, calcInterval) {
  14772. var data = series._rangeData,
  14773. points = series._points || [],
  14774. isArgumentAxisDiscrete = series.argumentAxisType === "discrete";
  14775. delete data.arg.interval;
  14776. _each(points, function(index, point) {
  14777. var arg = point.argument,
  14778. prevPoint = index > 0 ? points[index - 1] : null,
  14779. prevArg = prevPoint && prevPoint.argument;
  14780. !isArgumentAxisDiscrete && _processValue(series, "arg", arg, prevArg, calcInterval)
  14781. })
  14782. };
  14783. var _fillRangeData = function(series) {
  14784. var data = series._rangeData,
  14785. mainAxis = series._getMainAxisName(),
  14786. axis = mainAxis === "X" ? "Y" : "X";
  14787. data.arg.categories && (data.arg.categories = _unique(data.arg.categories));
  14788. data.val.categories && (data.val.categories = _unique(data.val.categories));
  14789. data.arg.visibleCategories && (data.arg.visibleCategories = _unique(data.arg.visibleCategories));
  14790. data.val.visibleCategories && (data.val.visibleCategories = _unique(data.val.visibleCategories));
  14791. data.arg.axisType = series.argumentAxisType;
  14792. data.arg.dataType = series.argumentType;
  14793. data.val.axisType = series.valueAxisType;
  14794. data.val.dataType = series.valueType;
  14795. data.val.isValueRange = true
  14796. };
  14797. var _setPadding = function(range, prefix, val, priority) {
  14798. range[prefix] = val;
  14799. range[prefix + "Priority"] = priority
  14800. };
  14801. var _setZeroPadding = function(range, val, prefix) {
  14802. val === 0 && _setPadding(range, prefix, 0, BAR_ZERO_VALUE_MARGIN_PRIORITY)
  14803. };
  14804. var _calculateRangeMinValue = function(series, zoomArgs) {
  14805. var data = series._rangeData.val,
  14806. minVisible = data[MIN_VISIBLE],
  14807. maxVisible = data[MAX_VISIBLE];
  14808. zoomArgs = zoomArgs || {};
  14809. if (data) {
  14810. data.alwaysCorrectMin = true;
  14811. series._rangeData.arg.keepValueMargins = true;
  14812. if (series.valueAxisType !== "logarithmic" && series.valueType !== "datetime" && series.getOptions().showZero !== false) {
  14813. data[MIN_VISIBLE] = minVisible > (zoomArgs.minVal || 0) ? zoomArgs.minVal || 0 : minVisible;
  14814. data[MAX_VISIBLE] = maxVisible < (zoomArgs.maxVal || 0) ? zoomArgs.maxVal || 0 : maxVisible;
  14815. data[MIN] = data[MIN] > 0 ? 0 : data[MIN];
  14816. _setZeroPadding(data, data[MIN], MIN_VALUE_MARGIN_SELECTOR);
  14817. data[MAX] = data[MAX] < 0 ? 0 : data[MAX];
  14818. if (data[MAX] === 0 || data[MAX] > 0 && data[MIN] < 0) {
  14819. data[MIN_VALUE_MARGIN_SELECTOR] = data[MAX_VALUE_MARGIN_SELECTOR];
  14820. data[MIN_VALUE_MARGIN_SELECTOR + "Priority"] = data[MAX_VALUE_MARGIN_SELECTOR + "Priority"]
  14821. }
  14822. _setZeroPadding(data, data[MAX], MAX_VALUE_MARGIN_SELECTOR)
  14823. }
  14824. }
  14825. };
  14826. var _processFullStackedRange = function(series) {
  14827. var data = series._rangeData.val,
  14828. isRangeEmpty = _isEmptyObject(data);
  14829. _setPadding(data, "minValueMargin", 0, FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY);
  14830. _setPadding(data, "maxValueMargin", 0, FULLSTACKED_SERIES_VALUE_MARGIN_PRIORITY);
  14831. !isRangeEmpty && (data.min = 0)
  14832. };
  14833. var _processRange = function(series, point, prevPoint) {
  14834. var val = point.value,
  14835. arg = point.argument,
  14836. prevVal = prevPoint && prevPoint.value,
  14837. prevArg = prevPoint && prevPoint.argument;
  14838. point.hasValue() && _processValue(series, "val", val, prevVal);
  14839. _processValue(series, "arg", arg, prevArg)
  14840. };
  14841. var _addLabelPaddings = function(series) {
  14842. var labelOptions = series.getOptions().label;
  14843. if (series.areLabelsVisible() && labelOptions && labelOptions.visible && labelOptions.position !== "inside")
  14844. _setPadding(series._rangeData.val, "maxValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY)
  14845. };
  14846. var _addRangeSeriesLabelPaddings = function(series) {
  14847. var data = series._rangeData.val;
  14848. if (series.areLabelsVisible() && series._options.label.visible && series._options.label.position !== "inside") {
  14849. _setPadding(data, "maxValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY);
  14850. _setPadding(data, "minValueMargin", SERIES_LABEL_VALUE_MARGIN, SERIES_VALUE_MARGIN_PRIORITY)
  14851. }
  14852. };
  14853. var _calculateRangeData = function(series, zoomArgs, calcIntervalFunction) {
  14854. var valueData = series._rangeData.val;
  14855. if (series.argumentAxisType !== "discrete" && zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {
  14856. valueData[MIN_VISIBLE] = zoomArgs.minVal;
  14857. valueData[MAX_VISIBLE] = zoomArgs.maxVal;
  14858. _processZoomArgument(series, zoomArgs);
  14859. _processZoomValue(series, zoomArgs)
  14860. }
  14861. else if (!zoomArgs && calcIntervalFunction)
  14862. _processNewInterval(series, calcIntervalFunction);
  14863. _fillRangeData(series)
  14864. };
  14865. var _calculateTwoValuesRangeData = function(series, zoomArgs, calcIntervalFunction, maxValueName, minValueName) {
  14866. var valueData = series._rangeData.val;
  14867. if (series.argumentAxisType !== "discrete" && zoomArgs && _isDefined(zoomArgs.minArg) && _isDefined(zoomArgs.maxArg)) {
  14868. valueData[MIN_VISIBLE] = zoomArgs.minVal;
  14869. valueData[MAX_VISIBLE] = zoomArgs.maxVal;
  14870. _processZoomArgument(series, zoomArgs);
  14871. _processZoomRangeValue(series, zoomArgs, maxValueName, minValueName)
  14872. }
  14873. else if (!zoomArgs && calcIntervalFunction)
  14874. _processNewInterval(series);
  14875. _fillRangeData(series)
  14876. };
  14877. return {
  14878. processRange: _processRange,
  14879. calculateRangeData: _calculateRangeData,
  14880. calculateTwoValuesRangeData: _calculateTwoValuesRangeData,
  14881. addLabelPaddings: _addLabelPaddings,
  14882. addRangeSeriesLabelPaddings: _addRangeSeriesLabelPaddings,
  14883. processFullStackedRange: _processFullStackedRange,
  14884. calculateRangeMinValue: _calculateRangeMinValue,
  14885. processTwoValues: _processTwoValues
  14886. }
  14887. }
  14888. })(jQuery, DevExpress);
  14889. /*! Module viz-core, file scatterSeries.js */
  14890. (function($, DX) {
  14891. var viz = DX.viz,
  14892. series = viz.core.series,
  14893. rangeCalculator = series.helpers.rangeDataCalculator(),
  14894. _each = $.each,
  14895. _extend = $.extend,
  14896. _map = $.map,
  14897. _noop = $.noop,
  14898. _isDefined = DX.utils.isDefined,
  14899. _floor = Math.floor,
  14900. DEFAULT_SYMBOL_POINT_SIZE = 2,
  14901. DEFAULT_TRACKER_WIDTH = 20,
  14902. DEFAULT_DURATION = 400;
  14903. series.mixins.chart.scatter = {
  14904. _defaultDuration: DEFAULT_DURATION,
  14905. _defaultTrackerWidth: DEFAULT_TRACKER_WIDTH,
  14906. _applyStyle: _noop,
  14907. _adjustLabels: _noop,
  14908. _updateOptions: _noop,
  14909. _parseStyle: _noop,
  14910. _prepareSegment: _noop,
  14911. _drawSegment: _noop,
  14912. _generateDefaultSegments: _noop,
  14913. _prepareSeriesToDrawing: function() {
  14914. this._deleteOldAnimationMethods();
  14915. this._firstDrawing && this._clearSeries();
  14916. this._disposePoints(this._oldPoints);
  14917. this._oldPoints = null
  14918. },
  14919. _applyTrackersClippings: function() {
  14920. this._markerTrackerGroup.applySettings({clipId: this._forceClipping ? this._paneClipRectID : null})
  14921. },
  14922. updateTeamplateFieldNames: function() {
  14923. var that = this,
  14924. options = that._options;
  14925. options.valueField = that.getValueFields()[0] + that.name;
  14926. options.tagField = that.getTagField() + that.name
  14927. },
  14928. _applyElementsClipRect: function(settings) {
  14929. settings.clipId = this._paneClipRectID
  14930. },
  14931. _applyMarkerClipRect: function(settings) {
  14932. settings.clipId = this._forceClipping ? this._paneClipRectID : null
  14933. },
  14934. _createGroup: function(groupName, parent, target, settings) {
  14935. var group = parent[groupName];
  14936. if (!group)
  14937. parent[groupName] = group = this._renderer.createGroup(settings);
  14938. else
  14939. group.applySettings(settings);
  14940. group.append(target)
  14941. },
  14942. _applyClearingSettings: function(settings) {
  14943. settings.opacity = null;
  14944. settings.scale = null;
  14945. if (this._options.rotated)
  14946. settings.translateX = null;
  14947. else
  14948. settings.translateY = null
  14949. },
  14950. _createMarkerGroup: function() {
  14951. var settings = this._getPointOptions().styles.normal;
  14952. settings["class"] = "dxc-markers";
  14953. settings.opacity = 1;
  14954. this._applyMarkerClipRect(settings);
  14955. this._createGroup("_markersGroup", this, this._group, settings)
  14956. },
  14957. _createLabelGroup: function() {
  14958. var settings = {
  14959. "class": "dxc-labels",
  14960. visibility: this.getLabelVisibility() ? "visible" : "hidden"
  14961. };
  14962. this._applyElementsClipRect(settings);
  14963. this._applyClearingSettings(settings);
  14964. this._createGroup("_labelsGroup", this, this._options.labelsGroup, settings)
  14965. },
  14966. _createGroups: function(animationEnabled) {
  14967. this._createMarkerGroup();
  14968. this._createLabelGroup();
  14969. animationEnabled && this._labelsGroup && this._labelsGroup.applySettings({opacity: 0.001})
  14970. },
  14971. _getCreatingPointOptions: function() {
  14972. if (!this._predefinedPointOptions) {
  14973. var defaultPointOptions = this._getPointOptions(),
  14974. r = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.r,
  14975. strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
  14976. creatingPointOptions = _extend(true, {}, defaultPointOptions);
  14977. creatingPointOptions.styles = creatingPointOptions.styles || {};
  14978. creatingPointOptions.styles.normal = {
  14979. r: r,
  14980. strokeWidth: strokeWidth
  14981. };
  14982. this._predefinedPointOptions = creatingPointOptions
  14983. }
  14984. return this._predefinedPointOptions
  14985. },
  14986. _getSpecialColor: function(mainSeriesColor) {
  14987. return mainSeriesColor
  14988. },
  14989. _getPointOptions: function() {
  14990. return this._pointOptions || (this._pointOptions = this._parsePointOptions(this._preparePointOptions(), this._options.label))
  14991. },
  14992. _preparePointOptions: function(customOptions) {
  14993. return customOptions ? _extend(true, {}, this._options.point, customOptions) : this._options.point
  14994. },
  14995. _parsePointStyle: function(style, defaultColor, defaultBorderColor) {
  14996. var border = style.border || {};
  14997. return {
  14998. fill: style.color || defaultColor,
  14999. stroke: border.color || defaultBorderColor,
  15000. strokeWidth: border.visible ? border.width : 0,
  15001. r: style.size / 2 + (border.visible && style.size !== 0 ? ~~(border.width / 2) || 0 : 0)
  15002. }
  15003. },
  15004. _createPointStyles: function(pointOptions) {
  15005. var mainPointColor = pointOptions.color || this._options.mainSeriesColor,
  15006. containerColor = this._options.containerBackgroundColor,
  15007. normalStyle = this._parsePointStyle(pointOptions, mainPointColor, mainPointColor);
  15008. normalStyle.visibility = pointOptions.visible ? "visible" : "hidden";
  15009. return {
  15010. normal: normalStyle,
  15011. hover: this._parsePointStyle(pointOptions.hoverStyle, containerColor, mainPointColor),
  15012. selection: this._parsePointStyle(pointOptions.selectionStyle, containerColor, mainPointColor)
  15013. }
  15014. },
  15015. _checkData: function(data) {
  15016. return _isDefined(data.argument) && data.value !== undefined
  15017. },
  15018. _processRange: function(point, prevPoint) {
  15019. rangeCalculator.processRange(this, point, prevPoint)
  15020. },
  15021. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  15022. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  15023. rangeCalculator.addLabelPaddings(this);
  15024. return this._rangeData
  15025. },
  15026. _getPointData: function(data, options) {
  15027. var argumentField = options.argumentField || "arg",
  15028. valueField = options.valueField || "val",
  15029. tagField = options.tagField || "tag";
  15030. return {
  15031. value: data[valueField],
  15032. argument: data[argumentField],
  15033. tag: data[tagField]
  15034. }
  15035. },
  15036. _drawPoint: function(point, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
  15037. if (point.isInVisibleArea()) {
  15038. point.clearVisibility();
  15039. point.draw(this._renderer, markersGroup, labelsGroup, animationEnabled, firstDrawing);
  15040. this._drawedPoints.push(point)
  15041. }
  15042. else
  15043. point.setInvisibility()
  15044. },
  15045. _clearingAnimation: function(translators, drawComplete) {
  15046. var that = this,
  15047. params = {opacity: 0.001},
  15048. options = {
  15049. duration: that._defaultDuration,
  15050. partitionDuration: 0.5
  15051. };
  15052. that._labelsGroup && that._labelsGroup.animate(params, options, function() {
  15053. that._markersGroup && that._markersGroup.animate(params, options, drawComplete)
  15054. })
  15055. },
  15056. _animate: function(complete) {
  15057. var that = this,
  15058. lastPointIndex = that._drawedPoints.length - 1,
  15059. labelAnimFunc = function() {
  15060. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  15061. },
  15062. settings;
  15063. _each(that._drawedPoints || [], function(i, p) {
  15064. settings = {translate: {
  15065. x: p.x,
  15066. y: p.y
  15067. }};
  15068. p.animate(i === lastPointIndex ? labelAnimFunc : undefined, settings)
  15069. })
  15070. },
  15071. _getPointSize: function() {
  15072. return this._options.point.visible ? this._options.point.size : DEFAULT_SYMBOL_POINT_SIZE
  15073. },
  15074. _calcMedianValue: function(fusionPoints, valueField) {
  15075. var result,
  15076. allValue;
  15077. allValue = _map(fusionPoints, function(point) {
  15078. return point[valueField]
  15079. });
  15080. allValue.sort(function(a, b) {
  15081. return a - b
  15082. });
  15083. result = allValue[_floor(allValue.length / 2)];
  15084. return _isDefined(result) ? result : null
  15085. },
  15086. _fusionPoints: function(fusionPoints, tick, index) {
  15087. var result = this._calcMedianValue(fusionPoints, "value");
  15088. return {
  15089. value: result,
  15090. argument: tick,
  15091. tag: null,
  15092. index: index,
  15093. seriesName: this.name
  15094. }
  15095. },
  15096. _endUpdateData: function() {
  15097. delete this._predefinedPointOptions
  15098. },
  15099. getArgumentField: function() {
  15100. return this._options.argumentField || "arg"
  15101. },
  15102. getValueFields: function() {
  15103. return [this._options.valueField || "val"]
  15104. },
  15105. _beginUpdateData: $.noop
  15106. }
  15107. })(jQuery, DevExpress);
  15108. /*! Module viz-core, file lineSeries.js */
  15109. (function($, DX) {
  15110. var viz = DX.viz,
  15111. series = viz.core.series.mixins.chart,
  15112. utils = DX.utils,
  15113. scatterSeries = series.scatter,
  15114. _extend = $.extend,
  15115. _map = $.map,
  15116. _each = $.each;
  15117. series.line = _extend({}, scatterSeries, {
  15118. _createElementsGroup: function(elementsStyle) {
  15119. var settings = _extend({"class": "dxc-elements"}, elementsStyle);
  15120. this._applyElementsClipRect(settings);
  15121. this._createGroup("_elementsGroup", this, this._group, settings)
  15122. },
  15123. _createBordersGroup: function(borderStyle) {
  15124. var settings = _extend({"class": "dxc-borders"}, borderStyle);
  15125. this._applyElementsClipRect(settings);
  15126. this._createGroup("_bordersGroup", this, this._group, settings)
  15127. },
  15128. _applyTrackersClippings: function() {
  15129. scatterSeries._applyTrackersClippings.call(this);
  15130. this._trackersGroup.applySettings({clipId: this._paneClipRectID})
  15131. },
  15132. _createGroups: function(animationEnabled, style) {
  15133. var style = style || this._styles.normal;
  15134. this._createElementsGroup(style.elements);
  15135. this._areBordersVisible() && this._createBordersGroup(style.border);
  15136. scatterSeries._createGroups.call(this, animationEnabled, {});
  15137. animationEnabled && this._markersGroup && this._markersGroup.applySettings({opacity: 0.001})
  15138. },
  15139. _areBordersVisible: function() {
  15140. return false
  15141. },
  15142. _getDefaultSegment: function(segment) {
  15143. return {line: _map(segment.line || [], function(pt) {
  15144. return pt.getDefaultCoords()
  15145. })}
  15146. },
  15147. _prepareSegment: function(points) {
  15148. return {line: points}
  15149. },
  15150. _parseLineOptions: function(options, defaultColor) {
  15151. return {
  15152. stroke: options.color || defaultColor,
  15153. strokeWidth: options.width,
  15154. dashStyle: options.dashStyle || 'solid'
  15155. }
  15156. },
  15157. _parseStyle: function(options, defaultColor) {
  15158. return {elements: this._parseLineOptions(options, defaultColor)}
  15159. },
  15160. _applyStyle: function(style) {
  15161. this._elementsGroup && this._elementsGroup.applySettings(style.elements);
  15162. _each(this._graphics || [], function(_, graphic) {
  15163. graphic.line && graphic.line.applySettings({strokeWidth: style.elements.strokeWidth})
  15164. })
  15165. },
  15166. _drawElement: function(segment, group) {
  15167. return {line: this._createMainElement(segment.line, {strokeWidth: this._styles.normal.elements.strokeWidth}).append(group)}
  15168. },
  15169. _removeElement: function(element) {
  15170. element.line.remove()
  15171. },
  15172. _generateDefaultSegments: function() {
  15173. var that = this,
  15174. segments = [];
  15175. _each(that._segments || [], function(_, segment) {
  15176. segments.push(that._getDefaultSegment(segment))
  15177. });
  15178. return segments
  15179. },
  15180. _updateElement: function(element, segment, animate, animateParams, complete) {
  15181. var params = {points: segment.line};
  15182. animate ? element.line.animate(params, animateParams, complete) : element.line.applySettings(params)
  15183. },
  15184. _clearingAnimation: function(translator, drawComplete) {
  15185. var that = this,
  15186. lastIndex = that._graphics.length - 1,
  15187. settings = {opacity: 0.001},
  15188. options = {
  15189. duration: that._defaultDuration,
  15190. partitionDuration: 0.5
  15191. };
  15192. that._labelsGroup && that._labelsGroup.animate(settings, options, function() {
  15193. that._markersGroup && that._markersGroup.animate(settings, options, function() {
  15194. _each(that._defaultSegments || [], function(i, segment) {
  15195. that._oldUpdateElement(that._graphics[i], segment, true, {partitionDuration: 0.5}, i === lastIndex ? drawComplete : undefined)
  15196. })
  15197. })
  15198. })
  15199. },
  15200. _animate: function() {
  15201. var that = this,
  15202. lastIndex = that._graphics.length - 1;
  15203. _each(that._graphics || [], function(i, elem) {
  15204. that._updateElement(elem, that._segments[i], true, {complete: i === lastIndex ? function() {
  15205. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration});
  15206. that._markersGroup && that._markersGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  15207. } : undefined})
  15208. })
  15209. },
  15210. _drawPoint: function(point, group, labelsGroup) {
  15211. scatterSeries._drawPoint.call(this, point, group, labelsGroup)
  15212. },
  15213. _createMainElement: function(points, settings) {
  15214. return this._renderer.createPath(points, settings)
  15215. },
  15216. _drawSegment: function(points, animationEnabled, segmentCount) {
  15217. var segment = this._prepareSegment(points, this._options.rotated);
  15218. this._segments.push(segment);
  15219. if (!this._graphics[segmentCount])
  15220. this._graphics[segmentCount] = this._drawElement(animationEnabled ? this._getDefaultSegment(segment) : segment, this._elementsGroup);
  15221. else if (!animationEnabled)
  15222. this._updateElement(this._graphics[segmentCount], segment)
  15223. },
  15224. _getTrackerSettings: function() {
  15225. return {
  15226. strokeWidth: this._styles.normal.elements.strokeWidth > this._defaultTrackerWidth ? this._styles.normal.elements.strokeWidth : this._defaultTrackerWidth,
  15227. fill: "none"
  15228. }
  15229. },
  15230. _getMainPointsFromSegment: function(segment) {
  15231. return segment.line
  15232. },
  15233. _drawTrackerElement: function(segment) {
  15234. return this._createMainElement(this._getMainPointsFromSegment(segment), this._getTrackerSettings(segment))
  15235. },
  15236. _updateTrackerElement: function(segment, element) {
  15237. var settings = this._getTrackerSettings(segment);
  15238. settings.points = this._getMainPointsFromSegment(segment);
  15239. element.applySettings(settings)
  15240. }
  15241. });
  15242. series.stepline = _extend({}, series.line, {
  15243. _calculateStepLinePoints: function(points) {
  15244. var segment = [];
  15245. _each(points, function(i, pt) {
  15246. var stepY;
  15247. if (!i) {
  15248. segment.push(pt);
  15249. return
  15250. }
  15251. stepY = segment[segment.length - 1].y;
  15252. if (stepY !== pt.y) {
  15253. var point = utils.clone(pt);
  15254. point.y = stepY;
  15255. segment.push(point)
  15256. }
  15257. segment.push(pt)
  15258. });
  15259. return segment
  15260. },
  15261. _prepareSegment: function(points) {
  15262. return series.line._prepareSegment(this._calculateStepLinePoints(points))
  15263. }
  15264. });
  15265. series.stackedline = _extend({}, series.line, {});
  15266. series.fullstackedline = _extend({}, series.line, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  15267. var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
  15268. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  15269. rangeCalculator.addLabelPaddings(this);
  15270. rangeCalculator.processFullStackedRange(this);
  15271. return this._rangeData
  15272. }});
  15273. series.spline = _extend({}, series.line, {
  15274. _calculateBezierPoints: function(src, rotated) {
  15275. var bezierPoints = [],
  15276. pointsCopy = src;
  15277. var checkExtr = function(otherPointCoord, pointCoord, controlCoord) {
  15278. return otherPointCoord > pointCoord && controlCoord > otherPointCoord || otherPointCoord < pointCoord && controlCoord < otherPointCoord ? otherPointCoord : controlCoord
  15279. };
  15280. var clonePoint = function(point, newX, newY) {
  15281. var p = utils.clone(point);
  15282. p.x = newX;
  15283. p.y = newY;
  15284. return p
  15285. };
  15286. if (pointsCopy.length !== 1)
  15287. _each(pointsCopy, function(i, curPoint) {
  15288. var leftControlX,
  15289. leftControlY,
  15290. rightControlX,
  15291. rightControlY,
  15292. prevPoint,
  15293. nextPoint,
  15294. xCur,
  15295. yCur,
  15296. x1,
  15297. x2,
  15298. y1,
  15299. y2,
  15300. delta,
  15301. lambda = 0.5,
  15302. curIsExtremum,
  15303. leftPoint,
  15304. rightPoint,
  15305. a,
  15306. b,
  15307. c,
  15308. xc,
  15309. yc,
  15310. shift;
  15311. if (!i) {
  15312. bezierPoints.push(curPoint);
  15313. bezierPoints.push(curPoint);
  15314. return
  15315. }
  15316. prevPoint = pointsCopy[i - 1];
  15317. if (i < pointsCopy.length - 1) {
  15318. nextPoint = pointsCopy[i + 1];
  15319. xCur = curPoint.x;
  15320. yCur = curPoint.y;
  15321. x1 = prevPoint.x;
  15322. x2 = nextPoint.x;
  15323. y1 = prevPoint.y;
  15324. y2 = nextPoint.y;
  15325. 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));
  15326. if (curIsExtremum)
  15327. if (!rotated) {
  15328. rightControlY = leftControlY = yCur;
  15329. rightControlX = (xCur + nextPoint.x) / 2;
  15330. leftControlX = (xCur + prevPoint.x) / 2
  15331. }
  15332. else {
  15333. rightControlX = leftControlX = xCur;
  15334. rightControlY = (yCur + nextPoint.y) / 2;
  15335. leftControlY = (yCur + prevPoint.y) / 2
  15336. }
  15337. else {
  15338. a = y2 - y1;
  15339. b = x1 - x2;
  15340. c = y1 * x2 - x1 * y2;
  15341. if (!rotated) {
  15342. xc = xCur;
  15343. yc = -1 * (a * xc + c) / b;
  15344. shift = yc - yCur || 0;
  15345. y1 -= shift;
  15346. y2 -= shift
  15347. }
  15348. else {
  15349. yc = yCur;
  15350. xc = -1 * (b * yc + c) / a;
  15351. shift = xc - xCur || 0;
  15352. x1 -= shift;
  15353. x2 -= shift
  15354. }
  15355. rightControlX = (xCur + lambda * x2) / (1 + lambda);
  15356. rightControlY = (yCur + lambda * y2) / (1 + lambda);
  15357. leftControlX = (xCur + lambda * x1) / (1 + lambda);
  15358. leftControlY = (yCur + lambda * y1) / (1 + lambda)
  15359. }
  15360. if (!rotated) {
  15361. leftControlY = checkExtr(prevPoint.y, yCur, leftControlY);
  15362. rightControlY = checkExtr(nextPoint.y, yCur, rightControlY)
  15363. }
  15364. else {
  15365. leftControlX = checkExtr(prevPoint.x, xCur, leftControlX);
  15366. rightControlX = checkExtr(nextPoint.x, xCur, rightControlX)
  15367. }
  15368. leftPoint = clonePoint(curPoint, leftControlX, leftControlY);
  15369. rightPoint = clonePoint(curPoint, rightControlX, rightControlY);
  15370. bezierPoints.push(leftPoint, curPoint, rightPoint)
  15371. }
  15372. else {
  15373. bezierPoints.push(curPoint, curPoint);
  15374. return
  15375. }
  15376. });
  15377. else
  15378. bezierPoints.push(pointsCopy[0]);
  15379. return bezierPoints
  15380. },
  15381. _prepareSegment: function(points, rotated) {
  15382. return series.line._prepareSegment(this._calculateBezierPoints(points, rotated))
  15383. },
  15384. _createMainElement: function(points, settings) {
  15385. return this._renderer.createBezierPath(points, settings)
  15386. }
  15387. })
  15388. })(jQuery, DevExpress);
  15389. /*! Module viz-core, file areaSeries.js */
  15390. (function($, DX) {
  15391. var viz = DX.viz,
  15392. utils = DX.utils,
  15393. series = viz.core.series.mixins.chart,
  15394. lineSeries = series.line,
  15395. _map = $.map,
  15396. _extend = $.extend,
  15397. HOVER_COLOR_HIGHLIGHTING = 20;
  15398. series.area = _extend({}, lineSeries, {
  15399. _createBorderElement: lineSeries._createMainElement,
  15400. _processSinglePointsAreaSegment: function(points, rotated) {
  15401. if (points.length == 1) {
  15402. var p = points[0],
  15403. p1 = utils.clone(p),
  15404. coord = rotated ? "y" : "x";
  15405. p1[coord] += 1;
  15406. return [p, p1]
  15407. }
  15408. return points
  15409. },
  15410. _prepareSegment: function(points, rotated) {
  15411. var processedPoints = this._processSinglePointsAreaSegment(points, rotated);
  15412. return {
  15413. line: processedPoints,
  15414. area: _map(processedPoints, function(pt) {
  15415. return pt.getCoords()
  15416. }).concat(_map(processedPoints.slice().reverse(), function(pt) {
  15417. return pt.getCoords(true)
  15418. })),
  15419. singlePointSegment: processedPoints !== points
  15420. }
  15421. },
  15422. _getSpecialColor: function(color) {
  15423. return this._options._IE8 ? new DX.Color(color).highlight(HOVER_COLOR_HIGHLIGHTING) : color
  15424. },
  15425. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  15426. var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
  15427. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  15428. rangeCalculator.addLabelPaddings(this);
  15429. rangeCalculator.calculateRangeMinValue(this, zoomArgs);
  15430. return this._rangeData
  15431. },
  15432. _getDefaultSegment: function(segment) {
  15433. var defaultSegment = lineSeries._getDefaultSegment(segment);
  15434. defaultSegment.area = defaultSegment.line.concat(defaultSegment.line.slice().reverse());
  15435. return defaultSegment
  15436. },
  15437. _updateElement: function(element, segment, animate, animateParams, complete) {
  15438. var lineParams = {points: segment.line},
  15439. areaParams = {points: segment.area},
  15440. borderElement = element.line;
  15441. if (animate) {
  15442. borderElement && borderElement.animate(lineParams, animateParams);
  15443. element.area.animate(areaParams, animateParams, complete)
  15444. }
  15445. else {
  15446. borderElement && borderElement.applySettings(lineParams);
  15447. element.area.applySettings(areaParams)
  15448. }
  15449. },
  15450. _removeElement: function(element) {
  15451. element.line && element.line.remove();
  15452. element.area.remove()
  15453. },
  15454. _drawElement: function(segment, group) {
  15455. return {
  15456. line: this._bordersGroup && this._createBorderElement(segment.line, {strokeWidth: this._styles.normal.border.strokeWidth}).append(this._bordersGroup),
  15457. area: this._createMainElement(segment.area).append(this._elementsGroup)
  15458. }
  15459. },
  15460. _applyStyle: function(style) {
  15461. this._elementsGroup && this._elementsGroup.applySettings(style.elements);
  15462. this._bordersGroup && this._bordersGroup.applySettings(style.border);
  15463. $.each(this._graphics || [], function(_, graphic) {
  15464. graphic.line && graphic.line.applySettings({strokeWidth: style.border.strokeWidth})
  15465. })
  15466. },
  15467. _createPattern: function(color, hatching) {
  15468. if (hatching && utils.isObject(hatching)) {
  15469. var pattern = this._renderer.createPattern(color, hatching);
  15470. this._patterns.push(pattern);
  15471. return pattern.id
  15472. }
  15473. return color
  15474. },
  15475. _parseStyle: function(options, defaultColor, defaultBorderColor) {
  15476. var borderOptions = options.border || {},
  15477. borderStyle = lineSeries._parseLineOptions(borderOptions, defaultBorderColor);
  15478. borderStyle.strokeWidth = borderOptions.visible ? borderStyle.strokeWidth : 0;
  15479. return {
  15480. border: borderStyle,
  15481. elements: {
  15482. stroke: "none",
  15483. fill: this._createPattern(options.color || defaultColor, options.hatching),
  15484. opacity: options.opacity
  15485. }
  15486. }
  15487. },
  15488. _areBordersVisible: function() {
  15489. var options = this._options;
  15490. return options.border.visible || options.hoverStyle.border.visible || options.selectionStyle.border.visible
  15491. },
  15492. _createMainElement: function(points, settings) {
  15493. return this._renderer.createArea(points, settings)
  15494. },
  15495. _getTrackerSettings: function(segment) {
  15496. return {strokeWidth: segment.singlePointSegment ? this._defaultTrackerWidth : 0}
  15497. },
  15498. _getMainPointsFromSegment: function(segment) {
  15499. return segment.area
  15500. }
  15501. });
  15502. series.steparea = _extend({}, series.area, {_prepareSegment: function(points, rotated) {
  15503. points = series.area._processSinglePointsAreaSegment(points, rotated);
  15504. return series.area._prepareSegment.call(this, series.stepline._calculateStepLinePoints(points))
  15505. }});
  15506. series.splinearea = _extend({}, series.area, {
  15507. _areaPointsToSplineAreaPoints: function(areaPoints) {
  15508. var lastFwPoint = areaPoints[areaPoints.length / 2 - 1],
  15509. firstBwPoint = areaPoints[areaPoints.length / 2];
  15510. areaPoints.splice(areaPoints.length / 2, 0, {
  15511. x: lastFwPoint.x,
  15512. y: lastFwPoint.y
  15513. }, {
  15514. x: firstBwPoint.x,
  15515. y: firstBwPoint.y
  15516. });
  15517. if (lastFwPoint.defaultCoords)
  15518. areaPoints[areaPoints.length / 2].defaultCoords = true;
  15519. if (firstBwPoint.defaultCoords)
  15520. areaPoints[areaPoints.length / 2 - 1].defaultCoords = true
  15521. },
  15522. _prepareSegment: function(points, rotated) {
  15523. var areaSeries = series.area,
  15524. processedPoints = areaSeries._processSinglePointsAreaSegment(points, rotated),
  15525. areaSegment = areaSeries._prepareSegment.call(this, series.spline._calculateBezierPoints(processedPoints, rotated));
  15526. this._areaPointsToSplineAreaPoints(areaSegment.area);
  15527. areaSegment.singlePointSegment = processedPoints !== points;
  15528. return areaSegment
  15529. },
  15530. _getDefaultSegment: function(segment) {
  15531. var areaDefaultSegment = series.area._getDefaultSegment(segment);
  15532. this._areaPointsToSplineAreaPoints(areaDefaultSegment.area);
  15533. return areaDefaultSegment
  15534. },
  15535. _createMainElement: function(points, settings) {
  15536. return this._renderer.createBezierArea(points, settings)
  15537. },
  15538. _createBorderElement: series.spline._createMainElement
  15539. })
  15540. })(jQuery, DevExpress);
  15541. /*! Module viz-core, file barSeries.js */
  15542. (function($, DX) {
  15543. var viz = DX.viz,
  15544. series = viz.core.series.mixins.chart,
  15545. scatterSeries = series.scatter,
  15546. areaSeries = series.area,
  15547. _extend = $.extend,
  15548. _each = $.each,
  15549. DEFAULT_BAR_POINT_SIZE = 3;
  15550. series.bar = _extend({}, scatterSeries, {
  15551. _getSpecialColor: areaSeries._getSpecialColor,
  15552. _createPattern: areaSeries._createPattern,
  15553. _updateOptions: function(options) {
  15554. this._stackName = "axis_" + (options.axis || "default") + "_stack_" + (options.stack || "default")
  15555. },
  15556. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  15557. var rangeData = areaSeries._getRangeData.apply(this, arguments);
  15558. rangeData.arg.stick = false;
  15559. return rangeData
  15560. },
  15561. _parsePointStyle: function(style, defaultColor, defaultBorderColor) {
  15562. var color = this._createPattern(style.color || defaultColor, style.hatching),
  15563. base = scatterSeries._parsePointStyle.call(this, style, color, defaultBorderColor);
  15564. base.fill = color;
  15565. base.dashStyle = style.border && style.border.dashStyle || "solid";
  15566. delete base.r;
  15567. return base
  15568. },
  15569. _applyMarkerClipRect: function(settings) {
  15570. settings.clipId = null
  15571. },
  15572. _applyTrackersClippings: function() {
  15573. this._markerTrackerGroup.applySettings({clipId: this._paneClipRectID})
  15574. },
  15575. _clearingAnimation: function(translators, drawComplete) {
  15576. var that = this,
  15577. settings;
  15578. if (that._options.rotated)
  15579. settings = {
  15580. scale: {
  15581. x: 0.001,
  15582. y: 1
  15583. },
  15584. translate: {x: translators.x.translate("canvas_position_default")}
  15585. };
  15586. else
  15587. settings = {
  15588. scale: {
  15589. x: 1,
  15590. y: 0.001
  15591. },
  15592. translate: {y: translators.y.translate("canvas_position_default")}
  15593. };
  15594. that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {
  15595. duration: that._defaultDuration,
  15596. partitionDuration: 0.5
  15597. }, function() {
  15598. that._markersGroup.animate(settings, {partitionDuration: 0.5}, function() {
  15599. that._markersGroup.applySettings({
  15600. scale: null,
  15601. translateX: 0,
  15602. translateY: 0
  15603. });
  15604. drawComplete()
  15605. })
  15606. })
  15607. },
  15608. _createGroups: function(animationEnabled, style, firstDrawing) {
  15609. var settings = {};
  15610. scatterSeries._createGroups.apply(this, arguments);
  15611. if (animationEnabled && firstDrawing)
  15612. if (!this._options.rotated)
  15613. settings = {
  15614. scale: {
  15615. x: 1,
  15616. y: 0.001
  15617. },
  15618. translateY: this.translators.y.translate("canvas_position_default")
  15619. };
  15620. else
  15621. settings = {
  15622. scale: {
  15623. x: 0.001,
  15624. y: 1
  15625. },
  15626. translateX: this.translators.x.translate("canvas_position_default")
  15627. };
  15628. else if (!animationEnabled)
  15629. settings = {
  15630. scale: {
  15631. x: 1,
  15632. y: 1
  15633. },
  15634. translateX: 0,
  15635. translateY: 0
  15636. };
  15637. this._markersGroup.applySettings(settings)
  15638. },
  15639. _drawPoint: function(point, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
  15640. scatterSeries._drawPoint.call(this, point, markersGroup, labelsGroup, animationEnabled && !firstDrawing)
  15641. },
  15642. _getMainColor: function() {
  15643. return this._options.mainSeriesColor
  15644. },
  15645. _createPointStyles: function(pointOptions) {
  15646. var mainColor = pointOptions.color || this._getMainColor(),
  15647. specialMainColor = this._getSpecialColor(mainColor);
  15648. return {
  15649. normal: this._parsePointStyle(pointOptions, mainColor, mainColor),
  15650. hover: this._parsePointStyle(pointOptions.hoverStyle || {}, specialMainColor, mainColor),
  15651. selection: this._parsePointStyle(pointOptions.selectionStyle || {}, specialMainColor, mainColor)
  15652. }
  15653. },
  15654. _preparePointOptions: function(customOptions) {
  15655. return customOptions ? _extend(true, {}, this._options, customOptions) : this._options
  15656. },
  15657. _animate: function(firstDrawing) {
  15658. var that = this,
  15659. labelAnimFunc = function() {
  15660. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  15661. },
  15662. lastPointIndex;
  15663. that._markersGroup.animate({
  15664. scale: {
  15665. x: 1,
  15666. y: 1
  15667. },
  15668. translate: {
  15669. y: 0,
  15670. x: 0
  15671. }
  15672. }, undefined, labelAnimFunc);
  15673. if (!firstDrawing) {
  15674. lastPointIndex = that._drawedPoints.length - 1;
  15675. _each(this._drawedPoints || [], function(i, point) {
  15676. point.animate(i === lastPointIndex ? labelAnimFunc : undefined, {
  15677. x: point.x,
  15678. y: point.y,
  15679. height: point.height,
  15680. width: point.width
  15681. })
  15682. })
  15683. }
  15684. },
  15685. _getPointSize: function() {
  15686. return DEFAULT_BAR_POINT_SIZE
  15687. }
  15688. })
  15689. })(jQuery, DevExpress);
  15690. /*! Module viz-core, file rangeSeries.js */
  15691. (function($, DX) {
  15692. var viz = DX.viz,
  15693. series = viz.core.series.mixins.chart,
  15694. _extend = $.extend,
  15695. _isDefined = DX.utils.isDefined,
  15696. _map = $.map,
  15697. rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
  15698. areaSeries = series.area;
  15699. var baseRangeSeries = {
  15700. _checkData: function(data) {
  15701. return _isDefined(data.argument) && data.value !== undefined && data.minValue !== undefined
  15702. },
  15703. updateTeamplateFieldNames: function() {
  15704. var that = this,
  15705. options = that._options,
  15706. valueFields = that.getValueFields(),
  15707. name = that.name;
  15708. options.rangeValue1Field = valueFields[0] + name;
  15709. options.rangeValue2Field = valueFields[1] + name;
  15710. options.tagField = that.getTagField() + name
  15711. },
  15712. _processRange: function(point, prevPoint) {
  15713. rangeCalculator.processTwoValues(this, point, prevPoint, "value", "minValue")
  15714. },
  15715. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  15716. rangeCalculator.calculateTwoValuesRangeData(this, zoomArgs, calcIntervalFunction, "value", "minValue");
  15717. rangeCalculator.addRangeSeriesLabelPaddings(this);
  15718. return this._rangeData
  15719. },
  15720. _getPointData: function(data, options) {
  15721. var argumentField = options.argumentField || "arg",
  15722. tagField = options.tagField || "tag",
  15723. rangeValue1Field = options.rangeValue1Field || "val1",
  15724. rangeValue2Field = options.rangeValue2Field || "val2";
  15725. return {
  15726. tag: data[tagField],
  15727. minValue: data[rangeValue1Field],
  15728. value: data[rangeValue2Field],
  15729. argument: data[argumentField]
  15730. }
  15731. },
  15732. _fusionPoints: function(fusionPoints, tick, index) {
  15733. var scatterSeries = series.scatter,
  15734. value = scatterSeries._calcMedianValue.call(this, fusionPoints, "value"),
  15735. minValue = scatterSeries._calcMedianValue.call(this, fusionPoints, "minValue"),
  15736. pointData;
  15737. if (value === null || minValue === null)
  15738. value = minValue = null;
  15739. pointData = {
  15740. minValue: minValue,
  15741. value: value,
  15742. argument: tick,
  15743. tag: null
  15744. };
  15745. return pointData
  15746. },
  15747. getValueFields: function() {
  15748. return [this._options.rangeValue1Field || "val1", this._options.rangeValue2Field || "val2"]
  15749. }
  15750. };
  15751. series.rangebar = _extend({}, series.bar, baseRangeSeries);
  15752. series.rangearea = _extend({}, areaSeries, {
  15753. _drawPoint: function(point, markersGroup, labelsGroup, animationEnabled) {
  15754. if (point.isInVisibleArea()) {
  15755. point.clearVisibility();
  15756. point.draw(this._renderer, markersGroup, labelsGroup, animationEnabled);
  15757. this._drawedPoints.push(point);
  15758. if (!point.visibleTopMarker)
  15759. point.hideMarker("top");
  15760. if (!point.visibleBottomMarker)
  15761. point.hideMarker("bottom")
  15762. }
  15763. else
  15764. point.setInvisibility()
  15765. },
  15766. _prepareSegment: function(points, rotated) {
  15767. var processedPoints = this._processSinglePointsAreaSegment(points, rotated),
  15768. processedMinPointsCoords = $.map(processedPoints, function(pt) {
  15769. return pt.getCoords(true)
  15770. });
  15771. return {
  15772. line: processedPoints,
  15773. bottomLine: processedMinPointsCoords,
  15774. area: $.map(processedPoints, function(pt) {
  15775. return pt.getCoords()
  15776. }).concat(processedMinPointsCoords.slice().reverse()),
  15777. singlePointSegment: processedPoints !== points
  15778. }
  15779. },
  15780. _getDefaultSegment: function(segment) {
  15781. var defaultSegment = areaSeries._getDefaultSegment.call(this, segment);
  15782. defaultSegment.bottomLine = defaultSegment.line;
  15783. return defaultSegment
  15784. },
  15785. _removeElement: function(element) {
  15786. areaSeries._removeElement.call(this, element);
  15787. element.bottomLine && element.bottomLine.remove()
  15788. },
  15789. _drawElement: function(segment, group) {
  15790. var drawnElement = areaSeries._drawElement.call(this, segment, group);
  15791. drawnElement.bottomLine = this._bordersGroup && this._createBorderElement(segment.bottomLine, {strokeWidth: this._styles.normal.border.strokeWidth}).append(this._bordersGroup);
  15792. return drawnElement
  15793. },
  15794. _applyStyle: function(style) {
  15795. this._elementsGroup && this._elementsGroup.applySettings(style.elements);
  15796. this._bordersGroup && this._bordersGroup.applySettings(style.border);
  15797. $.each(this._graphics || [], function(_, graphic) {
  15798. graphic.line && graphic.line.applySettings({strokeWidth: style.border.strokeWidth});
  15799. graphic.bottomLine && graphic.bottomLine.applySettings({strokeWidth: style.border.strokeWidth})
  15800. })
  15801. },
  15802. _updateElement: function(element, segment, animate, animateParams, complete) {
  15803. areaSeries._updateElement.call(this, element, segment, animate, animateParams, complete);
  15804. var bottomLineParams = {points: segment.bottomLine},
  15805. bottomBorderElement = element.bottomLine;
  15806. if (bottomBorderElement)
  15807. animate ? bottomBorderElement.animate(bottomLineParams, animateParams) : bottomBorderElement.applySettings(bottomLineParams)
  15808. }
  15809. }, baseRangeSeries)
  15810. })(jQuery, DevExpress);
  15811. /*! Module viz-core, file bubbleSeries.js */
  15812. (function($, DX) {
  15813. var viz = DX.viz,
  15814. series = viz.core.series.mixins.chart,
  15815. scatterSeries = series.scatter,
  15816. barSeries = series.bar,
  15817. _isDefined = DX.utils.isDefined,
  15818. _extend = $.extend,
  15819. _each = $.each;
  15820. series.bubble = _extend({}, scatterSeries, {
  15821. _applyTrackersClippings: barSeries._applyTrackersClippings,
  15822. _getMainColor: barSeries._getMainColor,
  15823. _createPointStyles: barSeries._createPointStyles,
  15824. _createPattern: barSeries._createPattern,
  15825. _preparePointOptions: barSeries._preparePointOptions,
  15826. _getSpecialColor: barSeries._getSpecialColor,
  15827. _applyMarkerClipRect: series.line._applyElementsClipRect,
  15828. _parsePointStyle: function(style, defaultColor, defaultBorderColor) {
  15829. var base = barSeries._parsePointStyle.call(this, style, defaultColor, defaultBorderColor);
  15830. base.opacity = style.opacity;
  15831. return base
  15832. },
  15833. _createMarkerGroup: function() {
  15834. var markersSettings = this._getPointOptions().styles.normal,
  15835. groupSettings;
  15836. markersSettings["class"] = "dxc-markers";
  15837. this._applyMarkerClipRect(markersSettings);
  15838. groupSettings = _extend({}, markersSettings);
  15839. delete groupSettings.opacity;
  15840. this._createGroup("_markersGroup", this, this._group, groupSettings)
  15841. },
  15842. _getCreatingPointOptions: function() {
  15843. if (!this._predefinedPointOptions) {
  15844. var styles,
  15845. defaultPointOptions = this._getPointOptions(),
  15846. strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
  15847. r = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.r,
  15848. opacity = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.opacity,
  15849. creatingPointOptions = _extend(true, {}, defaultPointOptions);
  15850. creatingPointOptions.styles = styles = creatingPointOptions.styles || {};
  15851. styles.normal = {
  15852. strokeWidth: strokeWidth,
  15853. r: r,
  15854. opacity: opacity
  15855. };
  15856. this._predefinedPointOptions = creatingPointOptions
  15857. }
  15858. return this._predefinedPointOptions
  15859. },
  15860. _checkData: function(data) {
  15861. return _isDefined(data.argument) && _isDefined(data.size) && data.value !== undefined
  15862. },
  15863. _getPointData: function(data, options) {
  15864. var pointData = scatterSeries._getPointData.call(this, data, options),
  15865. sizeField = options.sizeField || "size";
  15866. pointData.size = data[sizeField];
  15867. return pointData
  15868. },
  15869. _fusionPoints: function(fusionPoints, tick, index) {
  15870. var medianValue = scatterSeries._calcMedianValue.call(this, fusionPoints, "value"),
  15871. medianSize = scatterSeries._calcMedianValue.call(this, fusionPoints, "size");
  15872. return {
  15873. size: medianSize,
  15874. value: medianValue,
  15875. argument: tick,
  15876. tag: null
  15877. }
  15878. },
  15879. getValueFields: function() {
  15880. return [this._options.valueField || "val", this._options.sizeField || "size"]
  15881. },
  15882. updateTeamplateFieldNames: function() {
  15883. var that = this,
  15884. options = that._options,
  15885. valueFields = that.getValueFields(),
  15886. name = that.name;
  15887. options.valueField = valueFields[0] + name;
  15888. options.sizeField = valueFields[1] + name;
  15889. options.tagField = that.getTagField() + name
  15890. },
  15891. _clearingAnimation: function(translators, drawComplete) {
  15892. var that = this,
  15893. settings = {r: 0},
  15894. partitionDuration = 0.5,
  15895. lastPointIndex = that._drawedPoints.length - 1;
  15896. that._labelsGroup && that._labelsGroup.animate({opacity: 0.001}, {
  15897. duration: that._defaultDuration,
  15898. partitionDuration: partitionDuration
  15899. }, function() {
  15900. _each(that._drawedPoints || [], function(i, p) {
  15901. p.animate(i === lastPointIndex ? drawComplete : undefined, settings, partitionDuration)
  15902. })
  15903. })
  15904. },
  15905. _animate: function(firstDrawing) {
  15906. var that = this,
  15907. lastPointIndex = that._drawedPoints.length - 1,
  15908. labelAnimFunc = function() {
  15909. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: that._defaultDuration})
  15910. };
  15911. _each(that._drawedPoints || [], function(i, p) {
  15912. p.animate(i === lastPointIndex ? labelAnimFunc : undefined, {
  15913. r: p.bubbleSize,
  15914. translate: {
  15915. x: p.x,
  15916. y: p.y
  15917. }
  15918. })
  15919. })
  15920. }
  15921. })
  15922. })(jQuery, DevExpress);
  15923. /*! Module viz-core, file pieSeries.js */
  15924. (function($, DX) {
  15925. var viz = DX.viz,
  15926. mixins = viz.core.series.mixins,
  15927. pieSeries = mixins.pieChart,
  15928. utils = DX.utils,
  15929. scatterSeries = mixins.chart.scatter,
  15930. barSeries = mixins.chart.bar,
  15931. _extend = $.extend,
  15932. _each = $.each,
  15933. _noop = $.noop,
  15934. _map = $.map,
  15935. _isFinite = isFinite,
  15936. _max = Math.max;
  15937. pieSeries.pie = _extend({}, barSeries, {
  15938. _createLabelGroup: scatterSeries._createLabelGroup,
  15939. _createGroups: scatterSeries._createGroups,
  15940. _drawPoint: function(point) {
  15941. scatterSeries._drawPoint.apply(this, arguments);
  15942. !point.isVisible() && point.setInvisibility()
  15943. },
  15944. _applyTrackersClippings: _noop,
  15945. _processRange: _noop,
  15946. _applyElementsClipRect: _noop,
  15947. _updateDataType: _noop,
  15948. getColor: _noop,
  15949. _prepareSeriesToDrawing: _noop,
  15950. _endUpdateData: scatterSeries._prepareSeriesToDrawing,
  15951. resetLabelEllipsis: function() {
  15952. _each(this._points || [], function(_, point) {
  15953. point._label.setLabelEllipsis = false
  15954. })
  15955. },
  15956. _adjustLabels: function(firstDrawing) {
  15957. var that = this,
  15958. options = that._options,
  15959. canvas = that.canvas,
  15960. points = that._points || [],
  15961. labelsBBoxes = [],
  15962. labelsSpaces = [],
  15963. labelSpace = 0,
  15964. maxLabelLength,
  15965. paneSpaceHeight,
  15966. paneSpaceWidth,
  15967. min;
  15968. if (options.label.position !== "inside") {
  15969. _each(points, function(_, point) {
  15970. if (point._label.hasText())
  15971. labelsBBoxes.push(point._label.getTextCoords().width)
  15972. });
  15973. if (labelsBBoxes.length) {
  15974. maxLabelLength = _max.apply(null, labelsBBoxes);
  15975. _each(points, function(_, point) {
  15976. if (point._label.hasText()) {
  15977. point._label.updatePosition(maxLabelLength);
  15978. point._label.setLabelEllipsis = true
  15979. }
  15980. });
  15981. that._firstDrawing = !that.redraw && firstDrawing;
  15982. that.redraw = true
  15983. }
  15984. }
  15985. else
  15986. _each(points, function(i, point) {
  15987. if (point._label.hasText()) {
  15988. point._label.setLabelEllipsis = true;
  15989. point._label.updatePosition()
  15990. }
  15991. })
  15992. },
  15993. _getCreatingPointOptions: function() {
  15994. return this._getPointOptions()
  15995. },
  15996. _updateOptions: function(options) {
  15997. this.labelSpace = 0;
  15998. this.innerRadius = this.type === "pie" ? 0 : options.innerRadius;
  15999. this.redraw = false
  16000. },
  16001. _checkData: function(data) {
  16002. var base = barSeries._checkData(data);
  16003. return this._options.paintNullPoints ? base : base && data.value !== null
  16004. },
  16005. _createMarkerGroup: function() {
  16006. if (!this._markersGroup)
  16007. this._markersGroup = this._renderer.createGroup({"class": "dxc-markers"}).append(this._group)
  16008. },
  16009. _getMainColor: function() {
  16010. return this._options.mainSeriesColor()
  16011. },
  16012. _getPointOptions: function() {
  16013. return this._parsePointOptions(this._preparePointOptions(), this._options.label)
  16014. },
  16015. _getRangeData: function() {
  16016. return this._rangeData
  16017. },
  16018. _getArrangeTotal: function(points) {
  16019. var total = 0;
  16020. _each(points, function(_, point) {
  16021. if (point.isVisible())
  16022. total += point.initialValue
  16023. });
  16024. return total
  16025. },
  16026. _createPointStyles: function(pointOptions) {
  16027. var mainColor = pointOptions.color || this._getMainColor(),
  16028. specialMainColor = this._getSpecialColor(mainColor);
  16029. return {
  16030. normal: this._parsePointStyle(pointOptions, mainColor, mainColor),
  16031. hover: this._parsePointStyle(pointOptions.hoverStyle, specialMainColor, mainColor),
  16032. selection: this._parsePointStyle(pointOptions.selectionStyle, specialMainColor, mainColor),
  16033. legendStyles: {
  16034. normal: this._createLegendState(pointOptions, mainColor),
  16035. hover: this._createLegendState(pointOptions.hoverStyle, specialMainColor),
  16036. selection: this._createLegendState(pointOptions.selectionStyle, specialMainColor)
  16037. }
  16038. }
  16039. },
  16040. _getArrangeMinShownValue: function(points, total) {
  16041. var minSegmentSize = this._options.minSegmentSize,
  16042. totalMinSegmentSize = 0,
  16043. totalNotMinValues = 0;
  16044. total = total || points.length;
  16045. _each(points, function(_, point) {
  16046. if (point.isVisible())
  16047. if (point.initialValue < minSegmentSize * total / 360)
  16048. totalMinSegmentSize += minSegmentSize;
  16049. else
  16050. totalNotMinValues += point.initialValue
  16051. });
  16052. return totalMinSegmentSize < 360 ? minSegmentSize * totalNotMinValues / (360 - totalMinSegmentSize) : 0
  16053. },
  16054. _applyArrangeCorrection: function(points, minShownValue, total) {
  16055. var options = this._options,
  16056. isClockWise = options.segmentsDirection !== "anticlockwise",
  16057. shiftedAngle = _isFinite(options.startAngle) ? utils.normalizeAngle(options.startAngle) : 0,
  16058. minSegmentSize = options.minSegmentSize,
  16059. percent,
  16060. correction = 0,
  16061. zeroTotalCorrection = 0;
  16062. if (total === 0) {
  16063. total = points.length;
  16064. zeroTotalCorrection = 1
  16065. }
  16066. _each(isClockWise ? points : points.concat([]).reverse(), function(_, point) {
  16067. var val = point.isVisible() ? zeroTotalCorrection || point.initialValue : 0,
  16068. updatedZeroValue;
  16069. if (minSegmentSize && point.isVisible() && val < minShownValue)
  16070. updatedZeroValue = minShownValue;
  16071. percent = val / total;
  16072. point.correctValue(correction, percent, zeroTotalCorrection + (updatedZeroValue || 0));
  16073. point.shiftedAngle = shiftedAngle;
  16074. correction = correction + (updatedZeroValue || val)
  16075. });
  16076. this._rangeData = {val: {
  16077. min: 0,
  16078. max: correction
  16079. }}
  16080. },
  16081. arrangePoints: function() {
  16082. var that = this,
  16083. minSegmentSize = that._options.minSegmentSize,
  16084. minShownValue,
  16085. pointIndex = 0,
  16086. total,
  16087. points = that._originalPoints = that._points = _map(that._originalPoints || [], function(point) {
  16088. if (point.value === null || point.value < 0 || point.value === 0 && !minSegmentSize) {
  16089. point.dispose();
  16090. return null
  16091. }
  16092. else {
  16093. point.index = pointIndex++;
  16094. return point
  16095. }
  16096. });
  16097. total = that._getArrangeTotal(points);
  16098. if (minSegmentSize)
  16099. minShownValue = this._getArrangeMinShownValue(points, total);
  16100. that._applyArrangeCorrection(points, minShownValue, total)
  16101. },
  16102. correctPosition: function(correction) {
  16103. var debug = DX.utils.debug;
  16104. debug.assert(correction, "correction was not passed");
  16105. debug.assertParam(correction.centerX, "correction.centerX was not passed");
  16106. debug.assertParam(correction.centerY, "correction.centerY was not passed");
  16107. debug.assertParam(correction.radiusInner, "correction.radiusInner was not passed");
  16108. debug.assertParam(correction.radiusOuter, "correction.radiusOuter was not passed");
  16109. _each(this._points, function(_, point) {
  16110. point.correctPosition(correction)
  16111. })
  16112. },
  16113. _animate: function(firstDrawing) {
  16114. var that = this,
  16115. index = 0,
  16116. timeThreshold = 0.2,
  16117. points = that._points,
  16118. pointsCount = points && points.length,
  16119. duration = 1 / (timeThreshold * (pointsCount - 1) + 1),
  16120. animateP = function() {
  16121. points[index] && points[index++].animate(index === pointsCount ? completeFunc : undefined, duration, stepFunc)
  16122. },
  16123. stepFunc = function(_, progress) {
  16124. if (progress >= timeThreshold) {
  16125. this.step = null;
  16126. animateP()
  16127. }
  16128. },
  16129. completeFunc = function() {
  16130. that._labelsGroup && that._labelsGroup.animate({opacity: 1}, {duration: 400})
  16131. };
  16132. if (firstDrawing)
  16133. animateP();
  16134. else
  16135. $.each(points, function(i, p) {
  16136. p.animate(i == pointsCount - 1 ? completeFunc : undefined)
  16137. })
  16138. },
  16139. getVisiblePoints: function() {
  16140. return _map(this._points, function(p) {
  16141. return p.isVisible() ? p : null
  16142. })
  16143. },
  16144. _beginUpdateData: function() {
  16145. this._deletePatterns();
  16146. this._patterns = []
  16147. }
  16148. });
  16149. pieSeries.doughnut = pieSeries.donut = pieSeries.pie
  16150. })(jQuery, DevExpress);
  16151. /*! Module viz-core, file financialSeries.js */
  16152. (function($, DX) {
  16153. var viz = DX.viz,
  16154. series = viz.core.series.mixins.chart,
  16155. scatterSeries = series.scatter,
  16156. barSeries = series.bar,
  16157. rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
  16158. _isDefined = DX.utils.isDefined,
  16159. _extend = $.extend,
  16160. _each = $.each,
  16161. _noop = $.noop,
  16162. DEFAULT_FINANCIAL_POINT_SIZE = 10;
  16163. series.stock = _extend({}, scatterSeries, {
  16164. _animate: _noop,
  16165. _applyMarkerClipRect: series.line._applyElementsClipRect,
  16166. _applyTrackersClippings: barSeries._applyTrackersClippings,
  16167. _createPattern: barSeries._createPattern,
  16168. _preparePointOptions: barSeries._preparePointOptions,
  16169. _createMarkerGroup: function() {
  16170. var that = this,
  16171. markersGroup,
  16172. styles = that._getPointOptions().styles,
  16173. defaultStyle = styles.normal,
  16174. defaultPositiveStyle = styles.positive.normal,
  16175. reductionStyle = styles.reduction.normal,
  16176. reductionPositiveStyle = styles.reductionPositive.normal,
  16177. markerSettings = {"class": "dxc-markers"};
  16178. that._applyMarkerClipRect(markerSettings);
  16179. defaultStyle["class"] = "default-markers";
  16180. defaultPositiveStyle["class"] = "default-positive-markers";
  16181. reductionStyle["class"] = "reduction-markers";
  16182. reductionPositiveStyle["class"] = "reduction-positive-markers";
  16183. that._createGroup("_markersGroup", that, that._group, markerSettings);
  16184. markersGroup = that._markersGroup;
  16185. that._createGroup("defaultMarkersGroup", markersGroup, markersGroup, defaultStyle);
  16186. that._createGroup("reductionMarkersGroup", markersGroup, markersGroup, reductionStyle);
  16187. that._createGroup("defaultPositiveMarkersGroup", markersGroup, markersGroup, defaultPositiveStyle);
  16188. that._createGroup("reductionPositiveMarkersGroup", markersGroup, markersGroup, reductionPositiveStyle)
  16189. },
  16190. _createGroups: function() {
  16191. scatterSeries._createGroups.call(this, false)
  16192. },
  16193. _clearingAnimation: function(translators, drawComplete) {
  16194. drawComplete()
  16195. },
  16196. _getCreatingPointOptions: function() {
  16197. if (!this._predefinedPointOptions) {
  16198. var styles,
  16199. defaultPointOptions = this._getPointOptions(),
  16200. strokeWidth = defaultPointOptions.styles && defaultPointOptions.styles.normal && defaultPointOptions.styles.normal.strokeWidth,
  16201. creatingPointOptions = _extend(true, {}, defaultPointOptions);
  16202. creatingPointOptions.styles = styles = creatingPointOptions.styles || {};
  16203. styles.normal = styles.positive.normal = styles.reduction.normal = styles.reductionPositive.normal = {strokeWidth: strokeWidth};
  16204. this._predefinedPointOptions = creatingPointOptions
  16205. }
  16206. return this._predefinedPointOptions
  16207. },
  16208. _checkData: function(data) {
  16209. return _isDefined(data.argument) && data.highValue !== undefined && data.lowValue !== undefined && data.openValue !== undefined && data.closeValue !== undefined
  16210. },
  16211. _processRange: function(point, prevPoint) {
  16212. rangeCalculator.processTwoValues(this, point, prevPoint, "highValue", "lowValue")
  16213. },
  16214. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  16215. rangeCalculator.calculateTwoValuesRangeData(this, zoomArgs, calcIntervalFunction, "highValue", "lowValue");
  16216. rangeCalculator.addRangeSeriesLabelPaddings(this);
  16217. return this._rangeData
  16218. },
  16219. _getPointData: function(data, options) {
  16220. var that = this,
  16221. level,
  16222. argumentField = options.argumentField || "date",
  16223. tagField = options.tagField || "tag",
  16224. openValueField = options.openValueField || "open",
  16225. closeValueField = options.closeValueField || "close",
  16226. highValueField = options.highValueField || "high",
  16227. lowValueField = options.lowValueField || "low",
  16228. reductionValue;
  16229. that.level = options.reduction.level;
  16230. switch ((that.level || "").toLowerCase()) {
  16231. case"open":
  16232. level = openValueField;
  16233. break;
  16234. case"high":
  16235. level = highValueField;
  16236. break;
  16237. case"low":
  16238. level = lowValueField;
  16239. break;
  16240. default:
  16241. level = closeValueField;
  16242. that.level = "close";
  16243. break
  16244. }
  16245. reductionValue = data[level];
  16246. return {
  16247. argument: data[argumentField],
  16248. highValue: data[highValueField],
  16249. lowValue: data[lowValueField],
  16250. closeValue: data[closeValueField],
  16251. openValue: data[openValueField],
  16252. reductionValue: reductionValue,
  16253. tag: data[tagField],
  16254. isReduction: this._checkReduction(reductionValue)
  16255. }
  16256. },
  16257. _parsePointStyle: function(style, defaultColor, innerColor) {
  16258. return {
  16259. stroke: style.color || defaultColor,
  16260. strokeWidth: style.width,
  16261. fill: style.color || innerColor
  16262. }
  16263. },
  16264. updateTeamplateFieldNames: function() {
  16265. var that = this,
  16266. options = that._options,
  16267. valueFields = that.getValueFields(),
  16268. name = that.name;
  16269. options.openValueField = valueFields[0] + name;
  16270. options.highValueField = valueFields[1] + name;
  16271. options.lowValueField = valueFields[2] + name;
  16272. options.closeValueField = valueFields[3] + name;
  16273. options.tagField = that.getTagField() + name
  16274. },
  16275. _getDefaultStyle: function(options) {
  16276. var mainPointColor = options.color || this._options.mainSeriesColor;
  16277. return {
  16278. normal: this._parsePointStyle(options, mainPointColor, mainPointColor),
  16279. hover: this._parsePointStyle(options.hoverStyle, mainPointColor, mainPointColor),
  16280. selection: this._parsePointStyle(options.selectionStyle, mainPointColor, mainPointColor)
  16281. }
  16282. },
  16283. _getReductionStyle: function(options) {
  16284. var reductionColor = options.reduction.color,
  16285. normalStyle = this._parsePointStyle({
  16286. color: reductionColor,
  16287. width: options.width,
  16288. hatching: options.hatching
  16289. }, reductionColor, reductionColor);
  16290. return {
  16291. normal: normalStyle,
  16292. hover: this._parsePointStyle(options.hoverStyle, reductionColor, reductionColor),
  16293. selection: this._parsePointStyle(options.selectionStyle, reductionColor, reductionColor)
  16294. }
  16295. },
  16296. _createPointStyles: function(pointOptions) {
  16297. var that = this,
  16298. innerColor = that._options.innerColor,
  16299. styles = that._getDefaultStyle(pointOptions),
  16300. positiveStyle,
  16301. reductionStyle,
  16302. reductionPositiveStyle;
  16303. positiveStyle = _extend(true, {}, styles);
  16304. reductionStyle = that._getReductionStyle(pointOptions);
  16305. reductionPositiveStyle = _extend(true, {}, reductionStyle);
  16306. positiveStyle.normal.fill = positiveStyle.hover.fill = positiveStyle.selection.fill = innerColor;
  16307. reductionPositiveStyle.normal.fill = reductionPositiveStyle.hover.fill = reductionPositiveStyle.selection.fill = innerColor;
  16308. styles.positive = positiveStyle;
  16309. styles.reduction = reductionStyle;
  16310. styles.reductionPositive = reductionPositiveStyle;
  16311. return styles
  16312. },
  16313. _endUpdateData: function() {
  16314. delete this.prevLevelValue;
  16315. delete this._predefinedPointOptions
  16316. },
  16317. _checkReduction: function(value) {
  16318. var result = false;
  16319. if (value != null) {
  16320. if (_isDefined(this.prevLevelValue))
  16321. result = value < this.prevLevelValue;
  16322. this.prevLevelValue = value
  16323. }
  16324. return result
  16325. },
  16326. _fusionPoints: function(fusionPoints, tick, nowIndexTicks) {
  16327. var fusedPointData = {},
  16328. reductionLevel,
  16329. highValue = -Infinity,
  16330. lowValue = +Infinity,
  16331. openValue,
  16332. closeValue;
  16333. if (!fusionPoints.length)
  16334. return {};
  16335. _each(fusionPoints, function(_, point) {
  16336. if (!point.hasValue())
  16337. return;
  16338. highValue = Math.max(highValue, point.highValue);
  16339. lowValue = Math.min(lowValue, point.lowValue);
  16340. openValue = openValue !== undefined ? openValue : point.openValue;
  16341. closeValue = point.closeValue !== undefined ? point.closeValue : closeValue
  16342. });
  16343. fusedPointData.argument = tick;
  16344. fusedPointData.openValue = openValue;
  16345. fusedPointData.closeValue = closeValue;
  16346. fusedPointData.highValue = highValue;
  16347. fusedPointData.lowValue = lowValue;
  16348. fusedPointData.tag = null;
  16349. switch ((this.level || "").toLowerCase()) {
  16350. case"open":
  16351. reductionLevel = openValue;
  16352. break;
  16353. case"high":
  16354. reductionLevel = highValue;
  16355. break;
  16356. case"low":
  16357. reductionLevel = lowValue;
  16358. break;
  16359. default:
  16360. reductionLevel = closeValue;
  16361. break
  16362. }
  16363. fusedPointData.reductionValue = reductionLevel;
  16364. fusedPointData.isReduction = this._checkReduction(reductionLevel);
  16365. return fusedPointData
  16366. },
  16367. _getPointSize: function() {
  16368. return DEFAULT_FINANCIAL_POINT_SIZE
  16369. },
  16370. getValueFields: function() {
  16371. var options = this._options;
  16372. return [options.openValueField || "open", options.highValueField || "high", options.lowValueField || "low", options.closeValueField || "close"]
  16373. },
  16374. getArgumentField: function() {
  16375. return this._options.argumentField || "date"
  16376. }
  16377. });
  16378. series.candlestick = _extend({}, series.stock, {_parsePointStyle: function(style, defaultColor, innerColor) {
  16379. var color = this._createPattern(style.color || innerColor, style.hatching),
  16380. base = series.stock._parsePointStyle.call(this, style, defaultColor, color);
  16381. base.fill = color;
  16382. return base
  16383. }})
  16384. })(jQuery, DevExpress);
  16385. /*! Module viz-core, file stackedSeries.js */
  16386. (function($, DX) {
  16387. var viz = DX.viz,
  16388. series = viz.core.series.mixins.chart,
  16389. areaSeries = series.area,
  16390. barSeries = series.bar,
  16391. lineSeries = series.line,
  16392. rangeCalculator = viz.core.series.helpers.rangeDataCalculator(),
  16393. _extend = $.extend,
  16394. _noop = $.noop,
  16395. baseStackedSeries = {
  16396. _processRange: _noop,
  16397. _processStackedRange: function() {
  16398. var that = this,
  16399. prevPoint;
  16400. $.each(that.getAllPoints(), function(i, p) {
  16401. rangeCalculator.processRange(that, p, prevPoint);
  16402. prevPoint = p
  16403. })
  16404. },
  16405. _getRangeData: function() {
  16406. this._processStackedRange();
  16407. return areaSeries._getRangeData.apply(this, arguments)
  16408. }
  16409. },
  16410. baseFullStackedSeries = _extend({}, baseStackedSeries, {
  16411. _getRangeData: function(zoomArgs, calcIntervalFunction) {
  16412. this._processStackedRange();
  16413. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  16414. rangeCalculator.addLabelPaddings(this);
  16415. rangeCalculator.processFullStackedRange(this);
  16416. rangeCalculator.calculateRangeMinValue(this, zoomArgs);
  16417. return this._rangeData
  16418. },
  16419. isFullStackedSeries: function() {
  16420. return true
  16421. }
  16422. });
  16423. series.stackedline = _extend({}, lineSeries, baseStackedSeries, {_getRangeData: function() {
  16424. this._processStackedRange();
  16425. return lineSeries._getRangeData.apply(this, arguments)
  16426. }});
  16427. series.fullstackedline = _extend({}, lineSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  16428. this._processStackedRange();
  16429. var rangeCalculator = viz.core.series.helpers.rangeDataCalculator();
  16430. rangeCalculator.calculateRangeData(this, zoomArgs, calcIntervalFunction);
  16431. rangeCalculator.addLabelPaddings(this);
  16432. rangeCalculator.processFullStackedRange(this);
  16433. return this._rangeData
  16434. }});
  16435. series.stackedbar = _extend({}, barSeries, baseStackedSeries, {_getRangeData: function() {
  16436. this._processStackedRange();
  16437. return barSeries._getRangeData.apply(this, arguments)
  16438. }});
  16439. series.fullstackedbar = _extend({}, barSeries, baseFullStackedSeries, {_getRangeData: function(zoomArgs, calcIntervalFunction) {
  16440. var rangeData = baseFullStackedSeries._getRangeData.apply(this, arguments);
  16441. rangeData.arg.stick = false;
  16442. return rangeData
  16443. }});
  16444. series.stackedarea = _extend({}, areaSeries, baseStackedSeries);
  16445. series.fullstackedarea = _extend({}, areaSeries, baseFullStackedSeries)
  16446. })(jQuery, DevExpress);
  16447. /*! Module viz-core, file basePoint.js */
  16448. (function($, DX) {
  16449. var viz = DX.viz,
  16450. statesConsts = viz.core.series.helpers.consts.states,
  16451. _each = $.each,
  16452. _extend = $.extend,
  16453. _isDefined = DX.utils.isDefined,
  16454. _noop = $.noop,
  16455. pointTypes = {
  16456. scatter: "symbolPoint",
  16457. line: "symbolPoint",
  16458. spline: "symbolPoint",
  16459. stepline: "symbolPoint",
  16460. stackedline: "symbolPoint",
  16461. fullstackedline: "symbolPoint",
  16462. area: "symbolPoint",
  16463. splinearea: "symbolPoint",
  16464. steparea: "symbolPoint",
  16465. stackedarea: "symbolPoint",
  16466. fullstackedarea: "symbolPoint",
  16467. rangearea: "rangeSymbolPoint",
  16468. bar: "barPoint",
  16469. stackedbar: "barPoint",
  16470. fullstackedbar: "barPoint",
  16471. rangebar: "rangeBarPoint",
  16472. bubble: "bubblePoint",
  16473. pie: "piePoint",
  16474. doughnut: "piePoint",
  16475. donut: "piePoint",
  16476. stock: "stockPoint",
  16477. candlestick: "candlestickPoint"
  16478. };
  16479. viz.core.series.points = {};
  16480. viz.core.series.points.Point = DX.Class.inherit({
  16481. ctor: function(dataItem, options) {
  16482. this.update(dataItem, options);
  16483. this._emptySettings = {
  16484. fill: null,
  16485. stroke: null,
  16486. dashStyle: null
  16487. }
  16488. },
  16489. getColor: function() {
  16490. return this._styles.normal.fill || this.series.getColor()
  16491. },
  16492. _getStyle: function() {
  16493. var styles = this._styles,
  16494. style;
  16495. if (this.isSelected())
  16496. style = styles.selection;
  16497. else if (this.isHovered())
  16498. style = styles.hover;
  16499. else {
  16500. this.fullState = statesConsts.normalMark;
  16501. style = styles.normal
  16502. }
  16503. return style
  16504. },
  16505. update: function(dataItem, options) {
  16506. this.updateOptions(options);
  16507. this.updateData(dataItem)
  16508. },
  16509. updateData: function(dataItem) {
  16510. this._updateData(dataItem);
  16511. if (!this.hasValue())
  16512. this.setInvisibility();
  16513. else {
  16514. this._updateLabelData();
  16515. this._fillStyle()
  16516. }
  16517. },
  16518. deleteMarker: function() {
  16519. this.graphic && this.graphic.detach();
  16520. this.graphic = null
  16521. },
  16522. deleteTrackerMarker: function() {
  16523. this.trackerGraphic && this.trackerGraphic.remove();
  16524. this.trackerGraphic = null
  16525. },
  16526. draw: function(renderer, markersGroup, labelsGroup, animationEnabled, firstDrawing) {
  16527. if (this._needDeletingOnDraw) {
  16528. this.deleteMarker();
  16529. this.deleteTrackerMarker();
  16530. this._needDeletingOnDraw = false
  16531. }
  16532. if (this._needClearingOnDraw) {
  16533. this.clearMarker();
  16534. this._needClearingOnDraw = false
  16535. }
  16536. if (!this._hasGraphic())
  16537. this._options.visible && this._drawMarker(renderer, markersGroup, animationEnabled, firstDrawing);
  16538. else
  16539. this._updateMarker(animationEnabled, undefined, markersGroup);
  16540. this._drawLabel(renderer, labelsGroup)
  16541. },
  16542. applyStyle: function(style) {
  16543. if (this.graphic) {
  16544. if (style === "normal")
  16545. this.clearMarker();
  16546. else
  16547. this.graphic.toForeground();
  16548. this._updateMarker(true, this._styles[style])
  16549. }
  16550. },
  16551. setHoverState: function() {
  16552. this.series.setPointHoverState(this)
  16553. },
  16554. releaseHoverState: function(callback) {
  16555. this.series.releasePointHoverState(this, callback);
  16556. if (this.graphic)
  16557. !this.isSelected() && this.graphic.toBackground()
  16558. },
  16559. setSelectedState: function() {
  16560. this.series.setPointSelectedState(this)
  16561. },
  16562. releaseSelectedState: function() {
  16563. this.series.releasePointSelectedState(this)
  16564. },
  16565. select: function() {
  16566. this.series.selectPoint(this)
  16567. },
  16568. clearSelection: function() {
  16569. this.series.deselectPoint(this)
  16570. },
  16571. showTooltip: function() {
  16572. this.series.showPointTooltip(this)
  16573. },
  16574. hideTooltip: function() {
  16575. this.series.hidePointTooltip(this)
  16576. },
  16577. _checkLabelsChanging: function(oldType, newType) {
  16578. if (oldType) {
  16579. var isNewRange = ~newType.indexOf("range"),
  16580. isOldRange = ~oldType.indexOf("range");
  16581. return isOldRange && !isNewRange || !isOldRange && isNewRange
  16582. }
  16583. else
  16584. return false
  16585. },
  16586. updateOptions: function(newOptions) {
  16587. if (!_isDefined(newOptions))
  16588. return;
  16589. var that = this,
  16590. oldOptions = that._options,
  16591. oldType = oldOptions && oldOptions.type,
  16592. newType = newOptions.type;
  16593. if (pointTypes[oldType] !== pointTypes[newType]) {
  16594. that._needDeletingOnDraw = true;
  16595. that._needClearingOnDraw = false;
  16596. that._checkLabelsChanging(oldType, newType) && that.deleteLabel();
  16597. that._resetType(oldType);
  16598. that._setType(newType)
  16599. }
  16600. else {
  16601. that._needDeletingOnDraw = that._checkSymbol(oldOptions, newOptions);
  16602. that._needClearingOnDraw = that._checkCustomize(oldOptions, newOptions)
  16603. }
  16604. that.series = newOptions.series;
  16605. that._options = newOptions;
  16606. that._fillStyle();
  16607. that._updateLabelOptions(pointTypes[newType])
  16608. },
  16609. translate: function(translators) {
  16610. this.translators = translators || this.translators;
  16611. this.translators && this.hasValue() && this._translate(this.translators)
  16612. },
  16613. drawTracker: function(renderer, group) {
  16614. if (!this.trackerGraphic)
  16615. this._drawTrackerMarker(renderer, group);
  16616. else
  16617. this._updateTracker()
  16618. },
  16619. _checkCustomize: function(oldOptions, newOptions) {
  16620. return oldOptions.styles.usePointCustomOptions && !newOptions.styles.usePointCustomOptions
  16621. },
  16622. _getCustomLabelVisibility: function() {
  16623. if (this._styles.useLabelCustomOptions)
  16624. return this._options.label.visible ? "visible" : "hidden"
  16625. },
  16626. _getGraphicSettings: function() {
  16627. return {
  16628. x: this.graphic.settings.x || 0,
  16629. y: this.graphic.settings.y || 0,
  16630. height: this.graphic.settings.height || 0,
  16631. width: this.graphic.settings.width || 0
  16632. }
  16633. },
  16634. _resetType: function(type) {
  16635. var that = this;
  16636. if (type)
  16637. _each(viz.core.series.points.mixins[pointTypes[type]], function(methodName) {
  16638. delete that[methodName]
  16639. })
  16640. },
  16641. _setType: function(type) {
  16642. var that = this;
  16643. _each(viz.core.series.points.mixins[pointTypes[type]], function(methodName, method) {
  16644. that[methodName] = method
  16645. })
  16646. },
  16647. _prepareStatesOptions: function() {
  16648. var that = this;
  16649. if (that._options.states && that._options.states.normal)
  16650. that._populatePointShape(that._options.states.normal.r)
  16651. },
  16652. isInVisibleArea: function() {
  16653. return this.inVisibleArea
  16654. },
  16655. isSelected: function() {
  16656. return !!(this.fullState & statesConsts.selectedMark)
  16657. },
  16658. isHovered: function() {
  16659. return !!(this.fullState & statesConsts.hoverMark)
  16660. },
  16661. getOptions: function() {
  16662. return this._options
  16663. },
  16664. animate: function(complete, settings, partitionDuration) {
  16665. if (!this.graphic) {
  16666. complete && complete();
  16667. return
  16668. }
  16669. this.graphic.animate(settings, {partitionDuration: partitionDuration}, complete)
  16670. },
  16671. getCoords: function(min) {
  16672. if (!min)
  16673. return {
  16674. x: this.x,
  16675. y: this.y
  16676. };
  16677. if (!this._options.rotated)
  16678. return {
  16679. x: this.x,
  16680. y: this.minY
  16681. };
  16682. return {
  16683. x: this.minX,
  16684. y: this.y
  16685. }
  16686. },
  16687. getDefaultCoords: function() {
  16688. return !this._options.rotated ? {
  16689. x: this.x,
  16690. y: this.defaultY
  16691. } : {
  16692. x: this.defaultX,
  16693. y: this.y
  16694. }
  16695. },
  16696. _calculateVisibility: function(x, y, width, height) {
  16697. var that = this,
  16698. visibleAreaX,
  16699. visibleAreaY,
  16700. rotated = that._options.rotated;
  16701. if (that.translators) {
  16702. visibleAreaX = that.translators.x.getCanvasVisibleArea();
  16703. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  16704. 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))
  16705. that.inVisibleArea = false;
  16706. else
  16707. that.inVisibleArea = true
  16708. }
  16709. },
  16710. correctPosition: _noop,
  16711. hasValue: function() {
  16712. return this.value !== null && this.minValue !== null
  16713. },
  16714. _populatePointShape: _noop,
  16715. _checkSymbol: _noop,
  16716. hide: _noop,
  16717. show: _noop,
  16718. hideMarker: _noop,
  16719. setInvisibility: _noop,
  16720. clearVisibility: _noop,
  16721. isVisible: _noop,
  16722. resetCorrection: _noop,
  16723. correctValue: _noop,
  16724. setPercentValue: _noop,
  16725. correctCoordinates: _noop,
  16726. dispose: function() {
  16727. this.deleteMarker();
  16728. this.deleteTrackerMarker();
  16729. this.deleteLabel();
  16730. this._options = null;
  16731. this._styles = null;
  16732. this.series = null;
  16733. this.translators = null
  16734. },
  16735. getTooltipFormatObject: function(tooltip) {
  16736. var that = this,
  16737. tooltipFormatObject = that._getFormatObject(tooltip),
  16738. sharedTooltipValuesArray = [],
  16739. tooltipStackPointsFormatObject = [];
  16740. if (that.stackPoints) {
  16741. _each(that.stackPoints, function(_, point) {
  16742. if (!point.isVisible())
  16743. return;
  16744. var formatObject = point._getFormatObject(tooltip);
  16745. tooltipStackPointsFormatObject.push(point._getFormatObject(tooltip));
  16746. sharedTooltipValuesArray.push(formatObject.seriesName + ": " + formatObject.valueText)
  16747. });
  16748. _extend(tooltipFormatObject, {
  16749. points: tooltipStackPointsFormatObject,
  16750. valueText: sharedTooltipValuesArray.join("\n"),
  16751. stackName: that.stackPoints.stackName
  16752. })
  16753. }
  16754. return tooltipFormatObject
  16755. }
  16756. })
  16757. })(jQuery, DevExpress);
  16758. /*! Module viz-core, file label.js */
  16759. (function($, DX) {
  16760. var _isDefined = DX.utils.isDefined,
  16761. _extend = $.extend,
  16762. _math = Math,
  16763. _round = _math.round,
  16764. _floor = _math.floor,
  16765. _isEmptyObject = $.isEmptyObject,
  16766. _noop = $.noop,
  16767. LABEL_BACKGROUND_PADDING_X = 8,
  16768. LABEL_BACKGROUND_PADDING_Y = 4,
  16769. LABEL_OFFSET = 10,
  16770. setPositionFuncCollection = {
  16771. symbolPoint: "_setPositionForSymbol",
  16772. barPoint: "_setPositionForBar",
  16773. bubblePoint: "_setPositionForBubble",
  16774. rangeSymbolPoint: "_setPositionForSymbol",
  16775. rangeBarPoint: "_setPositionForBar",
  16776. stockPoint: "_setPositionForFinancial",
  16777. candlestickPoint: "_setPositionForFinancial"
  16778. },
  16779. checkPositionFuncCollection = {
  16780. symbolPoint: "_checkPositionForSymbol",
  16781. barPoint: "_checkPositionForBar",
  16782. bubblePoint: "_checkPositionForSymbol",
  16783. rangeSymbolPoint: "_checkPositionForSymbol",
  16784. rangeBarPoint: "_checkPositionForBar",
  16785. stockPoint: "_checkPositionForBar",
  16786. candlestickPoint: "_checkPositionForBar"
  16787. };
  16788. DX.viz.core.series.points.Label = DX.Class.inherit({
  16789. ctor: function(data, options) {
  16790. this._offset = LABEL_OFFSET;
  16791. this.updateData(data);
  16792. this.setOptions(options)
  16793. },
  16794. clearVisibility: function() {
  16795. if (this._group && this._group.settings.visibility)
  16796. this._group.applySettings({visibility: null})
  16797. },
  16798. hide: function() {
  16799. if (this._group && this._group.settings.visibility !== "hidden")
  16800. this._group.applySettings({visibility: "hidden"})
  16801. },
  16802. updateData: function(data) {
  16803. if (_isDefined(data)) {
  16804. this._data = data.formatObject;
  16805. this._initialValue = data.initialValue
  16806. }
  16807. },
  16808. updateOptions: function(options) {
  16809. this.setOptions(_extend(true, {}, {options: this._options}, options))
  16810. },
  16811. setOptions: function(newOptions) {
  16812. var that = this,
  16813. oldOptions = that._options,
  16814. newOptions = newOptions || {},
  16815. pointType = newOptions.type || "symbolPoint";
  16816. that._options = newOptions.options;
  16817. that._rotated = newOptions.rotated;
  16818. that._isFullStacked = newOptions.isFullStacked;
  16819. that._isRange = newOptions.isRange;
  16820. that._setPosition = that[setPositionFuncCollection[pointType]];
  16821. that._checkPosition = that[checkPositionFuncCollection[pointType]];
  16822. if (oldOptions) {
  16823. that._isBackgroundChanged(oldOptions.background, that._options.background) && that._deleteBackground();
  16824. that._isConnectorChanged(oldOptions.connector, that._options.connector) && that._deleteConnector()
  16825. }
  16826. },
  16827. setDataField: function(fieldName, fieldValue) {
  16828. this._data = this._data || {};
  16829. this._data[fieldName] = fieldValue
  16830. },
  16831. getData: function() {
  16832. return this._data
  16833. },
  16834. setCoords: function(coords, graphicBbox, location, visibleArea) {
  16835. this._coords = coords;
  16836. this._graphicBbox = graphicBbox;
  16837. this._visibleArea = visibleArea;
  16838. this._location = location
  16839. },
  16840. hasText: function() {
  16841. return !!this._text
  16842. },
  16843. getTextCoords: function() {
  16844. return this._text && this._text.getBBox()
  16845. },
  16846. getCoords: function() {
  16847. var coords = {},
  16848. insideGroup = this._insideGroup;
  16849. if (insideGroup) {
  16850. coords = insideGroup.getBBox();
  16851. coords.x = insideGroup.settings.translateX || 0;
  16852. coords.y = insideGroup.settings.translateY || 0
  16853. }
  16854. return coords
  16855. },
  16856. updatePosition: function(x, y) {
  16857. var settings = {},
  16858. insideGroup = this._insideGroup;
  16859. insideGroup.applySettings({
  16860. translateX: x,
  16861. translateY: y
  16862. });
  16863. this._connector && this._drawConnector()
  16864. },
  16865. _deleteElements: function() {
  16866. this._deleteConnector();
  16867. this._deleteBackground();
  16868. this._deleteText();
  16869. this._deleteGroups()
  16870. },
  16871. dispose: function() {
  16872. this._data = null;
  16873. this._options = null;
  16874. this._positioningFunction = null;
  16875. this._graphicBbox = null;
  16876. this._visibleArea = null;
  16877. this._coords = null;
  16878. this._deleteElements()
  16879. },
  16880. _deleteText: function() {
  16881. this._text && this._text.detach();
  16882. this._text = null
  16883. },
  16884. _deleteGroups: function() {
  16885. this._insideGroup = null;
  16886. this._group && this._group.detach();
  16887. this._group = null
  16888. },
  16889. _drawGroups: function(renderer, group) {
  16890. if (!this._group)
  16891. this._group = renderer.createGroup().append(group);
  16892. if (!this._insideGroup)
  16893. this._insideGroup = renderer.createGroup().append(this._group)
  16894. },
  16895. _drawText: function(renderer, text) {
  16896. if (!this._text)
  16897. this._text = renderer.createText(text, 0, 0, this._options.attributes).append(this._insideGroup);
  16898. else
  16899. this._text.applySettings({text: text}, this._options.attributes)
  16900. },
  16901. _drawBackground: function(renderer) {
  16902. var that = this,
  16903. options = that._options,
  16904. background = options.background || {},
  16905. settings;
  16906. if (that._checkBackground(background)) {
  16907. settings = _extend(that._getBackgroundSettings(), background);
  16908. if (!that._background)
  16909. that._background = renderer.createRect(settings.x, settings.y, settings.width, settings.height, 0, background).append(that._insideGroup);
  16910. else
  16911. that._background.applySettings(settings);
  16912. that._background.toBackground()
  16913. }
  16914. },
  16915. _drawConnector: function(renderer) {
  16916. var that = this,
  16917. connector = that._options.connector || {},
  16918. points;
  16919. if (that._checkConnector(connector)) {
  16920. points = that._getConnectorPoints() || [];
  16921. if (!that._connector)
  16922. that._connector = renderer.createPath(points, connector).append(that._group);
  16923. else
  16924. that._connector.applySettings(_extend({points: points}, connector));
  16925. that._connector.toBackground()
  16926. }
  16927. },
  16928. _setVisibility: function(visibility) {
  16929. this._group && this._group.applySettings({visibility: visibility})
  16930. },
  16931. draw: function(renderer, group, visibility) {
  16932. var that = this,
  16933. options = that._options,
  16934. background = options.background,
  16935. text = that._format();
  16936. if (_isDefined(text) && text !== "") {
  16937. that._drawGroups(renderer, group);
  16938. that._setVisibility(visibility);
  16939. that._drawText(renderer, text);
  16940. that._drawBackground(renderer);
  16941. that._rotateLabel();
  16942. that._setPosition();
  16943. that._drawConnector(renderer)
  16944. }
  16945. else
  16946. that._setVisibility("hidden")
  16947. },
  16948. _deleteBackground: function() {
  16949. this._background && this._background.detach();
  16950. this._background = null
  16951. },
  16952. _isBackgroundChanged: function(oldBackground, newBackground) {
  16953. return this._checkBackground(oldBackground || {}) !== this._checkBackground(newBackground || {})
  16954. },
  16955. _checkBackground: function(background) {
  16956. var hasColor = background.fill && background.fill !== "none",
  16957. hasBorder = background.strokeWidth && background.stroke && background.stroke !== "none";
  16958. return hasColor || hasBorder
  16959. },
  16960. _getBackgroundSettings: function() {
  16961. var bbox = this._text.getBBox();
  16962. return {
  16963. x: bbox.x - LABEL_BACKGROUND_PADDING_X,
  16964. y: bbox.y - LABEL_BACKGROUND_PADDING_Y,
  16965. width: bbox.width + 2 * LABEL_BACKGROUND_PADDING_X,
  16966. height: bbox.height + 2 * LABEL_BACKGROUND_PADDING_Y
  16967. }
  16968. },
  16969. _deleteConnector: function() {
  16970. this._connector && this._connector.detach();
  16971. this._connector = null
  16972. },
  16973. _isConnectorChanged: function(oldConnector, newConnector) {
  16974. return this._checkConnector(oldConnector || {}) !== this._checkConnector(newConnector || {})
  16975. },
  16976. _checkConnector: function(connector) {
  16977. return connector && connector.strokeWidth
  16978. },
  16979. _getConnectorPoints: function() {
  16980. var that = this,
  16981. rotated = that._rotated,
  16982. labelBbox = that._insideGroup.getBBox(),
  16983. graphicBbox = that._graphicBbox,
  16984. centerLabelY,
  16985. centerLabelX,
  16986. rightLabelCoord,
  16987. bottomLabelCoord,
  16988. x1,
  16989. x2,
  16990. y1,
  16991. y2;
  16992. labelBbox.x += that._insideGroup.settings.translateX || 0;
  16993. labelBbox.y += that._insideGroup.settings.translateY || 0;
  16994. centerLabelY = that._background ? labelBbox.y + labelBbox.height / 2 : null;
  16995. centerLabelX = that._background ? labelBbox.x + labelBbox.width / 2 : null,
  16996. rightLabelCoord = labelBbox.x + labelBbox.width;
  16997. bottomLabelCoord = labelBbox.y + labelBbox.height;
  16998. x1 = _floor(labelBbox.x + labelBbox.width / 2);
  16999. x2 = _floor(graphicBbox.x + graphicBbox.width / 2);
  17000. if (bottomLabelCoord < graphicBbox.y) {
  17001. y1 = centerLabelY || bottomLabelCoord;
  17002. y2 = graphicBbox.y
  17003. }
  17004. else if (labelBbox.y > graphicBbox.y + graphicBbox.height) {
  17005. y1 = centerLabelY || labelBbox.y;
  17006. y2 = graphicBbox.y + graphicBbox.height
  17007. }
  17008. else {
  17009. if (labelBbox.x > graphicBbox.x + graphicBbox.width) {
  17010. x1 = centerLabelX || labelBbox.x;
  17011. x2 = graphicBbox.x + graphicBbox.width
  17012. }
  17013. else if (rightLabelCoord < graphicBbox.x) {
  17014. x1 = centerLabelX || rightLabelCoord;
  17015. x2 = graphicBbox.x
  17016. }
  17017. else
  17018. return;
  17019. y1 = _floor(labelBbox.y + labelBbox.height / 2);
  17020. y2 = _floor(graphicBbox.y + graphicBbox.height / 2)
  17021. }
  17022. return [{
  17023. x: x1,
  17024. y: y1
  17025. }, {
  17026. x: x2,
  17027. y: y2
  17028. }]
  17029. },
  17030. _rotateLabel: function() {
  17031. var bbox = this._insideGroup.getBBox();
  17032. this._insideGroup.rotate(this._options.rotationAngle)
  17033. },
  17034. _format: function() {
  17035. var that = this,
  17036. data = that._data,
  17037. options = that._options,
  17038. formatHelper = DX.formatHelper;
  17039. data.valueText = formatHelper.format(data.value, options.format, options.precision);
  17040. data.argumentText = formatHelper.format(data.argument, options.argumentFormat, options.argumentPrecision);
  17041. if (data.percent !== undefined)
  17042. data.percentText = formatHelper.format(data.percent, "percent", options.percentPrecision);
  17043. if (data.total !== undefined)
  17044. data.totalText = formatHelper.format(data.total, options.format, options.precision);
  17045. if (data.openValue !== undefined)
  17046. data.openValueText = formatHelper.format(data.openValue, options.format, options.precision);
  17047. if (data.closeValue !== undefined)
  17048. data.closeValueText = formatHelper.format(data.closeValue, options.format, options.precision);
  17049. if (data.lowValue !== undefined)
  17050. data.lowValueText = formatHelper.format(data.lowValue, options.format, options.precision);
  17051. if (data.highValue !== undefined)
  17052. data.highValueText = formatHelper.format(data.highValue, options.format, options.precision);
  17053. if (data.reductionValue !== undefined)
  17054. data.reductionValueText = formatHelper.format(data.reductionValue, options.format, options.precision);
  17055. return options.customizeText ? options.customizeText.call(data, data) : data.valueText
  17056. },
  17057. _getOutsideLabelCoords: function(labelBbox) {
  17058. var graphicBbox = this._graphicBbox,
  17059. x = 0,
  17060. y = 0,
  17061. isTop = this._location === "top";
  17062. if (!this._rotated) {
  17063. x += graphicBbox.width / 2 + graphicBbox.x;
  17064. if (isTop)
  17065. y += graphicBbox.y - labelBbox.y - labelBbox.height - this._offset;
  17066. else
  17067. y += graphicBbox.y + graphicBbox.height - labelBbox.y + this._offset
  17068. }
  17069. else {
  17070. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  17071. if (isTop)
  17072. x += graphicBbox.x + graphicBbox.width - labelBbox.x + this._offset;
  17073. else
  17074. x += graphicBbox.x - labelBbox.x - labelBbox.width - this._offset
  17075. }
  17076. return {
  17077. x: x,
  17078. y: y
  17079. }
  17080. },
  17081. _getInsideLabelCoords: function(labelBbox) {
  17082. var graphicBbox = this._graphicBbox,
  17083. isTop = this._location === "top",
  17084. x = 0,
  17085. y = 0;
  17086. if (!this._isRange)
  17087. if (!this._rotated) {
  17088. x += graphicBbox.width / 2 + graphicBbox.x;
  17089. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2
  17090. }
  17091. else {
  17092. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  17093. x += graphicBbox.x - labelBbox.x - labelBbox.width / 2 + graphicBbox.width / 2
  17094. }
  17095. else if (!this._rotated) {
  17096. x += graphicBbox.width / 2 + graphicBbox.x;
  17097. if (isTop)
  17098. y += graphicBbox.y - labelBbox.y - labelBbox.height + this._offset + labelBbox.height;
  17099. else
  17100. y += graphicBbox.y + graphicBbox.height - labelBbox.y - this._offset - labelBbox.height
  17101. }
  17102. else {
  17103. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  17104. if (isTop)
  17105. x += graphicBbox.x + graphicBbox.width - labelBbox.x - labelBbox.width - this._offset;
  17106. else
  17107. x += graphicBbox.x - labelBbox.x + this._offset
  17108. }
  17109. return {
  17110. x: x,
  17111. y: y
  17112. }
  17113. },
  17114. _getFullstackedLabelCoords: function(labelBbox) {
  17115. var x = 0,
  17116. y = 0,
  17117. graphicBbox = this._graphicBbox;
  17118. if (!this._rotated) {
  17119. x += graphicBbox.width / 2 + graphicBbox.x;
  17120. y += this._coords.defaultY - labelBbox.y - labelBbox.height - this._offset
  17121. }
  17122. else {
  17123. y += graphicBbox.y - labelBbox.y - labelBbox.height / 2 + graphicBbox.height / 2;
  17124. x += this._coords.defaultX - labelBbox.x + this._offset
  17125. }
  17126. return {
  17127. x: x,
  17128. y: y
  17129. }
  17130. },
  17131. _setPositionForSymbol: function() {
  17132. var that = this,
  17133. offset = that._offset,
  17134. labelBBox = that._insideGroup.getBBox(),
  17135. graphicBbox = that._graphicBbox,
  17136. isTop = that._location === "top",
  17137. correctionY = 0,
  17138. correctionX = 0,
  17139. x = 0,
  17140. y = 0;
  17141. if (!that._rotated) {
  17142. correctionX = that._coords.x;
  17143. correctionY = isTop ? -labelBBox.y - labelBBox.height - offset : graphicBbox.height - labelBBox.y + offset;
  17144. correctionY += graphicBbox.y
  17145. }
  17146. else {
  17147. correctionY = graphicBbox.y - labelBBox.y - labelBBox.height / 2 + graphicBbox.height / 2;
  17148. correctionX = isTop ? graphicBbox.width - labelBBox.x + offset : -labelBBox.x - labelBBox.width - offset;
  17149. correctionX += graphicBbox.x
  17150. }
  17151. x += correctionX + that._options.horizontalOffset;
  17152. y += correctionY + that._options.verticalOffset;
  17153. that._checkPosition({
  17154. x: labelBBox.x + x,
  17155. y: labelBBox.y + y,
  17156. height: labelBBox.height,
  17157. width: labelBBox.width
  17158. }, x, y)
  17159. },
  17160. _checkPositionForSymbol: function(labelBbox, x, y) {
  17161. var that = this,
  17162. graphicBbox = that._graphicBbox,
  17163. visibleArea = that._visibleArea,
  17164. offset = that._offset;
  17165. if (!that._rotated) {
  17166. if (visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x) {
  17167. if (visibleArea.minX > labelBbox.x && that.adjustSeriesLabels)
  17168. x += visibleArea.minX - labelBbox.x;
  17169. if (visibleArea.maxX < labelBbox.x + labelBbox.width && that.adjustSeriesLabels)
  17170. x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
  17171. if (visibleArea.minY > labelBbox.y)
  17172. y += graphicBbox.y + graphicBbox.height - labelBbox.y + offset;
  17173. if (visibleArea.maxY < labelBbox.y + labelBbox.height)
  17174. y -= labelBbox.y + labelBbox.height - graphicBbox.y + offset
  17175. }
  17176. }
  17177. else if (visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y) {
  17178. if (visibleArea.minX > labelBbox.x)
  17179. x += graphicBbox.x + graphicBbox.width - labelBbox.x + offset;
  17180. if (visibleArea.maxX < labelBbox.x + labelBbox.width)
  17181. x -= labelBbox.x + labelBbox.width - graphicBbox.x + offset;
  17182. if (visibleArea.minY > graphicBbox.y && that.adjustSeriesLabels)
  17183. y += visibleArea.minY - labelBbox.y;
  17184. if (visibleArea.maxY < labelBbox.y + labelBbox.height && that.adjustSeriesLabels)
  17185. y -= labelBbox.y + labelBbox.height - visibleArea.maxY
  17186. }
  17187. that._insideGroup.applySettings({
  17188. translateX: _round(x),
  17189. translateY: _round(y)
  17190. })
  17191. },
  17192. _setPositionForBar: function() {
  17193. var that = this,
  17194. offset = that._offset,
  17195. labelPosition = that._options.position,
  17196. labelBbox = that._insideGroup.getBBox(),
  17197. coords;
  17198. if (that._initialValue === 0 && that._isFullStacked)
  17199. coords = that._getFullstackedLabelCoords(labelBbox);
  17200. else if (labelPosition === "inside")
  17201. coords = that._getInsideLabelCoords(labelBbox);
  17202. else
  17203. coords = that._getOutsideLabelCoords(labelBbox);
  17204. coords.x += that._options.horizontalOffset;
  17205. coords.y += that._options.verticalOffset;
  17206. that._checkPosition({
  17207. x: labelBbox.x + coords.x,
  17208. y: labelBbox.y + coords.y,
  17209. height: labelBbox.height,
  17210. width: labelBbox.width
  17211. }, coords.x, coords.y)
  17212. },
  17213. _checkPositionForBar: function(labelBbox, x, y) {
  17214. var that = this,
  17215. graphicBbox = that._graphicBbox,
  17216. visibleArea = that._visibleArea;
  17217. if (visibleArea.minX <= graphicBbox.x + graphicBbox.width && visibleArea.maxX >= graphicBbox.x && visibleArea.minY <= graphicBbox.y + graphicBbox.height && visibleArea.maxY >= graphicBbox.y)
  17218. if (!that._rotated) {
  17219. if (visibleArea.minX > labelBbox.x && that.adjustSeriesLabels)
  17220. x += visibleArea.minX - labelBbox.x;
  17221. if (visibleArea.maxX < labelBbox.x + labelBbox.width && that.adjustSeriesLabels)
  17222. x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
  17223. if (visibleArea.minY > labelBbox.y)
  17224. y += visibleArea.minY - labelBbox.y;
  17225. if (visibleArea.maxY < labelBbox.y + labelBbox.height)
  17226. y -= labelBbox.y + labelBbox.height - visibleArea.maxY
  17227. }
  17228. else {
  17229. if (visibleArea.minX > labelBbox.x)
  17230. x += visibleArea.minX - labelBbox.x;
  17231. if (visibleArea.maxX < labelBbox.x + labelBbox.width)
  17232. x -= labelBbox.x + labelBbox.width - visibleArea.maxX;
  17233. if (visibleArea.minY > labelBbox.y && that.adjustSeriesLabels)
  17234. y += visibleArea.minY - labelBbox.y;
  17235. if (visibleArea.maxY < labelBbox.y + labelBbox.height && that.adjustSeriesLabels)
  17236. y -= labelBbox.y + labelBbox.height - visibleArea.maxY
  17237. }
  17238. if (that._options.resolveLabelsOverlapping && that._options.position === "inside")
  17239. if (that._rotated) {
  17240. if (labelBbox.width > graphicBbox.width || labelBbox.height > graphicBbox.height) {
  17241. that.hide();
  17242. return
  17243. }
  17244. }
  17245. else if (labelBbox.height > graphicBbox.height || labelBbox.width > graphicBbox.width) {
  17246. that.hide();
  17247. return
  17248. }
  17249. that._insideGroup.applySettings({
  17250. translateX: _round(x),
  17251. translateY: _round(y)
  17252. })
  17253. },
  17254. _setPositionForBubble: function() {
  17255. var that = this,
  17256. labelBbox = that._insideGroup.getBBox(),
  17257. graphicBbox = that._graphicBbox,
  17258. x = 0,
  17259. y = 0;
  17260. if (that._options.position === "inside") {
  17261. x = that._coords.x;
  17262. y += graphicBbox.y + graphicBbox.height / 2 - labelBbox.y - labelBbox.height / 2;
  17263. x += that._options.horizontalOffset;
  17264. y += that._options.verticalOffset;
  17265. that._checkPosition({
  17266. x: labelBbox.x + x,
  17267. y: labelBbox.y + y,
  17268. height: labelBbox.height,
  17269. width: labelBbox.width
  17270. }, x, y)
  17271. }
  17272. else
  17273. that._setPositionForSymbol()
  17274. },
  17275. _setPositionForFinancial: function() {
  17276. var that = this,
  17277. offset = that._offset,
  17278. labelBbox = that._insideGroup.getBBox(),
  17279. coords;
  17280. coords = that._getOutsideLabelCoords(labelBbox);
  17281. coords.x += that._options.horizontalOffset;
  17282. coords.y += that._options.verticalOffset;
  17283. that._checkPosition({
  17284. x: labelBbox.x + coords.x,
  17285. y: labelBbox.y + coords.y,
  17286. height: labelBbox.height,
  17287. width: labelBbox.width
  17288. }, coords.x, coords.y)
  17289. }
  17290. })
  17291. })(jQuery, DevExpress);
  17292. /*! Module viz-core, file pieLabel.js */
  17293. (function($, DX) {
  17294. var getCosAndSin = DX.utils.getCosAndSin,
  17295. _extend = $.extend,
  17296. _math = Math,
  17297. _round = _math.round,
  17298. _max = _math.max,
  17299. _inArray = $.inArray,
  17300. _isDefined = DX.utils.isDefined,
  17301. INDENT_FROM_PIE = 30,
  17302. CONNECTOR_LENGTH = 20;
  17303. DX.viz.core.series.points.PieLabel = DX.viz.core.series.points.Label.inherit({
  17304. ctor: function(data, options) {
  17305. this.setLabelEllipsis = false;
  17306. this.indentFromPie = INDENT_FROM_PIE;
  17307. this.updateData(data);
  17308. this.setOptions(options)
  17309. },
  17310. updateData: function(data) {
  17311. if (_isDefined(data))
  17312. this._data = data.formatObject
  17313. },
  17314. setOptions: function(newOptions) {
  17315. var that = this,
  17316. oldOptions = that._options,
  17317. newOptions = newOptions || {};
  17318. that._options = newOptions.options;
  17319. that._borderWidth = newOptions.borderWidth;
  17320. if (oldOptions) {
  17321. that._isBackgroundChanged(oldOptions.background, that._options.background) && that._deleteBackground();
  17322. that._isConnectorChanged(oldOptions.connector, that._options.connector) && that._deleteConnector()
  17323. }
  17324. },
  17325. setCoords: function(coords, canvas) {
  17326. this._middleAngle = coords.middleAngle;
  17327. this._radiusOuter = coords.radiusOuter;
  17328. this._centerX = coords.centerX;
  17329. this._centerY = coords.centerY;
  17330. this._canvas = canvas
  17331. },
  17332. updatePosition: function(maxLabelLength) {
  17333. this._setPosition(maxLabelLength);
  17334. this._checkEllipsis();
  17335. this._drawBackground();
  17336. this._rotateLabel();
  17337. this._checkPosition();
  17338. this._connector && this._drawConnector()
  17339. },
  17340. dispose: function() {
  17341. this._data = null;
  17342. this._options = null;
  17343. this._canvas = null;
  17344. this._deleteElements()
  17345. },
  17346. draw: function(renderer, group, visibility) {
  17347. var that = this,
  17348. options = that._options,
  17349. background = options.background,
  17350. text = that._format();
  17351. if (_isDefined(text) && text !== "") {
  17352. that._drawGroups(renderer, group);
  17353. that._setVisibility(visibility);
  17354. that._drawText(renderer, text);
  17355. that._setPosition();
  17356. that._checkEllipsis();
  17357. that._drawBackground(renderer);
  17358. that._rotateLabel();
  17359. that._checkPosition();
  17360. that._drawConnector(renderer)
  17361. }
  17362. else
  17363. that._setVisibility("hidden")
  17364. },
  17365. _getOutsideGroupLabelPosition: function() {
  17366. this._deleteConnector();
  17367. return this._group && this._group.getBBox()
  17368. },
  17369. _setPosition: function(maxLabelLength) {
  17370. var that = this,
  17371. bbox = that._text.getBBox(),
  17372. options = that._options,
  17373. angleFunctions = getCosAndSin(that._middleAngle),
  17374. align = "center",
  17375. rad = that._radiusOuter + options.radialOffset,
  17376. canvas = that._canvas,
  17377. rightBorderX = canvas.width - canvas.right,
  17378. leftBorderX = canvas.left,
  17379. x,
  17380. y;
  17381. if (options.position === 'inside') {
  17382. rad -= that.indentFromPie;
  17383. x = that._centerX + rad * angleFunctions.cos
  17384. }
  17385. else if (options.position === 'columns') {
  17386. rad += CONNECTOR_LENGTH;
  17387. if (angleFunctions.cos >= 0) {
  17388. align = "right";
  17389. x = maxLabelLength ? that._centerX + rad + maxLabelLength : rightBorderX;
  17390. x = x > rightBorderX ? rightBorderX : x
  17391. }
  17392. else if (angleFunctions.cos < 0) {
  17393. align = "left";
  17394. x = maxLabelLength ? that._centerX - rad - maxLabelLength : leftBorderX;
  17395. x = x < leftBorderX ? leftBorderX : x
  17396. }
  17397. }
  17398. else {
  17399. rad += that.indentFromPie;
  17400. if (angleFunctions.cos > 0.1)
  17401. align = "left";
  17402. else if (angleFunctions.cos < -0.1)
  17403. align = "right";
  17404. x = that._centerX + rad * angleFunctions.cos
  17405. }
  17406. y = _round(that._text.settings.y + that._centerY - rad * angleFunctions.sin - bbox.y - bbox.height / 2);
  17407. that._text.applySettings({
  17408. x: x,
  17409. y: y,
  17410. align: align
  17411. })
  17412. },
  17413. _getConnectorPoints: function() {
  17414. var that = this,
  17415. options = that._options,
  17416. position = options.position,
  17417. angleFunctions,
  17418. rad = that._radiusOuter,
  17419. box,
  17420. x,
  17421. y,
  17422. points = [];
  17423. if (position !== "inside") {
  17424. angleFunctions = getCosAndSin(_round(that._middleAngle));
  17425. points.push({
  17426. x: _round(that._centerX + (rad - that._borderWidth) * angleFunctions.cos),
  17427. y: _round(that._centerY - (rad - that._borderWidth) * angleFunctions.sin)
  17428. });
  17429. x = _round(that._centerX + (rad + options.radialOffset + CONNECTOR_LENGTH) * angleFunctions.cos);
  17430. if (position === "columns") {
  17431. box = that._insideGroup.getBBox();
  17432. box.x = box.x + (that._insideGroup.settings.translateX || 0);
  17433. box.y = box.y + (that._insideGroup.settings.translateY || 0);
  17434. y = box.y + box.height / 2;
  17435. points.push({
  17436. x: x,
  17437. y: y
  17438. });
  17439. if (that._background)
  17440. x = box.x + box.width / 2;
  17441. else if (angleFunctions.cos < 0)
  17442. x = box.x + box.width;
  17443. else if (angleFunctions.cos > 0)
  17444. x = box.x;
  17445. points.push({
  17446. x: x,
  17447. y: y
  17448. })
  17449. }
  17450. else {
  17451. y = _round(that._centerY - (rad + options.radialOffset + CONNECTOR_LENGTH) * angleFunctions.sin);
  17452. points.push({
  17453. x: x,
  17454. y: y
  17455. })
  17456. }
  17457. }
  17458. return points
  17459. },
  17460. _rotateLabel: function() {
  17461. var that = this,
  17462. options = that._options,
  17463. shift = that._radiusOuter + options.radialOffset * 2 + CONNECTOR_LENGTH,
  17464. angleFunctions = getCosAndSin(that._middleAngle),
  17465. x,
  17466. y,
  17467. box = that._insideGroup.getBBox();
  17468. if (options.position === "inside" || options.position === "columns") {
  17469. x = box.x + box.width / 2;
  17470. y = box.y + box.height / 2
  17471. }
  17472. else {
  17473. x = that._centerX + shift * angleFunctions.cos;
  17474. y = that._centerY - shift * angleFunctions.sin
  17475. }
  17476. that._insideGroup.applySettings({
  17477. x: x,
  17478. y: y,
  17479. rotate: options.rotationAngle
  17480. })
  17481. },
  17482. _checkEllipsis: function() {
  17483. var that = this,
  17484. i,
  17485. LABEL_OFFSET = 10,
  17486. labelBox,
  17487. text,
  17488. textLength = 0,
  17489. linesLength = [],
  17490. numLastSpan = [],
  17491. maxLength,
  17492. numSpan,
  17493. index,
  17494. x,
  17495. y,
  17496. width,
  17497. rotationAngleFunction = getCosAndSin(that._options.rotationAngle),
  17498. canvas = that._canvas,
  17499. labelOptions = that._options,
  17500. angleFunctions = getCosAndSin(that._middleAngle),
  17501. borderX = that._centerX + (that._radiusOuter + CONNECTOR_LENGTH) * angleFunctions.cos;
  17502. if (!that._text.tspans || !that.setLabelEllipsis)
  17503. return;
  17504. labelBox = that._text.getBBox();
  17505. x = labelBox.x + labelBox.width < that._centerX ? labelBox.x + labelBox.width : labelBox.x;
  17506. y = labelBox.y + labelBox.height / 2;
  17507. width = labelBox.x + labelBox.width < that._centerX ? -labelBox.width : labelBox.width;
  17508. 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))
  17509. for (i = 0; i < that._text.tspans.length; i++) {
  17510. textLength += that._text.tspans[i].element.getNumberOfChars();
  17511. if (!that._text.tspans[i + 1] || that._text.tspans[i + 1].settings.dy > 0) {
  17512. linesLength.push(textLength);
  17513. numLastSpan.push(i);
  17514. textLength = 0
  17515. }
  17516. }
  17517. 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)) {
  17518. maxLength = _max.apply(null, linesLength);
  17519. if (maxLength === 0)
  17520. break;
  17521. index = _inArray(maxLength, linesLength);
  17522. numSpan = numLastSpan[index];
  17523. if (that._text.tspans[numSpan].element.textContent === "...") {
  17524. if (that._text.tspans[numSpan].settings.dy > 0 || !that._text.tspans[numSpan - 1])
  17525. linesLength[index] = 0;
  17526. else if (that._text.tspans[numSpan - 1]) {
  17527. that._text.tspans[numSpan].element.textContent = "";
  17528. numLastSpan[index] -= 1;
  17529. that._text.tspans[numSpan - 1].element.textContent += "..."
  17530. }
  17531. }
  17532. else {
  17533. text = that._text.tspans[numSpan].element.textContent;
  17534. text = text.substr(0, text.length - 1 - 3) + "...";
  17535. that._text.tspans[numSpan].element.textContent = text;
  17536. linesLength[index] -= 1
  17537. }
  17538. labelBox = that._text.getBBox();
  17539. x = labelBox.x + labelBox.width < that._centerX ? labelBox.x + labelBox.width : labelBox.x;
  17540. y = labelBox.y + labelBox.height / 2;
  17541. width = labelBox.x + labelBox.width < that._centerX ? -labelBox.width : labelBox.width
  17542. }
  17543. },
  17544. _checkPosition: function() {
  17545. var that = this,
  17546. group = that._insideGroup,
  17547. box = group.getBBox(),
  17548. canvas = that._canvas,
  17549. x = 0,
  17550. y = 0;
  17551. if (box.y + box.height > canvas.height - canvas.bottom)
  17552. y = canvas.height - box.y - box.height - canvas.bottom;
  17553. else if (box.y < canvas.top)
  17554. y = canvas.top - box.y;
  17555. if (box.x + box.width > canvas.width - canvas.right)
  17556. x = canvas.width - canvas.right - box.x - box.width;
  17557. else if (box.x < canvas.left)
  17558. x = canvas.left - box.x;
  17559. group.applySettings({
  17560. translateX: x,
  17561. translateY: y
  17562. })
  17563. },
  17564. setPosition: function(position) {
  17565. this._options.position = position
  17566. },
  17567. getPosition: function() {
  17568. return this._options.position
  17569. }
  17570. })
  17571. })(jQuery, DevExpress);
  17572. /*! Module viz-core, file symbolPoint.js */
  17573. (function($, DX) {
  17574. var viz = DevExpress.viz,
  17575. core = viz.core,
  17576. series = core.series,
  17577. _extend = $.extend,
  17578. _each = $.each,
  17579. _isNumber = DX.utils.isNumber,
  17580. _isDefined = DX.utils.isDefined,
  17581. _isEmptyObject = $.isEmptyObject,
  17582. _math = Math,
  17583. _round = _math.round,
  17584. _floor = _math.floor,
  17585. _ceil = _math.ceil,
  17586. DEFAULT_IMAGE_WIDTH = 20,
  17587. DEFAULT_IMAGE_HEIGHT = 20,
  17588. CANVAS_POSITION_DEFAULT = "canvas_position_default";
  17589. series.points.mixins = series.points.mixins || {};
  17590. series.points.mixins.symbolPoint = {
  17591. deleteLabel: function() {
  17592. this._label.dispose();
  17593. this._label = null
  17594. },
  17595. _hasGraphic: function() {
  17596. return this.graphic
  17597. },
  17598. _clearTrackerVisibility: function() {
  17599. if (this.trackerGraphic && this.trackerGraphic.settings.visibility)
  17600. this.trackerGraphic.applySettings({visibility: null})
  17601. },
  17602. clearVisibility: function() {
  17603. if (this.graphic && this.graphic.settings.visibility)
  17604. this.graphic.applySettings({visibility: null});
  17605. this._clearTrackerVisibility();
  17606. this._label.clearVisibility()
  17607. },
  17608. isVisible: function() {
  17609. return this.inVisibleArea && this.series.isVisible()
  17610. },
  17611. _setTrackerInvisibility: function() {
  17612. if (this.trackerGraphic && this.trackerGraphic.settings.visibility !== "hidden")
  17613. this.trackerGraphic.applySettings({visibility: "hidden"})
  17614. },
  17615. setInvisibility: function() {
  17616. if (this.graphic && this.graphic.settings.visibility !== "hidden")
  17617. this.graphic.applySettings({visibility: "hidden"});
  17618. this._setTrackerInvisibility();
  17619. this._label.hide()
  17620. },
  17621. clearMarker: function() {
  17622. this.graphic && this.graphic.applySettings(this._emptySettings)
  17623. },
  17624. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  17625. this._label.adjustSeriesLabels = adjustSeriesLabels
  17626. },
  17627. _getLabelOptions: function(type) {
  17628. var options = this._options;
  17629. return {
  17630. options: options.label,
  17631. rotated: options.rotated,
  17632. type: type,
  17633. isFullStacked: options.series.isFullStackedSeries(),
  17634. isRange: options.type.indexOf("range") !== -1
  17635. }
  17636. },
  17637. _createLabel: function() {
  17638. this._label = core.CoreFactory.createLabel(this._options.type)
  17639. },
  17640. _updateLabelData: function() {
  17641. this._label.updateData({
  17642. formatObject: this._getLabelFormatObject(),
  17643. initialValue: this.initialValue
  17644. })
  17645. },
  17646. _updateLabelOptions: function(type) {
  17647. !this._label && this._createLabel();
  17648. this._label.setOptions(this._getLabelOptions(type))
  17649. },
  17650. _checkImage: function(image) {
  17651. return _isDefined(image) && (typeof image === "string" || _isDefined(image.url))
  17652. },
  17653. _fillStyle: function() {
  17654. this._styles = this._options.styles
  17655. },
  17656. _checkSymbol: function(oldOptions, newOptions) {
  17657. var oldSymbol = oldOptions.symbol,
  17658. newSymbol = newOptions.symbol,
  17659. symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
  17660. imageChanged = this._checkImage(oldOptions.image) !== this._checkImage(newOptions.image);
  17661. if (symbolChanged || imageChanged)
  17662. return true;
  17663. return false
  17664. },
  17665. _getSquareMarkerCoords: function(radius) {
  17666. return [{
  17667. x: -radius,
  17668. y: -radius
  17669. }, {
  17670. x: radius,
  17671. y: -radius
  17672. }, {
  17673. x: radius,
  17674. y: radius
  17675. }, {
  17676. x: -radius,
  17677. y: radius
  17678. }, {
  17679. x: -radius,
  17680. y: -radius
  17681. }]
  17682. },
  17683. _getPolygonMarkerCoords: function(radius) {
  17684. var r = _ceil(radius);
  17685. return [{
  17686. x: -r,
  17687. y: 0
  17688. }, {
  17689. x: 0,
  17690. y: -r
  17691. }, {
  17692. x: r,
  17693. y: 0
  17694. }, {
  17695. x: 0,
  17696. y: r
  17697. }, {
  17698. x: -r,
  17699. y: 0
  17700. }]
  17701. },
  17702. _getTriangleMarkerCoords: function(radius) {
  17703. return [{
  17704. x: -radius,
  17705. y: -radius
  17706. }, {
  17707. x: radius,
  17708. y: -radius
  17709. }, {
  17710. x: 0,
  17711. y: radius
  17712. }, {
  17713. x: -radius,
  17714. y: -radius
  17715. }]
  17716. },
  17717. _getCrossMarkerCoords: function(radius) {
  17718. var r = _ceil(radius),
  17719. floorHalfRadius = _floor(r / 2),
  17720. ceilHalfRadius = _ceil(r / 2);
  17721. return [{
  17722. x: -r,
  17723. y: -floorHalfRadius
  17724. }, {
  17725. x: -floorHalfRadius,
  17726. y: -r
  17727. }, {
  17728. x: 0,
  17729. y: -ceilHalfRadius
  17730. }, {
  17731. x: floorHalfRadius,
  17732. y: -r
  17733. }, {
  17734. x: r,
  17735. y: -floorHalfRadius
  17736. }, {
  17737. x: ceilHalfRadius,
  17738. y: 0
  17739. }, {
  17740. x: r,
  17741. y: floorHalfRadius
  17742. }, {
  17743. x: floorHalfRadius,
  17744. y: r
  17745. }, {
  17746. x: 0,
  17747. y: ceilHalfRadius
  17748. }, {
  17749. x: -floorHalfRadius,
  17750. y: r
  17751. }, {
  17752. x: -r,
  17753. y: floorHalfRadius
  17754. }, {
  17755. x: -ceilHalfRadius,
  17756. y: 0
  17757. }]
  17758. },
  17759. _populatePointShape: function(symbol, radius) {
  17760. switch (symbol) {
  17761. case"square":
  17762. return this._getSquareMarkerCoords(radius);
  17763. case"polygon":
  17764. return this._getPolygonMarkerCoords(radius);
  17765. case"triangle":
  17766. return this._getTriangleMarkerCoords(radius);
  17767. case"cross":
  17768. return this._getCrossMarkerCoords(radius)
  17769. }
  17770. },
  17771. correctValue: function(correction) {
  17772. if (this.hasValue()) {
  17773. this.value = this.initialValue + correction;
  17774. this.minValue = correction;
  17775. this.translate()
  17776. }
  17777. },
  17778. resetCorrection: function() {
  17779. this.value = this.initialValue;
  17780. this.minValue = CANVAS_POSITION_DEFAULT
  17781. },
  17782. _getTranslates: function(animationEnabled) {
  17783. var translateX,
  17784. translateY;
  17785. translateX = this.x;
  17786. translateY = this.y;
  17787. if (animationEnabled)
  17788. if (this._options.rotated)
  17789. translateX = this.defaultX;
  17790. else
  17791. translateY = this.defaultY;
  17792. return {
  17793. x: translateX,
  17794. y: translateY
  17795. }
  17796. },
  17797. _createImageMarker: function(renderer, settings, options) {
  17798. var url,
  17799. width,
  17800. height,
  17801. offsetY,
  17802. attr = {
  17803. location: "center",
  17804. translateX: settings.attr.translateX,
  17805. translateY: settings.attr.translateY,
  17806. visibility: settings.attr.visibility
  17807. };
  17808. url = options.url ? options.url.toString() : options.toString();
  17809. width = options.width || DEFAULT_IMAGE_WIDTH;
  17810. height = options.height || DEFAULT_IMAGE_HEIGHT;
  17811. return renderer.createImage(-_round(width * 0.5), -_round(height * 0.5), width, height, url, attr)
  17812. },
  17813. _createSymbolMarker: function(renderer, pointSettings, animationEnabled) {
  17814. var marker,
  17815. options = this._options;
  17816. switch (options.symbol) {
  17817. case"circle":
  17818. marker = renderer.createCircle(0, 0, pointSettings.r, pointSettings.attr);
  17819. break;
  17820. case"square":
  17821. case"polygon":
  17822. case"triangle":
  17823. case"cross":
  17824. marker = renderer.createArea(pointSettings.points, pointSettings.attr);
  17825. break
  17826. }
  17827. return marker
  17828. },
  17829. _createMarker: function(renderer, group, image, settings, animationEnabled) {
  17830. var marker = this._checkImage(image) ? this._createImageMarker(renderer, settings, image) : this._createSymbolMarker(renderer, settings, animationEnabled);
  17831. marker && marker.append(group);
  17832. return marker
  17833. },
  17834. _getSymbolBbox: function(x, y, r) {
  17835. var bbox = {};
  17836. bbox.x = x - r;
  17837. bbox.y = y - r;
  17838. bbox.width = bbox.height = r * 2;
  17839. return bbox
  17840. },
  17841. _getImageBbox: function(x, y) {
  17842. var bbox = {},
  17843. image = this._options.image,
  17844. width = image.width || DEFAULT_IMAGE_WIDTH,
  17845. height = image.height || DEFAULT_IMAGE_HEIGHT;
  17846. bbox.x = x - _round(width / 2);
  17847. bbox.y = y - _round(height / 2);
  17848. bbox.width = width;
  17849. bbox.height = height;
  17850. return bbox
  17851. },
  17852. _getGraphicBbox: function() {
  17853. var options = this._options,
  17854. x = this.x,
  17855. y = this.y,
  17856. bbox;
  17857. if (options.visible)
  17858. bbox = this._checkImage(options.image) ? this._getImageBbox(x, y) : this._getSymbolBbox(x, y, options.styles.normal.r);
  17859. else
  17860. bbox = {
  17861. x: x,
  17862. y: y,
  17863. width: 0,
  17864. height: 0
  17865. };
  17866. return bbox
  17867. },
  17868. _drawLabel: function(renderer, group) {
  17869. var that = this,
  17870. customVisibility = that._getCustomLabelVisibility(),
  17871. visibleArea,
  17872. translators = that.translators;
  17873. if ((that._options.series.getLabelVisibility() || customVisibility) && that.hasValue()) {
  17874. if (translators)
  17875. visibleArea = {
  17876. minX: translators.x.getCanvasVisibleArea().min,
  17877. maxX: translators.x.getCanvasVisibleArea().max,
  17878. minY: translators.y.getCanvasVisibleArea().min,
  17879. maxY: translators.y.getCanvasVisibleArea().max
  17880. };
  17881. that._label.setCoords({
  17882. x: that.x,
  17883. y: that.y
  17884. }, that._getGraphicBbox(), that._getLabelPosition(), visibleArea);
  17885. that._label.draw(renderer, group, customVisibility)
  17886. }
  17887. else
  17888. that._label.hide()
  17889. },
  17890. _drawMarker: function(renderer, group, animationEnabled) {
  17891. var that = this,
  17892. options = that._options,
  17893. translates = that._getTranslates(animationEnabled),
  17894. marker,
  17895. style = that._getStyle(),
  17896. pointAttributes = _extend({
  17897. translateX: translates.x,
  17898. translateY: translates.y
  17899. }, style),
  17900. pointSettings = {
  17901. attr: pointAttributes,
  17902. points: that._populatePointShape(options.symbol, style.r),
  17903. r: style.r
  17904. };
  17905. marker = that._createMarker(renderer, group, options.image, pointSettings, animationEnabled);
  17906. that.graphic = marker
  17907. },
  17908. _drawTrackerMarker: function(renderer, group) {
  17909. var radius = this._options.trackerR || this.storeTrackerR();
  17910. this.trackerGraphic = renderer.createCircle(this.x, this.y, radius).append(group);
  17911. this.trackerGraphic.data({point: this})
  17912. },
  17913. getTooltipCoords: function() {
  17914. var coords;
  17915. if (this.graphic)
  17916. coords = {
  17917. x: this.x,
  17918. y: this.y,
  17919. offset: this.graphic.getBBox().height / 2
  17920. };
  17921. else
  17922. coords = {
  17923. x: this.x,
  17924. y: this.y,
  17925. offset: 0
  17926. };
  17927. return coords
  17928. },
  17929. hasValue: function() {
  17930. return this.value !== null && this.minValue !== null
  17931. },
  17932. setPercentValue: function(total) {
  17933. var valuePercent = this.value / total || 0,
  17934. percent = valuePercent,
  17935. minValuePercent = this.minValue / total || 0;
  17936. percent -= _isNumber(this.minValue) ? minValuePercent : 0;
  17937. this._label.setDataField("percent", percent);
  17938. this._label.setDataField("total", total);
  17939. if (this._options.series.isFullStackedSeries() && this.hasValue()) {
  17940. this.value = valuePercent;
  17941. this.minValue = !minValuePercent ? this.minValue : minValuePercent;
  17942. this.translate()
  17943. }
  17944. },
  17945. storeTrackerR: function() {
  17946. var navigator = window.navigator,
  17947. r = this._options.styles.normal.r,
  17948. minTrackerSize;
  17949. navigator = this.__debug_navigator || navigator;
  17950. this.__debug_browserNavigator = navigator;
  17951. minTrackerSize = "ontouchstart" in window || navigator.msPointerEnabled && navigator.msMaxTouchPoints || navigator.pointerEnabled && navigator.maxTouchPoints ? 20 : 6;
  17952. this._options.trackerR = r < minTrackerSize ? minTrackerSize : r;
  17953. return this._options.trackerR
  17954. },
  17955. _translate: function(translators) {
  17956. var that = this,
  17957. mainAxis = that._options.rotated ? "x" : "y",
  17958. upperMainAxis = mainAxis.toUpperCase(),
  17959. mainTranslator = translators[mainAxis],
  17960. axis = that._options.rotated ? "y" : "x";
  17961. that[mainAxis] = mainTranslator.translate(that.value);
  17962. that[axis] = translators[axis].translate(that.argument);
  17963. that["min" + upperMainAxis] = mainTranslator.translate(that.minValue);
  17964. that["default" + upperMainAxis] = mainTranslator.translate(CANVAS_POSITION_DEFAULT);
  17965. that._calculateVisibility(that.x, that.y);
  17966. that._prepareStatesOptions()
  17967. },
  17968. _changeData: function(data) {
  17969. this.value = this.initialValue = this.originalValue = data.value;
  17970. this.argument = this.initialArgument = this.originalArgument = data.argument;
  17971. this.minValue = this.initialMinValue = this.originalMinValue = _isDefined(data.minValue) ? data.minValue : CANVAS_POSITION_DEFAULT;
  17972. this.tag = data.tag;
  17973. this.index = data.index
  17974. },
  17975. _updateData: function(data) {
  17976. if (this.argument !== data.argument || this.value !== data.value || this.tag !== data.tag)
  17977. this._changeData(data)
  17978. },
  17979. _getImageSettings: function(image) {
  17980. return {
  17981. href: image.url || image.toString(),
  17982. width: image.width || DEFAULT_IMAGE_WIDTH,
  17983. height: image.height || DEFAULT_IMAGE_HEIGHT
  17984. }
  17985. },
  17986. _updateMarker: function(animationEnabled, style) {
  17987. var that = this,
  17988. options = that._options,
  17989. style = style || this._getStyle(),
  17990. settings,
  17991. image = options.image;
  17992. if (that._checkImage(image))
  17993. settings = _extend({}, {visibility: style.visibility}, that._getImageSettings(image));
  17994. else
  17995. settings = _extend({}, style, {points: that._populatePointShape(options.symbol, style.r)});
  17996. if (!animationEnabled) {
  17997. settings.translateX = that.x;
  17998. settings.translateY = that.y
  17999. }
  18000. that.graphic.applySettings(settings)
  18001. },
  18002. _updateTracker: function() {
  18003. this.trackerGraphic.applySettings({
  18004. cx: this.x,
  18005. cy: this.y,
  18006. r: this.storeTrackerR()
  18007. })
  18008. },
  18009. _getLabelFormatObject: function() {
  18010. return {
  18011. argument: this.initialArgument,
  18012. value: this.initialValue,
  18013. originalArgument: this.originalArgument,
  18014. originalValue: this.originalValue,
  18015. seriesName: this._options.series.name,
  18016. point: this
  18017. }
  18018. },
  18019. _getLabelPosition: function() {
  18020. if (this._options.series.isFullStackedSeries() || this.initialValue > 0)
  18021. return "top";
  18022. else
  18023. return "bottom"
  18024. },
  18025. _getFormatObject: function(tooltip) {
  18026. var labelFormatObject = this._label.getData(),
  18027. valueObject = {
  18028. argumentText: tooltip.formatValue(this.initialArgument, "argument"),
  18029. valueText: tooltip.formatValue(this.initialValue)
  18030. },
  18031. percentObject = _isDefined(labelFormatObject.percent) ? {percentText: tooltip.formatValue(labelFormatObject.percent, "percent")} : {},
  18032. totalObject = _isDefined(labelFormatObject.total) ? {totalText: tooltip.formatValue(labelFormatObject.total)} : {};
  18033. return _extend({}, labelFormatObject, valueObject, percentObject, totalObject)
  18034. }
  18035. }
  18036. })(jQuery, DevExpress);
  18037. /*! Module viz-core, file barPoint.js */
  18038. (function($, DX) {
  18039. var viz = DevExpress.viz,
  18040. points = viz.core.series.points.mixins,
  18041. _extend = $.extend,
  18042. _math = Math,
  18043. _round = _math.round,
  18044. _abs = _math.abs,
  18045. _min = _math.min,
  18046. CANVAS_POSITION_DEFAULT = "canvas_position_default",
  18047. DEFAULT_BAR_TRACKER_SIZE = 9,
  18048. CORRECTING_BAR_TRACKER_VALUE = 4;
  18049. points.barPoint = _extend({}, points.symbolPoint, {
  18050. correctCoordinates: function(correctOptions) {
  18051. var correction = correctOptions.offset - _round(correctOptions.width / 2),
  18052. rotated = this._options.rotated,
  18053. valueSelector = rotated ? "height" : "width",
  18054. correctionSelector = (rotated ? "y" : "x") + "Correction";
  18055. this[valueSelector] = correctOptions.width;
  18056. this[correctionSelector] = correction
  18057. },
  18058. _getGraphicBbox: function() {
  18059. var bbox = {};
  18060. bbox.x = this.x;
  18061. bbox.y = this.y;
  18062. bbox.width = this.width;
  18063. bbox.height = this.height;
  18064. return bbox
  18065. },
  18066. _getLabelPosition: function() {
  18067. var position,
  18068. invertX = this.translators.x.getBusinessRange().invert,
  18069. invertY = this.translators.y.getBusinessRange().invert,
  18070. isDiscreteValue = this.series.valueAxisType === "discrete",
  18071. isFullStacked = this.series.isFullStackedSeries(),
  18072. notVerticalInverted = !isDiscreteValue && (this.initialValue >= 0 && !invertY || this.initialValue < 0 && invertY) || isDiscreteValue && !invertY || isFullStacked,
  18073. notHorizontalInverted = !isDiscreteValue && (this.initialValue >= 0 && !invertX || this.initialValue < 0 && invertX) || isDiscreteValue && !invertX || isFullStacked;
  18074. if (!this._options.rotated)
  18075. position = notVerticalInverted ? "top" : "bottom";
  18076. else
  18077. position = notHorizontalInverted ? "top" : "bottom";
  18078. return position
  18079. },
  18080. _drawLabel: function(renderer, group) {
  18081. var that = this,
  18082. options = that._options,
  18083. coords,
  18084. commonVisibility = options.series.getLabelVisibility(),
  18085. customVisibility = that._getCustomLabelVisibility(),
  18086. visibleArea,
  18087. translators = that.translators;
  18088. if (that.hasValue() && (options.label.showForZeroValues || that.initialValue) && (customVisibility || commonVisibility)) {
  18089. coords = {
  18090. x: that.x,
  18091. y: that.y,
  18092. defaultX: that.defaultX,
  18093. defaultY: that.defaultY
  18094. };
  18095. if (translators)
  18096. visibleArea = {
  18097. minX: translators.x.getCanvasVisibleArea().min,
  18098. maxX: translators.x.getCanvasVisibleArea().max,
  18099. minY: translators.y.getCanvasVisibleArea().min,
  18100. maxY: translators.y.getCanvasVisibleArea().max
  18101. };
  18102. that._label.setCoords(coords, that._getGraphicBbox(), that._getLabelPosition(), visibleArea);
  18103. that._label.draw(renderer, group, customVisibility)
  18104. }
  18105. else
  18106. that._label.hide()
  18107. },
  18108. _drawMarker: function(renderer, group, animationEnabled) {
  18109. var style = this._getStyle(),
  18110. x = this.x,
  18111. y = this.y,
  18112. width = this.width,
  18113. height = this.height;
  18114. if (animationEnabled)
  18115. if (this._options.rotated) {
  18116. width = 0;
  18117. x = this.defaultX
  18118. }
  18119. else {
  18120. height = 0;
  18121. y = this.defaultY
  18122. }
  18123. this.graphic = renderer.createRect(x, y, width, height, this._options.cornerRadius, style).append(group)
  18124. },
  18125. _getSettingsForTracker: function() {
  18126. var that = this,
  18127. y = that.y,
  18128. height = that.height,
  18129. x = that.x,
  18130. width = that.width;
  18131. if (that._options.rotated) {
  18132. if (width === 1) {
  18133. width = DEFAULT_BAR_TRACKER_SIZE;
  18134. x -= CORRECTING_BAR_TRACKER_VALUE
  18135. }
  18136. }
  18137. else if (height === 1) {
  18138. height = DEFAULT_BAR_TRACKER_SIZE;
  18139. y -= CORRECTING_BAR_TRACKER_VALUE
  18140. }
  18141. return {
  18142. x: x,
  18143. y: y,
  18144. width: width,
  18145. height: height
  18146. }
  18147. },
  18148. _drawTrackerMarker: function(renderer, group) {
  18149. var settings = this._getSettingsForTracker();
  18150. this.trackerGraphic = renderer.createRect(settings.x, settings.y, settings.width, settings.height, this._options.cornerRadius).append(group);
  18151. this.trackerGraphic.data({point: this})
  18152. },
  18153. getGraphicSettings: function() {
  18154. return {
  18155. x: this.graphic.settings.x || 0,
  18156. y: this.graphic.settings.y || 0,
  18157. height: this.graphic.settings.height || 0,
  18158. width: this.graphic.settings.width || 0
  18159. }
  18160. },
  18161. getTooltipCoords: function() {
  18162. var x = this.x + this.width / 2,
  18163. y = this.y + this.height / 2;
  18164. return {
  18165. x: x,
  18166. y: y,
  18167. offset: 0
  18168. }
  18169. },
  18170. _truncateCoord: function(coord, minBounce, maxBounce) {
  18171. if (coord < minBounce)
  18172. return minBounce;
  18173. if (coord > maxBounce)
  18174. return maxBounce;
  18175. return coord
  18176. },
  18177. _translate: function(translators) {
  18178. var that = this,
  18179. rotated = that._options.rotated,
  18180. valAxis = rotated ? "x" : "y",
  18181. argAxis = rotated ? "y" : "x",
  18182. valIntervalName = rotated ? "width" : "height",
  18183. argIntervalName = rotated ? "height" : "width",
  18184. argTranslator = translators[argAxis],
  18185. valTranslator = translators[valAxis],
  18186. argVisibleArea = argTranslator.getCanvasVisibleArea(),
  18187. valVisibleArea = valTranslator.getCanvasVisibleArea(),
  18188. arg,
  18189. minArg,
  18190. val,
  18191. minVal;
  18192. arg = minArg = argTranslator.translate(that.argument) + (that[argAxis + "Correction"] || 0);
  18193. val = valTranslator.translate(that.value);
  18194. minVal = valTranslator.translate(that.minValue);
  18195. that[valIntervalName] = _abs(val - minVal);
  18196. that._calculateVisibility(rotated ? _min(val, minVal) : _min(arg, minArg), rotated ? _min(arg, minArg) : _min(val, minVal), that.width, that.height);
  18197. val = that._truncateCoord(val, valVisibleArea.min, valVisibleArea.max);
  18198. minVal = that._truncateCoord(minVal, valVisibleArea.min, valVisibleArea.max);
  18199. that[argAxis] = arg;
  18200. that["min" + argAxis.toUpperCase()] = minArg;
  18201. that[valIntervalName] = _abs(val - minVal);
  18202. that[valAxis] = _min(val, minVal) + (that[valAxis + "Correction"] || 0);
  18203. that["min" + valAxis.toUpperCase()] = minVal + (that[valAxis + "Correction"] || 0);
  18204. that["default" + valAxis.toUpperCase()] = valTranslator.translate(CANVAS_POSITION_DEFAULT);
  18205. if (that.inVisibleArea) {
  18206. if (that[argAxis] < argVisibleArea.min) {
  18207. that[argIntervalName] = that[argIntervalName] - (argVisibleArea.min - that[argAxis]);
  18208. that[argAxis] = argVisibleArea.min;
  18209. that["min" + argAxis.toUpperCase()] = argVisibleArea.min
  18210. }
  18211. if (that[argAxis] + that[argIntervalName] > argVisibleArea.max)
  18212. that[argIntervalName] = argVisibleArea.max - that[argAxis]
  18213. }
  18214. },
  18215. _updateMarker: function(animationEnabled, style) {
  18216. var style = style || this._getStyle(),
  18217. attributes = _extend({}, style);
  18218. if (!animationEnabled) {
  18219. attributes.x = this.x;
  18220. attributes.y = this.y;
  18221. attributes.width = this.width;
  18222. attributes.height = this.height
  18223. }
  18224. else
  18225. attributes.sharpEdges = false;
  18226. this.graphic.applySettings(attributes)
  18227. },
  18228. _updateTracker: function() {
  18229. this.trackerGraphic.applySettings(this._getSettingsForTracker())
  18230. }
  18231. })
  18232. })(jQuery, DevExpress);
  18233. /*! Module viz-core, file bubblePoint.js */
  18234. (function($, DX) {
  18235. var viz = DX.viz,
  18236. points = viz.core.series.points.mixins,
  18237. _extend = $.extend,
  18238. MIN_BUBBLE_HEIGHT = 20;
  18239. points.bubblePoint = _extend({}, points.symbolPoint, {
  18240. correctCoordinates: function(diameter) {
  18241. this.bubbleSize = diameter / 2
  18242. },
  18243. _drawMarker: function(renderer, group, animationEnabled) {
  18244. var style = this._getStyle(),
  18245. attr = _extend({
  18246. translateX: this.x,
  18247. translateY: this.y
  18248. }, style),
  18249. marker = renderer.createCircle(0, 0, animationEnabled ? 0 : this.bubbleSize, attr).append(group);
  18250. this.graphic = marker
  18251. },
  18252. _drawTrackerMarker: function(renderer, group) {
  18253. this.trackerGraphic = renderer.createCircle(this.x, this.y, this.bubbleSize).append(group);
  18254. this.trackerGraphic.data({point: this})
  18255. },
  18256. getTooltipCoords: function() {
  18257. if (this.graphic) {
  18258. var height = this.graphic.getBBox().height;
  18259. return {
  18260. x: this.x,
  18261. y: this.y,
  18262. offset: height < MIN_BUBBLE_HEIGHT ? height / 2 : 0
  18263. }
  18264. }
  18265. },
  18266. _getLabelFormatObject: function() {
  18267. var symbolMethods = points.symbolPoint,
  18268. formatObject = symbolMethods._getLabelFormatObject.call(this);
  18269. formatObject.size = this.initialSize;
  18270. return formatObject
  18271. },
  18272. _updateData: function(data) {
  18273. var symbolMethods = points.symbolPoint;
  18274. if (this.argument !== data.argument || this.value !== data.value || this.size !== data.size || this.tag !== data.tag) {
  18275. symbolMethods._changeData.call(this, data);
  18276. this.size = this.initialSize = data.size
  18277. }
  18278. },
  18279. _getGraphicBbox: function() {
  18280. return this._getSymbolBbox(this.x, this.y, this.bubbleSize)
  18281. },
  18282. _updateMarker: function(animationEnabled, style) {
  18283. var style = style || this._getStyle();
  18284. if (!animationEnabled)
  18285. style = $.extend({
  18286. r: this.bubbleSize,
  18287. translateX: this.x,
  18288. translateY: this.y
  18289. }, style);
  18290. this.graphic.applySettings(style)
  18291. },
  18292. _updateTracker: function() {
  18293. this.trackerGraphic.applySettings({
  18294. cx: this.x,
  18295. cy: this.y,
  18296. r: this.bubbleSize
  18297. })
  18298. },
  18299. _getFormatObject: function(tooltip) {
  18300. var symbolMethods = points.symbolPoint,
  18301. formatObject = symbolMethods._getFormatObject.call(this, tooltip);
  18302. formatObject.sizeText = tooltip.formatValue(this.initialSize);
  18303. return formatObject
  18304. }
  18305. })
  18306. })(jQuery, DevExpress);
  18307. /*! Module viz-core, file piePoint.js */
  18308. (function($, DX) {
  18309. var viz = DevExpress.viz,
  18310. points = viz.core.series.points.mixins,
  18311. _extend = $.extend,
  18312. _round = Math.round,
  18313. _getCosAndSin = DX.utils.getCosAndSin;
  18314. points.piePoint = _extend({}, points.symbolPoint, {
  18315. _populatePointShape: function(target, deltaRadius) {
  18316. var angleFunctions = _getCosAndSin(point.middleAngle);
  18317. target.x = point.centerX - ~~(deltaRadius * angleFunctions.cos);
  18318. target.y = point.centerY + ~~(deltaRadius * angleFunctions.sin);
  18319. target.outerRadius = this.radiusOuter + deltaRadius;
  18320. target.innerRadius = this.radiusInner;
  18321. target.startAngle = this.toAngle;
  18322. target.endAngle = this.fromAngle
  18323. },
  18324. _changeData: function(data) {
  18325. var that = this;
  18326. that.value = that.initialValue = that.originalValue = data.value;
  18327. that.argument = that.initialArgument = that.originalArgument = data.argument;
  18328. that.minValue = that.initialMinValue = that.originalMinValue = DevExpress.utils.isDefined(data.minValue) ? data.minValue : 0;
  18329. that.tag = data.tag;
  18330. that._visible = true;
  18331. that.index = data.index
  18332. },
  18333. animate: function(complete, duration, step) {
  18334. this.graphic.animate({
  18335. x: this.centerX,
  18336. y: this.centerY,
  18337. outerRadius: this.radiusOuter,
  18338. innerRadius: this.radiusInner,
  18339. startAngle: this.toAngle,
  18340. endAngle: this.fromAngle
  18341. }, {
  18342. partitionDuration: duration,
  18343. step: step
  18344. }, complete)
  18345. },
  18346. correctPosition: function(correction) {
  18347. this.radiusInner = correction.radiusInner;
  18348. this.radiusOuter = correction.radiusOuter;
  18349. this.centerX = correction.centerX;
  18350. this.centerY = correction.centerY
  18351. },
  18352. correctValue: function(correction, percent, base) {
  18353. this.value = (base || this.initialValue) + correction;
  18354. this.minValue = correction;
  18355. this.percent = percent;
  18356. this._label.setDataField("percent", percent)
  18357. },
  18358. _getLabelOptions: function() {
  18359. var options = this._options,
  18360. series = options.series,
  18361. seriesStyle = this._options.styles.normal,
  18362. borderWidth = series._options.containerBackgroundColor === seriesStyle.stroke ? _round(seriesStyle.strokeWidth / 2) : _round(-seriesStyle.strokeWidth / 2);
  18363. return {
  18364. options: options.label,
  18365. borderWidth: borderWidth
  18366. }
  18367. },
  18368. _updateLabelData: function() {
  18369. this._label.updateData({formatObject: this._getLabelFormatObject()})
  18370. },
  18371. _updateLabelOptions: function() {
  18372. !this._label && this._createLabel();
  18373. this._label.setOptions(this._getLabelOptions())
  18374. },
  18375. _drawLabel: function(renderer, group) {
  18376. var commonVisibility = this._options.series.getLabelVisibility(),
  18377. customVisibility = this._getCustomLabelVisibility();
  18378. if ((commonVisibility || customVisibility) && this.hasValue()) {
  18379. this._label.setCoords({
  18380. middleAngle: this.middleAngle,
  18381. radiusOuter: this.radiusOuter,
  18382. centerX: this.centerX,
  18383. centerY: this.centerY
  18384. }, this._options.series.canvas);
  18385. this._label.draw(renderer, group, customVisibility)
  18386. }
  18387. else
  18388. this._label.hide()
  18389. },
  18390. _drawMarker: function(renderer, group, animationEnabled, firstDrawing) {
  18391. var styles = this._getStyle(),
  18392. radiusOuter = this.radiusOuter,
  18393. radiusInner = this.radiusInner,
  18394. fromAngle = this.fromAngle,
  18395. toAngle = this.toAngle;
  18396. if (animationEnabled) {
  18397. radiusInner = radiusOuter = 0;
  18398. if (!firstDrawing)
  18399. fromAngle = toAngle = this.shiftedAngle
  18400. }
  18401. this.graphic = renderer.createArc(this.centerX, this.centerY, radiusOuter, radiusInner, toAngle, fromAngle, styles).append(group)
  18402. },
  18403. _drawTrackerMarker: function(renderer, group) {
  18404. this.trackerGraphic = renderer.createArc(this.centerX, this.centerY, this.radiusOuter, this.radiusInner, this.toAngle, this.fromAngle).append(group);
  18405. this.trackerGraphic.data({point: this})
  18406. },
  18407. getTooltipCoords: function() {
  18408. var angleFunctions = _getCosAndSin(this.middleAngle);
  18409. return {
  18410. x: this.centerX + (this.radiusInner + (this.radiusOuter - this.radiusInner) / 2) * angleFunctions.cos,
  18411. y: this.centerY - (this.radiusInner + (this.radiusOuter - this.radiusInner) / 2) * angleFunctions.sin,
  18412. offset: 0
  18413. }
  18414. },
  18415. _translate: function(translator) {
  18416. var angle = this.shiftedAngle || 0;
  18417. this.fromAngle = translator.translate(this.minValue) + angle;
  18418. this.toAngle = translator.translate(this.value) + angle;
  18419. this.middleAngle = translator.translate((this.value - this.minValue) / 2 + this.minValue) + angle;
  18420. if (!this.isVisible())
  18421. this.middleAngle = this.toAngle = this.fromAngle = this.fromAngle || angle
  18422. },
  18423. _updateMarker: function(animationEnabled, style) {
  18424. style = style || this._getStyle();
  18425. if (!animationEnabled)
  18426. style = _extend({
  18427. x: this.centerX,
  18428. y: this.centerY,
  18429. outerRadius: this.radiusOuter,
  18430. innerRadius: this.radiusInner,
  18431. startAngle: this.toAngle,
  18432. endAngle: this.fromAngle
  18433. }, style);
  18434. this.graphic.applySettings(style)
  18435. },
  18436. _updateTracker: function() {
  18437. this.trackerGraphic.applySettings({
  18438. x: this.centerX,
  18439. y: this.centerY,
  18440. outerRadius: this.radiusOuter,
  18441. innerRadius: this.radiusInner,
  18442. startAngle: this.toAngle,
  18443. endAngle: this.fromAngle
  18444. })
  18445. },
  18446. getLegendStyles: function() {
  18447. return this._styles.legendStyles
  18448. },
  18449. isInVisibleArea: function() {
  18450. return true
  18451. },
  18452. hide: function() {
  18453. if (this._visible) {
  18454. this._visible = false;
  18455. this.hideTooltip();
  18456. this._options.visibilityChanged(this)
  18457. }
  18458. },
  18459. show: function() {
  18460. if (!this._visible) {
  18461. this._visible = true;
  18462. this._options.visibilityChanged(this)
  18463. }
  18464. },
  18465. setInvisibility: function() {
  18466. this._setTrackerInvisibility();
  18467. this._label.hide()
  18468. },
  18469. isVisible: function() {
  18470. return this._visible
  18471. },
  18472. _getFormatObject: function(tooltip) {
  18473. var symbolMethods = points.symbolPoint,
  18474. formatObject = symbolMethods._getFormatObject.call(this, tooltip);
  18475. formatObject.percent = this.percent;
  18476. formatObject.percentText = tooltip.formatValue(this.percent, "percent");
  18477. return formatObject
  18478. },
  18479. getColor: function() {
  18480. return this._styles.normal.fill
  18481. }
  18482. })
  18483. })(jQuery, DevExpress);
  18484. /*! Module viz-core, file rangeSymbolPoint.js */
  18485. (function($, DX) {
  18486. var viz = DevExpress.viz,
  18487. points = viz.core.series.points.mixins,
  18488. _extend = $.extend,
  18489. _isDefined = DX.utils.isDefined,
  18490. _math = Math,
  18491. _abs = _math.abs,
  18492. _min = _math.min,
  18493. _max = _math.max,
  18494. _round = _math.round,
  18495. DEFAULT_IMAGE_WIDTH = 20,
  18496. DEFAULT_IMAGE_HEIGHT = 20;
  18497. points.rangeSymbolPoint = _extend({}, points.symbolPoint, {
  18498. deleteLabel: function() {
  18499. this._topLabel.dispose();
  18500. this._topLabel = null;
  18501. this._bottomLabel.dispose();
  18502. this._bottomLabel = null
  18503. },
  18504. hideMarker: function(type) {
  18505. var marker = this.graphic && this.graphic[type + "Marker"],
  18506. label = this["_" + type + "Label"];
  18507. if (marker && marker.settings.visibility !== "hidden")
  18508. marker.applySettings({visibility: "hidden"});
  18509. label.hide()
  18510. },
  18511. setInvisibility: function() {
  18512. this.hideMarker("top");
  18513. this.hideMarker("bottom");
  18514. this._setTrackerInvisibility()
  18515. },
  18516. clearVisibility: function() {
  18517. var graphic = this.graphic;
  18518. if (graphic) {
  18519. if (graphic.topMarker && graphic.topMarker.settings.visibility)
  18520. graphic.topMarker.applySettings({visibility: null});
  18521. if (graphic.bottomMarker && graphic.bottomMarker.settings.visibility)
  18522. graphic.bottomMarker.applySettings({visibility: null})
  18523. }
  18524. this._clearTrackerVisibility();
  18525. this._topLabel.clearVisibility();
  18526. this._bottomLabel.clearVisibility()
  18527. },
  18528. clearMarker: function() {
  18529. if (this.graphic) {
  18530. this.graphic.topMarker && this.graphic.topMarker.applySettings(this._emptySettings);
  18531. this.graphic.bottomMarker && this.graphic.bottomMarker.applySettings(this._emptySettings)
  18532. }
  18533. },
  18534. _getLabelPosition: function(markerType) {
  18535. var position,
  18536. rotated = this._options.rotated,
  18537. invertY = this.translators.y.getBusinessRange().invert,
  18538. invertX = this.translators.x.getBusinessRange().invert,
  18539. isDiscreteValue = this._options.series._options.valueAxisType === "discrete",
  18540. notInverted = isDiscreteValue && (!invertY && !rotated || invertX && rotated) || !isDiscreteValue && this.value > this.minValue && (!invertY && !rotated || !invertX && rotated);
  18541. if (markerType === "top")
  18542. position = notInverted ? "top" : "bottom";
  18543. else
  18544. position = notInverted ? "bottom" : "top";
  18545. return position
  18546. },
  18547. _getLabelMinFormatObject: function() {
  18548. return {
  18549. index: 0,
  18550. argument: this.initialArgument,
  18551. value: this.initialMinValue,
  18552. seriesName: this._options.series.name,
  18553. originalValue: this.originalMinValue,
  18554. originalArgument: this.originalArgument,
  18555. point: this
  18556. }
  18557. },
  18558. _updateLabelData: function() {
  18559. var maxFormatObject = this._getLabelFormatObject();
  18560. maxFormatObject.index = 1;
  18561. this._topLabel.updateData({
  18562. formatObject: maxFormatObject,
  18563. initialValue: this.initialValue
  18564. });
  18565. this._bottomLabel.updateData({
  18566. formatObject: this._getLabelMinFormatObject(),
  18567. initialValue: this.initialMinValue
  18568. })
  18569. },
  18570. _updateLabelOptions: function(type) {
  18571. var options = this._getLabelOptions(type);
  18572. (!this._topLabel || !this._bottomLabel) && this._createLabel();
  18573. this._topLabel.setOptions(options);
  18574. this._bottomLabel.setOptions(options)
  18575. },
  18576. setAdjustSeriesLabels: function(adjustSeriesLabels) {
  18577. this._topLabel.adjustSeriesLabels = adjustSeriesLabels;
  18578. this._bottomLabel.adjustSeriesLabels = adjustSeriesLabels
  18579. },
  18580. _createLabel: function() {
  18581. this._topLabel = viz.core.CoreFactory.createLabel();
  18582. this._bottomLabel = viz.core.CoreFactory.createLabel()
  18583. },
  18584. _getLabelCoords: function(location) {
  18585. var coords = {},
  18586. isTop = location === "top";
  18587. if (!this._options.rotated) {
  18588. coords.x = this.x;
  18589. coords.y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)
  18590. }
  18591. else {
  18592. coords.x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);
  18593. coords.y = this.y
  18594. }
  18595. return coords
  18596. },
  18597. _getGraphicBbox: function(location) {
  18598. var options = this._options,
  18599. rotated = options.rotated,
  18600. isTop = location === "top",
  18601. images = this._getImage(options.image),
  18602. image = isTop ? this._checkImage(images.top) : this._checkImage(images.bottom),
  18603. bbox,
  18604. x,
  18605. y;
  18606. if (!rotated) {
  18607. x = this.x;
  18608. y = isTop ? _min(this.y, this.minY) : _max(this.y, this.minY)
  18609. }
  18610. else {
  18611. x = isTop ? _max(this.x, this.minX) : _min(this.x, this.minX);
  18612. y = this.y
  18613. }
  18614. if (options.visible)
  18615. bbox = image ? this._getImageBbox(x, y) : this._getSymbolBbox(x, y, options.styles.normal.r);
  18616. else
  18617. bbox = {
  18618. x: x,
  18619. y: y,
  18620. width: 0,
  18621. height: 0
  18622. };
  18623. return bbox
  18624. },
  18625. _checkOverlay: function(bottomCoord, topCoord, topValue) {
  18626. return bottomCoord < topCoord + topValue
  18627. },
  18628. _getOverlayCorrections: function(type, topCoords, bottomCoords) {
  18629. var isVertical = type === "vertical",
  18630. coordSelector = isVertical ? "y" : "x",
  18631. valueSelector = isVertical ? "height" : "width",
  18632. visibleArea = this.translators[coordSelector].getCanvasVisibleArea(),
  18633. minBound = visibleArea.min,
  18634. maxBound = visibleArea.max,
  18635. delta = _round((topCoords[coordSelector] + topCoords[valueSelector] - bottomCoords[coordSelector]) / 2),
  18636. coord1 = topCoords[coordSelector] - delta,
  18637. coord2 = bottomCoords[coordSelector] + delta;
  18638. if (coord1 < minBound) {
  18639. delta = minBound - topCoords[coordSelector];
  18640. coord1 += delta;
  18641. coord2 += delta
  18642. }
  18643. else if (coord2 + bottomCoords[valueSelector] > maxBound) {
  18644. delta = -(bottomCoords[coordSelector] + bottomCoords[valueSelector] - maxBound);
  18645. coord1 += delta;
  18646. coord2 += delta
  18647. }
  18648. return {
  18649. coord1: coord1,
  18650. coord2: coord2
  18651. }
  18652. },
  18653. _checkLabelsOverlay: function(topLocation) {
  18654. var that = this,
  18655. topCoords = that._topLabel.getCoords(),
  18656. bottomCoords = that._bottomLabel.getCoords(),
  18657. corrections = {};
  18658. if (!that._options.rotated) {
  18659. if (topLocation === "top") {
  18660. if (this._checkOverlay(bottomCoords.y, topCoords.y, topCoords.height)) {
  18661. corrections = this._getOverlayCorrections("vertical", topCoords, bottomCoords);
  18662. that._topLabel.updatePosition(undefined, corrections.coord1);
  18663. that._bottomLabel.updatePosition(undefined, corrections.coord2)
  18664. }
  18665. }
  18666. else if (this._checkOverlay(topCoords.y, bottomCoords.y, bottomCoords.height)) {
  18667. corrections = this._getOverlayCorrections("vertical", bottomCoords, topCoords);
  18668. that._topLabel.updatePosition(undefined, corrections.coord2);
  18669. that._bottomLabel.updatePosition(undefined, corrections.coord1)
  18670. }
  18671. }
  18672. else if (topLocation === "top") {
  18673. if (this._checkOverlay(topCoords.x, bottomCoords.x, bottomCoords.width)) {
  18674. corrections = this._getOverlayCorrections("horizontal", bottomCoords, topCoords);
  18675. that._topLabel.updatePosition(corrections.coord2);
  18676. that._bottomLabel.updatePosition(corrections.coord1)
  18677. }
  18678. }
  18679. else if (this._checkOverlay(bottomCoords.x, topCoords.x, topCoords.width)) {
  18680. corrections = this._getOverlayCorrections("horizontal", topCoords, bottomCoords);
  18681. that._topLabel.updatePosition(corrections.coord1);
  18682. that._bottomLabel.updatePosition(corrections.coord2)
  18683. }
  18684. },
  18685. _drawLabel: function(renderer, group) {
  18686. var topCoords,
  18687. bottomCoords,
  18688. rotated = this._options.rotated,
  18689. topLocation = this._getLabelPosition("top"),
  18690. bottomLocation = this._getLabelPosition("bottom"),
  18691. isInside = this._options.label.position === "inside",
  18692. topPosition = isInside ? bottomLocation : topLocation,
  18693. bottomPosition = isInside ? topLocation : bottomLocation,
  18694. translators = this.translators,
  18695. visibleArea,
  18696. customVisibility = this._getCustomLabelVisibility(),
  18697. commonVisibility = this._options.series.getLabelVisibility();
  18698. if ((commonVisibility || customVisibility) && this.hasValue()) {
  18699. if (translators)
  18700. visibleArea = {
  18701. minX: translators.x.getCanvasVisibleArea().min,
  18702. maxX: translators.x.getCanvasVisibleArea().max,
  18703. minY: translators.y.getCanvasVisibleArea().min,
  18704. maxY: translators.y.getCanvasVisibleArea().max
  18705. };
  18706. this._topLabel.setCoords(this._getLabelCoords(topLocation), this._getGraphicBbox(topLocation), topPosition, visibleArea);
  18707. this._bottomLabel.setCoords(this._getLabelCoords(bottomLocation), this._getGraphicBbox(bottomLocation), bottomPosition, visibleArea);
  18708. this.visibleTopMarker && this._topLabel.draw(renderer, group, customVisibility);
  18709. this.visibleBottomMarker && this._bottomLabel.draw(renderer, group, customVisibility);
  18710. this._checkLabelsOverlay(topLocation)
  18711. }
  18712. else {
  18713. this._topLabel.hide();
  18714. this._bottomLabel.hide()
  18715. }
  18716. },
  18717. _getImage: function(imageOption) {
  18718. var image = {};
  18719. if (_isDefined(imageOption))
  18720. if (typeof imageOption === "string")
  18721. image.top = image.bottom = imageOption;
  18722. else {
  18723. image.top = {
  18724. url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMaxPoint,
  18725. width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMaxPoint,
  18726. height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMaxPoint
  18727. };
  18728. image.bottom = {
  18729. url: typeof imageOption.url === "string" ? imageOption.url : imageOption.url && imageOption.url.rangeMinPoint,
  18730. width: typeof imageOption.width === "number" ? imageOption.width : imageOption.width && imageOption.width.rangeMinPoint,
  18731. height: typeof imageOption.height === "number" ? imageOption.height : imageOption.height && imageOption.height.rangeMinPoint
  18732. }
  18733. }
  18734. return image
  18735. },
  18736. _checkSymbol: function(oldOptions, newOptions) {
  18737. var oldSymbol = oldOptions.symbol,
  18738. newSymbol = newOptions.symbol,
  18739. symbolChanged = oldSymbol === "circle" && newSymbol !== "circle" || oldSymbol !== "circle" && newSymbol === "circle",
  18740. oldImages = this._getImage(oldOptions.image),
  18741. newImages = this._getImage(newOptions.image),
  18742. topImageChanged = this._checkImage(oldImages.top) !== this._checkImage(newImages.top),
  18743. bottomImageChanged = this._checkImage(oldImages.bottom) !== this._checkImage(newImages.bottom);
  18744. return symbolChanged || topImageChanged || bottomImageChanged
  18745. },
  18746. _getSettingsForTwoMarkers: function(style) {
  18747. var that = this,
  18748. options = that._options,
  18749. settings = {},
  18750. x = options.rotated ? _min(that.x, that.minX) : that.x,
  18751. y = options.rotated ? that.y : _min(that.y, that.minY),
  18752. radius = style.r,
  18753. points = that._populatePointShape(options.symbol, radius);
  18754. settings.top = {
  18755. r: radius,
  18756. points: points,
  18757. attr: _extend({
  18758. translateX: x + that.width,
  18759. translateY: y
  18760. }, style)
  18761. };
  18762. settings.bottom = {
  18763. r: radius,
  18764. points: points,
  18765. attr: _extend({
  18766. translateX: x,
  18767. translateY: y + that.height
  18768. }, style)
  18769. };
  18770. return settings
  18771. },
  18772. _hasGraphic: function() {
  18773. return this.graphic && this.graphic.topMarker && this.graphic.bottomMarker
  18774. },
  18775. _drawOneMarker: function(renderer, markerType, imageSettings, settings) {
  18776. if (this.graphic[markerType])
  18777. this._updateOneMarker(markerType, settings);
  18778. else
  18779. this.graphic[markerType] = this._createMarker(renderer, this.graphic, imageSettings, settings)
  18780. },
  18781. _drawMarker: function(renderer, group, animationEnabled, style) {
  18782. var that = this,
  18783. style = style || that._getStyle(),
  18784. settings = that._getSettingsForTwoMarkers(style),
  18785. image = that._getImage(that._options.image);
  18786. if (that._checkImage(image.top))
  18787. settings.top = that._getImageSettings(settings.top, image.top);
  18788. if (that._checkImage(image.bottom))
  18789. settings.bottom = that._getImageSettings(settings.bottom, image.bottom);
  18790. that.graphic = that.graphic || renderer.createGroup().append(group);
  18791. that.visibleTopMarker && that._drawOneMarker(renderer, 'topMarker', image.top, settings.top);
  18792. that.visibleBottomMarker && that._drawOneMarker(renderer, 'bottomMarker', image.bottom, settings.bottom)
  18793. },
  18794. _getSettingsForTracker: function(radius) {
  18795. var that = this,
  18796. options = that._options,
  18797. x = options.rotated ? _min(that.x, that.minX) - radius : that.x - radius,
  18798. y = options.rotated ? that.y - radius : _min(that.y, that.minY) - radius,
  18799. width = that.width + 2 * radius,
  18800. height = that.height + 2 * radius;
  18801. return {
  18802. translateX: x,
  18803. translateY: y,
  18804. width: width,
  18805. height: height
  18806. }
  18807. },
  18808. _drawTrackerMarker: function(renderer, group) {
  18809. var that = this,
  18810. options = that._options,
  18811. radius = options.trackerR || that.storeTrackerR(),
  18812. settings = that._getSettingsForTracker(radius),
  18813. attr = {
  18814. translateX: settings.translateX,
  18815. translateY: settings.translateY
  18816. };
  18817. that.trackerGraphic = renderer.createRect(0, 0, settings.width, settings.height, 0, attr).append(group);
  18818. that.trackerGraphic.data({point: that})
  18819. },
  18820. isInVisibleArea: function() {
  18821. var that = this,
  18822. minArgument = _min(that.minX, that.x) || that.x,
  18823. maxArgument = _max(that.minX, that.x) || that.x,
  18824. maxValue = _max(that.minY, that.y) || that.y,
  18825. minValue = _min(that.minY, that.y) || that.y,
  18826. notVisibleBothMarkersRight,
  18827. notVisibleBothMarkersLeft,
  18828. notVisibleBothMarkersBottom,
  18829. notVisibleBothMarkersTop,
  18830. visibleTopMarker = true,
  18831. visibleBottomMarker = true,
  18832. visibleRangeArea = true,
  18833. visibleAreaX,
  18834. visibleAreaY;
  18835. if (that.translators) {
  18836. visibleAreaX = that.translators.x.getCanvasVisibleArea();
  18837. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  18838. notVisibleBothMarkersRight = visibleAreaX.max < minArgument && visibleAreaX.max < maxArgument;
  18839. notVisibleBothMarkersLeft = visibleAreaX.min > minArgument && visibleAreaX.min > maxArgument;
  18840. notVisibleBothMarkersTop = visibleAreaY.min > minValue && visibleAreaY.min > maxValue;
  18841. notVisibleBothMarkersBottom = visibleAreaY.max < minValue && visibleAreaY.max < maxValue;
  18842. if (notVisibleBothMarkersTop || notVisibleBothMarkersBottom || notVisibleBothMarkersRight || notVisibleBothMarkersLeft)
  18843. visibleTopMarker = visibleBottomMarker = visibleRangeArea = false;
  18844. else if (!that._options.rotated) {
  18845. visibleTopMarker = visibleAreaY.min < minValue && visibleAreaY.max > minValue;
  18846. visibleBottomMarker = visibleAreaY.min < maxValue && visibleAreaY.max > maxValue
  18847. }
  18848. else {
  18849. visibleBottomMarker = visibleAreaX.min < minArgument && visibleAreaX.max > minArgument;
  18850. visibleTopMarker = visibleAreaX.min < maxArgument && visibleAreaX.max > maxArgument
  18851. }
  18852. }
  18853. that.visibleTopMarker = visibleTopMarker;
  18854. that.visibleBottomMarker = visibleBottomMarker;
  18855. that.visibleRangeArea = visibleRangeArea;
  18856. return visibleRangeArea
  18857. },
  18858. getTooltipCoords: function() {
  18859. var that = this,
  18860. x,
  18861. y,
  18862. min,
  18863. max,
  18864. minValue,
  18865. visibleAreaX = that.translators.x.getCanvasVisibleArea(),
  18866. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  18867. if (!that._options.rotated) {
  18868. minValue = _min(that.y, that.minY);
  18869. x = that.x;
  18870. min = visibleAreaY.min > minValue ? visibleAreaY.min : minValue;
  18871. max = visibleAreaY.max < minValue + that.height ? visibleAreaY.max : minValue + that.height;
  18872. y = min + (max - min) / 2
  18873. }
  18874. else {
  18875. minValue = _min(that.x, that.minX);
  18876. y = that.y;
  18877. min = visibleAreaX.min > minValue ? visibleAreaX.min : minValue;
  18878. max = visibleAreaX.max < minValue + that.width ? visibleAreaX.max : minValue + that.width;
  18879. x = min + (max - min) / 2
  18880. }
  18881. return {
  18882. x: x,
  18883. y: y,
  18884. offset: 0
  18885. }
  18886. },
  18887. _translate: function(translators) {
  18888. var symbolMethods = points.symbolPoint;
  18889. this.minX = this.minY = translators.y.translate(this.minValue);
  18890. symbolMethods._translate.call(this, translators);
  18891. this.height = this._options.rotated ? 0 : _abs(this.minY - this.y);
  18892. this.width = this._options.rotated ? _abs(this.x - this.minX) : 0
  18893. },
  18894. _updateData: function(data) {
  18895. if (this.argument !== data.argument || this.value !== data.value || this.minValue !== data.minValue || this.tag !== data.tag) {
  18896. this._changeData(data);
  18897. this.minValue = this.initialMinValue = this.originalMinValue = data.minValue
  18898. }
  18899. },
  18900. _getImageSettings: function(settings, image) {
  18901. var x = settings.attr.translateX,
  18902. y = settings.attr.translateY;
  18903. return {
  18904. href: image.url || image.toString(),
  18905. width: image.width || DEFAULT_IMAGE_WIDTH,
  18906. height: image.height || DEFAULT_IMAGE_HEIGHT,
  18907. attr: {
  18908. translateX: x,
  18909. translateY: y
  18910. }
  18911. }
  18912. },
  18913. _updateOneMarker: function(markerType, settings) {
  18914. this.graphic && this.graphic[markerType] && this.graphic[markerType].applySettings(_extend({}, settings, settings.attr))
  18915. },
  18916. _updateMarker: function(animationEnabled, style) {
  18917. this._drawMarker(undefined, undefined, undefined, style)
  18918. },
  18919. _updateTracker: function() {
  18920. var radius = this.storeTrackerR(),
  18921. settings = this._getSettingsForTracker(radius);
  18922. this.trackerGraphic.applySettings(settings)
  18923. },
  18924. _getFormatObject: function(tooltip) {
  18925. var minValue = tooltip.formatValue(this.initialMinValue),
  18926. value = tooltip.formatValue(this.initialValue);
  18927. return {
  18928. argument: this.initialArgument,
  18929. argumentText: tooltip.formatValue(this.initialArgument, "argument"),
  18930. valueText: minValue + " - " + value,
  18931. rangeValue1Text: minValue,
  18932. rangeValue2Text: value,
  18933. rangeValue1: this.initialMinValue,
  18934. rangeValue2: this.initialValue,
  18935. seriesName: this.series.name,
  18936. point: this,
  18937. originalMinValue: this.originalMinValue,
  18938. originalValue: this.originalValue,
  18939. originalArgument: this.originalArgument
  18940. }
  18941. }
  18942. })
  18943. })(jQuery, DevExpress);
  18944. /*! Module viz-core, file rangeBarPoint.js */
  18945. (function($, DX) {
  18946. var viz = DevExpress.viz,
  18947. points = viz.core.series.points.mixins,
  18948. _isDefined = DX.utils.isDefined,
  18949. rangeSymbolPointMethods = points.rangeSymbolPoint,
  18950. _extend = $.extend;
  18951. points.rangeBarPoint = _extend({}, points.barPoint, {
  18952. deleteLabel: rangeSymbolPointMethods.deleteLabel,
  18953. _getFormatObject: rangeSymbolPointMethods._getFormatObject,
  18954. setAdjustSeriesLabels: rangeSymbolPointMethods.setAdjustSeriesLabels,
  18955. clearVisibility: function() {
  18956. if (this.graphic && this.graphic.settings.visibility)
  18957. this.graphic.applySettings({visibility: null});
  18958. this._topLabel.clearVisibility();
  18959. this._bottomLabel.clearVisibility()
  18960. },
  18961. setInvisibility: function() {
  18962. if (this.graphic && this.graphic.settings.visibility !== "hidden")
  18963. this.graphic.applySettings({visibility: "hidden"});
  18964. this._topLabel.hide();
  18965. this._bottomLabel.hide()
  18966. },
  18967. _translate: function(translator) {
  18968. var barMethods = points.barPoint;
  18969. barMethods._translate.call(this, translator);
  18970. if (this._options.rotated)
  18971. this.width = this.width || 1;
  18972. else
  18973. this.height = this.height || 1
  18974. },
  18975. _updateData: rangeSymbolPointMethods._updateData,
  18976. _getLabelPosition: rangeSymbolPointMethods._getLabelPosition,
  18977. _getLabelMinFormatObject: rangeSymbolPointMethods._getLabelMinFormatObject,
  18978. _updateLabelData: rangeSymbolPointMethods._updateLabelData,
  18979. _updateLabelOptions: rangeSymbolPointMethods._updateLabelOptions,
  18980. _createLabel: rangeSymbolPointMethods._createLabel,
  18981. _checkOverlay: rangeSymbolPointMethods._checkOverlay,
  18982. _getOverlayCorrections: rangeSymbolPointMethods._getOverlayCorrections,
  18983. _drawLabel: function(renderer, group) {
  18984. var topCoords,
  18985. bottomCoords,
  18986. rotated = this._options.rotated,
  18987. topLocation = this._getLabelPosition("top"),
  18988. bottomLocation = this._getLabelPosition("bottom"),
  18989. bbox = this._getGraphicBbox(),
  18990. coords = {
  18991. x: this.x,
  18992. y: this.y,
  18993. defaultX: this.defaultX,
  18994. defaultY: this.defaultY
  18995. },
  18996. translators = this.translators,
  18997. visibleArea,
  18998. customVisibility = this._getCustomLabelVisibility(),
  18999. commonVisibility = this._options.series.getLabelVisibility();
  19000. if ((customVisibility || commonVisibility) && this.hasValue()) {
  19001. if (translators)
  19002. visibleArea = {
  19003. minX: translators.x.getCanvasVisibleArea().min,
  19004. maxX: translators.x.getCanvasVisibleArea().max,
  19005. minY: translators.y.getCanvasVisibleArea().min,
  19006. maxY: translators.y.getCanvasVisibleArea().max
  19007. };
  19008. this._topLabel.setCoords(coords, bbox, topLocation, visibleArea);
  19009. this._bottomLabel.setCoords(coords, bbox, bottomLocation, visibleArea);
  19010. this._topLabel.draw(renderer, group, customVisibility);
  19011. this._bottomLabel.draw(renderer, group, customVisibility);
  19012. rangeSymbolPointMethods._checkLabelsOverlay.call(this, topLocation)
  19013. }
  19014. else {
  19015. this._topLabel.hide();
  19016. this._bottomLabel.hide()
  19017. }
  19018. }
  19019. })
  19020. })(jQuery, DevExpress);
  19021. /*! Module viz-core, file candlestickPoint.js */
  19022. (function($, DX) {
  19023. var viz = DevExpress.viz,
  19024. points = viz.core.series.points.mixins,
  19025. _isNumeric = $.isNumeric,
  19026. _extend = $.extend,
  19027. _math = Math,
  19028. _abs = _math.abs,
  19029. _min = _math.min,
  19030. _max = _math.max,
  19031. _round = _math.round,
  19032. DEFAULT_FINANCIAL_TRACKER_MARGIN = 2;
  19033. points.candlestickPoint = _extend({}, points.barPoint, {
  19034. _getContinuousPoints: function(minValueName, maxValueName) {
  19035. var that = this,
  19036. x = that.x,
  19037. createPoint = that._options.rotated ? function(x, y) {
  19038. return {
  19039. x: y,
  19040. y: x
  19041. }
  19042. } : function(x, y) {
  19043. return {
  19044. x: x,
  19045. y: y
  19046. }
  19047. },
  19048. width = that.width,
  19049. min = that[minValueName],
  19050. max = that[maxValueName],
  19051. points;
  19052. if (min === max)
  19053. 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)];
  19054. else
  19055. 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)];
  19056. return points
  19057. },
  19058. _getCategoryPoints: function(y) {
  19059. var that = this,
  19060. x = that.x,
  19061. createPoint = that._options.rotated ? function(x, y) {
  19062. return {
  19063. x: y,
  19064. y: x
  19065. }
  19066. } : function(x, y) {
  19067. return {
  19068. x: x,
  19069. y: y
  19070. }
  19071. };
  19072. 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)]
  19073. },
  19074. _getPoints: function() {
  19075. var that = this,
  19076. points,
  19077. minValueName,
  19078. maxValueName,
  19079. openValue = that.openValue,
  19080. closeValue = that.closeValue;
  19081. if (_isNumeric(openValue) && _isNumeric(closeValue)) {
  19082. minValueName = openValue > closeValue ? "closeY" : "openY";
  19083. maxValueName = openValue > closeValue ? "openY" : "closeY";
  19084. points = that._getContinuousPoints(minValueName, maxValueName)
  19085. }
  19086. else if (openValue === closeValue)
  19087. points = [{
  19088. x: that.x,
  19089. y: that.highY
  19090. }, {
  19091. x: that.x,
  19092. y: that.lowY
  19093. }];
  19094. else
  19095. points = that._getCategoryPoints(_isNumeric(openValue) ? that.openY : that.closeY);
  19096. return points
  19097. },
  19098. getColor: function() {
  19099. return this._isReduction ? this._options.reduction.color : this._styles.normal.stroke || this.series.getColor()
  19100. },
  19101. _drawMarkerInGroup: function(group, attributes, renderer) {
  19102. this.graphic = renderer.createArea(this._getPoints(), attributes).append(group)
  19103. },
  19104. _fillStyle: function() {
  19105. var styles = this._options.styles;
  19106. if (this._isReduction && this._isPositive)
  19107. this._styles = styles.reductionPositive;
  19108. else if (this._isReduction)
  19109. this._styles = styles.reduction;
  19110. else if (this._isPositive)
  19111. this._styles = styles.positive;
  19112. else
  19113. this._styles = styles
  19114. },
  19115. _getMinTrackerWidth: function() {
  19116. return 1 + 2 * this._styles.normal.strokeWidth
  19117. },
  19118. correctCoordinates: function(correctOptions) {
  19119. var minWidth = this._getMinTrackerWidth(),
  19120. maxWidth = 10;
  19121. this.width = correctOptions.width < minWidth ? minWidth : correctOptions.width > maxWidth ? maxWidth : correctOptions.width;
  19122. this.xCorrection = correctOptions.offset
  19123. },
  19124. _getMarkerGroup: function(group) {
  19125. var markerGroup;
  19126. if (this._isReduction && this._isPositive)
  19127. markerGroup = group.reductionPositiveMarkersGroup;
  19128. else if (this._isReduction)
  19129. markerGroup = group.reductionMarkersGroup;
  19130. else if (this._isPositive)
  19131. markerGroup = group.defaultPositiveMarkersGroup;
  19132. else
  19133. markerGroup = group.defaultMarkersGroup;
  19134. return markerGroup
  19135. },
  19136. _drawMarker: function(renderer, group) {
  19137. var attributes = this._getStyle(),
  19138. rotated = this._options.rotated,
  19139. pointGroup = this._getMarkerGroup(group);
  19140. this._drawMarkerInGroup(pointGroup, attributes, renderer)
  19141. },
  19142. _getSettingsForTracker: function() {
  19143. var that = this,
  19144. highY = that.highY,
  19145. lowY = that.lowY,
  19146. rotated = that._options.rotated,
  19147. x,
  19148. y,
  19149. width,
  19150. height;
  19151. if (highY === lowY) {
  19152. highY = rotated ? highY + DEFAULT_FINANCIAL_TRACKER_MARGIN : highY - DEFAULT_FINANCIAL_TRACKER_MARGIN;
  19153. lowY = rotated ? lowY - DEFAULT_FINANCIAL_TRACKER_MARGIN : lowY + DEFAULT_FINANCIAL_TRACKER_MARGIN
  19154. }
  19155. if (rotated) {
  19156. x = _min(lowY, highY);
  19157. y = that.x - that.width / 2;
  19158. width = _abs(lowY - highY);
  19159. height = that.width
  19160. }
  19161. else {
  19162. x = that.x - that.width / 2;
  19163. y = _min(lowY, highY);
  19164. width = that.width;
  19165. height = _abs(lowY - highY)
  19166. }
  19167. return {
  19168. x: x,
  19169. y: y,
  19170. width: width,
  19171. height: height
  19172. }
  19173. },
  19174. _drawTrackerMarker: function(renderer, group) {
  19175. var settings = this._getSettingsForTracker();
  19176. this.trackerGraphic = renderer.createRect(settings.x, settings.y, settings.width, settings.height, 0).append(group);
  19177. this.trackerGraphic.data({point: this})
  19178. },
  19179. _getGraphicBbox: function() {
  19180. var bbox = {},
  19181. rotated = this._options.rotated;
  19182. bbox.x = !rotated ? this.x - _round(this.width / 2) : this.lowY;
  19183. bbox.y = !rotated ? this.highY : this.x - _round(this.width / 2);
  19184. bbox.width = !rotated ? this.width : this.highY - this.lowY;
  19185. bbox.height = !rotated ? this.lowY - this.highY : this.width;
  19186. return bbox
  19187. },
  19188. _drawLabel: function(renderer, group) {
  19189. var coords,
  19190. commonVisibility = this._options.series.getLabelVisibility(),
  19191. customVisibility = this._getCustomLabelVisibility(),
  19192. visibleArea,
  19193. reductionColor = this._options.reduction.color,
  19194. translators = this.translators;
  19195. if (this.hasValue() && (commonVisibility || customVisibility)) {
  19196. visibleArea = {
  19197. minX: translators.x.getCanvasVisibleArea().min,
  19198. maxX: translators.x.getCanvasVisibleArea().max,
  19199. minY: translators.y.getCanvasVisibleArea().min,
  19200. maxY: translators.y.getCanvasVisibleArea().max
  19201. };
  19202. if (this._isReduction)
  19203. this._label.updateOptions({options: {
  19204. background: {fill: reductionColor},
  19205. connector: {stroke: reductionColor}
  19206. }});
  19207. coords = this._options.rotated ? {
  19208. x: this.highY,
  19209. y: this.x
  19210. } : {
  19211. x: this.x,
  19212. y: this.highY
  19213. };
  19214. this._label.setCoords(coords, this._getGraphicBbox(), "top", visibleArea);
  19215. this._label.draw(renderer, group, customVisibility)
  19216. }
  19217. },
  19218. getTooltipCoords: function() {
  19219. var that = this;
  19220. if (that.graphic) {
  19221. var x,
  19222. y,
  19223. min,
  19224. max,
  19225. minValue = _min(that.lowY, that.highY),
  19226. maxValue = _max(that.lowY, that.highY),
  19227. visibleAreaX = that.translators.x.getCanvasVisibleArea(),
  19228. visibleAreaY = that.translators.y.getCanvasVisibleArea();
  19229. if (!that._options.rotated) {
  19230. min = _max(visibleAreaY.min, minValue);
  19231. max = _min(visibleAreaY.max, maxValue);
  19232. x = that.x;
  19233. y = min + (max - min) / 2
  19234. }
  19235. else {
  19236. min = _max(visibleAreaX.min, minValue);
  19237. max = _min(visibleAreaX.max, maxValue);
  19238. y = that.x;
  19239. x = min + (max - min) / 2
  19240. }
  19241. return {
  19242. x: x,
  19243. y: y,
  19244. offset: 0
  19245. }
  19246. }
  19247. },
  19248. hasValue: function() {
  19249. return this.highValue !== null && this.lowValue !== null
  19250. },
  19251. _translate: function(translator) {
  19252. var that = this,
  19253. rotated = that._options.rotated,
  19254. argTranslator = rotated ? that.translators.y : that.translators.x,
  19255. valTranslator = rotated ? that.translators.x : that.translators.y,
  19256. centerValue,
  19257. height;
  19258. that.x = argTranslator.translate(that.argument) + (that.xCorrection || 0);
  19259. that.openY = that.openValue !== null ? valTranslator.translate(that.openValue) : null;
  19260. that.highY = valTranslator.translate(that.highValue);
  19261. that.lowY = valTranslator.translate(that.lowValue);
  19262. that.closeY = that.closeValue !== null ? valTranslator.translate(that.closeValue) : null;
  19263. height = _abs(that.lowY - that.highY);
  19264. centerValue = _min(that.lowY, that.highY) + _abs(that.lowY - that.highY) / 2;
  19265. that._calculateVisibility(!rotated ? that.x : centerValue, !rotated ? centerValue : that.x)
  19266. },
  19267. _updateData: function(data) {
  19268. var that = this;
  19269. 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) {
  19270. that.value = that.initialValue = data.reductionValue;
  19271. that.originalValue = data.value;
  19272. that.argument = that.initialArgument = data.argument;
  19273. that.originalArgument = data.argument;
  19274. that.lowValue = data.lowValue;
  19275. that.originalLowValue = data.lowValue;
  19276. that.highValue = data.highValue;
  19277. that.originalHighValue = data.highValue;
  19278. that.openValue = data.openValue;
  19279. that.originalOpenValue = data.openValue;
  19280. that.closeValue = data.closeValue;
  19281. that.originalCloseValue = data.closeValue;
  19282. that.tag = data.tag;
  19283. that.pointClassName = data.pointClassName;
  19284. that._isPositive = data.openValue < data.closeValue;
  19285. that._isReduction = data.isReduction
  19286. }
  19287. },
  19288. _updateMarker: function(animationEnabled, style, group) {
  19289. var style = style || this._getStyle();
  19290. this.graphic.applySettings(_extend({points: this._getPoints()}, style));
  19291. group && this.graphic.append(this._getMarkerGroup(group))
  19292. },
  19293. _updateTracker: function() {
  19294. this.trackerGraphic.applySettings(this._getSettingsForTracker())
  19295. },
  19296. _getLabelFormatObject: function() {
  19297. return {
  19298. openValue: this.openValue,
  19299. highValue: this.highValue,
  19300. lowValue: this.lowValue,
  19301. closeValue: this.closeValue,
  19302. reductionValue: this.initialValue,
  19303. argument: this.initialArgument,
  19304. value: this.initialValue,
  19305. seriesName: this._options.series.name,
  19306. originalOpenValue: this.originalOpenValue,
  19307. originalCloseValue: this.originalCloseValue,
  19308. originalLowValue: this.originalLowValue,
  19309. originalHighValue: this.originalHighValue,
  19310. originalArgument: this.originalArgument,
  19311. point: this
  19312. }
  19313. },
  19314. _getFormatObject: function(tooltip) {
  19315. var highValue = tooltip.formatValue(this.highValue),
  19316. openValue = tooltip.formatValue(this.openValue),
  19317. closeValue = tooltip.formatValue(this.closeValue),
  19318. lowValue = tooltip.formatValue(this.lowValue),
  19319. symbolMethods = points.symbolPoint,
  19320. formatObject = symbolMethods._getFormatObject.call(this, tooltip);
  19321. return _extend({}, formatObject, {
  19322. valueText: "h: " + highValue + (openValue !== "" ? " o: " + openValue : "") + (closeValue !== "" ? " c: " + closeValue : "") + " l: " + lowValue,
  19323. highValueText: highValue,
  19324. openValueText: openValue,
  19325. closeValueText: closeValue,
  19326. lowValueText: lowValue
  19327. })
  19328. }
  19329. })
  19330. })(jQuery, DevExpress);
  19331. /*! Module viz-core, file stockPoint.js */
  19332. (function($, DX) {
  19333. var viz = DevExpress.viz,
  19334. points = viz.core.series.points.mixins,
  19335. _extend = $.extend,
  19336. _isNumeric = $.isNumeric;
  19337. points.stockPoint = _extend({}, points.candlestickPoint, {
  19338. _getPoints: function() {
  19339. var that = this,
  19340. createPoint = that._options.rotated ? function(x, y) {
  19341. return {
  19342. x: y,
  19343. y: x
  19344. }
  19345. } : function(x, y) {
  19346. return {
  19347. x: x,
  19348. y: y
  19349. }
  19350. },
  19351. openYExist = _isNumeric(that.openY),
  19352. closeYExist = _isNumeric(that.closeY),
  19353. x = that.x,
  19354. width = that.width,
  19355. 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)];
  19356. return points
  19357. },
  19358. _drawMarkerInGroup: function(group, attributes, renderer) {
  19359. this.graphic = renderer.createPath(this._getPoints(), attributes).append(group)
  19360. },
  19361. _getMinTrackerWidth: function() {
  19362. return 2 + this._styles.normal.strokeWidth
  19363. }
  19364. })
  19365. })(jQuery, DevExpress);
  19366. /*! Module viz-core, file default.js */
  19367. (function($, DX, undefined) {
  19368. DX.viz.themes = DX.viz.themes || [];
  19369. var fontFamilyDefault = "'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
  19370. fontFamilyLight = "'Segoe UI Light', 'Helvetica Neue Light', 'Segoe UI', 'Helvetica Neue', 'Trebuchet MS', Verdana",
  19371. baseChartTheme = {
  19372. containerBackgroundColor: '#ffffff',
  19373. animation: {
  19374. enabled: true,
  19375. duration: 1000,
  19376. easing: 'easeOutCubic',
  19377. maxPointCountSupported: 300
  19378. },
  19379. commonSeriesSettings: {
  19380. border: {
  19381. visible: false,
  19382. width: 2
  19383. },
  19384. showInLegend: true,
  19385. visible: true,
  19386. hoverMode: 'excludePoints',
  19387. selectionMode: 'includePoints',
  19388. hoverStyle: {
  19389. hatching: {
  19390. direction: 'right',
  19391. width: 2,
  19392. step: 6,
  19393. opacity: 0.75
  19394. },
  19395. border: {
  19396. visible: false,
  19397. width: 3
  19398. }
  19399. },
  19400. selectionStyle: {
  19401. hatching: {
  19402. direction: 'right',
  19403. width: 2,
  19404. step: 6,
  19405. opacity: 0.5
  19406. },
  19407. border: {
  19408. visible: false,
  19409. width: 3
  19410. }
  19411. },
  19412. label: {
  19413. visible: false,
  19414. alignment: 'center',
  19415. rotationAngle: 0,
  19416. horizontalOffset: 0,
  19417. verticalOffset: 0,
  19418. radialOffset: 0,
  19419. format: '',
  19420. argumentFormat: '',
  19421. precision: 0,
  19422. argumentPrecision: 0,
  19423. percentPrecision: 0,
  19424. showForZeroValues: true,
  19425. customizeText: undefined,
  19426. maxLabelCount: undefined,
  19427. position: 'outside',
  19428. font: {color: '#ffffff'},
  19429. border: {
  19430. visible: false,
  19431. width: 1,
  19432. color: '#d3d3d3',
  19433. dashStyle: 'solid'
  19434. },
  19435. connector: {
  19436. visible: false,
  19437. width: 1
  19438. }
  19439. }
  19440. },
  19441. redrawOnResize: true,
  19442. margin: {
  19443. left: 0,
  19444. top: 0,
  19445. right: 0,
  19446. bottom: 0
  19447. },
  19448. seriesSelectionMode: 'single',
  19449. pointSelectionMode: 'single',
  19450. legend: {
  19451. hoverMode: 'includePoints',
  19452. verticalAlignment: 'top',
  19453. horizontalAlignment: 'right',
  19454. position: 'outside',
  19455. visible: true,
  19456. customizeText: undefined,
  19457. itemTextPosition: undefined,
  19458. margin: 10,
  19459. equalColumnWidth: false,
  19460. markerSize: 12,
  19461. backgroundColor: undefined,
  19462. backgroundOpacity: undefined,
  19463. border: {
  19464. visible: false,
  19465. width: 1,
  19466. color: '#d3d3d3',
  19467. cornerRadius: 0,
  19468. dashStyle: 'solid'
  19469. },
  19470. paddingLeftRight: 20,
  19471. paddingTopBottom: 15,
  19472. columnCount: 0,
  19473. rowCount: 0,
  19474. columnItemSpacing: 20,
  19475. rowItemSpacing: 8
  19476. },
  19477. tooltip: {
  19478. enabled: false,
  19479. border: {
  19480. width: 1,
  19481. color: '#d3d3d3',
  19482. dashStyle: 'solid',
  19483. visible: true
  19484. },
  19485. font: {
  19486. family: fontFamilyDefault,
  19487. weight: 400,
  19488. size: 12,
  19489. color: '#232323'
  19490. },
  19491. color: '#ffffff',
  19492. arrowLength: 10,
  19493. paddingLeftRight: 18,
  19494. paddingTopBottom: 15,
  19495. shared: false,
  19496. format: '',
  19497. argumentFormat: '',
  19498. precision: 0,
  19499. argumentPrecision: 0,
  19500. percentPrecision: 0,
  19501. customizeText: undefined,
  19502. customizeTooltip: undefined,
  19503. shadow: {
  19504. opacity: 0.4,
  19505. offsetX: 0,
  19506. offsetY: 4,
  19507. blur: 2,
  19508. color: '#000000'
  19509. }
  19510. },
  19511. size: {
  19512. width: undefined,
  19513. height: undefined
  19514. },
  19515. loadingIndicator: {
  19516. font: {},
  19517. backgroundColor: '#ffffff',
  19518. text: 'Loading...'
  19519. },
  19520. dataPrepareSettings: {
  19521. checkTypeForAllData: false,
  19522. convertToAxisDataType: true,
  19523. sortingMethod: true
  19524. },
  19525. title: {
  19526. font: {
  19527. family: fontFamilyLight,
  19528. weight: 200,
  19529. color: '#232323',
  19530. size: 28
  19531. },
  19532. margin: 10
  19533. },
  19534. adaptiveLayout: {
  19535. width: 80,
  19536. height: 80,
  19537. keepLabels: true
  19538. },
  19539. _rtl: {legend: {itemTextPosition: 'left'}}
  19540. },
  19541. baseDarkChartTheme = {
  19542. containerBackgroundColor: '#2b2b2b',
  19543. commonSeriesSettings: {label: {border: {color: '#494949'}}},
  19544. legend: {border: {color: '#494949'}},
  19545. loadingIndicator: {backgroundColor: '#2b2b2b'},
  19546. title: {font: {color: '#929292'}},
  19547. tooltip: {
  19548. color: '#2b2b2b',
  19549. border: {color: '#494949'},
  19550. font: {color: '#929292'}
  19551. }
  19552. };
  19553. DX.viz.themes.push({
  19554. name: 'desktop',
  19555. font: {
  19556. color: '#767676',
  19557. family: fontFamilyDefault,
  19558. weight: 400,
  19559. size: 12,
  19560. cursor: 'default'
  19561. },
  19562. chart: $.extend(true, {}, baseChartTheme, {
  19563. commonSeriesSettings: {
  19564. type: 'line',
  19565. stack: 'default',
  19566. point: {
  19567. visible: true,
  19568. symbol: 'circle',
  19569. size: 12,
  19570. border: {
  19571. visible: false,
  19572. width: 1
  19573. },
  19574. hoverMode: 'onlyPoint',
  19575. selectionMode: 'onlyPoint',
  19576. hoverStyle: {
  19577. border: {
  19578. visible: true,
  19579. width: 4
  19580. },
  19581. size: 12
  19582. },
  19583. selectionStyle: {
  19584. border: {
  19585. visible: true,
  19586. width: 4
  19587. },
  19588. size: 12
  19589. }
  19590. },
  19591. scatter: {},
  19592. line: {
  19593. width: 2,
  19594. dashStyle: 'solid',
  19595. hoverStyle: {
  19596. width: 3,
  19597. hatching: {direction: 'none'}
  19598. },
  19599. selectionStyle: {width: 3}
  19600. },
  19601. stackedline: {
  19602. width: 2,
  19603. dashStyle: 'solid',
  19604. hoverStyle: {
  19605. width: 3,
  19606. hatching: {direction: 'none'}
  19607. },
  19608. selectionStyle: {width: 3}
  19609. },
  19610. fullstackedline: {
  19611. width: 2,
  19612. dashStyle: 'solid',
  19613. hoverStyle: {
  19614. width: 3,
  19615. hatching: {direction: 'none'}
  19616. },
  19617. selectionStyle: {width: 3}
  19618. },
  19619. stepline: {
  19620. width: 2,
  19621. dashStyle: 'solid',
  19622. hoverStyle: {
  19623. width: 3,
  19624. hatching: {direction: 'none'}
  19625. },
  19626. selectionStyle: {width: 3}
  19627. },
  19628. area: {
  19629. point: {visible: false},
  19630. opacity: 0.5
  19631. },
  19632. stackedarea: {
  19633. point: {visible: false},
  19634. opacity: 0.5
  19635. },
  19636. fullstackedarea: {
  19637. point: {visible: false},
  19638. opacity: 0.5
  19639. },
  19640. steparea: {
  19641. border: {
  19642. visible: true,
  19643. width: 2
  19644. },
  19645. point: {visible: false},
  19646. hoverStyle: {border: {
  19647. visible: true,
  19648. width: 3
  19649. }},
  19650. selectionStyle: {border: {
  19651. visible: true,
  19652. width: 3
  19653. }},
  19654. opacity: 0.5
  19655. },
  19656. spline: {
  19657. width: 2,
  19658. hoverStyle: {
  19659. width: 3,
  19660. hatching: {direction: 'none'}
  19661. },
  19662. selectionStyle: {width: 3}
  19663. },
  19664. splinearea: {
  19665. point: {visible: false},
  19666. opacity: 0.5
  19667. },
  19668. bar: {
  19669. cornerRadius: 0,
  19670. point: {
  19671. hoverStyle: {border: {visible: false}},
  19672. selectionStyle: {border: {visible: false}}
  19673. }
  19674. },
  19675. stackedbar: {
  19676. cornerRadius: 0,
  19677. point: {
  19678. hoverStyle: {border: {visible: false}},
  19679. selectionStyle: {border: {visible: false}}
  19680. },
  19681. label: {position: "inside"}
  19682. },
  19683. fullstackedbar: {
  19684. cornerRadius: 0,
  19685. point: {
  19686. hoverStyle: {border: {visible: false}},
  19687. selectionStyle: {border: {visible: false}}
  19688. },
  19689. label: {position: "inside"}
  19690. },
  19691. rangebar: {
  19692. cornerRadius: 0,
  19693. point: {
  19694. hoverStyle: {border: {visible: false}},
  19695. selectionStyle: {border: {visible: false}}
  19696. }
  19697. },
  19698. rangearea: {
  19699. point: {visible: false},
  19700. opacity: 0.5
  19701. },
  19702. rangesplinearea: {
  19703. point: {visible: false},
  19704. opacity: 0.5
  19705. },
  19706. bubble: {
  19707. opacity: 0.5,
  19708. point: {
  19709. hoverStyle: {border: {visible: false}},
  19710. selectionStyle: {border: {visible: false}}
  19711. }
  19712. },
  19713. candlestick: {
  19714. width: 1,
  19715. innerColor: '#ffffff',
  19716. reduction: {color: '#ff0000'},
  19717. hoverStyle: {
  19718. width: 3,
  19719. hatching: {direction: 'none'}
  19720. },
  19721. selectionStyle: {width: 3},
  19722. point: {border: {visible: true}}
  19723. },
  19724. stock: {
  19725. width: 1,
  19726. reduction: {color: '#ff0000'},
  19727. hoverStyle: {
  19728. width: 3,
  19729. hatching: {direction: 'none'}
  19730. },
  19731. selectionStyle: {width: 3},
  19732. point: {border: {visible: true}}
  19733. }
  19734. },
  19735. crosshair: {
  19736. enabled: false,
  19737. color: '#c6c6c6',
  19738. width: 1,
  19739. dashStyle: 'solid',
  19740. verticalLine: {visible: true},
  19741. horizontalLine: {visible: true}
  19742. },
  19743. commonAxisSettings: {
  19744. tickInterval: undefined,
  19745. setTicksAtUnitBeginning: true,
  19746. valueMarginsEnabled: true,
  19747. placeholderSize: null,
  19748. logarithmBase: 10,
  19749. discreteAxisDivisionMode: 'betweenLabels',
  19750. visible: false,
  19751. color: '#d3d3d3',
  19752. width: 1,
  19753. multipleAxesSpacing: 5,
  19754. label: {
  19755. visible: true,
  19756. overlappingBehavior: {
  19757. mode: 'auto',
  19758. rotationAngle: 90,
  19759. staggeringSpacing: 5
  19760. },
  19761. precision: 0,
  19762. format: '',
  19763. customizeText: undefined,
  19764. indentFromAxis: 10
  19765. },
  19766. grid: {
  19767. visible: false,
  19768. color: '#d3d3d3',
  19769. width: 1
  19770. },
  19771. tick: {
  19772. visible: false,
  19773. color: '#d3d3d3'
  19774. },
  19775. title: {
  19776. font: {size: 16},
  19777. margin: 10
  19778. },
  19779. stripStyle: {
  19780. paddingLeftRight: 10,
  19781. paddingTopBottom: 5
  19782. },
  19783. constantLineStyle: {
  19784. paddingLeftRight: 10,
  19785. paddingTopBottom: 10,
  19786. width: 1,
  19787. color: '#000000',
  19788. dashStyle: 'solid',
  19789. label: {
  19790. visible: true,
  19791. position: 'inside'
  19792. }
  19793. }
  19794. },
  19795. horizontalAxis: {
  19796. isHorizontal: true,
  19797. position: 'bottom',
  19798. axisDivisionFactor: 50,
  19799. label: {alignment: "center"},
  19800. stripStyle: {label: {
  19801. horizontalAlignment: 'center',
  19802. verticalAlignment: 'top'
  19803. }},
  19804. constantLineStyle: {label: {
  19805. horizontalAlignment: 'right',
  19806. verticalAlignment: 'top'
  19807. }},
  19808. constantLines: {}
  19809. },
  19810. verticalAxis: {
  19811. isHorizontal: false,
  19812. position: 'left',
  19813. axisDivisionFactor: 30,
  19814. label: {
  19815. alignment: 'right',
  19816. overlappingBehavior: {mode: 'enlargeTickInterval'}
  19817. },
  19818. stripStyle: {label: {
  19819. horizontalAlignment: 'left',
  19820. verticalAlignment: 'center'
  19821. }},
  19822. constantLineStyle: {label: {
  19823. horizontalAlignment: 'left',
  19824. verticalAlignment: 'top'
  19825. }},
  19826. constantLines: {}
  19827. },
  19828. argumentAxis: {},
  19829. valueAxis: {grid: {visible: true}},
  19830. commonPaneSettings: {
  19831. backgroundColor: 'none',
  19832. border: {
  19833. color: '#d3d3d3',
  19834. width: 1,
  19835. visible: false,
  19836. top: true,
  19837. bottom: true,
  19838. left: true,
  19839. right: true,
  19840. dashStyle: 'solid'
  19841. }
  19842. },
  19843. useAggregation: false,
  19844. adjustOnZoom: true,
  19845. rotated: false,
  19846. synchronizeMultiAxes: true,
  19847. equalBarWidth: true,
  19848. minBubbleSize: 12,
  19849. maxBubbleSize: 0.2
  19850. }),
  19851. pie: $.extend(true, {}, baseChartTheme, {
  19852. commonSeriesSettings: {
  19853. type: 'pie',
  19854. pie: {
  19855. border: {
  19856. visible: false,
  19857. width: 2,
  19858. color: '#ffffff'
  19859. },
  19860. hoverStyle: {
  19861. hatching: {
  19862. direction: 'right',
  19863. width: 4,
  19864. step: 10,
  19865. opacity: 0.75
  19866. },
  19867. border: {
  19868. visible: false,
  19869. width: 2
  19870. }
  19871. },
  19872. selectionStyle: {
  19873. hatching: {
  19874. direction: 'right',
  19875. width: 4,
  19876. step: 10,
  19877. opacity: 0.5
  19878. },
  19879. border: {
  19880. visible: false,
  19881. width: 2
  19882. }
  19883. }
  19884. },
  19885. doughnut: {
  19886. innerRadius: 0.5,
  19887. border: {
  19888. visible: false,
  19889. width: 2,
  19890. color: '#ffffff'
  19891. },
  19892. hoverStyle: {
  19893. hatching: {
  19894. direction: 'right',
  19895. width: 4,
  19896. step: 10,
  19897. opacity: 0.75
  19898. },
  19899. border: {
  19900. visible: false,
  19901. width: 2
  19902. }
  19903. },
  19904. selectionStyle: {
  19905. hatching: {
  19906. direction: 'right',
  19907. width: 4,
  19908. step: 10,
  19909. opacity: 0.5
  19910. },
  19911. border: {
  19912. visible: false,
  19913. width: 2
  19914. }
  19915. }
  19916. },
  19917. donut: {
  19918. innerRadius: 0.5,
  19919. border: {
  19920. visible: false,
  19921. width: 2,
  19922. color: '#ffffff'
  19923. },
  19924. hoverStyle: {
  19925. hatching: {
  19926. direction: 'right',
  19927. width: 4,
  19928. step: 10,
  19929. opacity: 0.75
  19930. },
  19931. border: {
  19932. visible: false,
  19933. width: 2
  19934. }
  19935. },
  19936. selectionStyle: {
  19937. hatching: {
  19938. direction: 'right',
  19939. width: 4,
  19940. step: 10,
  19941. opacity: 0.5
  19942. },
  19943. border: {
  19944. visible: false,
  19945. width: 2
  19946. }
  19947. }
  19948. }
  19949. },
  19950. legend: {hoverMode: 'markPoint'},
  19951. adaptiveLayout: {keepLabels: false}
  19952. }),
  19953. pieIE8: {commonSeriesSettings: {
  19954. pie: {
  19955. hoverStyle: {border: {
  19956. visible: true,
  19957. color: '#ffffff'
  19958. }},
  19959. selectionStyle: {border: {
  19960. visible: true,
  19961. color: '#ffffff'
  19962. }}
  19963. },
  19964. donut: {
  19965. hoverStyle: {border: {
  19966. visible: true,
  19967. color: '#ffffff'
  19968. }},
  19969. selectionStyle: {border: {
  19970. visible: true,
  19971. color: '#ffffff'
  19972. }}
  19973. },
  19974. doughnut: {
  19975. hoverStyle: {border: {
  19976. visible: true,
  19977. color: '#ffffff'
  19978. }},
  19979. selectionStyle: {border: {
  19980. visible: true,
  19981. color: '#ffffff'
  19982. }}
  19983. }
  19984. }},
  19985. gauge: {
  19986. containerBackgroundColor: '#ffffff',
  19987. scale: {
  19988. majorTick: {
  19989. visible: true,
  19990. length: 5,
  19991. width: 2,
  19992. showCalculatedTicks: true,
  19993. useTicksAutoArrangement: true,
  19994. color: '#ffffff'
  19995. },
  19996. minorTick: {
  19997. visible: false,
  19998. length: 3,
  19999. width: 1,
  20000. showCalculatedTicks: true,
  20001. color: '#ffffff'
  20002. },
  20003. label: {
  20004. visible: true,
  20005. font: {}
  20006. }
  20007. },
  20008. rangeContainer: {
  20009. offset: 0,
  20010. width: 5,
  20011. backgroundColor: '#808080'
  20012. },
  20013. valueIndicator: {
  20014. _default: {color: '#c2c2c2'},
  20015. rangebar: {
  20016. space: 2,
  20017. size: 10,
  20018. color: '#cbc5cf',
  20019. backgroundColor: 'none',
  20020. text: {
  20021. indent: 0,
  20022. font: {
  20023. size: 14,
  20024. color: null
  20025. }
  20026. }
  20027. },
  20028. twocolorneedle: {secondColor: '#e18e92'},
  20029. twocolorrectangle: {secondColor: '#e18e92'}
  20030. },
  20031. subvalueIndicator: {
  20032. _default: {color: '#8798a5'},
  20033. trianglemarker: {
  20034. space: 2,
  20035. length: 14,
  20036. width: 13,
  20037. color: '#8798a5'
  20038. },
  20039. triangle: {
  20040. space: 2,
  20041. length: 14,
  20042. width: 13,
  20043. color: '#8798a5'
  20044. },
  20045. textcloud: {
  20046. arrowLength: 5,
  20047. horizontalOffset: 6,
  20048. verticalOffset: 3,
  20049. color: '#679ec5',
  20050. text: {font: {
  20051. color: '#ffffff',
  20052. size: 18
  20053. }}
  20054. }
  20055. },
  20056. valueIndicators: {
  20057. _default: {color: '#c2c2c2'},
  20058. rangebar: {
  20059. space: 2,
  20060. size: 10,
  20061. color: '#cbc5cf',
  20062. backgroundColor: 'none',
  20063. text: {
  20064. indent: 0,
  20065. font: {
  20066. size: 14,
  20067. color: null
  20068. }
  20069. }
  20070. },
  20071. twocolorneedle: {secondColor: '#e18e92'},
  20072. trianglemarker: {
  20073. space: 2,
  20074. length: 14,
  20075. width: 13,
  20076. color: '#8798a5'
  20077. },
  20078. textcloud: {
  20079. arrowLength: 5,
  20080. horizontalOffset: 6,
  20081. verticalOffset: 3,
  20082. color: '#679ec5',
  20083. text: {font: {
  20084. color: '#ffffff',
  20085. size: 18
  20086. }}
  20087. }
  20088. },
  20089. title: {
  20090. layout: {
  20091. horizontalAlignment: 'center',
  20092. verticalAlignment: 'top',
  20093. overlay: 0
  20094. },
  20095. font: {
  20096. size: 16,
  20097. color: '#232323',
  20098. family: fontFamilyDefault,
  20099. weight: 400
  20100. }
  20101. },
  20102. subtitle: {font: {
  20103. size: 14,
  20104. color: '#232323',
  20105. family: fontFamilyDefault,
  20106. weight: 400
  20107. }},
  20108. indicator: {
  20109. hasPositiveMeaning: true,
  20110. layout: {
  20111. horizontalAlignment: 'center',
  20112. verticalAlignment: 'bottom',
  20113. overlay: 0
  20114. },
  20115. text: {font: {size: 18}}
  20116. },
  20117. tooltip: {
  20118. arrowLength: 10,
  20119. paddingLeftRight: 18,
  20120. paddingTopBottom: 15,
  20121. enabled: false,
  20122. border: {
  20123. width: 1,
  20124. color: '#d3d3d3',
  20125. dashStyle: 'solid',
  20126. visible: true
  20127. },
  20128. color: '#ffffff',
  20129. font: {
  20130. color: '#232323',
  20131. size: 12,
  20132. family: fontFamilyDefault,
  20133. weight: 400
  20134. },
  20135. shadow: {
  20136. opacity: 0.4,
  20137. offsetX: 0,
  20138. offsetY: 4,
  20139. blur: 2,
  20140. color: '#000000'
  20141. }
  20142. },
  20143. loadingIndicator: {
  20144. font: {},
  20145. backgroundColor: '#ffffff',
  20146. text: 'Loading...'
  20147. },
  20148. _circular: {
  20149. scale: {
  20150. orientation: 'outside',
  20151. label: {indentFromTick: 10}
  20152. },
  20153. rangeContainer: {orientation: 'outside'},
  20154. valueIndicator: {
  20155. type: 'rectangleneedle',
  20156. _default: {
  20157. offset: 20,
  20158. indentFromCenter: 0,
  20159. width: 2,
  20160. spindleSize: 14,
  20161. spindleGapSize: 10
  20162. },
  20163. triangleneedle: {width: 4},
  20164. triangle: {width: 4},
  20165. twocolorneedle: {
  20166. space: 2,
  20167. secondFraction: 0.4
  20168. },
  20169. twocolorrectangle: {
  20170. space: 2,
  20171. secondFraction: 0.4
  20172. },
  20173. rangebar: {offset: 30}
  20174. },
  20175. subvalueIndicator: {
  20176. type: 'trianglemarker',
  20177. trianglemarker: {offset: 6},
  20178. triangle: {offset: 6},
  20179. textcloud: {offset: -6}
  20180. },
  20181. valueIndicators: {
  20182. _type: 'rectangleneedle',
  20183. _default: {
  20184. offset: 20,
  20185. indentFromCenter: 0,
  20186. width: 2,
  20187. spindleSize: 14,
  20188. spindleGapSize: 10
  20189. },
  20190. triangleneedle: {width: 4},
  20191. twocolorneedle: {
  20192. space: 2,
  20193. secondFraction: 0.4
  20194. },
  20195. rangebar: {offset: 30},
  20196. trianglemarker: {offset: 6},
  20197. textcloud: {offset: -6}
  20198. }
  20199. },
  20200. _linear: {
  20201. scale: {
  20202. horizontalOrientation: 'right',
  20203. verticalOrientation: 'bottom',
  20204. label: {indentFromTick: -10}
  20205. },
  20206. rangeContainer: {
  20207. horizontalOrientation: 'right',
  20208. verticalOrientation: 'bottom'
  20209. },
  20210. valueIndicator: {
  20211. type: 'rangebar',
  20212. _default: {
  20213. offset: 2.5,
  20214. length: 15,
  20215. width: 15
  20216. },
  20217. rectangle: {width: 10},
  20218. rangebar: {
  20219. offset: 10,
  20220. horizontalOrientation: 'right',
  20221. verticalOrientation: 'bottom'
  20222. }
  20223. },
  20224. subvalueIndicator: {
  20225. type: 'trianglemarker',
  20226. _default: {
  20227. offset: -1,
  20228. horizontalOrientation: 'left',
  20229. verticalOrientation: 'top'
  20230. }
  20231. },
  20232. valueIndicators: {
  20233. _type: 'rectangle',
  20234. _default: {
  20235. offset: 2.5,
  20236. length: 15,
  20237. width: 15
  20238. },
  20239. rectangle: {width: 10},
  20240. rangebar: {
  20241. offset: 10,
  20242. horizontalOrientation: 'right',
  20243. verticalOrientation: 'bottom'
  20244. },
  20245. trianglemarker: {
  20246. offset: -1,
  20247. horizontalOrientation: 'left',
  20248. verticalOrientation: 'top'
  20249. },
  20250. textcloud: {
  20251. offset: -1,
  20252. horizontalOrientation: 'left',
  20253. verticalOrientation: 'top'
  20254. }
  20255. }
  20256. }
  20257. },
  20258. barGauge: {
  20259. backgroundColor: '#e0e0e0',
  20260. relativeInnerRadius: 0.3,
  20261. barSpacing: 4,
  20262. label: {
  20263. indent: 20,
  20264. connectorWidth: 2,
  20265. font: {size: 16}
  20266. },
  20267. title: {
  20268. layout: {
  20269. horizontalAlignment: 'center',
  20270. verticalAlignment: 'top',
  20271. overlay: 0
  20272. },
  20273. font: {
  20274. size: 16,
  20275. color: '#232323',
  20276. family: fontFamilyDefault,
  20277. weight: 400
  20278. }
  20279. },
  20280. subtitle: {font: {
  20281. size: 14,
  20282. color: '#232323',
  20283. family: fontFamilyDefault,
  20284. weight: 400
  20285. }},
  20286. indicator: {
  20287. hasPositiveMeaning: true,
  20288. layout: {
  20289. horizontalAlignment: 'center',
  20290. verticalAlignment: 'bottom',
  20291. overlay: 0
  20292. },
  20293. text: {font: {size: 18}}
  20294. },
  20295. tooltip: {
  20296. arrowLength: 10,
  20297. paddingLeftRight: 18,
  20298. paddingTopBottom: 15,
  20299. enabled: false,
  20300. border: {
  20301. width: 1,
  20302. color: '#d3d3d3',
  20303. dashStyle: 'solid',
  20304. visible: true
  20305. },
  20306. color: '#ffffff',
  20307. font: {
  20308. size: 12,
  20309. color: '#232323',
  20310. family: fontFamilyDefault,
  20311. weight: 400
  20312. },
  20313. shadow: {
  20314. opacity: 0.4,
  20315. offsetX: 0,
  20316. offsetY: 4,
  20317. blur: 2,
  20318. color: '#000000'
  20319. }
  20320. },
  20321. loadingIndicator: {
  20322. font: {},
  20323. backgroundColor: '#ffffff',
  20324. text: 'Loading...'
  20325. }
  20326. },
  20327. rangeSelector: {
  20328. containerBackgroundColor: '#ffffff',
  20329. scale: {
  20330. label: {
  20331. topIndent: 7,
  20332. font: {size: 11}
  20333. },
  20334. tick: {
  20335. width: 1,
  20336. color: '#000000',
  20337. opacity: 0.1
  20338. },
  20339. marker: {
  20340. separatorHeight: 33,
  20341. topIndent: 10,
  20342. textLeftIndent: 7,
  20343. textTopIndent: 11
  20344. }
  20345. },
  20346. loadingIndicator: {
  20347. font: {},
  20348. backgroundColor: '#ffffff',
  20349. text: 'Loading...'
  20350. },
  20351. sliderMarker: {
  20352. padding: 7,
  20353. pointerSize: 6,
  20354. color: '#9b9b9b',
  20355. invalidRangeColor: '#ff0000',
  20356. font: {
  20357. color: '#ffffff',
  20358. size: 11
  20359. }
  20360. },
  20361. sliderHandle: {
  20362. width: 1,
  20363. color: '#000000',
  20364. opacity: 0.2
  20365. },
  20366. shutter: {
  20367. color: undefined,
  20368. opacity: 0.75
  20369. },
  20370. background: {color: "#c0bae1"},
  20371. chart: {
  20372. containerBackgroundColor: undefined,
  20373. commonSeriesSettings: {
  20374. label: baseChartTheme.commonSeriesSettings.label,
  20375. border: {
  20376. visible: false,
  20377. width: 1
  20378. },
  20379. visible: true,
  20380. type: 'area',
  20381. hoverMode: 'none',
  20382. hoverStyle: {border: {}},
  20383. selectionStyle: {border: {}},
  20384. point: {
  20385. visible: false,
  20386. symbol: 'circle',
  20387. border: {
  20388. visible: false,
  20389. width: 1
  20390. },
  20391. size: 12,
  20392. hoverStyle: {border: {}},
  20393. selectionStyle: {border: {}}
  20394. },
  20395. line: {width: 2},
  20396. stepline: {width: 2},
  20397. scatter: {point: {visible: true}},
  20398. stackedline: {width: 2},
  20399. fullstackedline: {width: 2},
  20400. area: {opacity: 0.5},
  20401. stackedarea: {opacity: 0.5},
  20402. fullstackedarea: {opacity: 0.5},
  20403. spline: {width: 2},
  20404. splinearea: {opacity: 0.5},
  20405. steparea: {
  20406. border: {
  20407. visible: true,
  20408. width: 2
  20409. },
  20410. opacity: 0.5
  20411. },
  20412. bubble: {
  20413. opacity: 0.5,
  20414. point: {visible: true}
  20415. },
  20416. bar: {
  20417. cornerRadius: 0,
  20418. point: {visible: true}
  20419. },
  20420. stackedbar: {
  20421. cornerRadius: 0,
  20422. point: {visible: true}
  20423. },
  20424. fullstackedbar: {
  20425. cornerRadius: 0,
  20426. point: {visible: true}
  20427. },
  20428. rangebar: {
  20429. cornerRadius: 0,
  20430. point: {visible: true}
  20431. },
  20432. rangearea: {opacity: 0.5},
  20433. rangesplinearea: {opacity: 0.5},
  20434. candlestick: {
  20435. width: 1,
  20436. innerColor: '#ffffff',
  20437. reduction: {color: '#ff0000'}
  20438. },
  20439. stock: {
  20440. width: 1,
  20441. reduction: {color: '#ff0000'}
  20442. }
  20443. },
  20444. dataPrepareSettings: {
  20445. checkTypeForAllData: false,
  20446. convertToAxisDataType: true,
  20447. sortingMethod: true
  20448. },
  20449. useAggregation: false,
  20450. equalBarWidth: true,
  20451. minBubbleSize: 12,
  20452. maxBubbleSize: 0.2,
  20453. topIndent: 0.1,
  20454. bottomIndent: 0,
  20455. valueAxis: {
  20456. min: undefined,
  20457. max: undefined,
  20458. inverted: false,
  20459. logarithmBase: 10
  20460. }
  20461. }
  20462. },
  20463. map: {
  20464. background: {
  20465. borderWidth: 1,
  20466. borderColor: '#cacaca',
  20467. color: '#ffffff'
  20468. },
  20469. area: {
  20470. borderWidth: 1,
  20471. borderColor: '#ffffff',
  20472. color: '#d2d2d2',
  20473. hoveredBorderColor: '#303030',
  20474. selectedBorderWidth: 2,
  20475. selectedBorderColor: '#303030'
  20476. },
  20477. marker: {
  20478. font: {
  20479. color: '#2b2b2b',
  20480. size: 12
  20481. },
  20482. _dot: {
  20483. borderWidth: 2,
  20484. borderColor: '#ffffff',
  20485. color: '#ba4d51',
  20486. size: 8,
  20487. selectedStep: 2,
  20488. backStep: 18,
  20489. backColor: '#ffffff',
  20490. backOpacity: 0.32,
  20491. shadow: true
  20492. },
  20493. _bubble: {
  20494. minSize: 20,
  20495. maxSize: 50,
  20496. color: '#ba4d51',
  20497. hoveredBorderWidth: 1,
  20498. hoveredBorderColor: '#303030',
  20499. selectedBorderWidth: 2,
  20500. selectedBorderColor: '#303030'
  20501. },
  20502. _pie: {
  20503. size: 50,
  20504. hoveredBorderWidth: 1,
  20505. hoveredBorderColor: '#303030',
  20506. selectedBorderWidth: 2,
  20507. selectedBorderColor: '#303030'
  20508. },
  20509. _image: {size: 20}
  20510. },
  20511. controlBar: {
  20512. borderColor: '#5d5d5d',
  20513. borderWidth: 3,
  20514. color: '#ffffff'
  20515. },
  20516. tooltip: {
  20517. borderWidth: 1,
  20518. borderColor: '#d7d7d7',
  20519. arrowLength: 10,
  20520. paddingLeftRight: 18,
  20521. paddingTopBottom: 15,
  20522. border: {
  20523. width: 1,
  20524. color: '#d3d3d3',
  20525. dashStyle: 'solid',
  20526. visible: true
  20527. },
  20528. color: '#ffffff',
  20529. font: {
  20530. color: '#232323',
  20531. size: 12,
  20532. family: fontFamilyDefault,
  20533. weight: 400
  20534. },
  20535. shadow: {
  20536. opacity: 0.4,
  20537. offsetX: 0,
  20538. offsetY: 4,
  20539. blur: 2,
  20540. color: '#000000'
  20541. }
  20542. },
  20543. legend: {
  20544. verticalAlignment: 'bottom',
  20545. horizontalAlignment: 'right',
  20546. position: 'inside',
  20547. visible: true,
  20548. margin: 10,
  20549. equalColumnWidth: false,
  20550. markerSize: 12,
  20551. backgroundColor: '#ffffff',
  20552. backgroundOpacity: 0.65,
  20553. border: {
  20554. visible: true,
  20555. width: 1,
  20556. color: '#cacaca',
  20557. cornerRadius: 0,
  20558. dashStyle: 'solid'
  20559. },
  20560. paddingLeftRight: 16,
  20561. paddingTopBottom: 12,
  20562. columnItemSpacing: 20,
  20563. rowItemSpacing: 8,
  20564. font: {
  20565. color: '#2b2b2b',
  20566. size: 12
  20567. }
  20568. },
  20569. loadingIndicator: {
  20570. backgroundColor: '#ffffff',
  20571. font: {},
  20572. text: 'Loading...'
  20573. },
  20574. _rtl: {legend: {itemTextPosition: 'left'}}
  20575. },
  20576. sparkline: {
  20577. lineColor: '#666666',
  20578. lineWidth: 2,
  20579. areaOpacity: 0.2,
  20580. minColor: '#e8c267',
  20581. maxColor: '#e55253',
  20582. barPositiveColor: '#a9a9a9',
  20583. barNegativeColor: '#d7d7d7',
  20584. winColor: '#a9a9a9',
  20585. lossColor: '#d7d7d7',
  20586. firstLastColor: '#666666',
  20587. pointSymbol: 'circle',
  20588. pointColor: '#ffffff',
  20589. pointSize: 4,
  20590. tooltip: {
  20591. enabled: true,
  20592. allowContainerResizing: true,
  20593. verticalAlignment: 'top',
  20594. horizontalAlignment: 'center',
  20595. format: '',
  20596. paddingLeftRight: 18,
  20597. paddingTopBottom: 15,
  20598. arrowLength: 10,
  20599. precision: 0,
  20600. color: '#ffffff',
  20601. border: {
  20602. width: 1,
  20603. color: '#d3d3d3',
  20604. dashStyle: 'solid',
  20605. visible: true
  20606. },
  20607. font: {
  20608. color: '#232323',
  20609. family: fontFamilyDefault,
  20610. size: 12,
  20611. weight: 400
  20612. },
  20613. shadow: {
  20614. opacity: 0.4,
  20615. offsetX: 0,
  20616. offsetY: 4,
  20617. blur: 2,
  20618. color: '#000000'
  20619. }
  20620. }
  20621. },
  20622. bullet: {
  20623. color: '#e8c267',
  20624. targetColor: '#666666',
  20625. targetWidth: 4,
  20626. showTarget: true,
  20627. showZeroLevel: true,
  20628. tooltip: {
  20629. enabled: true,
  20630. allowContainerResizing: true,
  20631. verticalAlignment: 'top',
  20632. horizontalAlignment: 'center',
  20633. format: '',
  20634. precision: 0,
  20635. paddingLeftRight: 18,
  20636. paddingTopBottom: 15,
  20637. arrowLength: 10,
  20638. color: '#ffffff',
  20639. border: {
  20640. width: 1,
  20641. color: '#d3d3d3',
  20642. dashStyle: 'solid',
  20643. visible: true
  20644. },
  20645. font: {
  20646. color: '#232323',
  20647. family: fontFamilyDefault,
  20648. size: 12,
  20649. weight: 400
  20650. },
  20651. shadow: {
  20652. opacity: 0.4,
  20653. offsetX: 0,
  20654. offsetY: 4,
  20655. blur: 2,
  20656. color: '#000000'
  20657. }
  20658. }
  20659. }
  20660. });
  20661. DX.viz.core.registerTheme({
  20662. name: 'desktop-dark',
  20663. font: {color: '#808080'},
  20664. chart: $.extend(true, {}, baseDarkChartTheme, {
  20665. commonSeriesSettings: {candlestick: {innerColor: '#2b2b2b'}},
  20666. crosshair: {color: '#515151'},
  20667. commonAxisSettings: {
  20668. color: '#494949',
  20669. grid: {color: '#494949'},
  20670. tick: {color: '#494949'},
  20671. constantLineStyle: {color: '#ffffff'}
  20672. },
  20673. commonPaneSettings: {border: {color: '#494949'}}
  20674. }),
  20675. pie: $.extend(true, {}, baseDarkChartTheme),
  20676. pieIE8: {commonSeriesSettings: {
  20677. pie: {
  20678. hoverStyle: {border: {color: '#2b2b2b'}},
  20679. selectionStyle: {border: {color: '#2b2b2b'}}
  20680. },
  20681. donut: {
  20682. hoverStyle: {border: {color: '#2b2b2b'}},
  20683. selectionStyle: {border: {color: '#2b2b2b'}}
  20684. },
  20685. doughnut: {
  20686. hoverStyle: {border: {color: '#2b2b2b'}},
  20687. selectionStyle: {border: {color: '#2b2b2b'}}
  20688. }
  20689. }},
  20690. gauge: {
  20691. containerBackgroundColor: '#2b2b2b',
  20692. scale: {
  20693. majorTick: {color: '#303030'},
  20694. minorTick: {color: '#303030'}
  20695. },
  20696. rangeContainer: {backgroundColor: '#b5b5b5'},
  20697. valueIndicator: {
  20698. _default: {color: '#b5b5b5'},
  20699. rangebar: {color: '#84788b'},
  20700. twocolorneedle: {secondColor: '#ba544d'},
  20701. twocolorrectangle: {secondColor: '#ba544d'}
  20702. },
  20703. subvalueIndicator: {_default: {color: '#b7918f'}},
  20704. valueIndicators: {
  20705. _default: {color: '#b5b5b5'},
  20706. rangebar: {color: '#84788b'},
  20707. twocolorneedle: {secondColor: '#ba544d'},
  20708. trianglemarker: {color: '#b7918f'},
  20709. textcloud: {color: '#ba544d'}
  20710. },
  20711. title: {font: {color: '#929292'}},
  20712. subtitle: {font: {color: '#929292'}},
  20713. loadingIndicator: {backgroundColor: '#2b2b2b'},
  20714. tooltip: {
  20715. color: '#2b2b2b',
  20716. border: {color: '#494949'},
  20717. font: {color: '#929292'}
  20718. }
  20719. },
  20720. barGauge: {
  20721. title: {font: {color: '#929292'}},
  20722. subtitle: {font: {color: '#929292'}},
  20723. tooltip: {
  20724. color: '#2b2b2b',
  20725. border: {color: '#494949'},
  20726. font: {color: '#929292'}
  20727. },
  20728. loadingIndicator: {backgroundColor: '#2b2b2b'}
  20729. },
  20730. rangeSelector: {
  20731. containerBackgroundColor: '#2b2b2b',
  20732. scale: {tick: {
  20733. color: '#ffffff',
  20734. opacity: 0.05
  20735. }},
  20736. loadingIndicator: {backgroundColor: '#2b2b2b'},
  20737. sliderMarker: {
  20738. color: '#b5b5b5',
  20739. font: {color: '#303030'}
  20740. },
  20741. sliderHandle: {
  20742. color: '#ffffff',
  20743. opacity: 0.35
  20744. },
  20745. shutter: {
  20746. color: '#2b2b2b',
  20747. opacity: 0.9
  20748. }
  20749. },
  20750. map: {
  20751. background: {
  20752. borderColor: '#3f3f3f',
  20753. color: '#303030'
  20754. },
  20755. area: {
  20756. borderColor: '#303030',
  20757. color: '#686868',
  20758. hoveredBorderColor: '#ffffff',
  20759. selectedBorderColor: '#ffffff'
  20760. },
  20761. marker: {
  20762. font: {color: '#ffffff'},
  20763. _bubble: {
  20764. hoveredBorderColor: '#ffffff',
  20765. selectedBorderColor: '#ffffff'
  20766. },
  20767. _pie: {
  20768. hoveredBorderColor: '#ffffff',
  20769. selectedBorderColor: '#ffffff'
  20770. }
  20771. },
  20772. controlBar: {
  20773. borderColor: '#c7c7c7',
  20774. color: '#303030'
  20775. },
  20776. legend: {
  20777. border: {color: '#3f3f3f'},
  20778. backgroundColor: '#303030',
  20779. font: {color: '#ffffff'}
  20780. },
  20781. tooltip: {
  20782. color: '#2b2b2b',
  20783. border: {color: '#494949'},
  20784. font: {color: '#929292'}
  20785. },
  20786. loadingIndicator: {backgroundColor: '#2b2b2b'}
  20787. },
  20788. sparkline: {
  20789. lineColor: '#c7c7c7',
  20790. firstLastColor: '#c7c7c7',
  20791. barPositiveColor: '#b8b8b8',
  20792. barNegativeColor: '#8e8e8e',
  20793. winColor: '#b8b8b8',
  20794. lossColor: '#8e8e8e',
  20795. pointColor: '#303030',
  20796. tooltip: {
  20797. color: '#2b2b2b',
  20798. border: {color: '#494949'},
  20799. font: {color: '#929292'}
  20800. }
  20801. },
  20802. bullet: {
  20803. targetColor: '#8e8e8e',
  20804. tooltip: {
  20805. color: '#2b2b2b',
  20806. border: {color: '#494949'},
  20807. font: {color: '#929292'}
  20808. }
  20809. }
  20810. }, 'desktop')
  20811. })(jQuery, DevExpress);
  20812. /*! Module viz-core, file android.js */
  20813. (function($, DX, undefined) {
  20814. var baseChartTheme = {
  20815. containerBackgroundColor: '#050506',
  20816. title: {font: {color: '#ffffff'}},
  20817. commonSeriesSettings: {label: {border: {color: '#4c4c4c'}}},
  20818. legend: {
  20819. font: {
  20820. color: '#ffffff',
  20821. size: 11
  20822. },
  20823. border: {color: '#4c4c4c'}
  20824. },
  20825. loadingIndicator: {backgroundColor: '#050506'},
  20826. tooltip: {
  20827. color: '#050506',
  20828. border: {color: '#4c4c4c'},
  20829. font: {color: '#ffffff'}
  20830. }
  20831. },
  20832. baseLightChartTheme = {
  20833. containerBackgroundColor: '#e8e8e8',
  20834. title: {font: {color: '#808080'}},
  20835. legend: {font: {
  20836. color: '#000000',
  20837. size: 11
  20838. }},
  20839. loadingIndicator: {backgroundColor: '#e8e8e8'},
  20840. tooltip: {
  20841. color: '#e8e8e8',
  20842. font: {color: '#808080'}
  20843. }
  20844. };
  20845. DX.viz.core.registerTheme({
  20846. name: 'android',
  20847. chart: $.extend(true, {}, baseChartTheme, {
  20848. commonSeriesSettings: {candlestick: {innerColor: '#050506'}},
  20849. commonAxisSettings: {
  20850. color: '#4c4c4c',
  20851. grid: {color: '#4c4c4c'},
  20852. tick: {color: '#4c4c4c'},
  20853. title: {font: {color: '#545455'}},
  20854. label: {font: {
  20855. color: '#ffffff',
  20856. size: 11
  20857. }}
  20858. },
  20859. commonPaneSettings: {border: {color: '#4c4c4c'}}
  20860. }),
  20861. pie: $.extend(true, {}, baseChartTheme),
  20862. pieIE8: {commonSeriesSettings: {
  20863. pie: {
  20864. hoverStyle: {border: {color: '#050506'}},
  20865. selectionStyle: {border: {color: '#050506'}}
  20866. },
  20867. donut: {
  20868. hoverStyle: {border: {color: '#050506'}},
  20869. selectionStyle: {border: {color: '#050506'}}
  20870. },
  20871. doughnut: {
  20872. hoverStyle: {border: {color: '#050506'}},
  20873. selectionStyle: {border: {color: '#050506'}}
  20874. }
  20875. }},
  20876. gauge: {
  20877. containerBackgroundColor: '#050506',
  20878. title: {font: {color: '#ffffff'}},
  20879. subtitle: {font: {color: '#ffffff'}},
  20880. loadingIndicator: {backgroundColor: '#050506'},
  20881. tooltip: {
  20882. color: '#050506',
  20883. border: {color: '#4c4c4c'},
  20884. font: {color: '#ffffff'}
  20885. }
  20886. },
  20887. barGauge: {
  20888. title: {font: {color: '#ffffff'}},
  20889. subtitle: {font: {color: '#ffffff'}},
  20890. tooltip: {
  20891. color: '#050506',
  20892. border: {color: '#4c4c4c'},
  20893. font: {color: '#ffffff'}
  20894. },
  20895. loadingIndicator: {backgroundColor: '#050506'}
  20896. },
  20897. rangeSelector: {
  20898. containerBackgroundColor: '#050506',
  20899. loadingIndicator: {backgroundColor: '#050506'}
  20900. },
  20901. map: {
  20902. loadingIndicator: {backgroundColor: '#050506'},
  20903. tooltip: {
  20904. color: '#050506',
  20905. border: {color: '#4c4c4c'},
  20906. font: {color: '#ffffff'}
  20907. }
  20908. },
  20909. sparkline: {tooltip: {
  20910. color: '#050506',
  20911. border: {color: '#4c4c4c'},
  20912. font: {color: '#ffffff'}
  20913. }},
  20914. bullet: {tooltip: {
  20915. color: '#050506',
  20916. border: {color: '#4c4c4c'},
  20917. font: {color: '#ffffff'}
  20918. }}
  20919. }, 'desktop-dark');
  20920. DX.viz.core.registerTheme({
  20921. name: 'android-holo-light',
  20922. chart: $.extend(true, {}, baseLightChartTheme, {
  20923. commonSeriesSettings: {candlestick: {innerColor: '#e8e8e8'}},
  20924. commonAxisSettings: {
  20925. title: {font: {color: '#939393'}},
  20926. label: {font: {
  20927. color: '#404040',
  20928. size: 11
  20929. }}
  20930. }
  20931. }),
  20932. pie: $.extend(true, {}, baseLightChartTheme),
  20933. pieIE8: {commonSeriesSettings: {
  20934. pie: {
  20935. hoverStyle: {border: {color: '#e8e8e8'}},
  20936. selectionStyle: {border: {color: '#e8e8e8'}}
  20937. },
  20938. donut: {
  20939. hoverStyle: {border: {color: '#e8e8e8'}},
  20940. selectionStyle: {border: {color: '#e8e8e8'}}
  20941. },
  20942. doughnut: {
  20943. hoverStyle: {border: {color: '#e8e8e8'}},
  20944. selectionStyle: {border: {color: '#e8e8e8'}}
  20945. }
  20946. }},
  20947. gauge: {
  20948. containerBackgroundColor: '#e8e8e8',
  20949. title: {font: {color: '#808080'}},
  20950. subtitle: {font: {color: '#808080'}},
  20951. loadingIndicator: {backgroundColor: '#e8e8e8'},
  20952. tooltip: {
  20953. color: '#e8e8e8',
  20954. font: {color: '#808080'}
  20955. }
  20956. },
  20957. barGauge: {
  20958. title: {font: {color: '#808080'}},
  20959. subtitle: {font: {color: '#808080'}},
  20960. tooltip: {
  20961. color: '#e8e8e8',
  20962. font: {color: '#808080'}
  20963. },
  20964. loadingIndicator: {backgroundColor: '#e8e8e8'}
  20965. },
  20966. rangeSelector: {
  20967. containerBackgroundColor: '#e8e8e8',
  20968. loadingIndicator: {backgroundColor: '#e8e8e8'}
  20969. },
  20970. map: {
  20971. loadingIndicator: {backgroundColor: '#e8e8e8'},
  20972. tooltip: {
  20973. color: '#e8e8e8',
  20974. font: {color: '#808080'}
  20975. }
  20976. },
  20977. sparkline: {tooltip: {
  20978. color: '#e8e8e8',
  20979. font: {color: '#808080'}
  20980. }},
  20981. bullet: {tooltip: {
  20982. color: '#e8e8e8',
  20983. font: {color: '#808080'}
  20984. }}
  20985. }, 'desktop')
  20986. })(jQuery, DevExpress);
  20987. /*! Module viz-core, file ios.js */
  20988. (function($, DX, undefined) {
  20989. var baseChartTheme = {
  20990. containerBackgroundColor: '#cbd0da',
  20991. title: {font: {color: '#808080'}},
  20992. commonSeriesSettings: {label: {border: {color: '#b0b3ba'}}},
  20993. legend: {
  20994. font: {
  20995. color: '#000000',
  20996. size: 11
  20997. },
  20998. border: {color: '#b0b3ba'}
  20999. },
  21000. loadingIndicator: {backgroundColor: '#cbd0da'},
  21001. tooltip: {font: {color: '#808080'}}
  21002. },
  21003. baseIos7ChartTheme = {
  21004. containerBackgroundColor: '#ffffff',
  21005. title: {font: {color: '#808080'}},
  21006. commonSeriesSettings: {label: {border: {color: '#d3d3d3'}}},
  21007. legend: {
  21008. font: {
  21009. color: '#000000',
  21010. size: 11
  21011. },
  21012. border: {color: '#d3d3d3'}
  21013. },
  21014. loadingIndicator: {backgroundColor: '#ffffff'},
  21015. tooltip: {font: {color: '#808080'}}
  21016. };
  21017. DX.viz.core.registerTheme({
  21018. name: 'ios',
  21019. chart: $.extend(true, {}, baseChartTheme, {
  21020. commonSeriesSettings: {candlestick: {innerColor: '#cbd0da'}},
  21021. commonAxisSettings: {
  21022. color: '#b0b3ba',
  21023. grid: {color: '#b0b3ba'},
  21024. tick: {color: '#b0b3ba'},
  21025. title: {font: {color: '#939393'}},
  21026. label: {font: {
  21027. color: '#000000',
  21028. size: 11
  21029. }}
  21030. },
  21031. commonPaneSettings: {border: {color: '#b0b3ba'}}
  21032. }),
  21033. pie: $.extend(true, {}, baseChartTheme),
  21034. pieIE8: {commonSeriesSettings: {
  21035. pie: {
  21036. hoverStyle: {border: {color: '#cbd0da'}},
  21037. selectionStyle: {border: {color: '#cbd0da'}}
  21038. },
  21039. donut: {
  21040. hoverStyle: {border: {color: '#cbd0da'}},
  21041. selectionStyle: {border: {color: '#cbd0da'}}
  21042. },
  21043. doughnut: {
  21044. hoverStyle: {border: {color: '#cbd0da'}},
  21045. selectionStyle: {border: {color: '#cbd0da'}}
  21046. }
  21047. }},
  21048. gauge: {
  21049. title: {font: {color: '#808080'}},
  21050. subtitle: {font: {color: '#808080'}},
  21051. tooltip: {font: {color: '#808080'}}
  21052. },
  21053. barGauge: {
  21054. title: {font: {color: '#808080'}},
  21055. subtitle: {font: {color: '#808080'}},
  21056. tooltip: {font: {color: '#808080'}}
  21057. },
  21058. map: {tooltip: {font: {color: '#808080'}}},
  21059. sparkline: {tooltip: {font: {color: '#808080'}}},
  21060. bullet: {tooltip: {font: {color: '#808080'}}}
  21061. }, 'desktop');
  21062. DX.viz.core.registerTheme({
  21063. name: 'ios:7',
  21064. chart: $.extend(true, {}, baseIos7ChartTheme, {
  21065. commonAxisSettings: {
  21066. color: '#d3d3d3',
  21067. grid: {color: '#d3d3d3'},
  21068. tick: {color: '#d3d3d3'},
  21069. title: {font: {color: '#939393'}},
  21070. label: {font: {
  21071. color: '#000000',
  21072. size: 11
  21073. }}
  21074. },
  21075. commonPaneSettings: {border: {color: '#d3d3d3'}}
  21076. }),
  21077. pie: $.extend(true, {}, baseIos7ChartTheme),
  21078. gauge: {
  21079. title: {font: {color: '#808080'}},
  21080. subtitle: {font: {color: '#808080'}},
  21081. tooltip: {font: {color: '#808080'}}
  21082. },
  21083. barGauge: {
  21084. title: {font: {color: '#808080'}},
  21085. subtitle: {font: {color: '#808080'}},
  21086. tooltip: {font: {color: '#808080'}}
  21087. },
  21088. map: {tooltip: {font: {color: '#808080'}}},
  21089. sparkline: {tooltip: {font: {color: '#808080'}}},
  21090. bullet: {tooltip: {font: {color: '#808080'}}}
  21091. }, 'desktop')
  21092. })(jQuery, DevExpress);
  21093. /*! Module viz-core, file win8.js */
  21094. (function($, DX) {
  21095. var baseChartTheme = {
  21096. containerBackgroundColor: '#000000',
  21097. title: {font: {color: '#ffffff'}},
  21098. commonSeriesSettings: {label: {border: {color: '#454545'}}},
  21099. legend: {
  21100. font: {
  21101. color: '#ffffff',
  21102. size: 11
  21103. },
  21104. border: {color: '#454545'}
  21105. },
  21106. loadingIndicator: {backgroundColor: '#000000'},
  21107. tooltip: {
  21108. color: '#000000',
  21109. font: {color: '#ffffff'}
  21110. }
  21111. },
  21112. baseWhiteChartTheme = {
  21113. title: {font: {color: '#808080'}},
  21114. legend: {font: {
  21115. color: '#000000',
  21116. size: 11
  21117. }},
  21118. tooltip: {font: {color: '#808080'}}
  21119. };
  21120. DX.viz.core.registerTheme({
  21121. name: 'win8',
  21122. chart: $.extend(true, {}, baseChartTheme, {
  21123. commonSeriesSettings: {candlestick: {innerColor: '#000000'}},
  21124. commonAxisSettings: {
  21125. color: '#454545',
  21126. grid: {color: '#454545'},
  21127. tick: {color: '#454545'},
  21128. title: {font: {color: '#535353'}},
  21129. label: {font: {
  21130. color: '#ffffff',
  21131. size: 11
  21132. }}
  21133. },
  21134. commonPaneSettings: {border: {color: '#454545'}}
  21135. }),
  21136. pie: $.extend(true, {}, baseChartTheme),
  21137. pieIE8: {commonSeriesSettings: {
  21138. pie: {
  21139. hoverStyle: {border: {color: '#000000'}},
  21140. selectionStyle: {border: {color: '#000000'}}
  21141. },
  21142. donut: {
  21143. hoverStyle: {border: {color: '#000000'}},
  21144. selectionStyle: {border: {color: '#000000'}}
  21145. },
  21146. doughnut: {
  21147. hoverStyle: {border: {color: '#000000'}},
  21148. selectionStyle: {border: {color: '#000000'}}
  21149. }
  21150. }},
  21151. gauge: {
  21152. containerBackgroundColor: '#000000',
  21153. title: {font: {color: '#ffffff'}},
  21154. subtitle: {font: {color: '#ffffff'}},
  21155. loadingIndicator: {backgroundColor: '#000000'},
  21156. tooltip: {
  21157. color: '#000000',
  21158. font: {color: '#ffffff'}
  21159. }
  21160. },
  21161. barGauge: {
  21162. title: {font: {color: '#ffffff'}},
  21163. subtitle: {font: {color: '#ffffff'}},
  21164. tooltip: {
  21165. color: '#000000',
  21166. font: {color: '#ffffff'}
  21167. },
  21168. loadingIndicator: {backgroundColor: '#000000'}
  21169. },
  21170. rangeSelector: {
  21171. containerBackgroundColor: '#000000',
  21172. loadingIndicator: {backgroundColor: '#000000'}
  21173. },
  21174. map: {
  21175. loadingIndicator: {backgroundColor: '#000000'},
  21176. tooltip: {
  21177. color: '#000000',
  21178. font: {color: '#ffffff'}
  21179. }
  21180. },
  21181. sparkline: {tooltip: {
  21182. color: '#000000',
  21183. font: {color: '#ffffff'}
  21184. }},
  21185. bullet: {tooltip: {
  21186. color: '#000000',
  21187. font: {color: '#ffffff'}
  21188. }}
  21189. }, 'desktop-dark');
  21190. DX.viz.core.registerTheme({
  21191. name: 'win8-white',
  21192. chart: $.extend(true, {}, baseWhiteChartTheme, {commonAxisSettings: {
  21193. title: {font: {color: '#939393'}},
  21194. label: {font: {
  21195. color: '#404040',
  21196. size: 11
  21197. }}
  21198. }}),
  21199. pie: $.extend(true, {}, baseWhiteChartTheme),
  21200. gauge: {
  21201. title: {font: {color: '#808080'}},
  21202. subtitle: {font: {color: '#808080'}},
  21203. tooltip: {font: {color: '#808080'}}
  21204. },
  21205. barGauge: {
  21206. title: {font: {color: '#808080'}},
  21207. subtitle: {font: {color: '#808080'}},
  21208. tooltip: {font: {color: '#808080'}}
  21209. },
  21210. map: {tooltip: {font: {color: '#808080'}}},
  21211. sparkline: {tooltip: {font: {color: '#808080'}}},
  21212. bullet: {tooltip: {font: {color: '#808080'}}}
  21213. }, 'desktop')
  21214. })(jQuery, DevExpress);
  21215. /*! Module viz-core, file others.js */
  21216. (function($, DX) {
  21217. DX.viz.core.registerTheme({name: 'generic'}, 'desktop');
  21218. DX.viz.core.registerTheme({name: 'generic-dark'}, 'desktop-dark');
  21219. DX.viz.core.registerTheme({name: 'tizen'}, 'desktop');
  21220. DX.viz.core.registerTheme({name: 'tizen-black'}, 'desktop-dark')
  21221. })(jQuery, DevExpress);
  21222. /*! Module viz-core, file namespaces.js */
  21223. (function(DevExpress) {
  21224. DevExpress.viz.renderers = {}
  21225. })(DevExpress);
  21226. /*! Module viz-core, file svgRenderer.js */
  21227. (function($, DX) {
  21228. var renderers = DX.viz.renderers,
  21229. utils = DX.utils,
  21230. Class = DX.Class,
  21231. doc = document,
  21232. MAX_PIXEL_COUNT = 10000000000;
  21233. function createElement(name) {
  21234. return doc.createElementNS('http://www.w3.org/2000/svg', name)
  21235. }
  21236. function getPatternUrl(id, pathModified) {
  21237. return id !== null ? 'url(' + (pathModified ? window.location.href : '') + '#' + id + ')' : null
  21238. }
  21239. var BaseSvgElement = Class.inherit({
  21240. ctor: function baseSvgElementCtor(renderer, name, params) {
  21241. this.renderer = renderer;
  21242. this.element = this.createElement(name);
  21243. this.$element = $(this.element);
  21244. this.applySettings($.extend({}, this.defaultSettings(), params));
  21245. this.__passedParams = params
  21246. },
  21247. defaultSettings: $.noop,
  21248. createElement: function(nodeName) {
  21249. this._nodeName = nodeName;
  21250. return createElement(nodeName)
  21251. },
  21252. dispose: function() {
  21253. this.off();
  21254. this.remove();
  21255. this.renderer = null;
  21256. this.element = null;
  21257. this.settings = null;
  21258. this.$element = null;
  21259. this.transformation = null;
  21260. this.__passedParams = null;
  21261. this.__appliedSettings = null;
  21262. this.__appliedStyle = null
  21263. },
  21264. append: function(svgElement) {
  21265. var toElement = svgElement || this.renderer.getRoot();
  21266. toElement.element.appendChild(this.element);
  21267. return this
  21268. },
  21269. insertBefore: function(target) {
  21270. target.element.parentNode.insertBefore(this.element, target.element);
  21271. return this
  21272. },
  21273. toBackground: function() {
  21274. this.element.parentNode && this.element.parentNode.insertBefore(this.element, this.element.parentNode.firstChild);
  21275. return this
  21276. },
  21277. toForeground: function() {
  21278. this.element.parentNode && this.element.parentNode.appendChild(this.element);
  21279. return this
  21280. },
  21281. addClass: function(className) {
  21282. var classAttribute = this.$element.attr('class'),
  21283. classNameIndex,
  21284. classNames;
  21285. if (className) {
  21286. if (classAttribute) {
  21287. classNames = classAttribute.split(' ');
  21288. classNameIndex = $.inArray(className, classNames);
  21289. if (classNameIndex === -1)
  21290. classAttribute += ' ' + className
  21291. }
  21292. else
  21293. classAttribute = className;
  21294. this.$element.attr('class', classAttribute)
  21295. }
  21296. return this.$element
  21297. },
  21298. removeClass: function(className) {
  21299. var classAttribute = this.$element.attr('class'),
  21300. classNames,
  21301. indexDeleteElement,
  21302. resultClassNames = '',
  21303. i;
  21304. if (classAttribute && className) {
  21305. classNames = classAttribute.split(' ');
  21306. indexDeleteElement = $.inArray(className, classNames);
  21307. if (indexDeleteElement !== -1) {
  21308. for (i = 0; i < classNames.length; i++)
  21309. if (i !== indexDeleteElement)
  21310. resultClassNames += classNames[i] + ' ';
  21311. this.$element.attr('class', resultClassNames.replace(/ $/, ''))
  21312. }
  21313. }
  21314. return this.$element
  21315. },
  21316. applySettings: function(settings) {
  21317. var normalized;
  21318. this.settings = $.extend(this.settings || {}, settings || {});
  21319. this.adjustSettings();
  21320. normalized = this._normalizeSettings(this.settings);
  21321. this.applyStyle(this._style);
  21322. this._applyAttributes(normalized);
  21323. return this
  21324. },
  21325. _applyAttributes: function(settings) {
  21326. this.$element.attr(settings);
  21327. this.__appliedSettings = settings
  21328. },
  21329. adjustSettings: function(){},
  21330. applyStyle: function(style) {
  21331. this.$element.css(style || {});
  21332. this.__appliedStyle = style || {};
  21333. return this
  21334. },
  21335. trigger: function(event, data) {
  21336. this.$element.trigger(event, data)
  21337. },
  21338. on: function(events, data, handler) {
  21339. this.$element.on.apply(this.$element, arguments);
  21340. return this
  21341. },
  21342. data: function(key, value) {
  21343. this.$element.data(key, value);
  21344. return this
  21345. },
  21346. removeData: function() {
  21347. this.$element.removeData();
  21348. return this
  21349. },
  21350. off: function(events) {
  21351. this.$element.off(events);
  21352. return this
  21353. },
  21354. getBBox: function() {
  21355. var that = this,
  21356. bBox,
  21357. element = this.element,
  21358. transformation = that.transformation,
  21359. rotateAngle = transformation.rotateAngle || 0,
  21360. rotateX = transformation.rotateX || 0,
  21361. rotateY = transformation.rotateY || 0,
  21362. mabs = Math.abs,
  21363. mmin = Math.min;
  21364. function bBox(el) {
  21365. var ret = {};
  21366. try {
  21367. if (!$.isFunction(el.getBBox))
  21368. throw{};
  21369. else
  21370. ret = el.getBBox()
  21371. }
  21372. catch(e) {
  21373. ret = {
  21374. x: 0,
  21375. y: 0,
  21376. width: el.offsetWidth || 0,
  21377. height: el.offsetHeight || 0
  21378. }
  21379. }
  21380. return ret
  21381. }
  21382. bBox = $.extend({}, bBox(element));
  21383. if (rotateAngle) {
  21384. var cossin = utils.getCosAndSin(rotateAngle),
  21385. sin = cossin.sin.toFixed(3),
  21386. cos = cossin.cos.toFixed(3),
  21387. ltx = bBox.x - rotateX,
  21388. lty = bBox.y - rotateY,
  21389. rtx = bBox.x + bBox.width - rotateX,
  21390. rty = bBox.y - rotateY,
  21391. lbx = bBox.x - rotateX,
  21392. lby = bBox.y + bBox.height - rotateY,
  21393. rbx = bBox.x + bBox.width - rotateX,
  21394. rby = bBox.y + bBox.height - rotateY,
  21395. w,
  21396. h;
  21397. w = mabs(bBox.height * sin) + mabs(bBox.width * cos);
  21398. h = mabs(bBox.height * cos) + mabs(bBox.width * sin);
  21399. bBox.x = mmin(ltx * cos - lty * sin + rotateX, rtx * cos - rty * sin + rotateX, lbx * cos - lby * sin + rotateX, rbx * cos - rby * sin + rotateX);
  21400. bBox.y = mmin(ltx * sin + lty * cos + rotateY, rtx * sin + rty * cos + rotateY, lbx * sin + lby * cos + rotateY, rbx * sin + rby * cos + rotateY);
  21401. bBox.width = w;
  21402. bBox.height = h
  21403. }
  21404. return that._normalizeBBox(bBox)
  21405. },
  21406. _normalizeBBox: function(bBox) {
  21407. var ceil = Math.ceil,
  21408. floor = Math.floor,
  21409. $isNumeric = $.isNumeric,
  21410. rxl = floor(bBox.x),
  21411. ryt = floor(bBox.y),
  21412. rxr = ceil(bBox.width + bBox.x),
  21413. ryb = ceil(bBox.height + bBox.y),
  21414. width,
  21415. height;
  21416. bBox.x = $isNumeric(rxl) && rxl < MAX_PIXEL_COUNT && rxl > -MAX_PIXEL_COUNT ? rxl : 0;
  21417. bBox.y = $isNumeric(ryt) && ryt < MAX_PIXEL_COUNT && ryt > -MAX_PIXEL_COUNT ? ryt : 0;
  21418. width = rxr - rxl;
  21419. height = ryb - ryt;
  21420. bBox.width = $isNumeric(width) && width < MAX_PIXEL_COUNT && width > -MAX_PIXEL_COUNT ? width : 0;
  21421. bBox.height = $isNumeric(height) && height < MAX_PIXEL_COUNT && height > -MAX_PIXEL_COUNT ? height : 0;
  21422. bBox.isEmpty = !bBox.x && !bBox.y && !bBox.width && !bBox.height;
  21423. return bBox
  21424. },
  21425. clear: function(selector) {
  21426. selector ? this.$element.find(selector).remove() : this.$element.empty();
  21427. return this
  21428. },
  21429. detach: function() {
  21430. this.$element.detach();
  21431. return this
  21432. },
  21433. animate: function(params, options, complete) {
  21434. options = options || {};
  21435. var that = this,
  21436. animationParams = {};
  21437. if (complete)
  21438. $.extend(options, {complete: complete});
  21439. if (this.renderer.animOptions.enabled) {
  21440. $.each(params, function(name, to) {
  21441. switch (name) {
  21442. case'scale':
  21443. animationParams['transform'] = animationParams['transform'] || {};
  21444. var scale = that.transformation.scale || {};
  21445. animationParams['transform'].scale = {
  21446. x: {
  21447. from: utils.isDefined(scale.x) ? scale.x : 1,
  21448. to: utils.isDefined(to.x) ? to.x : 1
  21449. },
  21450. y: {
  21451. from: utils.isDefined(scale.y) ? scale.y : 1,
  21452. to: utils.isDefined(to.y) ? to.y : 1
  21453. }
  21454. };
  21455. break;
  21456. case'rotate':
  21457. animationParams['transform'] = animationParams['transform'] || {};
  21458. animationParams['transform'].rotate = {
  21459. angle: {
  21460. from: that.transformation.rotateAngle || 0,
  21461. to: to.angle
  21462. },
  21463. y: to.y || 0,
  21464. x: to.x || 0
  21465. };
  21466. break;
  21467. case'translate':
  21468. animationParams['transform'] = animationParams['transform'] || {};
  21469. animationParams['transform'].translate = {
  21470. x: {
  21471. from: that.transformation.translateX || 0,
  21472. to: to.x || 0
  21473. },
  21474. y: {
  21475. from: that.transformation.translateY || 0,
  21476. to: to.y || 0
  21477. }
  21478. };
  21479. break;
  21480. case'arc':
  21481. case'points':
  21482. animationParams[name] = to;
  21483. break;
  21484. default:
  21485. animationParams[name] = {
  21486. from: that.settings[name] || 0,
  21487. to: to
  21488. }
  21489. }
  21490. });
  21491. that.renderer.animateElement(that, animationParams, $.extend({}, this.renderer.animOptions, options))
  21492. }
  21493. else {
  21494. if (params.translate) {
  21495. if ('x' in params.translate)
  21496. params.translateX = params.translate.x;
  21497. if ('y' in params.translate)
  21498. params.translateY = params.translate.y;
  21499. delete params.translate
  21500. }
  21501. if (options) {
  21502. options.step && options.step.call(that, 1, 1);
  21503. options.complete && options.complete.call(that)
  21504. }
  21505. this.applySettings(params)
  21506. }
  21507. },
  21508. stopAnimation: function(disableComplete) {
  21509. var that = this;
  21510. that.animation && that.animation.stop(true, disableComplete);
  21511. return that
  21512. },
  21513. move: function(x, y, animate, animOptions) {
  21514. x = x || 0,
  21515. y = y || 0;
  21516. animOptions = animOptions || {};
  21517. if (!animate)
  21518. this.applySettings({
  21519. translateX: x,
  21520. translateY: y
  21521. });
  21522. else
  21523. this.animate({translate: {
  21524. x: x,
  21525. y: y
  21526. }}, animOptions);
  21527. return this
  21528. },
  21529. rotate: function(angle, x, y, animate, animOptions) {
  21530. angle = angle || 0;
  21531. x = x || 0;
  21532. y = y || 0;
  21533. animOptions = animOptions || {};
  21534. if (!animate)
  21535. this.applySettings({rotate: [angle, x, y]});
  21536. else
  21537. this.animate({rotate: {
  21538. angle: angle,
  21539. x: x,
  21540. y: y
  21541. }}, animOptions)
  21542. },
  21543. remove: function() {
  21544. this.$element.remove()
  21545. },
  21546. _normalizeSettings: function(settings) {
  21547. var key,
  21548. style,
  21549. firstChar,
  21550. styleName,
  21551. prop,
  21552. value,
  21553. normalized = {},
  21554. fontSetting,
  21555. rtl = this.renderer.rtl;
  21556. for (key in settings) {
  21557. prop = key,
  21558. value = settings[prop];
  21559. if (prop === 'align') {
  21560. prop = 'text-anchor';
  21561. value = {
  21562. left: rtl ? 'end' : 'start',
  21563. center: 'middle',
  21564. right: rtl ? 'start' : 'end'
  21565. }[value]
  21566. }
  21567. else if (prop === 'font') {
  21568. style = this['_style'] = this['_style'] || {};
  21569. if (!$.isPlainObject(value))
  21570. continue;
  21571. $.each(value, function(fontSetting) {
  21572. switch (fontSetting) {
  21573. case'color':
  21574. styleName = 'fill';
  21575. break;
  21576. case'opacity':
  21577. styleName = 'fillOpacity';
  21578. break;
  21579. case'cursor':
  21580. styleName = fontSetting;
  21581. break;
  21582. default:
  21583. firstChar = fontSetting.charAt(0);
  21584. styleName = 'font' + fontSetting.replace(firstChar, firstChar.toUpperCase())
  21585. }
  21586. style[styleName] = value[fontSetting]
  21587. });
  21588. continue
  21589. }
  21590. else if (prop === 'dashStyle') {
  21591. prop = 'stroke-dasharray';
  21592. value = (value || 'none').toLowerCase();
  21593. if (value === 'solid' || value === 'none')
  21594. value = null;
  21595. else {
  21596. value = value.replace(/longdash/g, '8,3,').replace(/dash/g, '4,3,').replace(/dot/g, '1,3,').replace(/,$/, '').split(',');
  21597. value = $.map(value, function(p) {
  21598. return +p * (settings.strokeWidth || 1)
  21599. }).join(',')
  21600. }
  21601. }
  21602. else if (/^(linecap|linejoin)$/i.test(prop))
  21603. prop = 'stroke-' + prop;
  21604. else if (/^(translateX|translateY|rotate|scale)$/i.test(prop)) {
  21605. this['_' + prop] = value;
  21606. continue
  21607. }
  21608. else if (prop === 'clipId') {
  21609. prop = 'clip-path';
  21610. value = getPatternUrl(value, this.renderer.pathModified)
  21611. }
  21612. else if (prop === 'style') {
  21613. this['_style'] = this['_style'] || {};
  21614. $.extend(true, this['_style'], value);
  21615. continue
  21616. }
  21617. else if (prop === 'sharpEdges')
  21618. continue;
  21619. else if (prop === 'text')
  21620. continue;
  21621. else if (prop === 'segments')
  21622. continue;
  21623. else
  21624. prop = DX.inflector.dasherize(prop);
  21625. normalized[prop] = value
  21626. }
  21627. return this._applyTransformation(normalized)
  21628. },
  21629. _applyTransformation: function(settings) {
  21630. this.transformation = {
  21631. translateX: this._translateX,
  21632. translateY: this._translateY,
  21633. rotateAngle: 0,
  21634. rotateX: 0,
  21635. rotateY: 0
  21636. };
  21637. var tr = this.transformation,
  21638. rotate = this._rotate,
  21639. scale = this._scale,
  21640. transformations = [];
  21641. if (utils.isDefined(tr.translateX) || utils.isDefined(tr.translateY))
  21642. transformations.push('translate(' + (tr.translateX || 0) + ',' + (tr.translateY || 0) + ')');
  21643. if (utils.isDefined(rotate)) {
  21644. if (utils.isNumber(rotate)) {
  21645. tr.rotateAngle = rotate;
  21646. tr.rotateX = settings.x || 0;
  21647. tr.rotateY = settings.y || 0
  21648. }
  21649. else if ($.isArray(rotate)) {
  21650. tr.rotateAngle = rotate[0] || 0;
  21651. tr.rotateX = rotate[1] || 0;
  21652. tr.rotateY = rotate[2] || 0
  21653. }
  21654. else if (utils.isObject(rotate)) {
  21655. tr.rotateAngle = rotate.angle || 0;
  21656. tr.rotateX = rotate.x || 0;
  21657. tr.rotateY = rotate.y || 0
  21658. }
  21659. transformations.push('rotate(' + tr.rotateAngle + ',' + tr.rotateX + ',' + tr.rotateY + ')')
  21660. }
  21661. if (utils.isNumber(scale)) {
  21662. var value = utils.isDefined(scale) ? scale : 1;
  21663. transformations.push('scale(' + value + ',' + value + ')');
  21664. tr.scale = {
  21665. x: value,
  21666. y: value
  21667. }
  21668. }
  21669. else if (utils.isObject(scale)) {
  21670. var valueX = utils.isDefined(scale.x) ? scale.x : 1;
  21671. var valueY = utils.isDefined(scale.y) ? scale.y : 1;
  21672. transformations.push('scale(' + valueX + ',' + valueY + ')');
  21673. tr.scale = {
  21674. x: valueX,
  21675. y: valueY
  21676. }
  21677. }
  21678. if (transformations.length)
  21679. settings.transform = transformations.join(' ');
  21680. return settings
  21681. }
  21682. });
  21683. var RootSvgElement = BaseSvgElement.inherit({
  21684. defaultSettings: function() {
  21685. return {
  21686. width: 0,
  21687. height: 0,
  21688. style: {
  21689. '-webkit-tap-highlight-color': 'rgba(0, 0, 0, 0)',
  21690. display: 'block',
  21691. overflow: 'hidden'
  21692. },
  21693. xmlns: 'http://www.w3.org/2000/svg',
  21694. 'xmlns:xlink': 'http://www.w3.org/1999/xlink',
  21695. version: '1.1',
  21696. stroke: 'none',
  21697. strokeWidth: 0,
  21698. fill: 'none'
  21699. }
  21700. },
  21701. ctor: function(renderer, params) {
  21702. this.callBase(renderer, 'svg', params)
  21703. }
  21704. });
  21705. var RectSvgBaseElement = {
  21706. defaultSettings: function() {
  21707. return {
  21708. x: 0,
  21709. y: 0,
  21710. width: 0,
  21711. height: 0
  21712. }
  21713. },
  21714. adjustSettings: function() {
  21715. if (!utils.isDefined(this.settings.sharpEdges) || this.settings.sharpEdges) {
  21716. this.sharpEdges();
  21717. delete this.settings.sharpEdges
  21718. }
  21719. },
  21720. prepareSettings: function(settings) {
  21721. var prevStrokeWidth = this.settings ? Number(this.settings.strokeWidth) || 0 : 0,
  21722. newStrokeWidth,
  21723. maxStrokeWidth,
  21724. strokeWidthChanged = false;
  21725. if (utils.isDefined(settings.width))
  21726. this._realWidth = Number(settings.width);
  21727. if (utils.isDefined(settings.height))
  21728. this._realHeight = Number(settings.height);
  21729. if (utils.isDefined(settings.x))
  21730. this._realX = Number(settings.x);
  21731. if (utils.isDefined(settings.y))
  21732. this._realY = Number(settings.y);
  21733. if (utils.isDefined(settings.strokeWidth))
  21734. this._realStrokeWidth = Number(settings.strokeWidth);
  21735. this._realStrokeWidth = this._realStrokeWidth || this.defaultSettings().strokeWidth || 0;
  21736. maxStrokeWidth = ~~((this._realWidth < this._realHeight ? this._realWidth : this._realHeight) / 2);
  21737. newStrokeWidth = this._realStrokeWidth < maxStrokeWidth ? this._realStrokeWidth : maxStrokeWidth;
  21738. if (newStrokeWidth !== prevStrokeWidth) {
  21739. strokeWidthChanged = true;
  21740. settings.sharpEdges = true;
  21741. newStrokeWidth > 0 && (settings.strokeWidth = newStrokeWidth)
  21742. }
  21743. (utils.isDefined(settings.x) || strokeWidthChanged) && (settings.x = this._realX + newStrokeWidth / 2);
  21744. (utils.isDefined(settings.y) || strokeWidthChanged) && (settings.y = this._realY + newStrokeWidth / 2);
  21745. (utils.isDefined(settings.width) || strokeWidthChanged) && (settings.width = this._realWidth - newStrokeWidth);
  21746. (utils.isDefined(settings.height) || strokeWidthChanged) && (settings.height = this._realHeight - newStrokeWidth)
  21747. },
  21748. applySettings: function(settings) {
  21749. var settings = $.extend(true, {}, settings);
  21750. this.prepareSettings(settings);
  21751. return this.callBase(settings)
  21752. },
  21753. sharpEdges: function() {
  21754. var strokeWidth = Math.round(this.settings.strokeWidth || 0),
  21755. correction = strokeWidth % 2 / 2;
  21756. this.settings.x = Math.floor(this.settings.x - correction || 0) + correction;
  21757. this.settings.y = Math.floor(this.settings.y - correction || 0) + correction;
  21758. this.settings.width = Math.floor(this.settings.width || 0);
  21759. this.settings.height = Math.floor(this.settings.height || 0);
  21760. this.settings.strokeWidth > 0 && (this.settings.strokeWidth = strokeWidth)
  21761. }
  21762. };
  21763. var ImageSvgElement = BaseSvgElement.inherit(RectSvgBaseElement).inherit({
  21764. ctor: function(renderer, params, href, location) {
  21765. var locationToPreserveAspectRatioMap = {
  21766. full: 'none',
  21767. lefttop: 'xMinYMin',
  21768. leftcenter: 'xMinYMid',
  21769. leftbottom: 'xMinYMax',
  21770. centertop: 'xMidYMin',
  21771. center: 'xMidYMid',
  21772. centerbottom: 'xMidYMax',
  21773. righttop: 'xMaxYMin',
  21774. rightcenter: 'xMaxYMid',
  21775. rightbottom: 'xMaxYMax'
  21776. };
  21777. this.href = utils.isDefined(href) ? href : '';
  21778. this.preserveAspectRatio = locationToPreserveAspectRatioMap[(location || '').toLowerCase()];
  21779. this.preserveAspectRatio = this.preserveAspectRatio || 'none';
  21780. this.callBase(renderer, 'image', params)
  21781. },
  21782. adjustSettings: function() {
  21783. this.callBase();
  21784. this.element.setAttributeNS('http://www.w3.org/1999/xlink', 'href', this.href);
  21785. if (this.preserveAspectRatio)
  21786. this.element.setAttribute('preserveAspectRatio', this.preserveAspectRatio)
  21787. }
  21788. });
  21789. var RectSvgElement = BaseSvgElement.inherit(RectSvgBaseElement).inherit({
  21790. defaultSettings: function() {
  21791. return {
  21792. x: 0,
  21793. y: 0,
  21794. width: 0,
  21795. height: 0,
  21796. rx: 0,
  21797. ry: 0
  21798. }
  21799. },
  21800. ctor: function(renderer, params) {
  21801. this.callBase(renderer, 'rect', params)
  21802. }
  21803. });
  21804. var PathSvgElement = BaseSvgElement.inherit({
  21805. defaultSettings: function() {
  21806. return {points: {
  21807. x: 0,
  21808. y: 0
  21809. }}
  21810. },
  21811. getNodeName: function() {
  21812. return 'path'
  21813. },
  21814. getPathAttributeName: function() {
  21815. return 'd'
  21816. },
  21817. ctor: function(renderer, params) {
  21818. this.callBase(renderer, this.getNodeName(), params)
  21819. },
  21820. dispose: function() {
  21821. this.segments = null;
  21822. this.fromSegments = null;
  21823. this.callBase()
  21824. },
  21825. adjustSettings: function() {
  21826. this.prepareSegments(this.settings)
  21827. },
  21828. applySettings: function(settings) {
  21829. var settings = settings || {};
  21830. if (this.settings && settings.strokeWidth && this.settings.strokeWidth !== settings.strokeWidth)
  21831. settings.sharpEdges = true;
  21832. return this.callBase(settings)
  21833. },
  21834. prepareSegments: function(params) {
  21835. if ('points' in params) {
  21836. var points = params.points,
  21837. firstElem = points[0],
  21838. close = this.closePath || params.closePath,
  21839. segments = [],
  21840. i;
  21841. if (utils.isObject(firstElem))
  21842. segments = $.map(points, function(pt, i) {
  21843. if (!pt)
  21844. return null;
  21845. if (!i)
  21846. return [['M', pt.x, pt.y]];
  21847. return [['L', pt.x, pt.y]]
  21848. });
  21849. else if (utils.isNumber(firstElem))
  21850. for (i = 0; i < points.length; i += 2) {
  21851. if (!i) {
  21852. segments = [['M', points[i] || 0, points[i + 1] || 0]];
  21853. continue
  21854. }
  21855. segments.push(['L', points[i] || 0, points[i + 1] || 0])
  21856. }
  21857. else
  21858. segments = [['M', 0, 0]];
  21859. if (close)
  21860. segments.push(['Z']);
  21861. this.segments = segments;
  21862. delete params.points;
  21863. delete params.closePath;
  21864. params.sharpEdges = true
  21865. }
  21866. if (params.sharpEdges) {
  21867. this.sharpEdges();
  21868. this.combinePathParams(params);
  21869. delete params.sharpEdges
  21870. }
  21871. },
  21872. customizeSegments: function(segments) {
  21873. return segments
  21874. },
  21875. combinePathParams: function(params) {
  21876. var path;
  21877. this.segments = this.customizeSegments(this.segments);
  21878. if (this.segments) {
  21879. path = $.map(this.segments, function(seg, i) {
  21880. return seg.join(' ')
  21881. });
  21882. path = path.join(' ');
  21883. params[this.getPathAttributeName()] = path
  21884. }
  21885. },
  21886. _prepareDifferrentPath: function(from, to) {
  21887. var end = {},
  21888. constsSeg;
  21889. if (to.length > from.length)
  21890. this._makeEqualPath(from, to);
  21891. else {
  21892. this.combinePathParams(end);
  21893. this._makeEqualPath(to, from)
  21894. }
  21895. return end.d
  21896. },
  21897. _prepareConstSegment: function(seg) {
  21898. seg[0] = "L"
  21899. },
  21900. _makeEqualPath: function(short, long) {
  21901. var constSeg = short[short.length - 1].slice();
  21902. this._prepareConstSegment(constSeg);
  21903. for (var i = short.length; i < long.length; i++)
  21904. short[i] = constSeg
  21905. },
  21906. animate: function(params, options, complete) {
  21907. var that = this;
  21908. if (!('points' in params) || !that.renderer.animOptions.enabled)
  21909. return that.callBase(params, options, complete);
  21910. var fromPath = that.segments,
  21911. end;
  21912. that.prepareSegments(params);
  21913. delete params.d;
  21914. if (fromPath.length === that.segments.length)
  21915. params.points = {
  21916. from: fromPath,
  21917. to: that.segments
  21918. };
  21919. else
  21920. end = that._prepareDifferrentPath(fromPath, that.segments);
  21921. params.points = {
  21922. from: fromPath,
  21923. to: that.segments,
  21924. end: end
  21925. };
  21926. that.callBase(params, options, complete)
  21927. },
  21928. sharpEdges: function() {
  21929. var that = this,
  21930. segLength = that.segments.length,
  21931. i = 0,
  21932. curSeg,
  21933. nextSeg,
  21934. curX,
  21935. curY,
  21936. nextX,
  21937. nextY,
  21938. curXIdx,
  21939. curYIdx,
  21940. nextXIdx,
  21941. nextYIdx,
  21942. strokeWidth = Math.round(that.settings.strokeWidth || 0),
  21943. correction = strokeWidth % 2 / 2;
  21944. for (i; i < segLength - 1; i++) {
  21945. curSeg = that.segments[i];
  21946. nextSeg = that.segments[i + 1];
  21947. if (nextSeg[0] === 'Z' && i)
  21948. nextSeg = that.segments[0];
  21949. switch (curSeg[0]) {
  21950. case'M':
  21951. case'L':
  21952. curXIdx = 1;
  21953. curYIdx = 2;
  21954. break;
  21955. case'C':
  21956. curXIdx = 5;
  21957. curYIdx = 6;
  21958. break;
  21959. case'A':
  21960. curXIdx = 6;
  21961. curYIdx = 7;
  21962. break;
  21963. case'Z':
  21964. continue
  21965. }
  21966. switch (nextSeg[0]) {
  21967. case'M':
  21968. case'L':
  21969. nextXIdx = 1;
  21970. nextYIdx = 2;
  21971. break;
  21972. case'C':
  21973. nextXIdx = 5;
  21974. nextYIdx = 6;
  21975. break;
  21976. case'A':
  21977. nextXIdx = 6;
  21978. nextYIdx = 7;
  21979. break;
  21980. case'Z':
  21981. continue
  21982. }
  21983. curX = Math.floor(curSeg[curXIdx]);
  21984. curY = Math.floor(curSeg[curYIdx]);
  21985. nextX = nextSeg[nextXIdx] = Math.floor(nextSeg[nextXIdx]);
  21986. nextY = nextSeg[nextYIdx] = Math.floor(nextSeg[nextYIdx]);
  21987. curSeg[curXIdx] = i == 0 ? curX : curSeg[curXIdx];
  21988. curSeg[curYIdx] = i == 0 ? curY : curSeg[curYIdx];
  21989. if (curX == nextX) {
  21990. curSeg[curXIdx] = curX + correction;
  21991. nextSeg[nextXIdx] = nextX + correction
  21992. }
  21993. if (curY == nextY) {
  21994. curSeg[curYIdx] = curY + correction;
  21995. nextSeg[nextYIdx] = nextY + correction
  21996. }
  21997. }
  21998. }
  21999. });
  22000. var SegmentRectSvgElement = PathSvgElement.inherit(RectSvgBaseElement).inherit({
  22001. defaultSettings: function() {
  22002. return $.extend(true, {}, this.callBase(), {segments: {
  22003. top: true,
  22004. bottom: true,
  22005. left: true,
  22006. right: true
  22007. }})
  22008. },
  22009. prepareSegments: function() {
  22010. var that = this,
  22011. settings = that.settings,
  22012. left = settings.x,
  22013. right = left + settings.width,
  22014. top = settings.y,
  22015. bottom = top + settings.height,
  22016. segments = [],
  22017. segmentSequence,
  22018. visiblyOpt = 0,
  22019. prevSegmentVisibility = 0;
  22020. var allSegment = {
  22021. top: [['M', left, top], ['L', right, top]],
  22022. right: [['M', right, top], ['L', right, bottom]],
  22023. bottom: [['M', right, bottom], ['L', left, bottom]],
  22024. left: [['M', left, bottom], ['L', left, top]]
  22025. };
  22026. $.each(allSegment, function(seg, _) {
  22027. var visibility = !!that.settings.segments[seg];
  22028. visiblyOpt = visiblyOpt * 2 + ~~visibility
  22029. });
  22030. switch (visiblyOpt) {
  22031. case(13):
  22032. case(9):
  22033. segmentSequence = ['left', 'top', 'right', 'bottom'];
  22034. break;
  22035. case(11):
  22036. segmentSequence = ['bottom', 'left', 'top', 'right'];
  22037. break;
  22038. default:
  22039. segmentSequence = ['top', 'right', 'bottom', 'left']
  22040. }
  22041. $.each(segmentSequence, function(_, seg) {
  22042. var segmentVisibility = !!that.settings.segments[seg];
  22043. if (segmentVisibility)
  22044. $.each(allSegment[seg].slice(prevSegmentVisibility), function(_, segment) {
  22045. segments.push(segment)
  22046. });
  22047. prevSegmentVisibility = ~~segmentVisibility
  22048. });
  22049. visiblyOpt == 15 && segments.push(['Z']);
  22050. this.segments = segments.length ? segments : [['M', 0, 0], ['Z']];
  22051. this.combinePathParams(settings)
  22052. },
  22053. adjustSettings: function() {
  22054. this.callBase();
  22055. this.prepareSegments()
  22056. },
  22057. applySettings: function(settings) {
  22058. var segments = this.settings && this.settings.segments || this.defaultSettings().segments;
  22059. settings.segments = $.extend(true, {}, segments || {}, settings.segments);
  22060. return this.callBase(settings)
  22061. }
  22062. });
  22063. var baseAreaElement = {
  22064. defaultSettings: function() {
  22065. return {points: {
  22066. x: 0,
  22067. y: 0
  22068. }}
  22069. },
  22070. ctor: function(renderer, params) {
  22071. this.closePath = true;
  22072. this.callBase(renderer, params)
  22073. },
  22074. _tailIndex: 0,
  22075. _makeEqualPath: function(short, long) {
  22076. var i,
  22077. tail,
  22078. head,
  22079. constsSeg1,
  22080. constsSeg2,
  22081. newTail = [];
  22082. if ((short.length - 1) % 2 == 0 && (long.length - 1) % 2 == 0) {
  22083. i = (short.length - 1) / 2 - 1;
  22084. tail = short.slice(i + 1);
  22085. head = short.slice(0, i + 1);
  22086. constsSeg1 = head[head.length - 1];
  22087. constsSeg2 = tail[this._tailIndex];
  22088. this._prepareConstSegment(constsSeg1);
  22089. for (var j = i; j < (long.length - 1) / 2 - 1; j++) {
  22090. head.push(constsSeg1);
  22091. newTail.push(constsSeg2)
  22092. }
  22093. head = this._concatAnimationSegment(head, newTail, tail);
  22094. for (i = 0; i < head.length; i++)
  22095. short[i] = head[i]
  22096. }
  22097. },
  22098. _concatAnimationSegment: function(head, newTail, tail) {
  22099. return head.concat(newTail, tail)
  22100. }
  22101. };
  22102. var AreaSvgElement = PathSvgElement.inherit(baseAreaElement);
  22103. var BezierSvgElement = PathSvgElement.inherit({
  22104. defaultSettings: function() {
  22105. return {points: {
  22106. x: 0,
  22107. y: 0
  22108. }}
  22109. },
  22110. _prepareConstSegment: function(seg) {
  22111. var x = seg[seg.length - 2],
  22112. y = seg[seg.length - 1];
  22113. seg[0] = "C";
  22114. seg[5] = seg[3] = seg[1] = x;
  22115. seg[6] = seg[4] = seg[2] = y
  22116. },
  22117. prepareSegments: function(params) {
  22118. if (!('points' in params))
  22119. return;
  22120. var points = params.points,
  22121. firstElem = points[0],
  22122. close = this.closePath || params.closePath,
  22123. segments = [],
  22124. seg = [],
  22125. i,
  22126. x,
  22127. y;
  22128. var cnt = 0;
  22129. if (utils.isObject(firstElem)) {
  22130. for (i = 0; i < points.length; i++) {
  22131. x = points[i].x;
  22132. y = points[i].y;
  22133. if (!i) {
  22134. segments = [['M', x, y]];
  22135. continue
  22136. }
  22137. if ((i - 1) % 3 == 0) {
  22138. if (seg.length > 0)
  22139. segments.push(seg);
  22140. seg = ['C', x, y];
  22141. continue
  22142. }
  22143. seg.push(x);
  22144. seg.push(y)
  22145. }
  22146. if (seg.length > 0)
  22147. segments.push(seg)
  22148. }
  22149. else if (utils.isNumber(firstElem)) {
  22150. for (i = 0; i < points.length; i += 2) {
  22151. x = points[i];
  22152. y = points[i + 1];
  22153. if (!i) {
  22154. segments = [['M', x, y || 0]];
  22155. continue
  22156. }
  22157. if ((i - 2) % 6 == 0) {
  22158. if (seg.length > 0)
  22159. segments.push(seg);
  22160. seg = ['C', x, y || 0];
  22161. continue
  22162. }
  22163. seg.push(x);
  22164. seg.push(y || 0)
  22165. }
  22166. if (seg.length > 0)
  22167. segments.push(seg)
  22168. }
  22169. else
  22170. segments = [['M', 0, 0]];
  22171. if (close)
  22172. segments.push(['Z']);
  22173. this.segments = segments;
  22174. delete params.points;
  22175. delete params.closePath;
  22176. this.combinePathParams(params)
  22177. }
  22178. });
  22179. var BezierAreaSvgElement = BezierSvgElement.inherit(baseAreaElement).inherit({
  22180. _concatAnimationSegment: function(head, newTail, tail) {
  22181. var point = tail.splice(0, 1);
  22182. return head.concat(point.concat(newTail), tail)
  22183. },
  22184. _tailIndex: 1
  22185. });
  22186. var ArcSvgElement = PathSvgElement.inherit({
  22187. defaultSettings: function() {
  22188. return {
  22189. x: 0,
  22190. y: 0,
  22191. linejoin: 'round'
  22192. }
  22193. },
  22194. createArcSegments: function(x, y, innerR, outerR, startAngle, endAngle, isCircle) {
  22195. var longFlag = Math.floor(Math.abs(endAngle - startAngle) / Math.PI) % 2 ? '1' : '0',
  22196. xOuterStart = x + outerR * Math.cos(startAngle),
  22197. yOuterStart = y - outerR * Math.sin(startAngle),
  22198. xOuterEnd = x + outerR * Math.cos(endAngle),
  22199. yOuterEnd = y - outerR * Math.sin(endAngle),
  22200. xInnerStart = x + innerR * Math.cos(endAngle),
  22201. yInnerStart = y - innerR * Math.sin(endAngle),
  22202. xInnerEnd = x + innerR * Math.cos(startAngle),
  22203. yInnerEnd = y - innerR * Math.sin(startAngle);
  22204. 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']]
  22205. },
  22206. prepareSegments: function(params) {
  22207. if (!('x' in params) && !('y' in params) && !('outerRadius' in params) && !('innerRadius' in params) && !('startAngle' in params) && !('endAngle' in params))
  22208. return;
  22209. var x = utils.isNumber(params.x) ? Number(params.x) : 0,
  22210. y = utils.isNumber(params.y) ? Number(params.y) : 0,
  22211. outerR = utils.isNumber(params.outerRadius) ? Number(params.outerRadius) : 0,
  22212. innerR = utils.isNumber(params.innerRadius) ? Number(params.innerRadius) : 0,
  22213. startAngle = utils.isNumber(params.startAngle) ? Number(params.startAngle) : 0,
  22214. endAngle = utils.isNumber(params.endAngle) ? Number(params.endAngle) : 360,
  22215. isCircle;
  22216. this.segments = [['M', 0, 0], ['Z']];
  22217. if (outerR || innerR) {
  22218. var tmp = Math.min(outerR, innerR);
  22219. outerR = Math.max(outerR, innerR);
  22220. innerR = tmp;
  22221. if (Math.round(startAngle) != Math.round(endAngle)) {
  22222. if (Math.abs(endAngle - startAngle) % 360 == 0) {
  22223. startAngle = 0;
  22224. endAngle = 360;
  22225. isCircle = true;
  22226. endAngle -= 0.0001
  22227. }
  22228. if (startAngle > 360)
  22229. startAngle = startAngle % 360;
  22230. if (endAngle > 360)
  22231. endAngle = endAngle % 360;
  22232. if (startAngle > endAngle)
  22233. startAngle -= 360;
  22234. startAngle = startAngle * Math.PI / 180;
  22235. endAngle = endAngle * Math.PI / 180;
  22236. this.segments = this.createArcSegments(x, y, innerR, outerR, startAngle, endAngle, isCircle)
  22237. }
  22238. }
  22239. this.x = params.x;
  22240. this.y = params.y;
  22241. this.outerRadius = params.outerRadius;
  22242. this.innerRadius = params.innerRadius;
  22243. this.startAngle = params.startAngle;
  22244. this.endAngle = params.endAngle;
  22245. delete params.x;
  22246. delete params.y;
  22247. delete params.outerRadius;
  22248. delete params.innerRadius;
  22249. delete params.startAngle;
  22250. delete params.endAngle;
  22251. this.combinePathParams(params)
  22252. },
  22253. animate: function(params) {
  22254. var _this = this;
  22255. if ('x' in params && 'y' in params && 'outerRadius' in params && 'innerRadius' in params && 'startAngle' in params && 'endAngle' in params && this.renderer.animOptions.enabled) {
  22256. var settings = this.settings;
  22257. params.arc = {
  22258. from: {
  22259. x: this.x,
  22260. y: this.y,
  22261. outerRadius: this.outerRadius,
  22262. innerRadius: this.innerRadius,
  22263. startAngle: this.startAngle,
  22264. endAngle: this.endAngle
  22265. },
  22266. to: {
  22267. x: params.x,
  22268. y: params.y,
  22269. outerRadius: params.outerRadius,
  22270. innerRadius: params.innerRadius,
  22271. startAngle: params.startAngle,
  22272. endAngle: params.endAngle
  22273. }
  22274. };
  22275. delete params.d;
  22276. delete params.x;
  22277. delete params.y;
  22278. delete params.outerRadius;
  22279. delete params.innerRadius;
  22280. delete params.startAngle;
  22281. delete params.endAngle
  22282. }
  22283. this.callBase.apply(this, arguments)
  22284. }
  22285. });
  22286. var CircleSvgElement = BaseSvgElement.inherit({
  22287. defaultSettings: function() {
  22288. return {
  22289. cx: 0,
  22290. cy: 0,
  22291. r: 0
  22292. }
  22293. },
  22294. ctor: function(renderer, params) {
  22295. this.callBase(renderer, 'circle', params)
  22296. }
  22297. });
  22298. var TextSvgElement = BaseSvgElement.inherit({
  22299. defaultSettings: function() {
  22300. return {
  22301. x: 0,
  22302. y: 0
  22303. }
  22304. },
  22305. ctor: function(renderer, params) {
  22306. this.tspans = [];
  22307. this.callBase(renderer, 'text', params)
  22308. },
  22309. dispose: function() {
  22310. this.tspans = null;
  22311. this.callBase()
  22312. },
  22313. updateText: function(text) {
  22314. if (!utils.isDefined(text))
  22315. text = '';
  22316. this.applySettings({text: text})
  22317. },
  22318. adjustSettings: function() {
  22319. if (!('text' in this.settings)) {
  22320. this.changeX();
  22321. return
  22322. }
  22323. this._createElementWithText(this.settings.text)
  22324. },
  22325. changeX: function() {
  22326. for (var i = 0; i < this.tspans.length; i++)
  22327. if (this.tspans[i].settings.x != undefined)
  22328. this.tspans[i].applySettings({x: this.settings.x})
  22329. },
  22330. _createElementWithText: function(text) {
  22331. var div,
  22332. i;
  22333. this.clear();
  22334. text = text.toString().replace(/\r/g, "");
  22335. text = text.replace(/\n/g, "<br/>");
  22336. div = doc.createElement("div");
  22337. div.innerHTML = text;
  22338. div.params = {style: {}};
  22339. this._orderText(div)
  22340. },
  22341. clear: function() {
  22342. this.callBase();
  22343. this.tspans = []
  22344. },
  22345. _orderText: function(node) {
  22346. var textArray = [],
  22347. defaultFontSize = (this.settings.font ? this.settings.font.size : 12) || 12;
  22348. var order = function(strCount, node, textArray) {
  22349. var params = {style: {}},
  22350. textArray = textArray || [];
  22351. node.params = node.params || {};
  22352. if (node.parentNode && node.nodeName != "#text")
  22353. if (node.parentNode.params)
  22354. for (var i in node.parentNode.params)
  22355. node.params[i] = node.parentNode.params[i];
  22356. switch (node.tagName) {
  22357. case"B" || "STRONG":
  22358. node.params.fontWeight = "bold";
  22359. break;
  22360. case"I" || "EM":
  22361. node.params.fontStyle = "italic";
  22362. break;
  22363. case"U":
  22364. node.params.textDecoration = "underline";
  22365. break;
  22366. case"BR":
  22367. strCount++;
  22368. break
  22369. }
  22370. if (node.style) {
  22371. if (node.style.fontSize)
  22372. node.params.fontSize = (parseInt(node.style.fontSize) || node.params.fontSize) + "px";
  22373. node.params.fill = node.style.color || node.params.fill;
  22374. node.params.fontStyle = node.style.fontStyle || node.params.fontStyle;
  22375. node.params.fontWeight = node.style.fontWeight || node.params.fontWeight;
  22376. node.params.textDecoration = node.style.textDecoration || node.params.textDecoration
  22377. }
  22378. var childnum = node.childNodes.length;
  22379. var count = 0;
  22380. while (count != childnum)
  22381. strCount = order(strCount, node.childNodes[count++], textArray);
  22382. if (node.wholeText != undefined) {
  22383. params.fill = node.parentNode.params.fill;
  22384. params.text = node.wholeText;
  22385. node.parentNode.params.fontSize && (params.style.fontSize = node.parentNode.params.fontSize);
  22386. node.parentNode.params.fontStyle && (params.style.fontStyle = node.parentNode.params.fontStyle);
  22387. node.parentNode.params.fontWeight && (params.style.fontWeight = node.parentNode.params.fontWeight);
  22388. node.parentNode.params.textDecoration && (params.style.textDecoration = node.parentNode.params.textDecoration);
  22389. textArray.push({
  22390. params: params,
  22391. line: strCount
  22392. })
  22393. }
  22394. return strCount
  22395. };
  22396. order(0, node, textArray);
  22397. for (var txt = 0; txt < textArray.length; txt++) {
  22398. if (txt != 0)
  22399. if (textArray[txt].line != textArray[txt - 1].line) {
  22400. textArray[txt].params.dy = textArray[txt].params.style.fontSize || defaultFontSize;
  22401. textArray[txt].params.x = this.settings.x
  22402. }
  22403. else {
  22404. textArray[txt].params.dy = 0;
  22405. textArray[txt].params.dx = 0
  22406. }
  22407. else {
  22408. textArray[txt].params.x = this.settings.x;
  22409. textArray[txt].params.dy = 0
  22410. }
  22411. var tspan = new TspanSvgElement(this.renderer, textArray[txt].params);
  22412. tspan.append(this);
  22413. this.tspans.push(tspan)
  22414. }
  22415. }
  22416. });
  22417. var TspanSvgElement = BaseSvgElement.inherit({ctor: function(renderer, params) {
  22418. var text = params.text || '';
  22419. delete params.text;
  22420. this.callBase(renderer, 'tspan', params);
  22421. this.element.appendChild(doc.createTextNode(text))
  22422. }});
  22423. var GroupSvgElement = BaseSvgElement.inherit({
  22424. ctor: function(renderer, params) {
  22425. this.callBase(renderer, 'g', params)
  22426. },
  22427. update: $.noop
  22428. });
  22429. var PatternSvgElement = BaseSvgElement.inherit({
  22430. ctor: function(renderer, params) {
  22431. this.__patternParams = $.extend({}, params);
  22432. var id = utils.getNextDefsSvgId(),
  22433. color = params.color,
  22434. hatching = params.hatching,
  22435. opacity = hatching.opacity,
  22436. width = hatching.width || 1,
  22437. step = hatching.step || 6,
  22438. direction = hatching.direction,
  22439. options = {
  22440. strokeWidth: width,
  22441. stroke: color
  22442. };
  22443. this.callBase(renderer, 'pattern', {
  22444. id: id,
  22445. width: step,
  22446. height: step
  22447. });
  22448. this.element.setAttribute('patternUnits', 'userSpaceOnUse');
  22449. this._rect = renderer.createRect(0, 0, step, step, 0, {
  22450. fill: color,
  22451. opacity: opacity
  22452. }).append(this);
  22453. this._path = renderer.createPath(0, options).append(this);
  22454. if (direction === 'right')
  22455. 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});
  22456. else if (direction === 'left')
  22457. 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});
  22458. this.id = getPatternUrl(id, renderer.pathModified)
  22459. },
  22460. append: function() {
  22461. return this.callBase(this.renderer.getDefsSvg())
  22462. },
  22463. clear: function() {
  22464. this.callBase();
  22465. this._path = null
  22466. },
  22467. dispose: function() {
  22468. this._path = null;
  22469. this.callBase()
  22470. }
  22471. });
  22472. var ClipRectSvgElement = BaseSvgElement.inherit({
  22473. ctor: function(renderer, params) {
  22474. this.__clipRectParams = $.extend({}, params);
  22475. var x = params.x,
  22476. y = params.y,
  22477. w = params.w,
  22478. h = params.h,
  22479. id = utils.getNextDefsSvgId();
  22480. delete params.x;
  22481. delete params.y;
  22482. delete params.w;
  22483. delete params.h;
  22484. this.callBase(renderer, 'clipPath', {id: id});
  22485. this.id = id;
  22486. this._rect = renderer.createRect(x, y, w, h, 0, params);
  22487. this._rect.append(this)
  22488. },
  22489. append: function() {
  22490. return this.callBase(this.renderer.getDefsSvg())
  22491. },
  22492. updateRectangle: function(settings) {
  22493. this._rect.applySettings(settings)
  22494. },
  22495. dispose: function() {
  22496. this._rect = null;
  22497. this.callBase()
  22498. }
  22499. });
  22500. var BaseFilterSvgElement = BaseSvgElement.inherit({
  22501. ctor: function(renderer) {
  22502. this.applySettings = $.noop;
  22503. this.callBase(renderer, 'filter');
  22504. delete this.applySettings;
  22505. this.ref = null;
  22506. this._create()
  22507. },
  22508. append: function() {
  22509. return this.callBase(this.renderer.getDefsSvg())
  22510. },
  22511. dispose: function() {
  22512. while (this.element.firstChild)
  22513. this.element.removeChild(this.element.firstChild);
  22514. this.callBase();
  22515. return this
  22516. },
  22517. applySettings: function(settings) {
  22518. settings = settings || {};
  22519. settings.id = utils.getNextDefsSvgId();
  22520. this.$element.attr({
  22521. id: settings.id,
  22522. x: settings.x || null,
  22523. y: settings.y || null,
  22524. width: settings.width || null,
  22525. height: settings.height || null
  22526. });
  22527. this.ref = settings.id ? getPatternUrl(settings.id, this.renderer.pathModified) : null;
  22528. this._update(settings);
  22529. return this
  22530. }
  22531. });
  22532. function setAttributes(element, attr) {
  22533. $.each(attr, function(name, value) {
  22534. element.setAttribute(name, value)
  22535. })
  22536. }
  22537. var ShadowFilterSvgElement = BaseFilterSvgElement.inherit({
  22538. _create: function() {
  22539. var that = this,
  22540. gaussianBlur = that._gaussianBlur = createElement('feGaussianBlur'),
  22541. offset = that._offset = createElement('feOffset'),
  22542. flood = that._flood = createElement('feFlood'),
  22543. composite = that._composite = createElement('feComposite'),
  22544. finalComposite = createElement('feComposite');
  22545. setAttributes(gaussianBlur, {
  22546. 'in': 'SourceGraphic',
  22547. result: 'gaussianBlurResult'
  22548. });
  22549. setAttributes(offset, {
  22550. 'in': 'gaussianBlurResult',
  22551. result: 'offsetResult'
  22552. });
  22553. setAttributes(flood, {result: 'floodResult'});
  22554. setAttributes(composite, {
  22555. 'in': 'floodResult',
  22556. in2: 'offsetResult',
  22557. operator: 'in',
  22558. result: 'compositeResult'
  22559. });
  22560. setAttributes(finalComposite, {
  22561. 'in': 'SourceGraphic',
  22562. in2: 'compositeResult',
  22563. operator: 'over'
  22564. });
  22565. that.element.appendChild(gaussianBlur);
  22566. that.element.appendChild(offset);
  22567. that.element.appendChild(flood);
  22568. that.element.appendChild(composite);
  22569. that.element.appendChild(finalComposite)
  22570. },
  22571. _update: function(settings) {
  22572. setAttributes(this._gaussianBlur, {stdDeviation: settings.blur || 0});
  22573. setAttributes(this._offset, {
  22574. dx: settings.dx || 0,
  22575. dy: settings.dy || 0
  22576. });
  22577. setAttributes(this._flood, {
  22578. 'flood-color': settings.color,
  22579. 'flood-opacity': settings.opacity
  22580. })
  22581. }
  22582. });
  22583. renderers.SvgRenderer = Class.inherit({
  22584. ctor: function(options) {
  22585. var that = this;
  22586. options = options || {};
  22587. that._setAnimationOptions(options.animation || {});
  22588. that.animationController = new renderers.AnimationController;
  22589. that.pathModified = options.pathModified;
  22590. that.rtl = !!options.rtl;
  22591. that.cssClass = options.cssClass || '';
  22592. that.recreateCanvas(options.width, options.height)
  22593. },
  22594. dispose: function() {
  22595. var that = this;
  22596. that.detachContainer();
  22597. that.svgRoot && (that.svgRoot.remove(), that.svgRoot = null);
  22598. that.animationController.dispose();
  22599. that.animOptions = null;
  22600. that.animationController = null
  22601. },
  22602. _setAnimationOptions: function(options) {
  22603. this.animOptions = {
  22604. enabled: true,
  22605. duration: 1000,
  22606. easing: 'easeOutCubic'
  22607. };
  22608. if ('enabled' in options)
  22609. this.animOptions.enabled = options.enabled;
  22610. if ('duration' in options)
  22611. this.animOptions.duration = options.duration;
  22612. if ('easing' in options)
  22613. this.animOptions.easing = options.easing
  22614. },
  22615. animationEnabled: function() {
  22616. return !!this.animOptions.enabled
  22617. },
  22618. updateAnimationOptions: function(newOptions) {
  22619. this._setAnimationOptions($.extend(this.animOptions || {}, newOptions))
  22620. },
  22621. stopAllAnimations: function(lock) {
  22622. lock ? this.animationController.lock() : this.animationController.stop()
  22623. },
  22624. detachContainer: function() {
  22625. var that = this;
  22626. that.svgRoot && that.svgRoot.detach();
  22627. that.defsSvg && (that.defsSvg.remove(), that.defsSvg = null);
  22628. that.drawn = null
  22629. },
  22630. recreateCanvas: function(width, height, cssClass) {
  22631. if (width >= 0 && height >= 0) {
  22632. if (!this.svgRoot) {
  22633. this.cssClass = cssClass || this.cssClass;
  22634. this.svgRoot = new RootSvgElement(this, {
  22635. width: width,
  22636. height: height,
  22637. 'class': this.cssClass,
  22638. direction: this.rtl ? 'rtl' : 'ltr'
  22639. });
  22640. this.animationController.element = this.svgRoot.element
  22641. }
  22642. else
  22643. this.svgRoot.applySettings({
  22644. width: width,
  22645. height: height
  22646. });
  22647. this.defsSvg && this.defsSvg.clear("pattern")
  22648. }
  22649. },
  22650. resize: function(width, height) {
  22651. var root = this.getRoot();
  22652. root && width > 0 && height > 0 && root.applySettings({
  22653. width: width,
  22654. height: height
  22655. })
  22656. },
  22657. getRoot: function() {
  22658. return this.svgRoot
  22659. },
  22660. isInitialized: function() {
  22661. return !!this.svgRoot
  22662. },
  22663. draw: function(container) {
  22664. if (!container || this.drawn)
  22665. return;
  22666. container.appendChild(this.getRoot().element);
  22667. this.drawn = true
  22668. },
  22669. updateParams: function(params, options) {
  22670. if (options && options.strokeWidth)
  22671. params.strokeWidth = options.strokeWidth
  22672. },
  22673. animateElement: function(element, params, options) {
  22674. this.animationController.animateElement(element, params, options)
  22675. },
  22676. createRect: function(x, y, w, h, r, options) {
  22677. var params = {
  22678. x: x,
  22679. y: y,
  22680. width: w,
  22681. height: h,
  22682. rx: r,
  22683. ry: r
  22684. };
  22685. if (options && !options.inh)
  22686. $.extend(params, options);
  22687. this.updateParams(params, options);
  22688. return new RectSvgElement(this, params)
  22689. },
  22690. createSegmentRect: function(x, y, w, h, r, segments, options) {
  22691. var params = $.extend({}, options || {}, {
  22692. x: x,
  22693. y: y,
  22694. width: w,
  22695. height: h,
  22696. rx: r,
  22697. ry: r,
  22698. segments: segments
  22699. });
  22700. return new SegmentRectSvgElement(this, params)
  22701. },
  22702. createClipRect: function(x, y, w, h) {
  22703. var attr = {
  22704. x: x,
  22705. y: y,
  22706. w: w,
  22707. h: h,
  22708. fill: 'none',
  22709. stroke: 'none',
  22710. strokeWidth: 0
  22711. };
  22712. return new ClipRectSvgElement(this, attr)
  22713. },
  22714. createPattern: function(color, hatching) {
  22715. hatching = hatching || {};
  22716. hatching.direction = (hatching.direction || '').toLowerCase();
  22717. if (hatching.direction !== 'right' && hatching.direction !== 'left')
  22718. return {
  22719. id: color,
  22720. append: function() {
  22721. return this
  22722. },
  22723. clear: function(){},
  22724. dispose: function(){}
  22725. };
  22726. return new PatternSvgElement(this, {
  22727. hatching: hatching,
  22728. color: color
  22729. })
  22730. },
  22731. createImage: function(x, y, w, h, href, options) {
  22732. var params = $.extend({}, options || {}, {
  22733. x: x,
  22734. y: y,
  22735. width: w,
  22736. height: h
  22737. });
  22738. return new ImageSvgElement(this, params, href, params.location)
  22739. },
  22740. createLine: function(x1, y1, x2, y2, options) {
  22741. var params = {points: [x1, y1, x2, y2]};
  22742. if (options && !options.inh)
  22743. $.extend(params, options);
  22744. this.updateParams(params, options);
  22745. return new PathSvgElement(this, params)
  22746. },
  22747. createPath: function(points, options) {
  22748. var params = {points: points};
  22749. if (options && !options.inh)
  22750. $.extend(params, options);
  22751. this.updateParams(params, options);
  22752. return new PathSvgElement(this, params)
  22753. },
  22754. createSimplePath: function(options) {
  22755. return new BaseSvgElement(this, 'path', options)
  22756. },
  22757. createBezierPath: function(points, options) {
  22758. var params = {points: points};
  22759. if (options && !options.inh)
  22760. $.extend(params, options);
  22761. this.updateParams(params, options);
  22762. return new BezierSvgElement(this, params)
  22763. },
  22764. createArea: function(points, options) {
  22765. var params = {points: points};
  22766. if (options && !options.inh)
  22767. $.extend(params, options);
  22768. this.updateParams(params, options);
  22769. return new AreaSvgElement(this, params)
  22770. },
  22771. createBezierArea: function(points, options) {
  22772. var params = {points: points};
  22773. if (options && !options.inh)
  22774. $.extend(params, options);
  22775. this.updateParams(params, options);
  22776. return new BezierAreaSvgElement(this, params)
  22777. },
  22778. createCircle: function(x, y, r, options) {
  22779. var params = {
  22780. cx: x,
  22781. cy: y,
  22782. r: r
  22783. };
  22784. if (options && !options.inh)
  22785. $.extend(params, options);
  22786. return new CircleSvgElement(this, params)
  22787. },
  22788. createArc: function(x, y, outerRadius, innerRadius, startAngle, endAngle, options) {
  22789. var params = {
  22790. x: x,
  22791. y: y,
  22792. outerRadius: outerRadius,
  22793. innerRadius: innerRadius,
  22794. startAngle: startAngle,
  22795. endAngle: endAngle
  22796. };
  22797. if (options && !options.inh)
  22798. $.extend(params, options);
  22799. this.updateParams(params, options);
  22800. return new ArcSvgElement(this, params)
  22801. },
  22802. createText: function(text, x, y, options) {
  22803. var params = {
  22804. x: x,
  22805. y: y,
  22806. text: text
  22807. };
  22808. if (options && !options.inh)
  22809. $.extend(params, options);
  22810. return new TextSvgElement(this, params)
  22811. },
  22812. createGroup: function(options) {
  22813. return new GroupSvgElement(this, options)
  22814. },
  22815. createFilter: function(type) {
  22816. var filterType = type === 'shadow' ? ShadowFilterSvgElement : null;
  22817. if (filterType)
  22818. return new filterType(this);
  22819. return null
  22820. },
  22821. getDefsSvg: function() {
  22822. this.defsSvg = this.defsSvg || new BaseSvgElement(this, 'defs').append();
  22823. return this.defsSvg
  22824. },
  22825. svg: function() {
  22826. return this.svgRoot.$element.parent().html()
  22827. }
  22828. });
  22829. function buildPath(points) {
  22830. var i = 0,
  22831. ii = points.length,
  22832. list = [];
  22833. for (; i < ii; )
  22834. list.push('L', points[i++].toFixed(2), points[i++].toFixed(2));
  22835. if (ii) {
  22836. list[0] = 'M';
  22837. list.push('Z');
  22838. list = list.join(' ')
  22839. }
  22840. else
  22841. list = '';
  22842. return list
  22843. }
  22844. function processCircleSettings(x, y, size, borderWidth) {
  22845. var correct = size + ~~borderWidth & 1;
  22846. return {
  22847. cx: correct ? x + 0.5 : x,
  22848. cy: correct ? y + 0.5 : y,
  22849. r: size / 2
  22850. }
  22851. }
  22852. renderers._svgBuildPath = buildPath;
  22853. renderers._svgProcessCircleSettings = processCircleSettings;
  22854. renderers._svgRendererInternals = {
  22855. BaseSvgElement: BaseSvgElement,
  22856. RootSvgElement: RootSvgElement,
  22857. RectSvgElement: RectSvgElement,
  22858. ImageSvgElement: ImageSvgElement,
  22859. PathSvgElement: PathSvgElement,
  22860. AreaSvgElement: AreaSvgElement,
  22861. BezierSvgElement: BezierSvgElement,
  22862. BezierAreaSvgElement: BezierAreaSvgElement,
  22863. CircleSvgElement: CircleSvgElement,
  22864. TextSvgElement: TextSvgElement,
  22865. TspanSvgElement: TspanSvgElement,
  22866. GroupSvgElement: GroupSvgElement,
  22867. ArcSvgElement: ArcSvgElement,
  22868. RectSvgBaseElement: RectSvgBaseElement,
  22869. SegmentRectSvgElement: SegmentRectSvgElement,
  22870. ClipRectSvgElement: ClipRectSvgElement,
  22871. PatternSvgElement: PatternSvgElement,
  22872. ShadowFilterSvgElement: ShadowFilterSvgElement
  22873. }
  22874. })(jQuery, DevExpress);
  22875. /*! Module viz-core, file vmlRenderer.js */
  22876. (function($, DX) {
  22877. var renderers = DX.viz.renderers,
  22878. utils = DX.utils,
  22879. doc = document,
  22880. svgRendererInternals = renderers._svgRendererInternals,
  22881. documentFragment = doc.createDocumentFragment();
  22882. function createVmlElement(nodeName) {
  22883. var element = doc.createElement(nodeName);
  22884. return documentFragment.appendChild(element)
  22885. }
  22886. var appendTimerID;
  22887. var vmlElementsToAppend = [];
  22888. var CSS_PROPERTIES = ['position', 'display', 'visibility', 'filter', 'margin', 'marginTop', 'marginLeft', 'marginRight', 'marginBottom', 'whiteSpace', 'clip', 'overflow'];
  22889. var INHERITABLE_PROPERTIES = ['stroke', 'fill', 'opacity', 'strokeWidth', 'align', 'dashStyle'];
  22890. var defaultVmlSettings = {
  22891. x: 0,
  22892. y: 0,
  22893. width: 1,
  22894. height: 1,
  22895. position: 'absolute',
  22896. behavior: 'url(#default#VML)',
  22897. display: 'inline-block',
  22898. xmlns: "urn:schemas-microsoft-com:vml"
  22899. };
  22900. var CLIP_RECT_CLASS = "dx-vml-clip-rect";
  22901. var extendDefaultVmlOptions = function(customOptions, baseOptions) {
  22902. return $.extend(true, baseOptions || {}, defaultVmlSettings, customOptions)
  22903. };
  22904. var parseRotateParameter = function(rotate, defaultX, defaultY) {
  22905. var rotateObject;
  22906. if (utils.isDefined(rotate))
  22907. if (utils.isNumber(rotate))
  22908. rotateObject = {
  22909. angle: rotate,
  22910. x: defaultX || 0,
  22911. y: defaultY || 0
  22912. };
  22913. else if ($.isArray(rotate))
  22914. rotateObject = {
  22915. angle: rotate[0] || 0,
  22916. x: rotate[1] || 0,
  22917. y: rotate[2] || 0
  22918. };
  22919. else if (utils.isObject(rotate))
  22920. rotateObject = {
  22921. angle: rotate.angle || 0,
  22922. x: rotate.x || 0,
  22923. y: rotate.y || 0
  22924. };
  22925. return rotateObject
  22926. };
  22927. function adjustOpacity(value) {
  22928. return value >= 0.002 ? value : value === null ? 1 : 0.002
  22929. }
  22930. var applySubElementAttribute = function(vmlElement, params, name) {
  22931. var element = vmlElement.element,
  22932. subElement,
  22933. value = params[name];
  22934. if (name === 'opacity' || name === 'fillOpacity')
  22935. if (element.fill)
  22936. element.fill.opacity = adjustOpacity(value);
  22937. if (name === 'joinStyle')
  22938. if (element.stroke)
  22939. element.stroke.joinStyle = value;
  22940. if (name === 'opacity' || name === 'strokeOpacity')
  22941. if (element.stroke)
  22942. element.stroke.opacity = value >= 0.002 ? value : value === null ? 1 : 0.002;
  22943. if (name === 'dashstyle')
  22944. if (element.stroke)
  22945. element.stroke.dashstyle = value
  22946. };
  22947. var getBoundingClientRect = function(element) {
  22948. var i,
  22949. resultRect,
  22950. rect,
  22951. tagName = element.tagName.toLowerCase(),
  22952. points,
  22953. value,
  22954. halfStrokeWidth;
  22955. if (element.className && element.className.indexOf(CLIP_RECT_CLASS) !== -1)
  22956. return;
  22957. if (tagName === 'div') {
  22958. if (element.childNodes.length > 0) {
  22959. resultRect = {};
  22960. for (i = 0; i < element.childNodes.length; i++) {
  22961. rect = getBoundingClientRect(element.childNodes[i]);
  22962. if (!rect)
  22963. continue;
  22964. resultRect.left = resultRect.left === undefined || rect.left < resultRect.left ? rect.left : resultRect.left;
  22965. resultRect.top = resultRect.top === undefined || rect.top < resultRect.top ? rect.top : resultRect.top;
  22966. resultRect.right = resultRect.right === undefined || rect.right > resultRect.right ? rect.right : resultRect.right;
  22967. resultRect.bottom = resultRect.bottom === undefined || rect.bottom > resultRect.bottom ? rect.bottom : resultRect.bottom
  22968. }
  22969. }
  22970. }
  22971. else if (tagName === 'shape' || tagName === 'vml:shape') {
  22972. points = (element.path.value || element.path).match(/[-0-9]+/g);
  22973. resultRect = {};
  22974. rect = element.getBoundingClientRect();
  22975. for (i = 0; i < points.length; i++) {
  22976. value = parseInt(points[i]);
  22977. if (i % 2) {
  22978. resultRect.top = resultRect.top === undefined || value < resultRect.top ? value : resultRect.top;
  22979. resultRect.bottom = resultRect.bottom === undefined || value > resultRect.bottom ? value : resultRect.bottom
  22980. }
  22981. else {
  22982. resultRect.left = resultRect.left === undefined || value < resultRect.left ? value : resultRect.left;
  22983. resultRect.right = resultRect.right === undefined || value > resultRect.right ? value : resultRect.right
  22984. }
  22985. }
  22986. resultRect.left = resultRect.left || 0;
  22987. resultRect.top = resultRect.top || 0;
  22988. resultRect.right = resultRect.right || 0;
  22989. resultRect.bottom = resultRect.bottom || 0;
  22990. if (rect.right - rect.left <= 1 && rect.top - rect.bottom <= 1) {
  22991. resultRect.right = resultRect.right + rect.left;
  22992. resultRect.bottom = resultRect.bottom + rect.top;
  22993. resultRect.left = resultRect.left + rect.left;
  22994. resultRect.top = resultRect.top + rect.top
  22995. }
  22996. else {
  22997. resultRect.right = resultRect.right - resultRect.left + rect.left;
  22998. resultRect.bottom = resultRect.bottom - resultRect.top + rect.top;
  22999. resultRect.left = rect.left;
  23000. resultRect.top = rect.top
  23001. }
  23002. halfStrokeWidth = Math.ceil(parseFloat(element.strokeweight) / 2);
  23003. if (halfStrokeWidth && halfStrokeWidth > 1) {
  23004. resultRect.left -= halfStrokeWidth;
  23005. resultRect.top -= halfStrokeWidth;
  23006. resultRect.right += halfStrokeWidth;
  23007. resultRect.bottom += halfStrokeWidth
  23008. }
  23009. }
  23010. else
  23011. resultRect = element.getBoundingClientRect();
  23012. return resultRect
  23013. };
  23014. var BaseVmlElement = {
  23015. isVml: function() {
  23016. return true
  23017. },
  23018. dispose: function() {
  23019. this.childElements = null;
  23020. this._style = null;
  23021. this._fullSettings = null;
  23022. this.callBase()
  23023. },
  23024. defaultSettings: function(customOptions) {
  23025. return extendDefaultVmlOptions(customOptions, this.callBase ? this.callBase() : {})
  23026. },
  23027. createElement: function(nodeName) {
  23028. this._nodeName = nodeName;
  23029. this.childElements = [];
  23030. this._fullSettings = {};
  23031. if (this.isVml()) {
  23032. var result = createVmlElement('vml:' + nodeName);
  23033. return result
  23034. }
  23035. else
  23036. return doc.createElement(nodeName)
  23037. },
  23038. append: function(element) {
  23039. var toElement = element || this.renderer.getRoot();
  23040. if (toElement) {
  23041. toElement.element.appendChild(this.element);
  23042. toElement.childElements.push(this);
  23043. if (this.parentElement)
  23044. this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
  23045. this.parentElement = toElement
  23046. }
  23047. if (toElement === this.renderer.getRoot() || toElement._isAppended)
  23048. this.appendComplete();
  23049. return this
  23050. },
  23051. insertBefore: function(target) {
  23052. var parent = target.parentElement;
  23053. parent.element.insertBefore(this.element, target.element);
  23054. this.parentElement = parent;
  23055. parent.childElements.splice($.inArray(target, parent.childElements), 0, this);
  23056. parent._isAppended && this.appendComplete();
  23057. return this
  23058. },
  23059. remove: function() {
  23060. this.callBase.apply(this, arguments);
  23061. if (this.parentElement) {
  23062. this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
  23063. this.parentElement = null
  23064. }
  23065. return this
  23066. },
  23067. detach: function() {
  23068. this.callBase.apply(this, arguments);
  23069. this._delayAttributes(['opacity']);
  23070. this._onDetach();
  23071. if (this.parentElement) {
  23072. this.parentElement.childElements.splice($.inArray(this, this.parentElement.childElements), 1);
  23073. this.parentElement = null
  23074. }
  23075. return this
  23076. },
  23077. clear: function() {
  23078. this.callBase.apply(this, arguments);
  23079. $.each(this.childElements, function(_, element) {
  23080. element._delayAttributes(['opacity']);
  23081. element._onDetach();
  23082. element.parentElement = null
  23083. });
  23084. this.childElements = [];
  23085. return this
  23086. },
  23087. applyStyle: function(style) {
  23088. this.callBase(style);
  23089. if (style.opacity)
  23090. this.element.style.opacity = style.opacity;
  23091. if (style.clip)
  23092. try {
  23093. this.element.style.clip = style.clip
  23094. }
  23095. catch(e) {}
  23096. },
  23097. _fillAttributesFromParentAndCurrentStyle: function(attributes) {
  23098. var element = this.element,
  23099. parent = this.parentElement,
  23100. i,
  23101. settingToStyleMap = {strokeWidth: 'stroke-width'},
  23102. propertyName,
  23103. styleName,
  23104. settingsToApply = {};
  23105. if (parent)
  23106. for (i = 0; i < INHERITABLE_PROPERTIES.length; i++) {
  23107. propertyName = INHERITABLE_PROPERTIES[i];
  23108. if (!this.settings[propertyName] && parent._fullSettings[propertyName])
  23109. settingsToApply[propertyName] = parent._fullSettings[propertyName]
  23110. }
  23111. if (element.style && element.currentStyle)
  23112. for (i = 0; i < INHERITABLE_PROPERTIES.length; i++) {
  23113. propertyName = INHERITABLE_PROPERTIES[i];
  23114. styleName = settingToStyleMap[propertyName] || propertyName;
  23115. if (element.currentStyle[styleName])
  23116. settingsToApply[propertyName] = element.currentStyle[styleName]
  23117. }
  23118. $.extend(this._fullSettings, this.settings, settingsToApply);
  23119. if (this.isVml())
  23120. $.extend(attributes, this._normalizeSettings(settingsToApply))
  23121. },
  23122. _applyAttributes: function(params) {
  23123. var name,
  23124. value;
  23125. if (params && params.arcsize !== undefined) {
  23126. try {
  23127. this.element.setAttribute('arcsize', params.arcsize)
  23128. }
  23129. catch(e) {}
  23130. this.__appliedSettings = {arcsize: params.arcsize};
  23131. delete params.arcsize
  23132. }
  23133. if (params && params['class']) {
  23134. this.element.className = params['class'];
  23135. delete params['class']
  23136. }
  23137. if (!this._isAppended)
  23138. this._delayedAttributes = params;
  23139. else {
  23140. params = params || this._delayedAttributes;
  23141. if (params) {
  23142. this._fillAttributesFromParentAndCurrentStyle(params);
  23143. if (this.isVml()) {
  23144. for (name in params) {
  23145. value = params[name];
  23146. if (name === 'opacity' || name === 'fillOpacity' || name === 'strokeOpacity' || name === 'dashstyle' || name === 'joinStyle')
  23147. applySubElementAttribute(this, params, name);
  23148. else
  23149. this.element[name] = value
  23150. }
  23151. $.each(this.element.children, function(_, e) {
  23152. e.style.behavior = 'url(#default#VML)';
  23153. e.style.display = 'inline-block';
  23154. e.xmlns = "urn:schemas-microsoft-com:vml"
  23155. })
  23156. }
  23157. this.__appliedSettings = this.isVml() ? params : {};
  23158. delete this._delayedAttributes
  23159. }
  23160. }
  23161. },
  23162. _onDetach: function() {
  23163. this._isAppended = false;
  23164. $.each(this.childElements, function(_, child) {
  23165. child._onDetach()
  23166. })
  23167. },
  23168. appendComplete: function() {
  23169. if (this.renderer.isElementAppendedToPage(this)) {
  23170. this._isAppended = true;
  23171. this._applyAttributes();
  23172. $.each(this.childElements, function(_, child) {
  23173. child.appendComplete()
  23174. });
  23175. if (this.parentElement instanceof GroupVmlElement && this.parentElement._clipRect && this.parentElement._clipRect !== this)
  23176. if (this.parentElement._clipRect._isAppended)
  23177. this.parentElement._clipRect.toForeground();
  23178. else
  23179. this.parentElement._clipRect.append(this.parentElement)
  23180. }
  23181. else {
  23182. vmlElementsToAppend.push(this);
  23183. $(this.element).data('vmlNeedAppendComplete', true);
  23184. if (appendTimerID === undefined)
  23185. appendTimerID = setTimeout(function() {
  23186. appendTimerID = undefined;
  23187. var vmlElements = vmlElementsToAppend;
  23188. vmlElementsToAppend = [];
  23189. $.each(vmlElements, function() {
  23190. if ($(this.element).data('vmlNeedAppendComplete') && !this._isAppended)
  23191. this.appendComplete()
  23192. })
  23193. }, 200)
  23194. }
  23195. },
  23196. _delayAttributes: function(attributes) {
  23197. var attr,
  23198. val,
  23199. i,
  23200. settings = this.settings || {};
  23201. attributes = attributes || [];
  23202. this._delayedAttributes = this._delayedAttributes || {};
  23203. for (i = 0; i < attributes.length; i++) {
  23204. attr = attributes[i];
  23205. val = settings[attr];
  23206. if (val)
  23207. this._delayedAttributes[attr] = val
  23208. }
  23209. $.each(this.childElements || [], function(_, child) {
  23210. child._delayAttributes(attributes)
  23211. })
  23212. },
  23213. _normalizeSettings: function(settings) {
  23214. var key,
  23215. style = {},
  23216. normalized = {},
  23217. clipRect,
  23218. pos,
  23219. prop,
  23220. value;
  23221. for (key in settings) {
  23222. prop = key;
  23223. value = settings[prop];
  23224. if (prop === 'x' || prop === 'translateX') {
  23225. pos = settings.x || 0;
  23226. if (settings.translateX)
  23227. pos += settings.translateX;
  23228. style.left = pos + 'px'
  23229. }
  23230. else if (prop === 'y' || prop === 'translateY') {
  23231. pos = settings.y || 0;
  23232. if (settings.translateY)
  23233. pos += settings.translateY;
  23234. style.top = pos + 'px'
  23235. }
  23236. else if (prop === 'width')
  23237. style.width = value + 'px';
  23238. else if (prop === "behavior")
  23239. style[prop] = value;
  23240. else if (prop === 'height')
  23241. style.height = value + 'px';
  23242. else if (prop === 'align')
  23243. continue;
  23244. else if (prop === 'scale')
  23245. continue;
  23246. else if ($.inArray(prop, CSS_PROPERTIES) != -1)
  23247. style[prop] = value !== null ? value : '';
  23248. else if (prop === 'font') {
  23249. if (!$.isPlainObject(value))
  23250. continue;
  23251. $.each(value, function(fontSetting) {
  23252. var styleName,
  23253. firstChar;
  23254. switch (fontSetting) {
  23255. case'color':
  23256. styleName = "fill";
  23257. break;
  23258. case'opacity':
  23259. styleName = "opacity";
  23260. break;
  23261. case'cursor':
  23262. styleName = fontSetting;
  23263. break;
  23264. default:
  23265. firstChar = fontSetting.charAt(0);
  23266. styleName = 'font' + fontSetting.replace(firstChar, firstChar.toUpperCase())
  23267. }
  23268. if (styleName)
  23269. style[styleName] = value[fontSetting]
  23270. })
  23271. }
  23272. else if (prop === 'style')
  23273. $.extend(true, style, value);
  23274. else if (prop === 'rotate')
  23275. this['_rotate'] = value;
  23276. else if (prop === 'clipId') {
  23277. clipRect = this.renderer.getClipRect(value, this);
  23278. if (clipRect) {
  23279. var width = clipRect.width,
  23280. height = clipRect.height,
  23281. x = clipRect.x,
  23282. y = clipRect.y,
  23283. clipWidth = width + x,
  23284. clipHeight = height + y,
  23285. canvasSize = this.renderer._getSize();
  23286. style.width = canvasSize.width;
  23287. style.height = canvasSize.height;
  23288. style.clip = "rect(" + y + "px, " + clipWidth + "px, " + clipHeight + "px, " + x + "px)"
  23289. }
  23290. }
  23291. else if (prop === 'segments')
  23292. continue;
  23293. else if (prop === 'fill') {
  23294. normalized.filled = value === 'none' ? 'f' : 't';
  23295. normalized.fillcolor = value === 'grey' ? '#808080' : value
  23296. }
  23297. else if (prop === 'opacity')
  23298. normalized.opacity = value < 0.002 ? value : value;
  23299. else if (prop === 'stroke') {
  23300. normalized.stroked = value === 'none' ? 'f' : 't';
  23301. normalized.strokecolor = value
  23302. }
  23303. else if (prop === 'strokeWidth')
  23304. normalized.strokeweight = value + 'px';
  23305. else if (prop === 'lineJoin')
  23306. normalized.joinStyle = value;
  23307. else if (prop === 'dashStyle') {
  23308. value = (value || "").toLowerCase();
  23309. normalized.dashstyle = value
  23310. }
  23311. else
  23312. normalized[prop] = value
  23313. }
  23314. this['_style'] = style;
  23315. return normalized
  23316. },
  23317. _getBBox: function() {
  23318. var width,
  23319. height,
  23320. rect,
  23321. parentRect,
  23322. x = 0,
  23323. y = 0,
  23324. element = this.element,
  23325. parent;
  23326. try {
  23327. rect = getBoundingClientRect(element);
  23328. width = rect.right - rect.left;
  23329. height = rect.bottom - rect.top;
  23330. parent = this.element.parentNode || this.renderer.getRoot().element;
  23331. parentRect = parent.getBoundingClientRect();
  23332. x = rect.left - parentRect.left;
  23333. y = rect.top - parentRect.top;
  23334. if (element.tagName.toLowerCase() === 'div') {
  23335. x = x - (parseInt(element.style.left, 10) || 0);
  23336. y = y - (parseInt(element.style.top, 10) || 0)
  23337. }
  23338. }
  23339. catch(e) {
  23340. width = element.offsetWidth || 0;
  23341. height = element.offsetHeight || 0
  23342. }
  23343. return {
  23344. x: x,
  23345. y: y,
  23346. width: width,
  23347. height: height,
  23348. isEmpty: !x && !y && !width && !height
  23349. }
  23350. },
  23351. getBBox: function() {
  23352. return this._getBBox()
  23353. },
  23354. sharpEdges: function(){}
  23355. };
  23356. var convertSvgPathCommandToVml = function(command) {
  23357. switch (command) {
  23358. case'M':
  23359. return 'm';
  23360. case'L':
  23361. return 'l';
  23362. case'Z':
  23363. return 'x e'
  23364. }
  23365. return command
  23366. };
  23367. var BasePathVmlElement = {
  23368. defaultSettings: function() {
  23369. return $.extend(this.callBase(), {coordsize: '1,1'})
  23370. },
  23371. getNodeName: function() {
  23372. return 'shape'
  23373. },
  23374. getPathAttributeName: function() {
  23375. return 'path'
  23376. },
  23377. customizeSegments: function(segments) {
  23378. var result = segments;
  23379. if (segments)
  23380. result = $.map(segments, function(s, i) {
  23381. var pos,
  23382. segmentArray = [],
  23383. command = convertSvgPathCommandToVml(s[0]);
  23384. segmentArray.push(command);
  23385. for (pos = 1; pos < s.length; pos++)
  23386. segmentArray.push(Math.floor(s[pos]));
  23387. return [segmentArray]
  23388. });
  23389. return result
  23390. }
  23391. };
  23392. var RootVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  23393. isVml: function() {
  23394. return false
  23395. },
  23396. defaultSettings: function() {
  23397. return {
  23398. width: 0,
  23399. height: 0,
  23400. position: 'relative',
  23401. display: 'inline-block',
  23402. overflow: 'hidden',
  23403. stroke: 'none',
  23404. strokeWidth: 0,
  23405. fill: 'none'
  23406. }
  23407. },
  23408. ctor: function(renderer, params) {
  23409. this.callBase(renderer, 'div', params)
  23410. }
  23411. });
  23412. var ImageVmlElement = svgRendererInternals.BaseSvgElement.inherit(svgRendererInternals.RectSvgBaseElement).inherit(BaseVmlElement).inherit({
  23413. ctor: function(renderer, params) {
  23414. this.callBase(renderer, 'image', params)
  23415. },
  23416. defaultSettings: function() {
  23417. return $.extend(this.callBase(), {
  23418. strokeWidth: 0,
  23419. fill: 'none',
  23420. stroke: 'none'
  23421. })
  23422. },
  23423. adjustSettings: function() {
  23424. var defaultSettings = this.defaultSettings();
  23425. this.callBase();
  23426. if (this.settings.href) {
  23427. this.settings.src = this.settings.href;
  23428. delete this.settings.href
  23429. }
  23430. this.settings.fill = defaultSettings.fill;
  23431. this.settings.stroke = defaultSettings.stroke;
  23432. this.settings.strokeWidth = defaultSettings.strokeWidth
  23433. }
  23434. });
  23435. var RectVmlElement = svgRendererInternals.BaseSvgElement.inherit(svgRendererInternals.RectSvgBaseElement).inherit(BaseVmlElement).inherit({
  23436. defaultSettings: function() {
  23437. return extendDefaultVmlOptions({
  23438. stroked: 'f',
  23439. strokeWidth: 0,
  23440. rx: 0,
  23441. ry: 0
  23442. })
  23443. },
  23444. recreateElement: function(name) {
  23445. this._nodeName = name;
  23446. var parent = this.$element.parent()[0];
  23447. if (parent) {
  23448. var $oldElement = this.$element;
  23449. this.element = this.createElement(name);
  23450. this.$element = $(this.element);
  23451. this.$element.insertBefore($oldElement);
  23452. $oldElement.remove()
  23453. }
  23454. else {
  23455. this.element = this.createElement(name);
  23456. this.$element = $(this.element)
  23457. }
  23458. this.applySettings()
  23459. },
  23460. _adjustArcSize: function() {
  23461. var settings = this.settings;
  23462. var rx = settings.rx || 0,
  23463. ry = settings.ry || 0,
  23464. width = settings.width,
  23465. height = settings.height,
  23466. r,
  23467. halfsize,
  23468. arcsize;
  23469. if (settings.rx !== undefined || settings.ry !== undefined) {
  23470. r = Math.max(rx, ry);
  23471. halfsize = Math.max(width, height) / 2;
  23472. arcsize = r / halfsize;
  23473. settings.arcsize = arcsize;
  23474. if ($.isNumeric(arcsize) && arcsize != 0)
  23475. this._nodeName !== 'roundrect' && this.recreateElement('roundrect');
  23476. else
  23477. this._nodeName === 'roundrect' && this.recreateElement('rect');
  23478. delete settings.rx;
  23479. delete settings.ry
  23480. }
  23481. },
  23482. _adjustRotation: function() {
  23483. var settings = this.settings;
  23484. var rotate = this.settings.rotate,
  23485. rotateAngle,
  23486. radianAngle,
  23487. cos,
  23488. sin,
  23489. rotateX,
  23490. rotateY,
  23491. marginTop,
  23492. marginLeft,
  23493. cx,
  23494. cy,
  23495. rotateObject;
  23496. rotateObject = parseRotateParameter(rotate, settings.x, settings.y);
  23497. if (rotateObject) {
  23498. rotateAngle = rotateObject.angle;
  23499. rotateX = rotateObject.x;
  23500. rotateY = rotateObject.y;
  23501. radianAngle = rotateAngle * Math.PI / 180.0;
  23502. cos = Math.cos(radianAngle);
  23503. sin = Math.sin(radianAngle);
  23504. cx = settings.x + (settings.translateX || 0) + settings.width / 2;
  23505. cy = settings.y + (settings.translateY || 0) + settings.height / 2;
  23506. marginLeft = (cx - rotateX) * cos - (cy - rotateY) * sin + rotateX - cx;
  23507. marginTop = (cx - rotateX) * sin + (cy - rotateY) * cos + rotateY - cy;
  23508. this.settings.marginLeft = Math.round(marginLeft) + 'px';
  23509. this.settings.marginTop = Math.round(marginTop) + 'px';
  23510. this.settings.rotation = rotateAngle
  23511. }
  23512. },
  23513. adjustSettings: function() {
  23514. this.callBase();
  23515. this._adjustArcSize();
  23516. this._adjustRotation()
  23517. },
  23518. ctor: function(renderer, params) {
  23519. this.callBase(renderer, 'rect', params)
  23520. }
  23521. });
  23522. var PathVmlElement = svgRendererInternals.PathSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({prepareSegments: function(settings) {
  23523. var that = this,
  23524. rotate = settings.rotate,
  23525. rotateAngle,
  23526. rotateX,
  23527. rotateY,
  23528. oldSegments,
  23529. radianAngle,
  23530. cos,
  23531. sin,
  23532. x,
  23533. y,
  23534. rotatedX,
  23535. rotatedY,
  23536. rotateObject;
  23537. this.callBase(settings);
  23538. oldSegments = that.segments;
  23539. rotateObject = parseRotateParameter(rotate, settings.x, settings.y);
  23540. if (rotateObject) {
  23541. rotateAngle = rotateObject.angle;
  23542. rotateX = rotateObject.x;
  23543. rotateY = rotateObject.y;
  23544. if (that.segments) {
  23545. radianAngle = rotateAngle * Math.PI / 180.0;
  23546. cos = Math.cos(radianAngle);
  23547. sin = Math.sin(radianAngle);
  23548. that.segments = $.map(that.segments, function(s, i) {
  23549. if (s.length === 3) {
  23550. x = s[1],
  23551. y = s[2];
  23552. rotatedX = (x - rotateX) * cos - (y - rotateY) * sin + rotateX;
  23553. rotatedY = (x - rotateX) * sin + (y - rotateY) * cos + rotateY;
  23554. return [[s[0], Math.floor(rotatedX), Math.floor(rotatedY)]]
  23555. }
  23556. else
  23557. return [s]
  23558. });
  23559. that.combinePathParams(settings);
  23560. that.segments = oldSegments
  23561. }
  23562. }
  23563. }});
  23564. var SimplePathVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  23565. ctor: function(renderer, options) {
  23566. this.callBase(renderer, 'shape', options)
  23567. },
  23568. defaultSettings: function() {
  23569. return extendDefaultVmlOptions({coordsize: '1,1'})
  23570. },
  23571. adjustSettings: function() {
  23572. var settings = this.settings;
  23573. if (settings.d !== undefined) {
  23574. settings.path = settings.d;
  23575. delete settings.d
  23576. }
  23577. }
  23578. });
  23579. var AreaVmlElement = PathVmlElement.inherit({
  23580. defaultSettings: function() {
  23581. var baseOptions = this.callBase();
  23582. return extendDefaultVmlOptions({points: {
  23583. x: 0,
  23584. y: 0
  23585. }}, baseOptions)
  23586. },
  23587. ctor: function(renderer, params) {
  23588. this.closePath = true;
  23589. this.callBase(renderer, params)
  23590. }
  23591. });
  23592. var SegmentRectVmlElement = svgRendererInternals.SegmentRectSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({
  23593. defaultSettings: function() {
  23594. var settings = this.callBase();
  23595. settings.lineJoin = 'miter';
  23596. delete settings.fill;
  23597. delete settings.stroke;
  23598. delete settings.strokecolor;
  23599. delete settings.stroked;
  23600. return settings
  23601. },
  23602. prepareSegments: function() {
  23603. this.callBase();
  23604. this.segments = this.customizeSegments(this.segments);
  23605. this.settings.x = 0;
  23606. this.settings.y = 0;
  23607. this.settings.width = 1;
  23608. this.settings.height = 1
  23609. },
  23610. applySettings: function(settings) {
  23611. var x = settings.x,
  23612. y = settings.y,
  23613. w = settings.width,
  23614. h = settings.height;
  23615. this.callBase(settings);
  23616. this.settings.x = x;
  23617. this.settings.y = y;
  23618. this.settings.width = w;
  23619. this.settings.height = h;
  23620. return this
  23621. }
  23622. });
  23623. var BezierVmlElement = svgRendererInternals.BezierSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement);
  23624. var BezierAreaVmlElement = BezierVmlElement.inherit({
  23625. defaultSettings: function() {
  23626. var baseOptions = this.callBase();
  23627. return extendDefaultVmlOptions({points: {
  23628. x: 0,
  23629. y: 0
  23630. }}, baseOptions)
  23631. },
  23632. ctor: function(renderer, params) {
  23633. this.closePath = true;
  23634. this.callBase(renderer, params)
  23635. }
  23636. });
  23637. var ArcVmlElement = svgRendererInternals.ArcSvgElement.inherit(BaseVmlElement).inherit(BasePathVmlElement).inherit({createArcSegments: function(x, y, innerR, outerR, startAngle, endAngle, isCircle) {
  23638. var xOuterStart = x + outerR * Math.cos(startAngle),
  23639. yOuterStart = y - outerR * Math.sin(startAngle),
  23640. xOuterEnd = x + outerR * Math.cos(endAngle),
  23641. yOuterEnd = y - outerR * Math.sin(endAngle),
  23642. xInnerStart = x + innerR * Math.cos(endAngle),
  23643. yInnerStart = y - innerR * Math.sin(endAngle),
  23644. xInnerEnd = x + innerR * Math.cos(startAngle),
  23645. yInnerEnd = y - innerR * Math.sin(startAngle);
  23646. 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']]
  23647. }});
  23648. var CircleVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  23649. defaultSettings: function() {
  23650. return extendDefaultVmlOptions({
  23651. cx: 0,
  23652. cy: 0,
  23653. r: 0
  23654. })
  23655. },
  23656. applySettings: function(settings) {
  23657. settings.cx = settings.cx || settings.x;
  23658. settings.cy = settings.cy || settings.y;
  23659. return this.callBase(settings)
  23660. },
  23661. adjustSettings: function() {
  23662. var r,
  23663. cx,
  23664. cy;
  23665. if (this.settings.cx !== undefined || this.settings.cy !== undefined || this.settings.r !== undefined) {
  23666. r = 'r' in this.settings ? this.settings.r : this.settings.width / 2;
  23667. cx = 'cx' in this.settings ? this.settings.cx : this.settings.x + this.settings.width / 2;
  23668. cy = 'cy' in this.settings ? this.settings.cy : this.settings.y + this.settings.width / 2;
  23669. this.settings.x = cx - r;
  23670. this.settings.y = cy - r;
  23671. this.settings.width = this.settings.height = r * 2;
  23672. delete this.settings.cx;
  23673. delete this.settings.cy;
  23674. delete this.settings.r
  23675. }
  23676. },
  23677. ctor: function(renderer, params) {
  23678. this.callBase(renderer, 'oval', params)
  23679. }
  23680. });
  23681. var TextVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  23682. isVml: function() {
  23683. return false
  23684. },
  23685. defaultSettings: function() {
  23686. return {
  23687. x: 0,
  23688. y: 0,
  23689. position: 'absolute',
  23690. whiteSpace: 'nowrap'
  23691. }
  23692. },
  23693. ctor: function(renderer, params) {
  23694. this.callBase(renderer, 'span', params)
  23695. },
  23696. adjustSettings: function() {
  23697. var text,
  23698. settings = this.settings;
  23699. if (settings.font) {
  23700. settings.fill = settings.fill || settings.font.color;
  23701. settings.opacity = settings.opacity || settings.font.opacity
  23702. }
  23703. if ('text' in settings) {
  23704. text = utils.isDefined(settings.text) ? settings.text : '';
  23705. text = text.toString().replace(/\r/g, "");
  23706. text = text.replace(/\n/g, "<br/>");
  23707. $(this.element).html(text);
  23708. delete settings.text
  23709. }
  23710. if (this.renderer.rtl)
  23711. $(this.element).css('direction', 'rtl')
  23712. },
  23713. updateText: function(text) {
  23714. this.applySettings({text: utils.isDefined(text) ? text : ''})
  23715. },
  23716. _applyAttributes: function(settings) {
  23717. this.callBase(settings);
  23718. settings = this._fullSettings;
  23719. var rotate = settings.rotate,
  23720. rotateAngle = 0,
  23721. rotateX,
  23722. rotateY,
  23723. cos = 1,
  23724. sin = 0,
  23725. osin = 0,
  23726. ocos = 1,
  23727. angle,
  23728. otg,
  23729. rad,
  23730. y = settings.y + (settings.translateY || 0),
  23731. x = settings.x + (settings.translateX || 0),
  23732. align = settings.align,
  23733. bBox = this.getBBox(),
  23734. style = this._style || {},
  23735. marginLeft = 0,
  23736. marginTop = 0,
  23737. fontHeightOffset,
  23738. alignMultiplier,
  23739. rotateObject,
  23740. textWidth,
  23741. textHeight;
  23742. if (this._oldRotate && !bBox.isEmpty) {
  23743. rad = this._oldRotate.angle * Math.PI / 180.0;
  23744. osin = Math.sin(rad);
  23745. ocos = Math.cos(rad);
  23746. if ((this._oldRotate.angle | 0) % 90 !== 0)
  23747. if ((this._oldRotate.angle | 0) % 45 === 0)
  23748. textWidth = bBox.width,
  23749. textHeight = bBox.height;
  23750. else {
  23751. otg = Math.abs(Math.tan(rad));
  23752. var b = (bBox.width - bBox.height * otg) / (1 - otg * otg);
  23753. var a = bBox.width - b;
  23754. textHeight = Math.abs(a / osin);
  23755. textWidth = Math.abs(b / ocos)
  23756. }
  23757. else {
  23758. textHeight = Math.abs(bBox.height * ocos - bBox.width * osin);
  23759. textWidth = Math.abs(bBox.width * ocos - bBox.height * osin)
  23760. }
  23761. }
  23762. else
  23763. textWidth = bBox.width,
  23764. textHeight = bBox.height;
  23765. this.__textWidth = textWidth;
  23766. this.__textHeight = textHeight;
  23767. if (textHeight || textWidth) {
  23768. rotateObject = parseRotateParameter(rotate, x, y);
  23769. this._oldRotate = rotateObject;
  23770. if (rotateObject) {
  23771. rotateAngle = rotateObject.angle;
  23772. rotateX = rotateObject.x;
  23773. rotateY = rotateObject.y;
  23774. if (Math.abs(rotateAngle) > 360)
  23775. rotateAngle = rotateAngle % 360;
  23776. if (rotateAngle < 0)
  23777. rotateAngle = rotateAngle + 360;
  23778. if (rotateAngle) {
  23779. rad = rotateAngle * Math.PI / 180.0;
  23780. cos = Math.cos(rad);
  23781. sin = Math.sin(rad);
  23782. 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) + ')'
  23783. }
  23784. else {
  23785. style.filter = '';
  23786. this._oldRotate = null
  23787. }
  23788. marginLeft = (x - rotateX) * (cos - 1) - (y - rotateY) * sin;
  23789. marginTop = (x - rotateX) * sin + (y - rotateY) * (cos - 1)
  23790. }
  23791. fontHeightOffset = textHeight * (0.55 + 0.45 / 2);
  23792. if (rotateAngle < 90) {
  23793. marginTop -= fontHeightOffset * cos;
  23794. marginLeft -= (textHeight - fontHeightOffset) * sin
  23795. }
  23796. else if (rotateAngle < 180) {
  23797. marginTop += (textHeight - fontHeightOffset) * cos;
  23798. marginLeft += textWidth * cos - (textHeight - fontHeightOffset) * sin
  23799. }
  23800. else if (rotateAngle < 270) {
  23801. marginTop += (textHeight - fontHeightOffset) * cos + textWidth * sin;
  23802. marginLeft += textWidth * cos + fontHeightOffset * sin
  23803. }
  23804. else {
  23805. marginTop += textWidth * sin - fontHeightOffset * cos;
  23806. marginLeft += fontHeightOffset * sin
  23807. }
  23808. if (rotateAngle && this.renderer.rtl)
  23809. marginLeft -= textWidth - (textHeight * Math.abs(sin) + textWidth * Math.abs(cos));
  23810. alignMultiplier = {
  23811. center: 0.5,
  23812. right: 1
  23813. }[align];
  23814. if (alignMultiplier) {
  23815. marginLeft -= textWidth * alignMultiplier * cos;
  23816. marginTop -= textWidth * alignMultiplier * sin
  23817. }
  23818. style.marginLeft = Math.round(marginLeft) + 'px';
  23819. style.marginTop = Math.round(marginTop) + 'px'
  23820. }
  23821. if (settings.fill && settings.fill !== 'none')
  23822. style.color = settings.fill;
  23823. if (settings.opacity)
  23824. this.element.style.filter = 'alpha(opacity=' + settings.opacity * 100 + ')';
  23825. this.applyStyle(style)
  23826. }
  23827. });
  23828. var GroupVmlElement = svgRendererInternals.BaseSvgElement.inherit(BaseVmlElement).inherit({
  23829. isVml: function() {
  23830. return false
  23831. },
  23832. defaultSettings: function() {
  23833. return {
  23834. x: 0,
  23835. y: 0,
  23836. position: 'absolute'
  23837. }
  23838. },
  23839. ctor: function(renderer, params) {
  23840. this.callBase(renderer, 'div', params)
  23841. },
  23842. adjustSettings: function() {
  23843. if (this.settings.clipId || this._clipRect) {
  23844. var rect = this.renderer.getClipRect(this.settings.clipId, this);
  23845. if (this._clipRect)
  23846. if (rect)
  23847. this._clipRect.applySettings({
  23848. x: rect.x,
  23849. y: rect.y,
  23850. width: rect.width,
  23851. height: rect.height
  23852. });
  23853. else {
  23854. this._clipRect.remove();
  23855. this._clipRect = null
  23856. }
  23857. else
  23858. this._clipRect = this.renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
  23859. fill: "none",
  23860. opacity: 0.002,
  23861. "class": CLIP_RECT_CLASS
  23862. });
  23863. if (this._clipRect)
  23864. this.childElements.length && this._clipRect.append(this)
  23865. }
  23866. },
  23867. applySettings: function(settings) {
  23868. var rotate;
  23869. settings = settings || {};
  23870. rotate = settings.rotate;
  23871. if (rotate) {
  23872. if (utils.isNumber(rotate))
  23873. rotate = [rotate, settings.x || 0, settings.y || 0];
  23874. $.each(this.childElements, function(_, child) {
  23875. child.applySettings({rotate: rotate})
  23876. })
  23877. }
  23878. delete settings.rotate;
  23879. delete settings.x;
  23880. delete settings.y;
  23881. this.callBase(settings);
  23882. $.each(this.childElements || [], function(_, c) {
  23883. c.applySettings({})
  23884. });
  23885. return this
  23886. },
  23887. getBBox: function() {
  23888. return this._getBBox()
  23889. },
  23890. update: function() {
  23891. if (this.settings.clipId) {
  23892. var bbox = this.getBBox();
  23893. this.applyStyle({
  23894. left: bbox.x + (this.settings.translateX || 0),
  23895. right: bbox.y + (this.settings.translateY || 0),
  23896. width: bbox.width,
  23897. height: bbox.height
  23898. })
  23899. }
  23900. }
  23901. });
  23902. renderers.VmlRenderer = renderers.SvgRenderer.inherit({
  23903. ctor: function(options) {
  23904. options = options || {};
  23905. options.animation = {enabled: false};
  23906. if (doc.namespaces && !doc.namespaces.vml) {
  23907. doc.namespaces.add('vml', 'urn:schemas-microsoft-com:vml');
  23908. var cssText = 'vml\\:fill, vml\\:path, vml\\:shape, vml\\:stroke, vml\\:rect, vml\\:oval' + '{ behavior:url(#default#VML); display: inline-block; };';
  23909. try {
  23910. doc.createStyleSheet().cssText = cssText
  23911. }
  23912. catch(e) {
  23913. doc.styleSheets[0].cssText += cssText
  23914. }
  23915. }
  23916. this._clipRects = {};
  23917. this.cssClass = options.cssClass || '';
  23918. this.callBase(options)
  23919. },
  23920. dispose: function() {
  23921. this.callBase();
  23922. this._clipRects = null;
  23923. this._size = null
  23924. },
  23925. updateAnimationOptions: $.noop,
  23926. draw: function(container) {
  23927. var root = this.getRoot();
  23928. this.callBase(container);
  23929. if (root)
  23930. root.appendComplete()
  23931. },
  23932. recreateCanvas: function(width, height, cssClass) {
  23933. if (width >= 0 && height >= 0) {
  23934. this._size = {
  23935. width: width,
  23936. height: height
  23937. };
  23938. if (!this.svgRoot) {
  23939. this.cssClass = cssClass || this.cssClass;
  23940. this.svgRoot = new RootVmlElement(this, {
  23941. width: width,
  23942. height: height,
  23943. 'class': this.cssClass
  23944. })
  23945. }
  23946. else
  23947. this.svgRoot.applySettings({
  23948. width: width,
  23949. height: height
  23950. });
  23951. this.defsSvg && this.defsSvg.clear()
  23952. }
  23953. },
  23954. _getSize: function() {
  23955. return this._size || {}
  23956. },
  23957. isElementAppendedToPage: function(element) {
  23958. return $(element.element).closest(doc.documentElement).length
  23959. },
  23960. createRect: function(x, y, w, h, r, options) {
  23961. var params = $.extend(true, {}, options || {}, {
  23962. x: x,
  23963. y: y,
  23964. width: w,
  23965. height: h,
  23966. rx: r,
  23967. ry: r
  23968. });
  23969. return new RectVmlElement(this, params)
  23970. },
  23971. createSegmentRect: function(x, y, w, h, r, segments, options) {
  23972. var params = $.extend({}, options || {}, {
  23973. x: x,
  23974. y: y,
  23975. width: w,
  23976. height: h,
  23977. rx: r,
  23978. ry: r,
  23979. segments: segments
  23980. });
  23981. return new SegmentRectVmlElement(this, params)
  23982. },
  23983. createClipRect: function(x, y, width, height) {
  23984. var clipId = utils.getNextDefsSvgId(),
  23985. elements = [],
  23986. clipRect = {
  23987. id: clipId,
  23988. x: x,
  23989. y: y,
  23990. width: width,
  23991. height: height,
  23992. addElement: function(element) {
  23993. var hasElement = false;
  23994. $.each(elements, function() {
  23995. if (this === element) {
  23996. hasElement = true;
  23997. return false
  23998. }
  23999. });
  24000. if (!hasElement)
  24001. elements.push(element)
  24002. },
  24003. append: function() {
  24004. return this
  24005. },
  24006. remove: function(){},
  24007. dispose: function(){},
  24008. updateRectangle: function(settings) {
  24009. if ('x' in settings)
  24010. this.x = settings.x;
  24011. if ('translateX' in settings)
  24012. this.x += settings.translateX;
  24013. if ('y' in settings)
  24014. this.y = settings.y;
  24015. if ('translateY' in settings)
  24016. this.y += settings.translateY;
  24017. if ('width' in settings)
  24018. this.width = settings.width;
  24019. if ('height' in settings)
  24020. this.height = settings.height;
  24021. $.each(elements, function() {
  24022. this.applySettings({clipId: clipId})
  24023. });
  24024. return this
  24025. }
  24026. };
  24027. this._clipRects[clipId] = clipRect;
  24028. return clipRect
  24029. },
  24030. getClipRect: function(clipId, element) {
  24031. var clipRect = this._clipRects[clipId];
  24032. if (clipRect && element)
  24033. clipRect.addElement(element);
  24034. return this._clipRects[clipId]
  24035. },
  24036. createImage: function(x, y, w, h, href, options) {
  24037. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  24038. x: x,
  24039. y: y,
  24040. width: w,
  24041. height: h,
  24042. href: href
  24043. });
  24044. return new ImageVmlElement(this, params)
  24045. },
  24046. createLine: function(x1, y1, x2, y2, options) {
  24047. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: [x1, y1, x2, y2]});
  24048. return new PathVmlElement(this, params)
  24049. },
  24050. createPath: function(points, options) {
  24051. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  24052. return new PathVmlElement(this, params)
  24053. },
  24054. createSimplePath: function(options) {
  24055. return new SimplePathVmlElement(this, options)
  24056. },
  24057. createBezierPath: function(points, options) {
  24058. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  24059. return new BezierVmlElement(this, params)
  24060. },
  24061. createArea: function(points, options) {
  24062. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  24063. return new AreaVmlElement(this, params)
  24064. },
  24065. createBezierArea: function(points, options) {
  24066. var params = $.extend(true, {}, options && !options.inh ? options : {}, {points: points});
  24067. return new BezierAreaVmlElement(this, params)
  24068. },
  24069. createCircle: function(x, y, r, options) {
  24070. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  24071. cx: x,
  24072. cy: y,
  24073. r: r
  24074. });
  24075. return new CircleVmlElement(this, params)
  24076. },
  24077. createArc: function(x, y, outerRadius, innerRadius, startAngle, endAngle, options) {
  24078. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  24079. x: x,
  24080. y: y,
  24081. outerRadius: outerRadius,
  24082. innerRadius: innerRadius,
  24083. startAngle: startAngle,
  24084. endAngle: endAngle
  24085. });
  24086. return new ArcVmlElement(this, params)
  24087. },
  24088. createText: function(text, x, y, options) {
  24089. var params = $.extend(true, {}, options && !options.inh ? options : {}, {
  24090. x: x,
  24091. y: y,
  24092. text: text
  24093. });
  24094. return new TextVmlElement(this, params)
  24095. },
  24096. createGroup: function(options) {
  24097. return new GroupVmlElement(this, options)
  24098. },
  24099. createPattern: function(color, hatching) {
  24100. return {
  24101. id: color,
  24102. append: function() {
  24103. return this
  24104. },
  24105. clear: function(){},
  24106. dispose: function(){}
  24107. }
  24108. },
  24109. createFilter: function(type) {
  24110. if (type === 'shadow')
  24111. return {
  24112. ref: null,
  24113. append: function() {
  24114. return this
  24115. },
  24116. dispose: function() {
  24117. return this
  24118. },
  24119. applySettings: function() {
  24120. return this
  24121. }
  24122. };
  24123. return null
  24124. },
  24125. svg: function() {
  24126. return ''
  24127. }
  24128. });
  24129. function buildPath(points) {
  24130. var i = 0,
  24131. ii = points.length,
  24132. list = [];
  24133. for (; i < ii; )
  24134. list.push('l', points[i++].toFixed(0), points[i++].toFixed(0));
  24135. if (ii) {
  24136. list[0] = 'm';
  24137. list.push('x e');
  24138. list = list.join(' ')
  24139. }
  24140. else
  24141. list = '';
  24142. return list
  24143. }
  24144. function processCircleSettings(x, y, size) {
  24145. return {
  24146. cx: x,
  24147. cy: y,
  24148. r: size / 2
  24149. }
  24150. }
  24151. renderers._vmlBuildPath = buildPath;
  24152. renderers._vmlProcessCircleSettings = processCircleSettings;
  24153. renderers.__vmlRendererInternals = {
  24154. RootVmlElement: RootVmlElement,
  24155. RectVmlElement: RectVmlElement,
  24156. ImageVmlElement: ImageVmlElement,
  24157. PathVmlElement: PathVmlElement,
  24158. AreaVmlElement: AreaVmlElement,
  24159. BezierVmlElement: BezierVmlElement,
  24160. BezierAreaVmlElement: BezierAreaVmlElement,
  24161. SimplePathVmlElement: SimplePathVmlElement,
  24162. CircleVmlElement: CircleVmlElement,
  24163. TextVmlElement: TextVmlElement,
  24164. GroupVmlElement: GroupVmlElement,
  24165. ArcVmlElement: ArcVmlElement,
  24166. SegmentRectVmlElement: SegmentRectVmlElement
  24167. }
  24168. })(jQuery, DevExpress);
  24169. /*! Module viz-core, file renderer.js */
  24170. (function($, DX) {
  24171. var renderers = DX.viz.renderers,
  24172. browser = DX.browser;
  24173. function isSvg() {
  24174. return !(browser.msie && browser.version < 9) || !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', "svg").createSVGRect
  24175. }
  24176. if (!isSvg()) {
  24177. renderers.Renderer = renderers.VmlRenderer;
  24178. renderers.buildPath = renderers._vmlBuildPath;
  24179. renderers.processCircleSettings = renderers._vmlProcessCircleSettings
  24180. }
  24181. else {
  24182. renderers.Renderer = renderers.SvgRenderer;
  24183. renderers.buildPath = renderers._svgBuildPath;
  24184. renderers.processCircleSettings = renderers._svgProcessCircleSettings
  24185. }
  24186. renderers.isSvg = isSvg
  24187. })(jQuery, DevExpress);
  24188. /*! Module viz-core, file animation.js */
  24189. (function(DX) {
  24190. var renderers = DX.viz.renderers,
  24191. Class = DX.Class,
  24192. noop = function(){},
  24193. easingFunctions = {
  24194. easeOutCubic: function(pos, start, end) {
  24195. return pos === 1 ? end : (1 - Math.pow(1 - pos, 3)) * (end - start) + +start
  24196. },
  24197. linear: function(pos, start, end) {
  24198. return pos === 1 ? end : pos * (end - start) + +start
  24199. }
  24200. };
  24201. renderers.easingFunctions = easingFunctions;
  24202. renderers.animationSvgStep = {
  24203. points: function(elem, params, progress, easing, currentParams) {
  24204. var from = params.from,
  24205. to = params.to,
  24206. path = [],
  24207. i,
  24208. j,
  24209. seg,
  24210. d;
  24211. for (i = 0; i < from.length; i++) {
  24212. seg = [from[i][0]];
  24213. if (from[i].length > 1)
  24214. for (j = 1; j < from[i].length; j++)
  24215. seg.push(easing(progress, from[i][j], to[i][j]));
  24216. path[i] = seg.join(' ')
  24217. }
  24218. d = path.join(' ');
  24219. currentParams.d = params.end && progress === 1 ? params.end : d;
  24220. elem.element.setAttribute('d', d)
  24221. },
  24222. arc: function(elem, params, progress, easing) {
  24223. var from = params.from,
  24224. to = params.to,
  24225. current = {};
  24226. for (var i in from)
  24227. current[i] = easing(progress, from[i], to[i]);
  24228. elem.applySettings(current)
  24229. },
  24230. transform: function(elem, params, progress, easing, currentParams) {
  24231. var translate = params.translate,
  24232. rotate = params.rotate,
  24233. scale = params.scale,
  24234. transformations = [],
  24235. elemSettings = elem.settings;
  24236. if (translate) {
  24237. currentParams.translateX = easing(progress, translate.x.from, translate.x.to);
  24238. currentParams.translateY = easing(progress, translate.y.from, translate.y.to);
  24239. transformations.push('translate(' + currentParams.translateX + ',' + currentParams.translateY + ')')
  24240. }
  24241. else if (elemSettings.translateX || elemSettings.translateY)
  24242. transformations.push('translate(' + (elemSettings.translateX || 0) + ',' + (elemSettings.translateY || 0) + ')');
  24243. if (rotate) {
  24244. currentParams.rotate = {
  24245. angle: easing(progress, rotate.angle.from, rotate.angle.to),
  24246. x: rotate.x,
  24247. y: rotate.y
  24248. };
  24249. transformations.push('rotate(' + currentParams.rotate.angle + ',' + rotate.x + ',' + rotate.y + ')')
  24250. }
  24251. else if (elemSettings.rotate)
  24252. transformations.push('rotate(' + elemSettings.rotate.angle + ',' + (elemSettings.rotate.x || 0) + ',' + (elemSettings.rotate.y || 0) + ')');
  24253. if (scale) {
  24254. currentParams.scale = {
  24255. x: easing(progress, scale.x.from, scale.x.to),
  24256. y: easing(progress, scale.y.from, scale.y.to)
  24257. };
  24258. transformations.push('scale(' + currentParams.scale.x + ',' + currentParams.scale.y + ')')
  24259. }
  24260. else if (elemSettings.scale)
  24261. transformations.push('scale(' + elemSettings.scale.x + ',' + elemSettings.scale.y + ')');
  24262. elem.element.setAttribute('transform', transformations.join())
  24263. },
  24264. base: function(elem, params, progress, easing, currentParams, attributeName) {
  24265. currentParams[attributeName] = easing(progress, params.from, params.to);
  24266. elem.element.setAttribute(attributeName, currentParams[attributeName])
  24267. },
  24268. _: noop,
  24269. complete: function(element, currentSettings) {
  24270. element.applySettings(currentSettings)
  24271. }
  24272. };
  24273. var Animation = Class.inherit({
  24274. ctor: function(element, params, options) {
  24275. var that = this;
  24276. that._progress = 0;
  24277. that.element = element;
  24278. that.params = params;
  24279. that.options = options;
  24280. that.duration = options.partitionDuration ? options.duration * options.partitionDuration : options.duration;
  24281. that._animateStep = options.animateStep || renderers.animationSvgStep;
  24282. that._easing = easingFunctions[options.easing] || easingFunctions['easeOutCubic'];
  24283. that._currentParams = {};
  24284. that.tick = that._start
  24285. },
  24286. _calcProgress: function(now) {
  24287. return Math.min(1, (now - this._startTime) / this.duration)
  24288. },
  24289. _step: function(now) {
  24290. var that = this,
  24291. animateStep = that._animateStep,
  24292. attrName;
  24293. that._progress = that._calcProgress(now);
  24294. for (attrName in that.params) {
  24295. if (!that.params.hasOwnProperty(attrName))
  24296. continue;
  24297. var anim = animateStep[attrName] || animateStep.base;
  24298. anim(that.element, that.params[attrName], that._progress, that._easing, that._currentParams, attrName)
  24299. }
  24300. that.options.step && that.options.step(that._easing(that._progress, 0, 1), that._progress);
  24301. if (that._progress === 1)
  24302. return that.stop();
  24303. return true
  24304. },
  24305. _start: function(now) {
  24306. this._startTime = now;
  24307. this.tick = this._step;
  24308. return true
  24309. },
  24310. _end: function(disableComplete) {
  24311. var that = this;
  24312. that.stop = noop;
  24313. that.tick = noop;
  24314. that._animateStep.complete && that._animateStep.complete(that.element, that._currentParams);
  24315. that.options.complete && !disableComplete && that.options.complete()
  24316. },
  24317. tick: function(now) {
  24318. return true
  24319. },
  24320. stop: function(breakAnimation, disableComplete) {
  24321. var options = this.options;
  24322. if (!breakAnimation && options.repeatCount && --options.repeatCount > 0) {
  24323. this.tick = this._start;
  24324. return true
  24325. }
  24326. else
  24327. this._end(disableComplete)
  24328. }
  24329. });
  24330. renderers.AnimationController = Class.inherit(function() {
  24331. var FPS = 1000 / 60,
  24332. requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) {
  24333. setTimeout(callback, FPS)
  24334. };
  24335. return {
  24336. ctor: function() {
  24337. var that = this;
  24338. that.requestAnimationFrame = requestAnimationFrame;
  24339. that._animationCount = 0;
  24340. that._timerId = null;
  24341. that._animations = {}
  24342. },
  24343. _loop: function() {
  24344. var that = this,
  24345. animations = that._animations,
  24346. activeAnimation = 0,
  24347. now = (new Date).getTime(),
  24348. an;
  24349. for (an in animations) {
  24350. if (!animations.hasOwnProperty(an))
  24351. continue;
  24352. if (!animations[an].tick(now))
  24353. delete animations[an];
  24354. activeAnimation++
  24355. }
  24356. if (activeAnimation === 0) {
  24357. that.stop();
  24358. return
  24359. }
  24360. that._timerId = that.requestAnimationFrame.call(null, function() {
  24361. that._loop()
  24362. }, that.element)
  24363. },
  24364. addAnimation: function(animation) {
  24365. var that = this;
  24366. that._animations[that._animationCount++] = animation;
  24367. if (!that._timerId) {
  24368. clearTimeout(that._startDelay);
  24369. that._startDelay = setTimeout(function() {
  24370. that._timerId = 1;
  24371. that._loop()
  24372. }, 0)
  24373. }
  24374. },
  24375. animateElement: function(elem, params, options) {
  24376. if (elem && params && options) {
  24377. elem.animation && elem.animation.stop(true);
  24378. this.addAnimation(elem.animation = new Animation(elem, params, options))
  24379. }
  24380. },
  24381. dispose: function() {
  24382. this.stop();
  24383. this.element = null
  24384. },
  24385. stop: function() {
  24386. this._animations = {};
  24387. this._animationCount = 0;
  24388. clearTimeout(this._startDelay);
  24389. this._timerId = null
  24390. },
  24391. lock: function() {
  24392. var animations = this._animations;
  24393. for (var an in animations)
  24394. animations.hasOwnProperty(an) && animations[an].stop(true, true);
  24395. this.stop()
  24396. }
  24397. }
  24398. }());
  24399. renderers.Animation = Animation;
  24400. renderers.noop = noop
  24401. })(DevExpress);
  24402. /*! Module viz-core, file namespaces.js */
  24403. (function(DevExpress) {
  24404. DevExpress.viz.charts = {series: {}}
  24405. })(DevExpress);
  24406. /*! Module viz-core, file chartsConsts.js */
  24407. (function(DX) {
  24408. DX.viz.charts.consts = {
  24409. dataTypes: {
  24410. STRING: 'string',
  24411. NUMERIC: 'numeric',
  24412. DATETIME: 'datetime'
  24413. },
  24414. axisTypes: {
  24415. DISCRETE: 'discrete',
  24416. CONTINUOUS: 'continuous',
  24417. LOGARITHMIC: 'logarithmic'
  24418. }
  24419. }
  24420. })(DevExpress);
  24421. /*! Module viz-core, file dataValidator.js */
  24422. (function($, DX) {
  24423. var viz = DX.viz,
  24424. parseUtils = new viz.core.ParseUtils,
  24425. chartConst = viz.charts.consts,
  24426. dataTypes = chartConst.dataTypes,
  24427. axisTypes = chartConst.axisTypes,
  24428. utils = DX.utils,
  24429. _each = $.each,
  24430. _isDefined = utils.isDefined;
  24431. var mergeSort = function(data, field) {
  24432. function merge_sort(array, low, high, field) {
  24433. if (low < high) {
  24434. var mid = Math.floor((low + high) / 2);
  24435. merge_sort(array, low, mid, field);
  24436. merge_sort(array, mid + 1, high, field);
  24437. merge(array, low, mid, high, field)
  24438. }
  24439. }
  24440. var n = data.length;
  24441. merge_sort(data, 0, n - 1, field);
  24442. return data
  24443. };
  24444. var merge = function(array, low, mid, high, field) {
  24445. var newArray = new Array(high - low + 1),
  24446. countL = low,
  24447. countR = mid + 1,
  24448. k,
  24449. i = 0;
  24450. while (countL <= mid && countR <= high) {
  24451. if (array[countL][field] <= array[countR][field] || !_isDefined(array[countR][field])) {
  24452. newArray[i] = array[countL];
  24453. countL++
  24454. }
  24455. else {
  24456. newArray[i] = array[countR];
  24457. countR++
  24458. }
  24459. i++
  24460. }
  24461. if (countL > mid)
  24462. for (k = countR; k <= high; k++, i++)
  24463. newArray[i] = array[k];
  24464. else
  24465. for (k = countL; k <= mid; k++, i++)
  24466. newArray[i] = array[k];
  24467. for (k = 0; k <= high - low; k++)
  24468. array[k + low] = newArray[k];
  24469. return array
  24470. };
  24471. viz.charts.DataValidator = DX.Class.inherit({
  24472. ctor: function(data, groups, incidentOccured, dataPrepareOptions) {
  24473. var that = this;
  24474. groups = groups || [[]];
  24475. if (!data)
  24476. that._nullData = true;
  24477. that.groups = groups;
  24478. that.data = data || [];
  24479. that._parsers = {};
  24480. that._errorShowList = {};
  24481. that._skipFields = {};
  24482. that.options = dataPrepareOptions || {};
  24483. that.incidentOccured = incidentOccured;
  24484. that.userArgumentCategories = that.groups.length && that.groups[0].length && that.groups[0][0].getArgumentCategories();
  24485. if (!incidentOccured)
  24486. that.incidentOccured = $.noop
  24487. },
  24488. validate: function validate() {
  24489. var that = this;
  24490. that._data = that.data;
  24491. if (!utils.isArray(that.data) || that._nullData)
  24492. that._incorrectDataMessage();
  24493. that.groups.argumentType = null;
  24494. that.groups.argumentAxisType = null;
  24495. $.each(that.groups, function(_, group) {
  24496. group.valueType = null;
  24497. group.valueAxisType = null;
  24498. $.each(group, function(_, series) {
  24499. series.updateDataType({})
  24500. })
  24501. });
  24502. that._checkType();
  24503. that._checkAxisType();
  24504. if (that.options.convertToAxisDataType) {
  24505. that._createParser();
  24506. that._parse()
  24507. }
  24508. that._groupData();
  24509. that._sort();
  24510. $.each(that._skipFields, function(field, fieldValue) {
  24511. if (fieldValue === that._data.length)
  24512. that.incidentOccured("W2002", [field])
  24513. });
  24514. return that._data
  24515. },
  24516. _checkType: function _checkType() {
  24517. var that = this,
  24518. groupsWithUndefinedValueType = [],
  24519. groupsWithUndefinedArgumentType = [],
  24520. checkValueTypeOfGroup = function checkValueTypeOfGroup(group, cell) {
  24521. $.each(group, function(_, series) {
  24522. $.each(series.getValueFields(), function(_, field) {
  24523. group.valueType = that._getType(cell[field], group.valueType)
  24524. })
  24525. });
  24526. if (group.valueType)
  24527. return true
  24528. },
  24529. checkArgumentTypeOfGroup = function checkArgumentTypeOfGroup(group, cell) {
  24530. $.each(group, function(_, series) {
  24531. that.groups.argumentType = that._getType(cell[series.getArgumentField()], that.groups.argumentType)
  24532. });
  24533. if (that.groups.argumentType)
  24534. return true
  24535. };
  24536. $.each(that.groups, function(_, group) {
  24537. if (!group.length)
  24538. return null;
  24539. var options = group[0].getOptions(),
  24540. valueTypeGroup = options.valueType,
  24541. argumentTypeGroup = options.argumentType;
  24542. group.valueType = valueTypeGroup;
  24543. that.groups.argumentType = argumentTypeGroup;
  24544. valueTypeGroup ? null : groupsWithUndefinedValueType.push(group);
  24545. argumentTypeGroup ? null : groupsWithUndefinedArgumentType.push(group)
  24546. });
  24547. if (groupsWithUndefinedValueType.length || groupsWithUndefinedArgumentType.length)
  24548. $.each(that.data, function(_, cell) {
  24549. var define = true;
  24550. if (!utils.isObject(cell))
  24551. return;
  24552. $.each(groupsWithUndefinedValueType, function(index, group) {
  24553. define = define && checkValueTypeOfGroup(group, cell)
  24554. });
  24555. $.each(groupsWithUndefinedArgumentType, function(index, group) {
  24556. define = define && checkArgumentTypeOfGroup(group, cell)
  24557. });
  24558. if (!that.options.checkTypeForAllData && define)
  24559. return false
  24560. })
  24561. },
  24562. _checkAxisType: function _checkAxisType() {
  24563. var that = this;
  24564. $.each(that.groups, function(_, group) {
  24565. $.each(group, function(_, series) {
  24566. var optionsSeries = {},
  24567. existingSeriesOptions = series.getOptions();
  24568. optionsSeries.argumentAxisType = that._correctAxisType(that.groups.argumentType, existingSeriesOptions.argumentAxisType, !!that.userArgumentCategories.length);
  24569. optionsSeries.valueAxisType = that._correctAxisType(group.valueType, existingSeriesOptions.valueAxisType, !!series.getValueCategories().length);
  24570. that.groups.argumentAxisType = that.groups.argumentAxisType || optionsSeries.argumentAxisType;
  24571. group.valueAxisType = group.valueAxisType || optionsSeries.valueAxisType;
  24572. optionsSeries.argumentType = that.groups.argumentType;
  24573. optionsSeries.valueType = group.valueType;
  24574. series.updateDataType(optionsSeries)
  24575. })
  24576. })
  24577. },
  24578. _createParser: function _createParser() {
  24579. var that = this;
  24580. $.each(that.groups, function(index, group) {
  24581. $.each(group, function(_, series) {
  24582. that._parsers[series.getArgumentField()] = that._createParserUnit(that.groups.argumentType, that.groups.argumentAxisType === axisTypes.LOGARITHMIC ? that._filterForLogAxis : null);
  24583. $.each(series.getValueFields(), function(_, field) {
  24584. that._parsers[field] = that._createParserUnit(group.valueType, group.valueAxisType === axisTypes.LOGARITHMIC ? that._filterForLogAxis : null, series.getOptions().ignoreEmptyPoints)
  24585. });
  24586. if (series.getTagField())
  24587. that._parsers[series.getTagField()] = null
  24588. })
  24589. })
  24590. },
  24591. _parse: function _parse() {
  24592. var that = this,
  24593. parsedData = [];
  24594. $.each(that.data, function(_, cell) {
  24595. var parserObject = {};
  24596. if (!utils.isObject(cell)) {
  24597. cell && that._incorrectDataMessage();
  24598. return
  24599. }
  24600. $.each(that._parsers, function(field, parser) {
  24601. parserObject[field] = parser ? parser(cell[field], field) : cell[field];
  24602. parserObject['original' + field] = cell[field]
  24603. });
  24604. parsedData.push(parserObject)
  24605. });
  24606. this._data = parsedData
  24607. },
  24608. _groupMinSlices: function(argumentField, valueField, smallValuesGrouping) {
  24609. var that = this,
  24610. smallValuesGrouping = smallValuesGrouping || {},
  24611. mode = smallValuesGrouping.mode,
  24612. count = smallValuesGrouping.topCount,
  24613. threshold = smallValuesGrouping.threshold,
  24614. name = smallValuesGrouping.groupName || 'others',
  24615. others = {},
  24616. data = that._data.slice(),
  24617. index;
  24618. var groupingValues = function(index) {
  24619. if (!_isDefined(index) || index < 0)
  24620. return;
  24621. _each(data.slice(index), function(_, cell) {
  24622. if (!_isDefined(cell[valueField]))
  24623. return;
  24624. others[valueField] += cell[valueField];
  24625. cell[valueField] = undefined;
  24626. cell['original' + valueField] = undefined
  24627. })
  24628. };
  24629. if (!mode || mode === 'none')
  24630. return;
  24631. others[argumentField] = name + '';
  24632. others[valueField] = 0;
  24633. data.sort(function(a, b) {
  24634. if (_isDefined(b[valueField]) && _isDefined(a[valueField]))
  24635. return b[valueField] - a[valueField];
  24636. else if (!_isDefined(b[valueField]) && a[valueField])
  24637. return -1;
  24638. else if (!_isDefined(a[valueField]) && b[valueField])
  24639. return 1
  24640. });
  24641. if (mode === 'smallValueThreshold') {
  24642. _each(data, function(i, cell) {
  24643. if (_isDefined(index) || !_isDefined(cell[valueField]))
  24644. return;
  24645. if (threshold > cell[valueField])
  24646. index = i
  24647. });
  24648. groupingValues(index)
  24649. }
  24650. else if (mode === 'topN')
  24651. groupingValues(count);
  24652. others[valueField] && that._data.push(others)
  24653. },
  24654. _groupData: function() {
  24655. var that = this,
  24656. groups = that.groups,
  24657. isPie = groups.length && groups[0].length && (groups[0][0].type === 'pie' || groups[0][0].type === 'doughnut' || groups[0][0].type === 'donut'),
  24658. argumentField,
  24659. valueFields;
  24660. if (!isPie)
  24661. return;
  24662. _each(groups, function(_, group) {
  24663. _each(group, function(_, series) {
  24664. argumentField = series.getArgumentField();
  24665. valueFields = series.getValueFields();
  24666. if (groups.argumentAxisType === axisTypes.DISCRETE)
  24667. that._groupSameArguments(argumentField, valueFields);
  24668. that._groupMinSlices(argumentField, valueFields[0], series.getOptions().smallValuesGrouping)
  24669. })
  24670. })
  24671. },
  24672. _groupSameArguments: function(argumentField, valueFields) {
  24673. var that = this,
  24674. argument,
  24675. dataOfArguments = {},
  24676. parsedData = that._data;
  24677. _each(parsedData, function(i, cell) {
  24678. if (!_isDefined(cell[argumentField]) || !_isDefined(cell[valueFields[0]]))
  24679. return;
  24680. argument = cell[argumentField];
  24681. if (_isDefined(dataOfArguments[argument])) {
  24682. var data = parsedData[dataOfArguments[argument]];
  24683. _each(valueFields, function(_, field) {
  24684. data[field] += cell[field];
  24685. cell[field] = undefined;
  24686. cell['original' + field] = undefined
  24687. })
  24688. }
  24689. else
  24690. dataOfArguments[argument] = i
  24691. })
  24692. },
  24693. _getType: function _getType(unit, type) {
  24694. if (type === dataTypes.STRING || utils.isString(unit))
  24695. return dataTypes.STRING;
  24696. if (type === dataTypes.DATETIME || utils.isDate(unit))
  24697. return dataTypes.DATETIME;
  24698. if (utils.isNumber(unit))
  24699. return dataTypes.NUMERIC;
  24700. return type
  24701. },
  24702. _correctAxisType: function _correctAxisType(type, axisType, hasCategories) {
  24703. if (type === dataTypes.STRING && (axisType === axisTypes.CONTINUOUS || axisType === axisTypes.LOGARITHMIC))
  24704. this.incidentOccured("E2002");
  24705. if (axisType === axisTypes.LOGARITHMIC)
  24706. return axisTypes.LOGARITHMIC;
  24707. axisType = (hasCategories || axisType === axisTypes.DISCRETE || type === dataTypes.STRING) && axisTypes.DISCRETE;
  24708. return axisType || axisTypes.CONTINUOUS
  24709. },
  24710. _filterForLogAxis: function(val, field) {
  24711. if (val <= 0) {
  24712. this.incidentOccured("E2004", [field]);
  24713. return null
  24714. }
  24715. return val
  24716. },
  24717. _createParserUnit: function _createParserUnit(type, filter, ignoreEmptyPoints) {
  24718. var that = this,
  24719. parser = type ? parseUtils.getParser(type, undefined, true) : function(unit) {
  24720. return unit
  24721. };
  24722. return function(unit, field) {
  24723. var parseUnit = parser(unit);
  24724. if (filter)
  24725. parseUnit = filter.call(that, parseUnit, field);
  24726. parseUnit === null && ignoreEmptyPoints && (parseUnit = undefined);
  24727. if (parseUnit === undefined) {
  24728. that._addSkipFields(field);
  24729. that._validUnit(unit, field, type)
  24730. }
  24731. return parseUnit
  24732. }
  24733. },
  24734. _validUnit: function _validUnit(unit, field, type) {
  24735. if (!unit)
  24736. return;
  24737. if (!utils.isNumber(unit) && !utils.isDate(unit) && !utils.isString(unit)) {
  24738. this.incidentOccured("E2003", [field]);
  24739. return
  24740. }
  24741. this.incidentOccured("E2004", [field])
  24742. },
  24743. _sort: function _sort() {
  24744. var that = this,
  24745. groups = that.groups,
  24746. hash = {},
  24747. argumentField = groups.length && groups[0].length && groups[0][0].getArgumentField();
  24748. if (utils.isFunction(that.options.sortingMethod))
  24749. that._data.sort(that.options.sortingMethod);
  24750. else if (that.userArgumentCategories.length) {
  24751. $.each(that.userArgumentCategories, function(index, value) {
  24752. hash[value] = index
  24753. });
  24754. that._data.sort(function sortCat(a, b) {
  24755. a = a[argumentField];
  24756. b = b[argumentField];
  24757. return hash[a] - hash[b]
  24758. })
  24759. }
  24760. else if (that.options.sortingMethod === true && groups.argumentType !== dataTypes.STRING)
  24761. mergeSort(that._data, argumentField)
  24762. },
  24763. _addSkipFields: function _addSkipFields(field) {
  24764. this._skipFields[field] = (this._skipFields[field] || 0) + 1
  24765. },
  24766. _incorrectDataMessage: function() {
  24767. if (this._erorrDataSource !== true) {
  24768. this._erorrDataSource = true;
  24769. this.incidentOccured("E2001")
  24770. }
  24771. }
  24772. })
  24773. })(jQuery, DevExpress);
  24774. /*! Module viz-core, file themeManager.js */
  24775. (function($, DX, undefined) {
  24776. var viz = DX.viz,
  24777. Palette = viz.core.Palette,
  24778. utils = DX.utils;
  24779. var HOVER_COLOR_HIGHLIGHTING = 20,
  24780. HIGHLIGHTING_STEP = 50;
  24781. viz.charts.ThemeManager = viz.core.BaseThemeManager.inherit(function() {
  24782. var ctor = function(options, themeGroupName) {
  24783. var that = this;
  24784. options = options || {};
  24785. that._userOptions = options;
  24786. that._mergeAxisTitleOptions = [];
  24787. themeGroupName && (that._themeSection = themeGroupName);
  24788. that._IE8 = DX.browser.msie && DX.browser.version < 9;
  24789. that.setTheme(options.theme);
  24790. that.palette = new Palette(options.palette, {
  24791. stepHighlight: HIGHLIGHTING_STEP,
  24792. theme: that._themeName
  24793. })
  24794. };
  24795. var dispose = function() {
  24796. var that = this;
  24797. that.palette.dispose();
  24798. that.palette = that._userOptions = that._mergedSettings = null;
  24799. that.callBase()
  24800. };
  24801. var initDefaultSeriesTheme = function(that) {
  24802. var commonSeriesSettings = that._theme.commonSeriesSettings;
  24803. commonSeriesSettings.point = commonSeriesSettings.point || {};
  24804. commonSeriesSettings.label = commonSeriesSettings.label || {};
  24805. that._initializeFont(commonSeriesSettings.label.font)
  24806. };
  24807. var initAxisTheme = function(that) {
  24808. var axisTheme = that._theme.commonAxisSettings;
  24809. if (axisTheme) {
  24810. axisTheme.label = axisTheme.label || {};
  24811. axisTheme.grid = axisTheme.grid || {};
  24812. axisTheme.ticks = axisTheme.ticks || {};
  24813. axisTheme.line = axisTheme.line || {};
  24814. axisTheme.title = axisTheme.title || {};
  24815. axisTheme.label.font = axisTheme.label.font || {};
  24816. that._initializeFont(axisTheme.label.font);
  24817. axisTheme.title.font = axisTheme.title.font || {};
  24818. that._initializeFont(axisTheme.title.font)
  24819. }
  24820. };
  24821. var resetPalette = function() {
  24822. this.palette.reset()
  24823. };
  24824. var updatePalette = function(palette) {
  24825. this.palette = new Palette(palette || this._theme.defaultPalette, {
  24826. stepHighlight: HIGHLIGHTING_STEP,
  24827. theme: this.themeName
  24828. })
  24829. };
  24830. var processTitleOptions = function(options) {
  24831. return utils.isString(options) ? {text: options} : options
  24832. };
  24833. var processAxisOptions = function(axisOptions, name) {
  24834. if (!axisOptions)
  24835. return;
  24836. axisOptions = $.extend(true, {}, axisOptions);
  24837. axisOptions.title = processTitleOptions(axisOptions.title);
  24838. if (axisOptions.type === 'logarithmic' && axisOptions.logarithmBase <= 0 || axisOptions.logarithmBase && !$.isNumeric(axisOptions.logarithmBase)) {
  24839. axisOptions.logarithmBase = undefined;
  24840. axisOptions.logarithmBaseError = true
  24841. }
  24842. if (axisOptions.label) {
  24843. if (axisOptions.label.alignment)
  24844. axisOptions.label['userAlignment'] = true;
  24845. if (!axisOptions.label.overlappingBehavior) {
  24846. if (axisOptions.label.staggered)
  24847. axisOptions.label.overlappingBehavior = {
  24848. mode: 'stagger',
  24849. staggeringSpacing: axisOptions.label.staggeringSpacing
  24850. };
  24851. if (axisOptions.label.rotationAngle)
  24852. axisOptions.label.overlappingBehavior = {
  24853. mode: 'rotate',
  24854. rotationAngle: axisOptions.label.rotationAngle
  24855. }
  24856. }
  24857. if (utils.isString(axisOptions.label.overlappingBehavior))
  24858. axisOptions.label.overlappingBehavior = {mode: axisOptions.label.overlappingBehavior};
  24859. if (!axisOptions.label.overlappingBehavior || !axisOptions.label.overlappingBehavior.mode)
  24860. axisOptions.label.overlappingBehavior = axisOptions.label.overlappingBehavior || {}
  24861. }
  24862. return axisOptions
  24863. };
  24864. var applyParticularAxisOptions = function(name, userOptions, rotated) {
  24865. var theme = this._theme,
  24866. position = !(rotated ^ name === "valueAxis") ? "horizontalAxis" : "verticalAxis",
  24867. commonAxisSettings = processAxisOptions(this._userOptions["commonAxisSettings"], name);
  24868. return $.extend(true, {}, theme.commonAxisSettings, theme[position], theme[name], commonAxisSettings, processAxisOptions(userOptions, name))
  24869. };
  24870. var mergeOptions = function(name, userOptions) {
  24871. userOptions = userOptions || this._userOptions[name];
  24872. var theme = this._theme[name],
  24873. result = this._mergedSettings[name];
  24874. if (result)
  24875. return result;
  24876. if ($.isPlainObject(theme) && $.isPlainObject(userOptions))
  24877. result = $.extend(true, {}, theme, userOptions);
  24878. else
  24879. result = utils.isDefined(userOptions) ? userOptions : theme;
  24880. this._mergedSettings[name] = result;
  24881. return result
  24882. };
  24883. var applyParticularTheme = {
  24884. base: mergeOptions,
  24885. argumentAxis: applyParticularAxisOptions,
  24886. valueAxisRangeSelector: function() {
  24887. return mergeOptions.call(this, 'valueAxis')
  24888. },
  24889. valueAxis: applyParticularAxisOptions,
  24890. title: function(name) {
  24891. var userOptions = processTitleOptions(this._userOptions[name]);
  24892. return mergeOptions.call(this, name, userOptions)
  24893. },
  24894. series: function(name, userOptions, isPie) {
  24895. var theme = this._theme,
  24896. userCommonSettings = this._userOptions.commonSeriesSettings || {},
  24897. themeCommonSettings = theme.commonSeriesSettings,
  24898. type = ((userOptions.type || userCommonSettings.type || themeCommonSettings.type) + '').toLowerCase(),
  24899. settings,
  24900. palette = this.palette,
  24901. isBar = ~type.indexOf('bar'),
  24902. isBubble = ~type.indexOf('bubble'),
  24903. mainSeriesColor,
  24904. containerBackgroundColor = this.getOptions("containerBackgroundColor");
  24905. if (isBar || isBubble) {
  24906. userOptions = $.extend(true, {}, userCommonSettings, userCommonSettings[type], userOptions);
  24907. var seriesVisibility = userOptions.visible;
  24908. userCommonSettings = {type: {}};
  24909. $.extend(true, userOptions, userOptions.point);
  24910. userOptions.visible = seriesVisibility
  24911. }
  24912. settings = $.extend(true, {}, themeCommonSettings, themeCommonSettings[type], userCommonSettings, userCommonSettings[type], userOptions);
  24913. settings.type = type;
  24914. settings.containerBackgroundColor = containerBackgroundColor;
  24915. if (!isPie) {
  24916. settings.widgetType = 'chart';
  24917. mainSeriesColor = settings.color || palette.getNextColor()
  24918. }
  24919. else {
  24920. settings.widgetType = 'pieChart';
  24921. mainSeriesColor = function() {
  24922. return palette.getNextColor()
  24923. }
  24924. }
  24925. settings.mainSeriesColor = mainSeriesColor;
  24926. settings._IE8 = this._IE8;
  24927. return settings
  24928. },
  24929. pieSegment: function(name, seriesSettings, segmentSettings) {
  24930. var settings = $.extend(true, {}, seriesSettings, segmentSettings);
  24931. var mainColor = new DX.Color(settings.color || this.palette.getNextColor());
  24932. settings.color = mainColor.toHex();
  24933. settings.border.color = settings.border.color || mainColor.toHex();
  24934. settings.hoverStyle.color = settings.hoverStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
  24935. settings.hoverStyle.border.color = settings.hoverStyle.border.color || mainColor.toHex();
  24936. settings.selectionStyle.color = settings.selectionStyle.color || this._IE8 && mainColor.highlight(HOVER_COLOR_HIGHLIGHTING) || mainColor.toHex();
  24937. settings.selectionStyle.border.color = settings.selectionStyle.border.color || mainColor.toHex();
  24938. return settings
  24939. },
  24940. animation: function(name) {
  24941. var userOptions = this._userOptions[name];
  24942. userOptions = $.isPlainObject(userOptions) ? userOptions : utils.isDefined(userOptions) ? {enabled: !!userOptions} : {};
  24943. return mergeOptions.call(this, name, userOptions)
  24944. }
  24945. };
  24946. return {
  24947. _themeSection: 'chart',
  24948. ctor: ctor,
  24949. dispose: dispose,
  24950. _initializeTheme: function() {
  24951. var that = this,
  24952. theme = this._theme;
  24953. theme.legend = theme.legend || {};
  24954. theme.legend.font = theme.legend.font || {};
  24955. that._initializeFont(theme.legend.font);
  24956. initDefaultSeriesTheme(that);
  24957. initAxisTheme(that);
  24958. theme.title = theme.title || {};
  24959. theme.title.font = theme.title.font || {};
  24960. that._initializeFont(theme.title.font);
  24961. theme.tooltip = theme.tooltip || {};
  24962. theme.tooltip.font = theme.tooltip.font || {};
  24963. that._initializeFont(theme.tooltip.font);
  24964. theme.loadingIndicator = theme.loadingIndicator || {};
  24965. theme.loadingIndicator.font = theme.loadingIndicator.font || {};
  24966. that._initializeFont(theme.loadingIndicator.font)
  24967. },
  24968. resetPalette: resetPalette,
  24969. getOptions: function(name) {
  24970. return (applyParticularTheme[name] || applyParticularTheme["base"]).apply(this, arguments)
  24971. },
  24972. setTheme: function(theme) {
  24973. var that = this;
  24974. that._mergedSettings = {};
  24975. that.callBase(theme);
  24976. that.getOptions('rtlEnabled') && $.extend(true, that._theme, that._theme._rtl)
  24977. },
  24978. resetOptions: function(name) {
  24979. this._mergedSettings[name] = null
  24980. },
  24981. update: function(options) {
  24982. this._userOptions = options
  24983. },
  24984. updatePalette: updatePalette
  24985. }
  24986. }())
  24987. })(jQuery, DevExpress);
  24988. /*! Module viz-core, file factory.js */
  24989. (function($, DX) {
  24990. var viz = DX.viz,
  24991. charts = viz.charts,
  24992. series = charts.series;
  24993. charts.factory = function() {
  24994. var createSeriesFamily = function(options) {
  24995. return new series.SeriesFamily(options)
  24996. };
  24997. var createAxis = function(renderer, options) {
  24998. return new charts.Axis(renderer, options)
  24999. };
  25000. var createThemeManager = function(options, groupName) {
  25001. return new charts.ThemeManager(options, groupName)
  25002. };
  25003. var createDataValidator = function(data, groups, incidentOccured, dataPrepareOptions) {
  25004. return new charts.DataValidator(data, groups, incidentOccured, dataPrepareOptions)
  25005. };
  25006. var createTracker = function(options) {
  25007. return new charts.Tracker(options)
  25008. };
  25009. var createTitle = function(renderer, canvas, options, group) {
  25010. return new charts.ChartTitle(renderer, canvas, options, group)
  25011. };
  25012. var createChartLayoutManager = function(options) {
  25013. return new charts.LayoutManager(options)
  25014. };
  25015. return {
  25016. createSeriesFamily: createSeriesFamily,
  25017. createAxis: createAxis,
  25018. createThemeManager: createThemeManager,
  25019. createDataValidator: createDataValidator,
  25020. createTracker: createTracker,
  25021. createChartLayoutManager: createChartLayoutManager,
  25022. createTitle: createTitle
  25023. }
  25024. }()
  25025. })(jQuery, DevExpress);
  25026. /*! Module viz-core, file baseWidget.js */
  25027. (function($, DX, undefined) {
  25028. var core = DX.viz.core,
  25029. utils = DX.utils;
  25030. DX.viz.core.BaseWidget = DX.DOMComponent.inherit({
  25031. NAMESPACE: DX.ui,
  25032. _init: function() {
  25033. this._setRedrawOnResize(this._getOptionRedrawOnResize());
  25034. this._incidentOccured = this._createIncidentOccured();
  25035. this._renderVisiblityChange()
  25036. },
  25037. _optionChanged: function(name, value, prevValue) {
  25038. var that = this;
  25039. switch (name) {
  25040. case'redrawOnResize':
  25041. that._setRedrawOnResize(that._getOptionRedrawOnResize());
  25042. break;
  25043. case'loadingIndicator':
  25044. that._updateLoadIndicator(that._getLoadIndicatorOption());
  25045. break;
  25046. default:
  25047. that._invalidate()
  25048. }
  25049. that.callBase(name, value, prevValue)
  25050. },
  25051. _getOptionRedrawOnResize: function() {
  25052. var redrawOnResize = this.option('redrawOnResize');
  25053. redrawOnResize = redrawOnResize !== undefined ? !!redrawOnResize : true;
  25054. return redrawOnResize
  25055. },
  25056. _getLoadIndicatorOption: function() {
  25057. return this.option('loadingIndicator')
  25058. },
  25059. _dispose: function() {
  25060. var that = this;
  25061. if (that._resizeHandlerCallback)
  25062. that._removeResizeCallbacks();
  25063. that._incidentOccured = null;
  25064. that.callBase()
  25065. },
  25066. _visibilityChanged: function(visible) {
  25067. if (visible)
  25068. this.render()
  25069. },
  25070. _setRedrawOnResize: function(redrawOnResize) {
  25071. var that = this;
  25072. if (redrawOnResize) {
  25073. if (!that._resizeHandlerCallback && utils.isFunction(that._resize)) {
  25074. that._resizeHandlerCallback = DX.utils.createResizeHandler(function() {
  25075. that._resize()
  25076. });
  25077. utils.windowResizeCallbacks.add(that._resizeHandlerCallback)
  25078. }
  25079. }
  25080. else
  25081. that._removeResizeCallbacks()
  25082. },
  25083. _removeResizeCallbacks: function() {
  25084. var that = this;
  25085. that._resizeHandlerCallback && that._resizeHandlerCallback.stop();
  25086. utils.windowResizeCallbacks.remove(that._resizeHandlerCallback);
  25087. delete that._resizeHandlerCallback
  25088. },
  25089. _showLoadIndicator: function(options, canvas) {
  25090. var that = this;
  25091. that._loadIndicator = this._loadIndicator || core.CoreFactory.createLoadIndicator(options, that._element());
  25092. that._loadIndicator.show(canvas.width, canvas.height);
  25093. that._initializing && that._loadIndicator.endLoading(undefined, true)
  25094. },
  25095. _updateLoadIndicator: function(options, width, height) {
  25096. this._loadIndicator && this._loadIndicator.applyOptions(options, width, height)
  25097. },
  25098. _endLoading: function(complete) {
  25099. if (this._loadIndicator)
  25100. this._loadIndicator.endLoading(complete);
  25101. else
  25102. complete && complete()
  25103. },
  25104. _reappendLoadIndicator: function() {
  25105. this._loadIndicator && this._loadIndicator.toForeground()
  25106. },
  25107. _disposeLoadIndicator: function() {
  25108. this._loadIndicator && this._loadIndicator.dispose();
  25109. this._loadIndicator = null
  25110. },
  25111. _setDefaultOptions: function() {
  25112. this.callBase();
  25113. this.option({incidentOccured: function(options) {
  25114. var message = "" + options.id + " - " + options.text,
  25115. majorVerision = options.version.split(".").slice(0, 2).join("_"),
  25116. url = "http://js.devexpress.com/error/" + majorVerision + "/" + options.id;
  25117. utils.logger.warn(message + "\n" + url)
  25118. }})
  25119. },
  25120. _createIncidentOccured: function() {
  25121. var that = this;
  25122. return function(errorOrWarningId, options) {
  25123. var isError = errorOrWarningId[0] === 'E',
  25124. type = isError ? "error" : "warning",
  25125. formattingArray = options ? options.slice(0) : [],
  25126. text,
  25127. incidentOccuredFunc = that.option('incidentOccured');
  25128. formattingArray.unshift(core.errorsWarnings[errorOrWarningId]);
  25129. text = utils.stringFormat.apply(null, formattingArray);
  25130. if (utils.isFunction(incidentOccuredFunc))
  25131. setTimeout(function() {
  25132. incidentOccuredFunc({
  25133. id: errorOrWarningId,
  25134. type: type,
  25135. args: options,
  25136. text: text,
  25137. widget: that.NAME,
  25138. version: DevExpress.VERSION
  25139. })
  25140. })
  25141. }
  25142. },
  25143. _normalizeHtml: function(html) {
  25144. var re = /xmlns="[\s\S]*?"/gi,
  25145. first = true;
  25146. html = html.replace(re, function(match) {
  25147. if (!first)
  25148. return "";
  25149. first = false;
  25150. return match
  25151. });
  25152. return html.replace(/xmlns:NS1="[\s\S]*?"/gi, "").replace(/NS1:xmlns:xlink="([\s\S]*?)"/gi, 'xmlns:xlink="$1"')
  25153. },
  25154. _drawn: function() {
  25155. var that = this,
  25156. drawnCallback = that.option('drawn');
  25157. utils.isFunction(drawnCallback) && setTimeout(function() {
  25158. drawnCallback(that)
  25159. })
  25160. },
  25161. showLoadingIndicator: function() {
  25162. this._showLoadIndicator(this.option('loadingIndicator'), this.canvas || {})
  25163. },
  25164. hideLoadingIndicator: function() {
  25165. this._loadIndicator && this._loadIndicator.hide()
  25166. },
  25167. endUpdate: function() {
  25168. if (this._updateLockCount === 1 && !this._requireRefresh)
  25169. this.hideLoadingIndicator();
  25170. this.callBase()
  25171. },
  25172. svg: function() {
  25173. var renderer = this.renderer || this._renderer;
  25174. return renderer ? this._normalizeHtml(renderer.svg()) : ''
  25175. }
  25176. })
  25177. })(jQuery, DevExpress);
  25178. /*! Module viz-core, file CoreFactory.js */
  25179. (function(DX, undefined) {
  25180. var renderers = DX.viz.renderers,
  25181. core = DX.viz.core;
  25182. DX.viz.core.CoreFactory = function() {
  25183. return {
  25184. createSeries: function(renderer, options) {
  25185. return new core.series.Series(renderer, options)
  25186. },
  25187. createPoint: function(data, options) {
  25188. return new core.series.points.Point(data, options)
  25189. },
  25190. createLabel: function(type, data, options) {
  25191. if (type === "pie" || type === "doughnut" || type === "donut")
  25192. return new core.series.points.PieLabel(data, options);
  25193. else
  25194. return new core.series.points.Label(data, options)
  25195. },
  25196. createRenderer: function(options) {
  25197. return new renderers.Renderer(options)
  25198. },
  25199. createTranslator1D: function(fromValue, toValue, fromAngle, toAngle) {
  25200. return (new core.Translator1D).setDomain(fromValue, toValue).setCodomain(fromAngle, toAngle)
  25201. },
  25202. createTranslator2D: function(range, canvas, options) {
  25203. return new core.Translator2D(range, canvas, options)
  25204. },
  25205. getTickProvider: function() {
  25206. return core.tickProvider
  25207. },
  25208. createTooltip: function(options, group, renderer) {
  25209. return new core.Tooltip(options, group, renderer)
  25210. },
  25211. createLoadIndicator: function(options, group) {
  25212. return new core.LoadIndicator(options, group)
  25213. },
  25214. createLegend: function(data, options, renderer, group) {
  25215. return new core.Legend(data, options, renderer, group)
  25216. },
  25217. createSeriesFamily: function(options) {
  25218. return new core.series.helpers.SeriesFamily(options)
  25219. }
  25220. }
  25221. }()
  25222. })(DevExpress);
  25223. DevExpress.MOD_VIZ_CORE = true
  25224. }
  25225. if (!DevExpress.MOD_VIZ_CHARTS) {
  25226. if (!DevExpress.MOD_VIZ_CORE)
  25227. throw Error('Required module is not referenced: viz-core');
  25228. /*! Module viz-charts, file chartTitle.js */
  25229. (function($, DX, undefined) {
  25230. var isDefined = DX.utils.isDefined,
  25231. endsWith = function(value, pattern) {
  25232. return value.substr(value.length - pattern.length) === pattern
  25233. },
  25234. startsWith = function(value, pattern) {
  25235. return value.indexOf(pattern) === 0
  25236. },
  25237. decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
  25238. DEFAULT_MARGIN = 10;
  25239. DX.viz.charts.ChartTitle = DX.Class.inherit({
  25240. ctor: function(renderer, options, width, group) {
  25241. var that = this;
  25242. that._init(options, width);
  25243. that.renderer = renderer;
  25244. that.titleGroup = group
  25245. },
  25246. dispose: function() {
  25247. var that = this;
  25248. that.renderer = null;
  25249. that.clipRect = null;
  25250. that.title = null;
  25251. that.innerTitleGroup = null;
  25252. that.titleGroup = null;
  25253. that.options = null
  25254. },
  25255. update: function(options, width) {
  25256. this._init(options, width)
  25257. },
  25258. _init: function(options, width) {
  25259. var that = this;
  25260. if (options) {
  25261. that._parseAlignments(options);
  25262. that.horizontalAlignment = options.horizontalAlignment;
  25263. that.verticalAlignment = options.verticalAlignment;
  25264. that._parseMargins(options);
  25265. that.margin = options.margin;
  25266. that.options = options
  25267. }
  25268. that.setSize({width: width})
  25269. },
  25270. _parseMargins: function(options) {
  25271. options.margin = isDefined(options.margin) ? options.margin : {};
  25272. if (typeof options.margin === 'number') {
  25273. options.margin = options.margin >= 0 ? options.margin : DEFAULT_MARGIN;
  25274. options.margin = {
  25275. top: options.margin,
  25276. bottom: options.margin,
  25277. left: options.margin,
  25278. right: options.margin
  25279. }
  25280. }
  25281. else {
  25282. options.margin.top = options.margin.top >= 0 ? options.margin.top : DEFAULT_MARGIN;
  25283. options.margin.bottom = options.margin.bottom >= 0 ? options.margin.bottom : DEFAULT_MARGIN;
  25284. options.margin.left = options.margin.left >= 0 ? options.margin.left : DEFAULT_MARGIN;
  25285. options.margin.right = options.margin.right >= 0 ? options.margin.right : DEFAULT_MARGIN
  25286. }
  25287. },
  25288. _parseAlignments: function(options) {
  25289. if (isDefined(options.position) && !(isDefined(options.verticalAlignment) && isDefined(options.horizontalAlignment))) {
  25290. options.position = options.position.toLowerCase();
  25291. options.verticalAlignment = endsWith(options.position, 'top') ? 'top' : 'bottom';
  25292. options.horizontalAlignment = startsWith(options.position, 'left') ? 'left' : startsWith(options.position, 'center') && 'center' || 'right';
  25293. return
  25294. }
  25295. options.verticalAlignment = (options.verticalAlignment || '').toLowerCase();
  25296. options.horizontalAlignment = (options.horizontalAlignment || '').toLowerCase();
  25297. if (options.verticalAlignment !== 'top' && options.verticalAlignment !== 'bottom')
  25298. options.verticalAlignment = 'top';
  25299. if (options.horizontalAlignment !== 'left' && options.horizontalAlignment !== 'center' && options.horizontalAlignment !== 'right')
  25300. options.horizontalAlignment = 'center'
  25301. },
  25302. _setBoundingRect: function() {
  25303. var that = this,
  25304. options = that.options,
  25305. margin = that.changedMargin || that.margin,
  25306. box;
  25307. if (!that.innerTitleGroup)
  25308. return;
  25309. box = that.innerTitleGroup.getBBox();
  25310. box.height += margin.top + margin.bottom;
  25311. box.width += margin.left + margin.right;
  25312. box.x -= margin.left;
  25313. box.y -= margin.top;
  25314. if (isDefined(options.placeholderSize))
  25315. box.height = options.placeholderSize;
  25316. that.boundingRect = box
  25317. },
  25318. draw: function() {
  25319. var that = this,
  25320. titleOptions = that.options,
  25321. renderer = that.renderer,
  25322. attr;
  25323. if (!titleOptions.text)
  25324. return;
  25325. that.changedMargin = null;
  25326. if (!that.innerTitleGroup) {
  25327. that.innerTitleGroup = renderer.createGroup();
  25328. that.clipRect = that.createClipRect();
  25329. that.titleGroup && that.clipRect && that.titleGroup.applySettings({clipId: that.clipRect.id})
  25330. }
  25331. else
  25332. that.innerTitleGroup.clear();
  25333. that.innerTitleGroup.append(that.titleGroup);
  25334. attr = {
  25335. font: titleOptions.font,
  25336. align: that.horizontalAlignment,
  25337. style: titleOptions.fontStyle
  25338. };
  25339. that.title = renderer.createText(titleOptions.text, 0, 0, attr).append(that.innerTitleGroup);
  25340. that.title.text = titleOptions.text;
  25341. that._correctTitleLength();
  25342. that._setClipRectSettings()
  25343. },
  25344. _correctTitleLength: function() {
  25345. var that = this,
  25346. text = that.title.text,
  25347. updateText,
  25348. lineLength,
  25349. box;
  25350. that.title.updateText(text);
  25351. that._setBoundingRect();
  25352. box = that.getLayoutOptions();
  25353. if (that._width > box.width || text.indexOf("<br/>") !== -1)
  25354. return;
  25355. lineLength = text.length * that._width / box.width;
  25356. updateText = text.substr(0, ~~lineLength - 1 - 3) + "...";
  25357. that.title.updateText(updateText);
  25358. that._setBoundingRect()
  25359. },
  25360. changeSize: function(size) {
  25361. var that = this,
  25362. margin = $.extend(true, {}, that.margin);
  25363. if (margin.top + margin.bottom < size.height) {
  25364. if (this.innerTitleGroup) {
  25365. that.options._incidentOccured("W2103");
  25366. this.innerTitleGroup.remove();
  25367. this.innerTitleGroup = null
  25368. }
  25369. if (that.clipRect) {
  25370. that.clipRect.remove();
  25371. that.clipRect = null
  25372. }
  25373. }
  25374. else if (size.height > 0) {
  25375. decreaseGaps(margin, ["top", "bottom"], size.height);
  25376. size.height && (that.changedMargin = margin)
  25377. }
  25378. that._correctTitleLength();
  25379. that._setBoundingRect();
  25380. that._setClipRectSettings()
  25381. },
  25382. getLayoutOptions: function() {
  25383. var options = this.options,
  25384. boundingRect = this.innerTitleGroup ? this.boundingRect : {
  25385. width: 0,
  25386. height: 0,
  25387. x: 0,
  25388. y: 0
  25389. };
  25390. boundingRect.verticalAlignment = options.verticalAlignment;
  25391. boundingRect.horizontalAlignment = options.horizontalAlignment;
  25392. boundingRect.cutLayoutSide = options.verticalAlignment;
  25393. return boundingRect
  25394. },
  25395. setSize: function(size) {
  25396. this._width = size.width || this._width
  25397. },
  25398. shift: function(x, y) {
  25399. var that = this,
  25400. box = that.getLayoutOptions();
  25401. x -= box.x;
  25402. y -= box.y;
  25403. that.innerTitleGroup && that.innerTitleGroup.move(x, y);
  25404. that.clipRect && that.clipRect.updateRectangle({
  25405. translateX: x,
  25406. translateY: y
  25407. })
  25408. },
  25409. createClipRect: function() {
  25410. if (isDefined(this.options.placeholderSize))
  25411. return this.renderer.createClipRect(0, 0, 0, 0)
  25412. },
  25413. _setClipRectSettings: function() {
  25414. var bbox = this.getLayoutOptions(),
  25415. clipRect = this.clipRect;
  25416. if (clipRect) {
  25417. clipRect.append();
  25418. clipRect.updateRectangle({
  25419. x: bbox.x,
  25420. y: bbox.y,
  25421. width: bbox.width,
  25422. height: bbox.height
  25423. })
  25424. }
  25425. }
  25426. });
  25427. DX.viz.charts.ChartTitle.__DEFAULT_MARGIN = DEFAULT_MARGIN
  25428. })(jQuery, DevExpress);
  25429. /*! Module viz-charts, file axis.js */
  25430. (function($, DX, undefined) {
  25431. var utils = DX.utils,
  25432. isDefinedUtils = utils.isDefined,
  25433. isDateUtils = utils.isDate,
  25434. mathAbs = Math.abs,
  25435. core = DX.viz.core,
  25436. AXIS_VALUE_MARGIN_PRIORITY = 100,
  25437. DEFAULT_AXIS_LABEL_SPACING = 5,
  25438. AXIS_STAGGER_OVERLAPPING_KOEF = 2,
  25439. MAX_GRID_BORDER_ADHENSION = 4,
  25440. CANVAS_POSITION_PREFIX = 'canvas_position_',
  25441. CANVAS_POSITION_START = 'canvas_position_start',
  25442. CANVAS_POSITION_END = 'canvas_position_end',
  25443. TOP = 'top',
  25444. BOTTOM = 'bottom',
  25445. LEFT = 'left',
  25446. RIGHT = 'right',
  25447. CENTER = 'center';
  25448. DX.viz.charts.AXIS_STAGGER_OVERLAPPING_KOEF = AXIS_STAGGER_OVERLAPPING_KOEF;
  25449. var processCustomOptions = function(options) {
  25450. var label = options.label,
  25451. position = options.position;
  25452. if (options.isHorizontal) {
  25453. if (!(position === BOTTOM || position === TOP))
  25454. position = BOTTOM
  25455. }
  25456. else if (!(position === LEFT || position === RIGHT))
  25457. position = LEFT;
  25458. options.position = position;
  25459. if (position === RIGHT && !label.userAlignment)
  25460. label.alignment = LEFT
  25461. };
  25462. var formatLabel = function(value, options, axisMinMax) {
  25463. var formatObject = {
  25464. value: value,
  25465. valueText: DX.formatHelper.format(value, options.format, options.precision) || ''
  25466. };
  25467. if (axisMinMax) {
  25468. formatObject.min = axisMinMax.min;
  25469. formatObject.max = axisMinMax.max
  25470. }
  25471. return options.customizeText ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText
  25472. };
  25473. var nextState = function(state) {
  25474. switch (state) {
  25475. case'overlap':
  25476. return 'stagger';
  25477. case'stagger':
  25478. return 'rotate';
  25479. case'rotate':
  25480. default:
  25481. return 'end'
  25482. }
  25483. };
  25484. DX.viz.charts.Axis = function(renderer, options) {
  25485. var debug = DX.utils.debug;
  25486. debug.assertParam(renderer, 'renderer was not passed');
  25487. debug.assertParam(options.label, 'label was not passed');
  25488. debug.assertParam(options.tick, 'tick was not passed');
  25489. debug.assertParam(options.grid, 'grid was not passed');
  25490. debug.assertParam(options.title, 'title was not passed');
  25491. debug.assert(options.axisDivisionFactor, 'axisDivisionFactor was not passed');
  25492. debug.assert(options.stripStyle, 'stripStyle was not passed');
  25493. debug.assert(options.constantLineStyle, 'constantLineStyle was not passed');
  25494. debug.assert(options.position, 'position was not passed');
  25495. debug.assertParam(options.isHorizontal, 'isHorizontal was not passed');
  25496. this.renderer = renderer;
  25497. this._init(options)
  25498. };
  25499. $.extend(DX.viz.charts.Axis.prototype, {
  25500. dispose: function() {
  25501. var that = this;
  25502. that._axisElementsGroup && that._axisElementsGroup.dispose();
  25503. $.each(that.labels || [], function(_, label) {
  25504. label.removeData()
  25505. });
  25506. that.labels = null;
  25507. that.title = null;
  25508. that.stripLabels = null;
  25509. that.stripRects = null;
  25510. that.constantLineLabels = null;
  25511. that.constantLines = null;
  25512. that._axisStripGroup = null;
  25513. that._axisConstantLineGroup = null;
  25514. that._axisLableGroup = null;
  25515. that._axisLineGroup = null;
  25516. that._axisElementsGroup = null;
  25517. that._axisGridGroup = null;
  25518. that._axisGroup = null;
  25519. that.axesContainerGroup = null;
  25520. that.stripsGroup = null;
  25521. that.constantLinesGroup = null;
  25522. that._axisTitleGroup = null;
  25523. that.renderer = null;
  25524. that.translator = null;
  25525. that.orthogonalTranslator = null;
  25526. that.options = null;
  25527. that.textOptions = null;
  25528. that._tickValues = null;
  25529. that._fullTickValues = null;
  25530. that._fullTickPositions = null
  25531. },
  25532. _init: function(options) {
  25533. var that = this,
  25534. categories = options.categories,
  25535. labelOptions = options.label;
  25536. options.hoverMode = options.hoverMode ? options.hoverMode.toLowerCase() : 'none';
  25537. that.hasLabelFormat = labelOptions.format !== '' && isDefinedUtils(labelOptions.format);
  25538. that.options = options;
  25539. that.staggered = labelOptions.staggered;
  25540. labelOptions.minSpacing = isDefinedUtils(labelOptions.minSpacing) ? labelOptions.minSpacing : DEFAULT_AXIS_LABEL_SPACING;
  25541. processCustomOptions(options);
  25542. if (categories) {
  25543. that.labelsNumber = categories.length;
  25544. that.ticksNumber = that.labelsNumber
  25545. }
  25546. options.range = {
  25547. min: options.min,
  25548. max: options.max,
  25549. categories: options.categories && options.categories.slice(0)
  25550. };
  25551. that.pane = options.pane;
  25552. that.textOptions = {
  25553. align: labelOptions.alignment,
  25554. font: labelOptions.font,
  25555. opacity: labelOptions.opacity,
  25556. style: labelOptions.style
  25557. };
  25558. if (options.type === 'logarithmic') {
  25559. if (options.logarithmBaseError) {
  25560. options.incidentOccured('E2104');
  25561. delete options.logarithmBaseError
  25562. }
  25563. that.calcInterval = function(value, prevValue) {
  25564. return utils.getLog(value / prevValue, options.logarithmBase)
  25565. }
  25566. }
  25567. },
  25568. updateSize: function(clearAxis) {
  25569. var that = this,
  25570. options = that.options,
  25571. direction = options.isHorizontal ? "horizontal" : "vertical";
  25572. if (that.title && that._axisTitleGroup) {
  25573. options.incidentOccured('W2105', [direction]);
  25574. that._axisTitleGroup.remove();
  25575. that._axisTitleGroup = null
  25576. }
  25577. if (clearAxis && that._axisElementsGroup && that.labels) {
  25578. options.incidentOccured('W2106', [direction]);
  25579. that._axisElementsGroup.remove();
  25580. that._axisElementsGroup = null
  25581. }
  25582. that._setBoundingRect()
  25583. },
  25584. _updateTranslatorInterval: function() {
  25585. var that = this,
  25586. i,
  25587. tickValues,
  25588. businessRange = that.translator.getBusinessRange();
  25589. if (businessRange && businessRange.addRange && !that.options.categories) {
  25590. tickValues = that.getTickValues();
  25591. for (i = 0; i < tickValues.length - 1; i++)
  25592. businessRange.addRange({interval: mathAbs(tickValues[i] - tickValues[i + 1])})
  25593. }
  25594. },
  25595. setTranslator: function(translator, orthogonalTranslator) {
  25596. var that = this;
  25597. var debug = DX.utils.debug;
  25598. debug.assertParam(translator, 'translator was not passed');
  25599. that.translator = translator;
  25600. orthogonalTranslator && (that.orthogonalTranslator = orthogonalTranslator);
  25601. that.resetTicks();
  25602. that._updateTranslatorInterval()
  25603. },
  25604. resetTicks: function() {
  25605. var that = this;
  25606. that._tickValues = that._tickPositions = that._fullTickValues = that._fullTickPositions = null
  25607. },
  25608. setRange: function(range) {
  25609. var debug = DX.utils.debug;
  25610. debug.assertParam(range, 'range was not passed');
  25611. var options = this.options;
  25612. options.min = range.minVisible;
  25613. options.max = range.maxVisible;
  25614. options.categories = range.categories;
  25615. options.stubData = range.stubData;
  25616. this.resetTicks()
  25617. },
  25618. _drawAxis: function() {
  25619. var that = this,
  25620. translator = that.translator,
  25621. options = that.options,
  25622. hasCategories = !!options.categories,
  25623. axisPosition = that.axisPosition,
  25624. p11,
  25625. p12,
  25626. p21,
  25627. p22;
  25628. if (!options.visible)
  25629. return;
  25630. p11 = translator.translateSpecialCase(CANVAS_POSITION_START);
  25631. p21 = translator.translateSpecialCase(CANVAS_POSITION_END);
  25632. if (options.isHorizontal)
  25633. p12 = p22 = axisPosition;
  25634. else {
  25635. p12 = p11;
  25636. p22 = p21;
  25637. p11 = p21 = axisPosition
  25638. }
  25639. that.renderer.createLine(p11, p12, p21, p22, {
  25640. strokeWidth: options.width,
  25641. stroke: options.color,
  25642. strokeOpacity: options.opacity
  25643. }).append(that._axisLineGroup)
  25644. },
  25645. _getOptimalRotationAngle: function(tick1, tick2, labelOptions) {
  25646. var that = this,
  25647. translator = that.options.isHorizontal ? that.translator : that.orthogonalTranslator,
  25648. renderer = that.renderer,
  25649. outOfScreen = core.outOfScreen,
  25650. textOptions = that.textOptions,
  25651. svgElement1 = renderer.createText(formatLabel(tick1, labelOptions), outOfScreen.x + translator.translate(tick1), outOfScreen.y, textOptions).append(),
  25652. svgElement2 = renderer.createText(formatLabel(tick2, labelOptions), outOfScreen.x + translator.translate(tick2), outOfScreen.y, textOptions).append(),
  25653. bBox1 = svgElement1.getBBox(),
  25654. bBox2 = svgElement2.getBBox(),
  25655. angle = Math.asin((bBox1.height + labelOptions.minSpacing) / (bBox2.x - bBox1.x)) * 180 / Math.PI;
  25656. svgElement1.remove();
  25657. svgElement2.remove();
  25658. return isNaN(angle) ? 90 : Math.ceil(angle)
  25659. },
  25660. _applyOptimalOverlappingBehavior: function(ticks, ticksOptions) {
  25661. var that = this,
  25662. overlappingBehavior = that.overlappingBehavior,
  25663. isOverlapped = false,
  25664. rotationAngle = null,
  25665. mode = null,
  25666. options = $.extend({}, ticksOptions),
  25667. state = 'overlap';
  25668. while (state !== 'end') {
  25669. isOverlapped = rotationAngle && rotationAngle !== 90 ? false : that.options.tickProvider.isOverlappedTicks(ticks, options);
  25670. state = nextState(isOverlapped ? state : null);
  25671. that.testAutoOverlappingState = state;
  25672. switch (state) {
  25673. case'stagger':
  25674. options.screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
  25675. mode = state;
  25676. break;
  25677. case'rotate':
  25678. rotationAngle = that._getOptimalRotationAngle(ticks[0], ticks[1], that.options.label);
  25679. that.testAutoOverlappingRotationAngle = rotationAngle;
  25680. options.screenDelta = ticksOptions.screenDelta;
  25681. options.textOptions.rotate = rotationAngle;
  25682. mode = state;
  25683. break
  25684. }
  25685. }
  25686. that.testAutoOverlappingOptions = options;
  25687. overlappingBehavior.isOverlapped = isOverlapped;
  25688. overlappingBehavior.mode = mode;
  25689. overlappingBehavior.rotationAngle = rotationAngle
  25690. },
  25691. _getTicksOptions: function() {
  25692. var that = this,
  25693. options = that.options,
  25694. translator = that.translator,
  25695. screenDelta = mathAbs(translator.translateSpecialCase(CANVAS_POSITION_START) - translator.translateSpecialCase(CANVAS_POSITION_END)),
  25696. min = options.min,
  25697. max = options.max,
  25698. digitPosition = utils.getSignificantDigitPosition(mathAbs(max - min) / screenDelta),
  25699. correctingValue,
  25700. getText = function() {
  25701. return ''
  25702. };
  25703. if (utils.isNumber(min) && options.type !== 'logarithmic') {
  25704. min = utils.roundValue(options.min, digitPosition);
  25705. if (min < options.min) {
  25706. correctingValue = Math.pow(10, -digitPosition);
  25707. min = utils.applyPrecisionByMinDelta(min, correctingValue, min + correctingValue)
  25708. }
  25709. if (min > max)
  25710. min = options.min
  25711. }
  25712. if (!options.stubData)
  25713. getText = function(value) {
  25714. return formatLabel(value, options.label, {
  25715. min: min,
  25716. max: max
  25717. })
  25718. };
  25719. return {
  25720. min: min,
  25721. max: max,
  25722. base: options.type === 'logarithmic' ? options.logarithmBase : undefined,
  25723. axisType: options.type,
  25724. dataType: options.dataType,
  25725. customTicks: $.isArray(options.categories) ? options.categories : that._tickValues,
  25726. useTicksAutoArrangement: false,
  25727. textOptions: that.textOptions,
  25728. getText: getText,
  25729. renderer: that.renderer,
  25730. textSpacing: options.label.minSpacing,
  25731. translator: translator,
  25732. tickInterval: options.stubData ? null : options.tickInterval,
  25733. screenDelta: screenDelta,
  25734. gridSpacingFactor: options.axisDivisionFactor,
  25735. isHorizontal: options.isHorizontal,
  25736. setTicksAtUnitBeginning: options.setTicksAtUnitBeginning,
  25737. incidentOccured: options.incidentOccured
  25738. }
  25739. },
  25740. getTickValues: function() {
  25741. var that = this,
  25742. correctedScreenDelta,
  25743. options = that.options,
  25744. tickProvider = options.tickProvider,
  25745. labelOptions = options.label,
  25746. categories = options.categories,
  25747. ticksOptions = that._getTicksOptions();
  25748. that._fullTickValues = that._tickValues = tickProvider.getTicks(ticksOptions);
  25749. if ((isDateUtils(options.min) || isDateUtils(categories && categories[0])) && !that.hasLabelFormat && that._tickValues.length)
  25750. labelOptions.format = DX.formatHelper.getDateFormatByTicks(that._tickValues);
  25751. that.overlappingBehavior = labelOptions.overlappingBehavior ? $.extend({}, labelOptions.overlappingBehavior) : null;
  25752. if (that.overlappingBehavior) {
  25753. if (!options.isHorizontal && that.overlappingBehavior.mode !== 'ignore')
  25754. that.overlappingBehavior.mode = 'enlargeTickInterval';
  25755. ticksOptions.useTicksAutoArrangement = that.overlappingBehavior.mode !== 'ignore';
  25756. if (ticksOptions.useTicksAutoArrangement)
  25757. that._fullTickValues = that._tickValues = tickProvider.getCorrectedTicks(that._fullTickValues, ticksOptions);
  25758. if (that.overlappingBehavior.mode === 'auto') {
  25759. that.textOptions.rotate = 0;
  25760. that._applyOptimalOverlappingBehavior(that._fullTickValues, ticksOptions);
  25761. ticksOptions.useTicksAutoArrangement = that.overlappingBehavior.isOverlapped
  25762. }
  25763. if (that.overlappingBehavior.mode === 'rotate') {
  25764. that.textOptions.rotate = that.overlappingBehavior.rotationAngle;
  25765. if (!labelOptions.userAlignment)
  25766. that.textOptions.align = LEFT
  25767. }
  25768. else if (!labelOptions.userAlignment)
  25769. that.textOptions.align = labelOptions.alignment
  25770. }
  25771. if (ticksOptions.useTicksAutoArrangement) {
  25772. correctedScreenDelta = that._tickValues.length ? that.translator.translate(that._tickValues[that._tickValues.length - 1]) - that.translator.translate(that._tickValues[0]) : null;
  25773. if (correctedScreenDelta) {
  25774. ticksOptions.screenDelta = mathAbs(correctedScreenDelta);
  25775. ticksOptions.ticksCount = that._tickValues.length - 1
  25776. }
  25777. else
  25778. ticksOptions.ticksCount = that._tickValues.length;
  25779. if (that.overlappingBehavior && that.overlappingBehavior.mode === 'stagger')
  25780. ticksOptions.screenDelta *= AXIS_STAGGER_OVERLAPPING_KOEF;
  25781. ticksOptions.customTicks = that._tickValues;
  25782. that._tickValues = tickProvider.getTicks(ticksOptions)
  25783. }
  25784. that._testTKScreenDelta = ticksOptions.screenDelta;
  25785. that._autoArrangementStep = that._tickValues.autoArrangementStep;
  25786. that._useTicksAutoArrangement = ticksOptions.useTicksAutoArrangement;
  25787. if (that.options.stubData) {
  25788. that._testSkippedFormattingAndOverlapping = true;
  25789. return that._tickValues
  25790. }
  25791. if (!$.isArray(categories))
  25792. that._fullTickValues = that._tickValues;
  25793. return that._tickValues
  25794. },
  25795. setTickValues: function(tickValues) {
  25796. this.resetTicks();
  25797. this._fullTickValues = this._tickValues = tickValues
  25798. },
  25799. _prepareLabelsToDraw: function() {
  25800. var that = this,
  25801. ticksValues = that.getTickValues(),
  25802. ticks = [],
  25803. i;
  25804. if (ticksValues.hideLabels || that.options.stubData)
  25805. ticks.hideLabels = true;
  25806. for (i = 0; i < ticksValues.length; i++)
  25807. ticks.push({
  25808. text: ticksValues[i],
  25809. pos: that.translator.translate(ticksValues[i])
  25810. });
  25811. return ticks
  25812. },
  25813. _correctTicksPosition: function(ticks) {
  25814. var that = this,
  25815. options = that.options,
  25816. tickDelta = that.translator.getInterval() / 2,
  25817. i;
  25818. if (options.categories && (options.discreteAxisDivisionMode !== 'crossLabels' || !options.discreteAxisDivisionMode)) {
  25819. if (options.isHorizontal) {
  25820. if (!options.valueMarginsEnabled)
  25821. ticks = ticks.slice(0, ticks.length - 1)
  25822. }
  25823. else {
  25824. tickDelta = -tickDelta;
  25825. if (!options.valueMarginsEnabled)
  25826. ticks = ticks.slice(1, ticks.length)
  25827. }
  25828. for (i = 0; i < ticks.length; i++)
  25829. ticks[i].pos = ticks[i].pos + tickDelta
  25830. }
  25831. return ticks
  25832. },
  25833. _prepareFullTicksToDraw: function() {
  25834. var that = this,
  25835. ticksValues = that._fullTickValues,
  25836. ticks = [],
  25837. i;
  25838. if (!that._fullTickPositions) {
  25839. if (!ticksValues) {
  25840. that.getTickValues();
  25841. ticksValues = that._fullTickValues || []
  25842. }
  25843. for (i = 0; i < ticksValues.length; i++)
  25844. ticks.push({pos: that.translator.translate(ticksValues[i])});
  25845. that._fullTickPositions = that._correctTicksPosition(ticks)
  25846. }
  25847. return that._fullTickPositions
  25848. },
  25849. _drawTicks: function() {
  25850. var that = this,
  25851. options = that.options,
  25852. ticksOptions = options.tick,
  25853. i,
  25854. axisPosition = that.axisPosition,
  25855. tickStart = axisPosition - 4,
  25856. tickEnd = axisPosition + 4,
  25857. tick,
  25858. ticksToDraw;
  25859. if (!ticksOptions.visible)
  25860. return;
  25861. var drawLine = function(p11, p12, p21, p22) {
  25862. that.renderer.createLine(p11, p12, p21, p22, {
  25863. strokeWidth: 1,
  25864. stroke: ticksOptions.color,
  25865. strokeOpacity: ticksOptions.opacity
  25866. }).append(that._axisLineGroup)
  25867. };
  25868. ticksToDraw = that._prepareFullTicksToDraw();
  25869. if (options.isHorizontal)
  25870. for (i = 0; i < ticksToDraw.length; i++) {
  25871. tick = ticksToDraw[i];
  25872. drawLine(tick.pos, tickStart, tick.pos, tickEnd)
  25873. }
  25874. else
  25875. for (i = 0; i < ticksToDraw.length; i++) {
  25876. tick = ticksToDraw[i];
  25877. drawLine(tickStart, tick.pos, tickEnd, tick.pos)
  25878. }
  25879. },
  25880. setPercentLabelFormat: function() {
  25881. var labelOptions = this.options.label;
  25882. if (!this.hasLabelFormat)
  25883. labelOptions.format = 'percent'
  25884. },
  25885. resetAutoLabelFormat: function() {
  25886. var labelOptions = this.options.label;
  25887. if (!this.hasLabelFormat)
  25888. delete labelOptions.format
  25889. },
  25890. _drawLabels: function() {
  25891. var that = this,
  25892. i,
  25893. options = that.options,
  25894. renderer = that.renderer,
  25895. axisPosition = that.axisPosition,
  25896. labelOptions = options.label,
  25897. labelOffset = labelOptions.indentFromAxis,
  25898. labelsToDraw,
  25899. labelPoint,
  25900. label,
  25901. labels = [],
  25902. createText = options.isHorizontal ? renderer.createText : function(text, y, x, textOptions) {
  25903. return this.createText(text, x, y, textOptions)
  25904. },
  25905. emptyStrRegExp = /^\s+$/,
  25906. currentLabelConst = options.position === TOP || options.position === LEFT ? axisPosition - labelOffset : axisPosition + labelOffset,
  25907. text;
  25908. if (!labelOptions.visible || !that._axisElementsGroup)
  25909. return;
  25910. labelsToDraw = that._prepareLabelsToDraw();
  25911. if (labelsToDraw.length === 0 || labelsToDraw.hideLabels)
  25912. return true;
  25913. for (i = 0; i < labelsToDraw.length; i++) {
  25914. labelPoint = labelsToDraw[i];
  25915. text = formatLabel(labelPoint.text, labelOptions, {
  25916. min: options.min,
  25917. max: options.max
  25918. });
  25919. if (isDefinedUtils(text) && text !== '' && !emptyStrRegExp.test(text)) {
  25920. label = createText.call(renderer, text, labelPoint.pos, currentLabelConst, that.textOptions);
  25921. labels.push(label);
  25922. label.append(that._axisElementsGroup);
  25923. label.data({argument: labelPoint.text})
  25924. }
  25925. }
  25926. that.labels = labels
  25927. },
  25928. getMultipleAxesSpacing: function() {
  25929. return this.options.multipleAxesSpacing || 0
  25930. },
  25931. _drawTitle: function() {
  25932. var that = this,
  25933. i,
  25934. options = that.options,
  25935. renderer = that.renderer,
  25936. axisPosition = that.axisPosition,
  25937. titleOptions = options.title,
  25938. title,
  25939. attr = {
  25940. font: titleOptions.font,
  25941. opacity: titleOptions.opacity,
  25942. align: CENTER,
  25943. 'class': 'dx-chart-axis-title'
  25944. },
  25945. centerPosition = that.translator.translateSpecialCase(CANVAS_POSITION_PREFIX + CENTER),
  25946. x,
  25947. y;
  25948. if (!titleOptions.text || !that._axisTitleGroup)
  25949. return;
  25950. if (options.isHorizontal) {
  25951. x = centerPosition;
  25952. y = axisPosition
  25953. }
  25954. else {
  25955. if (options.position === LEFT)
  25956. attr.rotate = 270;
  25957. else
  25958. attr.rotate = 90;
  25959. x = axisPosition;
  25960. y = centerPosition
  25961. }
  25962. that.title = renderer.createText(titleOptions.text, x, y, attr).append(that._axisTitleGroup)
  25963. },
  25964. _drawGrid: function(borderOptions) {
  25965. var that = this,
  25966. positionsToDraw,
  25967. options = that.options,
  25968. gridOptions = options.grid,
  25969. i;
  25970. if (!gridOptions.visible)
  25971. return;
  25972. borderOptions = borderOptions || {visible: false};
  25973. var drawLine = function() {
  25974. var translator = that.translator,
  25975. orthogonalTranslator = that.orthogonalTranslator,
  25976. isHorizontal = options.isHorizontal,
  25977. canvasStart = isHorizontal ? LEFT : TOP,
  25978. canvasEnd = isHorizontal ? RIGHT : BOTTOM,
  25979. positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START),
  25980. positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END),
  25981. firstBorderLinePosition = borderOptions.visible && borderOptions[canvasStart] ? translator.translateSpecialCase(CANVAS_POSITION_PREFIX + canvasStart) : undefined,
  25982. lastBorderLinePosition = borderOptions.visible && borderOptions[canvasEnd] ? translator.translateSpecialCase(CANVAS_POSITION_PREFIX + canvasEnd) : undefined;
  25983. return function(tick) {
  25984. if (mathAbs(tick.pos - firstBorderLinePosition) < MAX_GRID_BORDER_ADHENSION || mathAbs(tick.pos - lastBorderLinePosition) < MAX_GRID_BORDER_ADHENSION)
  25985. return;
  25986. var p11 = tick.pos,
  25987. p12 = positionFrom,
  25988. p21 = tick.pos,
  25989. p22 = positionTo;
  25990. if (!isHorizontal) {
  25991. p11 = positionFrom;
  25992. p12 = p22 = tick.pos;
  25993. p21 = positionTo
  25994. }
  25995. that.renderer.createLine(p11, p12, p21, p22, {
  25996. strokeWidth: gridOptions.width,
  25997. stroke: gridOptions.color,
  25998. strokeOpacity: gridOptions.opacity
  25999. }).append(that._axisGridGroup)
  26000. }
  26001. }();
  26002. positionsToDraw = that._prepareFullTicksToDraw();
  26003. for (i = 0; i < positionsToDraw.length; i++)
  26004. drawLine(positionsToDraw[i])
  26005. },
  26006. _drawConstantLine: function() {
  26007. var that = this,
  26008. group = that._axisConstantLineGroup,
  26009. renderer = that.renderer,
  26010. options = that.options,
  26011. data = options.constantLines,
  26012. translator = that.translator,
  26013. orthogonalTranslator = that.orthogonalTranslator,
  26014. isHorizontal = options.isHorizontal,
  26015. i,
  26016. lines = [],
  26017. labels = [],
  26018. positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START),
  26019. positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END),
  26020. canvasStart = translator.translateSpecialCase(CANVAS_POSITION_START),
  26021. canvasEnd = translator.translateSpecialCase(CANVAS_POSITION_END),
  26022. range = translator.getBusinessRange();
  26023. var getPos = function(lineValue) {
  26024. var parsedValue = that.validateUnit(lineValue, "E2105", 'constantLine'),
  26025. value = translator.translate(parsedValue),
  26026. isContinous = !!(range.minVisible || range.maxVisible);
  26027. if (!isContinous && $.inArray(lineValue, range.categories || []) === -1 || !isDefinedUtils(value) || value < Math.min(canvasStart, canvasEnd) || value > Math.max(canvasStart, canvasEnd))
  26028. return {};
  26029. return {
  26030. value: value,
  26031. parsedValue: parsedValue
  26032. }
  26033. };
  26034. var drawLinesAndLabels = function(lineOptions) {
  26035. if (lineOptions.value === undefined)
  26036. return;
  26037. var pos = getPos(lineOptions.value),
  26038. labelOptions = lineOptions.label || {},
  26039. value = pos.value,
  26040. line,
  26041. attr = {
  26042. stroke: lineOptions.color,
  26043. strokeWidth: lineOptions.width,
  26044. dashStyle: lineOptions.dashStyle
  26045. };
  26046. if (!isDefinedUtils(value)) {
  26047. lines.push(null);
  26048. if (labelOptions.visible)
  26049. labels.push(null);
  26050. return
  26051. }
  26052. line = isHorizontal ? renderer.createLine(value, positionTo, value, positionFrom, attr) : renderer.createLine(positionFrom, value, positionTo, value, attr);
  26053. lines.push(line.append(group));
  26054. if (labelOptions.visible)
  26055. labels.push(that._drawConstantLineLabels(pos.parsedValue, labelOptions, value, group));
  26056. else
  26057. labels.push(null)
  26058. };
  26059. for (i = 0; i < data.length; i++)
  26060. drawLinesAndLabels(data[i]);
  26061. that.constantLines = lines;
  26062. that.constantLineLabels = labels
  26063. },
  26064. _checkAlignmentConstantLineLabels: function(labelOptions) {
  26065. var options = this.options;
  26066. labelOptions.verticalAlignment = (labelOptions.verticalAlignment || '').toLowerCase();
  26067. labelOptions.horizontalAlignment = (labelOptions.horizontalAlignment || '').toLowerCase();
  26068. if (options.isHorizontal && labelOptions.position === 'outside') {
  26069. labelOptions.verticalAlignment = labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
  26070. labelOptions.horizontalAlignment = CENTER
  26071. }
  26072. if (options.isHorizontal && labelOptions.position === 'inside') {
  26073. labelOptions.verticalAlignment = labelOptions.verticalAlignment === CENTER ? CENTER : labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
  26074. labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === LEFT ? LEFT : RIGHT
  26075. }
  26076. if (!options.isHorizontal && labelOptions.position === 'outside') {
  26077. labelOptions.verticalAlignment = CENTER;
  26078. labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === LEFT ? LEFT : RIGHT
  26079. }
  26080. if (!options.isHorizontal && labelOptions.position === 'inside') {
  26081. labelOptions.verticalAlignment = labelOptions.verticalAlignment === BOTTOM ? BOTTOM : TOP;
  26082. labelOptions.horizontalAlignment = labelOptions.horizontalAlignment === RIGHT ? RIGHT : labelOptions.horizontalAlignment === CENTER ? CENTER : LEFT
  26083. }
  26084. },
  26085. _drawConstantLineLabels: function(parsedValue, lineLabelOptions, value, group) {
  26086. var that = this,
  26087. text = lineLabelOptions.text,
  26088. orthogonalTranslator = that.orthogonalTranslator,
  26089. options = that.options,
  26090. labelOptions = options.label,
  26091. attr = {
  26092. align: CENTER,
  26093. font: $.extend({}, labelOptions.font, lineLabelOptions.font)
  26094. },
  26095. x,
  26096. y;
  26097. that._checkAlignmentConstantLineLabels(lineLabelOptions);
  26098. text = isDefinedUtils(text) ? text : formatLabel(parsedValue, labelOptions);
  26099. if (options.isHorizontal) {
  26100. x = value;
  26101. switch (lineLabelOptions.horizontalAlignment) {
  26102. case LEFT:
  26103. attr.align = RIGHT;
  26104. break;
  26105. case RIGHT:
  26106. attr.align = LEFT;
  26107. break
  26108. }
  26109. y = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.verticalAlignment)
  26110. }
  26111. else {
  26112. y = value;
  26113. x = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + lineLabelOptions.horizontalAlignment);
  26114. switch (lineLabelOptions.horizontalAlignment) {
  26115. case LEFT:
  26116. attr.align = lineLabelOptions.position === 'inside' ? LEFT : RIGHT;
  26117. break;
  26118. case CENTER:
  26119. attr.align = CENTER;
  26120. break;
  26121. case RIGHT:
  26122. attr.align = lineLabelOptions.position === 'inside' ? RIGHT : LEFT;
  26123. break
  26124. }
  26125. }
  26126. return that.renderer.createText(text, x, y, attr).append(group)
  26127. },
  26128. _adjustConstantLineLabels: function() {
  26129. var that = this,
  26130. options = that.options,
  26131. isHorizontal = options.isHorizontal,
  26132. lines = that.constantLines,
  26133. labels = that.constantLineLabels,
  26134. label,
  26135. line,
  26136. lineBox,
  26137. linesOptions,
  26138. labelOptions,
  26139. box,
  26140. x,
  26141. y,
  26142. i,
  26143. padding = isHorizontal ? {
  26144. top: 0,
  26145. bottom: 0
  26146. } : {
  26147. left: 0,
  26148. right: 0
  26149. };
  26150. if (labels === undefined && lines === undefined)
  26151. return;
  26152. for (i = 0; i < labels.length; i++) {
  26153. x = y = 0;
  26154. linesOptions = options.constantLines[i];
  26155. labelOptions = linesOptions.label;
  26156. label = labels[i];
  26157. if (label !== null) {
  26158. line = lines[i];
  26159. box = label.getBBox();
  26160. lineBox = line.getBBox();
  26161. if (isHorizontal)
  26162. if (labelOptions.position === 'inside') {
  26163. switch (labelOptions.horizontalAlignment) {
  26164. case LEFT:
  26165. x -= linesOptions.paddingLeftRight;
  26166. break;
  26167. default:
  26168. x += linesOptions.paddingLeftRight;
  26169. break
  26170. }
  26171. switch (labelOptions.verticalAlignment) {
  26172. case CENTER:
  26173. y += lineBox.y + lineBox.height / 2 - box.y - box.height / 2;
  26174. break;
  26175. case BOTTOM:
  26176. y -= linesOptions.paddingTopBottom;
  26177. break;
  26178. default:
  26179. y += linesOptions.paddingTopBottom + box.height;
  26180. break
  26181. }
  26182. }
  26183. else
  26184. switch (labelOptions.verticalAlignment) {
  26185. case BOTTOM:
  26186. y += box.height + linesOptions.paddingTopBottom - (box.y + box.height - that.orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + labelOptions.verticalAlignment));
  26187. if (padding[BOTTOM] < box.height + linesOptions.paddingTopBottom)
  26188. padding[BOTTOM] = box.height + linesOptions.paddingTopBottom;
  26189. break;
  26190. default:
  26191. y -= linesOptions.paddingTopBottom;
  26192. if (padding[TOP] < linesOptions.paddingTopBottom + box.height)
  26193. padding[TOP] = linesOptions.paddingTopBottom + box.height;
  26194. break
  26195. }
  26196. else if (labelOptions.position === 'inside') {
  26197. switch (labelOptions.horizontalAlignment) {
  26198. case CENTER:
  26199. x += lineBox.x + lineBox.width / 2 - box.x - box.width / 2;
  26200. break;
  26201. case RIGHT:
  26202. x -= linesOptions.paddingLeftRight;
  26203. break;
  26204. default:
  26205. x += linesOptions.paddingLeftRight;
  26206. break
  26207. }
  26208. switch (labelOptions.verticalAlignment) {
  26209. case BOTTOM:
  26210. y += lineBox.y - box.y + linesOptions.paddingTopBottom;
  26211. break;
  26212. default:
  26213. y -= linesOptions.paddingTopBottom;
  26214. break
  26215. }
  26216. }
  26217. else {
  26218. y += lineBox.y + lineBox.height / 2 - box.y - box.height / 2;
  26219. switch (labelOptions.horizontalAlignment) {
  26220. case RIGHT:
  26221. x += linesOptions.paddingLeftRight;
  26222. if (padding[RIGHT] < linesOptions.paddingLeftRight + box.width)
  26223. padding[RIGHT] = linesOptions.paddingLeftRight + box.width;
  26224. break;
  26225. default:
  26226. x -= linesOptions.paddingLeftRight;
  26227. if (padding[LEFT] < linesOptions.paddingLeftRight + box.width)
  26228. padding[LEFT] = linesOptions.paddingLeftRight + box.width;
  26229. break
  26230. }
  26231. }
  26232. label.move(x, y)
  26233. }
  26234. }
  26235. that.padding = padding
  26236. },
  26237. _drawStrip: function() {
  26238. var that = this,
  26239. renderer = that.renderer,
  26240. options = that.options,
  26241. stripData = options.strips,
  26242. translator = that.translator,
  26243. orthogonalTranslator = that.orthogonalTranslator,
  26244. range = translator.getBusinessRange(),
  26245. i,
  26246. stripLabels = [],
  26247. stripRects = [],
  26248. rect,
  26249. isHorizontal = options.isHorizontal,
  26250. stripOptions,
  26251. positionFrom,
  26252. positionTo,
  26253. stripPos,
  26254. stripLabelOptions,
  26255. attr;
  26256. if (options.stubData)
  26257. return;
  26258. var getPos = function(startV, endV) {
  26259. var isContinous = !!(range.minVisible || range.maxVisible),
  26260. cateories = range.categories || [],
  26261. start = translator.translate(that.validateUnit(startV, "E2105", "strip")),
  26262. end = translator.translate(that.validateUnit(endV, "E2105", "strip")),
  26263. canvasStart = translator.translateSpecialCase(CANVAS_POSITION_START),
  26264. canvasEnd = translator.translateSpecialCase(CANVAS_POSITION_END),
  26265. min = range.minVisible;
  26266. if (!isContinous && ($.inArray(startV, cateories) === -1 || $.inArray(endV, cateories) === -1))
  26267. return {
  26268. stripFrom: 0,
  26269. stripTo: 0
  26270. };
  26271. if (!isDefinedUtils(start) && isContinous)
  26272. start = startV < min ? canvasStart : canvasEnd;
  26273. if (!isDefinedUtils(end) && isContinous)
  26274. end = endV < min ? canvasStart : canvasEnd;
  26275. return start < end ? {
  26276. stripFrom: start,
  26277. stripTo: end
  26278. } : {
  26279. stripFrom: end,
  26280. stripTo: start
  26281. }
  26282. };
  26283. positionFrom = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_START);
  26284. positionTo = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_END);
  26285. for (i = 0; i < stripData.length; i++) {
  26286. stripOptions = stripData[i];
  26287. stripLabelOptions = stripOptions.label || {};
  26288. attr = {fill: stripOptions.color};
  26289. if (stripOptions.startValue !== undefined && stripOptions.endValue !== undefined && stripOptions.color !== undefined) {
  26290. stripPos = getPos(stripOptions.startValue, stripOptions.endValue);
  26291. if (stripPos.stripTo - stripPos.stripFrom === 0 || !stripPos.stripTo && stripPos.stripTo !== 0 || !stripPos.stripFrom && stripPos.stripFrom !== 0) {
  26292. stripRects.push(null);
  26293. if (stripLabelOptions.text)
  26294. stripLabels.push(null);
  26295. continue
  26296. }
  26297. 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);
  26298. stripRects.push(rect.append(that._axisStripGroup));
  26299. if (stripLabelOptions.text)
  26300. stripLabels.push(that._drawStripLabel(stripLabelOptions, stripPos.stripFrom, stripPos.stripTo));
  26301. else
  26302. stripLabels.push(null)
  26303. }
  26304. }
  26305. that.stripLabels = stripLabels;
  26306. that.stripRects = stripRects
  26307. },
  26308. _drawStripLabel: function(stripLabelOptions, stripFrom, stripTo) {
  26309. var that = this,
  26310. orthogonalTranslator = that.orthogonalTranslator,
  26311. options = that.options,
  26312. isHorizontal = options.isHorizontal,
  26313. attr = {
  26314. align: isHorizontal ? CENTER : LEFT,
  26315. font: $.extend({}, options.label.font, stripLabelOptions.font)
  26316. },
  26317. x,
  26318. y;
  26319. if (isHorizontal) {
  26320. if (stripLabelOptions.horizontalAlignment === CENTER) {
  26321. x = stripFrom + (stripTo - stripFrom) / 2;
  26322. attr.align = CENTER
  26323. }
  26324. else if (stripLabelOptions.horizontalAlignment === LEFT) {
  26325. x = stripFrom;
  26326. attr.align = LEFT
  26327. }
  26328. else if (stripLabelOptions.horizontalAlignment === RIGHT) {
  26329. x = stripTo;
  26330. attr.align = RIGHT
  26331. }
  26332. y = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.verticalAlignment)
  26333. }
  26334. else {
  26335. x = orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + stripLabelOptions.horizontalAlignment);
  26336. attr.align = stripLabelOptions.horizontalAlignment;
  26337. if (stripLabelOptions.verticalAlignment === TOP)
  26338. y = stripFrom;
  26339. else if (stripLabelOptions.verticalAlignment === CENTER)
  26340. y = stripTo + (stripFrom - stripTo) / 2;
  26341. else if (stripLabelOptions.verticalAlignment === BOTTOM)
  26342. y = stripTo
  26343. }
  26344. return that.renderer.createText(stripLabelOptions.text, x, y, attr).append(that._axisLableGroup)
  26345. },
  26346. _initAxisPositions: function() {
  26347. var that = this,
  26348. position = that.options.position,
  26349. delta = 0;
  26350. if (that.delta)
  26351. delta = that.delta[position] || 0;
  26352. that.axisPosition = that.orthogonalTranslator.translateSpecialCase(CANVAS_POSITION_PREFIX + position) + delta
  26353. },
  26354. _adjustLabels: function() {
  26355. var that = this,
  26356. options = that.options,
  26357. isHorizontal = options.isHorizontal,
  26358. position = options.position,
  26359. labels = that.labels,
  26360. label,
  26361. labelHeight,
  26362. isNeedLabelAdjustment,
  26363. staggeringSpacing,
  26364. i,
  26365. xt,
  26366. shift = that.padding && that.padding[position] || 0,
  26367. boxAxis = that._axisElementsGroup && that._axisElementsGroup.getBBox() || {},
  26368. box;
  26369. if (!options.label.visible || !labels || !labels.length)
  26370. return;
  26371. for (i = 0; i < labels.length; i++) {
  26372. label = labels[i];
  26373. box = label.getBBox();
  26374. if (isHorizontal && position === BOTTOM)
  26375. label.applySettings({y: 2 * label.settings.y - box.y + shift});
  26376. else if (!isHorizontal) {
  26377. if (position === LEFT)
  26378. if (that.textOptions.align === RIGHT)
  26379. xt = box.x + box.width - shift;
  26380. else if (that.textOptions.align === CENTER)
  26381. xt = box.x + box.width / 2 - shift - (boxAxis.width / 2 || 0);
  26382. else
  26383. xt = box.x - shift - (boxAxis.width || 0);
  26384. else if (that.textOptions.align === CENTER)
  26385. xt = box.x + box.width / 2 + (boxAxis.width / 2 || 0) + shift;
  26386. else if (that.textOptions.align === RIGHT)
  26387. xt = box.x + box.width + (boxAxis.width || 0) + shift;
  26388. else
  26389. xt = box.x + shift;
  26390. label.applySettings({
  26391. x: xt,
  26392. y: label.settings.y + ~~(label.settings.y - box.y - box.height / 2)
  26393. })
  26394. }
  26395. else if (isHorizontal && position === TOP)
  26396. label.applySettings({y: 2 * label.settings.y - box.y - box.height - shift})
  26397. }
  26398. isNeedLabelAdjustment = isHorizontal && that.overlappingBehavior && that.overlappingBehavior.mode === 'stagger';
  26399. that._testIsNeedLabelAdjustment = isNeedLabelAdjustment;
  26400. if (isNeedLabelAdjustment) {
  26401. labelHeight = 0;
  26402. for (i = 0; i < labels.length; i = i + 2) {
  26403. label = labels[i];
  26404. box = label.getBBox();
  26405. if (box.height > labelHeight)
  26406. labelHeight = box.height
  26407. }
  26408. staggeringSpacing = that.overlappingBehavior.staggeringSpacing;
  26409. that._testStaggeringSpacing = staggeringSpacing;
  26410. labelHeight = Math.round(labelHeight) + staggeringSpacing;
  26411. for (i = 1; i < labels.length; i = i + 2) {
  26412. label = labels[i];
  26413. if (position === BOTTOM)
  26414. label.move(0, labelHeight);
  26415. else if (position === TOP)
  26416. label.move(0, -labelHeight)
  26417. }
  26418. for (i = 0; i < labels.length; i++)
  26419. labels[i].rotate(0)
  26420. }
  26421. },
  26422. _adjustStripLabels: function() {
  26423. var that = this,
  26424. labelOptions,
  26425. labels = that.stripLabels,
  26426. rects = that.stripRects,
  26427. label,
  26428. i,
  26429. box,
  26430. rectBox,
  26431. stripOptions,
  26432. x,
  26433. y;
  26434. if (labels === undefined && rects === undefined)
  26435. return;
  26436. for (i = 0; i < labels.length; i++) {
  26437. x = y = 0;
  26438. stripOptions = that.options.strips[i];
  26439. labelOptions = stripOptions.label;
  26440. label = labels[i];
  26441. if (label !== null) {
  26442. box = label.getBBox();
  26443. rectBox = rects[i].getBBox();
  26444. if (labelOptions.horizontalAlignment === LEFT)
  26445. x += stripOptions.paddingLeftRight;
  26446. else if (labelOptions.horizontalAlignment === RIGHT)
  26447. x -= stripOptions.paddingLeftRight;
  26448. if (labelOptions.verticalAlignment === TOP)
  26449. y += rectBox.y - box.y + stripOptions.paddingTopBottom;
  26450. else if (labelOptions.verticalAlignment === CENTER)
  26451. y += rectBox.y + rectBox.height / 2 - box.y - box.height / 2;
  26452. else if (labelOptions.verticalAlignment === BOTTOM)
  26453. y -= stripOptions.paddingTopBottom;
  26454. label.move(x, y)
  26455. }
  26456. }
  26457. },
  26458. _adjustTitle: function() {
  26459. var that = this,
  26460. options = that.options,
  26461. position = options.position,
  26462. title = that.title,
  26463. margin = options.title.margin,
  26464. boxGroup,
  26465. boxTitle;
  26466. if (!title || !that._axisElementsGroup)
  26467. return;
  26468. boxTitle = title.getBBox();
  26469. boxGroup = that._axisElementsGroup.getBBox();
  26470. if (options.isHorizontal)
  26471. if (position === BOTTOM)
  26472. title.applySettings({
  26473. y: boxGroup.isEmpty ? undefined : boxGroup.y + boxGroup.height,
  26474. translateY: margin + boxTitle.height
  26475. });
  26476. else
  26477. title.applySettings({
  26478. y: boxGroup.isEmpty ? undefined : boxGroup.y,
  26479. translateY: -margin
  26480. });
  26481. else if (position === LEFT)
  26482. title.applySettings({
  26483. x: boxGroup.isEmpty ? undefined : boxGroup.x,
  26484. translateX: -margin
  26485. });
  26486. else
  26487. title.applySettings({
  26488. x: boxGroup.isEmpty ? undefined : boxGroup.x + boxGroup.width,
  26489. translateX: margin
  26490. })
  26491. },
  26492. draw: function(externalOptions, adjustAxis) {
  26493. var that = this,
  26494. options = that.options,
  26495. isHorizontal = options.isHorizontal,
  26496. cssClass = isHorizontal ? 'dxc-h-axis' : 'dxc-v-axis',
  26497. stripClass = isHorizontal ? 'dxc-h-strips' : 'dxc-v-strips',
  26498. constantLineClass = isHorizontal ? 'dxc-h-constant-lines' : 'dxc-v-constant-lines';
  26499. externalOptions = externalOptions || {};
  26500. var debug = DX.utils.debug;
  26501. debug.assertParam(this.translator, 'translator was not set before Draw call');
  26502. if (that._axisGroup) {
  26503. that._axisGroup.detach();
  26504. that._axisStripGroup.detach();
  26505. that._axisLableGroup.detach();
  26506. that._axisConstantLineGroup.detach();
  26507. that._axisTitleGroup ? that._axisTitleGroup.clear() : !adjustAxis && (that._axisTitleGroup = that.renderer.createGroup({'class': 'dxc-title'}).append(that._axisGroup));
  26508. that._axisGridGroup.clear();
  26509. that._axisElementsGroup ? that._axisElementsGroup.clear() : !adjustAxis && (that._axisElementsGroup = that.renderer.createGroup({'class': 'dxc-elements'}).append(that._axisGroup));
  26510. that._axisLineGroup.clear();
  26511. that._axisStripGroup.clear();
  26512. that._axisConstantLineGroup.clear();
  26513. that._axisLableGroup.clear()
  26514. }
  26515. else {
  26516. that._axisGroup = that.renderer.createGroup({
  26517. 'class': cssClass,
  26518. clipId: that.clipRectID
  26519. });
  26520. that._axisStripGroup = that.renderer.createGroup({'class': stripClass});
  26521. that._axisGridGroup = that.renderer.createGroup({'class': 'dxc-grid'}).append(that._axisGroup);
  26522. that._axisElementsGroup = that.renderer.createGroup({'class': 'dxc-elements'}).append(that._axisGroup);
  26523. that._axisLineGroup = that.renderer.createGroup({'class': 'dxc-line'}).append(that._axisGroup);
  26524. that._axisTitleGroup = that.renderer.createGroup({'class': 'dxc-title'}).append(that._axisGroup);
  26525. that._axisConstantLineGroup = that.renderer.createGroup({'class': constantLineClass});
  26526. that._axisLableGroup = that.renderer.createGroup({'class': 'dxc-axis-labels'})
  26527. }
  26528. that._initAxisPositions();
  26529. if (!that._virtual) {
  26530. that._drawAxis();
  26531. that._drawTicks();
  26532. that._drawLabels();
  26533. that._drawTitle()
  26534. }
  26535. if (options.strips)
  26536. that._drawStrip();
  26537. if (options.constantLines)
  26538. that._drawConstantLine();
  26539. that._drawGrid(externalOptions.borderOptions);
  26540. that._axisStripGroup.append(that.stripsGroup);
  26541. that._axisConstantLineGroup.append(that.constantLinesGroup);
  26542. that._axisGroup.append(that.axesContainerGroup);
  26543. that._axisLableGroup.append(that.labelAxesGroup);
  26544. that._adjustConstantLineLabels();
  26545. that._adjustLabels();
  26546. that._adjustStripLabels();
  26547. that._adjustTitle();
  26548. that._setBoundingRect()
  26549. },
  26550. _setBoundingRect: function() {
  26551. var that = this,
  26552. options = that.options,
  26553. axisBox = that._axisElementsGroup ? that._axisElementsGroup.getBBox() : {
  26554. x: 0,
  26555. y: 0,
  26556. width: 0,
  26557. height: 0,
  26558. isEmpty: true
  26559. },
  26560. lineBox = that._axisLineGroup.getBBox(),
  26561. placeholderSize = options.placeholderSize,
  26562. start,
  26563. isHorizontal = options.isHorizontal,
  26564. coord = isHorizontal && 'y' || 'x',
  26565. side = isHorizontal && 'height' || 'width',
  26566. axisTitleBox = that.title && that._axisTitleGroup ? that._axisTitleGroup.getBBox() : axisBox;
  26567. if (axisBox.isEmpty && axisTitleBox.isEmpty && !placeholderSize) {
  26568. that.boundingRect = axisBox;
  26569. return
  26570. }
  26571. start = lineBox[coord] || that.axisPosition;
  26572. if (options.position === (isHorizontal && BOTTOM || RIGHT)) {
  26573. axisBox[side] = placeholderSize || axisTitleBox[coord] + axisTitleBox[side] - start;
  26574. axisBox[coord] = start
  26575. }
  26576. else {
  26577. axisBox[side] = placeholderSize || lineBox[side] + start - axisTitleBox[coord];
  26578. axisBox[coord] = axisTitleBox.isEmpty ? start : axisTitleBox[coord]
  26579. }
  26580. that.boundingRect = axisBox
  26581. },
  26582. getBoundingRect: function() {
  26583. return this._axisElementsGroup ? this.boundingRect : {
  26584. x: 0,
  26585. y: 0,
  26586. width: 0,
  26587. height: 0
  26588. }
  26589. },
  26590. shift: function(x, y) {
  26591. var settings = {};
  26592. if (x)
  26593. settings.translateX = x;
  26594. if (y)
  26595. settings.translateY = y;
  26596. this._axisGroup.applySettings(settings)
  26597. },
  26598. applyClipRect: function(clipId) {
  26599. this._axisStripGroup.applySettings({clipId: clipId})
  26600. },
  26601. validate: function(isArgumentAxis, incidentOccured) {
  26602. var that = this,
  26603. options = that.options,
  26604. range = options.range,
  26605. parseUtils = new core.ParseUtils,
  26606. dataType = isArgumentAxis ? options.argumentType : options.valueType,
  26607. parser = dataType ? parseUtils.getParser(dataType, 'axis') : function(unit) {
  26608. return unit
  26609. };
  26610. that.parser = parser;
  26611. that.incidentOccured = incidentOccured;
  26612. options.dataType = dataType;
  26613. if (options.min)
  26614. options.min = that.validateUnit(options.min, "E2106");
  26615. if (options.max)
  26616. options.max = that.validateUnit(options.max, "E2106");
  26617. if (range.min)
  26618. range.min = that.validateUnit(range.min);
  26619. if (range.max)
  26620. range.max = that.validateUnit(range.max)
  26621. },
  26622. validateUnit: function(unit, idError, parameters) {
  26623. var that = this,
  26624. dataType = that.options.dataType;
  26625. unit = that.parser(unit);
  26626. if (unit === undefined && idError)
  26627. that.incidentOccured(idError, [parameters]);
  26628. return unit
  26629. },
  26630. adjustZoomValues: function(min, max) {
  26631. var that = this,
  26632. range = that.options.range;
  26633. min = that.validateUnit(min);
  26634. max = that.validateUnit(max);
  26635. if (range && isDefinedUtils(range.min)) {
  26636. min = isDefinedUtils(min) ? range.min < min ? min : range.min : min;
  26637. max = isDefinedUtils(max) ? range.min < max ? max : range.min : max
  26638. }
  26639. if (range && isDefinedUtils(range.max)) {
  26640. max = isDefinedUtils(max) ? range.max > max ? max : range.max : max;
  26641. min = isDefinedUtils(min) ? range.max > min ? min : range.max : min
  26642. }
  26643. that.minRangeArg = min;
  26644. that.maxRangeArg = max;
  26645. return {
  26646. min: min,
  26647. max: max
  26648. }
  26649. },
  26650. getRangeData: function() {
  26651. var that = this,
  26652. options = that.options,
  26653. optionsRange = options.range,
  26654. range = {},
  26655. min,
  26656. max;
  26657. var addValueMarginToRange = function(prefix) {
  26658. if (options.valueMarginsEnabled) {
  26659. if (isDefinedUtils(options[prefix])) {
  26660. range[prefix] = options[prefix];
  26661. range[prefix + 'Priority'] = AXIS_VALUE_MARGIN_PRIORITY
  26662. }
  26663. }
  26664. else {
  26665. range[prefix] = 0;
  26666. range[prefix + 'Priority'] = AXIS_VALUE_MARGIN_PRIORITY
  26667. }
  26668. };
  26669. if (isDefinedUtils(optionsRange.min) && isDefinedUtils(optionsRange.max)) {
  26670. min = optionsRange.min < optionsRange.max ? optionsRange.min : optionsRange.max;
  26671. max = optionsRange.max > optionsRange.min ? optionsRange.max : optionsRange.min
  26672. }
  26673. else {
  26674. min = optionsRange.min;
  26675. max = optionsRange.max
  26676. }
  26677. range.min = min;
  26678. range.max = max;
  26679. addValueMarginToRange('minValueMargin');
  26680. addValueMarginToRange('maxValueMargin');
  26681. range.stick = !options.valueMarginsEnabled;
  26682. range.categories = optionsRange.categories;
  26683. range.dataType = options.dataType;
  26684. range.axisType = options.type;
  26685. if (range.axisType === 'logarithmic')
  26686. range.base = options.logarithmBase;
  26687. if (options.isHorizontal) {
  26688. range.minVisible = isDefinedUtils(that.minRangeArg) ? that.minRangeArg : optionsRange.min;
  26689. range.maxVisible = isDefinedUtils(that.maxRangeArg) ? that.maxRangeArg : optionsRange.max;
  26690. range.invert = options.inverted
  26691. }
  26692. else {
  26693. range.minVisible = optionsRange.min;
  26694. range.maxVisible = optionsRange.max;
  26695. range.invert = options.inverted || options.type === 'discrete' && options.oppositeDirectionYAxis
  26696. }
  26697. return range
  26698. }
  26699. })
  26700. })(jQuery, DevExpress);
  26701. /*! Module viz-charts, file baseChart.js */
  26702. (function($, DX, undefined) {
  26703. var ui = DX.ui,
  26704. charts = DX.viz.charts,
  26705. utils = DX.utils,
  26706. TRACKER_RENDERING_DELAY = 1200,
  26707. resizeRedrawOptions = {
  26708. animate: false,
  26709. isResize: true
  26710. },
  26711. ACTIONS_BY_PRIORITY = ['reinit', '_reinitDataSource', '_handleDataSourceChanged', 'force_render'],
  26712. core = DX.viz.core,
  26713. DEFAULT_ANIMATION_OPTIONS = {
  26714. asyncSeriesRendering: true,
  26715. asyncTrackersRendering: true,
  26716. trackerRenderingDelay: TRACKER_RENDERING_DELAY
  26717. };
  26718. charts.BaseChart = core.BaseWidget.inherit({
  26719. _setDefaultOptions: function() {
  26720. this.callBase();
  26721. this.option({
  26722. done: $.noop,
  26723. drawn: $.noop,
  26724. seriesClick: null,
  26725. pointClick: null,
  26726. legendClick: null,
  26727. argumentAxisClick: null,
  26728. seriesHover: null,
  26729. pointHover: null,
  26730. seriesSelected: null,
  26731. pointSelected: null,
  26732. seriesSelectionChanged: null,
  26733. pointSelectionChanged: null,
  26734. seriesHoverChanged: null,
  26735. pointHoverChanged: null
  26736. })
  26737. },
  26738. _createThemeManager: function() {
  26739. return charts.factory.createThemeManager(this.option())
  26740. },
  26741. _init: function() {
  26742. this.__TRACKER_RENDERING_DELAY = TRACKER_RENDERING_DELAY;
  26743. var that = this;
  26744. that.callBase();
  26745. that.themeManager = this._createThemeManager();
  26746. that._initRenderer();
  26747. that.canvasClipRect = that.renderer.createClipRect();
  26748. that._createHtmlStructure();
  26749. that._needHandleRenderComplete = true;
  26750. that.layoutManager = charts.factory.createChartLayoutManager(that.themeManager.getOptions("adaptiveLayout"));
  26751. that._reinit();
  26752. that._element().css({webkitUserSelect: 'none'}).on('contextmenu', function(event) {
  26753. that.eventType = 'contextmenu';
  26754. if (ui.events.isTouchEvent(event) || ui.events.isPointerEvent(event))
  26755. event.preventDefault()
  26756. }).on('MSHoldVisual', function(event) {
  26757. that.eventType = 'MSHoldVisual';
  26758. event.preventDefault()
  26759. })
  26760. },
  26761. _reinit: function() {
  26762. var that = this;
  26763. that.layoutManager.update(that);
  26764. that._createTracker();
  26765. that._reinitDataSource()
  26766. },
  26767. _createHtmlStructure: function() {
  26768. var that = this,
  26769. renderer = that.renderer;
  26770. that._panesBackgroundGroup = renderer.createGroup({'class': 'dxc-background'});
  26771. that._titleGroup = renderer.createGroup({'class': 'dxc-title'});
  26772. that._legendGroup = renderer.createGroup({
  26773. 'class': 'dxc-legend',
  26774. clipId: that._getCanvasClipRectID()
  26775. });
  26776. that._stripsGroup = renderer.createGroup({'class': 'dxc-strips-group'});
  26777. that._constantLinesGroup = renderer.createGroup({'class': 'dxc-constant-lines-group'});
  26778. that._axesGroup = renderer.createGroup({'class': 'dxc-axes-group'});
  26779. that._panesBorderGroup = renderer.createGroup({'class': 'dxc-border'});
  26780. that._labelAxesGroup = renderer.createGroup({'class': 'dxc-strips-labels-group'});
  26781. that._seriesGroup = renderer.createGroup({'class': 'dxc-series-group'});
  26782. that._labelsGroup = renderer.createGroup({'class': 'dxc-labels-group'});
  26783. that._tooltipGroup = renderer.createGroup({'class': 'dxc-tooltip'});
  26784. that._trackerGroup = renderer.createGroup({
  26785. 'class': 'dxc-trackers',
  26786. opacity: 0.0001,
  26787. stroke: "gray",
  26788. fill: "gray"
  26789. });
  26790. that._crosshairTrackerGroup = renderer.createGroup({
  26791. 'class': 'dxc-crosshair-trackers',
  26792. stroke: 'none',
  26793. fill: 'grey'
  26794. }).append(that._trackerGroup);
  26795. that._seriesTrackerGroup = renderer.createGroup({'class': 'dxc-series-trackers'}).append(that._trackerGroup);
  26796. that._markerTrackerGroup = renderer.createGroup({
  26797. 'class': 'dxc-markers-trackers',
  26798. stroke: 'none',
  26799. fill: 'grey'
  26800. }).append(that._trackerGroup);
  26801. that._crossHairCursorGroup = renderer.createGroup({'class': 'dxc-crosshair-cursor'})
  26802. },
  26803. _cleanHtmlStructure: function() {
  26804. var that = this;
  26805. that._panesBackgroundGroup && that._panesBackgroundGroup.clear();
  26806. that._titleGroup && that._titleGroup.clear();
  26807. that._legendGroup && (that._legendGroup.detach(), that._legendGroup.clear());
  26808. that._stripsGroup && (that._stripsGroup.detach(), that._stripsGroup.clear());
  26809. that._constantLinesGroup && (that._constantLinesGroup.detach(), that._constantLinesGroup.clear());
  26810. that._axesGroup && (that._axesGroup.detach(), that._axesGroup.clear());
  26811. that._labelAxesGroup && (that._labelAxesGroup.detach(), that._labelAxesGroup.clear());
  26812. that._seriesGroup && (that._seriesGroup.detach(), that._seriesGroup.clear());
  26813. that._labelsGroup && (that._labelsGroup.detach(), that._labelsGroup.clear());
  26814. that._trackerGroup && (that._trackerGroup.detach(), that._seriesTrackerGroup.clear(), that._markerTrackerGroup.clear(), that._crosshairTrackerGroup.clear());
  26815. that._panesBorderGroup && that._panesBorderGroup.clear();
  26816. that._tooltipGroup && that._tooltipGroup.clear();
  26817. that._crossHairCursorGroup && (that._crossHairCursorGroup.clear(), that._crossHairCursorGroup.detach())
  26818. },
  26819. _disposeObjectsInArray: function(propName, fieldNames) {
  26820. $.each(this[propName] || [], function(_, item) {
  26821. if (fieldNames && item)
  26822. $.each(fieldNames, function(_, field) {
  26823. item[field] && item[field].dispose()
  26824. });
  26825. else
  26826. item && item.dispose()
  26827. });
  26828. this[propName] = null
  26829. },
  26830. _dispose: function() {
  26831. var that = this,
  26832. disposeObject = function(propName) {
  26833. that[propName] && that[propName].dispose(),
  26834. that[propName] = null
  26835. },
  26836. detachGroup = function(groupName) {
  26837. that[groupName] && that[groupName].detach()
  26838. },
  26839. disposeObjectsInArray = this._disposeObjectsInArray;
  26840. clearTimeout(that.delayedRedraw);
  26841. that.callBase();
  26842. disposeObjectsInArray.call(that, "businessRanges", ["arg", "val"]);
  26843. that.translators = null;
  26844. disposeObjectsInArray.call(that, "series");
  26845. disposeObject("layoutManager");
  26846. disposeObject("themeManager");
  26847. disposeObject("renderer");
  26848. disposeObject("tracker");
  26849. disposeObject("tooltip");
  26850. disposeObject("chartTitle");
  26851. that.paneAxis = null;
  26852. that._userOptions = null;
  26853. that.dirtyCanvas = null;
  26854. that.canvas = null;
  26855. detachGroup("_legendGroup");
  26856. detachGroup("_stripsGroup");
  26857. detachGroup("_constantLinesGroup");
  26858. detachGroup("_axesGroup");
  26859. detachGroup("_labelAxesGroup");
  26860. detachGroup("_seriesGroup");
  26861. detachGroup("_labelsGroup");
  26862. detachGroup("_trackerGroup");
  26863. detachGroup("_crossHairCursorGroup");
  26864. disposeObject("canvasClipRect");
  26865. disposeObject("_panesBackgroundGroup");
  26866. disposeObject("_titleGroup");
  26867. disposeObject("_legendGroup");
  26868. disposeObject("_stripsGroup");
  26869. disposeObject("_constantLinesGroup");
  26870. disposeObject("_axesGroup");
  26871. disposeObject("_labelAxesGroup");
  26872. disposeObject("_panesBorderGroup");
  26873. disposeObject("_seriesGroup");
  26874. disposeObject("_labelsGroup");
  26875. disposeObject("_tooltipGroup");
  26876. disposeObject("_crossHairCursorGroup");
  26877. disposeObject("_seriesTrackerGroup");
  26878. disposeObject("_markerTrackerGroup");
  26879. disposeObject("_crosshairTrackerGroup");
  26880. disposeObject("_trackerGroup");
  26881. that._disposeLoadIndicator()
  26882. },
  26883. _clean: function _clean(hideLoadIndicator) {
  26884. this.renderer && this.renderer.stopAllAnimations();
  26885. hideLoadIndicator && this.hideLoadingIndicator();
  26886. this._cleanHtmlStructure();
  26887. this.callBase();
  26888. this._saveDirtyCanvas()
  26889. },
  26890. _getAnimationOptions: function() {
  26891. return $.extend({}, DEFAULT_ANIMATION_OPTIONS, this.themeManager.getOptions("animation"))
  26892. },
  26893. _initRenderer: function _initRenderer() {
  26894. if (this.renderer)
  26895. return;
  26896. this.renderer = core.CoreFactory.createRenderer({
  26897. animation: this._getAnimationOptions(),
  26898. cssClass: 'dxc dxc-chart',
  26899. pathModified: this.option('pathModified'),
  26900. rtl: this.themeManager.getOptions('rtlEnabled')
  26901. })
  26902. },
  26903. _initSeries: function() {
  26904. this.series = this.series || this._populateSeries()
  26905. },
  26906. _reinitDataSource: function() {
  26907. this._refreshDataSource()
  26908. },
  26909. _saveDirtyCanvas: function() {
  26910. this.dirtyCanvas = $.extend({}, this.canvas)
  26911. },
  26912. _resize: function() {
  26913. this._render(resizeRedrawOptions)
  26914. },
  26915. _calculateCanvas: function() {
  26916. var canvas = this.themeManager.getOptions('size'),
  26917. result = {},
  26918. container = this._element();
  26919. if (!utils.isDefined(canvas.width))
  26920. result.width = container.width() || 400;
  26921. else
  26922. result.width = canvas.width < 0 ? 0 : canvas.width;
  26923. if (!utils.isDefined(canvas.height))
  26924. result.height = container.height() || 400;
  26925. else
  26926. result.height = canvas.height < 0 ? 0 : canvas.height;
  26927. return $.extend({}, result, this.themeManager.getOptions('margin'))
  26928. },
  26929. _createTracker: function() {
  26930. var that = this,
  26931. tooltipOptions = that.themeManager.getOptions('tooltip') || {};
  26932. if (that.tracker)
  26933. that.tracker.dispose();
  26934. that.tracker = charts.factory.createTracker({
  26935. series: that.series,
  26936. valueAxis: that._valueAxes,
  26937. argumentAxis: that._argumentAxes,
  26938. seriesSelectionMode: that.themeManager.getOptions('seriesSelectionMode'),
  26939. pointSelectionMode: that.themeManager.getOptions('pointSelectionMode'),
  26940. tooltipShown: that.option('tooltipShown'),
  26941. tooltipHidden: that.option('tooltipHidden'),
  26942. markerTrackerGroup: that._markerTrackerGroup,
  26943. crossHairOptions: that._crossHairOptions,
  26944. seriesTrackerGroup: that._seriesTrackerGroup,
  26945. seriesGroup: that._seriesGroup,
  26946. tooltipEnabled: tooltipOptions.enabled,
  26947. renderer: that.renderer,
  26948. events: {
  26949. seriesClick: that.option('seriesClick'),
  26950. pointClick: that.option('pointClick'),
  26951. argumentAxisClick: that.option('argumentAxisClick'),
  26952. seriesHover: that.option('seriesHover'),
  26953. seriesSelected: that.option('seriesSelected'),
  26954. pointHover: that.option('pointHover'),
  26955. pointSelected: that.option('pointSelected'),
  26956. legendClick: that.option('legendClick'),
  26957. seriesSelectionChanged: that.option('seriesSelectionChanged'),
  26958. pointSelectionChanged: that.option('pointSelectionChanged'),
  26959. seriesHoverChanged: that.option('seriesHoverChanged'),
  26960. pointHoverChanged: that.option('pointHoverChanged')
  26961. }
  26962. })
  26963. },
  26964. _updateTracker: function() {
  26965. var that = this;
  26966. if (!that.tracker)
  26967. that._createTracker();
  26968. else
  26969. that.tracker._reinit({
  26970. series: that.series,
  26971. valueAxis: that._valueAxes,
  26972. argumentAxis: that._argumentAxes,
  26973. legendGroup: that.legend.getTrackerGroup(),
  26974. legendCallback: $.proxy(that.legend.getActionCallback, that.legend)
  26975. })
  26976. },
  26977. _render: function(drawOptions) {
  26978. this._optionsInitializing = false;
  26979. var that = this,
  26980. renderer = that.renderer,
  26981. updatedCanvas = that.canvas,
  26982. container = this._element(),
  26983. currentDirtyCanvas = that._calculateCanvas(),
  26984. oldDirtyCanvas = that.dirtyCanvas;
  26985. drawOptions = drawOptions || {recreateCanvas: true};
  26986. drawOptions.recreateCanvas = drawOptions.recreateCanvas || !renderer.isInitialized();
  26987. if (!drawOptions.force && oldDirtyCanvas && oldDirtyCanvas.width === currentDirtyCanvas.width && oldDirtyCanvas.height === currentDirtyCanvas.height && !that.hiddenContainer) {
  26988. that.stopRedraw = true;
  26989. return
  26990. }
  26991. clearTimeout(that.delayedRedraw);
  26992. if (drawOptions.recreateCanvas)
  26993. that.canvas = updatedCanvas = that._calculateCanvas();
  26994. if (updatedCanvas.width && updatedCanvas.height && container.is(':visible'))
  26995. that.hiddenContainer = false;
  26996. else {
  26997. that._incidentOccured('W2001', [that.NAME]);
  26998. that.hiddenContainer = true;
  26999. that.stopRedraw = true;
  27000. renderer.detachContainer();
  27001. return
  27002. }
  27003. if (drawOptions.recreateCanvas) {
  27004. renderer.recreateCanvas(that.canvas.width, that.canvas.height);
  27005. renderer.draw(that._element()[0]);
  27006. that._reappendLoadIndicator();
  27007. that._updateLoadIndicator(undefined, updatedCanvas.width, updatedCanvas.height);
  27008. that._updateCanvasClipRect()
  27009. }
  27010. that.renderer.stopAllAnimations(true);
  27011. that.layoutManager.update(that);
  27012. that._cleanGroups(drawOptions);
  27013. that._saveDirtyCanvas()
  27014. },
  27015. _cleanGroups: function(drawOptions) {
  27016. var that = this;
  27017. that._stripsGroup.detach();
  27018. that._constantLinesGroup.detach();
  27019. that._axesGroup.detach();
  27020. that._labelAxesGroup.detach();
  27021. that._labelsGroup.detach();
  27022. that._tooltipGroup.detach();
  27023. that._crossHairCursorGroup.detach();
  27024. if (!drawOptions || drawOptions.drawLegend) {
  27025. that._legendGroup.detach();
  27026. that._legendGroup.clear()
  27027. }
  27028. if (!drawOptions || drawOptions.drawTitle) {
  27029. that._titleGroup.detach();
  27030. that._titleGroup.clear()
  27031. }
  27032. that._stripsGroup.clear();
  27033. that._constantLinesGroup.clear();
  27034. that._axesGroup.clear();
  27035. that._labelAxesGroup.clear();
  27036. that._labelsGroup.clear();
  27037. that._tooltipGroup.clear();
  27038. that._crossHairCursorGroup.clear();
  27039. that._crosshairTrackerGroup.clear()
  27040. },
  27041. _drawTitle: function() {
  27042. var that = this,
  27043. options = that.themeManager.getOptions("title"),
  27044. width = that.canvas.width - that.canvas.left - that.canvas.right;
  27045. options._incidentOccured = that._incidentOccured;
  27046. if (that.chartTitle)
  27047. that.chartTitle.update(options, width);
  27048. else
  27049. that.chartTitle = charts.factory.createTitle(that.renderer, options, width, that._titleGroup)
  27050. },
  27051. _createTooltip: function() {
  27052. var that = this,
  27053. tooltipOptions = $.extend(true, {
  27054. canvasWidth: that.canvas.width,
  27055. canvasHeight: that.canvas.height
  27056. }, that.themeManager.getOptions('tooltip') || {}),
  27057. tooltipCoords,
  27058. point = this.tracker.pointAtShownTooltip;
  27059. if (!$.isFunction(tooltipOptions.customizeText) && utils.isDefined(tooltipOptions.customizeText)) {
  27060. that._incidentOccured("E2103", ['customizeText']);
  27061. tooltipOptions.customizeText = undefined
  27062. }
  27063. if (that.tooltip)
  27064. that.tooltip.update(tooltipOptions);
  27065. else
  27066. that.tooltip = core.CoreFactory.createTooltip(tooltipOptions, that._tooltipGroup, that.renderer);
  27067. that.tracker.setTooltip(that.tooltip);
  27068. if (point) {
  27069. tooltipCoords = point.getTooltipCoords();
  27070. that.tooltip.move(~~tooltipCoords.x, ~~tooltipCoords.y, tooltipCoords.offset);
  27071. that.tooltip.show()
  27072. }
  27073. },
  27074. _prepareDrawOptions: function(drawOptions) {
  27075. var animationOptions = this._getAnimationOptions(),
  27076. options;
  27077. options = $.extend({}, {
  27078. force: false,
  27079. adjustAxes: true,
  27080. drawLegend: true,
  27081. drawTitle: true,
  27082. adjustSeriesLabels: true,
  27083. animate: animationOptions.enabled,
  27084. animationPointsLimit: animationOptions.maxPointCountSupported,
  27085. asyncSeriesRendering: animationOptions.asyncSeriesRendering,
  27086. asyncTrackersRendering: animationOptions.asyncTrackersRendering,
  27087. trackerRenderingDelay: animationOptions.trackerRenderingDelay
  27088. }, drawOptions);
  27089. if (!utils.isDefined(options.recreateCanvas))
  27090. options.recreateCanvas = options.adjustAxes && options.drawLegend && options.drawTitle;
  27091. return options
  27092. },
  27093. _processRefreshData: function(newRefreshAction) {
  27094. var currentRefreshActionPosition = $.inArray(this._currentRefreshData, ACTIONS_BY_PRIORITY),
  27095. newRefreshActionPosition = $.inArray(newRefreshAction, ACTIONS_BY_PRIORITY);
  27096. if (!this._currentRefreshData || currentRefreshActionPosition >= 0 && newRefreshActionPosition < currentRefreshActionPosition)
  27097. this._currentRefreshData = newRefreshAction
  27098. },
  27099. _disposeSeries: function() {
  27100. var that = this;
  27101. that.tracker._clean();
  27102. $.each(that.series || [], function(_, series) {
  27103. series.dispose()
  27104. });
  27105. that.series = null;
  27106. $.each(that.seriesFamilies || [], function(_, family) {
  27107. family.dispose()
  27108. });
  27109. that.seriesFamilies = null
  27110. },
  27111. _optionChanged: function(name) {
  27112. var that = this,
  27113. themeManager = this.themeManager;
  27114. themeManager.resetOptions(name);
  27115. themeManager.update(that._options);
  27116. if (name === 'animation') {
  27117. that.renderer.updateAnimationOptions(this._getAnimationOptions());
  27118. return
  27119. }
  27120. clearTimeout(that.delayedRedraw);
  27121. switch (name) {
  27122. case'dataSource':
  27123. that._needHandleRenderComplete = true;
  27124. that._processRefreshData('_reinitDataSource');
  27125. break;
  27126. case'palette':
  27127. that.themeManager.updatePalette(this.option(name));
  27128. that._disposeSeries();
  27129. that._needHandleRenderComplete = true;
  27130. that._processRefreshData('_handleDataSourceChanged');
  27131. break;
  27132. case'series':
  27133. case'commonSeriesSettings':
  27134. case'containerBackgroundColor':
  27135. case'dataPrepareSettings':
  27136. that._disposeSeries();
  27137. that._needHandleRenderComplete = true;
  27138. that._processRefreshData('_handleDataSourceChanged');
  27139. break;
  27140. case'legend':
  27141. case'seriesTemplate':
  27142. that._processRefreshData('_handleDataSourceChanged');
  27143. break;
  27144. case'title':
  27145. that._processRefreshData('force_render');
  27146. break;
  27147. case'valueAxis':
  27148. case'argumentAxis':
  27149. case'commonAxisSettings':
  27150. that._needHandleRenderComplete = true;
  27151. that._processRefreshData('reinit');
  27152. that._disposeSeries();
  27153. that.paneAxis = {};
  27154. break;
  27155. case'panes':
  27156. case'defaultPane':
  27157. that._disposeSeries();
  27158. that.paneAxis = {};
  27159. that._needHandleRenderComplete = true;
  27160. that._processRefreshData('reinit');
  27161. break;
  27162. case'size':
  27163. that._processRefreshData('force_render');
  27164. break;
  27165. case'rotated':
  27166. case'equalBarWidth':
  27167. case'customizePoint':
  27168. case'customizeLabel':
  27169. that._disposeSeries();
  27170. that._needHandleRenderComplete = true;
  27171. that._processRefreshData('reinit');
  27172. break;
  27173. case'theme':
  27174. that._disposeSeries();
  27175. themeManager.setTheme(that.option(name));
  27176. that._processRefreshData('reinit');
  27177. break;
  27178. default:
  27179. that._processRefreshData('reinit')
  27180. }
  27181. that.callBase.apply(that, arguments)
  27182. },
  27183. _getLoadIndicatorOption: function() {
  27184. return this.themeManager.getOptions("loadingIndicator")
  27185. },
  27186. _refresh: function() {
  27187. var that = this;
  27188. this.renderer.stopAllAnimations(true);
  27189. if (that._currentRefreshData) {
  27190. switch (that._currentRefreshData) {
  27191. case'force_render':
  27192. that._render({force: true});
  27193. break;
  27194. case'reinit':
  27195. that._reinit(true);
  27196. break;
  27197. default:
  27198. that[that._currentRefreshData] && that[that._currentRefreshData]()
  27199. }
  27200. delete that._currentRefreshData
  27201. }
  27202. else
  27203. that._render({force: true})
  27204. },
  27205. _dataSourceOptions: function() {
  27206. return {
  27207. paginate: false,
  27208. _preferSync: true
  27209. }
  27210. },
  27211. _updateCanvasClipRect: function(canvas) {
  27212. var that = this,
  27213. width,
  27214. height;
  27215. canvas = canvas || that.canvas;
  27216. width = Math.max(canvas.width - canvas.left - canvas.right, 0);
  27217. height = Math.max(canvas.height - canvas.top - canvas.bottom, 0);
  27218. that.canvasClipRect.updateRectangle({
  27219. x: canvas.left,
  27220. y: canvas.top,
  27221. width: width,
  27222. height: height
  27223. });
  27224. that.canvasClipRect.append()
  27225. },
  27226. _getCanvasClipRectID: function() {
  27227. return this.canvasClipRect.id
  27228. },
  27229. _handleDataSourceChanged: function() {
  27230. clearTimeout(this.delayedRedraw);
  27231. this._dataSpecificInit(true)
  27232. },
  27233. _groupSeries: function() {
  27234. this._groupedSeries = [this.series]
  27235. },
  27236. _dataSpecificInit: function(needRedraw) {
  27237. this._initSeries();
  27238. this._repopulateSeries();
  27239. this._handleSeriesPopulated(needRedraw)
  27240. },
  27241. _processSingleSeries: function(){},
  27242. _repopulateSeries: function() {
  27243. var that = this,
  27244. parsedData,
  27245. data = that._dataSource && that._dataSource.items(),
  27246. dataValidatorOptions = that.themeManager.getOptions('dataPrepareSettings'),
  27247. seriesTemplate = that.themeManager.getOptions('seriesTemplate');
  27248. if (that._dataSource && seriesTemplate) {
  27249. that._templatedSeries = utils.processSeriesTemplate(seriesTemplate, that._dataSource.items());
  27250. that._populateSeries();
  27251. delete that._templatedSeries;
  27252. data = that.teamplateData || data
  27253. }
  27254. that._groupSeries();
  27255. that._dataValidator = charts.factory.createDataValidator(data, that._groupedSeries, that._incidentOccured, dataValidatorOptions);
  27256. parsedData = that._dataValidator.validate();
  27257. that.themeManager.resetPalette();
  27258. $.each(that.series, function(_, singleSeries) {
  27259. singleSeries.updateData(parsedData);
  27260. that._processSingleSeries(singleSeries)
  27261. })
  27262. },
  27263. _handleRenderComplete: function() {
  27264. var that = this,
  27265. userHandle = this.option('done'),
  27266. allSeriesInited = true;
  27267. if (that._needHandleRenderComplete) {
  27268. $.each(that.series, function(_, s) {
  27269. allSeriesInited = allSeriesInited && s.canRenderCompleteHandle()
  27270. });
  27271. if (allSeriesInited) {
  27272. that._needHandleRenderComplete = false;
  27273. $.isFunction(userHandle) && userHandle.call(that)
  27274. }
  27275. }
  27276. },
  27277. _renderTitleAndLegend: function(drawOptions, legendHasInsidePosition) {
  27278. var that = this,
  27279. titleOptions = that.themeManager.getOptions("title"),
  27280. drawTitle = titleOptions.text && drawOptions.drawTitle,
  27281. drawLegend = drawOptions.drawLegend && that.legend && !legendHasInsidePosition,
  27282. drawElements = [];
  27283. if (drawTitle) {
  27284. that._titleGroup.append();
  27285. that._drawTitle();
  27286. drawElements.push(that.chartTitle)
  27287. }
  27288. if (drawLegend) {
  27289. that._legendGroup.append();
  27290. drawElements.push(that.legend)
  27291. }
  27292. drawElements.length && that.layoutManager.drawElements(drawElements, that.canvas);
  27293. if (drawTitle)
  27294. that.layoutManager.correctSizeElement(that.chartTitle, that.canvas)
  27295. },
  27296. getAllSeries: function getAllSeries() {
  27297. return this.series.slice()
  27298. },
  27299. getSeriesByName: function getSeriesByName(name) {
  27300. var found = null;
  27301. $.each(this.series, function(i, singleSeries) {
  27302. if (singleSeries.name === name) {
  27303. found = singleSeries;
  27304. return false
  27305. }
  27306. });
  27307. return found
  27308. },
  27309. getSeriesByPos: function getSeriesByPos(pos) {
  27310. return this.series[pos]
  27311. },
  27312. getSelectedSeries: function getSelectedSeries() {
  27313. return null
  27314. },
  27315. clearSelection: function clearSelection() {
  27316. this.tracker.clearSelection()
  27317. },
  27318. hideTooltip: function() {
  27319. this.tracker._hideTooltip()
  27320. },
  27321. showLoadingIndicator: function() {
  27322. this._showLoadIndicator(this.themeManager.getOptions("loadingIndicator"), this.canvas || {})
  27323. },
  27324. render: function(renderOptions) {
  27325. this._render(renderOptions)
  27326. },
  27327. getSize: function() {
  27328. var canvas = this.canvas || {};
  27329. return {
  27330. width: canvas.width,
  27331. height: canvas.height
  27332. }
  27333. }
  27334. }).include(ui.DataHelperMixin)
  27335. })(jQuery, DevExpress);
  27336. /*! Module viz-charts, file chart.js */
  27337. (function($, DX, undefined) {
  27338. var core = DX.viz.core,
  27339. charts = DX.viz.charts,
  27340. utils = DX.utils,
  27341. MAX_ADJUSTMENT_ATTEMPTS = 5,
  27342. DEFAULT_PANE_NAME = 'default',
  27343. DEFAULT_AXIS_NAME = 'defaultAxisName',
  27344. DEFAULT_BUSINESS_RANGE_VALUE_MARGIN = 0.1,
  27345. ASYNC_SERIES_RENDERING_DELAY = 25,
  27346. _each = $.each;
  27347. function prepareAxis(axisOptions) {
  27348. return $.isArray(axisOptions) ? axisOptions.length === 0 ? [{}] : axisOptions : [axisOptions]
  27349. }
  27350. charts.Chart = charts.BaseChart.inherit({
  27351. _setDefaultOptions: function() {
  27352. this.callBase();
  27353. this.option({
  27354. defaultPane: DEFAULT_PANE_NAME,
  27355. panes: [{
  27356. name: DEFAULT_PANE_NAME,
  27357. border: {}
  27358. }]
  27359. })
  27360. },
  27361. _dispose: function() {
  27362. var that = this,
  27363. disposeObjectsInArray = this._disposeObjectsInArray;
  27364. that.callBase();
  27365. that.panes = null;
  27366. that.legend && (that.legend.dispose(), that.legend = null);
  27367. disposeObjectsInArray.call(that, "panesBackground");
  27368. disposeObjectsInArray.call(that, "panesClipRects");
  27369. disposeObjectsInArray.call(that, "financialPanesClipRects");
  27370. disposeObjectsInArray.call(that, "_argumentAxes");
  27371. disposeObjectsInArray.call(that, "_valueAxes");
  27372. disposeObjectsInArray.call(that, "seriesFamilies");
  27373. _each(that._paneTrackerGroups || [], function(_, groups) {
  27374. groups.paneSeriesGroup.dispose();
  27375. groups.paneMarkerGroup.dispose()
  27376. });
  27377. that._paneTrackerGroups = null
  27378. },
  27379. _init: function() {
  27380. this.__ASYNC_SERIES_RENDERING_DELAY = ASYNC_SERIES_RENDERING_DELAY;
  27381. this.paneAxis = {};
  27382. this._crossHairOptions = {};
  27383. this.callBase()
  27384. },
  27385. _reinit: function(needRedraw) {
  27386. var that = this;
  27387. that.translators = {};
  27388. that.panes = that._createPanes();
  27389. that._populateAxes();
  27390. that.callBase();
  27391. delete that._seriesInitializing;
  27392. if (!that.series)
  27393. that._dataSpecificInit();
  27394. else
  27395. that._correctValueAxes();
  27396. that._endLoading(function() {
  27397. needRedraw && that._render({force: true})
  27398. })
  27399. },
  27400. _correctBusinessRange: function(range, tickInterval, setTicksAtUnitBeginning) {
  27401. var min = 'min',
  27402. max = 'max';
  27403. if (!tickInterval || !utils.isDefined(range[min]) || !utils.isDefined(range[max]))
  27404. return false;
  27405. var tickIntervalRange = {},
  27406. originInterval = tickInterval;
  27407. tickInterval = $.isNumeric(tickInterval) ? tickInterval : utils.convertDateTickIntervalToMilliseconds(tickInterval);
  27408. if (tickInterval >= Math.abs(range[max] - range[min])) {
  27409. if (utils.isDate(range[min])) {
  27410. if (!$.isNumeric(originInterval)) {
  27411. tickIntervalRange[min] = utils.addInterval(range[min], originInterval, true);
  27412. tickIntervalRange[max] = utils.addInterval(range[max], originInterval, false)
  27413. }
  27414. else {
  27415. tickIntervalRange[min] = new Date(range[min].valueOf() - tickInterval);
  27416. tickIntervalRange[max] = new Date(range[max].valueOf() + tickInterval)
  27417. }
  27418. if (setTicksAtUnitBeginning) {
  27419. utils.correctDateWithUnitBeginning(tickIntervalRange[max], originInterval);
  27420. utils.correctDateWithUnitBeginning(tickIntervalRange[min], originInterval)
  27421. }
  27422. }
  27423. else {
  27424. tickIntervalRange[min] = range[min] - tickInterval;
  27425. tickIntervalRange[max] = range[max] + tickInterval
  27426. }
  27427. range.addRange(tickIntervalRange);
  27428. return true
  27429. }
  27430. return false
  27431. },
  27432. _seriesVisibilityChanged: function() {
  27433. this._processSeriesFamilies();
  27434. this._populateBusinessRange();
  27435. this.renderer.stopAllAnimations(true);
  27436. this._render({
  27437. force: true,
  27438. asyncSeriesRendering: false,
  27439. asyncTrackersRendering: false
  27440. })
  27441. },
  27442. _populateBusinessRange: function(visibleArea) {
  27443. var that = this,
  27444. businessRanges = [],
  27445. aggregationRange,
  27446. minBound,
  27447. maxBound,
  27448. i,
  27449. themeManager = that.themeManager,
  27450. rotated = themeManager.getOptions('rotated'),
  27451. singleSeriesRange,
  27452. valAxes = that._valueAxes,
  27453. valueAxes = {},
  27454. argAxes = that._argumentAxes,
  27455. useAggregation = themeManager.getOptions('useAggregation'),
  27456. argumentTickInterval,
  27457. setTicksAtUnitBeginning,
  27458. paneAxis = that.paneAxis,
  27459. groupedSeries = that._groupedSeries;
  27460. that._disposeObjectsInArray("businessRanges", ["arg", "val"]);
  27461. var argRange = new core.Range({
  27462. rotated: !!rotated,
  27463. minValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN,
  27464. maxValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN
  27465. });
  27466. _each(valAxes, function(_, axis) {
  27467. valueAxes[axis.name] = axis
  27468. });
  27469. _each(paneAxis, function(paneName, pane) {
  27470. _each(pane, function(axisName, _) {
  27471. var seriesForRange = [],
  27472. firstSeriesForRange,
  27473. options,
  27474. valueAxesForRange,
  27475. valRange = new core.Range({
  27476. isValueRange: true,
  27477. rotated: !!rotated,
  27478. pane: paneName,
  27479. axis: axisName,
  27480. minValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN,
  27481. maxValueMargin: DEFAULT_BUSINESS_RANGE_VALUE_MARGIN
  27482. }),
  27483. valueType,
  27484. calcInterval;
  27485. _each(groupedSeries, function(_, particularSeriesGroup) {
  27486. if (particularSeriesGroup[0].pane === paneName && particularSeriesGroup[0].axis === axisName)
  27487. seriesForRange = particularSeriesGroup
  27488. });
  27489. _each(valAxes, function(_, axis) {
  27490. if (axis.pane === paneName && axis.name === axisName) {
  27491. valueAxesForRange = axis;
  27492. return false
  27493. }
  27494. });
  27495. firstSeriesForRange = seriesForRange && seriesForRange.length ? seriesForRange[0] : {};
  27496. _each(argAxes, function(_, axis) {
  27497. var options = axis.options;
  27498. options.type = firstSeriesForRange.argumentAxisType || options.type;
  27499. options.argumentType = firstSeriesForRange.argumentType || options.argumentType;
  27500. axis.validate(true, that._incidentOccured);
  27501. argRange = argRange.addRange(axis.getRangeData());
  27502. argumentTickInterval = options.tickInterval;
  27503. setTicksAtUnitBeginning = options.setTicksAtUnitBeginning;
  27504. calcInterval = axis.calcInterval
  27505. });
  27506. options = valueAxesForRange.options;
  27507. options.type = firstSeriesForRange.valueAxisType || options.type;
  27508. options.valueType = firstSeriesForRange.valueType || options.valueType;
  27509. valueAxesForRange.validate(false, that._incidentOccured);
  27510. var axisRange = new core.Range(valueAxesForRange.getRangeData());
  27511. valueType = valueType || options.valueType === 'datetime' ? 'datetime' : undefined;
  27512. valRange = valRange.addRange(axisRange);
  27513. minBound = valRange.min;
  27514. maxBound = valRange.max;
  27515. for (i = 0; i < seriesForRange.length; i++) {
  27516. if (visibleArea) {
  27517. visibleArea.minVal = minBound;
  27518. visibleArea.maxVal = maxBound;
  27519. if (useAggregation && !visibleArea.adjustOnZoom) {
  27520. aggregationRange = seriesForRange[i]._originalBusinessRange;
  27521. visibleArea.minVal = utils.isDefined(visibleArea.minVal) ? visibleArea.minVal : aggregationRange.val.min;
  27522. visibleArea.maxVal = utils.isDefined(visibleArea.maxVal) ? visibleArea.maxVal : aggregationRange.val.max
  27523. }
  27524. }
  27525. singleSeriesRange = seriesForRange[i].getRangeData(visibleArea, calcInterval);
  27526. valRange = valRange.addRange(singleSeriesRange.val);
  27527. argRange = argRange.addRange(singleSeriesRange.arg)
  27528. }
  27529. if (!valRange.isDefined())
  27530. valRange.setStubData(valueType);
  27531. businessRanges.push({val: valRange})
  27532. })
  27533. });
  27534. if (!argRange.isDefined())
  27535. argRange.setStubData(argAxes[0].options.argumentType);
  27536. var bussinesRangeCorrectedWithTickInterval = that._correctBusinessRange(argRange, argumentTickInterval, setTicksAtUnitBeginning);
  27537. !bussinesRangeCorrectedWithTickInterval && argRange.applyValueMargins();
  27538. _each(businessRanges, function(_, item) {
  27539. var range = item.val,
  27540. vAxis = valueAxes[range.axis];
  27541. range.applyValueMargins();
  27542. if (vAxis && vAxis.options.showZero)
  27543. range.correctValueZeroLevel();
  27544. item.arg = argRange
  27545. });
  27546. that.businessRanges = businessRanges
  27547. },
  27548. _groupSeries: function() {
  27549. var that = this,
  27550. panes = that.panes,
  27551. valAxes = that._valueAxes,
  27552. paneList = $.map(panes, function(pane) {
  27553. return pane.name
  27554. }),
  27555. series = that.series,
  27556. paneAxis = that.paneAxis,
  27557. groupedSeries = that._groupedSeries = [];
  27558. var getFirstAxisNameForPane = function(axes, paneName) {
  27559. var result;
  27560. for (var i = 0; i < axes.length; i++)
  27561. if (axes[i].pane === paneName) {
  27562. result = axes[i].name;
  27563. break
  27564. }
  27565. if (!result)
  27566. result = valAxes[0].name;
  27567. return result
  27568. };
  27569. _each(series, function(i, particularSeries) {
  27570. particularSeries.axis = particularSeries.axis || getFirstAxisNameForPane(valAxes, particularSeries.pane);
  27571. if (particularSeries.axis) {
  27572. paneAxis[particularSeries.pane] = paneAxis[particularSeries.pane] || {};
  27573. paneAxis[particularSeries.pane][particularSeries.axis] = true
  27574. }
  27575. });
  27576. _each(valAxes, function(_, axis) {
  27577. if (axis.name && axis.pane && $.inArray(axis.pane, paneList) != -1) {
  27578. paneAxis[axis.pane] = paneAxis[axis.pane] || {};
  27579. paneAxis[axis.pane][axis.name] = true
  27580. }
  27581. });
  27582. that._correctValueAxes();
  27583. var hideGridsOnNonFirstValueAxisForPane = function(paneName) {
  27584. var axesForPane = [],
  27585. firstShownAxis;
  27586. _each(valAxes, function(_, axis) {
  27587. if (axis.pane === paneName)
  27588. axesForPane.push(axis)
  27589. });
  27590. if (axesForPane.length > 1 && that.themeManager.getOptions('synchronizeMultiAxes'))
  27591. _each(axesForPane, function(_, axis) {
  27592. var gridOpt = axis.options.grid;
  27593. if (firstShownAxis && gridOpt && gridOpt.visible)
  27594. gridOpt.visible = false;
  27595. else
  27596. firstShownAxis = firstShownAxis ? firstShownAxis : gridOpt && gridOpt.visible
  27597. })
  27598. };
  27599. _each(paneAxis, function(paneName, pane) {
  27600. hideGridsOnNonFirstValueAxisForPane(paneName);
  27601. _each(pane, function(axisName, _) {
  27602. var group = [];
  27603. _each(series, function(_, particularSeries) {
  27604. if (particularSeries.pane === paneName && particularSeries.axis === axisName)
  27605. group.push(particularSeries)
  27606. });
  27607. group.length && groupedSeries.push(group)
  27608. })
  27609. })
  27610. },
  27611. _cleanPanesClipRects: function(clipArrayName) {
  27612. var that = this,
  27613. clipArray = that[clipArrayName];
  27614. _each(clipArray || [], function(_, clipRect) {
  27615. clipRect && clipRect.remove()
  27616. });
  27617. that[clipArrayName] = []
  27618. },
  27619. _createPanes: function() {
  27620. var that = this,
  27621. panes = that.option('panes'),
  27622. panesNameCounter = 0,
  27623. bottomPaneName;
  27624. if (panes && utils.isArray(panes) && !panes.length || $.isEmptyObject(panes))
  27625. panes = that.initialOption("panes");
  27626. that._cleanPanesClipRects('panesClipRects');
  27627. that._cleanPanesClipRects('financialPanesClipRects');
  27628. that.defaultPane = that.option('defaultPane');
  27629. panes = $.isArray(panes) ? panes : panes ? [panes] : [];
  27630. _each(panes, function(_, pane) {
  27631. pane.name = !utils.isDefined(pane.name) ? DEFAULT_PANE_NAME + panesNameCounter++ : pane.name
  27632. });
  27633. if (!that._doesPaneExists(panes, that.defaultPane) && panes.length > 0) {
  27634. bottomPaneName = panes[panes.length - 1].name;
  27635. that._incidentOccured('W2101', [that.defaultPane, bottomPaneName]);
  27636. that.defaultPane = bottomPaneName
  27637. }
  27638. panes = that.themeManager.getOptions('rotated') ? panes.reverse() : panes;
  27639. return panes
  27640. },
  27641. _doesPaneExists: function(panes, paneName) {
  27642. var found = false;
  27643. _each(panes, function(_, pane) {
  27644. if (pane.name === paneName) {
  27645. found = true;
  27646. return false
  27647. }
  27648. });
  27649. return found
  27650. },
  27651. _populateSeries: function() {
  27652. var that = this,
  27653. themeManager = that.themeManager,
  27654. hasSeriesTemplate = !!themeManager.getOptions('seriesTemplate'),
  27655. series = hasSeriesTemplate ? that._templatedSeries : that.option('series'),
  27656. allSeriesOptions = $.isArray(series) ? series : series ? [series] : [],
  27657. argumentAxisOptions = that.option('argumentAxis'),
  27658. valueAxisOptions = that.option('valueAxis'),
  27659. data,
  27660. particularSeriesOptions,
  27661. particularSeries,
  27662. rotated = themeManager.getOptions('rotated'),
  27663. i,
  27664. paneList = $.map(that.panes, function(pane) {
  27665. return pane.name
  27666. }),
  27667. paneName,
  27668. paneIndex;
  27669. that.teamplateData = [];
  27670. _each(that._paneTrackerGroups || [], function(_, groups) {
  27671. groups.paneSeriesGroup.remove();
  27672. groups.paneMarkerGroup.remove()
  27673. });
  27674. that._paneTrackerGroups = [];
  27675. _each(that.panes, function(_, pane) {
  27676. var paneSeriesTrackerGroup = that.renderer.createGroup({'class': 'dxc-pane-tracker'}),
  27677. paneMarkerTrackerGroup = that.renderer.createGroup({'class': 'dxc-pane-tracker'});
  27678. that._paneTrackerGroups.push({
  27679. paneSeriesGroup: paneSeriesTrackerGroup,
  27680. paneMarkerGroup: paneMarkerTrackerGroup
  27681. })
  27682. });
  27683. that._disposeSeries();
  27684. that.series = [];
  27685. themeManager.resetPalette();
  27686. for (i = 0; i < allSeriesOptions.length; i++) {
  27687. particularSeriesOptions = $.extend(true, {}, allSeriesOptions[i]);
  27688. if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))
  27689. particularSeriesOptions.type = '';
  27690. data = particularSeriesOptions.data;
  27691. particularSeriesOptions.data = null;
  27692. particularSeriesOptions.rotated = rotated;
  27693. particularSeriesOptions.customizePoint = themeManager.getOptions("customizePoint");
  27694. particularSeriesOptions.customizeLabel = themeManager.getOptions("customizeLabel");
  27695. particularSeriesOptions.visibilityChanged = $.proxy(this._seriesVisibilityChanged, this);
  27696. particularSeriesOptions.resolveLabelsOverlapping = themeManager.getOptions("resolveLabelsOverlapping");
  27697. if (argumentAxisOptions) {
  27698. particularSeriesOptions.argumentCategories = argumentAxisOptions.categories;
  27699. particularSeriesOptions.argumentAxisType = argumentAxisOptions.type;
  27700. particularSeriesOptions.argumentType = argumentAxisOptions.argumentType
  27701. }
  27702. if (valueAxisOptions)
  27703. if (utils.isArray(valueAxisOptions))
  27704. _each(valueAxisOptions, function(iter, options) {
  27705. if (!particularSeriesOptions.axis && !iter || particularSeriesOptions.axis === options.name) {
  27706. particularSeriesOptions.valueCategories = options.categories;
  27707. particularSeriesOptions.valueAxisType = options.type;
  27708. particularSeriesOptions.valueType = options.valueType;
  27709. particularSeriesOptions.showZero = options.showZero
  27710. }
  27711. });
  27712. else {
  27713. particularSeriesOptions.valueCategories = valueAxisOptions.categories;
  27714. particularSeriesOptions.valueAxisType = valueAxisOptions.type;
  27715. particularSeriesOptions.valueType = valueAxisOptions.valueType;
  27716. particularSeriesOptions.showZero = valueAxisOptions.showZero
  27717. }
  27718. particularSeriesOptions.incidentOccured = that._incidentOccured;
  27719. if (!particularSeriesOptions.name)
  27720. particularSeriesOptions.name = 'Series ' + (i + 1).toString();
  27721. var seriesTheme = themeManager.getOptions("series", particularSeriesOptions);
  27722. seriesTheme.pane = seriesTheme.pane || that.defaultPane;
  27723. paneName = seriesTheme.pane;
  27724. paneIndex = that._getPaneIndex(paneName);
  27725. if ($.inArray(paneName, paneList) === -1)
  27726. continue;
  27727. seriesTheme.seriesGroup = that._seriesGroup;
  27728. seriesTheme.labelsGroup = that._labelsGroup;
  27729. seriesTheme.trackersGroup = that._paneTrackerGroups[paneIndex].paneSeriesGroup;
  27730. seriesTheme.markerTrackerGroup = that._paneTrackerGroups[paneIndex].paneMarkerGroup;
  27731. particularSeries = core.CoreFactory.createSeries(that.renderer, seriesTheme);
  27732. if (!particularSeries.isUpdated)
  27733. that._incidentOccured("E2101", [seriesTheme.type]);
  27734. else {
  27735. particularSeries.index = i;
  27736. that.series.push(particularSeries)
  27737. }
  27738. if (hasSeriesTemplate) {
  27739. _each(data, function(_, data) {
  27740. _each(particularSeries.getTeamplatedFields(), function(_, field) {
  27741. data[field.teamplateField] = data[field.originalField]
  27742. });
  27743. that.teamplateData.push(data)
  27744. });
  27745. particularSeries.updateTeamplateFieldNames()
  27746. }
  27747. }
  27748. return that.series
  27749. },
  27750. _createValueAxis: function(axisOptions, rotated, tickProvider) {
  27751. var that = this,
  27752. axis;
  27753. axisOptions = that.themeManager.getOptions("valueAxis", $.extend({
  27754. isHorizontal: rotated,
  27755. tickProvider: tickProvider,
  27756. incidentOccured: that._incidentOccured
  27757. }, axisOptions), rotated);
  27758. if (axisOptions.strips)
  27759. _each(axisOptions.strips, function(i, strips) {
  27760. axisOptions.strips[i] = $.extend(true, {}, axisOptions.stripStyle, axisOptions.strips[i])
  27761. });
  27762. if (axisOptions.constantLines)
  27763. _each(axisOptions.constantLines, function(i, line) {
  27764. axisOptions.constantLines[i] = $.extend(true, {}, axisOptions.constantLineStyle, line)
  27765. });
  27766. axis = charts.factory.createAxis(that.renderer, axisOptions);
  27767. axis.name = axisOptions.name;
  27768. axis.pane = axis.pane || axisOptions.pane;
  27769. axis.priority = axisOptions.priority;
  27770. return axis
  27771. },
  27772. _disposeAxes: function() {
  27773. var that = this;
  27774. _each(that._valueAxes || [], function(_, axis) {
  27775. axis.dispose()
  27776. });
  27777. _each(that._argumentAxes || [], function(_, axis) {
  27778. axis.dispose()
  27779. });
  27780. that._valueAxes = null;
  27781. that._argumentAxes = null
  27782. },
  27783. _populateAxes: function() {
  27784. var that = this,
  27785. valueAxes = [],
  27786. argumentAxes = [],
  27787. panes = that.panes,
  27788. themeManager = that.themeManager,
  27789. rotated = themeManager.getOptions('rotated'),
  27790. valueAxisOptions = that.option('valueAxis') || {},
  27791. argumentOption = that.option('argumentAxis') || {},
  27792. argumentAxesOptions = prepareAxis(argumentOption),
  27793. valueAxesOptions = prepareAxis(valueAxisOptions),
  27794. axis,
  27795. axisNames = [],
  27796. tickProvider = core.CoreFactory.getTickProvider(),
  27797. paneWithNonVirtualAxis;
  27798. that._disposeAxes();
  27799. var createArgumentAxis = function(axisOptions, virtual) {
  27800. axisOptions = that.themeManager.getOptions("argumentAxis", $.extend(true, {
  27801. isHorizontal: !rotated,
  27802. tickProvider: tickProvider,
  27803. pane: that.defaultPane,
  27804. incidentOccured: that._incidentOccured
  27805. }, axisOptions), rotated);
  27806. if (axisOptions.strips)
  27807. _each(axisOptions.strips, function(i, strips) {
  27808. axisOptions.strips[i] = $.extend(true, {}, axisOptions.stripStyle, axisOptions.strips[i])
  27809. });
  27810. if (axisOptions.constantLines)
  27811. _each(axisOptions.constantLines, function(i, line) {
  27812. axisOptions.constantLines[i] = $.extend(true, {}, axisOptions.constantLineStyle, line)
  27813. });
  27814. axis = charts.factory.createAxis(that.renderer, axisOptions);
  27815. axis._virtual = virtual;
  27816. argumentAxes.push(axis);
  27817. return axis
  27818. };
  27819. if (rotated)
  27820. paneWithNonVirtualAxis = argumentAxesOptions[0].position === 'right' ? panes[panes.length - 1].name : panes[0].name;
  27821. else
  27822. paneWithNonVirtualAxis = argumentAxesOptions[0].position === 'top' ? panes[0].name : panes[panes.length - 1].name;
  27823. _each(panes, function(_, pane) {
  27824. var paneName = pane.name,
  27825. virtual = paneName != paneWithNonVirtualAxis;
  27826. var axisOptions = $.extend(true, {}, argumentAxesOptions[0], {pane: paneName});
  27827. createArgumentAxis(axisOptions, virtual)
  27828. });
  27829. var valueAxesCounter = 0;
  27830. var getNextAxisName = function() {
  27831. return DEFAULT_AXIS_NAME + valueAxesCounter++
  27832. };
  27833. var unique = function(array) {
  27834. var values = {},
  27835. i,
  27836. len = array.length;
  27837. for (i = 0; i < len; i++)
  27838. values[array[i]] = true;
  27839. return $.map(values, function(_, key) {
  27840. return key
  27841. })
  27842. };
  27843. _each(valueAxesOptions, function(priority, axisOptions) {
  27844. var axisPanes = [],
  27845. name = axisOptions.name;
  27846. if (name && $.inArray(name, axisNames) != -1) {
  27847. that._incidentOccured("E2102");
  27848. return
  27849. }
  27850. name && axisNames.push(name);
  27851. if (axisOptions.pane)
  27852. axisPanes.push(axisOptions.pane);
  27853. if (axisOptions.panes && axisOptions.panes.length)
  27854. axisPanes = axisPanes.concat(axisOptions.panes.slice(0));
  27855. axisPanes = unique(axisPanes);
  27856. if (!axisPanes.length)
  27857. axisPanes.push(undefined);
  27858. _each(axisPanes, function(_, pane) {
  27859. valueAxes.push(that._createValueAxis($.extend(true, {}, axisOptions, {
  27860. name: name || getNextAxisName(),
  27861. pane: pane,
  27862. priority: priority
  27863. }), rotated, tickProvider))
  27864. })
  27865. });
  27866. that._valueAxes = valueAxes;
  27867. that._argumentAxes = argumentAxes
  27868. },
  27869. _correctValueAxes: function() {
  27870. var that = this,
  27871. rotated = that.themeManager.getOptions('rotated'),
  27872. valueAxisOptions = that.option('valueAxis') || {},
  27873. valueAxesOptions = $.isArray(valueAxisOptions) ? valueAxisOptions : [valueAxisOptions],
  27874. tickProvider = core.CoreFactory.getTickProvider(),
  27875. valueAxes = that._valueAxes || [],
  27876. defaultAxisName = valueAxes[0].name,
  27877. paneAxis = that.paneAxis || {},
  27878. panes = that.panes,
  27879. i,
  27880. neededAxis = {};
  27881. var getPaneForAxis = function(axisNameWithoutPane) {
  27882. var result;
  27883. _each(that.paneAxis, function(paneName, pane) {
  27884. _each(pane, function(axisName, _) {
  27885. if (axisNameWithoutPane == axisName) {
  27886. result = paneName;
  27887. return false
  27888. }
  27889. })
  27890. });
  27891. return result
  27892. };
  27893. var axesWithoutPanes = $.map(valueAxes, function(axis) {
  27894. if (axis.pane)
  27895. return null;
  27896. return axis
  27897. });
  27898. _each(axesWithoutPanes, function(_, axis) {
  27899. axis.pane = getPaneForAxis(axis.name);
  27900. if (!axis.pane) {
  27901. axis.pane = that.defaultPane;
  27902. paneAxis[axis.pane] = paneAxis[axis.pane] || {};
  27903. paneAxis[axis.pane][axis.name] = true
  27904. }
  27905. axis.options.pane = axis.pane
  27906. });
  27907. for (i = 0; i < panes.length; i++)
  27908. if (!paneAxis[panes[i].name]) {
  27909. paneAxis[panes[i].name] = {};
  27910. paneAxis[panes[i].name][defaultAxisName] = true
  27911. }
  27912. var findAxisOptions = function(axisName) {
  27913. var result,
  27914. axInd;
  27915. for (axInd = 0; axInd < valueAxesOptions.length; axInd++)
  27916. if (valueAxesOptions[axInd].name == axisName) {
  27917. result = valueAxesOptions[axInd];
  27918. result.priority = axInd;
  27919. break
  27920. }
  27921. if (!result)
  27922. for (axInd = 0; axInd < valueAxes.length; axInd++)
  27923. if (valueAxes[axInd].name == axisName) {
  27924. result = valueAxes[axInd].options;
  27925. result.priority = valueAxes[axInd].priority;
  27926. break
  27927. }
  27928. if (!result) {
  27929. that._incidentOccured("W2102", [axisName]);
  27930. result = {
  27931. name: axisName,
  27932. priority: valueAxes.length
  27933. }
  27934. }
  27935. return result
  27936. };
  27937. var findAxis = function(paneName, axisName) {
  27938. var axis;
  27939. for (i = 0; i < valueAxes.length; i++) {
  27940. axis = valueAxes[i];
  27941. if (axis.name === axisName && axis.pane === paneName)
  27942. return axis
  27943. }
  27944. };
  27945. _each(that.paneAxis, function(paneName, axisNames) {
  27946. _each(axisNames, function(axisName, _) {
  27947. neededAxis[axisName + '-' + paneName] = true;
  27948. if (!findAxis(paneName, axisName)) {
  27949. var axisOptions = findAxisOptions(axisName);
  27950. if (axisOptions)
  27951. valueAxes.push(that._createValueAxis($.extend(true, {}, axisOptions, {
  27952. pane: paneName,
  27953. name: axisName
  27954. }), rotated, tickProvider))
  27955. }
  27956. })
  27957. });
  27958. valueAxes = $.grep(valueAxes, function(elem) {
  27959. return !!neededAxis[elem.name + '-' + elem.pane]
  27960. });
  27961. valueAxes.sort(function(a, b) {
  27962. return a.priority - b.priority
  27963. });
  27964. that._valueAxes = valueAxes
  27965. },
  27966. _processSeriesFamilies: function() {
  27967. var that = this,
  27968. types = [],
  27969. families = [],
  27970. paneSeries,
  27971. themeManager = that.themeManager,
  27972. rotated = themeManager.getOptions('rotated');
  27973. if (that.seriesFamilies && that.seriesFamilies.length) {
  27974. _each(that.seriesFamilies, function(_, family) {
  27975. family.adjustSeriesValues()
  27976. });
  27977. return
  27978. }
  27979. _each(that.series, function(_, item) {
  27980. if ($.inArray(item.type, types) === -1)
  27981. types.push(item.type)
  27982. });
  27983. _each(that.panes, function(_, pane) {
  27984. paneSeries = [];
  27985. _each(that.series, function(_, oneSeries) {
  27986. if (oneSeries.pane === pane.name)
  27987. paneSeries.push(oneSeries)
  27988. });
  27989. _each(types, function(_, type) {
  27990. var family = core.CoreFactory.createSeriesFamily({
  27991. type: type,
  27992. pane: pane.name,
  27993. rotated: rotated,
  27994. equalBarWidth: themeManager.getOptions('equalBarWidth'),
  27995. minBubbleSize: themeManager.getOptions('minBubbleSize'),
  27996. maxBubbleSize: themeManager.getOptions('maxBubbleSize')
  27997. });
  27998. family.add(paneSeries);
  27999. family.adjustSeriesValues();
  28000. families.push(family)
  28001. })
  28002. });
  28003. that.seriesFamilies = families
  28004. },
  28005. _createLegend: function() {
  28006. var that = this,
  28007. legendData = [],
  28008. legendOptions = that.themeManager.getOptions('legend');
  28009. legendData = $.map(that.series, function(seriesItem) {
  28010. if (seriesItem.getOptions().showInLegend)
  28011. return {
  28012. text: seriesItem.name,
  28013. color: seriesItem.getColor(),
  28014. id: seriesItem.index,
  28015. states: seriesItem.getLegendStyles()
  28016. }
  28017. });
  28018. legendOptions.containerBackgroundColor = that.themeManager.getOptions("containerBackgroundColor");
  28019. legendOptions._incidentOccured = that._incidentOccured;
  28020. if (that.legend)
  28021. that.legend.update(legendData, legendOptions);
  28022. else
  28023. that.legend = core.CoreFactory.createLegend(legendData, legendOptions, that.renderer, that._legendGroup)
  28024. },
  28025. _createTranslator: function(range, canvas, options) {
  28026. return core.CoreFactory.createTranslator2D(range, canvas, options)
  28027. },
  28028. _createPanesBorderOptions: function() {
  28029. var commonBorderOptions = this.themeManager.getOptions('commonPaneSettings').border,
  28030. panesBorderOptions = {};
  28031. _each(this.panes, function(_, pane) {
  28032. var borderOptions = $.extend(true, {}, commonBorderOptions, pane.border);
  28033. panesBorderOptions[pane.name] = borderOptions
  28034. });
  28035. return panesBorderOptions
  28036. },
  28037. _render: function(drawOptions) {
  28038. var that = this,
  28039. themeManager = that.themeManager,
  28040. rotated = themeManager.getOptions('rotated'),
  28041. i,
  28042. layoutManager = that.layoutManager,
  28043. panesBorderOptions = that._createPanesBorderOptions(),
  28044. needHideLoadIndicator,
  28045. legendHasInsidePosition = that.legend && that.legend.getPosition() === "inside";
  28046. var drawSeries = function drawSeries() {
  28047. var panes = that.panes,
  28048. hideLayoutLabels = that.layoutManager.needMoreSpaceForPanesCanvas(that.panes, rotated) && !that.themeManager.getOptions("adaptiveLayout").keepLabels,
  28049. stackPoints = {};
  28050. _each(that.seriesFamilies || [], function(_, seriesFamily) {
  28051. var tr = that._getTranslator(seriesFamily.pane) || {},
  28052. translators = {};
  28053. translators[rotated ? 'x' : 'y'] = tr.val;
  28054. translators[rotated ? 'y' : 'x'] = tr.arg;
  28055. seriesFamily.updateSeriesValues(translators);
  28056. seriesFamily.adjustSeriesDimensions(translators)
  28057. });
  28058. that._createCrossHairCursor();
  28059. function applyPaneClipRect(seriesOptions) {
  28060. var paneIndex = that._getPaneIndex(seriesOptions.pane);
  28061. seriesOptions.setClippingParams(seriesOptions.isFinancialSeries() ? that.financialPanesClipRects[paneIndex].id : that.panesClipRects[paneIndex].id, that._getPaneBorderVisibility(paneIndex))
  28062. }
  28063. function preparePointsForSharedTooltip(singleSeries, stackPoints) {
  28064. if (!themeManager.getOptions('tooltip').shared)
  28065. return;
  28066. var points = singleSeries.getPoints(),
  28067. stackName = singleSeries.getStackName();
  28068. _each(points, function(index, point) {
  28069. var argument = point.argument;
  28070. if (!stackPoints[argument]) {
  28071. stackPoints[argument] = {};
  28072. stackPoints[argument][null] = []
  28073. }
  28074. if (stackName && !DX.utils.isArray(stackPoints[argument][stackName])) {
  28075. stackPoints[argument][stackName] = [];
  28076. _each(stackPoints[argument][null], function(_, point) {
  28077. if (!point.stackName)
  28078. stackPoints[argument][stackName].push(point)
  28079. })
  28080. }
  28081. if (stackName) {
  28082. stackPoints[argument][stackName].push(point);
  28083. stackPoints[argument][null].push(point)
  28084. }
  28085. else
  28086. _each(stackPoints[argument], function(_, stack) {
  28087. stack.push(point)
  28088. });
  28089. point.stackPoints = stackPoints[argument][stackName];
  28090. point.stackName = stackName
  28091. })
  28092. }
  28093. _each(that.series, function(_, particularSeries) {
  28094. preparePointsForSharedTooltip(particularSeries, stackPoints);
  28095. applyPaneClipRect(particularSeries);
  28096. particularSeries.setAdjustSeriesLabels(drawOptions.adjustSeriesLabels);
  28097. var tr = that._getTranslator(particularSeries.pane, particularSeries.axis),
  28098. translators = {};
  28099. translators[rotated ? 'x' : 'y'] = tr.val;
  28100. translators[rotated ? 'y' : 'x'] = tr.arg;
  28101. particularSeries.draw(translators, drawOptions.animate && particularSeries.getPoints().length <= drawOptions.animationPointsLimit && that.renderer.animationEnabled(), hideLayoutLabels, that.legend && that.legend.getActionCallback(particularSeries))
  28102. });
  28103. that._trackerGroup.append();
  28104. if (drawOptions.drawLegend && that.legend && legendHasInsidePosition) {
  28105. var newCanvas = $.extend({}, panes[0].canvas),
  28106. layoutManager = charts.factory.createChartLayoutManager();
  28107. newCanvas.right = panes[panes.length - 1].canvas.right;
  28108. newCanvas.bottom = panes[panes.length - 1].canvas.bottom;
  28109. that._legendGroup.append();
  28110. that._tooltipGroup.append();
  28111. layoutManager.drawElements([that.legend], newCanvas);
  28112. layoutManager.placeDrawnElements(newCanvas)
  28113. }
  28114. needHideLoadIndicator && that.hideLoadingIndicator();
  28115. that._drawn();
  28116. var drawChartTrackers = function drawChartTrackers() {
  28117. var i;
  28118. for (i = 0; i < that.series.length; i++)
  28119. that.series[i].drawTrackers();
  28120. if (that.legend) {
  28121. that.legend.drawTrackers();
  28122. legendHasInsidePosition && that._legendGroup.append();
  28123. legendHasInsidePosition && that._tooltipGroup.append()
  28124. }
  28125. that.tracker._prepare();
  28126. _each(that._paneTrackerGroups, function(index, paneGroups) {
  28127. paneGroups.paneSeriesGroup.append(that._seriesTrackerGroup);
  28128. paneGroups.paneMarkerGroup.append(that._markerTrackerGroup)
  28129. });
  28130. that._handleRenderComplete()
  28131. };
  28132. that._createTooltip();
  28133. if (drawOptions.asyncTrackersRendering)
  28134. that.delayedRedraw = setTimeout(drawChartTrackers, drawOptions.trackerRenderingDelay);
  28135. else
  28136. drawChartTrackers()
  28137. };
  28138. drawOptions = that._prepareDrawOptions(drawOptions);
  28139. that.callBase(drawOptions);
  28140. if (that.stopRedraw) {
  28141. that.stopRedraw = false;
  28142. return
  28143. }
  28144. that._createPanesBackground();
  28145. that._stripsGroup.append();
  28146. that._axesGroup.append();
  28147. that._constantLinesGroup.append();
  28148. that._labelAxesGroup.append();
  28149. that._createTranslators(drawOptions);
  28150. that._options.useAggregation && _each(that.series, function(_, series) {
  28151. series._originalBusinessRange = series._originalBusinessRange || series.getRangeData();
  28152. var tr = that._getTranslator(series.pane, series.axis),
  28153. translators = {};
  28154. translators[rotated ? 'x' : 'y'] = tr.val;
  28155. translators[rotated ? 'y' : 'x'] = tr.arg;
  28156. series.resamplePoints(translators, that._zoomMinArg, that._zoomMaxArg)
  28157. });
  28158. if (utils.isDefined(that._zoomMinArg) || utils.isDefined(that._zoomMaxArg))
  28159. that._populateBusinessRange({
  28160. adjustOnZoom: themeManager.getOptions('adjustOnZoom'),
  28161. minArg: that._zoomMinArg,
  28162. maxArg: that._zoomMaxArg
  28163. });
  28164. if (that._options.useAggregation || utils.isDefined(that._zoomMinArg) || utils.isDefined(that._zoomMaxArg))
  28165. that._updateTranslators();
  28166. that._renderTitleAndLegend(drawOptions, legendHasInsidePosition);
  28167. if (drawOptions && drawOptions.recreateCanvas)
  28168. layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
  28169. that._drawAxes(panesBorderOptions, drawOptions);
  28170. if (layoutManager.needMoreSpaceForPanesCanvas(that.panes, rotated)) {
  28171. layoutManager.updateDrawnElements(that._argumentAxes, that._valueAxes, that.canvas, that.dirtyCanvas, that.panes, rotated);
  28172. if (that.chartTitle)
  28173. that.layoutManager.correctSizeElement(that.chartTitle, that.canvas);
  28174. that._updateCanvasClipRect(that.dirtyCanvas);
  28175. layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
  28176. that._drawAxes(panesBorderOptions, drawOptions, true)
  28177. }
  28178. layoutManager.placeDrawnElements(that.canvas);
  28179. that._drawPanesBorders(panesBorderOptions);
  28180. that._createClipRectsForPanes();
  28181. for (i = 0; i < that._argumentAxes.length; i++)
  28182. that._argumentAxes[i].applyClipRect(that._getElementsClipRectID(that._argumentAxes[i].pane));
  28183. for (i = 0; i < that._valueAxes.length; i++)
  28184. that._valueAxes[i].applyClipRect(that._getElementsClipRectID(that._valueAxes[i].pane));
  28185. that._fillPanesBackground();
  28186. that._seriesGroup.append();
  28187. that._labelsGroup.append();
  28188. that._crossHairCursorGroup.append();
  28189. that._legendGroup.append();
  28190. that._tooltipGroup.append();
  28191. needHideLoadIndicator = that._loadIndicator && that._loadIndicator.isShown && that._dataSource && that._dataSource.isLoaded() && !drawOptions.isResize;
  28192. if (drawOptions.asyncSeriesRendering)
  28193. that.delayedRedraw = setTimeout(drawSeries, ASYNC_SERIES_RENDERING_DELAY);
  28194. else
  28195. drawSeries()
  28196. },
  28197. _createTranslators: function(drawOptions) {
  28198. var that = this,
  28199. rotated = that.themeManager.getOptions("rotated"),
  28200. translators;
  28201. if (!drawOptions.recreateCanvas)
  28202. return;
  28203. that.translators = translators = {};
  28204. that.layoutManager.updatePanesCanvases(that.panes, that.canvas, rotated);
  28205. _each(that.paneAxis, function(paneName, pane) {
  28206. translators[paneName] = translators[paneName] || {};
  28207. _each(pane, function(axisName, _) {
  28208. var translator = that._createTranslator(new core.Range(that._getBusinessRange(paneName, axisName).val), that._getCanvasForPane(paneName), rotated ? {direction: 'horizontal'} : {});
  28209. translator.pane = paneName;
  28210. translator.axis = axisName;
  28211. translators[paneName][axisName] = {val: translator}
  28212. })
  28213. });
  28214. _each(that._argumentAxes, function(_, axis) {
  28215. var translator = that._createTranslator(new core.Range(that._getBusinessRange(axis.pane).arg), that._getCanvasForPane(axis.pane), !rotated ? {direction: 'horizontal'} : {});
  28216. _each(translators[axis.pane], function(valAxis, paneAsixTran) {
  28217. paneAsixTran.arg = translator
  28218. })
  28219. })
  28220. },
  28221. _updateTranslators: function() {
  28222. var that = this;
  28223. _each(that.translators, function(pane, axisTrans) {
  28224. _each(axisTrans, function(axis, translator) {
  28225. translator.arg.updateBusinessRange(new core.Range(that._getBusinessRange(pane).arg));
  28226. delete translator.arg._originalBusinessRange;
  28227. translator.val.updateBusinessRange(new core.Range(that._getBusinessRange(pane, axis).val));
  28228. delete translator.val._originalBusinessRange
  28229. })
  28230. })
  28231. },
  28232. _reinitTranslators: function() {
  28233. var that = this;
  28234. _each(that._argumentAxes, function(_, axis) {
  28235. var translator = that._getTranslator(axis.pane);
  28236. if (translator) {
  28237. translator.arg.reinit();
  28238. axis.setRange(translator.arg.getBusinessRange());
  28239. axis.setTranslator(translator.arg, translator.val)
  28240. }
  28241. });
  28242. _each(that._valueAxes, function(_, axis) {
  28243. var translator = that._getTranslator(axis.pane, axis.name);
  28244. if (translator) {
  28245. translator.val.reinit();
  28246. axis.setRange(translator.val.getBusinessRange());
  28247. axis.setTranslator(translator.val, translator.arg)
  28248. }
  28249. })
  28250. },
  28251. _drawAxes: function(panesBorderOptions, drawOptions, adjustUnits) {
  28252. var that = this,
  28253. i = 0,
  28254. layoutManager = that.layoutManager,
  28255. rotated = that.themeManager.getOptions("rotated"),
  28256. translators = that.translators,
  28257. adjustmentCounter = 0,
  28258. synchronizeMultiAxes = that.themeManager.getOptions('synchronizeMultiAxes');
  28259. that._reinitTranslators();
  28260. do {
  28261. for (i = 0; i < that._argumentAxes.length; i++)
  28262. that._argumentAxes[i].resetTicks();
  28263. for (i = 0; i < that._valueAxes.length; i++)
  28264. that._valueAxes[i].resetTicks();
  28265. if (synchronizeMultiAxes)
  28266. charts.multiAxesSynchronizer.synchronize(that._valueAxes);
  28267. drawAxes(rotated ? that._valueAxes : that._argumentAxes);
  28268. layoutManager.requireAxesRedraw = false;
  28269. if (drawOptions.adjustAxes) {
  28270. layoutManager.applyHorizontalAxesLayout(rotated ? that._valueAxes : that._argumentAxes);
  28271. !layoutManager.stopDrawAxes && _each(translators, function(pane, axisTrans) {
  28272. _each(axisTrans, function(axis, translator) {
  28273. translator.arg.reinit();
  28274. translator.val.reinit()
  28275. })
  28276. })
  28277. }
  28278. drawAxes(rotated ? that._argumentAxes : that._valueAxes);
  28279. if (drawOptions.adjustAxes && !layoutManager.stopDrawAxes) {
  28280. layoutManager.applyVerticalAxesLayout(rotated ? that._argumentAxes : that._valueAxes);
  28281. !layoutManager.stopDrawAxes && _each(translators, function(pane, axisTrans) {
  28282. _each(axisTrans, function(axis, translator) {
  28283. translator.arg.reinit();
  28284. translator.val.reinit()
  28285. })
  28286. })
  28287. }
  28288. adjustmentCounter = adjustmentCounter + 1
  28289. } while (!layoutManager.stopDrawAxes && layoutManager.requireAxesRedraw && adjustmentCounter < MAX_ADJUSTMENT_ATTEMPTS);
  28290. that.__axisAdjustmentsCount = adjustmentCounter;
  28291. function drawAxes(axes) {
  28292. _each(axes, function(_, axis) {
  28293. axis.clipRectID = that._getCanvasClipRectID();
  28294. axis.stripsGroup = that._stripsGroup;
  28295. axis.labelAxesGroup = that._labelAxesGroup;
  28296. axis.constantLinesGroup = that._constantLinesGroup;
  28297. axis.axesContainerGroup = that._axesGroup;
  28298. axis.draw({borderOptions: panesBorderOptions[axis.pane]}, adjustUnits)
  28299. })
  28300. }
  28301. },
  28302. _createCrossHairCursor: function() {
  28303. var that = this,
  28304. renderer = that.renderer,
  28305. panes = that.panes,
  28306. commonCanvas,
  28307. canvas,
  28308. options = that.themeManager.getOptions('crosshair') || {},
  28309. hLine,
  28310. vLine,
  28311. attrHLine,
  28312. attrVLine,
  28313. i;
  28314. if (!options || !options.enabled)
  28315. return;
  28316. attrHLine = {
  28317. stroke: options.horizontalLine.color || options.color,
  28318. strokeWidth: options.horizontalLine.width || options.width,
  28319. dashStyle: options.horizontalLine.dashStyle || options.dashStyle,
  28320. visibility: 'hidden',
  28321. opacity: options.horizontalLine.opacity || options.opacity
  28322. };
  28323. attrVLine = {
  28324. stroke: options.verticalLine.color || options.color,
  28325. strokeWidth: options.verticalLine.width || options.width,
  28326. dashStyle: options.verticalLine.dashStyle || options.dashStyle,
  28327. visibility: 'hidden',
  28328. opacity: options.verticalLine.opacity || options.opacity
  28329. };
  28330. for (i = 0; i < panes.length; i++) {
  28331. canvas = panes[i].canvas;
  28332. if (!commonCanvas)
  28333. commonCanvas = $.extend({}, canvas);
  28334. else {
  28335. commonCanvas.right = canvas.right;
  28336. commonCanvas.bottom = canvas.bottom
  28337. }
  28338. renderer.createRect(canvas.left, canvas.top, canvas.width - canvas.right - canvas.left, canvas.height - canvas.bottom - canvas.top, 0).append(this._crosshairTrackerGroup)
  28339. }
  28340. if (options.horizontalLine && options.horizontalLine.visible)
  28341. hLine = renderer.createLine(commonCanvas.left, commonCanvas.top, commonCanvas.width - commonCanvas.right, commonCanvas.top, attrHLine).append(that._crossHairCursorGroup);
  28342. if (options.verticalLine && options.verticalLine.visible)
  28343. vLine = renderer.createLine(commonCanvas.left, commonCanvas.top, commonCanvas.left, commonCanvas.height - commonCanvas.bottom, attrVLine).append(that._crossHairCursorGroup);
  28344. that._crossHairOptions.horizontalLine = hLine;
  28345. that._crossHairOptions.verticalLine = vLine;
  28346. that._crossHairOptions.canvas = commonCanvas
  28347. },
  28348. _createPanesBackground: function() {
  28349. var that = this,
  28350. defaultBackgroundColor = that.themeManager.getOptions('commonPaneSettings').backgroundColor,
  28351. backgroundColor,
  28352. renderer = that.renderer,
  28353. rect,
  28354. i,
  28355. rects = [];
  28356. that._panesBackgroundGroup && that._panesBackgroundGroup.clear();
  28357. for (i = 0; i < that.panes.length; i++) {
  28358. backgroundColor = that.panes[i].backgroundColor || defaultBackgroundColor;
  28359. if (!backgroundColor || backgroundColor === 'none') {
  28360. rects.push(null);
  28361. continue
  28362. }
  28363. rect = renderer.createRect(0, 0, 0, 0, 0, {
  28364. fill: backgroundColor,
  28365. strokeWidth: 0
  28366. }).append(that._panesBackgroundGroup);
  28367. rects.push(rect)
  28368. }
  28369. that.panesBackground = rects;
  28370. that._panesBackgroundGroup.append()
  28371. },
  28372. _fillPanesBackground: function() {
  28373. var that = this,
  28374. bc;
  28375. _each(that.panes, function(i, pane) {
  28376. bc = pane.borderCoords;
  28377. if (that.panesBackground[i] != null)
  28378. that.panesBackground[i].applySettings({
  28379. x: bc.left,
  28380. y: bc.top,
  28381. width: bc.width,
  28382. height: bc.height
  28383. })
  28384. })
  28385. },
  28386. _calcPaneBorderCoords: function(pane, rotated) {
  28387. var canvas = pane.canvas,
  28388. bc = pane.borderCoords = pane.borderCoords || {};
  28389. bc.left = canvas.left;
  28390. bc.top = canvas.top;
  28391. bc.right = canvas.width - canvas.right;
  28392. bc.bottom = canvas.height - canvas.bottom;
  28393. bc.width = Math.max(bc.right - bc.left, 0);
  28394. bc.height = Math.max(bc.bottom - bc.top, 0)
  28395. },
  28396. _drawPanesBorders: function(panesBorderOptions) {
  28397. var that = this,
  28398. rotated = that.themeManager.getOptions('rotated');
  28399. that._panesBorderGroup && (that._panesBorderGroup.detach(), that._panesBorderGroup.clear());
  28400. _each(that.panes, function(i, pane) {
  28401. var bc,
  28402. borderOptions = panesBorderOptions[pane.name],
  28403. attr = {
  28404. fill: 'none',
  28405. stroke: borderOptions.color,
  28406. strokeOpacity: borderOptions.opacity,
  28407. strokeWidth: borderOptions.width,
  28408. dashStyle: borderOptions.dashStyle
  28409. };
  28410. that._calcPaneBorderCoords(pane, rotated);
  28411. if (!borderOptions.visible)
  28412. return;
  28413. bc = pane.borderCoords;
  28414. that.renderer.createSegmentRect(bc.left, bc.top, bc.width, bc.height, 0, borderOptions, attr).append(that._panesBorderGroup)
  28415. });
  28416. that._panesBorderGroup.append()
  28417. },
  28418. _createClipRect: function(clipArray, index, left, top, width, height) {
  28419. var that = this,
  28420. clipRect = clipArray[index];
  28421. if (!clipRect) {
  28422. clipRect = that.renderer.createClipRect(left, top, width, height);
  28423. clipArray[index] = clipRect
  28424. }
  28425. else
  28426. clipRect.updateRectangle({
  28427. x: left,
  28428. y: top,
  28429. width: width,
  28430. height: height
  28431. });
  28432. clipRect.append()
  28433. },
  28434. _createClipRectsForPanes: function() {
  28435. var that = this,
  28436. canvas = that.canvas;
  28437. _each(that.panes, function(i, pane) {
  28438. var hasFinancialSeries = false,
  28439. bc = pane.borderCoords,
  28440. left = bc.left,
  28441. top = bc.top,
  28442. width = bc.width,
  28443. height = bc.height;
  28444. that._createClipRect(that.panesClipRects, i, left, top, width, height);
  28445. _each(that.series, function(_, series) {
  28446. if (series.pane === pane.name && series.isFinancialSeries())
  28447. hasFinancialSeries = true
  28448. });
  28449. if (hasFinancialSeries) {
  28450. if (that.themeManager.getOptions('rotated')) {
  28451. top = 0;
  28452. height = canvas.height
  28453. }
  28454. else {
  28455. left = 0;
  28456. width = canvas.width
  28457. }
  28458. that._createClipRect(that.financialPanesClipRects, i, left, top, width, height)
  28459. }
  28460. else
  28461. that.financialPanesClipRects.push(null)
  28462. })
  28463. },
  28464. _getPaneIndex: function(paneName) {
  28465. var paneIndex;
  28466. _each(this.panes, function(index, pane) {
  28467. if (pane.name === paneName) {
  28468. paneIndex = index;
  28469. return false
  28470. }
  28471. });
  28472. return paneIndex
  28473. },
  28474. _getPaneBorderVisibility: function(paneIndex) {
  28475. var commonPaneBorderVisible = this.themeManager.getOptions('commonPaneSettings').border.visible,
  28476. pane = this.panes[paneIndex] || {},
  28477. paneBorder = pane.border || {};
  28478. return 'visible' in paneBorder ? paneBorder.visible : commonPaneBorderVisible
  28479. },
  28480. _getElementsClipRectID: function(paneName) {
  28481. return this.panesClipRects[this._getPaneIndex(paneName)].id
  28482. },
  28483. _getTranslator: function(paneName, axisName) {
  28484. var paneTrans = this.translators[paneName],
  28485. foundTranslator = null;
  28486. if (!paneTrans)
  28487. return foundTranslator;
  28488. foundTranslator = paneTrans[axisName];
  28489. if (!foundTranslator)
  28490. _each(paneTrans, function(axis, trans) {
  28491. foundTranslator = trans;
  28492. return false
  28493. });
  28494. return foundTranslator
  28495. },
  28496. _getCanvasForPane: function(paneName) {
  28497. var panes = this.panes,
  28498. panesNumber = panes.length,
  28499. i;
  28500. for (i = 0; i < panesNumber; i++)
  28501. if (panes[i].name === paneName)
  28502. return panes[i].canvas
  28503. },
  28504. _getBusinessRange: function(paneName, axisName) {
  28505. var ranges = this.businessRanges || [],
  28506. rangesNumber = ranges.length,
  28507. foundRange,
  28508. i;
  28509. for (i = 0; i < rangesNumber; i++)
  28510. if (ranges[i].val.pane === paneName && ranges[i].val.axis === axisName) {
  28511. foundRange = ranges[i];
  28512. break
  28513. }
  28514. if (!foundRange)
  28515. for (i = 0; i < rangesNumber; i++)
  28516. if (ranges[i].val.pane === paneName) {
  28517. foundRange = ranges[i];
  28518. break
  28519. }
  28520. return foundRange
  28521. },
  28522. _handleSeriesPopulated: function(needRedraw) {
  28523. var that = this;
  28524. that._processSeriesFamilies();
  28525. that._createLegend();
  28526. that._populateBusinessRange();
  28527. that._processValueAxisFormat();
  28528. that._updateTracker();
  28529. that._endLoading(function() {
  28530. needRedraw && that._render({force: true})
  28531. })
  28532. },
  28533. _processValueAxisFormat: function() {
  28534. var that = this,
  28535. valueAxes = that._valueAxes,
  28536. axesWithFullStackedFormat = [];
  28537. _each(that.series, function() {
  28538. if (this.isFullStackedSeries() && $.inArray(this.axis, axesWithFullStackedFormat) === -1)
  28539. axesWithFullStackedFormat.push(this.axis)
  28540. });
  28541. _each(valueAxes, function() {
  28542. if ($.inArray(this.name, axesWithFullStackedFormat) !== -1)
  28543. this.setPercentLabelFormat();
  28544. else
  28545. this.resetAutoLabelFormat()
  28546. })
  28547. },
  28548. zoomArgument: function(min, max) {
  28549. var that = this,
  28550. zoomArg = that._argumentAxes[0].adjustZoomValues(min, max);
  28551. that._zoomMinArg = zoomArg.min;
  28552. that._zoomMaxArg = zoomArg.max;
  28553. that._render({
  28554. force: true,
  28555. drawTitle: false,
  28556. drawLegend: false,
  28557. adjustAxes: false,
  28558. animate: false,
  28559. adjustSeriesLabels: false,
  28560. asyncSeriesRendering: false
  28561. })
  28562. }
  28563. })
  28564. })(jQuery, DevExpress);
  28565. /*! Module viz-charts, file pieChart.js */
  28566. (function($, DX, undefined) {
  28567. var core = DX.viz.core,
  28568. charts = DX.viz.charts,
  28569. utils = DX.utils;
  28570. charts.PieChart = charts.BaseChart.inherit({
  28571. _createThemeManager: function() {
  28572. return charts.factory.createThemeManager(this.option(), "pie")
  28573. },
  28574. _reinit: function(needRedraw) {
  28575. var that = this;
  28576. that.callBase();
  28577. if (!that.series)
  28578. that._dataSpecificInit();
  28579. that._endLoading(function() {
  28580. needRedraw && that._render({force: true})
  28581. })
  28582. },
  28583. _populateBusinessRange: function() {
  28584. var businessRanges = [],
  28585. series = this.series,
  28586. singleSeries = series[0],
  28587. range,
  28588. singleSeriesRange;
  28589. this._disposeObjectsInArray("businessRanges");
  28590. if (singleSeries) {
  28591. range = new core.Range({series: singleSeries});
  28592. singleSeriesRange = singleSeries.getRangeData();
  28593. range = range.addRange(singleSeriesRange.val);
  28594. if (!range.isDefined())
  28595. range.setStubData();
  28596. businessRanges.push(range)
  28597. }
  28598. this.businessRanges = businessRanges
  28599. },
  28600. _seriesVisibilytyChanged: function() {
  28601. this.series[0].arrangePoints();
  28602. this._populateBusinessRange();
  28603. this._refresh()
  28604. },
  28605. _createTranslator: function(range) {
  28606. return core.CoreFactory.createTranslator1D(range.min, range.max, 360, 0)
  28607. },
  28608. _populateSeries: function() {
  28609. var that = this,
  28610. renderer = that.renderer,
  28611. themeManager = that.themeManager,
  28612. hasSeriesTemplate = !!themeManager.getOptions("seriesTemplate"),
  28613. seriesOptions = hasSeriesTemplate ? that._templatedSeries : that.option("series"),
  28614. allSeriesOptions = $.isArray(seriesOptions) ? seriesOptions : seriesOptions ? [seriesOptions] : [],
  28615. data,
  28616. particularSeriesOptions,
  28617. particularSeries,
  28618. seriesTheme;
  28619. that._disposeSeries();
  28620. that.series = [];
  28621. themeManager.resetPalette();
  28622. if (allSeriesOptions.length) {
  28623. particularSeriesOptions = $.extend(true, {}, allSeriesOptions[0]);
  28624. if (particularSeriesOptions.type && !utils.isString(particularSeriesOptions.type))
  28625. particularSeriesOptions.type = "";
  28626. data = particularSeriesOptions.data;
  28627. particularSeriesOptions.data = null;
  28628. particularSeriesOptions.incidentOccured = that._incidentOccured;
  28629. seriesTheme = themeManager.getOptions("series", particularSeriesOptions, true);
  28630. seriesTheme.seriesGroup = that._seriesGroup;
  28631. seriesTheme.trackerGroup = that._trackerGroup;
  28632. seriesTheme.seriesLabelsGroup = that._labelsGroup;
  28633. seriesTheme.seriesTrackerGroup = that._seriesTrackerGroup;
  28634. seriesTheme.markerTrackerGroup = that._markerTrackerGroup;
  28635. seriesTheme.visibilityChanged = $.proxy(this._seriesVisibilytyChanged, this);
  28636. seriesTheme.customizePoint = themeManager.getOptions("customizePoint");
  28637. seriesTheme.customizeLabel = themeManager.getOptions("customizeLabel");
  28638. particularSeries = core.CoreFactory.createSeries(renderer, seriesTheme);
  28639. if (!particularSeries.isUpdated)
  28640. that._incidentOccured("E2101", [seriesTheme.type]);
  28641. else {
  28642. that._processSingleSeries(particularSeries);
  28643. that.series.push(particularSeries)
  28644. }
  28645. particularSeriesOptions.data = data
  28646. }
  28647. return that.series
  28648. },
  28649. _processSingleSeries: function(singleSeries) {
  28650. singleSeries.arrangePoints()
  28651. },
  28652. _handleSeriesPopulated: function(needRedraw) {
  28653. var that = this;
  28654. that._populateBusinessRange();
  28655. that._createLegend();
  28656. that._updateTracker();
  28657. that._endLoading(function() {
  28658. needRedraw && that._render({
  28659. force: true,
  28660. recreateCanvas: true
  28661. })
  28662. })
  28663. },
  28664. _createLegend: function() {
  28665. var that = this,
  28666. legendOptions = that.themeManager.getOptions("legend"),
  28667. data = $.map(that.series[0] ? that.series[0].getPoints() : [], function(item) {
  28668. return {
  28669. text: item.argument,
  28670. color: item.getColor(),
  28671. id: item.index,
  28672. states: item.getLegendStyles()
  28673. }
  28674. });
  28675. legendOptions._incidentOccured = that._incidentOccured;
  28676. that.legend = core.CoreFactory.createLegend(data, legendOptions, that.renderer, that._legendGroup)
  28677. },
  28678. _render: function(drawOptions) {
  28679. var that = this,
  28680. singleSeries = that.series && that.series[0],
  28681. layoutManager = that.layoutManager,
  28682. hideLayoutLabels;
  28683. drawOptions = that._prepareDrawOptions(drawOptions);
  28684. that.callBase(drawOptions);
  28685. if (that.stopRedraw) {
  28686. that.stopRedraw = false;
  28687. return
  28688. }
  28689. that._renderTitleAndLegend(drawOptions);
  28690. if (layoutManager.needMoreSpaceForPanesCanvas([that])) {
  28691. layoutManager.updateDrawnElements([], [], that.canvas, that.dirtyCanvas, [that]);
  28692. if (that.chartTitle)
  28693. that.layoutManager.correctSizeElement(that.chartTitle, that.canvas);
  28694. that._updateCanvasClipRect(that.dirtyCanvas)
  28695. }
  28696. layoutManager.placeDrawnElements(that.canvas);
  28697. if (singleSeries) {
  28698. hideLayoutLabels = layoutManager.needMoreSpaceForPanesCanvas([that]) && !that.themeManager.getOptions("adaptiveLayout").keepLabels;
  28699. layoutManager.applyPieChartSeriesLayout(that.canvas, singleSeries, true);
  28700. that._seriesGroup.append();
  28701. that._labelsGroup.append();
  28702. singleSeries.canvas = that.canvas;
  28703. singleSeries.resetLabelEllipsis();
  28704. singleSeries.draw(that._createTranslator(that.businessRanges[0], that.canvas), drawOptions.animate && that.renderer.animationEnabled(), hideLayoutLabels);
  28705. if (singleSeries.redraw) {
  28706. that.renderer.stopAllAnimations(true);
  28707. layoutManager.applyPieChartSeriesLayout(that.canvas, singleSeries, hideLayoutLabels);
  28708. singleSeries.draw(that._createTranslator(that.businessRanges[0], that.canvas), drawOptions.animate && that.renderer.animationEnabled(), hideLayoutLabels)
  28709. }
  28710. that._tooltipGroup.append();
  28711. that._trackerGroup.append();
  28712. that._createTooltip();
  28713. singleSeries.drawTrackers();
  28714. that.tracker._prepare("pieChart")
  28715. }
  28716. that._dataSource && that._dataSource.isLoaded() && !drawOptions.isResize && that.hideLoadingIndicator();
  28717. that._drawn();
  28718. that._handleRenderComplete()
  28719. },
  28720. getSeries: function getSeries() {
  28721. return this.series && this.series[0]
  28722. }
  28723. })
  28724. })(jQuery, DevExpress);
  28725. /*! Module viz-charts, file layoutManager.js */
  28726. (function($, DX, undefined) {
  28727. var isNumber = DX.utils.isNumber,
  28728. math = Math,
  28729. decreaseGaps = DevExpress.viz.core.utils.decreaseGaps,
  28730. CONNECTOR_MARGIN = 10,
  28731. round = math.round;
  28732. DX.viz.charts.LayoutManager = DX.Class.inherit(function() {
  28733. var ctor = function(options) {
  28734. this.verticalElements = [];
  28735. this.horizontalElements = [];
  28736. this._options = options
  28737. };
  28738. var update = function(chart) {
  28739. this.chart = chart;
  28740. setCanvasValues(chart && chart.canvas)
  28741. };
  28742. var dispose = function() {
  28743. this.chart = null
  28744. };
  28745. var setCanvasValues = function(canvas) {
  28746. if (canvas) {
  28747. canvas.originalTop = canvas.top;
  28748. canvas.originalBottom = canvas.bottom;
  28749. canvas.originalLeft = canvas.left;
  28750. canvas.originalRight = canvas.right
  28751. }
  28752. };
  28753. var placeElementAndCutCanvas = function(elements, canvas) {
  28754. $.each(elements, function(_, element) {
  28755. var shiftX,
  28756. shiftY,
  28757. options = element.getLayoutOptions(),
  28758. length = getLength(options.cutLayoutSide);
  28759. if (!options.width)
  28760. return;
  28761. switch (options.horizontalAlignment) {
  28762. case"left":
  28763. shiftX = canvas.left;
  28764. break;
  28765. case"center":
  28766. shiftX = (canvas.width - canvas.left - canvas.right - options.width) / 2 + canvas.left;
  28767. break;
  28768. case"right":
  28769. shiftX = canvas.width - canvas.right - options.width;
  28770. break
  28771. }
  28772. switch (options.verticalAlignment) {
  28773. case"top":
  28774. shiftY = canvas.top;
  28775. break;
  28776. case"bottom":
  28777. shiftY = canvas.height - canvas.bottom - options.height;
  28778. break
  28779. }
  28780. element.shift(round(shiftX), round(shiftY));
  28781. canvas[options.cutLayoutSide] += options[length];
  28782. setCanvasValues(canvas)
  28783. })
  28784. };
  28785. var drawElements = function(elements, canvas) {
  28786. var that = this,
  28787. verticalElements = that.verticalElements = [],
  28788. horizontalElements = that.horizontalElements = [];
  28789. $.each(elements, function(_, element) {
  28790. var freeHeight = canvas.height - canvas.top - canvas.bottom,
  28791. freeWidth = canvas.width - canvas.left - canvas.right,
  28792. options,
  28793. length,
  28794. arrayElements;
  28795. element.setSize({
  28796. height: freeHeight,
  28797. width: freeWidth
  28798. });
  28799. element.draw();
  28800. options = element.getLayoutOptions();
  28801. length = getLength(options.cutLayoutSide);
  28802. arrayElements = length === "width" ? horizontalElements : verticalElements;
  28803. arrayElements.push(element);
  28804. canvas[options.cutLayoutSide] += options[length];
  28805. setCanvasValues(canvas)
  28806. })
  28807. };
  28808. var getLength = function(side) {
  28809. var length = "height";
  28810. if (side === "left" || side === "right")
  28811. length = "width";
  28812. return length
  28813. };
  28814. var updatePanesCanvases = function(panes, canvas, rotated) {
  28815. var pane,
  28816. i,
  28817. paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,
  28818. paneSpaceWidth = canvas.width - canvas.left - canvas.right,
  28819. weightSum = 0,
  28820. padding = panes.padding || 10;
  28821. for (i = 0; i < panes.length; i++) {
  28822. pane = panes[i];
  28823. pane.weight = pane.weight || 1;
  28824. weightSum = weightSum + pane.weight
  28825. }
  28826. rotated ? createPanes(panes, paneSpaceWidth, "left", "right") : createPanes(panes, paneSpaceHeight, "top", "bottom");
  28827. function createPanes(panes, paneSpace, startName, endName) {
  28828. var distributedSpace = 0,
  28829. oneWeight = (paneSpace - padding * (panes.length - 1)) / weightSum;
  28830. $.each(panes, function(_, pane) {
  28831. var calcLength = round(pane.weight * oneWeight);
  28832. pane.canvas = pane.canvas || {};
  28833. $.extend(pane.canvas, {
  28834. deltaLeft: 0,
  28835. deltaRight: 0,
  28836. deltaTop: 0,
  28837. deltaBottom: 0
  28838. }, canvas);
  28839. pane.canvas[startName] = canvas[startName] + distributedSpace;
  28840. pane.canvas[endName] = canvas[endName] + (paneSpace - calcLength - distributedSpace);
  28841. distributedSpace = distributedSpace + calcLength + padding;
  28842. setCanvasValues(pane.canvas)
  28843. })
  28844. }
  28845. };
  28846. var applyPieChartSeriesLayout = function(canvas, singleSeries, hideLayoutLabels) {
  28847. var paneSpaceHeight = canvas.height - canvas.top - canvas.bottom,
  28848. paneSpaceWidth = canvas.width - canvas.left - canvas.right,
  28849. paneCenterX = paneSpaceWidth / 2 + canvas.left,
  28850. paneCenterY = paneSpaceHeight / 2 + canvas.top,
  28851. accessibleRadius = Math.min(paneSpaceWidth, paneSpaceHeight) / 2,
  28852. minR = 0.7 * accessibleRadius,
  28853. innerRadius = getInnerRadius(singleSeries);
  28854. if (!hideLayoutLabels)
  28855. $.each(singleSeries.getPoints(), function(_, point) {
  28856. if (point._label.hasText() && point.isVisible()) {
  28857. var labelBBox = point._label._getOutsideGroupLabelPosition(),
  28858. nearestX = getNearestCoord(labelBBox.x, labelBBox.x + labelBBox.width, paneCenterX),
  28859. nearestY = getNearestCoord(labelBBox.y, labelBBox.y + labelBBox.height, paneCenterY),
  28860. minRadiusWithLabels = Math.max(getLengthFromCenter(nearestX, nearestY) - CONNECTOR_MARGIN, minR);
  28861. accessibleRadius = Math.min(accessibleRadius, minRadiusWithLabels)
  28862. }
  28863. point._label.setPosition(point._label.originalPosition)
  28864. });
  28865. else
  28866. $.each(singleSeries.getPoints(), function(_, point) {
  28867. if (singleSeries.getOptions().label.position === "inside")
  28868. return false;
  28869. point._label.originalPosition = point._label.getPosition();
  28870. point._label.setPosition('outside')
  28871. });
  28872. singleSeries.correctPosition({
  28873. centerX: math.floor(paneCenterX),
  28874. centerY: math.floor(paneCenterY),
  28875. radiusInner: math.floor(accessibleRadius * innerRadius),
  28876. radiusOuter: math.floor(accessibleRadius)
  28877. });
  28878. function getNearestCoord(firstCoord, secondCoord, pointCenterCoord) {
  28879. var nearestCoord;
  28880. if (pointCenterCoord < firstCoord)
  28881. nearestCoord = firstCoord;
  28882. else if (secondCoord < pointCenterCoord)
  28883. nearestCoord = secondCoord;
  28884. else
  28885. nearestCoord = pointCenterCoord;
  28886. return nearestCoord
  28887. }
  28888. function getLengthFromCenter(x, y) {
  28889. return Math.sqrt(Math.pow(x - paneCenterX, 2) + Math.pow(y - paneCenterY, 2))
  28890. }
  28891. function getInnerRadius(series) {
  28892. var innerRadius;
  28893. if (singleSeries.type === 'pie')
  28894. innerRadius = 0;
  28895. else {
  28896. innerRadius = singleSeries.innerRadius;
  28897. if (!isNumber(innerRadius))
  28898. innerRadius = 0.5;
  28899. else {
  28900. innerRadius = Number(innerRadius);
  28901. if (innerRadius < 0.2)
  28902. innerRadius = 0.2;
  28903. if (innerRadius > 0.8)
  28904. innerRadius = 0.8
  28905. }
  28906. }
  28907. return innerRadius
  28908. }
  28909. };
  28910. var isValidBox = function isValidBox(box) {
  28911. return !!(box.x || box.y || box.width || box.height)
  28912. };
  28913. var correctDeltaMarginValue = function(panes, marginSides) {
  28914. var axisPanePosition,
  28915. canvasCell,
  28916. canvas,
  28917. deltaSide,
  28918. requireAxesRedraw;
  28919. $.each(panes, function(_, pane) {
  28920. canvas = pane.canvas;
  28921. $.each(marginSides, function(_, side) {
  28922. deltaSide = 'delta' + side;
  28923. canvas[deltaSide] = Math.max(canvas[deltaSide] - (canvas[side.toLowerCase()] - canvas['original' + side]), 0);
  28924. if (canvas[deltaSide] > 0)
  28925. requireAxesRedraw = true
  28926. })
  28927. });
  28928. return requireAxesRedraw
  28929. };
  28930. var getPane = function getPane(name, panes) {
  28931. var findPane = panes[0];
  28932. $.each(panes, function(_, pane) {
  28933. if (name === pane.name)
  28934. findPane = pane
  28935. });
  28936. return findPane
  28937. };
  28938. var applyAxesLayout = function(axes, panes, rotated) {
  28939. var that = this,
  28940. canvas,
  28941. axisPanePosition,
  28942. axisPosition,
  28943. canvasCell,
  28944. box,
  28945. delta,
  28946. axis,
  28947. axisLength,
  28948. direction,
  28949. directionMultiplier,
  28950. someDirection = [],
  28951. pane,
  28952. i;
  28953. $.each(panes, function(_, pane) {
  28954. $.extend(pane.canvas, {
  28955. deltaLeft: 0,
  28956. deltaRight: 0,
  28957. deltaTop: 0,
  28958. deltaBottom: 0
  28959. })
  28960. });
  28961. for (i = 0; i < axes.length; i++) {
  28962. axis = axes[i];
  28963. axisPosition = axis.options.position || 'left';
  28964. axis.delta = {};
  28965. box = axis.getBoundingRect();
  28966. pane = getPane(axis.pane, panes);
  28967. canvas = pane.canvas;
  28968. if (!isValidBox(box))
  28969. continue;
  28970. direction = "delta" + axisPosition.slice(0, 1).toUpperCase() + axisPosition.slice(1);
  28971. switch (axisPosition) {
  28972. case"right":
  28973. directionMultiplier = 1;
  28974. canvas.deltaLeft += axis.padding ? axis.padding.left : 0;
  28975. break;
  28976. case"left":
  28977. directionMultiplier = -1;
  28978. canvas.deltaRight += axis.padding ? axis.padding.right : 0;
  28979. break;
  28980. case"top":
  28981. directionMultiplier = -1;
  28982. canvas.deltaBottom += axis.padding ? axis.padding.bottom : 0;
  28983. break;
  28984. case"bottom":
  28985. directionMultiplier = 1;
  28986. canvas.deltaTop += axis.padding ? axis.padding.top : 0;
  28987. break
  28988. }
  28989. switch (axisPosition) {
  28990. case"right":
  28991. case"left":
  28992. if (!box.isEmpty) {
  28993. delta = box.y + box.height - (canvas.height - canvas.originalBottom);
  28994. if (delta > 0) {
  28995. that.requireAxesRedraw = true;
  28996. canvas.deltaBottom += delta
  28997. }
  28998. delta = canvas.originalTop - box.y;
  28999. if (delta > 0) {
  29000. that.requireAxesRedraw = true;
  29001. canvas.deltaTop += delta
  29002. }
  29003. }
  29004. axisLength = box.width;
  29005. someDirection = ['Left', 'Right'];
  29006. break;
  29007. case"top":
  29008. case"bottom":
  29009. if (!box.isEmpty) {
  29010. delta = box.x + box.width - (canvas.width - canvas.originalRight);
  29011. if (delta > 0) {
  29012. that.requireAxesRedraw = true;
  29013. canvas.deltaRight += delta
  29014. }
  29015. delta = canvas.originalLeft - box.x;
  29016. if (delta > 0) {
  29017. that.requireAxesRedraw = true;
  29018. canvas.deltaLeft += delta
  29019. }
  29020. }
  29021. someDirection = ['Bottom', 'Top'];
  29022. axisLength = box.height;
  29023. break
  29024. }
  29025. if (!axis.delta[axisPosition] && canvas[direction] > 0)
  29026. canvas[direction] += axis.getMultipleAxesSpacing();
  29027. axis.delta[axisPosition] = axis.delta[axisPosition] || 0;
  29028. axis.delta[axisPosition] += canvas[direction] * directionMultiplier;
  29029. canvas[direction] += axisLength
  29030. }
  29031. that.requireAxesRedraw = correctDeltaMarginValue(panes, someDirection) || that.requireAxesRedraw;
  29032. this.stopDrawAxes = applyFoundExceedings(panes, rotated)
  29033. };
  29034. var applyVerticalAxesLayout = function(axes) {
  29035. var chart = this.chart;
  29036. this.applyAxesLayout(axes, chart.panes, chart.option('rotated'))
  29037. };
  29038. var applyHorizontalAxesLayout = function(axes) {
  29039. var chart = this.chart;
  29040. axes.reverse();
  29041. this.applyAxesLayout(axes, chart.panes, chart.option('rotated'));
  29042. axes.reverse()
  29043. };
  29044. var placeDrawnElements = function(canvas) {
  29045. var that = this,
  29046. horizontalElements = that.horizontalElements,
  29047. verticalElements = that.verticalElements;
  29048. correctElementsPosition(horizontalElements, 'width');
  29049. placeElementAndCutCanvas(horizontalElements, canvas);
  29050. correctElementsPosition(verticalElements, 'height');
  29051. placeElementAndCutCanvas(verticalElements, canvas);
  29052. function correctElementsPosition(elements, direction) {
  29053. $.each(elements, function(_, element) {
  29054. var options = element.getLayoutOptions(),
  29055. side = options.cutLayoutSide;
  29056. canvas[side] -= options[direction]
  29057. })
  29058. }
  29059. };
  29060. var needMoreSpaceForPanesCanvas = function(panes, rotated) {
  29061. var that = this,
  29062. needHorizontalSpace = 0,
  29063. needVerticalSpace = 0;
  29064. $.each(panes, function(_, pane) {
  29065. var paneCanvas = pane.canvas,
  29066. needPaneHorizonralSpace = that._options.width - (paneCanvas.width - paneCanvas.left - paneCanvas.right),
  29067. needPaneVerticalSpace = that._options.height - (paneCanvas.height - paneCanvas.top - paneCanvas.bottom);
  29068. if (rotated) {
  29069. needHorizontalSpace += needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0;
  29070. needVerticalSpace = Math.max(needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0, needVerticalSpace)
  29071. }
  29072. else {
  29073. needHorizontalSpace = Math.max(needPaneHorizonralSpace > 0 ? needPaneHorizonralSpace : 0, needHorizontalSpace);
  29074. needVerticalSpace += needPaneVerticalSpace > 0 ? needPaneVerticalSpace : 0
  29075. }
  29076. });
  29077. return needHorizontalSpace > 0 || needVerticalSpace > 0 ? {
  29078. width: needHorizontalSpace,
  29079. height: needVerticalSpace
  29080. } : false
  29081. };
  29082. var updateDrawnElements = function(argumentAxis, valueAxis, canvas, dirtyCanvas, panes, rotated) {
  29083. var that = this,
  29084. needRemoveSpace,
  29085. saveDirtyCanvas = $.extend({}, dirtyCanvas),
  29086. verticalAxes = rotated ? argumentAxis : valueAxis,
  29087. horizontalAxes = rotated ? valueAxis : argumentAxis;
  29088. needRemoveSpace = this.needMoreSpaceForPanesCanvas(panes, rotated);
  29089. if (!needRemoveSpace)
  29090. return;
  29091. needRemoveSpace.height = decreaseGaps(dirtyCanvas, ["top", "bottom"], needRemoveSpace.height);
  29092. needRemoveSpace.width = decreaseGaps(dirtyCanvas, ["left", "right"], needRemoveSpace.width);
  29093. canvas.top -= saveDirtyCanvas.top - dirtyCanvas.top;
  29094. canvas.bottom -= saveDirtyCanvas.bottom - dirtyCanvas.bottom;
  29095. canvas.left -= saveDirtyCanvas.left - dirtyCanvas.left;
  29096. canvas.right -= saveDirtyCanvas.right - dirtyCanvas.right;
  29097. updateElements(that.horizontalElements, "width", "height");
  29098. updateElements(that.verticalElements, "height", "width");
  29099. updateAxis(verticalAxes, "width");
  29100. updateAxis(horizontalAxes, "height");
  29101. function updateAxis(axes, side) {
  29102. if (axes && needRemoveSpace[side] > 0) {
  29103. $.each(axes, function(i, axis) {
  29104. var bbox = axis.getBoundingRect();
  29105. axis.updateSize();
  29106. needRemoveSpace[side] -= bbox[side] - axis.getBoundingRect()[side]
  29107. });
  29108. if (needRemoveSpace[side] > 0)
  29109. $.each(axes, function(_, axis) {
  29110. axis.updateSize(true)
  29111. })
  29112. }
  29113. }
  29114. function updateElements(elements, length, otherLength) {
  29115. $.each(elements, function(_, element) {
  29116. var options = element.getLayoutOptions(),
  29117. side = options.cutLayoutSide,
  29118. freeSpaceWidth = dirtyCanvas.width - dirtyCanvas.left - dirtyCanvas.right,
  29119. freeSpaceHeight = dirtyCanvas.height - dirtyCanvas.top - dirtyCanvas.bottom,
  29120. updateObject = {};
  29121. element.setSize({
  29122. width: freeSpaceWidth,
  29123. height: freeSpaceHeight
  29124. });
  29125. updateObject[otherLength] = 0;
  29126. updateObject[length] = needRemoveSpace[length];
  29127. element.changeSize(updateObject);
  29128. canvas[side] -= options[length] - element.getLayoutOptions()[length];
  29129. needRemoveSpace[length] -= options[length] - element.getLayoutOptions()[length]
  29130. })
  29131. }
  29132. };
  29133. var correctSizeElement = function(element, canvas) {
  29134. element.setSize({
  29135. width: canvas.width - canvas.right - canvas.left,
  29136. height: canvas.width - canvas.right - canvas.left
  29137. });
  29138. element.changeSize({
  29139. width: 0,
  29140. height: 0
  29141. })
  29142. };
  29143. var applyFoundExceedings = function applyFoundExceedings(panes, rotated) {
  29144. var col,
  29145. row,
  29146. stopDrawAxes,
  29147. maxLeft = 0,
  29148. maxRight = 0,
  29149. maxTop = 0,
  29150. maxBottom = 0,
  29151. maxColNumber = 0;
  29152. $.each(panes, function(_, pane) {
  29153. maxLeft = Math.max(maxLeft, pane.canvas.deltaLeft);
  29154. maxRight = Math.max(maxRight, pane.canvas.deltaRight);
  29155. maxTop = Math.max(maxTop, pane.canvas.deltaTop);
  29156. maxBottom = Math.max(maxBottom, pane.canvas.deltaBottom)
  29157. });
  29158. if (rotated)
  29159. $.each(panes, function(_, pane) {
  29160. pane.canvas.top += maxTop;
  29161. pane.canvas.bottom += maxBottom;
  29162. pane.canvas.right += pane.canvas.deltaRight;
  29163. pane.canvas.left += pane.canvas.deltaLeft
  29164. });
  29165. else
  29166. $.each(panes, function(_, pane) {
  29167. pane.canvas.top += pane.canvas.deltaTop;
  29168. pane.canvas.bottom += pane.canvas.deltaBottom;
  29169. pane.canvas.right += maxRight;
  29170. pane.canvas.left += maxLeft
  29171. });
  29172. $.each(panes, function(_, pane) {
  29173. if (pane.canvas.top + pane.canvas.bottom > pane.canvas.height)
  29174. stopDrawAxes = true;
  29175. if (pane.canvas.left + pane.canvas.right > pane.canvas.width)
  29176. stopDrawAxes = true
  29177. });
  29178. return stopDrawAxes
  29179. };
  29180. return {
  29181. ctor: ctor,
  29182. update: update,
  29183. drawElements: drawElements,
  29184. updatePanesCanvases: updatePanesCanvases,
  29185. applyVerticalAxesLayout: applyVerticalAxesLayout,
  29186. applyHorizontalAxesLayout: applyHorizontalAxesLayout,
  29187. applyAxesLayout: applyAxesLayout,
  29188. applyPieChartSeriesLayout: applyPieChartSeriesLayout,
  29189. dispose: dispose,
  29190. updateDrawnElements: updateDrawnElements,
  29191. placeDrawnElements: placeDrawnElements,
  29192. needMoreSpaceForPanesCanvas: needMoreSpaceForPanesCanvas,
  29193. correctSizeElement: correctSizeElement
  29194. }
  29195. }())
  29196. })(jQuery, DevExpress);
  29197. /*! Module viz-charts, file multiAxesSynchronizer.js */
  29198. (function($, DX, undefined) {
  29199. var Range = DX.viz.core.Range,
  29200. utils = DX.utils,
  29201. adjustValueUtils = utils.adjustValue,
  29202. applyPrecisionByMinDeltaUtils = utils.applyPrecisionByMinDelta,
  29203. isDefinedUtils = utils.isDefined,
  29204. math = Math,
  29205. mathFloor = math.floor,
  29206. mathMax = math.max,
  29207. _each = $.each,
  29208. MIN_RANGE_FOR_ADJUST_BOUNDS = 0.1;
  29209. var getValueAxesPerPanes = function(valueAxes) {
  29210. var result = {};
  29211. _each(valueAxes, function(_, axis) {
  29212. var pane = axis.pane;
  29213. if (!result[pane])
  29214. result[pane] = [];
  29215. result[pane].push(axis)
  29216. });
  29217. return result
  29218. };
  29219. var restoreOriginalBusinessRange = function(axis) {
  29220. var businessRange;
  29221. if (!axis.translator._originalBusinessRange)
  29222. axis.translator._originalBusinessRange = new Range(axis.translator.getBusinessRange());
  29223. else {
  29224. businessRange = new Range(axis.translator._originalBusinessRange);
  29225. axis.translator.updateBusinessRange(businessRange);
  29226. axis.setRange(businessRange)
  29227. }
  29228. };
  29229. var linearConvertor = {
  29230. transform: function(v, b) {
  29231. return utils.getLog(v, b)
  29232. },
  29233. addInterval: function(v, i) {
  29234. return v + i
  29235. },
  29236. getInterval: function(base, tickInterval) {
  29237. return tickInterval
  29238. },
  29239. adjustValue: mathFloor
  29240. };
  29241. var logConvertor = {
  29242. transform: function(v, b) {
  29243. return utils.raiseTo(v, b)
  29244. },
  29245. addInterval: function(v, i) {
  29246. return v * i
  29247. },
  29248. getInterval: function(base, tickInterval) {
  29249. return math.pow(base, tickInterval)
  29250. },
  29251. adjustValue: adjustValueUtils
  29252. };
  29253. var convertAxisInfo = function(axisInfo, convertor) {
  29254. if (!axisInfo.isLogarithmic)
  29255. return;
  29256. var base = axisInfo.logarithmicBase,
  29257. tickValues = axisInfo.tickValues,
  29258. tick,
  29259. ticks = [],
  29260. interval;
  29261. axisInfo.minValue = convertor.transform(axisInfo.minValue, base);
  29262. axisInfo.oldMinValue = convertor.transform(axisInfo.oldMinValue, base);
  29263. axisInfo.maxValue = convertor.transform(axisInfo.maxValue, base);
  29264. axisInfo.oldMaxValue = convertor.transform(axisInfo.oldMaxValue, base);
  29265. axisInfo.tickInterval = math.round(axisInfo.tickInterval);
  29266. if (axisInfo.tickInterval < 1)
  29267. axisInfo.tickInterval = 1;
  29268. interval = convertor.getInterval(base, axisInfo.tickInterval);
  29269. for (tick = convertor.adjustValue(convertor.transform(tickValues[0], base)); ticks.length < tickValues.length; tick = convertor.addInterval(tick, interval))
  29270. ticks.push(tick);
  29271. ticks.tickInterval = axisInfo.tickInterval;
  29272. axisInfo.tickValues = ticks
  29273. };
  29274. var populateAxesInfo = function(axes) {
  29275. return $.map(axes, function(axis) {
  29276. restoreOriginalBusinessRange(axis);
  29277. var tickValues = axis.getTickValues(),
  29278. options = axis.options,
  29279. minValue,
  29280. maxValue,
  29281. axisInfo = null,
  29282. businessRange,
  29283. tickInterval,
  29284. synchronizedValue;
  29285. if (tickValues && tickValues.length > 0 && utils.isNumber(tickValues[0]) && options.type !== 'discrete') {
  29286. tickInterval = tickValues.tickInterval;
  29287. businessRange = axis.translator.getBusinessRange();
  29288. minValue = businessRange.minVisible;
  29289. maxValue = businessRange.maxVisible;
  29290. synchronizedValue = options.synchronizedValue;
  29291. if (minValue === maxValue && isDefinedUtils(synchronizedValue)) {
  29292. minValue = tickValues[0] - 1;
  29293. maxValue = tickValues[0] + 1;
  29294. tickInterval = 1
  29295. }
  29296. axisInfo = {
  29297. axis: axis,
  29298. isLogarithmic: options.type === 'logarithmic',
  29299. logarithmicBase: businessRange.base,
  29300. tickValues: tickValues,
  29301. minValue: minValue,
  29302. oldMinValue: minValue,
  29303. maxValue: maxValue,
  29304. oldMaxValue: maxValue,
  29305. inverted: businessRange.invert,
  29306. tickInterval: tickInterval,
  29307. synchronizedValue: synchronizedValue
  29308. };
  29309. if (businessRange.stubData) {
  29310. axisInfo.stubData = true;
  29311. axisInfo.tickInterval = axisInfo.tickInterval || options.tickInterval;
  29312. axisInfo.isLogarithmic = false
  29313. }
  29314. convertAxisInfo(axisInfo, linearConvertor);
  29315. DX.utils.debug.assert(axisInfo.tickInterval !== undefined && axisInfo.tickInterval !== null, 'tickInterval was not provided')
  29316. }
  29317. return axisInfo
  29318. })
  29319. };
  29320. var updateTickValues = function(axesInfo) {
  29321. var maxTicksCount = 0;
  29322. _each(axesInfo, function(_, axisInfo) {
  29323. maxTicksCount = mathMax(maxTicksCount, axisInfo.tickValues.length)
  29324. });
  29325. _each(axesInfo, function(_, axisInfo) {
  29326. var ticksMultiplier,
  29327. ticksCount,
  29328. additionalStartTicksCount = 0,
  29329. synchronizedValue = axisInfo.synchronizedValue,
  29330. tickValues = axisInfo.tickValues,
  29331. tickInterval = axisInfo.tickInterval;
  29332. if (isDefinedUtils(synchronizedValue)) {
  29333. axisInfo.baseTickValue = axisInfo.invertedBaseTickValue = synchronizedValue;
  29334. axisInfo.tickValues = [axisInfo.baseTickValue]
  29335. }
  29336. else {
  29337. if (tickValues.length > 1 && tickInterval) {
  29338. ticksMultiplier = mathFloor((maxTicksCount + 1) / tickValues.length);
  29339. ticksCount = ticksMultiplier > 1 ? mathFloor((maxTicksCount + 1) / ticksMultiplier) : maxTicksCount;
  29340. additionalStartTicksCount = mathFloor((ticksCount - tickValues.length) / 2);
  29341. while (additionalStartTicksCount > 0 && tickValues[0] !== 0) {
  29342. tickValues.unshift(applyPrecisionByMinDeltaUtils(tickValues[0], tickInterval, tickValues[0] - tickInterval));
  29343. additionalStartTicksCount--
  29344. }
  29345. while (tickValues.length < ticksCount)
  29346. tickValues.push(applyPrecisionByMinDeltaUtils(tickValues[0], tickInterval, tickValues[tickValues.length - 1] + tickInterval));
  29347. axisInfo.tickInterval = tickInterval / ticksMultiplier
  29348. }
  29349. axisInfo.baseTickValue = tickValues[0];
  29350. axisInfo.invertedBaseTickValue = tickValues[tickValues.length - 1]
  29351. }
  29352. })
  29353. };
  29354. var getAxisRange = function(axisInfo) {
  29355. return axisInfo.maxValue - axisInfo.minValue || 1
  29356. };
  29357. var getMainAxisInfo = function(axesInfo) {
  29358. for (var i = 0; i < axesInfo.length; i++)
  29359. if (!axesInfo[i].stubData)
  29360. return axesInfo[i];
  29361. return null
  29362. };
  29363. var correctMinMaxValues = function(axesInfo) {
  29364. var mainAxisInfo = getMainAxisInfo(axesInfo),
  29365. mainAxisInfoTickInterval = mainAxisInfo.tickInterval;
  29366. _each(axesInfo, function(_, axisInfo) {
  29367. var scale,
  29368. move,
  29369. mainAxisBaseValueOffset,
  29370. valueFromAxisInfo;
  29371. if (axisInfo !== mainAxisInfo) {
  29372. if (mainAxisInfoTickInterval && axisInfo.tickInterval) {
  29373. if (axisInfo.stubData && isDefinedUtils(axisInfo.synchronizedValue)) {
  29374. axisInfo.oldMinValue = axisInfo.minValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.minValue) / mainAxisInfoTickInterval * axisInfo.tickInterval;
  29375. axisInfo.oldMaxValue = axisInfo.maxValue = axisInfo.baseTickValue - (mainAxisInfo.baseTickValue - mainAxisInfo.maxValue) / mainAxisInfoTickInterval * axisInfo.tickInterval
  29376. }
  29377. scale = mainAxisInfoTickInterval / getAxisRange(mainAxisInfo) / axisInfo.tickInterval * getAxisRange(axisInfo);
  29378. axisInfo.maxValue = axisInfo.minValue + getAxisRange(axisInfo) / scale
  29379. }
  29380. if (mainAxisInfo.inverted && !axisInfo.inverted || !mainAxisInfo.inverted && axisInfo.inverted)
  29381. mainAxisBaseValueOffset = mainAxisInfo.maxValue - mainAxisInfo.invertedBaseTickValue;
  29382. else
  29383. mainAxisBaseValueOffset = mainAxisInfo.baseTickValue - mainAxisInfo.minValue;
  29384. valueFromAxisInfo = getAxisRange(axisInfo);
  29385. move = (mainAxisBaseValueOffset / getAxisRange(mainAxisInfo) - (axisInfo.baseTickValue - axisInfo.minValue) / valueFromAxisInfo) * valueFromAxisInfo;
  29386. axisInfo.minValue -= move;
  29387. axisInfo.maxValue -= move
  29388. }
  29389. })
  29390. };
  29391. var calculatePaddings = function(axesInfo) {
  29392. var minPadding,
  29393. maxPadding,
  29394. startPadding = 0,
  29395. endPadding = 0;
  29396. _each(axesInfo, function(_, axisInfo) {
  29397. var inverted = axisInfo.inverted;
  29398. minPadding = axisInfo.minValue > axisInfo.oldMinValue ? (axisInfo.minValue - axisInfo.oldMinValue) / getAxisRange(axisInfo) : 0;
  29399. maxPadding = axisInfo.maxValue < axisInfo.oldMaxValue ? (axisInfo.oldMaxValue - axisInfo.maxValue) / getAxisRange(axisInfo) : 0;
  29400. startPadding = mathMax(startPadding, inverted ? maxPadding : minPadding);
  29401. endPadding = mathMax(endPadding, inverted ? minPadding : maxPadding)
  29402. });
  29403. return {
  29404. start: startPadding,
  29405. end: endPadding
  29406. }
  29407. };
  29408. var correctMinMaxValuesByPaddings = function(axesInfo, paddings) {
  29409. _each(axesInfo, function(_, info) {
  29410. var range = getAxisRange(info),
  29411. inverted = info.inverted;
  29412. info.minValue -= paddings[inverted ? 'end' : 'start'] * range;
  29413. info.maxValue += paddings[inverted ? 'start' : 'end'] * range;
  29414. if (range > MIN_RANGE_FOR_ADJUST_BOUNDS) {
  29415. info.minValue = math.min(info.minValue, adjustValueUtils(info.minValue));
  29416. info.maxValue = mathMax(info.maxValue, adjustValueUtils(info.maxValue))
  29417. }
  29418. })
  29419. };
  29420. var updateTickValuesIfSyncronizedValueUsed = function(axesInfo) {
  29421. var hasSyncronizedValue = false;
  29422. _each(axesInfo, function(_, info) {
  29423. hasSyncronizedValue = hasSyncronizedValue || isDefinedUtils(info.synchronizedValue)
  29424. });
  29425. _each(axesInfo, function(_, info) {
  29426. var lastTickValue,
  29427. tickInterval = info.tickInterval,
  29428. tickValues = info.tickValues,
  29429. maxValue = info.maxValue,
  29430. minValue = info.minValue;
  29431. if (hasSyncronizedValue && tickInterval) {
  29432. while (tickValues[0] - tickInterval >= minValue)
  29433. tickValues.unshift(adjustValueUtils(tickValues[0] - tickInterval));
  29434. lastTickValue = tickValues[tickValues.length - 1];
  29435. while ((lastTickValue = lastTickValue + tickInterval) <= maxValue)
  29436. tickValues.push(utils.isExponential(lastTickValue) ? adjustValueUtils(lastTickValue) : utils.applyPrecisionByMinDelta(minValue, tickInterval, lastTickValue))
  29437. }
  29438. while (tickValues[0] < minValue)
  29439. tickValues.shift();
  29440. while (tickValues[tickValues.length - 1] > maxValue)
  29441. tickValues.pop()
  29442. })
  29443. };
  29444. var applyMinMaxValues = function(axesInfo) {
  29445. _each(axesInfo, function(_, info) {
  29446. var axis = info.axis,
  29447. range = axis.translator.getBusinessRange();
  29448. if (range.min === range.minVisible)
  29449. range.min = info.minValue;
  29450. if (range.max === range.maxVisible)
  29451. range.max = info.maxValue;
  29452. range.minVisible = info.minValue;
  29453. range.maxVisible = info.maxValue;
  29454. if (isDefinedUtils(info.stubData))
  29455. range.stubData = info.stubData;
  29456. if (range.min > range.minVisible)
  29457. range.min = range.minVisible;
  29458. if (range.max < range.maxVisible)
  29459. range.max = range.maxVisible;
  29460. axis.translator.updateBusinessRange(range);
  29461. axis.setRange(range);
  29462. axis.setTickValues(info.tickValues)
  29463. })
  29464. };
  29465. var correctAfterSynchronize = function(axesInfo) {
  29466. var invalidAxisInfo = [],
  29467. correctValue,
  29468. validAxisInfo;
  29469. _each(axesInfo, function(i, info) {
  29470. if (info.oldMaxValue - info.oldMinValue === 0)
  29471. invalidAxisInfo.push(info);
  29472. else if (!isDefinedUtils(correctValue) && !isDefinedUtils(info.synchronizedValue)) {
  29473. correctValue = math.abs((info.maxValue - info.minValue) / (info.tickValues[mathFloor(info.tickValues.length / 2)] || info.maxValue));
  29474. validAxisInfo = info
  29475. }
  29476. });
  29477. if (!isDefinedUtils(correctValue))
  29478. return;
  29479. _each(invalidAxisInfo, function(i, info) {
  29480. var firstTick = info.tickValues[0],
  29481. correctedTick = firstTick * correctValue,
  29482. tickValues = validAxisInfo.tickValues,
  29483. centralTick = tickValues[mathFloor(tickValues.length / 2)];
  29484. if (firstTick > 0) {
  29485. info.maxValue = correctedTick;
  29486. info.minValue = 0
  29487. }
  29488. else if (firstTick < 0) {
  29489. info.minValue = correctedTick;
  29490. info.maxValue = 0
  29491. }
  29492. else if (firstTick === 0) {
  29493. info.maxValue = validAxisInfo.maxValue - centralTick;
  29494. info.minValue = validAxisInfo.minValue - centralTick
  29495. }
  29496. })
  29497. };
  29498. DX.viz.charts.multiAxesSynchronizer = {synchronize: function(valueAxes) {
  29499. _each(getValueAxesPerPanes(valueAxes), function(_, axes) {
  29500. var axesInfo,
  29501. paddings;
  29502. if (axes.length > 1) {
  29503. axesInfo = populateAxesInfo(axes);
  29504. if (axesInfo.length === 0 || !getMainAxisInfo(axesInfo))
  29505. return;
  29506. updateTickValues(axesInfo);
  29507. correctMinMaxValues(axesInfo);
  29508. paddings = calculatePaddings(axesInfo);
  29509. correctMinMaxValuesByPaddings(axesInfo, paddings);
  29510. correctAfterSynchronize(axesInfo);
  29511. updateTickValuesIfSyncronizedValueUsed(axesInfo);
  29512. _each(axesInfo, function() {
  29513. convertAxisInfo(this, logConvertor)
  29514. });
  29515. applyMinMaxValues(axesInfo)
  29516. }
  29517. })
  29518. }}
  29519. })(jQuery, DevExpress);
  29520. /*! Module viz-charts, file tracker.js */
  29521. (function($, DX) {
  29522. var charts = DX.viz.charts,
  29523. eventsConsts = DX.viz.core.series.helpers.consts.events,
  29524. utils = DX.utils,
  29525. isFunction = utils.isFunction,
  29526. isDefined = utils.isDefined,
  29527. MULTIPLE_MODE = 'multiple',
  29528. SINGLE_MODE = 'single',
  29529. ALL_ARGUMENTS_POINTS_MODE = 'allargumentpoints',
  29530. ALL_SERIES_POINTS_MODE = 'allseriespoints',
  29531. msPointerEnabled = window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints || window.navigator.pointerEnabled && window.navigator.maxTouchPoints || null,
  29532. MOUSE_EVENT_LOCK_TIMEOUT = 1000,
  29533. CLICK_EVENT_LOCK_TIMEOUT = 600,
  29534. HOVER_START_DELAY = 100,
  29535. HOVER_HOLD_DELAY = 200,
  29536. TOOLTIP_HOLD_TIMEOUT = 400,
  29537. NONE_MODE = 'none';
  29538. var processMode = function(mode) {
  29539. return (mode + "").toLowerCase()
  29540. };
  29541. charts.Tracker = DX.Class.inherit({
  29542. ctor: function(options) {
  29543. this.__HOVER_HOLD_DELAY = HOVER_HOLD_DELAY;
  29544. this.__TOOLTIP_HOLD_TIMEOUT = TOOLTIP_HOLD_TIMEOUT;
  29545. this.__HOVER_START_DELAY = HOVER_START_DELAY;
  29546. var that = this,
  29547. events = options.events = options.events || {},
  29548. getEventHandler = function(func) {
  29549. return func && func.call ? function() {
  29550. var eventContext = this,
  29551. eventArgs = arguments;
  29552. setTimeout(function() {
  29553. func.apply(eventContext, eventArgs)
  29554. })
  29555. } : null
  29556. };
  29557. that._reinit(options);
  29558. that.pointSelectionMode = that._prepareMode(options.pointSelectionMode);
  29559. that.seriesSelectionMode = that._prepareMode(options.seriesSelectionMode);
  29560. that.hoverStartDelay = 0;
  29561. that.sensitivity = 7;
  29562. if (that.pointSelectionMode === MULTIPLE_MODE) {
  29563. that._releaseSelectedPoint = that._releaseSelectedPointMultiMode;
  29564. that.selectedPoint = []
  29565. }
  29566. else
  29567. that._releaseSelectedPoint = that._releaseSelectedPointSingleMode;
  29568. if (that.seriesSelectionMode === MULTIPLE_MODE) {
  29569. that._releaseSelectedSeries = that._releaseSelectedSeriesMultiMode;
  29570. that.selectedSeries = []
  29571. }
  29572. else
  29573. that._releaseSelectedSeries = that._releaseSelectedSeriesSingleMode;
  29574. that.tooltipEnabled = options.tooltipEnabled;
  29575. that.tooltipShown = options.tooltipShown;
  29576. that.tooltipHidden = options.tooltipHidden;
  29577. that.seriesClick = getEventHandler(events.seriesClick);
  29578. that.pointClick = getEventHandler(events.pointClick);
  29579. that.legendClick = getEventHandler(events.legendClick);
  29580. that.argumentAxisClick = getEventHandler(events.argumentAxisClick);
  29581. that.seriesHover = getEventHandler(events.seriesHover);
  29582. that.seriesSelected = getEventHandler(events.seriesSelected);
  29583. that.pointHover = getEventHandler(events.pointHover);
  29584. that.seriesSelectionChanged = getEventHandler(events.seriesSelectionChanged);
  29585. that.pointSelectionChanged = getEventHandler(events.pointSelectionChanged);
  29586. that.seriesHoverChanged = getEventHandler(events.seriesHoverChanged);
  29587. that.pointHoverChanged = getEventHandler(events.pointHoverChanged);
  29588. that.pointSelected = getEventHandler(events.pointSelected);
  29589. that.renderer = options.renderer;
  29590. that.seriesTrackerGroup = options.seriesTrackerGroup;
  29591. that.markerTrackerGroup = options.markerTrackerGroup;
  29592. that.seriesGroup = options.seriesGroup;
  29593. that.seriesGroup.on(eventsConsts.selectSeries, {tracker: that}, that._selectSeries);
  29594. that.seriesGroup.on(eventsConsts.deselectSeries, {tracker: that}, that._deselectSeries);
  29595. that.seriesGroup.on(eventsConsts.selectPoint, {tracker: that}, that._selectPoint);
  29596. that.seriesGroup.on(eventsConsts.deselectPoint, {tracker: that}, that._deselectPoint);
  29597. that.seriesGroup.on(eventsConsts.showPointTooltip, {tracker: that}, that._showPointTooltip);
  29598. that.seriesGroup.on(eventsConsts.hidePointTooltip, {tracker: that}, that._hidePointTooltip);
  29599. that.crossHairOptions = options.crossHairOptions
  29600. },
  29601. _clean: function() {
  29602. var that = this;
  29603. that.selectedPoint = that.pointSelectionMode === MULTIPLE_MODE ? [] : null;
  29604. that.selectedSeries = that.seriesSelectionMode === MULTIPLE_MODE ? [] : null;
  29605. that.hoveredPoint = null;
  29606. that.hoveredSeries = null;
  29607. that._hideTooltip(that.pointAtShownTooltip);
  29608. that._clearTimeouts()
  29609. },
  29610. _reinit: function(options) {
  29611. var that = this;
  29612. options = options || {};
  29613. if (that.storedSeries !== options.series) {
  29614. that.storedSeries = options.series || [];
  29615. that._clean()
  29616. }
  29617. else if (isDefined(that.storedSeries)) {
  29618. that._clearPointSelection();
  29619. that._clearHover(that);
  29620. that._clearTimeouts()
  29621. }
  29622. that.argumentAxis = options.argumentAxis || [];
  29623. that.legendGroup = options.legendGroup;
  29624. that.legendCallback = options.legendCallback || $.noop
  29625. },
  29626. _clearTimeouts: function() {
  29627. var that = this,
  29628. _clearTimeout = clearTimeout;
  29629. _clearTimeout(that.tooltipHoldTimeout);
  29630. _clearTimeout(that.cmpCoordTimeout);
  29631. _clearTimeout(that.hoverStartTimeOut);
  29632. _clearTimeout(that.hoverHoldTimeOut)
  29633. },
  29634. dispose: function() {
  29635. var that = this;
  29636. that._clearTimeouts();
  29637. clearTimeout(that.unlockMouseTimer);
  29638. clearTimeout(that.lockClickTimer);
  29639. $.each(that.argumentAxis, function(_, axis) {
  29640. axis._axisElementsGroup && axis._axisElementsGroup.off()
  29641. });
  29642. that.seriesTrackerGroup.off();
  29643. that.markerTrackerGroup.off();
  29644. that.legendGroup && that.legendGroup.off();
  29645. that.seriesGroup.off();
  29646. that.rootTracker && that.rootTracker.off();
  29647. that.argumentAxis = null;
  29648. that.seriesTrackerGroup = null;
  29649. that.markerTrackerGroup = null;
  29650. that.legendGroup = null;
  29651. that.legendCallback = null;
  29652. that.seriesGroup = null;
  29653. that.crossHairOptions = null;
  29654. that.selectedPoint = null;
  29655. that.selectedSeries = null;
  29656. that.hoveredSeries = null;
  29657. that.hoveredPoint = null;
  29658. that.storedSeries = null;
  29659. that.argumentAxis = null;
  29660. that.hoveredObject = null;
  29661. that.pointAtShownTooltip = null
  29662. },
  29663. _prepareMode: function(mode) {
  29664. mode = (mode || '').toLowerCase();
  29665. return mode = mode !== SINGLE_MODE && mode !== MULTIPLE_MODE ? SINGLE_MODE : mode
  29666. },
  29667. _prepare: function(typeChart) {
  29668. var that = this;
  29669. that.rootTracker = that.renderer.getRoot();
  29670. $.each(that.argumentAxis, function(_, axis) {
  29671. axis._axisElementsGroup && that._eventHandler(axis._axisElementsGroup, {
  29672. parser: that._getOptionsAxis,
  29673. condition: that._axisCondition,
  29674. execute: that._axisEvent
  29675. }, {
  29676. tracker: that,
  29677. axis: axis
  29678. })
  29679. });
  29680. that._eventHandler(that.seriesTrackerGroup, {
  29681. parser: that._getOptionsPointSeries,
  29682. condition: that._seriesCondition,
  29683. execute: that._seriesEvent
  29684. }, {tracker: that});
  29685. that._eventHandler(that.markerTrackerGroup, {
  29686. parser: that._getOptionsPointSeries,
  29687. condition: that._pointCondition,
  29688. execute: that._pointEvent
  29689. }, {tracker: that});
  29690. that.legendGroup && that._eventHandler(that.legendGroup, {
  29691. parser: that._getLegendData(typeChart),
  29692. condition: that._seriesCondition,
  29693. execute: that._getLegendEvent(typeChart)
  29694. }, {tracker: that});
  29695. that._eventHandler(that.rootTracker, {
  29696. parser: that._getOptionsCrossHair,
  29697. execute: that._crossHairEvent
  29698. }, {tracker: that})
  29699. },
  29700. _getLegendData: function(typeChart) {
  29701. return function(event) {
  29702. var target = $(event.target),
  29703. itemIndex = target.data('itemIndex'),
  29704. that = event.data.tracker,
  29705. mode = utils.isNumber(itemIndex) && target.data('mode');
  29706. if (event.type === 'mousemove')
  29707. return [that, event.pageX, event.pageY, event.offsetX, event.offsetY];
  29708. if (!utils.isNumber(itemIndex))
  29709. return null;
  29710. if (typeChart === 'pieChart')
  29711. return [that, that.storedSeries[0].getPoints()[itemIndex], mode, event];
  29712. else
  29713. return [that, that.storedSeries[itemIndex], mode, event]
  29714. }
  29715. },
  29716. _getLegendEvent: function(typeChart) {
  29717. var that = this,
  29718. legendEvent;
  29719. if (typeChart === 'pieChart')
  29720. legendEvent = $.extend({}, this._pointEvent, {
  29721. touchend: function(that, point, mode, event) {
  29722. if (!that.showHoldTooltip)
  29723. that._legendClick(that, point, true, event) || that._pointClick(that, point, true, event);
  29724. clearTimeout(that.tooltipHoldTimeout);
  29725. that._clickLock(that);
  29726. that._clearHover(that)
  29727. },
  29728. click: function(that, point, mode, event) {
  29729. that._legendClick(that, point, false, event) || that._pointClick(that, point, false, event)
  29730. }
  29731. });
  29732. else
  29733. legendEvent = $.extend({}, this._seriesEvent, {
  29734. click: function(that, series, mode, event) {
  29735. that._legendClick(that, series, false, event) || that._seriesClick(that, series, false, event)
  29736. },
  29737. touchend: function(that, series, mode, event) {
  29738. that._legendClick(that, series, true, event) || that._seriesClick(that, series, true, event);
  29739. that._clickLock(that)
  29740. }
  29741. });
  29742. this.__legendEvent = legendEvent;
  29743. return legendEvent
  29744. },
  29745. _eventHandler: function(group, handlers, data) {
  29746. var prepareHandlers = this._designerHandlers(handlers);
  29747. group.off(".dxc-tracker");
  29748. group.on(prepareHandlers, data)
  29749. },
  29750. _designerHandlers: function(handler) {
  29751. var handlers = {},
  29752. parser = handler.parser,
  29753. condition = handler.condition,
  29754. execute = handler.execute,
  29755. designerHandle = function(eventType, func) {
  29756. if (condition && condition[eventType] === null)
  29757. return;
  29758. handlers[eventType + ".dxc-tracker"] = function(event) {
  29759. var options = parser ? parser(event) : event;
  29760. if (!options)
  29761. return;
  29762. if (condition && condition[eventType] && condition[eventType].call)
  29763. condition[eventType].apply(null, options.concat([func]));
  29764. else
  29765. func.apply(null, options)
  29766. }
  29767. };
  29768. $.each(execute, designerHandle);
  29769. return handlers
  29770. },
  29771. _getOptionsCrossHair: function(event) {
  29772. var that = event.data.tracker;
  29773. var rootOffset = utils.getRootOffset(that.renderer);
  29774. var xe = event.pageX - rootOffset.left;
  29775. var ye = event.pageY - rootOffset.top;
  29776. return [that, xe, ye]
  29777. },
  29778. _getOptionsPointSeries: function(event) {
  29779. var object = $(event.target).data('point') || $(event.target).data('series'),
  29780. that = event.data.tracker,
  29781. mode = object && processMode($(event.target).data('mode') || object.getOptions().hoverMode);
  29782. if (event.type === 'mousemove')
  29783. return [that, event.pageX, event.pageY, event.offsetX, event.offsetY];
  29784. if (!object)
  29785. return null;
  29786. return [that, object, mode, event]
  29787. },
  29788. _getOptionsAxis: function(event) {
  29789. var that = event.data.tracker,
  29790. axis = event.data.axis,
  29791. mode = axis.options.hoverMode,
  29792. argument;
  29793. if (event.target.tagName === "tspan")
  29794. argument = $(event.target).parent().data('argument');
  29795. else
  29796. argument = $(event.target).data('argument');
  29797. if (event.type === 'mousemove')
  29798. return [that, event.pageX, event.pageY];
  29799. if (!axis)
  29800. return null;
  29801. return [that, axis, mode, argument, event]
  29802. },
  29803. _pointEvent: {
  29804. mouseover: function(that, point, mode) {
  29805. if (that.mouseLocked)
  29806. return;
  29807. that._setHoveredPoint(point, mode);
  29808. if (that.tooltipEnabled && point && point.getOptions())
  29809. that._compareCoords(that, function() {
  29810. that._showTooltip(that.tooltip, point)
  29811. })
  29812. },
  29813. mouseout: function(that, point, mode) {
  29814. if (that.mouseLocked)
  29815. return;
  29816. that._clearHover(that)
  29817. },
  29818. touchmove: function(that, point, mode) {
  29819. clearTimeout(that.tooltipHoldTimeout);
  29820. that.tooltipHoldTimeout = null;
  29821. that.showHoldTooltip = true
  29822. },
  29823. mousemove: function(that, pageX, pageY, offsetX, offsetY) {
  29824. that._setCurCoords(that, pageX, pageY)
  29825. },
  29826. touchstart: function(that, point, mode) {
  29827. that.showHoldTooltip = false;
  29828. that._mouseLock(that);
  29829. if (that.tooltipEnabled)
  29830. that.tooltipHoldTimeout = setTimeout(function() {
  29831. that.showHoldTooltip = true;
  29832. that._showTooltip(that.tooltip, point)
  29833. }, TOOLTIP_HOLD_TIMEOUT)
  29834. },
  29835. touchend: function(that, point, mode, event) {
  29836. if (!that.showHoldTooltip)
  29837. that._pointClick(that, point, true, event);
  29838. clearTimeout(that.tooltipHoldTimeout);
  29839. that._clickLock(that);
  29840. that._clearHover(that)
  29841. },
  29842. click: function(that, point, mode, event) {
  29843. that._pointClick(that, point, false, event)
  29844. },
  29845. mousedown: function(that, point, mode) {
  29846. that._pointEvent.touchstart(that, point, mode)
  29847. },
  29848. mouseup: function(that, point, mode, event) {
  29849. that._pointEvent.touchend(that, point, mode, event)
  29850. }
  29851. },
  29852. _pointCondition: {
  29853. mouseover: function(that, point, mode, event, func) {
  29854. if (mode === ALL_ARGUMENTS_POINTS_MODE && that.hoveredPoint && that.hoveredPoint.argument === point.argument) {
  29855. that.hoverHoldTimeOut = clearTimeout(that.hoverHoldTimeOut);
  29856. that.hoveredObject = point;
  29857. func(that, point, mode);
  29858. return
  29859. }
  29860. that._setHover(that, point, mode, func)
  29861. },
  29862. mouseout: function(that, point, mode, event, func) {
  29863. that._releaseHover(that, point, mode, func)
  29864. },
  29865. touchstart: !msPointerEnabled,
  29866. touchend: !msPointerEnabled,
  29867. mousedown: msPointerEnabled,
  29868. mouseup: msPointerEnabled
  29869. },
  29870. _seriesEvent: {
  29871. mouseover: function(that, series, mode) {
  29872. if (that.mouseLocked)
  29873. return;
  29874. that._setHoveredSeries(series, mode)
  29875. },
  29876. mouseout: function(that, series, mode) {
  29877. that._clearHover(that)
  29878. },
  29879. mousemove: function(that, pageX, pageY, offsetX, offsetY) {
  29880. that._setCurCoords(that, pageX, pageY)
  29881. },
  29882. touchstart: function(that) {
  29883. that._mouseLock(that)
  29884. },
  29885. touchend: function(that, series, _, event) {
  29886. that._seriesClick(that, series, true, event);
  29887. that._clickLock(that)
  29888. },
  29889. click: function(that, series, mode, event) {
  29890. that._seriesClick(that, series, false, event)
  29891. },
  29892. mousedown: function(that, point, mode) {
  29893. that._seriesEvent.touchstart(that, point, mode)
  29894. },
  29895. mouseup: function(that, point, mode) {
  29896. that._seriesEvent.touchend(that, point, mode)
  29897. }
  29898. },
  29899. _crossHairEvent: {
  29900. mousemove: function(that, x, y) {
  29901. if (!that.eventType) {
  29902. that.eventType = 'mouse';
  29903. return
  29904. }
  29905. else if (that.eventType === 'touch')
  29906. return;
  29907. else if (that.eventType === 'mouse') {
  29908. that._moveCrossHair(that, x, y);
  29909. that.eventType = null
  29910. }
  29911. },
  29912. mouseout: function(that) {
  29913. that._hideCrossHair(that);
  29914. that.eventType = null
  29915. },
  29916. touchstart: function(that, x, y) {
  29917. that.eventType = 'touch'
  29918. },
  29919. touchend: function(that, x, y) {
  29920. that.eventType = null
  29921. },
  29922. mousedown: function(that, x, y) {
  29923. that._crossHairEvent.touchstart(that, x, y)
  29924. },
  29925. mouseup: function(that, x, y) {
  29926. that._crossHairEvent.touchend(that, x, y)
  29927. }
  29928. },
  29929. _hideCrossHair: function(that) {
  29930. if (!that.crossHairOptions)
  29931. return;
  29932. var horizontalLine = that.crossHairOptions.horizontalLine,
  29933. verticalLine = that.crossHairOptions.verticalLine;
  29934. horizontalLine && horizontalLine.applySettings({visibility: 'hidden'});
  29935. verticalLine && verticalLine.applySettings({visibility: 'hidden'})
  29936. },
  29937. _moveCrossHair: function(that, x, y) {
  29938. if (!that.crossHairOptions)
  29939. return;
  29940. var horizontalLine = that.crossHairOptions.horizontalLine,
  29941. verticalLine = that.crossHairOptions.verticalLine,
  29942. canvas = that.crossHairOptions.canvas || {};
  29943. if (x > canvas.left && x < canvas.width - canvas.right && y > canvas.top && y < canvas.height - canvas.bottom) {
  29944. horizontalLine && horizontalLine.applySettings({visibility: 'visible'});
  29945. verticalLine && verticalLine.applySettings({visibility: 'visible'});
  29946. horizontalLine && horizontalLine.applySettings({translateY: y - canvas.top});
  29947. verticalLine && verticalLine.applySettings({translateX: x - canvas.left})
  29948. }
  29949. else {
  29950. horizontalLine && horizontalLine.applySettings({visibility: 'hidden'});
  29951. verticalLine && verticalLine.applySettings({visibility: 'hidden'})
  29952. }
  29953. },
  29954. _seriesCondition: {
  29955. mouseover: function(that, series, mode, event, func) {
  29956. that.hoverStartDelay = 0;
  29957. that._setHover(that, series, mode, func)
  29958. },
  29959. mouseout: function(that, series, mode, event, func) {
  29960. that.hoverStartDelay = HOVER_START_DELAY;
  29961. that._releaseHover(that, series, mode, func)
  29962. },
  29963. touchstart: !msPointerEnabled,
  29964. touchend: !msPointerEnabled,
  29965. mousedown: msPointerEnabled,
  29966. mouseup: msPointerEnabled
  29967. },
  29968. _axisEvent: {
  29969. mouseover: function(that, axis, argument) {
  29970. if (that.mouseLocked || isDefined(that.hoveredArgument) && that.hoveredArgument === argument)
  29971. return;
  29972. that._clearHover(that);
  29973. if (isDefined(that.hoveredArgument))
  29974. that._toAllArgumentPoints(that.hoveredArgument, 'releasePointHoverState');
  29975. that._toAllArgumentPoints(argument, 'setPointHoverState');
  29976. that.hoveredArgument = argument
  29977. },
  29978. mouseout: function(that, axis) {
  29979. if (that.mouseLocked || !isDefined(that.hoveredArgument))
  29980. return;
  29981. that._toAllArgumentPoints(that.hoveredArgument, 'releasePointHoverState');
  29982. that.hoveredArgument = null
  29983. },
  29984. mousemove: function(that, pageX, pageY) {
  29985. that._setCurCoords(that, pageX, pageY)
  29986. },
  29987. touchstart: function(that) {
  29988. that._mouseLock(that)
  29989. },
  29990. touchend: function(that, axis, mode, argument, event) {
  29991. that._argumentAxisClick(that, axis, argument, true, event);
  29992. that._clearHover(that);
  29993. that._clickLock(that)
  29994. },
  29995. click: function(that, axis, mode, argument, event) {
  29996. that._clearHover(that);
  29997. that._argumentAxisClick(that, axis, argument, false, event)
  29998. },
  29999. mousedown: function(that) {
  30000. that._axisEvent.touchstart(that)
  30001. },
  30002. mouseup: function(that, axis, mode, argument, event) {
  30003. that._axisEvent.touchend(that, axis, mode, argument, event)
  30004. }
  30005. },
  30006. _axisCondition: {
  30007. mouseover: function(that, axis, mode, argument, event, func) {
  30008. that._hideCrossHair(that);
  30009. if (mode === ALL_ARGUMENTS_POINTS_MODE)
  30010. that._setHover(that, axis, argument, func)
  30011. },
  30012. mouseout: function(that, axis, mode, argument, event, func) {
  30013. that._releaseHover(that, axis, argument, func)
  30014. },
  30015. touchstart: !msPointerEnabled,
  30016. touchend: !msPointerEnabled,
  30017. mousedown: msPointerEnabled,
  30018. mouseup: msPointerEnabled
  30019. },
  30020. _setHover: function(that, object, mode, func) {
  30021. if (object === that.hoveredObject) {
  30022. that.hoverHoldTimeOut = clearTimeout(that.hoverHoldTimeOut);
  30023. if (mode === object.lastHoverMode)
  30024. return
  30025. }
  30026. if (that.mouseLocked)
  30027. return;
  30028. clearTimeout(that.cmpCoordTimeout);
  30029. clearTimeout(that.hoverStartTimeOut);
  30030. that.hoverStartTimeOut = setTimeout(function() {
  30031. clearTimeout(that.hoverHoldTimeOut);
  30032. that.hoveredObject = object;
  30033. func(that, object, mode)
  30034. }, that.hoverStartDelay)
  30035. },
  30036. _releaseHover: function(that, object, mode, func) {
  30037. if (that.mouseLocked)
  30038. return;
  30039. clearTimeout(that.cmpCoordTimeout);
  30040. clearTimeout(that.hoverStartTimeOut);
  30041. if (object === that.hoveredObject)
  30042. that.hoverHoldTimeOut = setTimeout(function() {
  30043. that.hoveredObject = null;
  30044. func(that, object, mode);
  30045. that.hoverStartDelay = 0
  30046. }, HOVER_HOLD_DELAY)
  30047. },
  30048. _compareCoords: function(that, func) {
  30049. clearTimeout(that.cmpCoordTimeout);
  30050. if (Math.abs(that.pX - that.cX) + Math.abs(that.pY - that.cY) < that.sensitivity) {
  30051. if (that.mouseLocked)
  30052. return;
  30053. func()
  30054. }
  30055. else {
  30056. that.pX = that.cX;
  30057. that.pY = that.cY;
  30058. that.cmpCoordTimeout = setTimeout(function() {
  30059. that._compareCoords(that, func)
  30060. }, that.hoverStartDelay === 0 ? HOVER_START_DELAY : 0)
  30061. }
  30062. },
  30063. _seriesClick: function(that, series, touchEvent, event) {
  30064. if (that.lockClick && !touchEvent)
  30065. return;
  30066. that.seriesClick && that.seriesClick.call(series, series, event)
  30067. },
  30068. _legendClick: function(that, series, touchEvent, event) {
  30069. var legendClick = that.legendClick;
  30070. if (that.lockClick && !touchEvent)
  30071. return true;
  30072. if (legendClick) {
  30073. legendClick.call(series, series, event);
  30074. return true
  30075. }
  30076. return false
  30077. },
  30078. _pointClick: function(that, point, touchEvent, event) {
  30079. var series = point.series;
  30080. if (that.lockClick && !touchEvent)
  30081. return;
  30082. if (that.pointClick) {
  30083. that.pointClick.call(point, point, event);
  30084. return
  30085. }
  30086. that.seriesClick && that.seriesClick.call(series, series, event);
  30087. return
  30088. },
  30089. _argumentAxisClick: function(that, axis, argument, touchEvent, event) {
  30090. if (that.lockClick && !touchEvent)
  30091. return;
  30092. that.argumentAxisClick && that.argumentAxisClick.call(axis, axis, argument, event)
  30093. },
  30094. _selectSeries: function(event, mode) {
  30095. event.data.tracker._setSelectedSeries(event.target, mode)
  30096. },
  30097. _deselectSeries: function(event, mode) {
  30098. event.data.tracker._releaseSelectedSeries(event.target, mode)
  30099. },
  30100. _selectPoint: function(event, point) {
  30101. event.data.tracker._setSelectedPoint(point)
  30102. },
  30103. _deselectPoint: function(event, point) {
  30104. event.data.tracker._releaseSelectedPoint(point)
  30105. },
  30106. _showPointTooltip: function(event, point) {
  30107. var that = event.data.tracker;
  30108. that._showTooltip(that.tooltip, point)
  30109. },
  30110. _hidePointTooltip: function(event, point) {
  30111. event.data.tracker._hideTooltip(point)
  30112. },
  30113. _hideTooltip: function(point) {
  30114. var tooltip = this && this.tooltip;
  30115. if (!tooltip || point && this.pointAtShownTooltip !== point)
  30116. return;
  30117. point = point || this.pointAtShownTooltip;
  30118. tooltip.hide();
  30119. if (this.pointAtShownTooltip) {
  30120. this.pointAtShownTooltip = null;
  30121. isFunction(this.tooltipHidden) && this.tooltipHidden.call(point, point)
  30122. }
  30123. },
  30124. _showTooltip: function(tooltip, point) {
  30125. var tooltipFormatObject = point.getTooltipFormatObject(tooltip);
  30126. if (!isDefined(tooltipFormatObject.valueText) && !tooltipFormatObject.points || !point.isVisible())
  30127. return;
  30128. this.pointAtShownTooltip && this._hideTooltip(this.pointAtShownTooltip);
  30129. if (point && point.getOptions()) {
  30130. var tooltipCoords = point.getTooltipCoords();
  30131. if (!tooltip.prepare(tooltipFormatObject, {
  30132. x: tooltipCoords.x,
  30133. y: tooltipCoords.y,
  30134. offset: tooltipCoords.offset
  30135. }))
  30136. return;
  30137. tooltip.show();
  30138. !this.pointAtShownTooltip && isFunction(this.tooltipShown) && this.tooltipShown.call(point, point);
  30139. this.pointAtShownTooltip = point
  30140. }
  30141. },
  30142. _setHoveredSeries: function(series, mode) {
  30143. var that = this;
  30144. if (mode !== NONE_MODE && that.hoveredSeries !== series || series.lastHoverMode !== mode) {
  30145. that._clearHover(that);
  30146. that.hoveredSeries = series;
  30147. series.setHoverState(mode, that.legendCallback(series));
  30148. that.seriesHover && that.seriesHover.call(series, series);
  30149. that.seriesHoverChanged && that.seriesHoverChanged.call(series, series)
  30150. }
  30151. if (mode === NONE_MODE)
  30152. $(series).trigger('NoneMode')
  30153. },
  30154. _setSelectedSeries: function(series, mode) {
  30155. var that = this,
  30156. seriesContain = false;
  30157. if (this.seriesSelectionMode === MULTIPLE_MODE)
  30158. $.each(that.selectedSeries, function(_, sr) {
  30159. if (sr == series) {
  30160. seriesContain = true;
  30161. return false
  30162. }
  30163. });
  30164. else if (that.selectedSeries == series)
  30165. seriesContain = true;
  30166. if (!seriesContain || series.lastSelectionMode !== mode) {
  30167. if (that.seriesSelectionMode === SINGLE_MODE) {
  30168. this._releaseSelectedSeries();
  30169. that.selectedSeries = series
  30170. }
  30171. else
  30172. that.selectedSeries.push(series);
  30173. series.setSelectedState(mode, that.legendCallback(series));
  30174. that.seriesSelected && that.seriesSelected.call(series, series);
  30175. that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series)
  30176. }
  30177. },
  30178. _setHoveredPoint: function(point, mode) {
  30179. var that = this;
  30180. var debug = DX.utils.debug;
  30181. debug.assert(point.series, 'series was not assigned to point or empty');
  30182. if (that.hoveredPoint === point && !point.series)
  30183. return;
  30184. that._clearHover(that);
  30185. that.hoveredPoint = point;
  30186. if (point && point.getOptions())
  30187. that._setHoverStylePointWithMode(point, 'setPointHoverState', mode || processMode(point.getOptions().hoverMode), that.pointHoverChanged, that.legendCallback(point));
  30188. that.pointHover && that.pointHover.call(point, point)
  30189. },
  30190. _toAllArgumentPoints: function(argument, func, callBack) {
  30191. var that = this;
  30192. $.each(that.storedSeries, function(_, series) {
  30193. var neighborPoint = series.getPointByArg(argument);
  30194. if (neighborPoint) {
  30195. series[func](neighborPoint);
  30196. callBack && callBack.call(neighborPoint, neighborPoint)
  30197. }
  30198. })
  30199. },
  30200. _setHoverStylePointWithMode: function(point, func, mode, callBack, legendCallback) {
  30201. var that = this;
  30202. switch (mode) {
  30203. case ALL_ARGUMENTS_POINTS_MODE:
  30204. this._toAllArgumentPoints(point.argument, func, callBack);
  30205. break;
  30206. case ALL_SERIES_POINTS_MODE:
  30207. $.each(point.series.getPoints(), function(_, point) {
  30208. point.series[func](point);
  30209. callBack && callBack.call(point, point)
  30210. });
  30211. break;
  30212. case NONE_MODE:
  30213. break;
  30214. default:
  30215. point.series[func](point, legendCallback);
  30216. callBack && callBack.call(point, point)
  30217. }
  30218. },
  30219. _setSelectedPoint: function(point) {
  30220. var that = this,
  30221. pointContain = false;
  30222. if (this.pointSelectionMode === MULTIPLE_MODE) {
  30223. $.each(that.selectedPoint, function(_, pt) {
  30224. if (pt == point) {
  30225. pointContain = true;
  30226. return false
  30227. }
  30228. });
  30229. !pointContain && that.selectedPoint.push(point)
  30230. }
  30231. else if (that.selectedPoint !== point) {
  30232. this._releaseSelectedPoint();
  30233. that.selectedPoint = point
  30234. }
  30235. else
  30236. pointContain = true;
  30237. if (!pointContain) {
  30238. that._setHoverStylePointWithMode(point, 'setPointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
  30239. that.pointSelected && that.pointSelected.call(point, point)
  30240. }
  30241. },
  30242. _releaseHoveredSeries: function() {
  30243. var that = this;
  30244. if (!that.hoveredSeries)
  30245. return;
  30246. that.hoveredSeries.releaseHoverState(undefined, that.legendCallback(that.hoveredSeries));
  30247. that.seriesHoverChanged && that.seriesHoverChanged.call(that.hoveredSeries, that.hoveredSeries);
  30248. that.hoveredSeries = null
  30249. },
  30250. _releaseSelectedSeriesMultiMode: function(series) {
  30251. var that = this;
  30252. if (!that.selectedSeries)
  30253. return;
  30254. series.releaseSelectedState(undefined, that.legendCallback(series));
  30255. that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series);
  30256. that.selectedSeries = $.map(that.selectedSeries, function(sr) {
  30257. if (sr !== series)
  30258. return sr
  30259. })
  30260. },
  30261. _releaseSelectedSeriesSingleMode: function() {
  30262. var that = this,
  30263. series = this.selectedSeries;
  30264. if (!series)
  30265. return;
  30266. series.releaseSelectedState(undefined, that.legendCallback(series));
  30267. that.seriesSelectionChanged && that.seriesSelectionChanged.call(series, series);
  30268. that.selectedSeries = null
  30269. },
  30270. _releaseHoveredPoint: function() {
  30271. var that = this,
  30272. point = that.hoveredPoint,
  30273. mode;
  30274. if (!point || !point.getOptions())
  30275. return;
  30276. mode = processMode(point.getOptions().hoverMode);
  30277. if (mode === ALL_SERIES_POINTS_MODE)
  30278. $.each(point.series.getPoints(), function(_, point) {
  30279. point.series.releasePointHoverState(point);
  30280. that.pointHoverChanged && that.pointHoverChanged.call(point, point)
  30281. });
  30282. else if (mode === ALL_ARGUMENTS_POINTS_MODE)
  30283. that._toAllArgumentPoints(point.argument, 'releasePointHoverState', that.pointHoverChanged);
  30284. else {
  30285. point.releaseHoverState(that.legendCallback(point));
  30286. that.pointHoverChanged && that.pointHoverChanged.call(point, point)
  30287. }
  30288. if (that.tooltipEnabled && !that.showHoldTooltip)
  30289. that._hideTooltip(point);
  30290. that.hoveredPoint = null
  30291. },
  30292. _releaseSelectedPointMultiMode: function(point) {
  30293. var that = this,
  30294. points = that.selectedPoint;
  30295. if (!points)
  30296. return;
  30297. that._setHoverStylePointWithMode(point, 'releasePointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
  30298. this.selectedPoint = $.map(this.selectedPoint, function(pt) {
  30299. if (pt !== point)
  30300. return pt
  30301. })
  30302. },
  30303. _releaseSelectedPointSingleMode: function() {
  30304. var that = this,
  30305. point = that.selectedPoint;
  30306. if (!point)
  30307. return;
  30308. that._setHoverStylePointWithMode(point, 'releasePointSelectedState', processMode(point.getOptions().selectionMode), that.pointSelectionChanged, that.legendCallback(point));
  30309. this.selectedPoint = null
  30310. },
  30311. _clearPointSelection: function() {
  30312. var that = this;
  30313. if (that.pointSelectionMode === SINGLE_MODE)
  30314. that._releaseSelectedPoint();
  30315. else
  30316. $.each(that.selectedPoint || [], function(_, point) {
  30317. that._releaseSelectedPoint(point)
  30318. })
  30319. },
  30320. clearSelection: function() {
  30321. var that = this;
  30322. that._clearPointSelection();
  30323. if (that.seriesSelectionMode === SINGLE_MODE)
  30324. that._releaseSelectedSeries();
  30325. else
  30326. $.each(that.selectedSeries, function(_, series) {
  30327. that._releaseSelectedSeries(series)
  30328. })
  30329. },
  30330. setTooltip: function(tooltip) {
  30331. this.tooltip = tooltip
  30332. },
  30333. _mouseLock: function(tracker) {
  30334. if (tracker.unlockMouseTimer)
  30335. clearTimeout(tracker.unlockMouseTimer);
  30336. tracker.mouseLocked = true;
  30337. tracker.unlockMouseTimer = setTimeout(function() {
  30338. tracker.mouseLocked = false
  30339. }, MOUSE_EVENT_LOCK_TIMEOUT)
  30340. },
  30341. _clickLock: function(tracker) {
  30342. tracker.lockClick = true;
  30343. if (tracker.lockClickTimer)
  30344. clearTimeout(tracker.lockClickTimer);
  30345. tracker.lockClickTimer = setTimeout(function() {
  30346. tracker.lockClick = false
  30347. }, CLICK_EVENT_LOCK_TIMEOUT)
  30348. },
  30349. _setCurCoords: function(that, pageX, pageY) {
  30350. that.cX = pageX;
  30351. that.cY = pageY
  30352. },
  30353. _clearHover: function(that) {
  30354. that._releaseHoveredSeries();
  30355. that._releaseHoveredPoint()
  30356. }
  30357. })
  30358. })(jQuery, DevExpress);
  30359. /*! Module viz-charts, file dxChart.js */
  30360. (function($, DX, undefined) {
  30361. var ui = DX.ui,
  30362. viz = DX.viz;
  30363. DX.registerComponent("dxChart", viz.charts.Chart)
  30364. })(jQuery, DevExpress);
  30365. /*! Module viz-charts, file dxPieChart.js */
  30366. (function($, DX, undefined) {
  30367. var ui = DX.ui,
  30368. viz = DX.viz;
  30369. DX.registerComponent("dxPieChart", viz.charts.PieChart)
  30370. })(jQuery, DevExpress);
  30371. DevExpress.MOD_VIZ_CHARTS = true
  30372. }
  30373. if (!DevExpress.MOD_VIZ_GAUGES) {
  30374. if (!DevExpress.MOD_VIZ_CORE)
  30375. throw Error('Required module is not referenced: viz-core');
  30376. /*! Module viz-gauges, file namespaces.js */
  30377. (function(DX) {
  30378. DX.viz.gauges = {__internals: {
  30379. circularNeedles: {},
  30380. circularMarkers: {},
  30381. linearNeedles: {},
  30382. linearMarkers: {}
  30383. }};
  30384. DX.viz.gauges.__tests = {}
  30385. })(DevExpress);
  30386. /*! Module viz-gauges, file factory.js */
  30387. (function(DX, $, undefined) {
  30388. var internals = DX.viz.gauges.__internals,
  30389. circularNeedles = internals.circularNeedles,
  30390. circularMarkers = internals.circularMarkers,
  30391. linearNeedles = internals.linearNeedles,
  30392. linearMarkers = internals.linearMarkers;
  30393. var _String = window.String,
  30394. _isString = DX.utils.isString;
  30395. DX.viz.gauges.__factory = {
  30396. createCircularValueIndicator: function(type) {
  30397. var indicatorType = circularNeedles.RectangleNeedle;
  30398. switch (_String(type).toLowerCase()) {
  30399. case'rectangleneedle':
  30400. case'rectangle':
  30401. indicatorType = circularNeedles.RectangleNeedle;
  30402. break;
  30403. case'triangleneedle':
  30404. case'triangle':
  30405. indicatorType = circularNeedles.TriangleNeedle;
  30406. break;
  30407. case'twocolorneedle':
  30408. case'twocolorrectangle':
  30409. indicatorType = circularNeedles.TwoColorRectangleNeedle;
  30410. break;
  30411. case'rangebar':
  30412. indicatorType = internals.CircularRangeBar;
  30413. break
  30414. }
  30415. return new indicatorType
  30416. },
  30417. createLinearValueIndicator: function(type) {
  30418. var indicatorType = internals.LinearRangeBar;
  30419. switch (_String(type).toLowerCase()) {
  30420. case'rectangle':
  30421. indicatorType = linearNeedles.RectangleNeedle;
  30422. break;
  30423. case'rhombus':
  30424. indicatorType = linearNeedles.RhombusNeedle;
  30425. break;
  30426. case'circle':
  30427. indicatorType = linearNeedles.CircleNeedle;
  30428. break;
  30429. case'rangebar':
  30430. indicatorType = internals.LinearRangeBar;
  30431. break
  30432. }
  30433. return new indicatorType
  30434. },
  30435. createCircularSubvalueIndicator: function(type) {
  30436. var indicatorType = circularMarkers.TriangleMarker;
  30437. switch (_String(type).toLowerCase()) {
  30438. case'trianglemarker':
  30439. case'triangle':
  30440. indicatorType = circularMarkers.TriangleMarker;
  30441. break;
  30442. case'textcloud':
  30443. indicatorType = circularMarkers.TextCloudMarker;
  30444. break
  30445. }
  30446. return new indicatorType
  30447. },
  30448. createLinearSubvalueIndicator: function(type) {
  30449. var indicatorType = linearMarkers.TriangleMarker;
  30450. switch (_String(type).toLowerCase()) {
  30451. case'trianglemarker':
  30452. case'triangle':
  30453. indicatorType = linearMarkers.TriangleMarker;
  30454. break;
  30455. case'textcloud':
  30456. indicatorType = linearMarkers.TextCloudMarker;
  30457. break
  30458. }
  30459. return new indicatorType
  30460. },
  30461. createCircularValueIndicatorInHardMode: function(type) {
  30462. var indicatorType = null;
  30463. switch (_String(type).toLowerCase()) {
  30464. case'rectangleneedle':
  30465. indicatorType = circularNeedles.RectangleNeedle;
  30466. break;
  30467. case'triangleneedle':
  30468. indicatorType = circularNeedles.TriangleNeedle;
  30469. break;
  30470. case'twocolorneedle':
  30471. indicatorType = circularNeedles.TwoColorRectangleNeedle;
  30472. break;
  30473. case'rangebar':
  30474. indicatorType = internals.CircularRangeBar;
  30475. break;
  30476. case'trianglemarker':
  30477. indicatorType = circularMarkers.TriangleMarker;
  30478. break;
  30479. case'textcloud':
  30480. indicatorType = circularMarkers.TextCloudMarker;
  30481. break
  30482. }
  30483. return indicatorType ? new indicatorType : null
  30484. },
  30485. createLinearValueIndicatorInHardMode: function(type) {
  30486. var indicatorType = null;
  30487. switch (_String(type).toLowerCase()) {
  30488. case'rectangle':
  30489. indicatorType = linearNeedles.RectangleNeedle;
  30490. break;
  30491. case'rhombus':
  30492. indicatorType = linearNeedles.RhombusNeedle;
  30493. break;
  30494. case'circle':
  30495. indicatorType = linearNeedles.CircleNeedle;
  30496. break;
  30497. case'rangebar':
  30498. indicatorType = internals.LinearRangeBar;
  30499. break;
  30500. case'trianglemarker':
  30501. indicatorType = linearMarkers.TriangleMarker;
  30502. break;
  30503. case'textcloud':
  30504. indicatorType = linearMarkers.TextCloudMarker;
  30505. break
  30506. }
  30507. return indicatorType ? new indicatorType : null
  30508. },
  30509. createCircularNeedle: function(type) {
  30510. switch (_String(type).toLowerCase()) {
  30511. case'rectangleneedle':
  30512. case'rectangle':
  30513. return new circularNeedles.RectangleNeedle;
  30514. case'twocolorneedle':
  30515. case'twocolorrectangle':
  30516. return new circularNeedles.TwoColorRectangleNeedle;
  30517. case'triangleneedle':
  30518. case'triangle':
  30519. return new circularNeedles.TriangleNeedle;
  30520. case'rangebar':
  30521. return new internals.CircularRangeBar
  30522. }
  30523. return undefined
  30524. },
  30525. createLinearNeedle: function(type) {
  30526. switch (_String(type).toLowerCase()) {
  30527. case'rectangle':
  30528. return new linearNeedles.RectangleNeedle;
  30529. case'rhombus':
  30530. return new linearNeedles.RhombusNeedle;
  30531. case'circle':
  30532. return new linearNeedles.CircleNeedle;
  30533. case'rangebar':
  30534. return new internals.LinearRangeBar
  30535. }
  30536. return undefined
  30537. },
  30538. createCircularMarker: function(type) {
  30539. switch (_String(type).toLowerCase()) {
  30540. case'trianglemarker':
  30541. case'triangle':
  30542. return new circularMarkers.TriangleMarker;
  30543. case'textcloud':
  30544. return new circularMarkers.TextCloudMarker
  30545. }
  30546. return undefined
  30547. },
  30548. createLinearMarker: function(type) {
  30549. switch (_String(type).toLowerCase()) {
  30550. case'trianglemarker':
  30551. case'triangle':
  30552. return new linearMarkers.TriangleMarker;
  30553. case'textcloud':
  30554. return new linearMarkers.TextCloudMarker
  30555. }
  30556. return undefined
  30557. },
  30558. createCircularRangeBar: function(parameters) {
  30559. return new internals.CircularRangeBar(parameters)
  30560. },
  30561. createLinearRangeBar: function(parameters) {
  30562. return new internals.LinearRangeBar(parameters)
  30563. },
  30564. createCircularScale: function(parameters) {
  30565. return new internals.CircularScale(parameters)
  30566. },
  30567. createLinearScale: function(parameters) {
  30568. return new internals.LinearScale(parameters)
  30569. },
  30570. createCircularRangeContainer: function(parameters) {
  30571. return new internals.CircularRangeContainer(parameters)
  30572. },
  30573. createLinearRangeContainer: function(parameters) {
  30574. return new internals.LinearRangeContainer(parameters)
  30575. },
  30576. createTitle: function(parameters) {
  30577. return new internals.Title(parameters)
  30578. },
  30579. createIndicator: function() {
  30580. return internals.Indicator && new internals.Indicator || null
  30581. },
  30582. createLayoutManager: function() {
  30583. return new internals.LayoutManager
  30584. },
  30585. createThemeManager: function(options) {
  30586. return new internals.ThemeManager(options)
  30587. },
  30588. createTracker: function(parameters) {
  30589. return new internals.Tracker(parameters)
  30590. }
  30591. };
  30592. var _isFunction = DX.utils.isFunction,
  30593. _String = window.String,
  30594. _extend = $.extend;
  30595. var _formatHelper = DX.formatHelper;
  30596. internals.formatValue = function(value, options, extra) {
  30597. options = options || {};
  30598. var text = _formatHelper.format(value, options.format, options.precision),
  30599. context;
  30600. if (_isFunction(options.customizeText)) {
  30601. var context = _extend({
  30602. value: value,
  30603. valueText: text
  30604. }, extra);
  30605. return _String(options.customizeText.call(context, context))
  30606. }
  30607. return text
  30608. };
  30609. internals.getSampleText = function(translator, options) {
  30610. var text1 = internals.formatValue(translator.getDomainStart(), options),
  30611. text2 = internals.formatValue(translator.getDomainEnd(), options);
  30612. return text1.length >= text2.length ? text1 : text2
  30613. }
  30614. })(DevExpress, jQuery);
  30615. /*! Module viz-gauges, file scale.js */
  30616. (function(DX, $, undefined) {
  30617. var _Number = Number,
  30618. _String = String,
  30619. _isFinite = isFinite,
  30620. _min = Math.min,
  30621. _max = Math.max,
  30622. _abs = Math.abs,
  30623. _atan = Math.atan,
  30624. _acos = Math.acos,
  30625. _ceil = Math.ceil,
  30626. _isFunction = DX.utils.isFunction,
  30627. _isArray = DX.utils.isArray,
  30628. _getCosAndSin = DX.utils.getCosAndSin,
  30629. _normalizeAngle = DX.utils.normalizeAngle,
  30630. _convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  30631. _map = $.map;
  30632. var _formatHelper = DX.formatHelper,
  30633. _tickProvider = DX.viz.core.tickProvider;
  30634. var PI_DIV_180 = Math.PI / 180;
  30635. function binarySearch(x, list) {
  30636. var a = 0,
  30637. b = list.length - 1,
  30638. flag = list[a] - list[b] < 0,
  30639. c,
  30640. k = -1;
  30641. if (list[a] === x)
  30642. k = a;
  30643. if (list[b] === x)
  30644. k = b;
  30645. while (k < 0 && a <= b) {
  30646. c = ~~((a + b) / 2);
  30647. if (list[c] === x)
  30648. k = c;
  30649. else if (list[c] - x < 0 === flag)
  30650. a = c + 1;
  30651. else
  30652. b = c - 1
  30653. }
  30654. return k
  30655. }
  30656. function sortAsc(x, y) {
  30657. return x - y
  30658. }
  30659. function sortDes(x, y) {
  30660. return y - x
  30661. }
  30662. DX.viz.gauges.__internals.BaseScale = DX.Class.inherit({
  30663. ctor: function(parameters) {
  30664. var that = this;
  30665. that._renderer = parameters.renderer;
  30666. that._container = parameters.container;
  30667. that._translator = parameters.translator;
  30668. that._root = that._renderer.createGroup({'class': 'dxg-scale'});
  30669. that._majorTicks = that._renderer.createGroup({'class': 'dxg-major-ticks'});
  30670. that._minorTicks = that._renderer.createGroup({'class': 'dxg-minor-ticks'});
  30671. that._labels = that._renderer.createGroup({'class': 'dxg-labels'})
  30672. },
  30673. dispose: function() {
  30674. var that = this;
  30675. that._renderer = that._container = that._renderer = that._root = that._majorTicks = that._minorTicks = that._labels = null;
  30676. return that
  30677. },
  30678. clean: function() {
  30679. var that = this;
  30680. that._root.detach();
  30681. that._majorTicks.detach().clear();
  30682. that._minorTicks.detach().clear();
  30683. that._labels.detach().clear();
  30684. that._majorTicksEnabled = that._minorTicksEnabled = that._labelsEnabled = that._options = that.enabled = null;
  30685. return that
  30686. },
  30687. render: function(options) {
  30688. var that = this;
  30689. that._options = options;
  30690. that._processOptions(options);
  30691. if (that._majorTicksEnabled || that._minorTicksEnabled || that._labelsEnabled) {
  30692. that.enabled = true;
  30693. that._root.append(that._container);
  30694. if (that._majorTicksEnabled)
  30695. that._majorTicks.append(that._root);
  30696. if (that._minorTicksEnabled)
  30697. that._minorTicks.append(that._root);
  30698. if (that._labelsEnabled) {
  30699. that._labels.append(that._root);
  30700. that._measureText()
  30701. }
  30702. }
  30703. return that
  30704. },
  30705. _processOptions: function(options) {
  30706. var that = this;
  30707. that._majorTicksEnabled = options.majorTick.visible && options.majorTick.length > 0 && options.majorTick.width > 0;
  30708. that._minorTicksEnabled = options.minorTick.visible && options.minorTick.length > 0 && options.minorTick.width > 0;
  30709. that._labelsEnabled = options.label.visible && _Number(options.label.indentFromTick) !== 0;
  30710. that._setupOrientation()
  30711. },
  30712. _getSampleText: function() {
  30713. var that = this,
  30714. domain = that._translator.getDomain(),
  30715. texts = [],
  30716. i,
  30717. ii,
  30718. text,
  30719. maxLength = 0,
  30720. maxText = '';
  30721. var ticks = _tickProvider.getTicks({
  30722. min: domain[0],
  30723. max: domain[1],
  30724. tickInterval: that._options.majorTick.tickInterval > 0 ? _Number(that._options.majorTick.tickInterval) : undefined,
  30725. screenDelta: that._options.approximateScreenDelta,
  30726. gridSpacingFactor: that._getGridSpacingFactor().majorTicks
  30727. });
  30728. for (i = 0, ii = ticks.length; i < ii; ++i) {
  30729. text = that._formatValue(ticks[i]);
  30730. text.length > maxLength && (maxText = text) && (maxLength = text.length)
  30731. }
  30732. return maxText
  30733. },
  30734. _measureText: function() {
  30735. var that = this,
  30736. value = that._getSampleText(),
  30737. text = that._renderer.createText(value, 0, 0, {font: that._options.label.font}).append(that._labels),
  30738. bbox = text.getBBox();
  30739. text.remove();
  30740. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  30741. that._textWidth = bbox.width;
  30742. that._textHeight = bbox.height;
  30743. that._textLength = value.length
  30744. },
  30745. _formatValue: function(value) {
  30746. var options = this._options.label,
  30747. text = _formatHelper.format(value, options.format, options.precision);
  30748. if (_isFunction(options.customizeText)) {
  30749. text = {
  30750. value: value,
  30751. valueText: text
  30752. };
  30753. text = _String(options.customizeText.call(text, text))
  30754. }
  30755. return text
  30756. },
  30757. _setupOrientation: null,
  30758. _getCustomValues: function(values, compare) {
  30759. var translator = this._translator,
  30760. result = [];
  30761. if (_isArray(values)) {
  30762. result = _map(values, function(x) {
  30763. return _isFinite(translator.translate(x)) ? _Number(x) : null
  30764. }).sort(compare);
  30765. result = _map(result, function(x, i) {
  30766. return x !== result[i - 1] ? x : null
  30767. })
  30768. }
  30769. return result
  30770. },
  30771. _generateTicks: function(layout) {
  30772. var that = this,
  30773. majorTicksOptions = {
  30774. tickInterval: that._options.majorTick.tickInterval > 0 ? _Number(that._options.majorTick.tickInterval) : undefined,
  30775. gridSpacingFactor: that._getGridSpacingFactor().majorTicks,
  30776. numberMultipliers: [1, 2, 5]
  30777. },
  30778. minorTicksOptions = {
  30779. tickInterval: that._options.minorTick.tickInterval > 0 ? _Number(that._options.minorTick.tickInterval) : undefined,
  30780. gridSpacingFactor: that._getGridSpacingFactor().minorTicks,
  30781. numberMultipliers: [1, 2, 5]
  30782. };
  30783. if (that._options.majorTick.useTicksAutoArrangement) {
  30784. majorTicksOptions.useTicksAutoArrangement = true;
  30785. majorTicksOptions.renderer = that._renderer;
  30786. majorTicksOptions.translator = that._translator;
  30787. majorTicksOptions.getCustomAutoArrangementStep = function(values) {
  30788. return that._getCuttingFactor(values.length, {
  30789. width: that._textWidth,
  30790. height: that._textHeight
  30791. }, layout)
  30792. }
  30793. }
  30794. return _tickProvider.getFullTicks(that._translator.getDomain()[0], that._translator.getDomain()[1], that._getScreenDelta(layout), majorTicksOptions, minorTicksOptions)
  30795. },
  30796. _getTicks: function(layout) {
  30797. var that = this,
  30798. compareCallback = that._translator.getDomain()[0] < that._translator.getDomain()[1] ? sortAsc : sortDes,
  30799. info = that._generateTicks(layout);
  30800. var majorValues = that._options.majorTick.showCalculatedTicks ? info.majorTicks : [];
  30801. var customMajorValues = that._getCustomValues(that._options.majorTick.customTickValues, compareCallback);
  30802. customMajorValues = _map(customMajorValues, function(value) {
  30803. return binarySearch(value, majorValues) === -1 ? value : null
  30804. });
  30805. var minorValues = that._options.minorTick.showCalculatedTicks ? info.minorTicks : [];
  30806. minorValues = _map(minorValues, function(value) {
  30807. return binarySearch(value, customMajorValues) === -1 ? value : null
  30808. });
  30809. var customMinorValues = that._getCustomValues(that._options.minorTick.customTickValues, compareCallback);
  30810. var list = majorValues.concat(minorValues, customMajorValues).sort(compareCallback);
  30811. customMinorValues = _map(customMinorValues, function(value) {
  30812. return binarySearch(value, list) === -1 ? value : null
  30813. });
  30814. return {
  30815. major: _map(majorValues.concat(customMajorValues), function(value) {
  30816. return {
  30817. value: value,
  30818. position: that._translator.translate(value)
  30819. }
  30820. }),
  30821. minor: _map(minorValues.concat(customMinorValues), function(value) {
  30822. return {
  30823. value: value,
  30824. position: that._translator.translate(value)
  30825. }
  30826. })
  30827. }
  30828. },
  30829. _createMajorTicks: function(ticks, layout) {
  30830. var that = this;
  30831. that._majorTicks.clear().applySettings({fill: that._options.majorTick.color});
  30832. var points = that._getTickPoints(_Number(that._options.majorTick.length), _Number(that._options.majorTick.width), layout);
  30833. if (points) {
  30834. var i = 0,
  30835. ii = ticks.length,
  30836. element;
  30837. that._options.hideFirstTick && ++i;
  30838. that._options.hideLastTick && --ii;
  30839. for (; i < ii; ++i) {
  30840. element = that._renderer.createArea(points);
  30841. that._moveTick(element, ticks[i], layout);
  30842. element.append(that._majorTicks)
  30843. }
  30844. }
  30845. },
  30846. _createMinorTicks: function(ticks, layout) {
  30847. var that = this;
  30848. that._minorTicks.clear().applySettings({fill: that._options.minorTick.color});
  30849. var points = that._getTickPoints(_Number(that._options.minorTick.length), _Number(that._options.minorTick.width), layout);
  30850. if (points) {
  30851. var i = 0,
  30852. ii = ticks.length,
  30853. element;
  30854. for (; i < ii; ++i) {
  30855. element = that._renderer.createArea(points);
  30856. that._moveTick(element, ticks[i], layout);
  30857. element.append(that._minorTicks)
  30858. }
  30859. }
  30860. },
  30861. _createLabels: function(ticks, layout) {
  30862. var that = this,
  30863. indentFromTick = _Number(that._options.label.indentFromTick);
  30864. that._labels.clear().applySettings({
  30865. align: that._getLabelAlign(indentFromTick),
  30866. font: that._options.label.font
  30867. });
  30868. var textPosition = that._getLabelPosition(that._majorTicksEnabled ? _Number(that._options.majorTick.length) : 0, indentFromTick, layout);
  30869. if (textPosition) {
  30870. var i = 0,
  30871. ii = ticks.length,
  30872. points,
  30873. text;
  30874. that._options.hideFirstLabel && ++i;
  30875. that._options.hideLastLabel && --ii;
  30876. for (; i < ii; ++i) {
  30877. text = that._formatValue(ticks[i].value);
  30878. points = that._getLabelOptions(text, textPosition, indentFromTick, ticks[i], layout);
  30879. that._renderer.createText(text, points.x, points.y + that._textVerticalOffset).append(that._labels)
  30880. }
  30881. }
  30882. },
  30883. resize: function(layout) {
  30884. var that = this,
  30885. ticks = that._getTicks(layout);
  30886. if (that._majorTicksEnabled)
  30887. that._createMajorTicks(ticks.major, layout);
  30888. if (that._minorTicksEnabled)
  30889. that._createMinorTicks(ticks.minor, layout);
  30890. if (that._labelsEnabled)
  30891. that._createLabels(ticks.major, layout);
  30892. return that
  30893. }
  30894. });
  30895. function getBasedAngle(startAngle, endAngle) {
  30896. var startDelta,
  30897. endDelta,
  30898. tmp;
  30899. if (startAngle > endAngle) {
  30900. tmp = endAngle;
  30901. endAngle = startAngle;
  30902. startAngle = tmp
  30903. }
  30904. startDelta = 0 <= startAngle && startAngle <= 180 ? _abs(90 - startAngle) : _abs(270 - startAngle);
  30905. startDelta = startAngle < 90 && 90 < endAngle || startAngle < 270 && 270 < endAngle ? 0 : startDelta;
  30906. endDelta = 0 < endAngle && endAngle < 180 ? _abs(90 - endAngle) : _abs(270 - endAngle);
  30907. return startDelta < endDelta ? startDelta : endDelta
  30908. }
  30909. DX.viz.gauges.__internals.CircularScale = DX.viz.gauges.__internals.BaseScale.inherit({
  30910. _getGridSpacingFactor: function() {
  30911. return {
  30912. majorTicks: 17,
  30913. minorTicks: 5
  30914. }
  30915. },
  30916. _getScreenDelta: function(layout) {
  30917. return (this._translator.getCodomainStart() - this._translator.getCodomainEnd()) * layout.radius * PI_DIV_180
  30918. },
  30919. _getCuttingFactor: function(ticksCount, maxLabelSize, layout) {
  30920. var that = this,
  30921. options = that._options,
  30922. startAngle = that._translator.getCodomainStart(),
  30923. endAngle = that._translator.getCodomainEnd(),
  30924. radius = that._getLabelPosition(that._majorTicksEnabled ? _Number(that._options.majorTick.length) : 0, _Number(that._options.label.indentFromTick), layout),
  30925. baseAngle = getBasedAngle(_normalizeAngle(startAngle), _normalizeAngle(endAngle)),
  30926. baseAngleCosSin = _getCosAndSin(baseAngle),
  30927. degreesPerTick = (startAngle - endAngle) / ticksCount,
  30928. minAngleBetweenTicks,
  30929. widthBasedAngle,
  30930. tanOfWidthBasedAngle,
  30931. heightBasedAngle,
  30932. cosOfHeightBasedAngle,
  30933. cuttingBackFactor = 1;
  30934. tanOfWidthBasedAngle = (baseAngleCosSin.sin * radius + maxLabelSize.width) / (baseAngleCosSin.cos * radius);
  30935. widthBasedAngle = _abs(baseAngle - _atan(tanOfWidthBasedAngle) / PI_DIV_180);
  30936. cosOfHeightBasedAngle = baseAngleCosSin.cos - maxLabelSize.height / radius;
  30937. heightBasedAngle = -1 > cosOfHeightBasedAngle || cosOfHeightBasedAngle > 1 ? 90 : _abs(baseAngle - _acos(cosOfHeightBasedAngle) / PI_DIV_180);
  30938. minAngleBetweenTicks = widthBasedAngle < heightBasedAngle ? widthBasedAngle : heightBasedAngle;
  30939. if (degreesPerTick < minAngleBetweenTicks)
  30940. cuttingBackFactor = _ceil(minAngleBetweenTicks / degreesPerTick);
  30941. return _max(1, cuttingBackFactor)
  30942. },
  30943. _setupOrientation: function() {
  30944. var that = this;
  30945. that._inner = that._outer = 0;
  30946. switch (that._options.orientation) {
  30947. case'inside':
  30948. that._inner = 1;
  30949. break;
  30950. case'center':
  30951. that._inner = that._outer = 0.5;
  30952. break;
  30953. default:
  30954. that._outer = 1;
  30955. break
  30956. }
  30957. },
  30958. _getTickPoints: function(length, width, layout) {
  30959. var x1 = layout.x - width / 2,
  30960. x2 = layout.x + width / 2,
  30961. y1 = layout.y - layout.radius - length * this._outer,
  30962. y2 = layout.y - layout.radius + length * this._inner;
  30963. return y1 > 0 && y2 > 0 ? [x1, y1, x2, y1, x2, y2, x1, y2] : null
  30964. },
  30965. _moveTick: function(element, tick, layout) {
  30966. element.rotate(_convertAngleToRendererSpace(tick.position), layout.x, layout.y)
  30967. },
  30968. _getLabelPosition: function(tickLength, textIndent, layout) {
  30969. var position = layout.radius + tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
  30970. return position > 0 ? position : null
  30971. },
  30972. _getLabelAlign: function() {
  30973. return 'center'
  30974. },
  30975. _getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {
  30976. var cossin = _getCosAndSin(tick.position),
  30977. x = layout.x + cossin.cos * textPosition,
  30978. y = layout.y - cossin.sin * textPosition,
  30979. dx = cossin.cos * (textValue.length / this._textLength) * this._textWidth / 2,
  30980. dy = cossin.sin * this._textHeight / 2;
  30981. if (textIndent > 0) {
  30982. x += dx;
  30983. y -= dy
  30984. }
  30985. else {
  30986. x -= dx;
  30987. y += dy
  30988. }
  30989. return {
  30990. x: x,
  30991. y: y
  30992. }
  30993. },
  30994. measure: function(layout) {
  30995. var that = this,
  30996. result = {
  30997. min: layout.radius,
  30998. max: layout.radius
  30999. };
  31000. if (that._majorTicksEnabled) {
  31001. result.min = _min(result.min, layout.radius - that._inner * that._options.majorTick.length);
  31002. result.max = _max(result.max, layout.radius + that._outer * that._options.majorTick.length)
  31003. }
  31004. if (that._minorTicksEnabled) {
  31005. result.min = _min(result.min, layout.radius - that._inner * that._options.minorTick.length);
  31006. result.max = _max(result.max, layout.radius + that._outer * that._options.minorTick.length)
  31007. }
  31008. if (that._labelsEnabled) {
  31009. if (that._options.label.indentFromTick > 0) {
  31010. result.horizontalOffset = _Number(that._options.label.indentFromTick) + that._textWidth;
  31011. result.verticalOffset = _Number(that._options.label.indentFromTick) + that._textHeight
  31012. }
  31013. else {
  31014. result.horizontalOffset = result.verticalOffset = 0;
  31015. result.min -= -_Number(that._options.label.indentFromTick) + _max(that._textWidth, that._textHeight)
  31016. }
  31017. result.inverseHorizontalOffset = that._textWidth / 2;
  31018. result.inverseVerticalOffset = that._textHeight / 2
  31019. }
  31020. return result
  31021. }
  31022. });
  31023. DX.viz.gauges.__internals.LinearScale = DX.viz.gauges.__internals.BaseScale.inherit({
  31024. _getGridSpacingFactor: function() {
  31025. return {
  31026. majorTicks: 25,
  31027. minorTicks: 5
  31028. }
  31029. },
  31030. _getScreenDelta: function(layout) {
  31031. return _abs(this._translator.getCodomainEnd() - this._translator.getCodomainStart())
  31032. },
  31033. _getCuttingFactor: function(ticksCount, maxLabelSize, layout) {
  31034. var that = this,
  31035. labelSize = that.vertical ? maxLabelSize.height : maxLabelSize.width,
  31036. screenSize = _abs(that._translator.getCodomainEnd() - that._translator.getCodomainStart());
  31037. return _max(1, _ceil(ticksCount * labelSize / (screenSize + labelSize)))
  31038. },
  31039. _setupOrientation: function() {
  31040. var that = this;
  31041. that.vertical = that._options.vertical;
  31042. that._inner = that._outer = 0;
  31043. if (that.vertical)
  31044. switch (that._options.horizontalOrientation) {
  31045. case'left':
  31046. that._inner = 1;
  31047. break;
  31048. case'center':
  31049. that._inner = that._outer = 0.5;
  31050. break;
  31051. default:
  31052. that._outer = 1;
  31053. break
  31054. }
  31055. else
  31056. switch (that._options.verticalOrientation) {
  31057. case'top':
  31058. that._inner = 1;
  31059. break;
  31060. case'middle':
  31061. that._inner = that._outer = 0.5;
  31062. break;
  31063. default:
  31064. that._outer = 1;
  31065. break
  31066. }
  31067. },
  31068. _getTickPoints: function(length, width, layout) {
  31069. var that = this,
  31070. x1,
  31071. x2,
  31072. y1,
  31073. y2;
  31074. if (that.vertical) {
  31075. x1 = layout.x - length * that._inner;
  31076. x2 = layout.x + length * that._outer;
  31077. y1 = -width / 2;
  31078. y2 = +width / 2
  31079. }
  31080. else {
  31081. x1 = -width / 2;
  31082. x2 = +width / 2;
  31083. y1 = layout.y - length * that._inner;
  31084. y2 = layout.y + length * that._outer
  31085. }
  31086. return [x1, y1, x2, y1, x2, y2, x1, y2]
  31087. },
  31088. _moveTick: function(element, tick, layout) {
  31089. var x = 0,
  31090. y = 0;
  31091. if (this.vertical)
  31092. y = tick.position;
  31093. else
  31094. x = tick.position;
  31095. element.move(x, y)
  31096. },
  31097. _getLabelPosition: function(tickLength, textIndent, layout) {
  31098. var position = tickLength * (textIndent >= 0 ? this._outer : -this._inner) + textIndent;
  31099. if (this.vertical)
  31100. position += layout.x;
  31101. else
  31102. position += layout.y + (textIndent >= 0 ? 1 : -1) * this._textVerticalOffset;
  31103. return position
  31104. },
  31105. _getLabelAlign: function(textIndent) {
  31106. return this.vertical ? textIndent > 0 ? 'left' : 'right' : 'center'
  31107. },
  31108. _getLabelOptions: function(textValue, textPosition, textIndent, tick, layout) {
  31109. var x,
  31110. y;
  31111. if (this.vertical) {
  31112. x = textPosition;
  31113. y = tick.position
  31114. }
  31115. else {
  31116. x = tick.position;
  31117. y = textPosition
  31118. }
  31119. return {
  31120. x: x,
  31121. y: y
  31122. }
  31123. },
  31124. measure: function(layout) {
  31125. var that = this,
  31126. p = layout[that.vertical ? 'x' : 'y'],
  31127. result = {
  31128. min: p,
  31129. max: p
  31130. };
  31131. if (that._majorTicksEnabled) {
  31132. result.min = _min(result.min, p - that._inner * that._options.majorTick.length);
  31133. result.max = _max(result.max, p + that._outer * that._options.majorTick.length)
  31134. }
  31135. if (that._minorTicksEnabled) {
  31136. result.min = _min(result.min, p - that._inner * that._options.minorTick.length);
  31137. result.max = _max(result.max, p + that._outer * that._options.minorTick.length)
  31138. }
  31139. if (that._labelsEnabled) {
  31140. if (that._options.label.indentFromTick > 0)
  31141. result.max += +_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
  31142. else
  31143. result.min -= -_Number(that._options.label.indentFromTick) + that[that.vertical ? '_textWidth' : '_textHeight'];
  31144. result.indent = that[that.vertical ? '_textHeight' : '_textWidth'] / 2
  31145. }
  31146. return result
  31147. }
  31148. })
  31149. })(DevExpress, jQuery);
  31150. /*! Module viz-gauges, file baseIndicator.js */
  31151. (function(DX, $, undefined) {
  31152. var _isFinite = isFinite,
  31153. _Number = Number,
  31154. _extend = $.extend;
  31155. DX.viz.gauges.__internals.BaseIndicator = DX.Class.inherit({
  31156. setup: function(parameters) {
  31157. var that = this;
  31158. that._renderer = parameters.renderer;
  31159. that._translator = parameters.translator;
  31160. that._owner = parameters.owner;
  31161. that._tracker = parameters.tracker;
  31162. that._className = parameters.className;
  31163. that._options = {};
  31164. that._rootElement = that._createRoot();
  31165. that._trackerElement = that._createTracker();
  31166. return that
  31167. },
  31168. dispose: function() {
  31169. var that = this;
  31170. that._renderer = that._owner = that._translator = that._tracker = that._options = that._rootElement = that._trackerElement = null;
  31171. return that
  31172. },
  31173. _setupAnimation: function() {
  31174. var that = this;
  31175. if (that._options.animation)
  31176. that._animation = {
  31177. step: function(pos) {
  31178. that._actualValue = that._animation.start + that._animation.delta * pos;
  31179. that._actualPosition = that._translator.translate(that._actualValue);
  31180. that._move()
  31181. },
  31182. duration: that._options.animation.duration > 0 ? _Number(that._options.animation.duration) : 0,
  31183. easing: that._options.animation.easing
  31184. }
  31185. },
  31186. _runAnimation: function(value) {
  31187. var that = this,
  31188. animation = that._animation;
  31189. animation.start = that._actualValue;
  31190. animation.delta = value - that._actualValue;
  31191. that._rootElement.animate({_: 0}, {
  31192. step: animation.step,
  31193. duration: animation.duration,
  31194. easing: animation.easing
  31195. })
  31196. },
  31197. _createRoot: function() {
  31198. return this._renderer.createGroup({'class': this._className})
  31199. },
  31200. _createTracker: function() {
  31201. return this._renderer.createArea()
  31202. },
  31203. _getTrackerSettings: function(){},
  31204. clean: function() {
  31205. var that = this;
  31206. that._animation && that._rootElement.stopAnimation();
  31207. that._rootElement.detach();
  31208. that._rootElement.clear();
  31209. that._clear();
  31210. that._tracker.detach(that._trackerElement);
  31211. that._options = that.enabled = that._animation = null;
  31212. return that
  31213. },
  31214. render: function(options) {
  31215. var that = this;
  31216. that.type = options.type;
  31217. that._options = options;
  31218. that._actualValue = that._currentValue = that._translator.adjust(that._options.currentValue);
  31219. that.enabled = that._isEnabled();
  31220. if (that.enabled) {
  31221. that._setupAnimation();
  31222. that._rootElement.applySettings({fill: that._options.color}).append(that._owner);
  31223. that._tracker.attach(that._trackerElement, that, that._trackerInfo)
  31224. }
  31225. return that
  31226. },
  31227. resize: function(layout) {
  31228. var that = this;
  31229. that._rootElement.clear();
  31230. that._clear();
  31231. that.visible = that._isVisible(layout);
  31232. if (that.visible) {
  31233. _extend(that._options, layout);
  31234. that._actualPosition = that._translator.translate(that._actualValue);
  31235. that._render();
  31236. that._trackerElement.applySettings(that._getTrackerSettings());
  31237. that._move()
  31238. }
  31239. return that
  31240. },
  31241. value: function(arg, _noAnimation) {
  31242. var that = this;
  31243. if (arg !== undefined) {
  31244. var val = that._translator.adjust(arg);
  31245. if (that._currentValue !== val && _isFinite(val)) {
  31246. that._currentValue = val;
  31247. if (that.visible)
  31248. if (that._animation && !_noAnimation)
  31249. that._runAnimation(val);
  31250. else {
  31251. that._actualValue = val;
  31252. that._actualPosition = that._translator.translate(val);
  31253. that._move()
  31254. }
  31255. }
  31256. return that
  31257. }
  31258. return that._currentValue
  31259. },
  31260. _isEnabled: null,
  31261. _isVisible: null,
  31262. _render: null,
  31263. _clear: null,
  31264. _move: null
  31265. })
  31266. })(DevExpress, jQuery);
  31267. /*! Module viz-gauges, file baseMarker.js */
  31268. (function(DX, undefined) {
  31269. var TextCloud = DX.viz.core.TextCloud;
  31270. var formatValue = DX.viz.gauges.__internals.formatValue,
  31271. getSampleText = DX.viz.gauges.__internals.getSampleText;
  31272. DX.viz.gauges.__internals.BaseTextCloudMarker = DX.viz.gauges.__internals.BaseIndicator.inherit({
  31273. _move: function() {
  31274. var that = this,
  31275. bbox,
  31276. info = new TextCloud,
  31277. textCloudOptions = that._getTextCloudOptions();
  31278. that._text.applySettings({text: formatValue(that._actualValue, that._options.text)});
  31279. bbox = that._text.getBBox();
  31280. info.setup({
  31281. x: textCloudOptions.x,
  31282. y: textCloudOptions.y,
  31283. textWidth: bbox.width,
  31284. textHeight: bbox.height,
  31285. horMargin: that._options.horizontalOffset,
  31286. verMargin: that._options.verticalOffset,
  31287. tailLength: that._options.arrowLength,
  31288. type: textCloudOptions.type
  31289. });
  31290. that._text.applySettings({
  31291. x: info.cx(),
  31292. y: info.cy() + that._textVerticalOffset
  31293. });
  31294. that._cloud.applySettings({points: info.points()});
  31295. that._trackerElement && that._trackerElement.applySettings({points: info.points()})
  31296. },
  31297. _measureText: function() {
  31298. var that = this,
  31299. root,
  31300. text,
  31301. bbox;
  31302. if (!that._textVerticalOffset) {
  31303. root = that._createRoot().append(that._owner);
  31304. text = that._renderer.createText(getSampleText(that._translator, that._options.text), 0, 0, {
  31305. align: 'center',
  31306. font: that._options.text.font
  31307. }).append(root);
  31308. bbox = text.getBBox();
  31309. root.remove();
  31310. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  31311. that._textWidth = bbox.width;
  31312. that._textHeight = bbox.height;
  31313. that._textFullWidth = that._textWidth + 2 * that._options.horizontalOffset;
  31314. that._textFullHeight = that._textHeight + 2 * that._options.verticalOffset
  31315. }
  31316. },
  31317. _render: function() {
  31318. var that = this;
  31319. that._measureText();
  31320. that._cloud = that._cloud || that._renderer.createArea().append(that._rootElement);
  31321. that._text = that._text || that._renderer.createText().append(that._rootElement);
  31322. that._text.applySettings({
  31323. align: 'center',
  31324. font: that._options.text.font
  31325. })
  31326. },
  31327. _clear: function() {
  31328. delete this._cloud;
  31329. delete this._text
  31330. },
  31331. getTooltipParameters: function() {
  31332. var position = this._getTextCloudOptions();
  31333. return {
  31334. x: position.x,
  31335. y: position.y,
  31336. value: this._currentValue,
  31337. color: this._options.color
  31338. }
  31339. }
  31340. })
  31341. })(DevExpress);
  31342. /*! Module viz-gauges, file baseRangeBar.js */
  31343. (function(DX, $, undefined) {
  31344. var $extend = $.extend;
  31345. var formatValue = DX.viz.gauges.__internals.formatValue,
  31346. getSampleText = DX.viz.gauges.__internals.getSampleText;
  31347. DX.viz.gauges.__internals.BaseRangeBar = DX.viz.gauges.__internals.BaseIndicator.inherit({
  31348. _measureText: function() {
  31349. var that = this,
  31350. root,
  31351. text,
  31352. bbox;
  31353. that._hasText = that._isTextVisible();
  31354. if (that._hasText && !that._textVerticalOffset) {
  31355. root = that._createRoot().append(that._owner);
  31356. text = that._renderer.createText(getSampleText(that._translator, that._options.text), 0, 0, {
  31357. 'class': 'dxg-text',
  31358. align: 'center',
  31359. font: that._options.text.font
  31360. }).append(root);
  31361. bbox = text.getBBox();
  31362. root.remove();
  31363. that._textVerticalOffset = -bbox.y - bbox.height / 2;
  31364. that._textWidth = bbox.width;
  31365. that._textHeight = bbox.height
  31366. }
  31367. },
  31368. _move: function() {
  31369. var that = this;
  31370. that._updateBarItemsPositions();
  31371. if (that._hasText) {
  31372. that._text.applySettings({text: formatValue(that._actualValue, that._options.text)});
  31373. that._updateTextPosition();
  31374. that._updateLinePosition()
  31375. }
  31376. },
  31377. _updateBarItems: function() {
  31378. var that = this,
  31379. options = that._options,
  31380. backgroundColor,
  31381. spaceColor;
  31382. that._setBarSides();
  31383. that._startPosition = that._translator.translate(that._translator.getDomainStart());
  31384. that._endPosition = that._translator.translate(that._translator.getDomainEnd());
  31385. that._basePosition = that._translator.translate(options.baseValue);
  31386. that._space = that._getSpace();
  31387. backgroundColor = options.backgroundColor || 'none';
  31388. if (backgroundColor !== 'none' && that._space > 0)
  31389. spaceColor = options.containerBackgroundColor || 'none';
  31390. else {
  31391. that._space = 0;
  31392. spaceColor = 'none'
  31393. }
  31394. that._backItem1.applySettings({fill: backgroundColor});
  31395. that._backItem2.applySettings({fill: backgroundColor});
  31396. that._spaceItem1.applySettings({fill: spaceColor});
  31397. that._spaceItem2.applySettings({fill: spaceColor})
  31398. },
  31399. _getSpace: function() {
  31400. return 0
  31401. },
  31402. _updateTextItems: function() {
  31403. var that = this;
  31404. if (that._hasText) {
  31405. that._line = that._line || that._renderer.createPath([], {'class': 'dxg-main-bar'}).append(that._rootElement);
  31406. that._text = that._text || that._renderer.createText('', 0, 0, {'class': 'dxg-text'}).append(that._rootElement);
  31407. that._text.applySettings({
  31408. align: that._getTextAlign(),
  31409. font: that._getFontOptions()
  31410. });
  31411. that._setTextItemsSides()
  31412. }
  31413. else {
  31414. if (that._line) {
  31415. that._line.remove();
  31416. delete that._line
  31417. }
  31418. if (that._text) {
  31419. that._text.remove();
  31420. delete that._text
  31421. }
  31422. }
  31423. },
  31424. _isTextVisible: function() {
  31425. return false
  31426. },
  31427. _getTextAlign: function() {
  31428. return 'center'
  31429. },
  31430. _getFontOptions: function() {
  31431. var options = this._options,
  31432. font = options.text.font;
  31433. if (!font || !font.color)
  31434. font = $extend({}, font, {color: options.color});
  31435. return font
  31436. },
  31437. _updateBarItemsPositions: function() {
  31438. var that = this,
  31439. positions = that._getPositions();
  31440. that._backItem1.applySettings(that._buildItemSettings(positions.start, positions.back1));
  31441. that._backItem2.applySettings(that._buildItemSettings(positions.back2, positions.end));
  31442. that._spaceItem1.applySettings(that._buildItemSettings(positions.back1, positions.main1));
  31443. that._spaceItem2.applySettings(that._buildItemSettings(positions.main2, positions.back2));
  31444. that._mainItem.applySettings(that._buildItemSettings(positions.main1, positions.main2));
  31445. that._trackerElement && that._trackerElement.applySettings(that._buildItemSettings(positions.main1, positions.main2))
  31446. },
  31447. _render: function() {
  31448. var that = this;
  31449. that._measureText();
  31450. if (!that._backItem1) {
  31451. that._backItem1 = that._createBarItem();
  31452. that._backItem1.applySettings({'class': 'dxg-back-bar'})
  31453. }
  31454. if (!that._backItem2) {
  31455. that._backItem2 = that._createBarItem();
  31456. that._backItem2.applySettings({'class': 'dxg-back-bar'})
  31457. }
  31458. if (!that._spaceItem1) {
  31459. that._spaceItem1 = that._createBarItem();
  31460. that._spaceItem1.applySettings({'class': 'dxg-space-bar'})
  31461. }
  31462. if (!that._spaceItem2) {
  31463. that._spaceItem2 = that._createBarItem();
  31464. that._spaceItem2.applySettings({'class': 'dxg-space-bar'})
  31465. }
  31466. if (!that._mainItem) {
  31467. that._mainItem = that._createBarItem();
  31468. that._mainItem.applySettings({'class': 'dxg-main-bar'})
  31469. }
  31470. that._updateBarItems();
  31471. that._updateTextItems()
  31472. },
  31473. _clear: function() {
  31474. var that = this;
  31475. delete that._backItem1;
  31476. delete that._backItem2;
  31477. delete that._spaceItem1;
  31478. delete that._spaceItem2;
  31479. delete that._mainItem;
  31480. delete that._hasText;
  31481. delete that._line;
  31482. delete that._text
  31483. },
  31484. getTooltipParameters: function() {
  31485. var position = this._getTooltipPosition();
  31486. return {
  31487. x: position.x,
  31488. y: position.y,
  31489. value: this._currentValue,
  31490. color: this._options.color,
  31491. offset: 0
  31492. }
  31493. }
  31494. })
  31495. })(DevExpress, jQuery);
  31496. /*! Module viz-gauges, file circularNeedle.js */
  31497. (function(DX, undefined) {
  31498. var circularNeedles = DX.viz.gauges.__internals.circularNeedles;
  31499. var _Number = Number;
  31500. circularNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
  31501. _move: function() {
  31502. var that = this,
  31503. options = that._options,
  31504. angle = DX.utils.convertAngleToRendererSpace(that._actualPosition);
  31505. that._rootElement.rotate(angle, options.x, options.y);
  31506. that._trackerElement && that._trackerElement.rotate(angle, options.x, options.y)
  31507. },
  31508. _isEnabled: function() {
  31509. return this._options.width > 0
  31510. },
  31511. _isVisible: function(layout) {
  31512. return layout.radius - _Number(this._options.indentFromCenter) > 0
  31513. },
  31514. _getTrackerSettings: function() {
  31515. var options = this._options,
  31516. x = options.x,
  31517. y = options.y - (options.radius + _Number(options.indentFromCenter)) / 2,
  31518. width = options.width / 2,
  31519. length = (options.radius - _Number(options.indentFromCenter)) / 2;
  31520. width > 10 || (width = 10);
  31521. length > 10 || (length = 10);
  31522. return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
  31523. },
  31524. _renderSpindle: function() {
  31525. var that = this,
  31526. options = that._options,
  31527. gapSize;
  31528. if (options.spindleSize > 0) {
  31529. gapSize = _Number(options.spindleGapSize) || 0;
  31530. if (gapSize > 0)
  31531. gapSize = gapSize <= options.spindleSize ? gapSize : _Number(options.spindleSize);
  31532. that._spindleOuter = that._spindleOuter || that._renderer.createCircle().append(that._rootElement);
  31533. that._spindleInner = that._spindleInner || that._renderer.createCircle().append(that._rootElement);
  31534. that._spindleOuter.applySettings({
  31535. 'class': 'dxg-spindle-border',
  31536. cx: options.x,
  31537. cy: options.y,
  31538. r: options.spindleSize / 2
  31539. });
  31540. that._spindleInner.applySettings({
  31541. 'class': 'dxg-spindle-hole',
  31542. cx: options.x,
  31543. cy: options.y,
  31544. r: gapSize / 2,
  31545. fill: options.containerBackgroundColor
  31546. })
  31547. }
  31548. },
  31549. _render: function() {
  31550. var that = this;
  31551. that._renderPointer();
  31552. that._renderSpindle()
  31553. },
  31554. _clearSpindle: function() {
  31555. delete this._spindleOuter;
  31556. delete this._spindleInner
  31557. },
  31558. _clearPointer: function() {
  31559. delete this._element
  31560. },
  31561. _clear: function() {
  31562. this._clearPointer();
  31563. this._clearSpindle()
  31564. },
  31565. measure: function(layout) {
  31566. var result = {max: layout.radius};
  31567. if (this._options.indentFromCenter < 0)
  31568. result.inverseHorizontalOffset = result.inverseVerticalOffset = -_Number(this._options.indentFromCenter);
  31569. return result
  31570. },
  31571. getTooltipParameters: function() {
  31572. var options = this._options,
  31573. cossin = DX.utils.getCosAndSin(this._actualPosition),
  31574. r = (options.radius + _Number(options.indentFromCenter)) / 2;
  31575. return {
  31576. x: options.x + cossin.cos * r,
  31577. y: options.y - cossin.sin * r,
  31578. value: this._currentValue,
  31579. color: options.color,
  31580. offset: options.width / 2
  31581. }
  31582. }
  31583. });
  31584. circularNeedles.RectangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
  31585. var that = this,
  31586. options = that._options,
  31587. y2 = options.y - options.radius,
  31588. y1 = options.y - _Number(options.indentFromCenter),
  31589. x1 = options.x - options.width / 2,
  31590. x2 = x1 + _Number(options.width);
  31591. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  31592. that._element.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
  31593. }});
  31594. circularNeedles.TriangleNeedle = circularNeedles.SimpleIndicator.inherit({_renderPointer: function() {
  31595. var that = this,
  31596. options = that._options,
  31597. y2 = options.y - options.radius,
  31598. y1 = options.y - _Number(options.indentFromCenter),
  31599. x1 = options.x - options.width / 2,
  31600. x2 = options.x + options.width / 2;
  31601. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  31602. that._element.applySettings({points: [x1, y1, options.x, y2, x2, y1]})
  31603. }});
  31604. circularNeedles.TwoColorRectangleNeedle = circularNeedles.SimpleIndicator.inherit({
  31605. _renderPointer: function() {
  31606. var that = this,
  31607. options = that._options,
  31608. x1 = options.x - options.width / 2,
  31609. x2 = options.x + options.width / 2,
  31610. y4 = options.y - options.radius,
  31611. y1 = options.y - _Number(options.indentFromCenter),
  31612. fraction = _Number(options.secondFraction) || 0,
  31613. y2,
  31614. y3;
  31615. if (fraction >= 1)
  31616. y2 = y3 = y1;
  31617. else if (fraction <= 0)
  31618. y2 = y3 = y2;
  31619. else {
  31620. y3 = y4 + (y1 - y4) * fraction;
  31621. y2 = y3 + options.space
  31622. }
  31623. that._firstElement = that._firstElement || that._renderer.createArea().append(that._rootElement);
  31624. that._spaceElement = that._spaceElement || that._renderer.createArea().append(that._rootElement);
  31625. that._secondElement = that._secondElement || that._renderer.createArea().append(that._rootElement);
  31626. that._firstElement.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]});
  31627. that._spaceElement.applySettings({
  31628. points: [x1, y2, x1, y3, x2, y3, x2, y2],
  31629. 'class': 'dxg-hole',
  31630. fill: options.containerBackgroundColor
  31631. });
  31632. that._secondElement.applySettings({
  31633. points: [x1, y3, x1, y4, x2, y4, x2, y3],
  31634. 'class': 'dxg-part',
  31635. fill: options.secondColor
  31636. })
  31637. },
  31638. _clearPointer: function() {
  31639. delete this._firstElement;
  31640. delete this._secondElement;
  31641. delete this._spaceElement
  31642. }
  31643. })
  31644. })(DevExpress);
  31645. /*! Module viz-gauges, file linearNeedle.js */
  31646. (function(DX, undefined) {
  31647. var linearNeedles = DX.viz.gauges.__internals.linearNeedles;
  31648. var _Number = Number;
  31649. linearNeedles.SimpleIndicator = DX.viz.gauges.__internals.BaseIndicator.inherit({
  31650. _move: function() {
  31651. var that = this,
  31652. delta = that._actualPosition - that._zeroPosition;
  31653. that._rootElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0);
  31654. that._trackerElement && that._trackerElement.move(that.vertical ? 0 : delta, that.vertical ? delta : 0)
  31655. },
  31656. _isEnabled: function() {
  31657. this.vertical = this._options.vertical;
  31658. return this._options.length > 0 && this._options.width > 0
  31659. },
  31660. _isVisible: function(layout) {
  31661. return true
  31662. },
  31663. _getTrackerSettings: function() {
  31664. var options = this._options,
  31665. x1,
  31666. x2,
  31667. y1,
  31668. y2,
  31669. width = options.width / 2,
  31670. length = options.length / 2,
  31671. p = this._zeroPosition;
  31672. width > 10 || (width = 10);
  31673. length > 10 || (length = 10);
  31674. if (this.vertical) {
  31675. x1 = options.x - length;
  31676. x2 = options.x + length;
  31677. y1 = p + width;
  31678. y2 = p - width
  31679. }
  31680. else {
  31681. x1 = p - width;
  31682. x2 = p + width;
  31683. y1 = options.y + length;
  31684. y2 = options.y - length
  31685. }
  31686. return {points: [x1, y1, x1, y2, x2, y2, x2, y1]}
  31687. },
  31688. _render: function() {
  31689. var that = this;
  31690. that._zeroPosition = that._translator.getCodomainStart()
  31691. },
  31692. _clear: function() {
  31693. delete this._element
  31694. },
  31695. measure: function(layout) {
  31696. var p = this.vertical ? layout.x : layout.y;
  31697. return {
  31698. min: p - this._options.length / 2,
  31699. max: p + this._options.length / 2
  31700. }
  31701. },
  31702. getTooltipParameters: function() {
  31703. var that = this,
  31704. options = that._options,
  31705. p = that._actualPosition,
  31706. parameters = {
  31707. x: p,
  31708. y: p,
  31709. value: that._currentValue,
  31710. color: options.color,
  31711. offset: options.width / 2
  31712. };
  31713. that.vertical ? parameters.x = options.x : parameters.y = options.y;
  31714. return parameters
  31715. }
  31716. });
  31717. linearNeedles.RectangleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  31718. var that = this,
  31719. options = that._options,
  31720. p,
  31721. x1,
  31722. x2,
  31723. y1,
  31724. y2;
  31725. that.callBase();
  31726. p = that._zeroPosition;
  31727. if (that.vertical) {
  31728. x1 = options.x - options.length / 2;
  31729. x2 = options.x + options.length / 2;
  31730. y1 = p + options.width / 2;
  31731. y2 = p - options.width / 2
  31732. }
  31733. else {
  31734. x1 = p - options.width / 2;
  31735. x2 = p + options.width / 2;
  31736. y1 = options.y + options.length / 2;
  31737. y2 = options.y - options.length / 2
  31738. }
  31739. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  31740. that._element.applySettings({points: [x1, y1, x1, y2, x2, y2, x2, y1]})
  31741. }});
  31742. linearNeedles.RhombusNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  31743. var that = this,
  31744. options = that._options,
  31745. x,
  31746. y,
  31747. dx,
  31748. dy;
  31749. that.callBase();
  31750. if (that.vertical) {
  31751. x = options.x;
  31752. y = that._zeroPosition;
  31753. dx = options.length / 2 || 0;
  31754. dy = options.width / 2 || 0
  31755. }
  31756. else {
  31757. x = that._zeroPosition;
  31758. y = options.y;
  31759. dx = options.width / 2 || 0;
  31760. dy = options.length / 2 || 0
  31761. }
  31762. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  31763. that._element.applySettings({points: [x - dx, y, x, y - dy, x + dx, y, x, y + dy]})
  31764. }});
  31765. linearNeedles.CircleNeedle = linearNeedles.SimpleIndicator.inherit({_render: function() {
  31766. var that = this,
  31767. options = that._options,
  31768. x,
  31769. y,
  31770. r;
  31771. that.callBase();
  31772. if (that.vertical) {
  31773. x = options.x;
  31774. y = that._zeroPosition
  31775. }
  31776. else {
  31777. x = that._zeroPosition;
  31778. y = options.y
  31779. }
  31780. r = options.length / 2 || 0;
  31781. that._element = that._element || that._renderer.createCircle().append(that._rootElement);
  31782. that._element.applySettings({
  31783. cx: x,
  31784. cy: y,
  31785. r: r
  31786. })
  31787. }})
  31788. })(DevExpress);
  31789. /*! Module viz-gauges, file circularMarker.js */
  31790. (function(DX, undefined) {
  31791. var circularMarkers = DX.viz.gauges.__internals.circularMarkers;
  31792. var _Number = Number;
  31793. circularMarkers.TriangleMarker = DX.viz.gauges.__internals.circularNeedles.SimpleIndicator.inherit({
  31794. _isEnabled: function() {
  31795. return this._options.length > 0 && this._options.width > 0
  31796. },
  31797. _isVisible: function(layout) {
  31798. return layout.radius > 0
  31799. },
  31800. _render: function() {
  31801. var that = this,
  31802. options = that._options,
  31803. x = options.x,
  31804. y1 = options.y - options.radius,
  31805. dx = options.width / 2 || 0,
  31806. y2 = y1 - _Number(options.length),
  31807. settings;
  31808. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  31809. settings = {
  31810. points: [x, y1, x - dx, y2, x + dx, y2],
  31811. stroke: 'none',
  31812. strokeWidth: 0
  31813. };
  31814. if (options.space > 0) {
  31815. settings.strokeWidth = Math.min(options.space, options.width / 4) || 0;
  31816. settings.stroke = settings.strokeWidth > 0 ? options.containerBackgroundColor || 'none' : 'none'
  31817. }
  31818. that._element.applySettings(settings)
  31819. },
  31820. _clear: function() {
  31821. delete this._element
  31822. },
  31823. _getTrackerSettings: function() {
  31824. var options = this._options,
  31825. x = options.x,
  31826. y = options.y - options.radius - options.length / 2,
  31827. width = options.width / 2,
  31828. length = options.length / 2;
  31829. width > 10 || (width = 10);
  31830. length > 10 || (length = 10);
  31831. return {points: [x - width, y - length, x - width, y + length, x + width, y + length, x + width, y - length]}
  31832. },
  31833. measure: function(layout) {
  31834. return {
  31835. min: layout.radius,
  31836. max: layout.radius + _Number(this._options.length)
  31837. }
  31838. },
  31839. getTooltipParameters: function() {
  31840. var options = this._options,
  31841. cossin = DX.utils.getCosAndSin(this._actualPosition),
  31842. r = options.radius + options.length / 2,
  31843. parameters = this.callBase();
  31844. parameters.x = options.x + cossin.cos * r;
  31845. parameters.y = options.y - cossin.sin * r;
  31846. parameters.offset = options.length / 2;
  31847. return parameters
  31848. }
  31849. });
  31850. circularMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
  31851. _isEnabled: function() {
  31852. return true
  31853. },
  31854. _isVisible: function(layout) {
  31855. return layout.radius > 0
  31856. },
  31857. _getTextCloudOptions: function() {
  31858. var that = this,
  31859. cossin = DX.utils.getCosAndSin(that._actualPosition),
  31860. nangle = DX.utils.normalizeAngle(that._actualPosition);
  31861. return {
  31862. x: that._options.x + cossin.cos * that._options.radius,
  31863. y: that._options.y - cossin.sin * that._options.radius,
  31864. type: nangle > 270 ? 'left-top' : nangle > 180 ? 'top-right' : nangle > 90 ? 'right-bottom' : 'bottom-left'
  31865. }
  31866. },
  31867. measure: function(layout) {
  31868. var that = this;
  31869. that._measureText();
  31870. return {
  31871. min: layout.radius,
  31872. max: layout.radius,
  31873. horizontalOffset: that._textFullWidth + (_Number(that._options.arrowLength) || 0),
  31874. verticalOffset: that._textFullHeight + (_Number(that._options.arrowLength) || 0)
  31875. }
  31876. }
  31877. })
  31878. })(DevExpress);
  31879. /*! Module viz-gauges, file linearMarker.js */
  31880. (function(DX, undefined) {
  31881. var linearMarkers = DX.viz.gauges.__internals.linearMarkers;
  31882. var _Number = Number,
  31883. _String = String;
  31884. linearMarkers.TriangleMarker = DX.viz.gauges.__internals.linearNeedles.SimpleIndicator.inherit({
  31885. _isEnabled: function() {
  31886. var that = this;
  31887. that.vertical = that._options.vertical;
  31888. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  31889. return that._options.length > 0 && that._options.width > 0
  31890. },
  31891. _isVisible: function(layout) {
  31892. return true
  31893. },
  31894. _render: function() {
  31895. var that = this,
  31896. options = that._options,
  31897. x1,
  31898. x2,
  31899. y1,
  31900. y2,
  31901. settings = {
  31902. stroke: 'none',
  31903. strokeWidth: 0
  31904. };
  31905. that.callBase();
  31906. if (that.vertical) {
  31907. x1 = options.x;
  31908. y1 = that._zeroPosition;
  31909. x2 = x1 + _Number(that._inverted ? options.length : -options.length);
  31910. settings.points = [x1, y1, x2, y1 - options.width / 2, x2, y1 + options.width / 2]
  31911. }
  31912. else {
  31913. y1 = options.y;
  31914. x1 = that._zeroPosition;
  31915. y2 = y1 + _Number(that._inverted ? options.length : -options.length);
  31916. settings.points = [x1, y1, x1 - options.width / 2, y2, x1 + options.width / 2, y2]
  31917. }
  31918. if (options.space > 0) {
  31919. settings.strokeWidth = Math.min(options.space, options.width / 4) || 0;
  31920. settings.stroke = settings.strokeWidth > 0 ? options.containerBackgroundColor || 'none' : 'none'
  31921. }
  31922. that._element = that._element || that._renderer.createArea().append(that._rootElement);
  31923. that._element.applySettings(settings)
  31924. },
  31925. _getTrackerSettings: function() {
  31926. var that = this,
  31927. options = that._options,
  31928. width = options.width / 2,
  31929. length = _Number(options.length),
  31930. x1,
  31931. x2,
  31932. y1,
  31933. y2,
  31934. result;
  31935. width > 10 || (width = 10);
  31936. length > 20 || (length = 20);
  31937. if (that.vertical) {
  31938. x1 = x2 = options.x;
  31939. x2 = x1 + (that._inverted ? length : -length);
  31940. y1 = that._zeroPosition + width;
  31941. y2 = that._zeroPosition - width;
  31942. result = [x1, y1, x2, y1, x2, y2, x1, y2]
  31943. }
  31944. else {
  31945. y1 = options.y;
  31946. y2 = y1 + (that._inverted ? length : -length);
  31947. x1 = that._zeroPosition - width;
  31948. x2 = that._zeroPosition + width;
  31949. result = [x1, y1, x1, y2, x2, y2, x2, y1]
  31950. }
  31951. return {points: result}
  31952. },
  31953. measure: function(layout) {
  31954. var that = this,
  31955. length = _Number(that._options.length),
  31956. minbound,
  31957. maxbound;
  31958. if (that.vertical) {
  31959. minbound = maxbound = layout.x;
  31960. if (that._inverted)
  31961. maxbound = minbound + length;
  31962. else
  31963. minbound = maxbound - length
  31964. }
  31965. else {
  31966. minbound = maxbound = layout.y;
  31967. if (that._inverted)
  31968. maxbound = minbound + length;
  31969. else
  31970. minbound = maxbound - length
  31971. }
  31972. return {
  31973. min: minbound,
  31974. max: maxbound,
  31975. indent: that._options.width / 2
  31976. }
  31977. },
  31978. getTooltipParameters: function() {
  31979. var that = this,
  31980. options = that._options,
  31981. s = (that._inverted ? options.length : -options.length) / 2,
  31982. parameters = that.callBase();
  31983. that.vertical ? parameters.x += s : parameters.y += s;
  31984. parameters.offset = options.length / 2;
  31985. return parameters
  31986. }
  31987. });
  31988. linearMarkers.TextCloudMarker = DX.viz.gauges.__internals.BaseTextCloudMarker.inherit({
  31989. _isEnabled: function() {
  31990. var that = this;
  31991. that.vertical = that._options.vertical;
  31992. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  31993. return true
  31994. },
  31995. _isVisible: function(layout) {
  31996. return true
  31997. },
  31998. _getTextCloudOptions: function() {
  31999. var that = this,
  32000. x = that._actualPosition,
  32001. y = that._actualPosition,
  32002. type;
  32003. if (that.vertical) {
  32004. x = that._options.x;
  32005. type = that._inverted ? 'top-left' : 'top-right'
  32006. }
  32007. else {
  32008. y = that._options.y;
  32009. type = that._inverted ? 'right-top' : 'right-bottom'
  32010. }
  32011. return {
  32012. x: x,
  32013. y: y,
  32014. type: type
  32015. }
  32016. },
  32017. measure: function(layout) {
  32018. var that = this,
  32019. minbound,
  32020. maxbound,
  32021. arrowLength = _Number(that._options.arrowLength) || 0,
  32022. indent;
  32023. that._measureText();
  32024. if (that.vertical) {
  32025. indent = that._textFullHeight;
  32026. if (that._inverted) {
  32027. minbound = layout.x;
  32028. maxbound = layout.x + arrowLength + that._textFullWidth
  32029. }
  32030. else {
  32031. minbound = layout.x - arrowLength - that._textFullWidth;
  32032. maxbound = layout.x
  32033. }
  32034. }
  32035. else {
  32036. indent = that._textFullWidth;
  32037. if (that._inverted) {
  32038. minbound = layout.y;
  32039. maxbound = layout.y + arrowLength + that._textFullHeight
  32040. }
  32041. else {
  32042. minbound = layout.y - arrowLength - that._textFullHeight;
  32043. maxbound = layout.y
  32044. }
  32045. }
  32046. return {
  32047. min: minbound,
  32048. max: maxbound,
  32049. indent: indent
  32050. }
  32051. }
  32052. })
  32053. })(DevExpress);
  32054. /*! Module viz-gauges, file circularRangeBar.js */
  32055. (function(DX, undefined) {
  32056. var _Number = Number,
  32057. getCosAndSin = DX.utils.getCosAndSin,
  32058. convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  32059. max = Math.max,
  32060. min = Math.min;
  32061. DX.viz.gauges.__internals.CircularRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
  32062. _isEnabled: function() {
  32063. return this._options.size > 0
  32064. },
  32065. _isVisible: function(layout) {
  32066. return layout.radius - _Number(this._options.size) > 0
  32067. },
  32068. _createBarItem: function() {
  32069. return this._renderer.createArc().append(this._rootElement)
  32070. },
  32071. _createTracker: function() {
  32072. return this._renderer.createArc()
  32073. },
  32074. _setBarSides: function() {
  32075. var that = this;
  32076. that._maxSide = that._options.radius;
  32077. that._minSide = that._maxSide - _Number(that._options.size)
  32078. },
  32079. _getSpace: function() {
  32080. var options = this._options;
  32081. return options.space > 0 ? options.space * 180 / options.radius / Math.PI : 0
  32082. },
  32083. _isTextVisible: function() {
  32084. var options = this._options.text || {};
  32085. return options.indent > 0
  32086. },
  32087. _setTextItemsSides: function() {
  32088. var that = this,
  32089. options = that._options;
  32090. that._lineFrom = options.y - options.radius;
  32091. that._lineTo = that._lineFrom - _Number(options.text.indent);
  32092. that._textRadius = options.radius + _Number(options.text.indent)
  32093. },
  32094. _getPositions: function() {
  32095. var that = this,
  32096. basePosition = that._basePosition,
  32097. actualPosition = that._actualPosition,
  32098. mainPosition1,
  32099. mainPosition2;
  32100. if (basePosition >= actualPosition) {
  32101. mainPosition1 = basePosition;
  32102. mainPosition2 = actualPosition
  32103. }
  32104. else {
  32105. mainPosition1 = actualPosition;
  32106. mainPosition2 = basePosition
  32107. }
  32108. return {
  32109. start: that._startPosition,
  32110. end: that._endPosition,
  32111. main1: mainPosition1,
  32112. main2: mainPosition2,
  32113. back1: min(mainPosition1 + that._space, that._startPosition),
  32114. back2: max(mainPosition2 - that._space, that._endPosition)
  32115. }
  32116. },
  32117. _buildItemSettings: function(from, to) {
  32118. var that = this;
  32119. return {
  32120. x: that._options.x,
  32121. y: that._options.y,
  32122. innerRadius: that._minSide,
  32123. outerRadius: that._maxSide,
  32124. startAngle: to,
  32125. endAngle: from
  32126. }
  32127. },
  32128. _updateTextPosition: function() {
  32129. var that = this,
  32130. cossin = getCosAndSin(that._actualPosition),
  32131. x = that._options.x + that._textRadius * cossin.cos,
  32132. y = that._options.y - that._textRadius * cossin.sin;
  32133. x += cossin.cos * that._textWidth * 0.6;
  32134. y -= cossin.sin * that._textHeight * 0.6;
  32135. that._text.applySettings({
  32136. x: x,
  32137. y: y + that._textVerticalOffset
  32138. })
  32139. },
  32140. _updateLinePosition: function() {
  32141. var that = this,
  32142. x = that._options.x,
  32143. x1,
  32144. x2;
  32145. if (that._basePosition > that._actualPosition) {
  32146. x1 = x - 2;
  32147. x2 = x
  32148. }
  32149. else if (that._basePosition < that._actualPosition) {
  32150. x1 = x;
  32151. x2 = x + 2
  32152. }
  32153. else {
  32154. x1 = x - 1;
  32155. x2 = x + 1
  32156. }
  32157. that._line.applySettings({points: [x1, that._lineFrom, x1, that._lineTo, x2, that._lineTo, x2, that._lineFrom]});
  32158. that._line.rotate(convertAngleToRendererSpace(that._actualPosition), x, that._options.y)
  32159. },
  32160. _getTooltipPosition: function() {
  32161. var that = this,
  32162. cossin = getCosAndSin((that._basePosition + that._actualPosition) / 2),
  32163. r = (that._minSide + that._maxSide) / 2;
  32164. return {
  32165. x: that._options.x + cossin.cos * r,
  32166. y: that._options.y - cossin.sin * r
  32167. }
  32168. },
  32169. measure: function(layout) {
  32170. var that = this,
  32171. result = {
  32172. min: layout.radius - _Number(that._options.size),
  32173. max: layout.radius
  32174. };
  32175. that._measureText();
  32176. if (that._hasText) {
  32177. result.max += _Number(that._options.text.indent);
  32178. result.horizontalOffset = that._textWidth;
  32179. result.verticalOffset = that._textHeight
  32180. }
  32181. return result
  32182. }
  32183. })
  32184. })(DevExpress);
  32185. /*! Module viz-gauges, file linearRangeBar.js */
  32186. (function(DX, undefined) {
  32187. var _Number = Number,
  32188. _String = String;
  32189. DX.viz.gauges.__internals.LinearRangeBar = DX.viz.gauges.__internals.BaseRangeBar.inherit({
  32190. _isEnabled: function() {
  32191. var that = this;
  32192. that.vertical = that._options.vertical;
  32193. that._inverted = that.vertical ? _String(that._options.horizontalOrientation).toLowerCase() === 'right' : _String(that._options.verticalOrientation).toLowerCase() === 'bottom';
  32194. return that._options.size > 0
  32195. },
  32196. _isVisible: function(layout) {
  32197. return true
  32198. },
  32199. _createBarItem: function() {
  32200. return this._renderer.createArea().append(this._rootElement)
  32201. },
  32202. _createTracker: function() {
  32203. return this._renderer.createArea()
  32204. },
  32205. _setBarSides: function() {
  32206. var that = this,
  32207. options = that._options,
  32208. size = _Number(options.size),
  32209. minSide,
  32210. maxSide;
  32211. if (that.vertical)
  32212. if (that._inverted) {
  32213. minSide = options.x;
  32214. maxSide = options.x + size
  32215. }
  32216. else {
  32217. minSide = options.x - size;
  32218. maxSide = options.x
  32219. }
  32220. else if (that._inverted) {
  32221. minSide = options.y;
  32222. maxSide = options.y + size
  32223. }
  32224. else {
  32225. minSide = options.y - size;
  32226. maxSide = options.y
  32227. }
  32228. that._minSide = minSide;
  32229. that._maxSide = maxSide;
  32230. that._minBound = minSide;
  32231. that._maxBound = maxSide
  32232. },
  32233. _getSpace: function() {
  32234. var options = this._options;
  32235. return options.space > 0 ? _Number(options.space) : 0
  32236. },
  32237. _isTextVisible: function() {
  32238. var textOptions = this._options.text || {};
  32239. return textOptions.indent > 0 || textOptions.indent < 0
  32240. },
  32241. _getTextAlign: function() {
  32242. return this.vertical ? this._options.text.indent > 0 ? 'left' : 'right' : 'center'
  32243. },
  32244. _setTextItemsSides: function() {
  32245. var that = this,
  32246. indent = _Number(that._options.text.indent);
  32247. if (indent > 0) {
  32248. that._lineStart = that._maxSide;
  32249. that._lineEnd = that._maxSide + indent;
  32250. that._textPosition = that._lineEnd + (that.vertical ? 2 : that._textHeight / 2);
  32251. that._maxBound = that._textPosition + (that.vertical ? that._textWidth : that._textHeight / 2)
  32252. }
  32253. else if (indent < 0) {
  32254. that._lineStart = that._minSide;
  32255. that._lineEnd = that._minSide + indent;
  32256. that._textPosition = that._lineEnd - (that.vertical ? 2 : that._textHeight / 2);
  32257. that._minBound = that._textPosition - (that.vertical ? that._textWidth : that._textHeight / 2)
  32258. }
  32259. },
  32260. _getPositions: function() {
  32261. var that = this,
  32262. options = that._options,
  32263. startPosition = that._startPosition,
  32264. endPosition = that._endPosition,
  32265. space = that._space,
  32266. basePosition = that._basePosition,
  32267. actualPosition = that._actualPosition,
  32268. mainPosition1,
  32269. mainPosition2,
  32270. backPosition1,
  32271. backPosition2;
  32272. if (startPosition < endPosition) {
  32273. if (basePosition < actualPosition) {
  32274. mainPosition1 = basePosition;
  32275. mainPosition2 = actualPosition
  32276. }
  32277. else {
  32278. mainPosition1 = actualPosition;
  32279. mainPosition2 = basePosition
  32280. }
  32281. backPosition1 = mainPosition1 - space;
  32282. backPosition2 = mainPosition2 + space
  32283. }
  32284. else {
  32285. if (basePosition > actualPosition) {
  32286. mainPosition1 = basePosition;
  32287. mainPosition2 = actualPosition
  32288. }
  32289. else {
  32290. mainPosition1 = actualPosition;
  32291. mainPosition2 = basePosition
  32292. }
  32293. backPosition1 = mainPosition1 + space;
  32294. backPosition2 = mainPosition2 - space
  32295. }
  32296. return {
  32297. start: startPosition,
  32298. end: endPosition,
  32299. main1: mainPosition1,
  32300. main2: mainPosition2,
  32301. back1: backPosition1,
  32302. back2: backPosition2
  32303. }
  32304. },
  32305. _buildItemSettings: function(from, to) {
  32306. var that = this,
  32307. side1 = that._minSide,
  32308. side2 = that._maxSide;
  32309. var points = that.vertical ? [side1, from, side1, to, side2, to, side2, from] : [from, side1, from, side2, to, side2, to, side1];
  32310. return {points: points}
  32311. },
  32312. _updateTextPosition: function() {
  32313. var that = this;
  32314. that._text.applySettings(that.vertical ? {
  32315. x: that._textPosition,
  32316. y: that._actualPosition + that._textVerticalOffset
  32317. } : {
  32318. x: that._actualPosition,
  32319. y: that._textPosition + that._textVerticalOffset
  32320. })
  32321. },
  32322. _updateLinePosition: function() {
  32323. var that = this,
  32324. actualPosition = that._actualPosition,
  32325. side1,
  32326. side2,
  32327. points;
  32328. if (that.vertical) {
  32329. if (that._basePosition >= actualPosition) {
  32330. side1 = actualPosition;
  32331. side2 = actualPosition + 2
  32332. }
  32333. else {
  32334. side1 = actualPosition - 2;
  32335. side2 = actualPosition
  32336. }
  32337. points = [that._lineStart, side1, that._lineStart, side2, that._lineEnd, side2, that._lineEnd, side1]
  32338. }
  32339. else {
  32340. if (that._basePosition <= actualPosition) {
  32341. side1 = actualPosition - 2;
  32342. side2 = actualPosition
  32343. }
  32344. else {
  32345. side1 = actualPosition;
  32346. side2 = actualPosition + 2
  32347. }
  32348. points = [side1, that._lineStart, side1, that._lineEnd, side2, that._lineEnd, side2, that._lineStart]
  32349. }
  32350. that._line.applySettings({points: points})
  32351. },
  32352. _getTooltipPosition: function() {
  32353. var that = this,
  32354. crossCenter = (that._minSide + that._maxSide) / 2,
  32355. alongCenter = (that._basePosition + that._actualPosition) / 2,
  32356. position = {};
  32357. if (that.vertical)
  32358. position = {
  32359. x: crossCenter,
  32360. y: alongCenter
  32361. };
  32362. else
  32363. position = {
  32364. x: alongCenter,
  32365. y: crossCenter
  32366. };
  32367. return position
  32368. },
  32369. measure: function(layout) {
  32370. var that = this,
  32371. size = _Number(that._options.size),
  32372. textIndent = _Number(that._options.text.indent),
  32373. minbound,
  32374. maxbound,
  32375. indent;
  32376. that._measureText();
  32377. if (that.vertical) {
  32378. minbound = maxbound = layout.x;
  32379. if (that._inverted)
  32380. maxbound = maxbound + size;
  32381. else
  32382. minbound = minbound - size;
  32383. if (that._hasText) {
  32384. indent = that._textHeight / 2;
  32385. if (textIndent > 0)
  32386. maxbound += textIndent + that._textWidth;
  32387. if (textIndent < 0)
  32388. minbound += textIndent - that._textWidth
  32389. }
  32390. }
  32391. else {
  32392. minbound = maxbound = layout.y;
  32393. if (that._inverted)
  32394. maxbound = maxbound + size;
  32395. else
  32396. minbound = minbound - size;
  32397. if (that._hasText) {
  32398. indent = that._textWidth / 2;
  32399. if (textIndent > 0)
  32400. maxbound += textIndent + that._textHeight;
  32401. if (textIndent < 0)
  32402. minbound += textIndent - that._textHeight
  32403. }
  32404. }
  32405. return {
  32406. min: minbound,
  32407. max: maxbound,
  32408. indent: indent
  32409. }
  32410. }
  32411. })
  32412. })(DevExpress);
  32413. /*! Module viz-gauges, file rangeContainer.js */
  32414. (function(DX, $, undefined) {
  32415. var _Number = Number,
  32416. _String = String,
  32417. _max = Math.max,
  32418. _abs = Math.abs,
  32419. _isString = DX.utils.isString,
  32420. _isArray = DX.utils.isArray,
  32421. _isFinite = isFinite,
  32422. _each = $.each,
  32423. _map = $.map;
  32424. var _Palette = DX.viz.core.Palette;
  32425. DX.viz.gauges.__internals.BaseRangeContainer = DX.Class.inherit({
  32426. ctor: function(parameters) {
  32427. var that = this;
  32428. that._renderer = parameters.renderer;
  32429. that._container = parameters.container;
  32430. that._translator = parameters.translator;
  32431. that._root = that._renderer.createGroup({'class': 'dxg-range-container'})
  32432. },
  32433. dispose: function() {
  32434. var that = this;
  32435. that._renderer = that._container = that._translator = that._root = null
  32436. },
  32437. clean: function() {
  32438. this._root.detach().clear();
  32439. this._options = this.enabled = null;
  32440. return this
  32441. },
  32442. _getRanges: function() {
  32443. var that = this,
  32444. options = that._options,
  32445. translator = that._translator,
  32446. totalStart = translator.getDomain()[0],
  32447. totalEnd = translator.getDomain()[1],
  32448. totalDelta = totalEnd - totalStart,
  32449. isNotEmptySegment = totalDelta >= 0 ? isNotEmptySegmentAsc : isNotEmptySegmentDes,
  32450. subtractSegment = totalDelta >= 0 ? subtractSegmentAsc : subtractSegmentDes,
  32451. list = [],
  32452. ranges = [],
  32453. backgroundRanges = [{
  32454. start: totalStart,
  32455. end: totalEnd
  32456. }],
  32457. threshold = _abs(totalDelta) / 1E4,
  32458. palette = new _Palette(options.palette, {
  32459. type: 'indicatingSet',
  32460. theme: options.themeName
  32461. }),
  32462. backgroundColor = _isString(options.backgroundColor) ? options.backgroundColor : 'none',
  32463. width = options.width || {},
  32464. startWidth = _Number(width > 0 ? width : width.start),
  32465. endWidth = _Number(width > 0 ? width : width.end),
  32466. deltaWidth = endWidth - startWidth;
  32467. if (options.ranges !== undefined && !_isArray(options.ranges))
  32468. return null;
  32469. if (!(startWidth >= 0 && endWidth >= 0 && startWidth + endWidth > 0))
  32470. return null;
  32471. list = _map(_isArray(options.ranges) ? options.ranges : [], function(rangeOptions, i) {
  32472. rangeOptions = rangeOptions || {};
  32473. var start = translator.adjust(rangeOptions.startValue),
  32474. end = translator.adjust(rangeOptions.endValue);
  32475. return _isFinite(start) && _isFinite(end) && isNotEmptySegment(start, end, threshold) ? {
  32476. start: start,
  32477. end: end,
  32478. color: rangeOptions.color,
  32479. classIndex: i
  32480. } : null
  32481. });
  32482. _each(list, function(i, item) {
  32483. var paletteColor = palette.getNextColor();
  32484. item.color = _isString(item.color) && item.color || paletteColor || 'none';
  32485. item.className = 'dxg-range dxg-range-' + item.classIndex;
  32486. delete item.classIndex
  32487. });
  32488. _each(list, function(_, item) {
  32489. var i,
  32490. ii,
  32491. sub,
  32492. subs,
  32493. range,
  32494. newRanges = [],
  32495. newBackgroundRanges = [];
  32496. for (i = 0, ii = ranges.length; i < ii; ++i) {
  32497. range = ranges[i];
  32498. subs = subtractSegment(range.start, range.end, item.start, item.end);
  32499. (sub = subs[0]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub);
  32500. (sub = subs[1]) && (sub.color = range.color) && (sub.className = range.className) && newRanges.push(sub)
  32501. }
  32502. newRanges.push(item);
  32503. ranges = newRanges;
  32504. for (i = 0, ii = backgroundRanges.length; i < ii; ++i) {
  32505. range = backgroundRanges[i];
  32506. subs = subtractSegment(range.start, range.end, item.start, item.end);
  32507. (sub = subs[0]) && newBackgroundRanges.push(sub);
  32508. (sub = subs[1]) && newBackgroundRanges.push(sub)
  32509. }
  32510. backgroundRanges = newBackgroundRanges
  32511. });
  32512. _each(backgroundRanges, function(_, range) {
  32513. range.color = backgroundColor;
  32514. range.className = 'dxg-range dxg-background-range';
  32515. ranges.push(range)
  32516. });
  32517. _each(ranges, function(_, range) {
  32518. range.startWidth = (range.start - totalStart) / totalDelta * deltaWidth + startWidth;
  32519. range.endWidth = (range.end - totalStart) / totalDelta * deltaWidth + startWidth
  32520. });
  32521. return ranges
  32522. },
  32523. render: function(options) {
  32524. var that = this;
  32525. that._options = options;
  32526. that._processOptions();
  32527. that._ranges = that._getRanges();
  32528. if (that._ranges) {
  32529. that.enabled = true;
  32530. that._root.append(that._container)
  32531. }
  32532. return that
  32533. },
  32534. resize: function(layout) {
  32535. var that = this;
  32536. that._root.clear();
  32537. if (that._isVisible(layout))
  32538. _each(that._ranges, function(_, range) {
  32539. that._createRange(range, layout).applySettings({
  32540. fill: range.color,
  32541. 'class': range.className
  32542. }).append(that._root)
  32543. });
  32544. return that
  32545. },
  32546. _processOptions: null,
  32547. _isVisible: null,
  32548. _createRange: null
  32549. });
  32550. function subtractSegmentAsc(segmentStart, segmentEnd, otherStart, otherEnd) {
  32551. var result;
  32552. if (otherStart > segmentStart && otherEnd < segmentEnd)
  32553. result = [{
  32554. start: segmentStart,
  32555. end: otherStart
  32556. }, {
  32557. start: otherEnd,
  32558. end: segmentEnd
  32559. }];
  32560. else if (otherStart >= segmentEnd || otherEnd <= segmentStart)
  32561. result = [{
  32562. start: segmentStart,
  32563. end: segmentEnd
  32564. }];
  32565. else if (otherStart <= segmentStart && otherEnd >= segmentEnd)
  32566. result = [];
  32567. else if (otherStart > segmentStart)
  32568. result = [{
  32569. start: segmentStart,
  32570. end: otherStart
  32571. }];
  32572. else if (otherEnd < segmentEnd)
  32573. result = [{
  32574. start: otherEnd,
  32575. end: segmentEnd
  32576. }];
  32577. return result
  32578. }
  32579. function subtractSegmentDes(segmentStart, segmentEnd, otherStart, otherEnd) {
  32580. var result;
  32581. if (otherStart < segmentStart && otherEnd > segmentEnd)
  32582. result = [{
  32583. start: segmentStart,
  32584. end: otherStart
  32585. }, {
  32586. start: otherEnd,
  32587. end: segmentEnd
  32588. }];
  32589. else if (otherStart <= segmentEnd || otherEnd >= segmentStart)
  32590. result = [{
  32591. start: segmentStart,
  32592. end: segmentEnd
  32593. }];
  32594. else if (otherStart >= segmentStart && otherEnd <= segmentEnd)
  32595. result = [];
  32596. else if (otherStart < segmentStart)
  32597. result = [{
  32598. start: segmentStart,
  32599. end: otherStart
  32600. }];
  32601. else if (otherEnd > segmentEnd)
  32602. result = [{
  32603. start: otherEnd,
  32604. end: segmentEnd
  32605. }];
  32606. return result
  32607. }
  32608. function isNotEmptySegmentAsc(start, end, threshold) {
  32609. return end - start >= threshold
  32610. }
  32611. function isNotEmptySegmentDes(start, end, threshold) {
  32612. return start - end >= threshold
  32613. }
  32614. DX.viz.gauges.__internals.CircularRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
  32615. _processOptions: function() {
  32616. var that = this;
  32617. that._inner = that._outer = 0;
  32618. switch (_String(that._options.orientation).toLowerCase()) {
  32619. case'inside':
  32620. that._inner = 1;
  32621. break;
  32622. case'center':
  32623. that._inner = that._outer = 0.5;
  32624. break;
  32625. default:
  32626. that._outer = 1;
  32627. break
  32628. }
  32629. },
  32630. _isVisible: function(layout) {
  32631. var width = this._options.width;
  32632. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  32633. return layout.radius - this._inner * width > 0
  32634. },
  32635. _createRange: function(range, layout) {
  32636. var that = this,
  32637. width = (range.startWidth + range.endWidth) / 2;
  32638. 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))
  32639. },
  32640. measure: function(layout) {
  32641. var width = this._options.width;
  32642. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  32643. return {
  32644. min: layout.radius - this._inner * width,
  32645. max: layout.radius + this._outer * width
  32646. }
  32647. }
  32648. });
  32649. DX.viz.gauges.__internals.LinearRangeContainer = DX.viz.gauges.__internals.BaseRangeContainer.inherit({
  32650. _processOptions: function() {
  32651. var that = this;
  32652. that.vertical = that._options.vertical;
  32653. that._inner = that._outer = 0;
  32654. if (that.vertical)
  32655. switch (_String(that._options.horizontalOrientation).toLowerCase()) {
  32656. case'left':
  32657. that._inner = 1;
  32658. break;
  32659. case'center':
  32660. that._inner = that._outer = 0.5;
  32661. break;
  32662. default:
  32663. that._outer = 1;
  32664. break
  32665. }
  32666. else
  32667. switch (_String(that._options.verticalOrientation).toLowerCase()) {
  32668. case'top':
  32669. that._inner = 1;
  32670. break;
  32671. case'middle':
  32672. that._inner = that._outer = 0.5;
  32673. break;
  32674. default:
  32675. that._outer = 1;
  32676. break
  32677. }
  32678. },
  32679. _isVisible: function(layout) {
  32680. return true
  32681. },
  32682. _createRange: function(range, layout) {
  32683. var that = this,
  32684. inner = that._inner,
  32685. outer = that._outer,
  32686. startPosition = that._translator.translate(range.start),
  32687. endPosition = that._translator.translate(range.end),
  32688. points;
  32689. if (that.vertical)
  32690. 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];
  32691. else
  32692. 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];
  32693. return that._renderer.createArea(points)
  32694. },
  32695. measure: function(layout) {
  32696. var result = {};
  32697. result.min = result.max = layout[this.vertical ? 'x' : 'y'];
  32698. var width = this._options.width;
  32699. width = _Number(width) || _max(_Number(width.start), _Number(width.end));
  32700. result.min -= this._inner * width;
  32701. result.max += this._outer * width;
  32702. return result
  32703. }
  32704. })
  32705. })(DevExpress, jQuery);
  32706. /*! Module viz-gauges, file title.js */
  32707. (function(DX, $, undefined) {
  32708. var _isString = DX.utils.isString,
  32709. _max = Math.max,
  32710. _extend = $.extend;
  32711. DX.viz.gauges.__internals.Title = DX.Class.inherit({
  32712. ctor: function(parameters) {
  32713. this._renderer = parameters.renderer;
  32714. this._container = parameters.container
  32715. },
  32716. dispose: function() {
  32717. this._renderer = this._container = null;
  32718. return this
  32719. },
  32720. clean: function() {
  32721. var that = this;
  32722. if (that._root) {
  32723. that._root.detach().clear();
  32724. that._root = that._layout = null
  32725. }
  32726. return that
  32727. },
  32728. render: function(titleOptions, subtitleOptions) {
  32729. var that = this,
  32730. hasTitle = _isString(titleOptions.text) && titleOptions.text.length > 0,
  32731. hasSubtitle = _isString(subtitleOptions.text) && subtitleOptions.text.length > 0;
  32732. if (!hasTitle && !hasSubtitle)
  32733. return that;
  32734. that._root = that._renderer.createGroup({'class': 'dxg-title'}).append(that._container);
  32735. var title = hasTitle ? that._renderer.createText(titleOptions.text, 0, 0, {
  32736. align: 'center',
  32737. font: titleOptions.font
  32738. }).append(that._root) : null,
  32739. subtitle = hasSubtitle ? that._renderer.createText(subtitleOptions.text, 0, 0, {
  32740. align: 'center',
  32741. font: subtitleOptions.font
  32742. }).append(that._root) : null,
  32743. titleBox = title ? title.getBBox() : {},
  32744. subtitleBox = subtitle ? subtitle.getBBox() : {},
  32745. y = 0;
  32746. if (title) {
  32747. y += -titleBox.y;
  32748. title.applySettings({
  32749. x: 0,
  32750. y: y
  32751. })
  32752. }
  32753. if (subtitle) {
  32754. y += -subtitleBox.y;
  32755. subtitle.applySettings({
  32756. x: 0,
  32757. y: y
  32758. })
  32759. }
  32760. that._layout = _extend({
  32761. position: titleOptions.position,
  32762. width: _max(titleBox.width || 0, subtitleBox.width || 0),
  32763. height: title && subtitle ? -titleBox.y + subtitleBox.height : titleBox.height || subtitleBox.height
  32764. }, titleOptions.layout);
  32765. return that
  32766. },
  32767. getLayoutOptions: function() {
  32768. return this._layout
  32769. },
  32770. locate: function(left, top) {
  32771. this._root.applySettings({
  32772. translateX: left + this._layout.width / 2,
  32773. translateY: top
  32774. });
  32775. return this
  32776. }
  32777. })
  32778. })(DevExpress, jQuery);
  32779. /*! Module viz-gauges, file tooltip.js */
  32780. (function(DX, $, undefined) {
  32781. var _extend = $.extend;
  32782. DX.viz.gauges.__internals.Tooltip = DX.viz.core.Tooltip.inherit({
  32783. ctor: function(parameters) {
  32784. var that = this;
  32785. that._container = parameters.container;
  32786. that._tracker = parameters.tracker;
  32787. that._root = parameters.renderer.createGroup({'class': 'dxg-tooltip'});
  32788. that.callBase(null, that._root, parameters.renderer);
  32789. that._setTrackerCallbacks()
  32790. },
  32791. dispose: function() {
  32792. var that = this;
  32793. that._container = that._tracker = that._root = null;
  32794. return that._shadow ? that.callBase.apply(that, arguments) : that
  32795. },
  32796. _setTrackerCallbacks: function() {
  32797. var that = this;
  32798. function prepareCallback(target, info) {
  32799. var tooltipParameters = target.getTooltipParameters(),
  32800. formatObject = _extend({
  32801. value: tooltipParameters.value,
  32802. valueText: that.formatValue(tooltipParameters.value),
  32803. color: tooltipParameters.color
  32804. }, info);
  32805. return that.prepare(formatObject, {
  32806. x: tooltipParameters.x,
  32807. y: tooltipParameters.y,
  32808. offset: tooltipParameters.offset
  32809. })
  32810. }
  32811. function showCallback() {
  32812. return that.show()
  32813. }
  32814. function hideCallback() {
  32815. return that.hide()
  32816. }
  32817. that._tracker.setCallbacks({
  32818. 'tooltip-prepare': prepareCallback,
  32819. 'tooltip-show': showCallback,
  32820. 'tooltip-hide': hideCallback
  32821. })
  32822. },
  32823. clean: function() {
  32824. this._root.detach();
  32825. return this
  32826. },
  32827. render: function(options, size) {
  32828. var that = this;
  32829. options.canvasWidth = size.width;
  32830. options.canvasHeight = size.height;
  32831. options.text = {'class': 'dxg-text'};
  32832. that.update(options);
  32833. that._tracker.setTooltipState(that.enabled());
  32834. that.enabled() && that._root.append(that._container);
  32835. return that
  32836. }
  32837. })
  32838. })(DevExpress, jQuery);
  32839. /*! Module viz-gauges, file layoutManager.js */
  32840. (function(DX, $, undefined) {
  32841. var _Number = Number,
  32842. _String = String,
  32843. _min = Math.min,
  32844. _max = Math.max,
  32845. _each = $.each;
  32846. function patchLayoutOptions(options) {
  32847. if (options.position) {
  32848. var position = _String(options.position).toLowerCase().split('-');
  32849. options.verticalAlignment = position[0];
  32850. options.horizontalAlignment = position[1]
  32851. }
  32852. }
  32853. DX.viz.gauges.__internals.LayoutManager = DX.Class.inherit({
  32854. setRect: function(rect) {
  32855. this._currentRect = rect.clone();
  32856. return this
  32857. },
  32858. getRect: function() {
  32859. return this._currentRect.clone()
  32860. },
  32861. beginLayout: function(rect) {
  32862. this._rootRect = rect.clone();
  32863. this._currentRect = rect.clone();
  32864. this._cache = [];
  32865. return this
  32866. },
  32867. applyLayout: function(target) {
  32868. var options = target.getLayoutOptions();
  32869. if (!options)
  32870. return this;
  32871. var currentRect = this._currentRect,
  32872. verticalOverlay = _Number(options.overlay) || 0;
  32873. patchLayoutOptions(options);
  32874. switch (_String(options.verticalAlignment).toLowerCase()) {
  32875. case'bottom':
  32876. currentRect.bottom -= _max(options.height - verticalOverlay, 0);
  32877. break;
  32878. default:
  32879. currentRect.top += _max(options.height - verticalOverlay, 0);
  32880. break
  32881. }
  32882. this._cache.push({
  32883. target: target,
  32884. options: options
  32885. });
  32886. return this
  32887. },
  32888. endLayout: function() {
  32889. var that = this,
  32890. rootRect = that._rootRect,
  32891. currentRect = that._currentRect;
  32892. _each(that._cache, function(_, cacheItem) {
  32893. var options = cacheItem.options,
  32894. left,
  32895. top,
  32896. verticalOverlay = _Number(options.overlay) || 0;
  32897. switch (_String(options.verticalAlignment).toLowerCase()) {
  32898. case'bottom':
  32899. top = currentRect.bottom - verticalOverlay;
  32900. currentRect.bottom += _max(options.height - verticalOverlay, 0);
  32901. break;
  32902. default:
  32903. top = currentRect.top - options.height + verticalOverlay;
  32904. currentRect.top -= _max(options.height - verticalOverlay, 0);
  32905. break
  32906. }
  32907. switch (_String(options.horizontalAlignment).toLowerCase()) {
  32908. case'left':
  32909. left = rootRect.left;
  32910. break;
  32911. case'right':
  32912. left = rootRect.right - options.width;
  32913. break;
  32914. default:
  32915. left = rootRect.horizontalMiddle() - options.width / 2;
  32916. break
  32917. }
  32918. cacheItem.target.locate(left, top)
  32919. });
  32920. that._cache = null;
  32921. return that
  32922. },
  32923. selectRectByAspectRatio: function(aspectRatio, margins) {
  32924. var rect = this._currentRect.clone(),
  32925. selfAspectRatio,
  32926. width = 0,
  32927. height = 0;
  32928. margins = margins || {};
  32929. if (aspectRatio > 0) {
  32930. rect.left += margins.left || 0;
  32931. rect.right -= margins.right || 0;
  32932. rect.top += margins.top || 0;
  32933. rect.bottom -= margins.bottom || 0;
  32934. if (rect.width() > 0 && rect.height() > 0) {
  32935. selfAspectRatio = rect.height() / rect.width();
  32936. if (selfAspectRatio > 1)
  32937. aspectRatio < selfAspectRatio ? width = rect.width() : height = rect.height();
  32938. else
  32939. aspectRatio > selfAspectRatio ? height = rect.height() : width = rect.width();
  32940. width > 0 || (width = height / aspectRatio);
  32941. height > 0 || (height = width * aspectRatio);
  32942. width = (rect.width() - width) / 2;
  32943. height = (rect.height() - height) / 2;
  32944. rect.left += width;
  32945. rect.right -= width;
  32946. rect.top += height;
  32947. rect.bottom -= height
  32948. }
  32949. else {
  32950. rect.left = rect.right = rect.horizontalMiddle();
  32951. rect.top = rect.bottom = rect.verticalMiddle()
  32952. }
  32953. }
  32954. return rect
  32955. },
  32956. selectRectBySizes: function(sizes, margins) {
  32957. var rect = this._currentRect.clone(),
  32958. step;
  32959. margins = margins || {};
  32960. if (sizes) {
  32961. rect.left += margins.left || 0;
  32962. rect.right -= margins.right || 0;
  32963. rect.top += margins.top || 0;
  32964. rect.bottom -= margins.bottom || 0;
  32965. if (sizes.width > 0) {
  32966. step = (rect.width() - sizes.width) / 2;
  32967. if (step > 0) {
  32968. rect.left += step;
  32969. rect.right -= step
  32970. }
  32971. }
  32972. if (sizes.height > 0) {
  32973. step = (rect.height() - sizes.height) / 2;
  32974. if (step > 0) {
  32975. rect.top += step;
  32976. rect.bottom -= step
  32977. }
  32978. }
  32979. }
  32980. return rect
  32981. }
  32982. })
  32983. })(DevExpress, jQuery);
  32984. /*! Module viz-gauges, file themeManager.js */
  32985. (function(DX, $, undefined) {
  32986. var _extend = $.extend;
  32987. DX.viz.gauges.__internals.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  32988. _themeSection: 'gauge',
  32989. _initializeTheme: function() {
  32990. var that = this;
  32991. if (that._subTheme) {
  32992. var subTheme = _extend(true, {}, that._theme[that._subTheme], that._theme);
  32993. _extend(true, that._theme, subTheme)
  32994. }
  32995. that._initializeFont(that._theme.scale.label.font);
  32996. that._initializeFont(that._theme.valueIndicator.rangebar.text.font);
  32997. that._initializeFont(that._theme.subvalueIndicator.textcloud.text.font);
  32998. that._initializeFont(that._theme.valueIndicators.rangebar.text.font);
  32999. that._initializeFont(that._theme.valueIndicators.textcloud.text.font);
  33000. that._initializeFont(that._theme.title.font);
  33001. that._initializeFont(that._theme.subtitle.font);
  33002. that._initializeFont(that._theme.tooltip.font);
  33003. that._initializeFont(that._theme.indicator.text.font);
  33004. that._initializeFont(that._theme.loadingIndicator.font)
  33005. }
  33006. })
  33007. })(DevExpress, jQuery);
  33008. /*! Module viz-gauges, file presetManager.js */
  33009. /*! Module viz-gauges, file baseGauge.js */
  33010. (function(DX, $, undefined) {
  33011. var _Number = Number,
  33012. _isNumber = DX.utils.isNumber,
  33013. _isString = DX.utils.isString,
  33014. _getAppropriateFormat = DX.utils.getAppropriateFormat,
  33015. _extend = $.extend,
  33016. _each = $.each;
  33017. DX.viz.gauges.__internals.BaseGauge = DX.viz.core.BaseWidget.inherit({
  33018. _init: function() {
  33019. var that = this;
  33020. that.callBase.apply(that, arguments);
  33021. that._renderer = that._factory.createRenderer({
  33022. width: 1,
  33023. height: 1,
  33024. pathModified: that.option('pathModified'),
  33025. rtl: that.option('rtlEnabled')
  33026. });
  33027. that._root = that._renderer.getRoot();
  33028. that._root.applySettings({'class': 'dxg ' + that._rootClass});
  33029. that._translator = that._factory.createTranslator();
  33030. that._themeManager = that._factory.createThemeManager();
  33031. that._tracker = that._factory.createTracker({
  33032. renderer: that._renderer,
  33033. container: that._root
  33034. });
  33035. that._layoutManager = that._factory.createLayoutManager();
  33036. that._tooltip = that._factory.createTooltip({
  33037. renderer: that._renderer,
  33038. container: that._root,
  33039. tracker: that._tracker
  33040. });
  33041. that._title = that._factory.createTitle({
  33042. renderer: that._renderer,
  33043. container: that._root
  33044. });
  33045. that._deltaIndicator = that._factory.createDeltaIndicator({
  33046. renderer: that._renderer,
  33047. container: that._root
  33048. });
  33049. that._setupDomain();
  33050. that._themeManager.setTheme(that.option('theme'))
  33051. },
  33052. _dispose: function() {
  33053. var that = this;
  33054. that.callBase.apply(that, arguments);
  33055. that._renderer.dispose();
  33056. that._themeManager.dispose();
  33057. that._tracker.dispose();
  33058. that._title.dispose();
  33059. that._deltaIndicator && that._deltaIndicator.dispose();
  33060. that._tooltip.dispose();
  33061. that._disposeLoadIndicator();
  33062. that._renderer = that._root = that._translator = that._themeManager = that._tracker = that._layoutManager = that._title = that._tooltip = null
  33063. },
  33064. _refresh: function() {
  33065. var that = this,
  33066. callBase = that.callBase;
  33067. that._endLoading(function() {
  33068. callBase.call(that)
  33069. })
  33070. },
  33071. _clean: function() {
  33072. this._cleanCore()
  33073. },
  33074. _render: function() {
  33075. var that = this;
  33076. that._setupCodomain();
  33077. that._setupAnimationSettings();
  33078. if (that._calculateSize() && that._checkDomain()) {
  33079. that._renderer.draw(that._element()[0]);
  33080. that._setupDefaultFormat();
  33081. that._renderCore()
  33082. }
  33083. that._drawn()
  33084. },
  33085. _cleanCore: function() {
  33086. var that = this;
  33087. that._tooltip.clean();
  33088. that._title.clean();
  33089. that._deltaIndicator && that._deltaIndicator.clean();
  33090. that._tracker.deactivate();
  33091. that._cleanContent()
  33092. },
  33093. _renderCore: function() {
  33094. var that = this;
  33095. that._title.render(_extend(true, {}, that._themeManager.theme()['title'], processTitleOptions(that.option('title'))), _extend(true, {}, that._themeManager.theme()['subtitle'], processTitleOptions(that.option('subtitle'))));
  33096. that._deltaIndicator && that._deltaIndicator.render(_extend(true, {}, that._themeManager.theme()['indicator'], that.option('indicator')));
  33097. that._layoutManager.beginLayout(that._rootRect);
  33098. _each([that._deltaIndicator, that._title], function(_, item) {
  33099. item && that._layoutManager.applyLayout(item)
  33100. });
  33101. that._mainRect = that._layoutManager.getRect();
  33102. that._renderContent();
  33103. that._layoutManager.endLayout();
  33104. that._tooltip.render(_extend(true, {}, that._themeManager.theme()['tooltip'], that.option('tooltip')), {
  33105. width: that._width,
  33106. height: that._height
  33107. });
  33108. that._tracker.activate();
  33109. that._updateLoadIndicator(undefined, that._width, that._height);
  33110. that._noAnimation = null;
  33111. that.option('debugMode') === true && that._renderDebugInfo();
  33112. that._debug_rendered && that._debug_rendered()
  33113. },
  33114. _renderDebugInfo: function() {
  33115. var that = this,
  33116. group = that._debugGroup || that._renderer.createGroup({'class': 'debug-info'}).append(),
  33117. rect;
  33118. group.clear();
  33119. rect = that._rootRect;
  33120. that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
  33121. stroke: '#000000',
  33122. strokeWidth: 1,
  33123. fill: 'none'
  33124. }).append(group);
  33125. rect = that._mainRect;
  33126. that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
  33127. stroke: '#0000FF',
  33128. strokeWidth: 1,
  33129. fill: 'none'
  33130. }).append(group);
  33131. rect = that._layoutManager.getRect();
  33132. rect && that._renderer.createRect(rect.left, rect.top, rect.width(), rect.height(), 0, {
  33133. stroke: '#FF0000',
  33134. strokeWidth: 1,
  33135. fill: 'none'
  33136. }).append(group);
  33137. rect = that._title.getLayoutOptions() ? that._title._root.getBBox() : null;
  33138. rect && that._renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
  33139. stroke: '#00FF00',
  33140. strokeWidth: 1,
  33141. fill: 'none'
  33142. }).append(group);
  33143. rect = that._deltaIndicator && that._deltaIndicator.getLayoutOptions() ? that._deltaIndicator._root.getBBox() : null;
  33144. rect && that._renderer.createRect(rect.x, rect.y, rect.width, rect.height, 0, {
  33145. stroke: '#00FF00',
  33146. strokeWidth: 1,
  33147. fill: 'none'
  33148. }).append(group)
  33149. },
  33150. _resize: function() {
  33151. var that = this;
  33152. if (that._calculateSize()) {
  33153. that._resizing = that._noAnimation = true;
  33154. that._cleanCore();
  33155. that._renderCore();
  33156. that._resizing = null
  33157. }
  33158. },
  33159. render: function(options) {
  33160. options && options.animate !== undefined && !options.animate && (this._noAnimation = true);
  33161. this._refresh();
  33162. return this
  33163. },
  33164. showLoadingIndicator: function() {
  33165. this._showLoadIndicator(this._getLoadIndicatorOption(), {
  33166. width: this._width,
  33167. height: this._height
  33168. })
  33169. },
  33170. _getLoadIndicatorOption: function() {
  33171. return _extend(true, {}, this._themeManager.theme()['loadingIndicator'], this.option('loadingIndicator'))
  33172. },
  33173. _optionChanged: function(name, newv, oldv) {
  33174. var that = this;
  33175. switch (name) {
  33176. case'theme':
  33177. that._themeManager.setTheme(newv);
  33178. that._invalidate();
  33179. break;
  33180. case'startValue':
  33181. case'endValue':
  33182. that._setupDomain();
  33183. that._invalidate();
  33184. break;
  33185. default:
  33186. that.callBase.apply(that, arguments);
  33187. break
  33188. }
  33189. },
  33190. _calculateSize: function() {
  33191. var that = this;
  33192. that._calculateSizeCore();
  33193. if (that._width === 0 || that._height === 0 || !that._element().is(':visible')) {
  33194. that._incidentOccured('W2001', [that.NAME]);
  33195. return false
  33196. }
  33197. else {
  33198. that._renderer.resize(that._width, that._height);
  33199. return true
  33200. }
  33201. },
  33202. _checkDomain: function() {
  33203. var that = this,
  33204. domain = that._translator.getDomain(),
  33205. isValid = isFinite(1 / (domain[1] - domain[0]));
  33206. if (!isValid)
  33207. that._incidentOccured('W2301');
  33208. return isValid
  33209. },
  33210. _setupAnimationSettings: function() {
  33211. var that = this,
  33212. option = that.option('animation');
  33213. that._animationSettings = null;
  33214. if (option === undefined || option) {
  33215. if (option === undefined)
  33216. option = {
  33217. enabled: that.option('animationEnabled'),
  33218. duration: that.option('animationDuration')
  33219. };
  33220. option = _extend({
  33221. enabled: true,
  33222. duration: 1000,
  33223. easing: 'easeOutCubic'
  33224. }, option);
  33225. if (option.enabled && option.duration > 0)
  33226. that._animationSettings = {
  33227. duration: _Number(option.duration),
  33228. easing: option.easing
  33229. }
  33230. }
  33231. that._containerBackgroundColor = that.option('containerBackgroundColor') || that._themeManager.theme().containerBackgroundColor
  33232. },
  33233. _setupDefaultFormat: function() {
  33234. var domain = this._translator.getDomain();
  33235. this._defaultFormatOptions = _getAppropriateFormat(domain[0], domain[1], this._getApproximateScreenRange())
  33236. },
  33237. _setupDomain: null,
  33238. _calculateSizeCore: null,
  33239. _cleanContent: null,
  33240. _renderContent: null,
  33241. _setupCodomain: null,
  33242. _getApproximateScreenRange: null,
  33243. _factory: {
  33244. createRenderer: DX.viz.core.CoreFactory.createRenderer,
  33245. createTranslator: function() {
  33246. return new DX.viz.core.Translator1D
  33247. },
  33248. createTracker: function(parameters) {
  33249. return new DX.viz.gauges.__internals.Tracker(parameters)
  33250. },
  33251. createLayoutManager: function() {
  33252. return new DX.viz.gauges.__internals.LayoutManager
  33253. },
  33254. createTitle: function(parameters) {
  33255. return new DX.viz.gauges.__internals.Title(parameters)
  33256. },
  33257. createDeltaIndicator: function(parameters) {
  33258. return DX.viz.gauges.__internals.DeltaIndicator ? new DX.viz.gauges.__internals.DeltaIndicator(parameters) : null
  33259. },
  33260. createTooltip: function(parameters) {
  33261. return new DX.viz.gauges.__internals.Tooltip(parameters)
  33262. }
  33263. }
  33264. });
  33265. function processTitleOptions(options) {
  33266. return _isString(options) ? {text: options} : options || {}
  33267. }
  33268. })(DevExpress, jQuery);
  33269. /*! Module viz-gauges, file gauge.js */
  33270. (function(DX, $, undefined) {
  33271. var _Rectangle = DX.viz.core.Rectangle;
  33272. var _isDefined = DX.utils.isDefined,
  33273. _isArray = DX.utils.isArray,
  33274. _isNumber = DX.utils.isNumber,
  33275. _isFinite = isFinite,
  33276. _Number = Number,
  33277. _String = String,
  33278. _abs = Math.abs,
  33279. _extend = $.extend,
  33280. _each = $.each,
  33281. _map = $.map,
  33282. _noop = $.noop;
  33283. var OPTION_VALUE = 'value',
  33284. OPTION_SUBVALUES = 'subvalues';
  33285. DX.viz.gauges.Gauge = DX.viz.gauges.__internals.BaseGauge.inherit({
  33286. _init: function() {
  33287. var that = this;
  33288. that.__value = that.option(OPTION_VALUE);
  33289. that.__subvalues = that.option(OPTION_SUBVALUES);
  33290. if (!_isArray(that.__subvalues))
  33291. that.__subvalues = _isNumber(that.__subvalues) ? [that.__subvalues] : null;
  33292. that._selectMode();
  33293. that.callBase.apply(that, arguments);
  33294. that._scale = that._createScale({
  33295. renderer: that._renderer,
  33296. container: that._root,
  33297. translator: that._translator
  33298. });
  33299. that._rangeContainer = that._createRangeContainer({
  33300. renderer: that._renderer,
  33301. container: that._root,
  33302. translator: that._translator
  33303. })
  33304. },
  33305. _dispose: function() {
  33306. var that = this;
  33307. that.callBase.apply(that, arguments);
  33308. that._scale.dispose();
  33309. that._rangeContainer.dispose();
  33310. that._disposeValueIndicators();
  33311. that._scale = that._rangeContainer = null
  33312. },
  33313. _disposeValueIndicators: function() {
  33314. var that = this;
  33315. that._valueIndicator && that._valueIndicator.dispose();
  33316. that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.dispose();
  33317. that._valueIndicator = that._subvalueIndicatorsSet = null
  33318. },
  33319. _selectMode: function() {
  33320. var that = this;
  33321. if (that.option(OPTION_VALUE) === undefined && that.option(OPTION_SUBVALUES) === undefined)
  33322. if (that.option('needles') !== undefined || that.option('markers') !== undefined || that.option('rangeBars') !== undefined) {
  33323. disableDefaultMode(that);
  33324. selectObsoleteMode(that)
  33325. }
  33326. else if (that.option('valueIndicators') !== undefined) {
  33327. disableDefaultMode(that);
  33328. selectHardMode(that)
  33329. }
  33330. },
  33331. _setupDomain: function() {
  33332. var that = this,
  33333. scaleOption = that.option('scale') || {},
  33334. startValue = that.option('startValue'),
  33335. endValue = that.option('endValue');
  33336. startValue = _isNumber(startValue) ? _Number(startValue) : _isNumber(scaleOption.startValue) ? _Number(scaleOption.startValue) : 0;
  33337. endValue = _isNumber(endValue) ? _Number(endValue) : _isNumber(scaleOption.endValue) ? _Number(scaleOption.endValue) : 100;
  33338. that._baseValue = startValue < endValue ? startValue : endValue;
  33339. that._translator.setDomain(startValue, endValue);
  33340. that._setupValueState()
  33341. },
  33342. _setupValueState: function() {
  33343. this._setupValue();
  33344. this.__subvalues !== null && this._setupSubvalues()
  33345. },
  33346. _calculateSizeCore: function() {
  33347. var that = this,
  33348. size = that.option('size') || {},
  33349. margin = that.option('margin') || {};
  33350. if (_Number(size.width) === 0 || _Number(size.height) === 0) {
  33351. that._width = that._height = 0;
  33352. that._rootRect = new _Rectangle
  33353. }
  33354. else {
  33355. var width = size.width > 0 ? _Number(size.width) : that._element().width() || that._getDefaultContainerSize().width,
  33356. height = size.height > 0 ? _Number(size.height) : that._element().height() || that._getDefaultContainerSize().height,
  33357. marginL = margin.left > 0 ? _Number(margin.left) : 0,
  33358. marginR = margin.right > 0 ? _Number(margin.right) : 0,
  33359. marginT = margin.top > 0 ? _Number(margin.top) : 0,
  33360. marginB = margin.bottom > 0 ? _Number(margin.bottom) : 0;
  33361. marginL + marginR >= width && (marginL = marginR = 0);
  33362. marginT + marginB >= height && (marginT = marginB = 0);
  33363. that._width = width;
  33364. that._height = height;
  33365. that._rootRect = new _Rectangle({
  33366. left: marginL,
  33367. top: marginT,
  33368. right: width - marginR,
  33369. bottom: height - marginB
  33370. })
  33371. }
  33372. },
  33373. _cleanContent: function() {
  33374. var that = this;
  33375. that._rangeContainer.clean();
  33376. that._scale.clean();
  33377. that._cleanValueIndicators()
  33378. },
  33379. _renderContent: function() {
  33380. var that = this;
  33381. that._rangeContainer.render(_extend(true, {}, that._themeManager.theme().rangeContainer, that.option('rangeContainer'), {
  33382. themeName: that._themeManager.themeName(),
  33383. vertical: that._area.vertical
  33384. }));
  33385. that._scale.render(_extend(true, {}, that._themeManager.theme().scale, that.option('scale'), {
  33386. approximateScreenDelta: that._getApproximateScreenRange(),
  33387. offset: 0,
  33388. vertical: that._area.vertical
  33389. }));
  33390. var elements = that._prepareValueIndicators();
  33391. elements = _map([that._scale, that._rangeContainer].concat(elements), function(element) {
  33392. return element && element.enabled ? element : null
  33393. });
  33394. that._applyMainLayout(elements);
  33395. _each(elements, function(_, element) {
  33396. that._updateElementPosition(element)
  33397. });
  33398. that._updateActiveElements()
  33399. },
  33400. _updateIndicatorSettings: function(settings) {
  33401. var that = this;
  33402. settings.currentValue = settings.baseValue = _isFinite(that._translator.translate(settings.baseValue)) ? _Number(settings.baseValue) : that._baseValue;
  33403. settings.vertical = that._area.vertical;
  33404. if (settings.text && !settings.text.format && !settings.text.precision) {
  33405. settings.text.format = that._defaultFormatOptions.format;
  33406. settings.text.precision = that._defaultFormatOptions.precision
  33407. }
  33408. },
  33409. _prepareValueIndicatorSettings: function() {
  33410. var that = this,
  33411. options = that.option('valueIndicator') || {},
  33412. defaultOptions = _extend(true, {}, that._themeManager.theme().valueIndicator),
  33413. type = _String(options.type || defaultOptions.type).toLowerCase();
  33414. that._valueIndicatorSettings = _extend(true, defaultOptions._default, defaultOptions[type], options, {
  33415. type: type,
  33416. animation: that._animationSettings,
  33417. containerBackgroundColor: that._containerBackgroundColor
  33418. });
  33419. that._updateIndicatorSettings(that._valueIndicatorSettings)
  33420. },
  33421. _prepareSubvalueIndicatorSettings: function() {
  33422. var that = this,
  33423. options = that.option('subvalueIndicator') || {},
  33424. defaultOptions = _extend(true, {}, that._themeManager.theme().subvalueIndicator),
  33425. type = _String(options.type || defaultOptions.type).toLowerCase();
  33426. that._subvalueIndicatorSettings = _extend(true, defaultOptions._default, defaultOptions[type], options, {
  33427. type: type,
  33428. animation: that._animationSettings,
  33429. containerBackgroundColor: that._containerBackgroundColor
  33430. });
  33431. that._updateIndicatorSettings(that._subvalueIndicatorSettings)
  33432. },
  33433. _cleanValueIndicators: function() {
  33434. this._valueIndicator && this._valueIndicator.clean();
  33435. this._subvalueIndicatorsSet && this._subvalueIndicatorsSet.clean()
  33436. },
  33437. _prepareValueIndicators: function() {
  33438. var that = this;
  33439. that._prepareValueIndicator();
  33440. that.__subvalues !== null && that._prepareSubvalueIndicators();
  33441. return [that._valueIndicator, that._subvalueIndicatorsSet]
  33442. },
  33443. _updateActiveElements: function() {
  33444. this._updateValueIndicator();
  33445. this._updateSubvalueIndicators()
  33446. },
  33447. _prepareValueIndicator: function() {
  33448. var that = this,
  33449. indicator = that._valueIndicator,
  33450. currentValue;
  33451. that._prepareValueIndicatorSettings();
  33452. indicator && that._valueIndicatorType !== that._valueIndicatorSettings.type && indicator.dispose() && (indicator = null);
  33453. that._valueIndicatorType = that._valueIndicatorSettings.type;
  33454. if (!indicator) {
  33455. indicator = that._valueIndicator = that._createValueIndicator(that._valueIndicatorType);
  33456. if (indicator) {
  33457. indicator.setup({
  33458. renderer: that._renderer,
  33459. translator: that._translator,
  33460. owner: that._root,
  33461. tracker: that._tracker,
  33462. className: 'dxg-value-indicator'
  33463. });
  33464. indicator._trackerInfo = {type: 'value-indicator'}
  33465. }
  33466. }
  33467. indicator.render(that._valueIndicatorSettings)
  33468. },
  33469. _prepareSubvalueIndicators: function() {
  33470. var that = this,
  33471. subvalueIndicatorsSet = that._subvalueIndicatorsSet;
  33472. if (!subvalueIndicatorsSet)
  33473. subvalueIndicatorsSet = that._subvalueIndicatorsSet = new DX.viz.gauges.__internals.ValueIndicatorsSet({
  33474. renderer: that._renderer,
  33475. translator: that._translator,
  33476. owner: that._root,
  33477. tracker: that._tracker,
  33478. className: 'dxg-subvalue-indicators',
  33479. indicatorClassName: 'dxg-subvalue-indicator',
  33480. trackerType: 'subvalue-indicator',
  33481. createIndicator: function() {
  33482. return that._createSubvalueIndicator(that._subvalueIndicatorType)
  33483. }
  33484. });
  33485. that._prepareSubvalueIndicatorSettings();
  33486. var isRecreate = that._subvalueIndicatorSettings.type !== that._subvalueIndicatorType;
  33487. that._subvalueIndicatorType = that._subvalueIndicatorSettings.type;
  33488. if (that._createSubvalueIndicator(that._subvalueIndicatorType))
  33489. subvalueIndicatorsSet.render(that._subvalueIndicatorSettings, isRecreate)
  33490. },
  33491. _processValue: function(value, fallbackValue) {
  33492. var _value = this._translator.adjust(value !== undefined ? value : this.__value);
  33493. return _isFinite(_value) ? _value : fallbackValue
  33494. },
  33495. _setupValue: function(value) {
  33496. this.__value = this._processValue(value, this.__value)
  33497. },
  33498. _setupSubvalues: function(subvalues) {
  33499. var _subvalues = subvalues === undefined ? this.__subvalues : _isArray(subvalues) ? subvalues : _isNumber(subvalues) ? [subvalues] : null;
  33500. if (_subvalues === null)
  33501. return;
  33502. var i = 0,
  33503. ii = _subvalues.length,
  33504. list = [];
  33505. for (; i < ii; ++i)
  33506. list.push(this._processValue(_subvalues[i], this.__subvalues[i]));
  33507. this.__subvalues = list
  33508. },
  33509. _updateValueIndicator: function() {
  33510. var that = this;
  33511. that._valueIndicator && that._valueIndicator.value(that.__value, that._noAnimation);
  33512. that._resizing || that.hideLoadingIndicator()
  33513. },
  33514. _updateSubvalueIndicators: function() {
  33515. var that = this;
  33516. that._subvalueIndicatorsSet && that._subvalueIndicatorsSet.values(that.__subvalues, that._noAnimation);
  33517. that._resizing || that.hideLoadingIndicator()
  33518. },
  33519. value: function(arg) {
  33520. var that = this;
  33521. if (arg !== undefined) {
  33522. that._setupValue(arg);
  33523. that._updateValueIndicator();
  33524. that.option(OPTION_VALUE, that.__value);
  33525. return that
  33526. }
  33527. return that.__value
  33528. },
  33529. subvalues: function(arg) {
  33530. var that = this;
  33531. if (arg !== undefined) {
  33532. if (that.__subvalues !== null) {
  33533. that._setupSubvalues(arg);
  33534. that._updateSubvalueIndicators();
  33535. that.option(OPTION_SUBVALUES, that.__subvalues)
  33536. }
  33537. return that
  33538. }
  33539. return that.__subvalues !== null ? that.__subvalues.slice() : undefined
  33540. },
  33541. _handleValueChanged: function(name, newv, oldv) {
  33542. var that = this;
  33543. switch (name) {
  33544. case OPTION_VALUE:
  33545. that._setupValue(newv);
  33546. that._updateValueIndicator();
  33547. that.option(OPTION_VALUE, that.__value);
  33548. return true;
  33549. case OPTION_SUBVALUES:
  33550. if (that.__subvalues !== null) {
  33551. that._setupSubvalues(newv);
  33552. that._updateSubvalueIndicators();
  33553. that.option(OPTION_SUBVALUES, that.__subvalues);
  33554. return true
  33555. }
  33556. return false;
  33557. default:
  33558. return false
  33559. }
  33560. },
  33561. _optionChanged: function(name, newValue, oldValue) {
  33562. var that = this;
  33563. if (that._handleValueChanged(name, newValue, oldValue))
  33564. return;
  33565. switch (name) {
  33566. case'scale':
  33567. that._setupDomain();
  33568. that._invalidate();
  33569. break;
  33570. default:
  33571. that.callBase.apply(that, arguments);
  33572. break
  33573. }
  33574. },
  33575. _optionValuesEqual: function(name, oldValue, newValue) {
  33576. switch (name) {
  33577. case OPTION_VALUE:
  33578. return oldValue === newValue;
  33579. case OPTION_SUBVALUES:
  33580. return compareArrays(oldValue, newValue);
  33581. default:
  33582. return this.callBase.apply(this, arguments)
  33583. }
  33584. },
  33585. _getDefaultContainerSize: null,
  33586. _applyMainLayout: null,
  33587. _updateElementPosition: null,
  33588. _createScale: null,
  33589. _createRangeContainer: null,
  33590. _createValueIndicator: null,
  33591. _createSubvalueIndicator: null,
  33592. _getApproximateScreenRange: null
  33593. });
  33594. DX.viz.gauges.Gauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  33595. DX.viz.gauges.Gauge.prototype._factory.createThemeManager = function() {
  33596. return new DX.viz.gauges.__internals.ThemeManager
  33597. };
  33598. function valueGetter(arg) {
  33599. return arg.value
  33600. }
  33601. function setupValues(that, fieldName, optionItems) {
  33602. var currentValues = that[fieldName],
  33603. newValues = _isArray(optionItems) ? _map(optionItems, valueGetter) : [],
  33604. i = 0,
  33605. ii = newValues.length,
  33606. list = [];
  33607. for (; i < ii; ++i)
  33608. list.push(that._processValue(newValues[i], currentValues[i]));
  33609. that[fieldName] = list
  33610. }
  33611. function disableDefaultMode(that) {
  33612. that.value = that.subvalues = _noop;
  33613. that._setupValue = that._setupSubvalues = that._updateValueIndicator = that._updateSubvalueIndicators = null
  33614. }
  33615. function selectObsoleteMode(that) {
  33616. that._needleValues = _map(that.option('needles') || [], valueGetter);
  33617. that._markerValues = _map(that.option('markers') || [], valueGetter);
  33618. that._rangeBarValues = _map(that.option('rangeBars') || [], valueGetter);
  33619. that._needles = [];
  33620. that._markers = [];
  33621. that._rangeBars = [];
  33622. that._setupValueState = function() {
  33623. var that = this;
  33624. setupValues(that, '_needleValues', that.option('needles'));
  33625. setupValues(that, '_markerValues', that.option('markers'));
  33626. setupValues(that, '_rangeBarValues', that.option('rangeBars'))
  33627. };
  33628. that._handleValueChanged = function(name, newv, oldv) {
  33629. var that = this,
  33630. result = false;
  33631. switch (name) {
  33632. case'needles':
  33633. setupValues(that, '_needleValues', newv);
  33634. result = true;
  33635. break;
  33636. case'markers':
  33637. setupValues(that, '_markerValues', newv);
  33638. result = true;
  33639. break;
  33640. case'rangeBars':
  33641. setupValues(that, '_rangeBarValues', newv);
  33642. result = true;
  33643. break
  33644. }
  33645. result && that._invalidate();
  33646. return result
  33647. };
  33648. that._updateActiveElements = function() {
  33649. var that = this;
  33650. _each(that._needles, function(_, needle) {
  33651. needle.value(that._needleValues[needle._index], that._noAnimation)
  33652. });
  33653. _each(that._markers, function(_, marker) {
  33654. marker.value(that._markerValues[marker._index], that._noAnimation)
  33655. });
  33656. _each(that._rangeBars, function(_, rangeBar) {
  33657. rangeBar.value(that._rangeBarValues[rangeBar._index], that._noAnimation)
  33658. });
  33659. that._resizing || that.hideLoadingIndicator()
  33660. };
  33661. that._prepareValueIndicators = function() {
  33662. return prepareObsoleteElements(this)
  33663. };
  33664. that._disposeValueIndicators = function() {
  33665. var that = this;
  33666. _each([].concat(that._needles, that._markers, that._rangeBars), function(_, pointer) {
  33667. pointer.dispose()
  33668. });
  33669. that._needles = that._markers = that._rangeBars = null
  33670. };
  33671. that._cleanValueIndicators = function() {
  33672. _each([].concat(this._needles, this._markers, this._rangeBars), function(_, pointer) {
  33673. pointer.clean()
  33674. })
  33675. };
  33676. that.needleValue = function(index, value) {
  33677. return accessPointerValue(this, this._needles, this._needleValues, index, value)
  33678. };
  33679. that.markerValue = function(index, value) {
  33680. return accessPointerValue(this, this._markers, this._markerValues, index, value)
  33681. };
  33682. that.rangeBarValue = function(index, value) {
  33683. return accessPointerValue(this, this._rangeBars, this._rangeBarValues, index, value)
  33684. }
  33685. }
  33686. function selectHardMode(that) {
  33687. that._indicatorValues = [];
  33688. that._valueIndicators = [];
  33689. that._setupValueState = function() {
  33690. setupValues(this, '_indicatorValues', this.option('valueIndicators'))
  33691. };
  33692. that._handleValueChagned = function(name, newv, oldv) {
  33693. if (name === 'valueIndicators') {
  33694. setupValues(this, '_indicatorValues', newv);
  33695. this._invalidate();
  33696. return true
  33697. }
  33698. return false
  33699. };
  33700. that._updateActiveElements = function() {
  33701. var that = this;
  33702. _each(that._valueIndicators, function(_, valueIndicator) {
  33703. valueIndicator.value(that._indicatorValues[valueIndicator._index], that._noAnimation)
  33704. });
  33705. that._resizing || that.hideLoadingIndicator()
  33706. };
  33707. that._prepareValueIndicators = function() {
  33708. return prepareValueIndicatorsInHardMode(this)
  33709. };
  33710. that._disposeValueIndicators = function() {
  33711. _each(this._valueIndicators, function(_, valueIndicator) {
  33712. valueIndicator.dispose()
  33713. });
  33714. this._valueIndicators = null
  33715. };
  33716. that._cleanValueIndicators = function() {
  33717. _each(this._valueIndicators, function(_, valueIndicator) {
  33718. valueIndicator.clean()
  33719. })
  33720. };
  33721. that.indicatorValue = function(index, value) {
  33722. return accessPointerValue(this, this._valueIndicators, this._indicatorValues, index, value)
  33723. }
  33724. }
  33725. function prepareValueIndicatorsInHardMode(that) {
  33726. var valueIndicators = that._valueIndicators || [],
  33727. userOptions = that.option('valueIndicators'),
  33728. optionList = [],
  33729. i = 0,
  33730. ii;
  33731. for (ii = _isArray(userOptions) ? userOptions.length : 0; i < ii; ++i)
  33732. optionList.push(userOptions[i]);
  33733. for (ii = valueIndicators.length; i < ii; ++i)
  33734. optionList.push(null);
  33735. var themeSettings = that._themeManager.theme().valueIndicators,
  33736. parameters = {
  33737. renderer: that._renderer,
  33738. owner: that._root,
  33739. translator: that._translator,
  33740. tracker: that._tracker
  33741. },
  33742. newValueIndicators = [];
  33743. _each(optionList, function(i, userSettings) {
  33744. var valueIndicator = valueIndicators[i];
  33745. if (!userSettings) {
  33746. valueIndicator && valueIndicator.dispose();
  33747. return
  33748. }
  33749. var type = _String(userSettings.type || themeSettings._type).toLowerCase();
  33750. if (valueIndicator && type !== valueIndicator.type) {
  33751. valueIndicator.dispose();
  33752. valueIndicator = null
  33753. }
  33754. if (!valueIndicator) {
  33755. valueIndicator = that._createValueIndicatorInHardMode(type);
  33756. valueIndicator && valueIndicator.setup(parameters)
  33757. }
  33758. if (valueIndicator) {
  33759. var settings = _extend(true, {}, themeSettings._default, themeSettings[type], userSettings, {
  33760. type: type,
  33761. animation: that._animationSettings,
  33762. containerBackgroundColor: that._containerBackgroundColor
  33763. });
  33764. that._updateIndicatorSettings(settings);
  33765. valueIndicator.render(settings);
  33766. valueIndicator._index = i;
  33767. valueIndicator._trackerInfo = {index: i};
  33768. newValueIndicators.push(valueIndicator)
  33769. }
  33770. });
  33771. that._valueIndicators = newValueIndicators;
  33772. return that._valueIndicators
  33773. }
  33774. function prepareObsoleteElements(that) {
  33775. var rangeBars = prepareObsoletePointers(that, '_rangeBars', '_createRangeBar', {
  33776. user: that.option('rangeBars'),
  33777. common: that.option('commonRangeBarSettings'),
  33778. theme: that._themeManager.theme().valueIndicator,
  33779. preset: {},
  33780. type: 'rangebar',
  33781. className: 'dxg-value-indicator'
  33782. });
  33783. var needles = prepareObsoletePointers(that, '_needles', '_createNeedle', {
  33784. user: that.option('needles'),
  33785. common: that.option('commonNeedleSettings'),
  33786. theme: that._themeManager.theme().valueIndicator,
  33787. preset: that._getPreset().commonNeedleSettings,
  33788. className: 'dxg-value-indicator'
  33789. });
  33790. var markers = prepareObsoletePointers(that, '_markers', '_createMarker', {
  33791. user: that.option('markers'),
  33792. common: that.option('commonMarkerSettings'),
  33793. theme: that._themeManager.theme().subvalueIndicator,
  33794. preset: that._getPreset().commonMarkerSettings,
  33795. className: 'dxg-subvalue-indicator'
  33796. });
  33797. var spindle = that._prepareObsoleteSpindle && that._prepareObsoleteSpindle();
  33798. return [].concat(rangeBars, needles, markers, [spindle])
  33799. }
  33800. function prepareObsoletePointers(that, fieldName, methodName, options) {
  33801. var pointers = that[fieldName],
  33802. userOptions = [],
  33803. i = 0,
  33804. ii;
  33805. for (ii = _isArray(options.user) ? options.user.length : 0; i < ii; ++i)
  33806. userOptions.push(options.user[i]);
  33807. for (ii = pointers.length; i < ii; ++i)
  33808. userOptions.push(null);
  33809. var themeOption = options.theme,
  33810. presetOption = options.preset,
  33811. commonOption = options.common || {},
  33812. parameters = {
  33813. renderer: that._renderer,
  33814. owner: that._root,
  33815. translator: that._translator,
  33816. tracker: that._tracker,
  33817. className: options.className
  33818. },
  33819. newPointers = [];
  33820. _each(userOptions, function(i, pointerOption) {
  33821. var pointer = pointers[i];
  33822. if (!pointerOption) {
  33823. pointer && pointer.dispose();
  33824. return
  33825. }
  33826. var type = _String(pointerOption.type || commonOption.type || presetOption.type || themeOption.type).toLowerCase(),
  33827. settings;
  33828. if (pointer && pointer.type !== type) {
  33829. pointer.dispose();
  33830. pointer = null
  33831. }
  33832. if (!pointer) {
  33833. pointer = that[methodName](type);
  33834. pointer.setup(parameters)
  33835. }
  33836. if (pointer) {
  33837. type = options.type || type;
  33838. settings = _extend(true, {}, themeOption._default, themeOption[type], commonOption, pointerOption),
  33839. settings.spindleSize = null;
  33840. settings.animation = that._animationSettings;
  33841. settings.containerBackgroundColor = that._containerBackgroundColor;
  33842. that._updateIndicatorSettings(settings);
  33843. pointer.render(settings);
  33844. pointer._index = i;
  33845. pointer._trackerInfo = {index: i};
  33846. newPointers.push(pointer)
  33847. }
  33848. });
  33849. that[fieldName] = newPointers;
  33850. return newPointers
  33851. }
  33852. function accessPointerValue(that, pointers, values, index, value) {
  33853. if (value !== undefined) {
  33854. if (values[index] !== undefined) {
  33855. values[index] = that._processValue(value, values[index]);
  33856. pointers[index] && pointers[index].value(values[index]);
  33857. that._resizing || that.hideLoadingIndicator()
  33858. }
  33859. return that
  33860. }
  33861. else
  33862. return values[index]
  33863. }
  33864. function compareArrays(array1, array2) {
  33865. if (array1 === array2)
  33866. return true;
  33867. if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
  33868. for (var i = 0, ii = array1.length; i < ii; ++i)
  33869. if (_abs(array1[i] - array2[i]) > 1E-8)
  33870. return false;
  33871. return true
  33872. }
  33873. return false
  33874. }
  33875. DX.viz.gauges.__internals.ValueIndicatorsSet = DX.Class.inherit({
  33876. ctor: function(parameters) {
  33877. var that = this;
  33878. that._parameters = parameters;
  33879. that._createIndicator = that._parameters.createIndicator || _noop;
  33880. that._root = that._parameters.renderer.createGroup({'class': that._parameters.className});
  33881. that._indicatorParameters = that._indicatorParameters || {
  33882. renderer: that._parameters.renderer,
  33883. translator: that._parameters.translator,
  33884. owner: that._root,
  33885. tracker: that._parameters.tracker,
  33886. className: that._parameters.indicatorClassName
  33887. };
  33888. that._indicators = []
  33889. },
  33890. dispose: function() {
  33891. var that = this;
  33892. _each(that._indicators, function(_, indicator) {
  33893. indicator.dispose()
  33894. });
  33895. that._parameters = that._createIndicator = that._root = that._options = that._indicators = that._colorPalette = that._palette = null;
  33896. return that
  33897. },
  33898. clean: function() {
  33899. var that = this;
  33900. that._root.detach();
  33901. that._sample && that._sample.clean().dispose();
  33902. _each(that._indicators, function(_, indicator) {
  33903. indicator.clean()
  33904. });
  33905. that._sample = that._options = that._palette = null;
  33906. return that
  33907. },
  33908. render: function(options, isRecreate) {
  33909. var that = this;
  33910. that._options = options;
  33911. that._sample = that._createIndicator();
  33912. that._sample && that._sample.setup(that._indicatorParameters).render(options);
  33913. that.enabled = that._sample && that._sample.enabled;
  33914. that._palette = _isDefined(options.palette) ? new DX.viz.core.Palette(options.palette) : null;
  33915. if (that.enabled) {
  33916. that._root.append(that._parameters.owner);
  33917. that._generatePalette(that._indicators.length);
  33918. that._indicators = _map(that._indicators, function(indicator, i) {
  33919. if (isRecreate) {
  33920. indicator.dispose();
  33921. indicator = that._createIndicator();
  33922. indicator.setup(that._indicatorParameters);
  33923. indicator._trackerInfo = {
  33924. type: that._parameters.trackerType,
  33925. index: i
  33926. }
  33927. }
  33928. indicator.render(that._getIndicatorOptions(i));
  33929. return indicator
  33930. })
  33931. }
  33932. return that
  33933. },
  33934. resize: function(layout) {
  33935. var that = this;
  33936. that._layout = layout;
  33937. _each(that._indicators, function(_, indicator) {
  33938. indicator.resize(layout)
  33939. });
  33940. return that
  33941. },
  33942. measure: function(layout) {
  33943. return this._sample.measure(layout)
  33944. },
  33945. _getIndicatorOptions: function(index) {
  33946. var result = this._options;
  33947. if (this._colorPalette)
  33948. result = _extend({}, result, {color: this._colorPalette[index]});
  33949. return result
  33950. },
  33951. _generatePalette: function(count) {
  33952. var that = this,
  33953. colors = null;
  33954. if (that._palette) {
  33955. colors = [];
  33956. that._palette.reset();
  33957. var i = 0;
  33958. for (; i < count; ++i)
  33959. colors.push(that._palette.getNextColor())
  33960. }
  33961. that._colorPalette = colors
  33962. },
  33963. _adjustIndicatorsCount: function(count) {
  33964. var that = this,
  33965. indicators = that._indicators,
  33966. i,
  33967. ii,
  33968. indicatorOptions,
  33969. indicator,
  33970. indicatorsLen = indicators.length,
  33971. palette = that._parameters.palette;
  33972. if (indicatorsLen > count) {
  33973. for (i = count, ii = indicatorsLen; i < ii; ++i)
  33974. indicators[i].clean().dispose();
  33975. that._indicators = indicators.slice(0, count);
  33976. that._generatePalette(indicators.length)
  33977. }
  33978. else if (indicatorsLen < count) {
  33979. that._generatePalette(count);
  33980. for (i = indicatorsLen, ii = count; i < ii; ++i) {
  33981. indicator = that._createIndicator();
  33982. indicator.setup(that._indicatorParameters);
  33983. indicator._trackerInfo = {
  33984. type: that._parameters.trackerType,
  33985. index: i
  33986. };
  33987. indicator.render(that._getIndicatorOptions(i)).resize(that._layout);
  33988. indicators.push(indicator)
  33989. }
  33990. }
  33991. },
  33992. values: function(arg, _noAnimation) {
  33993. var that = this;
  33994. if (!that.enabled)
  33995. return;
  33996. if (arg !== undefined) {
  33997. if (!_isArray(arg))
  33998. arg = _isFinite(arg) ? [Number(arg)] : null;
  33999. if (arg) {
  34000. that._adjustIndicatorsCount(arg.length);
  34001. _each(that._indicators, function(i, indicator) {
  34002. indicator.value(arg[i], _noAnimation)
  34003. })
  34004. }
  34005. return that
  34006. }
  34007. return _map(that._indicators, function(indicator) {
  34008. return indicator.value()
  34009. })
  34010. }
  34011. })
  34012. })(DevExpress, jQuery);
  34013. /*! Module viz-gauges, file circularGauge.js */
  34014. (function(DX, $, undefined) {
  34015. var factory = DX.viz.gauges.__factory;
  34016. var isFinite = window.isFinite,
  34017. Number = window.Number,
  34018. normalizeAngle = DX.utils.normalizeAngle,
  34019. getCosAndSin = DX.utils.getCosAndSin,
  34020. abs = Math.abs,
  34021. max = Math.max,
  34022. min = Math.min,
  34023. round = Math.round,
  34024. slice = Array.prototype.slice,
  34025. $extend = $.extend,
  34026. $each = $.each;
  34027. var PI = Math.PI;
  34028. function getSides(startAngle, endAngle) {
  34029. var startCosSin = getCosAndSin(startAngle),
  34030. endCosSin = getCosAndSin(endAngle),
  34031. startCos = startCosSin.cos,
  34032. startSin = startCosSin.sin,
  34033. endCos = endCosSin.cos,
  34034. endSin = endCosSin.sin;
  34035. return {
  34036. left: startSin <= 0 && endSin >= 0 || startSin <= 0 && endSin <= 0 && startCos <= endCos || startSin >= 0 && endSin >= 0 && startCos >= endCos ? -1 : min(startCos, endCos, 0),
  34037. right: startSin >= 0 && endSin <= 0 || startSin >= 0 && endSin >= 0 && startCos >= endCos || startSin <= 0 && endSin <= 0 && startCos <= endCos ? 1 : max(startCos, endCos, 0),
  34038. up: startCos <= 0 && endCos >= 0 || startCos <= 0 && endCos <= 0 && startSin >= endSin || startCos >= 0 && endCos >= 0 && startSin <= endSin ? -1 : -max(startSin, endSin, 0),
  34039. down: startCos >= 0 && endCos <= 0 || startCos >= 0 && endCos >= 0 && startSin <= endSin || startCos <= 0 && endCos <= 0 && startSin >= endSin ? 1 : -min(startSin, endSin, 0)
  34040. }
  34041. }
  34042. DX.viz.gauges.CircularGauge = DX.viz.gauges.Gauge.inherit({
  34043. _rootClass: 'dxg-circular-gauge',
  34044. _selectMode: function() {
  34045. this.callBase.apply(this, arguments);
  34046. if (typeof this.indicatorValue === 'function')
  34047. this._createValueIndicatorInHardMode = function(type) {
  34048. return factory.createCircularValueIndicatorInHardMode(type)
  34049. }
  34050. },
  34051. _setupCodomain: function() {
  34052. var that = this,
  34053. geometry = that.option('geometry') || {},
  34054. startAngle = geometry.startAngle,
  34055. endAngle = geometry.endAngle,
  34056. sides;
  34057. startAngle = isFinite(startAngle) ? normalizeAngle(startAngle) : 225;
  34058. endAngle = isFinite(endAngle) ? normalizeAngle(endAngle) : -45;
  34059. if (abs(startAngle - endAngle) < 1) {
  34060. endAngle -= 360;
  34061. sides = {
  34062. left: -1,
  34063. up: -1,
  34064. right: 1,
  34065. down: 1
  34066. }
  34067. }
  34068. else {
  34069. startAngle < endAngle && (endAngle -= 360);
  34070. sides = getSides(startAngle, endAngle)
  34071. }
  34072. that._area = {
  34073. x: 0,
  34074. y: 0,
  34075. radius: 100,
  34076. startCoord: startAngle,
  34077. endCoord: endAngle,
  34078. scaleRadius: geometry.scaleRadius > 0 ? Number(geometry.scaleRadius) : undefined,
  34079. sides: sides
  34080. };
  34081. that._translator.setCodomain(startAngle, endAngle)
  34082. },
  34083. _measureMainElements: function(elements) {
  34084. var that = this,
  34085. maxRadius = 0,
  34086. minRadius = Infinity,
  34087. maxHorizontalOffset = 0,
  34088. maxVerticalOffset = 0,
  34089. maxInverseHorizontalOffset = 0,
  34090. maxInverseVerticalOffset = 0;
  34091. $each(elements, function(_, element) {
  34092. var bounds = element.measure({radius: that._area.radius - (Number(element._options.offset) || 0)});
  34093. bounds.min > 0 && (minRadius = min(minRadius, bounds.min));
  34094. bounds.max > 0 && (maxRadius = max(maxRadius, bounds.max));
  34095. bounds.horizontalOffset > 0 && (maxHorizontalOffset = max(maxHorizontalOffset, bounds.max + bounds.horizontalOffset));
  34096. bounds.verticalOffset > 0 && (maxVerticalOffset = max(maxVerticalOffset, bounds.max + bounds.verticalOffset));
  34097. bounds.inverseHorizontalOffset > 0 && (maxInverseHorizontalOffset = max(maxInverseHorizontalOffset, bounds.inverseHorizontalOffset));
  34098. bounds.inverseVerticalOffset > 0 && (maxInverseVerticalOffset = max(maxInverseVerticalOffset, bounds.inverseVerticalOffset))
  34099. });
  34100. maxHorizontalOffset = max(maxHorizontalOffset - maxRadius, 0);
  34101. maxVerticalOffset = max(maxVerticalOffset - maxRadius, 0);
  34102. return {
  34103. minRadius: minRadius,
  34104. maxRadius: maxRadius,
  34105. horizontalMargin: maxHorizontalOffset,
  34106. verticalMargin: maxVerticalOffset,
  34107. inverseHorizontalMargin: maxInverseHorizontalOffset,
  34108. inverseVerticalMargin: maxInverseVerticalOffset
  34109. }
  34110. },
  34111. _applyMainLayout: function(elements) {
  34112. var that = this,
  34113. measurements = that._measureMainElements(elements),
  34114. area = that._area,
  34115. sides = area.sides,
  34116. margins = {
  34117. left: (sides.left < -0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
  34118. right: (sides.right > 0.1 ? measurements.horizontalMargin : measurements.inverseHorizontalMargin) || 0,
  34119. top: (sides.up < -0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0,
  34120. bottom: (sides.down > 0.1 ? measurements.verticalMargin : measurements.inverseVerticalMargin) || 0
  34121. },
  34122. rect = that._layoutManager.selectRectByAspectRatio((sides.down - sides.up) / (sides.right - sides.left), margins),
  34123. radius = min(rect.width() / (sides.right - sides.left), rect.height() / (sides.down - sides.up)),
  34124. x,
  34125. y;
  34126. var scaler = (measurements.maxRadius - area.radius + area.scaleRadius) / radius;
  34127. if (0 < scaler && scaler < 1) {
  34128. rect = rect.scale(scaler);
  34129. radius *= scaler
  34130. }
  34131. radius = radius - measurements.maxRadius + area.radius;
  34132. x = rect.left - rect.width() * sides.left / (sides.right - sides.left);
  34133. y = rect.top - rect.height() * sides.up / (sides.down - sides.up);
  34134. area.x = round(x);
  34135. area.y = round(y);
  34136. area.radius = radius;
  34137. rect.left -= margins.left;
  34138. rect.right += margins.right;
  34139. rect.top -= margins.top;
  34140. rect.bottom += margins.bottom;
  34141. that._layoutManager.setRect(rect)
  34142. },
  34143. _updateElementPosition: function(element) {
  34144. element.resize({
  34145. x: this._area.x,
  34146. y: this._area.y,
  34147. radius: round(this._area.radius - (Number(element._options.offset) || 0))
  34148. })
  34149. },
  34150. _createScale: function(parameters) {
  34151. return factory.createCircularScale(parameters)
  34152. },
  34153. _createRangeContainer: function(parameters) {
  34154. return factory.createCircularRangeContainer(parameters)
  34155. },
  34156. _createValueIndicator: function(type) {
  34157. return factory.createCircularValueIndicator(type)
  34158. },
  34159. _createSubvalueIndicator: function(type) {
  34160. return factory.createCircularSubvalueIndicator(type)
  34161. },
  34162. _getApproximateScreenRange: function() {
  34163. var that = this,
  34164. area = that._area,
  34165. r = min(that._width / (area.sides.right - area.sides.left), that._height / (area.sides.down - area.sides.up));
  34166. r > area.totalRadius && (r = area.totalRadius);
  34167. r = 0.8 * r;
  34168. return -that._translator.getCodomainRange() * r * PI / 180
  34169. },
  34170. _getDefaultContainerSize: function() {
  34171. return {
  34172. width: 300,
  34173. height: 300
  34174. }
  34175. },
  34176. _getPreset: function() {
  34177. var preset = this.option('preset'),
  34178. result;
  34179. if (preset === 'preset2')
  34180. result = {
  34181. commonNeedleSettings: {type: 'twocolorrectangle'},
  34182. commonMarkerSettings: {type: 'triangle'}
  34183. };
  34184. else if (preset === 'preset3')
  34185. result = {
  34186. commonNeedleSettings: {type: 'rectangle'},
  34187. commonMarkerSettings: {type: 'triangle'}
  34188. };
  34189. else
  34190. result = {
  34191. commonNeedleSettings: {type: 'rectangle'},
  34192. commonMarkerSettings: {type: 'textcloud'}
  34193. };
  34194. return result
  34195. },
  34196. _createNeedle: function(type) {
  34197. return factory.createCircularNeedle(type)
  34198. },
  34199. _createMarker: function(type) {
  34200. return factory.createCircularMarker(type)
  34201. },
  34202. _createRangeBar: function() {
  34203. return factory.createCircularRangeBar()
  34204. },
  34205. _prepareObsoleteSpindle: function() {
  34206. var that = this,
  34207. spindleOption = that.option('spindle') || {},
  34208. visible = that._needles && ('visible' in spindleOption ? !!spindleOption.visible : true);
  34209. if (visible) {
  34210. var themeOption = that._themeManager.theme().valueIndicator._default,
  34211. size = spindleOption.size || themeOption.spindleSize;
  34212. visible = size > 0
  34213. }
  34214. if (visible) {
  34215. var gapSize = spindleOption.gapSize || themeOption.spindleGapSize,
  34216. color = spindleOption.color || themeOption.color;
  34217. gapSize = gapSize <= size ? gapSize : size;
  34218. that._spindle = that._spindle || that._renderer.createGroup({'class': 'dxg-value-indicator'});
  34219. that._spindle.append(that._root);
  34220. that._spindleOuter = that._spindleOuter || that._renderer.createCircle(0, 0, 0, {
  34221. 'class': 'dxg-spindle-border',
  34222. stroke: 'none',
  34223. strokeWidth: 0
  34224. }).append(that._spindle);
  34225. that._spindleInner = that._spindleInner || that._renderer.createCircle(0, 0, 0, {
  34226. 'class': 'dxg-spindle-hole',
  34227. stroke: 'none',
  34228. strokeWidth: 0
  34229. }).append(that._spindle);
  34230. that._spindleOuter.applySettings({
  34231. cx: that._area.x,
  34232. cy: that._area.y,
  34233. r: size / 2,
  34234. fill: color
  34235. });
  34236. that._spindleInner.applySettings({
  34237. cx: that._area.x,
  34238. cy: that._area.y,
  34239. r: gapSize / 2,
  34240. fill: that._containerBackgroundColor
  34241. });
  34242. return {
  34243. enabled: true,
  34244. _options: {offset: 0},
  34245. measure: function(layout) {
  34246. return {}
  34247. },
  34248. resize: function(layout) {
  34249. that._spindleOuter.applySettings({
  34250. cx: layout.x,
  34251. cy: layout.y
  34252. });
  34253. that._spindleInner.applySettings({
  34254. cx: layout.x,
  34255. cy: layout.y
  34256. });
  34257. return that
  34258. }
  34259. }
  34260. }
  34261. else {
  34262. that._spindle && that._spindle.remove();
  34263. delete that._spindle;
  34264. delete that._spindleOuter;
  34265. delete that._spindleInner;
  34266. return null
  34267. }
  34268. }
  34269. });
  34270. DX.viz.gauges.CircularGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  34271. DX.viz.gauges.CircularGauge.prototype._factory.createThemeManager = function() {
  34272. var themeManager = new DX.viz.gauges.__internals.ThemeManager;
  34273. themeManager._subTheme = '_circular';
  34274. return themeManager
  34275. }
  34276. })(DevExpress, jQuery);
  34277. /*! Module viz-gauges, file linearGauge.js */
  34278. (function(DX, $, undefined) {
  34279. var factory = DX.viz.gauges.__factory;
  34280. var _String = String,
  34281. _Number = Number,
  34282. max = Math.max,
  34283. min = Math.min,
  34284. round = Math.round,
  34285. slice = Array.prototype.slice,
  34286. $extend = $.extend,
  34287. $each = $.each;
  34288. DX.viz.gauges.LinearGauge = DX.viz.gauges.Gauge.inherit({
  34289. _rootClass: 'dxg-linear-gauge',
  34290. _selectMode: function() {
  34291. this.callBase.apply(this, arguments);
  34292. if (typeof this.indicatorValue === 'function')
  34293. this._createValueIndicatorInHardMode = function(type) {
  34294. return factory.createLinearValueIndicatorInHardMode(type)
  34295. }
  34296. },
  34297. _setupCodomain: function() {
  34298. var that = this,
  34299. geometry = that.option('geometry') || {},
  34300. vertical = _String(geometry.orientation).toLowerCase() === 'vertical';
  34301. that._area = {
  34302. vertical: vertical,
  34303. x: 0,
  34304. y: 0,
  34305. startCoord: -100,
  34306. endCoord: 100,
  34307. scaleSize: geometry.scaleSize > 0 ? _Number(geometry.scaleSize) : undefined
  34308. };
  34309. that._scale.vertical = vertical;
  34310. that._rangeContainer.vertical = vertical
  34311. },
  34312. _measureMainElements: function(elements) {
  34313. var that = this,
  34314. minBound = 1000,
  34315. maxBound = 0,
  34316. indent = 0;
  34317. $each(elements, function(_, element) {
  34318. var bounds = element.measure({
  34319. x: that._area.x + (_Number(element._options.offset) || 0),
  34320. y: that._area.y + (_Number(element._options.offset) || 0)
  34321. });
  34322. maxBound = max(maxBound, bounds.max);
  34323. minBound = min(minBound, bounds.min);
  34324. bounds.indent > 0 && (indent = max(indent, bounds.indent))
  34325. });
  34326. return {
  34327. minBound: minBound,
  34328. maxBound: maxBound,
  34329. indent: indent
  34330. }
  34331. },
  34332. _applyMainLayout: function(elements) {
  34333. var that = this,
  34334. measurements = that._measureMainElements(elements),
  34335. area = that._area,
  34336. rect,
  34337. offset,
  34338. counterSize = area.scaleSize + 2 * measurements.indent;
  34339. if (area.vertical) {
  34340. rect = that._layoutManager.selectRectBySizes({
  34341. width: measurements.maxBound - measurements.minBound,
  34342. height: counterSize
  34343. });
  34344. offset = rect.horizontalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
  34345. area.startCoord = rect.bottom - measurements.indent;
  34346. area.endCoord = rect.top + measurements.indent;
  34347. area.x = round(area.x + offset)
  34348. }
  34349. else {
  34350. rect = that._layoutManager.selectRectBySizes({
  34351. height: measurements.maxBound - measurements.minBound,
  34352. width: counterSize
  34353. });
  34354. offset = rect.verticalMiddle() - (measurements.minBound + measurements.maxBound) / 2;
  34355. area.startCoord = rect.left + measurements.indent;
  34356. area.endCoord = rect.right - measurements.indent;
  34357. area.y = round(area.y + offset)
  34358. }
  34359. that._translator.setCodomain(area.startCoord, area.endCoord);
  34360. that._layoutManager.setRect(rect)
  34361. },
  34362. _updateElementPosition: function(element) {
  34363. element.resize({
  34364. x: round(this._area.x + (_Number(element._options.offset) || 0)),
  34365. y: round(this._area.y + (_Number(element._options.offset) || 0))
  34366. })
  34367. },
  34368. _createScale: function(parameters) {
  34369. return factory.createLinearScale(parameters)
  34370. },
  34371. _createRangeContainer: function(parameters) {
  34372. return factory.createLinearRangeContainer(parameters)
  34373. },
  34374. _createValueIndicator: function(type) {
  34375. return factory.createLinearValueIndicator(type)
  34376. },
  34377. _createSubvalueIndicator: function(type) {
  34378. return factory.createLinearSubvalueIndicator(type)
  34379. },
  34380. _getApproximateScreenRange: function() {
  34381. var that = this,
  34382. area = that._area,
  34383. s = area.vertical ? that._height : that._width;
  34384. s > area.totalSize && (s = area.totalSize);
  34385. s = s * 0.8;
  34386. return s
  34387. },
  34388. _getDefaultContainerSize: function() {
  34389. var geometry = this.option('geometry') || {};
  34390. if (geometry.orientation === 'vertical')
  34391. return {
  34392. width: 100,
  34393. height: 300
  34394. };
  34395. else
  34396. return {
  34397. width: 300,
  34398. height: 100
  34399. }
  34400. },
  34401. _getPreset: function() {
  34402. var preset = this.option('preset'),
  34403. result;
  34404. if (preset === 'preset2')
  34405. result = {
  34406. commonNeedleSettings: {type: 'rhombus'},
  34407. commonMarkerSettings: {type: 'triangle'}
  34408. };
  34409. else
  34410. result = {
  34411. commonNeedleSettings: {type: 'circle'},
  34412. commonMarkerSettings: {type: 'textcloud'}
  34413. };
  34414. return result
  34415. },
  34416. _createNeedle: function(type) {
  34417. return factory.createLinearNeedle(type)
  34418. },
  34419. _createMarker: function(type) {
  34420. return factory.createLinearMarker(type)
  34421. },
  34422. _createRangeBar: function() {
  34423. return factory.createLinearRangeBar()
  34424. }
  34425. });
  34426. DX.viz.gauges.LinearGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  34427. DX.viz.gauges.LinearGauge.prototype._factory.createThemeManager = function() {
  34428. var themeManager = new DX.viz.gauges.__internals.ThemeManager;
  34429. themeManager._subTheme = '_linear';
  34430. return themeManager
  34431. }
  34432. })(DevExpress, jQuery);
  34433. /*! Module viz-gauges, file barGauge.js */
  34434. (function(DX, $, undefined) {
  34435. var PI = Math.PI;
  34436. var _Number = window.Number,
  34437. _isFinite = window.isFinite,
  34438. _abs = Math.abs,
  34439. _round = Math.round,
  34440. _floor = Math.floor,
  34441. _min = Math.min,
  34442. _max = Math.max,
  34443. _isArray = DX.utils.isArray,
  34444. _convertAngleToRendererSpace = DX.utils.convertAngleToRendererSpace,
  34445. _getCosAndSin = DX.utils.getCosAndSin,
  34446. _noop = $.noop,
  34447. _extend = $.extend,
  34448. _getSampleText = DX.viz.gauges.__internals.getSampleText,
  34449. _formatValue = DX.viz.gauges.__internals.formatValue;
  34450. var _Rectangle = DX.viz.core.Rectangle,
  34451. _Palette = DX.viz.core.Palette;
  34452. DX.viz.gauges.BarGauge = DX.viz.gauges.__internals.BaseGauge.inherit({
  34453. _rootClass: 'dxbg-bar-gauge',
  34454. _init: function() {
  34455. var that = this;
  34456. that.callBase.apply(that, arguments);
  34457. that._barsGroup = that._renderer.createGroup({'class': 'dxbg-bars'});
  34458. that._values = [];
  34459. that._context = {
  34460. renderer: that._renderer,
  34461. translator: that._translator,
  34462. tracker: that._tracker,
  34463. group: that._barsGroup
  34464. };
  34465. that._animateStep = function(pos) {
  34466. var bars = that._bars,
  34467. i = 0,
  34468. ii = bars.length;
  34469. for (; i < ii; ++i)
  34470. bars[i].animate(pos)
  34471. };
  34472. that._animateComplete = function() {
  34473. var bars = that._bars,
  34474. i = 0,
  34475. ii = bars.length;
  34476. for (; i < ii; ++i)
  34477. bars[i].endAnimation()
  34478. }
  34479. },
  34480. _dispose: function() {
  34481. var that = this;
  34482. that.callBase.apply(that, arguments);
  34483. that._barsGroup = that._values = that._context = that._animateStep = that._animateComplete = null
  34484. },
  34485. _setupDomain: function() {
  34486. var that = this,
  34487. startValue = that.option('startValue'),
  34488. endValue = that.option('endValue');
  34489. _isFinite(startValue) || (startValue = 0);
  34490. _isFinite(endValue) || (endValue = 100);
  34491. that._translator.setDomain(startValue, endValue);
  34492. that._baseValue = that._translator.adjust(that.option('baseValue'));
  34493. _isFinite(that._baseValue) || (that._baseValue = startValue < endValue ? startValue : endValue)
  34494. },
  34495. _calculateSizeCore: function() {
  34496. var that = this,
  34497. size = that.option('size') || {};
  34498. if (_Number(size.width) === 0 || _Number(size.height) === 0) {
  34499. that._width = that._height = 0;
  34500. that._rootRect = new _Rectangle
  34501. }
  34502. else {
  34503. that._width = size.width > 0 ? _Number(size.width) : that._element().width() || 300;
  34504. that._height = size.height > 0 ? _Number(size.height) : that._element().height() || 300;
  34505. that._rootRect = new _Rectangle({
  34506. left: 0,
  34507. top: 0,
  34508. right: that._width,
  34509. bottom: that._height
  34510. })
  34511. }
  34512. },
  34513. _setupCodomain: DX.viz.gauges.CircularGauge.prototype._setupCodomain,
  34514. _getApproximateScreenRange: function() {
  34515. var that = this,
  34516. sides = that._area.sides,
  34517. width = that._width / (sides.right - sides.left),
  34518. height = that._height / (sides.down - sides.up),
  34519. r = width < height ? width : height;
  34520. return -that._translator.getCodomainRange() * r * PI / 180
  34521. },
  34522. _setupAnimationSettings: function() {
  34523. this.callBase();
  34524. if (this._animationSettings)
  34525. _extend(this._animationSettings, {
  34526. step: this._animateStep,
  34527. complete: this._animateComplete
  34528. })
  34529. },
  34530. _cleanContent: function() {
  34531. var that = this;
  34532. that._barsGroup.detach();
  34533. that._animationSettings && that._barsGroup.stopAnimation();
  34534. var i = 0,
  34535. ii = that._bars ? that._bars.length : 0;
  34536. for (; i < ii; ++i)
  34537. that._bars[i].dispose();
  34538. that._palette = that._bars = null
  34539. },
  34540. _renderContent: function() {
  34541. var that = this,
  34542. labelOptions = that.option('label');
  34543. that._barsGroup.append(that._root);
  34544. that._context.textEnabled = labelOptions === undefined || labelOptions && (!('visible' in labelOptions) || labelOptions.visible);
  34545. if (that._context.textEnabled) {
  34546. that._context.textColor = labelOptions && labelOptions.font && labelOptions.font.color || null;
  34547. labelOptions = _extend(true, {}, that._themeManager.theme().label, labelOptions);
  34548. that._context.formatOptions = {
  34549. format: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.format : that._defaultFormatOptions.format,
  34550. precision: labelOptions.format !== undefined || labelOptions.precision !== undefined ? labelOptions.precision : that._defaultFormatOptions.precision,
  34551. customizeText: labelOptions.customizeText
  34552. };
  34553. that._context.textOptions = {
  34554. font: _extend({}, that._themeManager.theme().label.font, labelOptions.font, {color: null}),
  34555. align: 'center'
  34556. };
  34557. that._textIndent = labelOptions.indent > 0 ? _Number(labelOptions.indent) : 0;
  34558. that._context.lineWidth = labelOptions.connectorWidth > 0 ? _Number(labelOptions.connectorWidth) : 0;
  34559. that._context.lineColor = labelOptions.connectorColor || null;
  34560. var text = that._renderer.createText(_getSampleText(that._translator, that._context.formatOptions), 0, 0, that._context.textOptions).append(that._barsGroup),
  34561. bbox = text.getBBox();
  34562. text.detach();
  34563. that._context.textVerticalOffset = -bbox.y - bbox.height / 2;
  34564. that._context.textWidth = bbox.width;
  34565. that._context.textHeight = bbox.height
  34566. }
  34567. DX.viz.gauges.CircularGauge.prototype._applyMainLayout.call(that);
  34568. that._renderBars()
  34569. },
  34570. _measureMainElements: function() {
  34571. var result = {maxRadius: this._area.radius};
  34572. if (this._context.textEnabled) {
  34573. result.horizontalMargin = this._context.textWidth;
  34574. result.verticalMargin = this._context.textHeight
  34575. }
  34576. return result
  34577. },
  34578. _renderBars: function() {
  34579. var that = this,
  34580. options = _extend({}, that._themeManager.theme(), that.option());
  34581. that._palette = new _Palette(options.palette, {
  34582. stepHighlight: 50,
  34583. theme: that._themeManager.themeName()
  34584. });
  34585. var relativeInnerRadius = options.relativeInnerRadius > 0 && options.relativeInnerRadius < 1 ? _Number(options.relativeInnerRadius) : 0.1,
  34586. radius = that._area.radius;
  34587. if (that._context.textEnabled) {
  34588. that._textIndent = _round(_min(that._textIndent, radius / 2));
  34589. radius -= that._textIndent
  34590. }
  34591. that._outerRadius = _round(radius);
  34592. that._innerRadius = _round(radius * relativeInnerRadius);
  34593. that._barSpacing = options.barSpacing > 0 ? _Number(options.barSpacing) : 0;
  34594. _extend(that._context, {
  34595. backgroundColor: options.backgroundColor,
  34596. x: that._area.x,
  34597. y: that._area.y,
  34598. startAngle: that._area.startCoord,
  34599. endAngle: that._area.endCoord,
  34600. baseAngle: that._translator.translate(that._baseValue)
  34601. });
  34602. that._bars = [];
  34603. that._updateValues(that.option('values'))
  34604. },
  34605. _arrangeBars: function(count) {
  34606. var that = this,
  34607. radius = that._outerRadius - that._innerRadius;
  34608. that._context.barSize = count > 0 ? _max((radius - (count - 1) * that._barSpacing) / count, 1) : 0;
  34609. var spacing = count > 1 ? _max(_min((radius - count * that._context.barSize) / (count - 1), that._barSpacing), 0) : 0,
  34610. _count = _min(_floor((radius + spacing) / that._context.barSize), count);
  34611. that._setBarsCount(_count);
  34612. radius = that._outerRadius;
  34613. that._context.textRadius = radius + that._textIndent;
  34614. that._palette.reset();
  34615. var unitOffset = that._context.barSize + spacing,
  34616. i = 0;
  34617. for (; i < _count; ++i, radius -= unitOffset)
  34618. that._bars[i].arrange({
  34619. radius: radius,
  34620. color: that._palette.getNextColor()
  34621. })
  34622. },
  34623. _setBarsCount: function(count) {
  34624. var that = this,
  34625. i,
  34626. ii;
  34627. if (that._bars.length > count) {
  34628. for (i = count, ii = that._bars.length; i < ii; ++i)
  34629. that._bars[i].dispose();
  34630. that._bars.splice(count, ii - count)
  34631. }
  34632. else if (that._bars.length < count)
  34633. for (i = that._bars.length, ii = count; i < ii; ++i)
  34634. that._bars.push(new BarWrapper(i, that._context));
  34635. if (that._bars.length > 0) {
  34636. if (that._dummyBackground) {
  34637. that._dummyBackground.detach();
  34638. that._dummyBackground = null
  34639. }
  34640. }
  34641. else {
  34642. if (!that._dummyBackground)
  34643. that._dummyBackground = that._renderer.createArc().append(that._barsGroup);
  34644. that._dummyBackground.applySettings({
  34645. x: that._context.x,
  34646. y: that._context.y,
  34647. outerRadius: that._outerRadius,
  34648. innerRadius: that._innerRadius,
  34649. startAngle: that._context.endAngle,
  34650. endAngle: that._context.startAngle,
  34651. fill: that._context.backgroundColor
  34652. })
  34653. }
  34654. },
  34655. _updateBars: function() {
  34656. var that = this,
  34657. i = 0,
  34658. ii = that._bars.length;
  34659. for (; i < ii; ++i)
  34660. that._bars[i].setValue(that._values[i])
  34661. },
  34662. _animateBars: function() {
  34663. var that = this,
  34664. i = 0,
  34665. ii = that._bars.length;
  34666. if (ii > 0) {
  34667. for (; i < ii; ++i)
  34668. that._bars[i].beginAnimation(that._values[i]);
  34669. that._barsGroup.animate({_: 0}, that._animationSettings)
  34670. }
  34671. },
  34672. _updateValues: function(values, noAnimation) {
  34673. var that = this,
  34674. list = _isArray(values) && values || _isFinite(values) && [values] || [],
  34675. i = 0,
  34676. ii = list.length,
  34677. value;
  34678. that._values = [];
  34679. for (; i < ii; ++i) {
  34680. value = that._translator.adjust(list[i]);
  34681. _isFinite(value) && that._values.push(value)
  34682. }
  34683. that._animationSettings && that._barsGroup.stopAnimation();
  34684. if (that._bars) {
  34685. that._arrangeBars(that._values.length);
  34686. if (that._animationSettings && !that._noAnimation)
  34687. that._animateBars();
  34688. else
  34689. that._updateBars()
  34690. }
  34691. if (!that._resizing) {
  34692. that.option('values', that._values);
  34693. that.hideLoadingIndicator()
  34694. }
  34695. },
  34696. values: function(arg) {
  34697. if (arg !== undefined) {
  34698. this._updateValues(arg);
  34699. return this
  34700. }
  34701. else
  34702. return this._values.slice(0)
  34703. },
  34704. _optionChanged: function(name, newValue, oldValue) {
  34705. switch (name) {
  34706. case'values':
  34707. this._updateValues(newValue);
  34708. break;
  34709. default:
  34710. this.callBase.apply(this, arguments);
  34711. break
  34712. }
  34713. },
  34714. _optionValuesEqual: function(name, oldValue, newValue) {
  34715. switch (name) {
  34716. case'values':
  34717. return compareArrays(oldValue, newValue);
  34718. default:
  34719. return this.callBase.apply(this, arguments)
  34720. }
  34721. }
  34722. });
  34723. var ThemeManager = DX.viz.gauges.__internals.ThemeManager.inherit({
  34724. _themeSection: 'barGauge',
  34725. _initializeTheme: function() {
  34726. var that = this;
  34727. that._initializeFont(that._theme.label.font);
  34728. that._initializeFont(that._theme.title.font);
  34729. that._initializeFont(that._theme.tooltip.font);
  34730. that._initializeFont(that._theme.loadingIndicator.font)
  34731. }
  34732. });
  34733. DX.viz.gauges.BarGauge.prototype._factory = DX.utils.clone(DX.viz.gauges.__internals.BaseGauge.prototype._factory);
  34734. DX.viz.gauges.BarGauge.prototype._factory.createThemeManager = function() {
  34735. return new ThemeManager
  34736. };
  34737. function BarWrapper(index, context) {
  34738. var that = this;
  34739. that._context = context;
  34740. that._background = context.renderer.createArc().append(context.group);
  34741. that._background.applySettings({fill: context.backgroundColor});
  34742. that._bar = context.renderer.createArc().append(context.group);
  34743. if (context.textEnabled) {
  34744. that._line = context.renderer.createPath([], {strokeWidth: context.lineWidth}).append(context.group);
  34745. that._text = context.renderer.createText('', 0, 0, context.textOptions).append(context.group)
  34746. }
  34747. that._tracker = context.renderer.createArc();
  34748. context.tracker.attach(that._tracker, that, {index: index});
  34749. that._index = index;
  34750. that._angle = context.baseAngle;
  34751. that._settings = {
  34752. x: context.x,
  34753. y: context.y,
  34754. startAngle: context.baseAngle,
  34755. endAngle: context.baseAngle
  34756. }
  34757. }
  34758. _extend(BarWrapper.prototype, {
  34759. dispose: function() {
  34760. var that = this;
  34761. that._background.detach();
  34762. that._bar.detach();
  34763. if (that._context.textEnabled) {
  34764. that._line.detach();
  34765. that._text.detach()
  34766. }
  34767. that._context.tracker.detach(that._tracker);
  34768. that._context = that._settings = that._background = that._bar = that._line = that._text = that._tracker = null;
  34769. return that
  34770. },
  34771. arrange: function(options) {
  34772. var that = this;
  34773. that._settings.outerRadius = options.radius;
  34774. that._settings.innerRadius = options.radius - that._context.barSize;
  34775. that._background.applySettings(_extend({}, that._settings, {
  34776. startAngle: that._context.endAngle,
  34777. endAngle: that._context.startAngle
  34778. }));
  34779. that._bar.applySettings(that._settings);
  34780. that._tracker.applySettings(that._settings);
  34781. that._color = options.color;
  34782. that._bar.applySettings({fill: options.color});
  34783. if (that._context.textEnabled) {
  34784. that._line.applySettings({
  34785. points: [that._context.x, that._context.y - that._settings.innerRadius, that._context.x, that._context.y - that._context.textRadius],
  34786. stroke: that._context.lineColor || options.color
  34787. });
  34788. that._text.applySettings({font: {color: that._context.textColor || options.color}})
  34789. }
  34790. return that
  34791. },
  34792. getTooltipParameters: function() {
  34793. var that = this,
  34794. cossin = _getCosAndSin((that._angle + that._context.baseAngle) / 2);
  34795. return {
  34796. x: _round(that._context.x + (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.cos),
  34797. y: _round(that._context.y - (that._settings.outerRadius + that._settings.innerRadius) / 2 * cossin.sin),
  34798. offset: 0,
  34799. color: that._color,
  34800. value: that._value
  34801. }
  34802. },
  34803. setAngle: function(angle) {
  34804. var that = this;
  34805. that._angle = angle;
  34806. setAngles(that._settings, that._context.baseAngle, that._angle);
  34807. that._bar.applySettings(that._settings);
  34808. that._tracker.applySettings(that._settings);
  34809. if (that._context.textEnabled) {
  34810. that._line.rotate(_convertAngleToRendererSpace(that._angle), that._context.x, that._context.y);
  34811. var cossin = _getCosAndSin(that._angle);
  34812. that._text.applySettings({
  34813. text: _formatValue(that._value, that._context.formatOptions, {index: that._index}),
  34814. x: that._context.x + (that._context.textRadius + that._context.textWidth * 0.6) * cossin.cos,
  34815. y: that._context.y - (that._context.textRadius + that._context.textHeight * 0.6) * cossin.sin + that._context.textVerticalOffset
  34816. })
  34817. }
  34818. return that
  34819. },
  34820. setValue: function(value) {
  34821. this._value = value;
  34822. return this.setAngle(this._context.translator.translate(value))
  34823. },
  34824. beginAnimation: function(value) {
  34825. var that = this;
  34826. that._value = value;
  34827. var angle = that._context.translator.translate(value);
  34828. if (!compareFloats(that._angle, angle)) {
  34829. that._start = that._angle;
  34830. that._delta = angle - that._angle;
  34831. that._tracker.applySettings({visibility: 'hidden'});
  34832. if (that._context.textEnabled) {
  34833. that._line.applySettings({visibility: 'hidden'});
  34834. that._text.applySettings({visibility: 'hidden'})
  34835. }
  34836. }
  34837. else
  34838. that.animate = _noop
  34839. },
  34840. animate: function(pos) {
  34841. var that = this;
  34842. that._angle = that._start + that._delta * pos;
  34843. setAngles(that._settings, that._context.baseAngle, that._angle);
  34844. that._bar.applySettings(that._settings)
  34845. },
  34846. endAnimation: function() {
  34847. var that = this;
  34848. if (that._delta !== undefined) {
  34849. if (compareFloats(that._angle, that._start + that._delta)) {
  34850. that._tracker.applySettings({visibility: null});
  34851. if (that._context.textEnabled) {
  34852. that._line.applySettings({visibility: null});
  34853. that._text.applySettings({visibility: null})
  34854. }
  34855. that.setAngle(that._angle)
  34856. }
  34857. }
  34858. else
  34859. delete that.animate;
  34860. delete that._start;
  34861. delete that._delta
  34862. }
  34863. });
  34864. function setAngles(target, angle1, angle2) {
  34865. target.startAngle = angle1 < angle2 ? angle1 : angle2;
  34866. target.endAngle = angle1 < angle2 ? angle2 : angle1
  34867. }
  34868. function compareFloats(value1, value2) {
  34869. return _abs(value1 - value2) < 0.0001
  34870. }
  34871. function compareArrays(array1, array2) {
  34872. if (array1 === array2)
  34873. return true;
  34874. if (_isArray(array1) && _isArray(array2) && array1.length === array2.length) {
  34875. for (var i = 0, ii = array1.length; i < ii; ++i)
  34876. if (!compareFloats(array1[i], array2[i]))
  34877. return false;
  34878. return true
  34879. }
  34880. return false
  34881. }
  34882. var __BarWrapper = BarWrapper;
  34883. DX.viz.gauges.__tests.BarWrapper = __BarWrapper;
  34884. DX.viz.gauges.__tests.stubBarWrapper = function(barWrapperType) {
  34885. BarWrapper = barWrapperType
  34886. };
  34887. DX.viz.gauges.__tests.restoreBarWrapper = function() {
  34888. BarWrapper = __BarWrapper
  34889. };
  34890. DX.registerComponent('dxBarGauge', DX.viz.gauges.BarGauge)
  34891. })(DevExpress, jQuery);
  34892. /*! Module viz-gauges, file tracker.js */
  34893. (function(DX, $, undefined) {
  34894. var _setTimeout = window.setTimeout,
  34895. _clearTimeout = window.clearTimeout,
  34896. _extend = $.extend,
  34897. _abs = Math.abs;
  34898. var TOOLTIP_SHOW_DELAY = 300,
  34899. TOOLTIP_HIDE_DELAY = 300,
  34900. TOOLTIP_TOUCH_SHOW_DELAY = 400,
  34901. TOOLTIP_TOUCH_HIDE_DELAY = 300;
  34902. DX.viz.gauges.__internals.Tracker = DX.Class.inherit({
  34903. ctor: function(parameters) {
  34904. DX.utils.debug.assertParam(parameters, 'parameters');
  34905. DX.utils.debug.assertParam(parameters.renderer, 'parameters.renderer');
  34906. DX.utils.debug.assertParam(parameters.container, 'parameters.container');
  34907. var that = this;
  34908. that._container = parameters.container;
  34909. that._element = parameters.renderer.createGroup({
  34910. 'class': 'dxg-tracker',
  34911. stroke: 'none',
  34912. strokeWidth: 0,
  34913. fill: '#000000',
  34914. opacity: 0.0001
  34915. });
  34916. that._showTooltipCallback = function() {
  34917. that._showTooltipTimeout = null;
  34918. var target = that._tooltipEvent.target;
  34919. that._targetEvent = null;
  34920. if (that._tooltipTarget !== target) {
  34921. that._tooltipTarget = target;
  34922. that._callbacks['tooltip-show']()
  34923. }
  34924. };
  34925. that._hideTooltipCallback = function() {
  34926. that._hideTooltipTimeout = null;
  34927. that._targetEvent = null;
  34928. if (that._tooltipTarget) {
  34929. that._callbacks['tooltip-hide']();
  34930. that._tooltipTarget = null
  34931. }
  34932. };
  34933. that._dispose = function() {
  34934. that._showTooltipCallback = that._hideTooltipCallback = that._dispose = null
  34935. };
  34936. that._DEBUG_showTooltipTimeoutSet = that._DEBUG_showTooltipTimeoutCleared = that._DEBUG_hideTooltipTimeoutSet = that._DEBUG_hideTooltipTimeoutCleared = 0
  34937. },
  34938. dispose: function() {
  34939. var that = this;
  34940. that._dispose();
  34941. that.deactivate();
  34942. that._element.off();
  34943. that._container = that._element = that._context = that._callbacks = null;
  34944. return that
  34945. },
  34946. activate: function() {
  34947. this._element.append(this._container);
  34948. return this
  34949. },
  34950. deactivate: function() {
  34951. this._element.detach();
  34952. this._element.clear();
  34953. return this
  34954. },
  34955. attach: function(element, target, info) {
  34956. element.data({
  34957. target: target,
  34958. info: info
  34959. });
  34960. element.append(this._element);
  34961. return this
  34962. },
  34963. detach: function(element) {
  34964. element.detach();
  34965. element.removeData();
  34966. return this
  34967. },
  34968. setTooltipState: function(state) {
  34969. var that = this,
  34970. data;
  34971. that._element.off(tooltipMouseEvents).off(tooltipTouchEvents);
  34972. if (state) {
  34973. data = {tracker: that};
  34974. that._element.on(tooltipMouseEvents, data).on(tooltipTouchEvents, data)
  34975. }
  34976. return that
  34977. },
  34978. setCallbacks: function(callbacks) {
  34979. this._callbacks = callbacks;
  34980. return this
  34981. },
  34982. _showTooltip: function(event, delay) {
  34983. var that = this,
  34984. data = $(event.target).data();
  34985. if (that._tooltipTarget === event.target || that._callbacks['tooltip-prepare'](data.target, data.info)) {
  34986. that._hideTooltipTimeout && ++that._DEBUG_hideTooltipTimeoutCleared;
  34987. _clearTimeout(that._hideTooltipTimeout);
  34988. that._hideTooltipTimeout = null;
  34989. _clearTimeout(that._showTooltipTimeout);
  34990. that._tooltipEvent = event;
  34991. ++that._DEBUG_showTooltipTimeoutSet;
  34992. that._showTooltipTimeout = _setTimeout(that._showTooltipCallback, delay)
  34993. }
  34994. },
  34995. _hideTooltip: function(delay) {
  34996. var that = this;
  34997. that._showTooltipTimeout && ++that._DEBUG_showTooltipTimeoutCleared;
  34998. _clearTimeout(that._showTooltipTimeout);
  34999. that._showTooltipTimeout = null;
  35000. _clearTimeout(that._hideTooltipTimeout);
  35001. ++that._DEBUG_hideTooltipTimeoutSet;
  35002. that._hideTooltipTimeout = _setTimeout(that._hideTooltipCallback, delay)
  35003. }
  35004. });
  35005. var tooltipMouseEvents = {
  35006. 'mouseover.gauge-tooltip': handleTooltipMouseOver,
  35007. 'mouseout.gauge-tooltip': handleTooltipMouseOut
  35008. };
  35009. var tooltipMouseMoveEvents = {'mousemove.gauge-tooltip': handleTooltipMouseMove};
  35010. var tooltipTouchEvents = {'touchstart.gauge-tooltip': handleTooltipTouchStart};
  35011. function handleTooltipMouseOver(event) {
  35012. var tracker = event.data.tracker;
  35013. tracker._x = event.pageX;
  35014. tracker._y = event.pageY;
  35015. tracker._element.off(tooltipMouseMoveEvents).on(tooltipMouseMoveEvents, event.data);
  35016. tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
  35017. }
  35018. function handleTooltipMouseMove(event) {
  35019. var tracker = event.data.tracker;
  35020. if (tracker._showTooltipTimeout && _abs(event.pageX - tracker._x) > 4 || _abs(event.pageY - tracker._y) > 4) {
  35021. tracker._x = event.pageX;
  35022. tracker._y = event.pageY;
  35023. tracker._showTooltip(event, TOOLTIP_SHOW_DELAY)
  35024. }
  35025. }
  35026. function handleTooltipMouseOut(event) {
  35027. var tracker = event.data.tracker;
  35028. tracker._element.off(tooltipMouseMoveEvents);
  35029. tracker._hideTooltip(TOOLTIP_HIDE_DELAY)
  35030. }
  35031. var active_touch_tooltip_tracker = null;
  35032. DX.viz.gauges.__internals.Tracker._DEBUG_reset = function() {
  35033. active_touch_tooltip_tracker = null
  35034. };
  35035. function handleTooltipTouchStart(event) {
  35036. event.preventDefault();
  35037. var tracker = active_touch_tooltip_tracker;
  35038. if (tracker && tracker !== event.data.tracker)
  35039. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  35040. tracker = active_touch_tooltip_tracker = event.data.tracker;
  35041. tracker._showTooltip(event, TOOLTIP_TOUCH_SHOW_DELAY);
  35042. tracker._touch = true
  35043. }
  35044. function handleTooltipDocumentTouchStart(event) {
  35045. var tracker = active_touch_tooltip_tracker;
  35046. if (tracker) {
  35047. if (!tracker._touch) {
  35048. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  35049. active_touch_tooltip_tracker = null
  35050. }
  35051. tracker._touch = null
  35052. }
  35053. }
  35054. function handleTooltipDocumentTouchEnd(event) {
  35055. var tracker = active_touch_tooltip_tracker;
  35056. if (tracker)
  35057. if (tracker._showTooltipTimeout) {
  35058. tracker._hideTooltip(TOOLTIP_TOUCH_HIDE_DELAY);
  35059. active_touch_tooltip_tracker = null
  35060. }
  35061. }
  35062. $(window.document).on({
  35063. 'touchstart.gauge-tooltip': handleTooltipDocumentTouchStart,
  35064. 'touchend.gauge-tooltip': handleTooltipDocumentTouchEnd
  35065. })
  35066. })(DevExpress, jQuery);
  35067. /*! Module viz-gauges, file dxCircularGauge.js */
  35068. (function(DX, undefined) {
  35069. DX.registerComponent("dxCircularGauge", DX.viz.gauges.CircularGauge)
  35070. })(DevExpress);
  35071. /*! Module viz-gauges, file dxLinearGauge.js */
  35072. (function(DX, undefined) {
  35073. DX.registerComponent("dxLinearGauge", DX.viz.gauges.LinearGauge)
  35074. })(DevExpress);
  35075. DevExpress.MOD_VIZ_GAUGES = true
  35076. }
  35077. if (!DevExpress.MOD_VIZ_RANGESELECTOR) {
  35078. if (!DevExpress.MOD_VIZ_CORE)
  35079. throw Error('Required module is not referenced: viz-core');
  35080. /*! Module viz-rangeselector, file namespaces.js */
  35081. (function(DevExpress) {
  35082. DevExpress.viz.rangeSelector = {utils: {}}
  35083. })(DevExpress);
  35084. /*! Module viz-rangeselector, file utils.js */
  35085. (function($, DX, undefined) {
  35086. var rangeSelector = DX.viz.rangeSelector,
  35087. utils = rangeSelector.utils,
  35088. dxUtils = DX.utils;
  35089. var INVISIBLE_POS = -1000;
  35090. var findLessOrEqualValueIndex = function(values, value) {
  35091. if (!values || values.length === 0)
  35092. return -1;
  35093. var minIndex = 0,
  35094. maxIndex = values.length - 1,
  35095. index = 0;
  35096. while (maxIndex - minIndex > 1) {
  35097. var index = minIndex + maxIndex >> 1;
  35098. if (values[index] > value)
  35099. maxIndex = index;
  35100. else
  35101. minIndex = index
  35102. }
  35103. return values[maxIndex] <= value ? maxIndex : minIndex
  35104. };
  35105. var findLessOrEqualValue = function(values, value) {
  35106. var index = findLessOrEqualValueIndex(values, value);
  35107. if (values && index >= 0 && index < values.length)
  35108. return values[index];
  35109. return value
  35110. };
  35111. var findNearValue = function(values, value) {
  35112. var index = findLessOrEqualValueIndex(values, value);
  35113. if (values && index >= 0 && index < values.length) {
  35114. if (index + 1 < values.length)
  35115. if (dxUtils.isDate(value)) {
  35116. if (values[index + 1].getTime() - value.getTime() < value.getTime() - values[index].getTime())
  35117. index++
  35118. }
  35119. else if (values[index + 1] - value < value - values[index])
  35120. index++;
  35121. return values[index]
  35122. }
  35123. return value
  35124. };
  35125. var findGreaterOrEqualValue = function(values, value) {
  35126. var index = findLessOrEqualValueIndex(values, value);
  35127. if (values && index >= 0 && index < values.length) {
  35128. if (values[index] < value && index + 1 < values.length)
  35129. index++;
  35130. return values[index]
  35131. }
  35132. return value
  35133. };
  35134. var getInterval = function(valueMin, valueMax, delta) {
  35135. var result,
  35136. minDateDaysCount,
  35137. maxDateDaysCount,
  35138. daysCount,
  35139. prevMaxDaysCount;
  35140. if (dxUtils.isDate(valueMin)) {
  35141. if (delta === 'year' || delta === 'quarter' || delta === 'month')
  35142. return {months: valueMax.getFullYear() * 12 + valueMax.getMonth() - valueMin.getFullYear() * 12 - valueMin.getMonth()};
  35143. else
  35144. return {milliseconds: valueMax.valueOf() - valueMin.valueOf()};
  35145. return result
  35146. }
  35147. else
  35148. return valueMax - valueMin
  35149. };
  35150. var getRootOffsetLeft = function(renderer) {
  35151. return dxUtils.getRootOffset(renderer).left || 0
  35152. };
  35153. var getEventPageX = function(eventArgs) {
  35154. var result = 0;
  35155. if (eventArgs.pageX)
  35156. result = eventArgs.pageX;
  35157. else if (eventArgs.originalEvent && eventArgs.originalEvent.pageX)
  35158. result = eventArgs.originalEvent.pageX;
  35159. if (eventArgs.originalEvent && eventArgs.originalEvent.touches)
  35160. if (eventArgs.originalEvent.touches.length > 0)
  35161. result = eventArgs.originalEvent.touches[0].pageX;
  35162. else if (eventArgs.originalEvent.changedTouches.length > 0)
  35163. result = eventArgs.originalEvent.changedTouches[0].pageX;
  35164. return result
  35165. };
  35166. var getTextBBox = function(renderer, text, fontOptions) {
  35167. var textElement = renderer.createText(text, INVISIBLE_POS, INVISIBLE_POS, {font: fontOptions}).append();
  35168. var textBBox = textElement.getBBox();
  35169. textElement.remove();
  35170. return textBBox
  35171. };
  35172. utils.findLessOrEqualValue = findLessOrEqualValue;
  35173. utils.findNearValue = findNearValue;
  35174. utils.findGreaterOrEqualValue = findGreaterOrEqualValue;
  35175. utils.getInterval = getInterval;
  35176. utils.getRootOffsetLeft = getRootOffsetLeft;
  35177. utils.getEventPageX = getEventPageX;
  35178. utils.getTextBBox = getTextBBox
  35179. })(jQuery, DevExpress);
  35180. /*! Module viz-rangeselector, file baseVisualElement.js */
  35181. (function(DX) {
  35182. DevExpress.viz.rangeSelector.BaseVisualElement = DX.Class.inherit({
  35183. ctor: function(renderer) {
  35184. this._renderer = renderer;
  35185. this._isDrawn = false
  35186. },
  35187. applyOptions: function(options) {
  35188. this._options = options || {};
  35189. this._applyOptions(this._options)
  35190. },
  35191. _applyOptions: function(options){},
  35192. redraw: function(group) {
  35193. var that = this;
  35194. if (!that._isDrawn) {
  35195. that._isDrawn = !(that._draw(group || that._group) === false);
  35196. if (group)
  35197. that._group = group
  35198. }
  35199. else
  35200. that._update(group || that._group)
  35201. },
  35202. isDrawn: function() {
  35203. return !!this._isDrawn
  35204. },
  35205. isInitialized: function() {
  35206. return !!this._options
  35207. },
  35208. _draw: function(group){},
  35209. _update: function(group) {
  35210. group.clear();
  35211. this._draw(group)
  35212. }
  35213. })
  35214. })(DevExpress);
  35215. /*! Module viz-rangeselector, file rangeSelector.js */
  35216. (function($, DX, undefined) {
  35217. var rangeSelector = DX.viz.rangeSelector,
  35218. utils = DX.utils,
  35219. dataUtils = DX.data.utils,
  35220. rangeSelectorUtils = rangeSelector.utils,
  35221. ParseUtils = DX.viz.core.ParseUtils,
  35222. formatHelper = DX.formatHelper,
  35223. core = DX.viz.core,
  35224. _max = Math.max,
  35225. _isDefined = utils.isDefined;
  35226. rangeSelector.consts = {
  35227. fontHeightRatio: 0.55,
  35228. emptySliderMarkerText: '. . .'
  35229. };
  35230. rangeSelector.formatValue = function(value, formatOptions) {
  35231. var formatObject = {
  35232. value: value,
  35233. valueText: formatHelper.format(value, formatOptions.format, formatOptions.precision)
  35234. };
  35235. return String(utils.isFunction(formatOptions.customizeText) ? formatOptions.customizeText.call(formatObject, formatObject) : formatObject.valueText)
  35236. };
  35237. rangeSelector.RangeSelector = core.BaseWidget.inherit(function() {
  35238. var SCALE_TEXT_SPACING = 5;
  35239. var defaultRangeSelectorOptions = {
  35240. size: undefined,
  35241. margin: {
  35242. left: 0,
  35243. top: 0,
  35244. right: 0,
  35245. bottom: 0
  35246. },
  35247. scale: {
  35248. showCustomBoundaryTicks: true,
  35249. showMinorTicks: true,
  35250. startValue: undefined,
  35251. endValue: undefined,
  35252. minorTickCount: undefined,
  35253. minorTickInterval: undefined,
  35254. majorTickInterval: undefined,
  35255. useTicksAutoArrangement: true,
  35256. setTicksAtUnitBeginning: true,
  35257. minRange: undefined,
  35258. maxRange: undefined,
  35259. placeholderHeight: undefined,
  35260. valueType: undefined,
  35261. label: {
  35262. visible: true,
  35263. format: undefined,
  35264. precision: undefined,
  35265. customizeText: undefined
  35266. },
  35267. marker: {
  35268. visible: true,
  35269. label: {
  35270. format: undefined,
  35271. precision: undefined,
  35272. customizeText: undefined
  35273. }
  35274. },
  35275. logarithmBase: 10
  35276. },
  35277. selectedRange: undefined,
  35278. sliderMarker: {
  35279. visible: true,
  35280. format: undefined,
  35281. precision: undefined,
  35282. customizeText: undefined,
  35283. placeholderSize: undefined
  35284. },
  35285. behavior: {
  35286. snapToTicks: true,
  35287. animationEnabled: true,
  35288. moveSelectedRangeByClick: true,
  35289. manualRangeSelectionEnabled: true,
  35290. allowSlidersSwap: true,
  35291. callSelectedRangeChanged: "onMovingComplete"
  35292. },
  35293. background: {
  35294. color: "#C0BAE1",
  35295. visible: true,
  35296. image: {
  35297. url: undefined,
  35298. location: 'full'
  35299. }
  35300. },
  35301. dataSource: undefined,
  35302. dataSourceField: 'arg',
  35303. redrawOnResize: true,
  35304. theme: undefined,
  35305. selectedRangeChanged: null
  35306. };
  35307. var calculateMarkerSize = function(renderer, value, sliderMarkerOptions) {
  35308. var formattedText = value === undefined ? rangeSelector.consts.emptySliderMarkerText : rangeSelector.formatValue(value, sliderMarkerOptions),
  35309. textBBox = rangeSelectorUtils.getTextBBox(renderer, formattedText, sliderMarkerOptions.font);
  35310. return {
  35311. width: Math.ceil(textBBox.width) + 2 * sliderMarkerOptions.padding,
  35312. height: Math.ceil(textBBox.height * rangeSelector.consts.fontHeightRatio) + 2 * sliderMarkerOptions.padding + sliderMarkerOptions.pointerSize
  35313. }
  35314. };
  35315. var calculateScaleLabelHalfWidth = function(renderer, value, scaleOptions) {
  35316. var formattedText = rangeSelector.formatValue(value, scaleOptions.label),
  35317. textBBox = rangeSelectorUtils.getTextBBox(renderer, formattedText, scaleOptions.label.font);
  35318. return Math.ceil(textBBox.width / 2)
  35319. };
  35320. var calculateRangeContainerCanvas = function(size, margin, sliderMarkerSpacing) {
  35321. var canvas = {
  35322. left: margin.left + sliderMarkerSpacing.left,
  35323. top: margin.top + sliderMarkerSpacing.top,
  35324. width: size.width - margin.left - margin.right - sliderMarkerSpacing.left - sliderMarkerSpacing.right,
  35325. height: size.height - margin.top - margin.bottom - sliderMarkerSpacing.top - sliderMarkerSpacing.bottom
  35326. };
  35327. if (canvas.width <= 0)
  35328. canvas.width = 1;
  35329. return canvas
  35330. };
  35331. var parseSliderMarkersPlaceholderSize = function(placeholderSize) {
  35332. var placeholderWidthLeft,
  35333. placeholderWidthRight,
  35334. placeholderHeight;
  35335. if (utils.isNumber(placeholderSize))
  35336. placeholderWidthLeft = placeholderWidthRight = placeholderHeight = placeholderSize;
  35337. else if (placeholderSize) {
  35338. if (utils.isNumber(placeholderSize.height))
  35339. placeholderHeight = placeholderSize.height;
  35340. if (utils.isNumber(placeholderSize.width))
  35341. placeholderWidthLeft = placeholderWidthRight = placeholderSize.width;
  35342. else if (placeholderSize.width) {
  35343. if (utils.isNumber(placeholderSize.width.left))
  35344. placeholderWidthLeft = placeholderSize.width.left;
  35345. if (utils.isNumber(placeholderSize.width.right))
  35346. placeholderWidthRight = placeholderSize.width.right
  35347. }
  35348. }
  35349. return {
  35350. widthLeft: placeholderWidthLeft,
  35351. widthRight: placeholderWidthRight,
  35352. height: placeholderHeight
  35353. }
  35354. };
  35355. var calculateSliderMarkersSpacing = function(renderer, size, scale, sliderMarkerOptions) {
  35356. var leftMarkerSize,
  35357. leftScaleLabelWidth = 0,
  35358. rightScaleLabelWidth = 0,
  35359. rightMarkerSize,
  35360. placeholderWidthLeft = 0,
  35361. placeholderWidthRight = 0,
  35362. placeholderHeight = 0,
  35363. parsedPlaceholderSize,
  35364. markerMaxWidth;
  35365. parsedPlaceholderSize = parseSliderMarkersPlaceholderSize(sliderMarkerOptions.placeholderSize);
  35366. placeholderWidthLeft = parsedPlaceholderSize.widthLeft || 0;
  35367. placeholderWidthRight = parsedPlaceholderSize.widthRight || 0;
  35368. placeholderHeight = parsedPlaceholderSize.height || 0;
  35369. if (sliderMarkerOptions.visible) {
  35370. leftMarkerSize = calculateMarkerSize(renderer, scale.startValue, sliderMarkerOptions);
  35371. rightMarkerSize = calculateMarkerSize(renderer, scale.endValue, sliderMarkerOptions);
  35372. markerMaxWidth = _max(leftMarkerSize.width, rightMarkerSize.width);
  35373. if (!placeholderWidthLeft)
  35374. placeholderWidthLeft = markerMaxWidth;
  35375. if (!placeholderWidthRight)
  35376. placeholderWidthRight = markerMaxWidth;
  35377. if (!placeholderHeight)
  35378. placeholderHeight = _max(leftMarkerSize.height, rightMarkerSize.height)
  35379. }
  35380. if (scale.label.visible) {
  35381. leftScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.startValue, scale);
  35382. rightScaleLabelWidth = calculateScaleLabelHalfWidth(renderer, scale.endValue, scale)
  35383. }
  35384. placeholderWidthLeft = _max(placeholderWidthLeft, leftScaleLabelWidth);
  35385. placeholderWidthRight = _max(placeholderWidthRight, rightScaleLabelWidth);
  35386. return {
  35387. left: placeholderWidthLeft,
  35388. right: placeholderWidthRight,
  35389. top: placeholderHeight,
  35390. bottom: 0
  35391. }
  35392. };
  35393. var clearContainer = function(container) {
  35394. if (container)
  35395. container.empty()
  35396. };
  35397. var getContainer = function(that) {
  35398. return that._element()
  35399. };
  35400. var createRangeContainer = function(rangeContainerOptions) {
  35401. return rangeSelector.rangeSelectorFactory.createRangeContainer(rangeContainerOptions)
  35402. };
  35403. var createTranslator = function(range, canvas) {
  35404. return {
  35405. x: core.CoreFactory.createTranslator2D(range.arg, canvas, {direction: "horizontal"}),
  35406. y: core.CoreFactory.createTranslator2D(range.val, canvas)
  35407. }
  35408. };
  35409. var createTranslatorCanvas = function(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight) {
  35410. return {
  35411. left: rangeContainerCanvas.left,
  35412. top: rangeContainerCanvas.top,
  35413. right: sizeOptions.width - rangeContainerCanvas.width - rangeContainerCanvas.left,
  35414. bottom: sizeOptions.height - rangeContainerCanvas.height - rangeContainerCanvas.top + scaleLabelsAreaHeight,
  35415. width: sizeOptions.width,
  35416. height: sizeOptions.height
  35417. }
  35418. };
  35419. var createRenderer = function(that) {
  35420. var renderer = that.option('renderer');
  35421. if (renderer)
  35422. return renderer;
  35423. return core.CoreFactory.createRenderer({
  35424. pathModified: that.option('pathModified'),
  35425. rtl: that.option('rtlEnabled')
  35426. })
  35427. };
  35428. var createThemeManager = function(theme) {
  35429. return rangeSelector.rangeSelectorFactory.createThemeManager(theme)
  35430. };
  35431. var calculateValueType = function(firstValue, secondValue) {
  35432. var types = [$.type(firstValue), $.type(secondValue)];
  35433. $.inArray();
  35434. return $.inArray('date', types) != -1 ? 'datetime' : $.inArray('number', types) != -1 ? 'numeric' : ''
  35435. };
  35436. var createSeriesDataSource = function(that) {
  35437. var seriesDataSource,
  35438. dataSource = that._dataSource && that._dataSource.items(),
  35439. scaleOptions = that.option('scale'),
  35440. chartOptions = that.option('chart') || {},
  35441. valueType = scaleOptions.valueType;
  35442. if (!valueType)
  35443. valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue);
  35444. if (dataSource || chartOptions.series) {
  35445. seriesDataSource = new rangeSelector.SeriesDataSource({
  35446. renderer: that.renderer,
  35447. dataSource: dataSource,
  35448. valueType: (valueType || '').toLowerCase(),
  35449. axisType: scaleOptions.type,
  35450. chart: chartOptions,
  35451. dataSourceField: that.option('dataSourceField'),
  35452. backgroundColor: that._userBackgroundColor,
  35453. incidentOccured: that._incidentOccured
  35454. });
  35455. checkLogarithmicOptions(chartOptions.valueAxis, seriesDataSource.themeManager.theme().valueAxis.logarithmBase, that._incidentOccured)
  35456. }
  35457. return seriesDataSource
  35458. };
  35459. var calculateTranslatorRange = function(that, seriesDataSource, scaleOptions) {
  35460. var translatorRange,
  35461. minValue,
  35462. maxValue,
  35463. inverted = false,
  35464. isEqualDates;
  35465. if (_isDefined(scaleOptions.startValue) && _isDefined(scaleOptions.endValue)) {
  35466. inverted = scaleOptions.inverted = scaleOptions.startValue > scaleOptions.endValue;
  35467. minValue = inverted ? scaleOptions.endValue : scaleOptions.startValue;
  35468. maxValue = inverted ? scaleOptions.startValue : scaleOptions.endValue
  35469. }
  35470. else if (_isDefined(scaleOptions.startValue) || _isDefined(scaleOptions.endValue)) {
  35471. minValue = scaleOptions.startValue;
  35472. maxValue = scaleOptions.endValue
  35473. }
  35474. translatorRange = seriesDataSource ? seriesDataSource.getBoundRange() : {
  35475. arg: new core.Range,
  35476. val: new core.Range({isValueRange: true})
  35477. };
  35478. isEqualDates = utils.isDate(minValue) && utils.isDate(maxValue) && minValue.getTime() === maxValue.getTime();
  35479. if (minValue !== maxValue && !isEqualDates)
  35480. translatorRange.arg.addRange({
  35481. invert: inverted,
  35482. min: minValue,
  35483. max: maxValue,
  35484. minVisible: minValue,
  35485. maxVisible: maxValue,
  35486. dataType: scaleOptions.valueType
  35487. });
  35488. translatorRange.arg.addRange({
  35489. base: scaleOptions.logarithmBase,
  35490. axisType: scaleOptions.type
  35491. });
  35492. if (!translatorRange.arg.isDefined()) {
  35493. if (isEqualDates)
  35494. scaleOptions.valueType = 'numeric';
  35495. translatorRange.arg.setStubData(scaleOptions.valueType)
  35496. }
  35497. return translatorRange
  35498. };
  35499. var calculateScaleAreaHeight = function(renderer, scaleOptions, visibleMarkers) {
  35500. var textBBox,
  35501. visibleLabels = scaleOptions.label.visible;
  35502. if (scaleOptions.placeholderHeight)
  35503. return scaleOptions.placeholderHeight;
  35504. else {
  35505. textBBox = rangeSelectorUtils.getTextBBox(renderer, '0', scaleOptions.label.font);
  35506. return (visibleLabels ? scaleOptions.label.topIndent + textBBox.height : 0) + (visibleMarkers ? scaleOptions.marker.topIndent + scaleOptions.marker.separatorHeight : 0)
  35507. }
  35508. };
  35509. var getTicksInfo = function(that, scaleOptions, translators, screenDelta) {
  35510. var isEmpty = scaleOptions.isEmpty,
  35511. tickProvider = core.CoreFactory.getTickProvider(),
  35512. minorTicksOptions,
  35513. majorTicksOptions,
  35514. startValue,
  35515. endValue,
  35516. businessRange = translators.x.getBusinessRange();
  35517. minorTicksOptions = {
  35518. tickInterval: isEmpty ? 0 : that.option('scale').minorTickInterval,
  35519. showCustomBoundaryTicks: scaleOptions.showCustomBoundaryTicks,
  35520. minorTickCount: scaleOptions.minorTickCount
  35521. };
  35522. majorTicksOptions = {
  35523. textOptions: {
  35524. align: 'center',
  35525. font: scaleOptions.label.font
  35526. },
  35527. renderer: that.renderer,
  35528. getText: function(value) {
  35529. return rangeSelector.formatValue(value, scaleOptions.label)
  35530. },
  35531. translator: translators.x,
  35532. isStartTickGenerated: !_isDefined(that.option('scale').majorTickInterval),
  35533. tickInterval: scaleOptions.majorTickInterval,
  35534. textSpacing: SCALE_TEXT_SPACING,
  35535. setTicksAtUnitBeginning: scaleOptions.setTicksAtUnitBeginning,
  35536. useTicksAutoArrangement: scaleOptions.useTicksAutoArrangement,
  35537. hideLabels: isEmpty
  35538. };
  35539. startValue = isEmpty ? businessRange.min : scaleOptions.startValue;
  35540. endValue = isEmpty ? businessRange.max : scaleOptions.endValue;
  35541. return tickProvider.getFullTicks(startValue, endValue, screenDelta, majorTicksOptions, minorTicksOptions, {
  35542. axisType: scaleOptions.type,
  35543. dataType: scaleOptions.valueType,
  35544. base: scaleOptions.logarithmBase
  35545. })
  35546. };
  35547. var updateTickIntervals = function(scaleOptions, screenDelta, incidentOccured) {
  35548. var tickProvider = core.CoreFactory.getTickProvider(),
  35549. tickIntervals = tickProvider.getTickIntervals(scaleOptions.startValue, scaleOptions.endValue, screenDelta, {
  35550. tickInterval: scaleOptions.majorTickInterval,
  35551. incidentOccured: incidentOccured
  35552. }, {
  35553. tickInterval: scaleOptions.minorTickInterval,
  35554. incidentOccured: incidentOccured
  35555. }, {
  35556. axisType: scaleOptions.type,
  35557. dataType: scaleOptions.valueType,
  35558. base: scaleOptions.logarithmBase
  35559. });
  35560. scaleOptions.minorTickInterval = tickIntervals.minorTickInterval;
  35561. scaleOptions.majorTickInterval = tickIntervals.majorTickInterval
  35562. };
  35563. var updateScaleOptions = function(that, seriesDataSource, translatorRange, screenDelta, scaleOptions) {
  35564. var minVisibleX = _isDefined(translatorRange.arg.minVisible) ? translatorRange.arg.minVisible : translatorRange.arg.min,
  35565. maxVisibleX = _isDefined(translatorRange.arg.maxVisible) ? translatorRange.arg.maxVisible : translatorRange.arg.max,
  35566. isEmptyInterval;
  35567. if (seriesDataSource && !seriesDataSource.isEmpty()) {
  35568. scaleOptions.startValue = scaleOptions.inverted ? maxVisibleX : minVisibleX;
  35569. scaleOptions.endValue = scaleOptions.inverted ? minVisibleX : maxVisibleX
  35570. }
  35571. isEmptyInterval = utils.isDate(scaleOptions.startValue) && utils.isDate(scaleOptions.endValue) && scaleOptions.startValue.getTime() === scaleOptions.endValue.getTime() || scaleOptions.startValue === scaleOptions.endValue;
  35572. scaleOptions.isEmpty = !_isDefined(scaleOptions.startValue) || !_isDefined(scaleOptions.endValue) || isEmptyInterval || scaleOptions.valueType === 'string';
  35573. if (scaleOptions.isEmpty)
  35574. scaleOptions.startValue = scaleOptions.endValue = undefined;
  35575. else {
  35576. updateTickIntervals(scaleOptions, screenDelta, that._incidentOccured);
  35577. if (scaleOptions.valueType === 'datetime' && !_isDefined(scaleOptions.label.format))
  35578. if (!scaleOptions.marker.visible)
  35579. scaleOptions.label.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.majorTickInterval);
  35580. else
  35581. scaleOptions.label.format = utils.getDateUnitInterval(scaleOptions.majorTickInterval)
  35582. }
  35583. };
  35584. var prepareSliderMarkersOptions = function(that, scaleOptions, screenDelta) {
  35585. var sliderMarkerOptions = $.extend(true, {}, that.option('sliderMarker')),
  35586. businessInterval;
  35587. if (!sliderMarkerOptions.format) {
  35588. if (!that.option('behavior').snapToTicks && utils.isNumber(scaleOptions.startValue)) {
  35589. businessInterval = Math.abs(scaleOptions.endValue - scaleOptions.startValue);
  35590. sliderMarkerOptions.format = 'fixedPoint';
  35591. sliderMarkerOptions.precision = utils.getSignificantDigitPosition(businessInterval / screenDelta)
  35592. }
  35593. if (scaleOptions.valueType === 'datetime')
  35594. if (!scaleOptions.marker.visible) {
  35595. if (_isDefined(scaleOptions.startValue) && _isDefined(scaleOptions.endValue))
  35596. sliderMarkerOptions.format = formatHelper.getDateFormatByTickInterval(scaleOptions.startValue, scaleOptions.endValue, scaleOptions.minorTickInterval !== 0 ? scaleOptions.minorTickInterval : scaleOptions.majorTickInterval)
  35597. }
  35598. else
  35599. sliderMarkerOptions.format = utils.getDateUnitInterval(_isDefined(scaleOptions.minorTickInterval) && scaleOptions.minorTickInterval !== 0 ? scaleOptions.minorTickInterval : scaleOptions.majorTickInterval)
  35600. }
  35601. return sliderMarkerOptions
  35602. };
  35603. var showScaleMarkers = function(scaleOptions) {
  35604. return scaleOptions.valueType == 'datetime' && scaleOptions.marker.visible
  35605. };
  35606. var updateTranslatorRangeInterval = function(translatorRange, scaleOptions) {
  35607. var intervalX = scaleOptions.minorTickInterval || scaleOptions.majorTickInterval;
  35608. translatorRange = translatorRange.arg.addRange({interval: intervalX})
  35609. };
  35610. var checkLogarithmicOptions = function(options, logarithmBase, incidentOccured) {
  35611. if (!options)
  35612. return;
  35613. if (options.type === 'logarithmic' && options.logarithmBase <= 0 || options.logarithmBase && !$.isNumeric(options.logarithmBase)) {
  35614. options.logarithmBase = logarithmBase;
  35615. incidentOccured('E2104')
  35616. }
  35617. else if (options.type !== 'logarithmic')
  35618. options.logarithmBase = undefined
  35619. };
  35620. var prepareScaleOptions = function(that, seriesDataSource) {
  35621. var scaleOptions = $.extend(true, {}, that.option('scale')),
  35622. incidentOccured = that._incidentOccured,
  35623. parsedValue = 0,
  35624. parseUtils = new ParseUtils({incidentOccured: incidentOccured}),
  35625. valueType = parseUtils.correctValueType((scaleOptions.valueType || '').toLowerCase());
  35626. if (seriesDataSource)
  35627. valueType = seriesDataSource.getCalculatedValueType() || valueType;
  35628. if (!valueType)
  35629. valueType = calculateValueType(scaleOptions.startValue, scaleOptions.endValue) || 'numeric';
  35630. scaleOptions.valueType = valueType;
  35631. if (scaleOptions.valueType === 'string') {
  35632. that._incidentOccured("E2201");
  35633. return scaleOptions
  35634. }
  35635. var parser = parseUtils.getParser(valueType, 'scale');
  35636. if (_isDefined(scaleOptions.startValue)) {
  35637. parsedValue = parser(scaleOptions.startValue);
  35638. if (_isDefined(parsedValue))
  35639. scaleOptions.startValue = parsedValue;
  35640. else {
  35641. scaleOptions.startValue = undefined;
  35642. that._incidentOccured("E2202", ["start"])
  35643. }
  35644. }
  35645. if (_isDefined(scaleOptions.endValue)) {
  35646. parsedValue = parser(scaleOptions.endValue);
  35647. if (_isDefined(parsedValue))
  35648. scaleOptions.endValue = parsedValue;
  35649. else {
  35650. scaleOptions.endValue = undefined;
  35651. that._incidentOccured("E2202", ["end"])
  35652. }
  35653. }
  35654. checkLogarithmicOptions(scaleOptions, defaultRangeSelectorOptions.scale.logarithmBase, that._incidentOccured);
  35655. if (!scaleOptions.type)
  35656. scaleOptions.type = 'continuous';
  35657. scaleOptions.parser = parser;
  35658. return scaleOptions
  35659. };
  35660. var correctSizeOptions = function(that, sizeOptions, scaleOptions) {
  35661. var size = that.option('size') || {};
  35662. if (!sizeOptions.height && size.height !== 0)
  35663. if (scaleOptions.valueType === 'datetime' && scaleOptions.marker.visible !== false)
  35664. sizeOptions.height = 160;
  35665. else
  35666. sizeOptions.height = 120;
  35667. if (!sizeOptions.width && size.width !== 0)
  35668. sizeOptions.width = 400
  35669. };
  35670. var applyOptions = function(that) {
  35671. var rangeContainerCanvas,
  35672. seriesDataSource,
  35673. translatorRange,
  35674. scaleLabelsAreaHeight,
  35675. sizeOptions,
  35676. sliderMarkerSpacing,
  35677. sliderMarkerOptions,
  35678. selectedRange,
  35679. $container = that.container;
  35680. that._isUpdating = true;
  35681. sizeOptions = calculateSize(that);
  35682. that._actualSize = sizeOptions;
  35683. seriesDataSource = createSeriesDataSource(that);
  35684. that._scaleOptions = prepareScaleOptions(that, seriesDataSource);
  35685. correctSizeOptions(that, sizeOptions, that._scaleOptions);
  35686. if (!sizeOptions.width || !sizeOptions.height || !$container.is(':visible')) {
  35687. that.stopRedraw = true;
  35688. that._incidentOccured("W2001", [that.NAME]);
  35689. return
  35690. }
  35691. else
  35692. that.stopRedraw = false;
  35693. updateRendererSize(that, sizeOptions);
  35694. that._updateLoadIndicator(undefined, that.canvas.width, that.canvas.height);
  35695. translatorRange = calculateTranslatorRange(that, seriesDataSource, that._scaleOptions);
  35696. updateScaleOptions(that, seriesDataSource, translatorRange, sizeOptions.width, that._scaleOptions);
  35697. updateTranslatorRangeInterval(translatorRange, that._scaleOptions);
  35698. sliderMarkerOptions = prepareSliderMarkersOptions(that, that._scaleOptions, sizeOptions.width);
  35699. selectedRange = initSelection(that, that._scaleOptions);
  35700. sliderMarkerSpacing = calculateSliderMarkersSpacing(that.renderer, sizeOptions, that._scaleOptions, sliderMarkerOptions);
  35701. rangeContainerCanvas = calculateRangeContainerCanvas(sizeOptions, that.option('margin'), sliderMarkerSpacing);
  35702. scaleLabelsAreaHeight = calculateScaleAreaHeight(that.renderer, that._scaleOptions, showScaleMarkers(that._scaleOptions));
  35703. that.translators = createTranslator(translatorRange, createTranslatorCanvas(sizeOptions, rangeContainerCanvas, scaleLabelsAreaHeight));
  35704. that._scaleOptions.ticksInfo = getTicksInfo(that, that._scaleOptions, that.translators, rangeContainerCanvas.width);
  35705. that._testTicksInfo = that._scaleOptions.ticksInfo;
  35706. that._selectedRange = selectedRange;
  35707. if (seriesDataSource)
  35708. seriesDataSource.adjustSeriesDimensions(that.translators);
  35709. that.rangeContainer.applyOptions({
  35710. canvas: rangeContainerCanvas,
  35711. scaleLabelsAreaHeight: scaleLabelsAreaHeight,
  35712. sliderMarkerSpacing: sliderMarkerSpacing,
  35713. translators: that.translators,
  35714. selectedRange: selectedRange,
  35715. scale: that._scaleOptions,
  35716. behavior: that.option('behavior'),
  35717. background: that.option('background'),
  35718. chart: that.option('chart'),
  35719. seriesDataSource: seriesDataSource,
  35720. sliderMarker: sliderMarkerOptions,
  35721. sliderHandle: that.option('sliderHandle'),
  35722. shutter: that.option('shutter'),
  35723. selectedRangeChanged: createSelectedRangeChangedFunction(that),
  35724. setSelectedRange: function(selectedRange) {
  35725. that.setSelectedRange(selectedRange)
  35726. }
  35727. });
  35728. that._isUpdating = false
  35729. };
  35730. var createSelectedRangeChangedFunction = function(that) {
  35731. return function(selectedRange, blockSelectedRangeChanged) {
  35732. var selectedRangeChanged = that.option('selectedRangeChanged');
  35733. that.option('selectedRange', selectedRange);
  35734. if (selectedRangeChanged && !blockSelectedRangeChanged)
  35735. setTimeout(function() {
  35736. selectedRangeChanged.call(null, selectedRange)
  35737. })
  35738. }
  35739. };
  35740. var calculateSize = function(that) {
  35741. var $container = that.container,
  35742. size = that.option('size') || {},
  35743. result = {
  35744. width: size.width,
  35745. height: size.height
  35746. };
  35747. if ($container) {
  35748. if (!result.width)
  35749. result.width = $container.width();
  35750. if (!result.height)
  35751. result.height = $container.height()
  35752. }
  35753. that.canvas = result;
  35754. return result
  35755. };
  35756. var updateRendererSize = function(that, size) {
  35757. var renderer = that.renderer;
  35758. if (renderer.isInitialized())
  35759. renderer.getRoot().applySettings({
  35760. width: size.width,
  35761. height: size.height
  35762. });
  35763. else {
  35764. renderer.recreateCanvas(size.width, size.height);
  35765. renderer.draw(that.container[0])
  35766. }
  35767. };
  35768. var prepareChartThemeOptions = function(that, options) {
  35769. var chartTheme,
  35770. chartOption = that.option('chart') || {};
  35771. if (!chartOption.theme && options && options.theme) {
  35772. chartTheme = options.theme;
  35773. if (chartTheme) {
  35774. if (typeof chartTheme === 'object') {
  35775. chartTheme = chartTheme.chart || {};
  35776. chartTheme.name = options.theme.name
  35777. }
  35778. chartOption.theme = chartTheme
  35779. }
  35780. }
  35781. };
  35782. var initSelection = function(that, scaleOptions) {
  35783. var selectedRangeOptions = that.option('selectedRange'),
  35784. startValue,
  35785. endValue,
  35786. parser = scaleOptions.parser || function() {
  35787. return null
  35788. },
  35789. parseValue = function(value, entity) {
  35790. var parsedValue,
  35791. result = scaleOptions[entity];
  35792. if (_isDefined(value))
  35793. parsedValue = parser(value);
  35794. if (!_isDefined(parsedValue))
  35795. that._incidentOccured("E2203", [entity]);
  35796. else
  35797. result = parsedValue;
  35798. return result
  35799. };
  35800. if (!selectedRangeOptions)
  35801. return {
  35802. startValue: scaleOptions.startValue,
  35803. endValue: scaleOptions.endValue
  35804. };
  35805. else {
  35806. startValue = parseValue(selectedRangeOptions.startValue, 'startValue');
  35807. startValue = that.rangeContainer.slidersContainer.truncateSelectedRange(startValue, scaleOptions);
  35808. endValue = parseValue(selectedRangeOptions.endValue, 'endValue');
  35809. endValue = that.rangeContainer.slidersContainer.truncateSelectedRange(endValue, scaleOptions);
  35810. return {
  35811. startValue: startValue,
  35812. endValue: endValue
  35813. }
  35814. }
  35815. };
  35816. var _isSizeChanged = function(that) {
  35817. var actualSize = that._actualSize,
  35818. newSize = calculateSize(that);
  35819. return actualSize && (actualSize.width !== newSize.width || actualSize.height !== newSize.height)
  35820. };
  35821. return {
  35822. isSizeChanged: function() {
  35823. return _isSizeChanged(this)
  35824. },
  35825. _setDefaultOptions: function() {
  35826. this.callBase();
  35827. this.option(defaultRangeSelectorOptions)
  35828. },
  35829. _dataSourceOptions: function() {
  35830. return {
  35831. paginate: false,
  35832. _preferSync: true
  35833. }
  35834. },
  35835. _init: function() {
  35836. var that = this;
  35837. that.container = getContainer(that);
  35838. clearContainer(that.container);
  35839. that.renderer = createRenderer(that);
  35840. that.rangeContainer = createRangeContainer(that.renderer);
  35841. that.callBase();
  35842. that._reinitDataSource()
  35843. },
  35844. _reinitDataSource: function() {
  35845. this._refreshDataSource()
  35846. },
  35847. _dispose: function() {
  35848. var that = this,
  35849. disposeObject = function(propName) {
  35850. that[propName] && that[propName].dispose(),
  35851. that[propName] = null
  35852. };
  35853. that.callBase();
  35854. disposeObject("renderer");
  35855. that.translators = null;
  35856. disposeObject("rangeContainer")
  35857. },
  35858. _initOptions: function(options) {
  35859. var that = this,
  35860. themeManager;
  35861. that._optionsInitializing = true;
  35862. options = options || {};
  35863. that._userOptions = $.extend(true, {}, options);
  35864. themeManager = createThemeManager(options.theme);
  35865. themeManager.setBackgroundColor(options.containerBackgroundColor);
  35866. that.option(themeManager.applyRangeSelectorTheme(options));
  35867. prepareChartThemeOptions(that, options);
  35868. if (options.background)
  35869. that._userBackgroundColor = options.background.color
  35870. },
  35871. _refresh: function() {
  35872. var that = this,
  35873. callBase = that.callBase;
  35874. that._endLoading(function() {
  35875. callBase.call(that)
  35876. })
  35877. },
  35878. _render: function(isResizing) {
  35879. var that = this,
  35880. currentAnimationEnabled,
  35881. behaviorOptions;
  35882. that._optionsInitializing = false;
  35883. applyOptions(that);
  35884. if (!that.stopRedraw) {
  35885. if (isResizing) {
  35886. behaviorOptions = that.option('behavior');
  35887. currentAnimationEnabled = behaviorOptions.animationEnabled;
  35888. behaviorOptions.animationEnabled = false;
  35889. that.rangeContainer.redraw();
  35890. behaviorOptions.animationEnabled = currentAnimationEnabled
  35891. }
  35892. else
  35893. that.rangeContainer.redraw();
  35894. !isResizing && (!that._dataSource || that._dataSource && that._dataSource.isLoaded()) && that.hideLoadingIndicator()
  35895. }
  35896. that._drawn();
  35897. that.__rendered && that.__rendered()
  35898. },
  35899. _optionChanged: function(name, value, prevValue) {
  35900. var that = this;
  35901. if (!that._optionsInitializing)
  35902. dataUtils.compileSetter(name)(that._userOptions, value, {
  35903. functionsAsIs: true,
  35904. merge: true
  35905. });
  35906. if (name === "dataSource") {
  35907. that._reinitDataSource();
  35908. that._invalidate()
  35909. }
  35910. else if (name === "selectedRange")
  35911. that.setSelectedRange(that.option('selectedRange'));
  35912. else if (name === "selectedRangeChanged")
  35913. that.rangeContainer.slidersContainer.selectedRangeChanged = createSelectedRangeChangedFunction(that);
  35914. else if (name === 'containerBackgroundColor' || name === 'theme') {
  35915. that._initOptions(that._userOptions);
  35916. that._invalidate()
  35917. }
  35918. else
  35919. that.callBase(name, value, prevValue)
  35920. },
  35921. _resize: function() {
  35922. if (_isSizeChanged(this))
  35923. this._render(true)
  35924. },
  35925. _handleDataSourceChanged: function() {
  35926. var that = this;
  35927. that._endLoading(function() {
  35928. if (that.renderer.isInitialized())
  35929. that._render()
  35930. })
  35931. },
  35932. getSelectedRange: function() {
  35933. var that = this;
  35934. var selectedRange = that.rangeContainer.slidersContainer.getSelectedRange();
  35935. return {
  35936. startValue: selectedRange.startValue,
  35937. endValue: selectedRange.endValue
  35938. }
  35939. },
  35940. setSelectedRange: function(selectedRange) {
  35941. var that = this;
  35942. if (that._isUpdating || !selectedRange)
  35943. return;
  35944. var oldSelectedRange = that.rangeContainer.slidersContainer.getSelectedRange();
  35945. if (oldSelectedRange && oldSelectedRange.startValue === selectedRange.startValue && oldSelectedRange.endValue === selectedRange.endValue)
  35946. return;
  35947. that.rangeContainer.slidersContainer.setSelectedRange(selectedRange)
  35948. },
  35949. resetSelectedRange: function(blockSelectedRangeChanged) {
  35950. var that = this;
  35951. that.setSelectedRange({
  35952. startValue: that._scaleOptions.startValue,
  35953. endValue: that._scaleOptions.endValue,
  35954. blockSelectedRangeChanged: blockSelectedRangeChanged
  35955. })
  35956. },
  35957. render: function(isResizing) {
  35958. this._render(isResizing);
  35959. return this
  35960. }
  35961. }
  35962. }()).include(DX.ui.DataHelperMixin)
  35963. })(jQuery, DevExpress);
  35964. /*! Module viz-rangeselector, file rangeContainer.js */
  35965. (function($, DX, undefined) {
  35966. var rangeSelector = DX.viz.rangeSelector;
  35967. rangeSelector.RangeContainer = rangeSelector.BaseVisualElement.inherit(function() {
  35968. var ctor = function(renderer) {
  35969. this.callBase(renderer);
  35970. this.slidersContainer = createSlidersContainer(renderer);
  35971. this.rangeView = createRangeView(renderer);
  35972. this.scale = createScale(renderer)
  35973. };
  35974. var _applyOptions = function(options) {
  35975. var that = this,
  35976. isEmpty = options.scale.isEmpty,
  35977. viewCanvas = {
  35978. left: options.canvas.left,
  35979. top: options.canvas.top,
  35980. width: options.canvas.width,
  35981. height: options.canvas.height >= options.scaleLabelsAreaHeight ? options.canvas.height - options.scaleLabelsAreaHeight : 0
  35982. };
  35983. that._viewCanvas = viewCanvas;
  35984. that.slidersContainer.applyOptions({
  35985. canvas: viewCanvas,
  35986. translator: options.translators.x,
  35987. scale: options.scale,
  35988. selectedRange: options.selectedRange,
  35989. sliderMarker: options.sliderMarker,
  35990. sliderHandle: options.sliderHandle,
  35991. shutter: options.shutter,
  35992. behavior: options.behavior,
  35993. selectedRangeChanged: options.selectedRangeChanged,
  35994. isEmpty: isEmpty
  35995. });
  35996. that.rangeView.applyOptions({
  35997. canvas: viewCanvas,
  35998. translators: options.translators,
  35999. background: options.background,
  36000. chart: options.chart,
  36001. seriesDataSource: options.seriesDataSource,
  36002. behavior: options.behavior,
  36003. isEmpty: isEmpty
  36004. });
  36005. that.scale.applyOptions({
  36006. canvas: options.canvas,
  36007. translator: options.translators.x,
  36008. scale: options.scale,
  36009. hideLabels: isEmpty,
  36010. scaleLabelsAreaHeight: options.scaleLabelsAreaHeight,
  36011. setSelectedRange: options.setSelectedRange
  36012. })
  36013. };
  36014. var createSlidersContainer = function(options) {
  36015. return rangeSelector.rangeSelectorFactory.createSlidersContainer(options)
  36016. };
  36017. var createScale = function(options) {
  36018. return rangeSelector.rangeSelectorFactory.createScale(options)
  36019. };
  36020. var createRangeView = function(options) {
  36021. return rangeSelector.rangeSelectorFactory.createRangeView(options)
  36022. };
  36023. var _createClipRectCanvas = function(canvas, sliderMarkerSpacing) {
  36024. return {
  36025. left: canvas.left - sliderMarkerSpacing.left,
  36026. top: canvas.top - sliderMarkerSpacing.top,
  36027. width: canvas.width + sliderMarkerSpacing.right + sliderMarkerSpacing.left,
  36028. height: canvas.height + sliderMarkerSpacing.bottom + sliderMarkerSpacing.top
  36029. }
  36030. };
  36031. var _draw = function() {
  36032. var that = this,
  36033. containerGroup,
  36034. rangeViewGroup,
  36035. slidersContainerGroup,
  36036. scaleGroup,
  36037. trackersGroup,
  36038. clipRectCanvas = _createClipRectCanvas(that._options.canvas, that._options.sliderMarkerSpacing),
  36039. viewCanvas = that._viewCanvas;
  36040. that._clipRect = that._renderer.createClipRect(clipRectCanvas.left, clipRectCanvas.top, clipRectCanvas.width, clipRectCanvas.height).append();
  36041. containerGroup = that._renderer.createGroup({
  36042. 'class': 'rangeContainer',
  36043. clipId: that._clipRect.id
  36044. }).append();
  36045. that._viewClipRect = that._renderer.createClipRect(viewCanvas.left, viewCanvas.top, viewCanvas.width, viewCanvas.height).append();
  36046. rangeViewGroup = that._renderer.createGroup({
  36047. 'class': 'view',
  36048. clipId: that._viewClipRect.id
  36049. });
  36050. rangeViewGroup.append(containerGroup);
  36051. that.rangeView.redraw(rangeViewGroup);
  36052. slidersContainerGroup = that._renderer.createGroup({'class': 'slidersContainer'});
  36053. slidersContainerGroup.append(containerGroup);
  36054. that.slidersContainer.redraw(slidersContainerGroup);
  36055. scaleGroup = that._renderer.createGroup({'class': 'scale'});
  36056. scaleGroup.append(containerGroup);
  36057. that.scale.redraw(scaleGroup);
  36058. trackersGroup = that._renderer.createGroup({'class': 'trackers'});
  36059. trackersGroup.append(containerGroup);
  36060. that._trackersGroup = trackersGroup;
  36061. that.slidersContainer.appendTrackers(trackersGroup)
  36062. };
  36063. var _update = function() {
  36064. var that = this,
  36065. clipRectCanvas = _createClipRectCanvas(that._options.canvas, that._options.sliderMarkerSpacing),
  36066. viewCanvas = that._viewCanvas;
  36067. that._clipRect.updateRectangle({
  36068. x: clipRectCanvas.left,
  36069. y: clipRectCanvas.top,
  36070. width: clipRectCanvas.width,
  36071. height: clipRectCanvas.height
  36072. });
  36073. that._viewClipRect.updateRectangle({
  36074. x: viewCanvas.left,
  36075. y: viewCanvas.top,
  36076. width: viewCanvas.width,
  36077. height: viewCanvas.height
  36078. });
  36079. that.rangeView.redraw();
  36080. that.slidersContainer.redraw();
  36081. that.slidersContainer.appendTrackers(that._trackersGroup);
  36082. that.scale.redraw()
  36083. };
  36084. var dispose = function() {
  36085. this.slidersContainer.dispose();
  36086. this.slidersContainer = null
  36087. };
  36088. var prototypeObject = {
  36089. createSlidersContainer: createSlidersContainer,
  36090. createScale: createScale,
  36091. ctor: ctor,
  36092. dispose: dispose,
  36093. _applyOptions: _applyOptions,
  36094. _draw: _draw,
  36095. _update: _update
  36096. };
  36097. return prototypeObject
  36098. }())
  36099. })(jQuery, DevExpress);
  36100. /*! Module viz-rangeselector, file scale.js */
  36101. (function($, DX, undefined) {
  36102. var rangeSelector = DX.viz.rangeSelector,
  36103. formatHelper = DX.formatHelper,
  36104. utils = DX.utils;
  36105. var SCALE_TEXT_SPACING = 5;
  36106. rangeSelector.Scale = rangeSelector.BaseVisualElement.inherit({
  36107. _setupDateUnitInterval: function(scaleOptions) {
  36108. var key,
  36109. hasObjectSingleField = function(object) {
  36110. var fieldsCounter = 0;
  36111. $.each(object, function() {
  36112. return ++fieldsCounter < 2
  36113. });
  36114. return fieldsCounter === 1
  36115. },
  36116. millisecTickInterval,
  36117. majorTickInterval = scaleOptions.ticksInfo.majorTickInterval,
  36118. majorTicks = scaleOptions.ticksInfo.majorTicks;
  36119. if (scaleOptions.valueType === 'datetime') {
  36120. if (utils.isObject(majorTickInterval) && !hasObjectSingleField(majorTickInterval))
  36121. 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).');
  36122. if (majorTicks && majorTicks.autoArrangementStep > 1) {
  36123. if (utils.isString(majorTickInterval))
  36124. majorTickInterval = utils.getDateIntervalByString(majorTickInterval);
  36125. for (key in majorTickInterval)
  36126. if (majorTickInterval.hasOwnProperty(key)) {
  36127. majorTickInterval[key] *= majorTicks.autoArrangementStep;
  36128. millisecTickInterval = utils.convertDateTickIntervalToMilliseconds(majorTickInterval)
  36129. }
  36130. majorTickInterval = utils.convertMillisecondsToDateUnits(millisecTickInterval)
  36131. }
  36132. this.dateUnitInterval = utils.getDateUnitInterval(majorTickInterval)
  36133. }
  36134. },
  36135. _prepareDatesDifferences: function(datesDifferences, tickInterval) {
  36136. var deleteDifferent = tickInterval,
  36137. dateUnitInterval,
  36138. i;
  36139. if (deleteDifferent === 'week')
  36140. deleteDifferent = 'day';
  36141. if (deleteDifferent === 'quarter')
  36142. deleteDifferent = 'month';
  36143. if (datesDifferences[deleteDifferent])
  36144. for (i = 0; i < utils.dateUnitIntervals.length; i++) {
  36145. dateUnitInterval = utils.dateUnitIntervals[i];
  36146. if (datesDifferences[dateUnitInterval]) {
  36147. datesDifferences[dateUnitInterval] = false;
  36148. datesDifferences.count--
  36149. }
  36150. if (dateUnitInterval === deleteDifferent)
  36151. break
  36152. }
  36153. },
  36154. _getMarkerDate: function(date, tickInterval) {
  36155. var markerDate = new Date(date.getTime()),
  36156. month = 0;
  36157. switch (tickInterval) {
  36158. case'quarter':
  36159. month = formatHelper.getFirstQuarterMonth(date.getMonth());
  36160. case'month':
  36161. markerDate.setMonth(month);
  36162. case'week':
  36163. case'day':
  36164. markerDate.setDate(1);
  36165. case'hour':
  36166. markerDate.setHours(0, 0, 0, 0);
  36167. break;
  36168. case'millisecond':
  36169. markerDate.setMilliseconds(0);
  36170. break;
  36171. case'second':
  36172. markerDate.setSeconds(0, 0);
  36173. break;
  36174. case'minute':
  36175. markerDate.setMinutes(0, 0, 0);
  36176. break
  36177. }
  36178. return markerDate
  36179. },
  36180. _drawDateMarker: function(date, options) {
  36181. var labelPosX,
  36182. labelPosY,
  36183. dateFormated,
  36184. scaleOptions,
  36185. textElement;
  36186. if (options.x === null)
  36187. return;
  36188. scaleOptions = this._options.scale;
  36189. this.lineOptions['class'] = 'dx-range-selector-date-marker';
  36190. this._renderer.createLine(options.x, options.y, options.x, options.y + scaleOptions.marker.separatorHeight, this.lineOptions).append(options.group);
  36191. dateFormated = this._getLabel(date, options.label);
  36192. labelPosX = options.x + scaleOptions.tick.width + scaleOptions.marker.textLeftIndent;
  36193. labelPosY = options.y + scaleOptions.marker.textTopIndent + scaleOptions.label.font.size;
  36194. this.textOptions.align = 'left';
  36195. textElement = this._renderer.createText(dateFormated, labelPosX, labelPosY, this.textOptions).append(options.group);
  36196. return labelPosX + textElement.getBBox().width
  36197. },
  36198. _drawDateMarkers: function(dates, group) {
  36199. var dateMarker,
  36200. i,
  36201. datesDifferences,
  36202. markerDate,
  36203. posX,
  36204. prevMarkerRightX = -1;
  36205. if (this._options.scale.valueType !== 'datetime' || !this.visibleMarkers)
  36206. return;
  36207. var markerDatePositions = [];
  36208. if (dates.length > 1) {
  36209. for (i = 1; i < dates.length; i++) {
  36210. datesDifferences = utils.getDatesDifferences(dates[i - 1], dates[i]);
  36211. this._prepareDatesDifferences(datesDifferences, this.dateUnitInterval);
  36212. if (datesDifferences.count > 0) {
  36213. markerDate = this._getMarkerDate(dates[i], this.dateUnitInterval);
  36214. this.markerDates = this.markerDates || [];
  36215. this.markerDates.push(markerDate);
  36216. posX = this.translator.translate(markerDate);
  36217. if (posX > prevMarkerRightX) {
  36218. posX !== null && markerDatePositions.push({
  36219. date: markerDate,
  36220. posX: posX
  36221. });
  36222. prevMarkerRightX = this._drawDateMarker(markerDate, {
  36223. group: group,
  36224. y: this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight + this._options.scale.marker.topIndent,
  36225. x: posX,
  36226. label: this._getLabelFormatOptions(formatHelper.getDateFormatByDifferences(datesDifferences))
  36227. })
  36228. }
  36229. }
  36230. }
  36231. this._initializeMarkersEvents(markerDatePositions, group)
  36232. }
  36233. },
  36234. _getLabelFormatOptions: function(formatString) {
  36235. if (!utils.isDefined(this._options.scale.marker.label.format))
  36236. return $.extend({}, this._options.scale.marker.label, {format: formatString});
  36237. return this._options.scale.marker.label
  36238. },
  36239. _calculateRangeByMarkerPosition: function(posX, markerDatePositions, scaleOptions) {
  36240. var selectedRange = {},
  36241. i,
  36242. position;
  36243. for (i = 0; i < markerDatePositions.length; i++) {
  36244. position = markerDatePositions[i];
  36245. if (!scaleOptions.inverted) {
  36246. if (posX >= position.posX)
  36247. selectedRange.startValue = position.date;
  36248. else if (!selectedRange.endValue)
  36249. selectedRange.endValue = position.date
  36250. }
  36251. else if (posX < position.posX)
  36252. selectedRange.endValue = position.date;
  36253. else if (!selectedRange.startValue)
  36254. selectedRange.startValue = position.date
  36255. }
  36256. selectedRange.startValue = selectedRange.startValue || scaleOptions.startValue;
  36257. selectedRange.endValue = selectedRange.endValue || scaleOptions.endValue;
  36258. return selectedRange
  36259. },
  36260. _initializeMarkersEvents: function(markerDatePositions, group) {
  36261. var that = this,
  36262. markersAreaTop = this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight + this._options.scale.marker.topIndent,
  36263. markersTracker,
  36264. svgOffsetLeft,
  36265. index,
  36266. posX,
  36267. selectedRange;
  36268. if (markerDatePositions.length > 0) {
  36269. markersTracker = that._renderer.createRect(that._options.canvas.left, markersAreaTop, that._options.canvas.width, that._options.scale.marker.separatorHeight, 0, {
  36270. fill: 'grey',
  36271. stroke: 'grey',
  36272. opacity: 0.0001
  36273. });
  36274. markersTracker.append(group);
  36275. markersTracker.on(rangeSelector.events.start, function(e) {
  36276. svgOffsetLeft = rangeSelector.utils.getRootOffsetLeft(that._renderer);
  36277. posX = rangeSelector.utils.getEventPageX(e) - svgOffsetLeft;
  36278. selectedRange = that._calculateRangeByMarkerPosition(posX, markerDatePositions, that._options.scale);
  36279. that._options.setSelectedRange(selectedRange)
  36280. });
  36281. that._markersTracker = markersTracker
  36282. }
  36283. },
  36284. _getLabel: function(value, options) {
  36285. var formatObject = {
  36286. value: value,
  36287. valueText: formatHelper.format(value, options.format, options.precision)
  36288. };
  36289. return String(utils.isFunction(options.customizeText) ? options.customizeText.call(formatObject, formatObject) : formatObject.valueText)
  36290. },
  36291. _drawLabel: function(value, group) {
  36292. var textY = this._options.canvas.top + this._options.canvas.height - this.markersAreaHeight,
  36293. textElement = this._renderer.createText(this._getLabel(value, this._options.scale.label), this.translator.translate(value), textY, this.textOptions);
  36294. textElement.append(group);
  36295. this.textElements = this.textElements || [];
  36296. this.textElements.push(textElement)
  36297. },
  36298. _drawTick: function(value, group) {
  36299. this.lineOptions['class'] = 'dx-range-selector-tick';
  36300. var secondY = this._options.canvas.top + this._options.canvas.height - this.scaleLabelsAreaHeight,
  36301. posX = this.translator.translate(value),
  36302. tickElement = this._renderer.createLine(posX, this._options.canvas.top, posX, secondY, this.lineOptions).append(group);
  36303. this.tickElements = this.tickElements || [];
  36304. this.tickElements.push(tickElement)
  36305. },
  36306. _redraw: function(group, isOptimize) {
  36307. var that = this,
  36308. scaleOptions = that._options.scale,
  36309. ticksGroup = that._renderer.createGroup(),
  36310. labelsGroup = that._renderer.createGroup().append(group),
  36311. majorTicks = scaleOptions.ticksInfo.majorTicks,
  36312. minorTicks = scaleOptions.ticksInfo.minorTicks,
  36313. customBoundaryTicks = scaleOptions.ticksInfo.customBoundaryTicks,
  36314. hideLabels = that._options.hideLabels || majorTicks.hideLabels || !scaleOptions.label.visible,
  36315. i;
  36316. for (i = 0; i < majorTicks.length; i++) {
  36317. if (!hideLabels)
  36318. that._drawLabel(majorTicks[i], labelsGroup);
  36319. that._drawTick(majorTicks[i], ticksGroup)
  36320. }
  36321. if (scaleOptions.showMinorTicks)
  36322. for (i = 0; i < minorTicks.length; i++)
  36323. that._drawTick(minorTicks[i], ticksGroup);
  36324. for (i = 0; i < customBoundaryTicks.length; i++)
  36325. that._drawTick(customBoundaryTicks[i], ticksGroup);
  36326. ticksGroup.append(group);
  36327. that._drawDateMarkers(majorTicks, labelsGroup)
  36328. },
  36329. _applyOptions: function(options) {
  36330. var scaleOptions = options.scale,
  36331. labelsAreaHeight;
  36332. this.textOptions = {
  36333. align: 'center',
  36334. 'class': 'dx-range-selector-scale',
  36335. font: scaleOptions.label.font,
  36336. style: {'-webkit-user-select': 'none'}
  36337. };
  36338. this.lineOptions = {
  36339. strokeWidth: scaleOptions.tick.width,
  36340. stroke: scaleOptions.tick.color,
  36341. strokeOpacity: scaleOptions.tick.opacity
  36342. };
  36343. this._setupDateUnitInterval(scaleOptions);
  36344. this.visibleMarkers = scaleOptions.marker.visible === undefined ? true : scaleOptions.marker.visible;
  36345. labelsAreaHeight = scaleOptions.label.visible ? scaleOptions.label.topIndent + scaleOptions.label.font.size : 0;
  36346. this.scaleLabelsAreaHeight = options.scaleLabelsAreaHeight;
  36347. this.markersAreaHeight = this.scaleLabelsAreaHeight - labelsAreaHeight;
  36348. this.translator = options.translator
  36349. },
  36350. _draw: function(group) {
  36351. this._redraw(group, false)
  36352. },
  36353. _update: function(group) {
  36354. var callBase = this.callBase;
  36355. if (this._markersTracker)
  36356. this._markersTracker.off(rangeSelector.events.start, '**');
  36357. this.callBase = callBase;
  36358. this.callBase(group)
  36359. }
  36360. })
  36361. })(jQuery, DevExpress);
  36362. /*! Module viz-rangeselector, file rangeFactory.js */
  36363. (function($, DX, undefined) {
  36364. var rangeSelector = DX.viz.rangeSelector,
  36365. renderers = DX.viz.renderers;
  36366. rangeSelector.rangeSelectorFactory = function() {
  36367. return {
  36368. createRangeContainer: function(rangeContainerOptions) {
  36369. return new rangeSelector.RangeContainer(rangeContainerOptions)
  36370. },
  36371. createSlidersContainer: function(options) {
  36372. return new rangeSelector.SlidersContainer(options)
  36373. },
  36374. createScale: function(options) {
  36375. return new rangeSelector.Scale(options)
  36376. },
  36377. createSliderMarker: function(options) {
  36378. return new rangeSelector.SliderMarker(options)
  36379. },
  36380. createRangeView: function(options) {
  36381. return new rangeSelector.RangeView(options)
  36382. },
  36383. createThemeManager: function(options) {
  36384. return new rangeSelector.ThemeManager(options)
  36385. },
  36386. createSlider: function(renderer, sliderIndex) {
  36387. return new rangeSelector.Slider(renderer, sliderIndex)
  36388. },
  36389. createSlidersEventsManager: function(renderer, slidersController, processSelectionChanged) {
  36390. return new rangeSelector.SlidersEventsManager(renderer, slidersController, processSelectionChanged)
  36391. },
  36392. createSlidersController: function(sliders) {
  36393. return new rangeSelector.SlidersController(sliders)
  36394. }
  36395. }
  36396. }()
  36397. })(jQuery, DevExpress);
  36398. /*! Module viz-rangeselector, file slidersContainer.js */
  36399. (function($, DX, undefined) {
  36400. var rangeSelector = DX.viz.rangeSelector,
  36401. utils = DX.utils;
  36402. var msPointerEnabled = window.navigator.msPointerEnabled || window.navigator.pointerEnabled;
  36403. var isNumber = DX.utils.isNumber;
  36404. var isDate = DX.utils.isDate;
  36405. var START_VALUE_INDEX = 0,
  36406. END_VALUE_INDEX = 1;
  36407. rangeSelector.SlidersContainer = rangeSelector.BaseVisualElement.inherit(function() {
  36408. var prototypeObject = {
  36409. getController: function() {
  36410. return this._controller
  36411. },
  36412. _drawAreaTracker: function(group) {
  36413. var that = this,
  36414. areaTracker,
  36415. selectedAreaTracker;
  36416. areaTracker = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0, {
  36417. fill: 'grey',
  36418. stroke: 'grey',
  36419. opacity: 0.0001
  36420. });
  36421. areaTracker.append(group);
  36422. selectedAreaTracker = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0, {
  36423. fill: 'grey',
  36424. stroke: 'grey',
  36425. opacity: 0.0001,
  36426. style: {cursor: 'pointer'}
  36427. });
  36428. selectedAreaTracker.append(group);
  36429. that._controller.setAreaTrackers(areaTracker, selectedAreaTracker)
  36430. },
  36431. dispose: function() {
  36432. this._eventsManager.dispose();
  36433. this._eventManager = null
  36434. },
  36435. _processSelectionChanged: function(moving, blockSelectedRangeChanged) {
  36436. var that = this,
  36437. equalLastSelectedRange = function(selectedRange) {
  36438. return selectedRange && that._lastSelectedRange.startValue === selectedRange.startValue && that._lastSelectedRange.endValue === selectedRange.endValue
  36439. },
  36440. selectedRange = that.getSelectedRange();
  36441. if ((!moving || (that._options.behavior.callSelectedRangeChanged || '').toLowerCase() === "onmoving") && that._options.selectedRangeChanged && !equalLastSelectedRange(selectedRange)) {
  36442. that._updateLastSelectedRange(selectedRange);
  36443. if (typeof that._options.selectedRangeChanged === 'function')
  36444. that._options.selectedRangeChanged.call(null, selectedRange, blockSelectedRangeChanged);
  36445. if (!moving && !equalLastSelectedRange(selectedRange))
  36446. that.setSelectedRange(selectedRange)
  36447. }
  36448. },
  36449. _updateLastSelectedRange: function(selectedRange) {
  36450. selectedRange = selectedRange || this._options.selectedRange;
  36451. this._lastSelectedRange = {
  36452. startValue: selectedRange.startValue,
  36453. endValue: selectedRange.endValue
  36454. }
  36455. },
  36456. _createSlider: function(sliderIndex) {
  36457. return rangeSelector.rangeSelectorFactory.createSlider(this._renderer, sliderIndex)
  36458. },
  36459. _createSlidersController: function(sliders) {
  36460. return rangeSelector.rangeSelectorFactory.createSlidersController(sliders)
  36461. },
  36462. _createSlidersEventsManager: function(controller) {
  36463. var that = this;
  36464. return rangeSelector.rangeSelectorFactory.createSlidersEventsManager(that._renderer, controller, function(moving) {
  36465. that._processSelectionChanged(moving)
  36466. })
  36467. },
  36468. ctor: function(renderer) {
  36469. var that = this,
  36470. sliders;
  36471. that.callBase(renderer);
  36472. sliders = [that._createSlider(START_VALUE_INDEX), that._createSlider(END_VALUE_INDEX)];
  36473. that._controller = that._createSlidersController(sliders);
  36474. that._eventsManager = that._createSlidersEventsManager(that._controller);
  36475. that._lastSelectedRange = {}
  36476. },
  36477. getSelectedRange: function() {
  36478. return this._controller.getSelectedRange()
  36479. },
  36480. truncateSelectedRange: function(value, scaleOptions) {
  36481. var min = scaleOptions.startValue > scaleOptions.endValue ? scaleOptions.endValue : scaleOptions.startValue,
  36482. max = scaleOptions.startValue > scaleOptions.endValue ? scaleOptions.startValue : scaleOptions.endValue;
  36483. if (value < min)
  36484. value = min;
  36485. if (value > max)
  36486. value = max;
  36487. return value
  36488. },
  36489. setSelectedRange: function(selectedRange) {
  36490. var that = this,
  36491. scale = that._options.scale,
  36492. startValue,
  36493. endValue,
  36494. currentSelectedRange = that._options.selectedRange;
  36495. if (selectedRange) {
  36496. startValue = selectedRange.startValue;
  36497. endValue = selectedRange.endValue
  36498. }
  36499. if (isNumber(scale.startValue) && isNumber(startValue) || isDate(scale.startValue) && isDate(startValue))
  36500. currentSelectedRange.startValue = startValue;
  36501. if (isNumber(scale.endValue) && isNumber(endValue) || isDate(scale.endValue) && isDate(endValue))
  36502. currentSelectedRange.endValue = endValue;
  36503. currentSelectedRange.startValue = that.truncateSelectedRange(currentSelectedRange.startValue, scale);
  36504. currentSelectedRange.endValue = that.truncateSelectedRange(currentSelectedRange.endValue, scale);
  36505. that._controller.applySelectedRange(currentSelectedRange);
  36506. that._controller.applyPosition();
  36507. that._processSelectionChanged(false, selectedRange && selectedRange.blockSelectedRangeChanged)
  36508. },
  36509. appendTrackers: function(group) {
  36510. this._controller.appendTrackers(group)
  36511. },
  36512. _applyOptions: function(options) {
  36513. var that = this;
  36514. that._controller.applyOptions({
  36515. translator: options.translator,
  36516. canvas: options.canvas,
  36517. sliderMarker: options.sliderMarker,
  36518. sliderHandle: options.sliderHandle,
  36519. shutter: options.shutter,
  36520. scale: options.scale,
  36521. behavior: options.behavior
  36522. });
  36523. that._eventsManager.applyOptions({behavior: options.behavior})
  36524. },
  36525. _draw: function(group) {
  36526. var that = this,
  36527. rootElement;
  36528. if (msPointerEnabled) {
  36529. rootElement = that._renderer.getRoot();
  36530. rootElement && (rootElement.element.style.msTouchAction = "pinch-zoom")
  36531. }
  36532. that._controller.redraw(group);
  36533. that._drawAreaTracker(group);
  36534. that._eventsManager.initialize();
  36535. that._update()
  36536. },
  36537. _update: function() {
  36538. var that = this,
  36539. isEmpty = that._options.isEmpty;
  36540. that._eventsManager.setEnabled(!isEmpty);
  36541. that._controller.applySelectedRange(isEmpty ? {} : that._options.selectedRange);
  36542. that._controller.applyPosition(that.isDrawn());
  36543. that._updateLastSelectedRange();
  36544. that._controller.redraw()
  36545. }
  36546. };
  36547. return prototypeObject
  36548. }())
  36549. })(jQuery, DevExpress);
  36550. /*! Module viz-rangeselector, file slidersController.js */
  36551. (function($, DX, undefined) {
  36552. var rangeSelector = DX.viz.rangeSelector,
  36553. utils = DX.utils;
  36554. var START_VALUE_INDEX = 0,
  36555. END_VALUE_INDEX = 1;
  36556. rangeSelector.SlidersController = DX.Class.inherit(function() {
  36557. return {
  36558. ctor: function(sliders) {
  36559. this._sliders = sliders;
  36560. sliders[START_VALUE_INDEX].setAnotherSlider(sliders[END_VALUE_INDEX]);
  36561. sliders[END_VALUE_INDEX].setAnotherSlider(sliders[START_VALUE_INDEX])
  36562. },
  36563. setAreaTrackers: function(areaTracker, selectedAreaTracker) {
  36564. this._areaTracker = areaTracker;
  36565. this._selectedAreaTracker = selectedAreaTracker
  36566. },
  36567. applyOptions: function(options) {
  36568. var that = this,
  36569. values = null;
  36570. that._options = options;
  36571. that.getSlider(START_VALUE_INDEX).applyOptions(options);
  36572. that.getSlider(END_VALUE_INDEX).applyOptions(options);
  36573. if (options.behavior.snapToTicks) {
  36574. values = options.scale.ticksInfo.fullTicks;
  36575. if (values.length > 1 && values[0] > values[values.length - 1])
  36576. values = values.reverse()
  36577. }
  36578. that.getSlider(START_VALUE_INDEX).setAvailableValues(values);
  36579. that.getSlider(END_VALUE_INDEX).setAvailableValues(values)
  36580. },
  36581. processDocking: function(sliderIndex) {
  36582. var that = this;
  36583. if (sliderIndex !== undefined)
  36584. that.getSlider(sliderIndex).processDocking();
  36585. else {
  36586. that.getSlider(START_VALUE_INDEX).processDocking();
  36587. that.getSlider(END_VALUE_INDEX).processDocking()
  36588. }
  36589. that.setTrackersCursorStyle('default');
  36590. that.applyAreaTrackersPosition()
  36591. },
  36592. getSelectedRangeInterval: function() {
  36593. var that = this,
  36594. type = that._options.scale.type,
  36595. base = that._options.scale.logarithmBase,
  36596. startValue = that.getSlider(START_VALUE_INDEX).getValue(),
  36597. endValue = that.getSlider(END_VALUE_INDEX).getValue();
  36598. if (type === 'logarithmic')
  36599. return rangeSelector.utils.getInterval(utils.getLog(startValue, base), utils.getLog(endValue, base));
  36600. else
  36601. return rangeSelector.utils.getInterval(startValue, endValue)
  36602. },
  36603. moveSliders: function(postitionDelta, selectedRangeInterval) {
  36604. var that = this;
  36605. that.getSlider(START_VALUE_INDEX).setPosition(that.getSlider(START_VALUE_INDEX).getPosition() + postitionDelta, false, selectedRangeInterval);
  36606. that.applyPosition(true)
  36607. },
  36608. moveSlider: function(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, startOffsetPositionChangedCallback) {
  36609. var that = this,
  36610. slider = that.getSlider(sliderIndex),
  36611. anotherSlider = slider.getAnotherSlider(),
  36612. anotherSliderIndex = anotherSlider.getIndex(),
  36613. doSwap;
  36614. if (slider.canSwap())
  36615. if (sliderIndex === START_VALUE_INDEX ? position > anotherSlider.getPosition() : position < anotherSlider.getPosition()) {
  36616. doSwap = fastSwap;
  36617. if (!fastSwap)
  36618. if (Math.abs(offsetPosition) >= Math.abs(startOffsetPosition) && offsetPosition * startOffsetPosition < 0) {
  36619. doSwap = true;
  36620. position += 2 * startOffsetPosition;
  36621. startOffsetPositionChangedCallback(-startOffsetPosition)
  36622. }
  36623. if (doSwap) {
  36624. that.swapSliders();
  36625. anotherSlider.applyPosition(true)
  36626. }
  36627. }
  36628. slider.setPosition(position, true);
  36629. slider.applyPosition(true);
  36630. that.applyAreaTrackersPosition();
  36631. that.setTrackersCursorStyle('w-resize')
  36632. },
  36633. applySelectedAreaCenterPosition: function(pos) {
  36634. var that = this,
  36635. slidersContainerHalfWidth = (that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition()) / 2,
  36636. selectedRangeInterval = that.getSelectedRangeInterval();
  36637. that.getSlider(START_VALUE_INDEX).setPosition(pos - slidersContainerHalfWidth, false, selectedRangeInterval);
  36638. that.applyPosition();
  36639. that.processDocking()
  36640. },
  36641. processManualSelection: function(startPosition, endPosition, eventArgs) {
  36642. var that = this,
  36643. animateSliderIndex,
  36644. movingSliderIndex,
  36645. positionRange = [Math.min(startPosition, endPosition), Math.max(startPosition, endPosition)];
  36646. animateSliderIndex = startPosition < endPosition ? START_VALUE_INDEX : END_VALUE_INDEX;
  36647. movingSliderIndex = startPosition < endPosition ? END_VALUE_INDEX : START_VALUE_INDEX;
  36648. that.getSlider(movingSliderIndex).setPosition(positionRange[movingSliderIndex]);
  36649. that.getSlider(animateSliderIndex).setPosition(positionRange[animateSliderIndex]);
  36650. that.getSlider(movingSliderIndex).setPosition(positionRange[movingSliderIndex], true);
  36651. that.getSlider(movingSliderIndex).startEventHandler(eventArgs);
  36652. that.getSlider(animateSliderIndex).processDocking();
  36653. that.getSlider(movingSliderIndex).applyPosition(true)
  36654. },
  36655. applySelectedRange: function(selectedRange) {
  36656. var that = this,
  36657. inverted = that._options.scale.inverted;
  36658. utils.debug.assertParam(selectedRange, 'selectedRange not passed');
  36659. if (!inverted && selectedRange.startValue > selectedRange.endValue || inverted && selectedRange.startValue < selectedRange.endValue) {
  36660. that.getSlider(START_VALUE_INDEX).setValue(selectedRange.endValue);
  36661. that.getSlider(END_VALUE_INDEX).setValue(selectedRange.startValue)
  36662. }
  36663. else {
  36664. that.getSlider(START_VALUE_INDEX).setValue(selectedRange.startValue);
  36665. that.getSlider(END_VALUE_INDEX).setValue(selectedRange.endValue)
  36666. }
  36667. },
  36668. getSelectedRange: function() {
  36669. var that = this;
  36670. return {
  36671. startValue: that.getSlider(START_VALUE_INDEX).getValue(),
  36672. endValue: that.getSlider(END_VALUE_INDEX).getValue()
  36673. }
  36674. },
  36675. swapSliders: function() {
  36676. var that = this;
  36677. that._sliders.reverse();
  36678. that.getSlider(START_VALUE_INDEX).changeLocation();
  36679. that.getSlider(END_VALUE_INDEX).changeLocation()
  36680. },
  36681. applyAreaTrackersPosition: function() {
  36682. var that = this,
  36683. selectedRange = that.getSelectedRange(),
  36684. scaleOptions = that._options.scale,
  36685. width = that.getSlider(END_VALUE_INDEX).getPosition() - that.getSlider(START_VALUE_INDEX).getPosition(),
  36686. options = {
  36687. x: that.getSlider(START_VALUE_INDEX).getPosition(),
  36688. width: width < 0 ? 0 : width,
  36689. y: that._options.canvas.top,
  36690. height: that._options.canvas.height,
  36691. style: {cursor: scaleOptions.endValue - scaleOptions.startValue === selectedRange.endValue - selectedRange.startValue ? 'default' : 'pointer'}
  36692. };
  36693. that._selectedAreaTracker.applySettings(options);
  36694. that._areaTracker.applySettings({
  36695. x: that._options.canvas.left,
  36696. width: that._options.canvas.width,
  36697. y: that._options.canvas.top,
  36698. height: that._options.canvas.height
  36699. })
  36700. },
  36701. applyPosition: function(disableAnimation) {
  36702. var that = this;
  36703. that.getSlider(START_VALUE_INDEX).applyPosition(disableAnimation);
  36704. that.getSlider(END_VALUE_INDEX).applyPosition(disableAnimation);
  36705. that.applyAreaTrackersPosition()
  36706. },
  36707. redraw: function(group) {
  36708. var that = this;
  36709. that.getSlider(START_VALUE_INDEX).redraw(group);
  36710. that.getSlider(END_VALUE_INDEX).redraw(group)
  36711. },
  36712. appendTrackers: function(group) {
  36713. var that = this;
  36714. if (that._areaTracker && that._selectedAreaTracker) {
  36715. that._areaTracker.append(group);
  36716. that._selectedAreaTracker.append(group)
  36717. }
  36718. that.getSlider(START_VALUE_INDEX).appendTrackers(group);
  36719. that.getSlider(END_VALUE_INDEX).appendTrackers(group)
  36720. },
  36721. getSlider: function(sliderIndex) {
  36722. return this._sliders[sliderIndex]
  36723. },
  36724. getAreaTracker: function() {
  36725. return this._areaTracker
  36726. },
  36727. getSelectedAreaTracker: function() {
  36728. return this._selectedAreaTracker
  36729. },
  36730. setTrackersCursorStyle: function(style) {
  36731. var that = this;
  36732. that._selectedAreaTracker.applySettings({style: {cursor: style}});
  36733. that._areaTracker.applySettings({style: {cursor: style}})
  36734. }
  36735. }
  36736. }())
  36737. })(jQuery, DevExpress);
  36738. /*! Module viz-rangeselector, file slidersEventsManager.js */
  36739. (function($, DX, undefined) {
  36740. var rangeSelector = DX.viz.rangeSelector,
  36741. utils = DX.utils,
  36742. MIN_MANUAL_SELECTING_WIDTH = 10,
  36743. START_VALUE_INDEX = 0,
  36744. END_VALUE_INDEX = 1,
  36745. addNamespace = DX.ui.events.addNamespace,
  36746. setEvents = function() {
  36747. var win = window;
  36748. win = DX.viz.rangeSelector.mockWindow || window;
  36749. var touchSupport = "ontouchstart" in win,
  36750. msPointerEnabled = win.navigator.msPointerEnabled,
  36751. pointerEnabled = win.navigator.pointerEnabled;
  36752. rangeSelector.events = {
  36753. start: pointerEnabled ? "pointerdown" : msPointerEnabled ? "MSPointerDown" : touchSupport ? "touchstart mousedown" : "mousedown",
  36754. move: pointerEnabled ? "pointermove" : msPointerEnabled ? "MSPointerMove" : touchSupport ? "touchmove mousemove" : "mousemove",
  36755. end: pointerEnabled ? "pointerup pointercancel" : msPointerEnabled ? "MSPointerUp MSPointerCancel" : touchSupport ? "touchend mouseup" : "mouseup"
  36756. }
  36757. },
  36758. _SlidersEventManager,
  36759. getEventPageX = rangeSelector.utils.getEventPageX,
  36760. rangeSelectorCount = 0;
  36761. setEvents();
  36762. var isLeftButtonPressed = function(event) {
  36763. var e = event || window.event,
  36764. originalEvent = e.originalEvent,
  36765. touches = e.touches,
  36766. pointerType = originalEvent ? originalEvent.pointerType : false,
  36767. eventTouches = originalEvent ? originalEvent.touches : false,
  36768. isIE8LeftClick = e.which === undefined && e.button === 1,
  36769. isMSPointerLeftClick = originalEvent && pointerType !== undefined && (pointerType === (originalEvent.MSPOINTER_TYPE_TOUCH || 'touch') || pointerType === (originalEvent.MSPOINTER_TYPE_MOUSE || 'mouse') && originalEvent.buttons === 1),
  36770. isLeftClick = isIE8LeftClick || e.which === 1,
  36771. isTouches = touches && touches.length > 0 || eventTouches && eventTouches.length > 0;
  36772. return isLeftClick || isMSPointerLeftClick || isTouches
  36773. };
  36774. var isMultiTouches = function(event) {
  36775. var originalEvent = event.originalEvent,
  36776. touches = event.touches,
  36777. eventTouches = originalEvent ? originalEvent.touches : false;
  36778. return touches && touches.length > 1 || eventTouches && eventTouches.length > 1 || null
  36779. };
  36780. var isTouchEventArgs = function(e) {
  36781. return e && e.type && e.type.indexOf('touch') === 0
  36782. };
  36783. _SlidersEventManager = rangeSelector.SlidersEventsManager = function(renderer, slidersController, processSelectionChanged) {
  36784. var that = this,
  36785. uniqueNS = that._uniqueNS = 'dx-range-selector_' + rangeSelectorCount++,
  36786. rangeSelectorEvents = rangeSelector.events;
  36787. that._renderer = renderer;
  36788. that._slidersController = slidersController;
  36789. that._processSelectionChanged = processSelectionChanged;
  36790. that._enabled = true;
  36791. that._eventsNames = {
  36792. start: addNamespace(rangeSelectorEvents.start, uniqueNS),
  36793. move: addNamespace(rangeSelectorEvents.move, uniqueNS),
  36794. end: addNamespace(rangeSelectorEvents.end, uniqueNS)
  36795. }
  36796. };
  36797. _SlidersEventManager.prototype = {
  36798. constructor: _SlidersEventManager,
  36799. _getRootOffsetLeft: function() {
  36800. return rangeSelector.utils.getRootOffsetLeft(this._renderer)
  36801. },
  36802. _initializeSliderEvents: function(sliderIndex) {
  36803. var that = this,
  36804. renderer = that._renderer,
  36805. isTouchEvent,
  36806. slidersController = that._slidersController,
  36807. processSelectionChanged = that._processSelectionChanged,
  36808. slider = slidersController.getSlider(sliderIndex),
  36809. anotherSlider = slider.getAnotherSlider(),
  36810. fastSwap,
  36811. startOffsetPosition,
  36812. splitterMoving,
  36813. sliderEndHandler = function(e) {
  36814. if (splitterMoving) {
  36815. splitterMoving = false;
  36816. slidersController.processDocking();
  36817. processSelectionChanged(false)
  36818. }
  36819. },
  36820. sliderMoveHandler = function(e) {
  36821. var doSwap,
  36822. pageX,
  36823. offsetPosition,
  36824. svgOffsetLeft = that._getRootOffsetLeft(),
  36825. position,
  36826. sliderIndex = slider.getIndex();
  36827. if (isTouchEvent !== isTouchEventArgs(e))
  36828. return;
  36829. if (!isLeftButtonPressed(e, true) && splitterMoving) {
  36830. splitterMoving = false;
  36831. slidersController.processDocking();
  36832. processSelectionChanged(false)
  36833. }
  36834. else if (splitterMoving) {
  36835. if (!isMultiTouches(e)) {
  36836. this.preventedDefault = true;
  36837. e.preventDefault()
  36838. }
  36839. pageX = getEventPageX(e);
  36840. position = pageX - startOffsetPosition - svgOffsetLeft;
  36841. offsetPosition = pageX - slider.getPosition() - svgOffsetLeft;
  36842. slidersController.moveSlider(sliderIndex, fastSwap, position, offsetPosition, startOffsetPosition, function(newStartOffsetPosition) {
  36843. startOffsetPosition = newStartOffsetPosition
  36844. });
  36845. processSelectionChanged(true)
  36846. }
  36847. },
  36848. eventsNames = that._eventsNames;
  36849. slider.startEventHandler = function(e) {
  36850. if (!that._enabled || !isLeftButtonPressed(e) || splitterMoving)
  36851. return;
  36852. fastSwap = this === slider.getSliderTracker().element;
  36853. splitterMoving = true;
  36854. isTouchEvent = isTouchEventArgs(e);
  36855. startOffsetPosition = getEventPageX(e) - slider.getPosition() - that._getRootOffsetLeft();
  36856. if (!isMultiTouches(e)) {
  36857. this.preventedDefault = true;
  36858. e.stopPropagation();
  36859. e.preventDefault()
  36860. }
  36861. };
  36862. slider.on(eventsNames.start, slider.startEventHandler);
  36863. $(document).on(eventsNames.end, sliderEndHandler).on(eventsNames.move, sliderMoveHandler);
  36864. slider.__moveEventHandler = sliderMoveHandler
  36865. },
  36866. _initializeAreaEvents: function() {
  36867. var that = this,
  36868. renderer = that._renderer,
  36869. isTouchEvent,
  36870. slidersController = that._slidersController,
  36871. processSelectionChanged = that._processSelectionChanged,
  36872. areaTracker = slidersController.getAreaTracker(),
  36873. unselectedAreaProcessing = false,
  36874. splitterMoving = false,
  36875. startPageX,
  36876. areaEndHandler = function(e) {
  36877. var pageX;
  36878. if (unselectedAreaProcessing) {
  36879. pageX = getEventPageX(e);
  36880. if (that._options.behavior.moveSelectedRangeByClick && Math.abs(startPageX - pageX) < MIN_MANUAL_SELECTING_WIDTH)
  36881. slidersController.applySelectedAreaCenterPosition(pageX - that._getRootOffsetLeft());
  36882. unselectedAreaProcessing = false;
  36883. processSelectionChanged(false)
  36884. }
  36885. },
  36886. areaMoveHandler = function(e) {
  36887. var pageX,
  36888. startPosition,
  36889. endPosition,
  36890. svgOffsetLeft = that._getRootOffsetLeft();
  36891. if (isTouchEvent !== isTouchEventArgs(e))
  36892. return;
  36893. if (unselectedAreaProcessing && !isLeftButtonPressed(e)) {
  36894. unselectedAreaProcessing = false;
  36895. processSelectionChanged(false)
  36896. }
  36897. if (unselectedAreaProcessing) {
  36898. pageX = getEventPageX(e);
  36899. if (that._options.behavior.manualRangeSelectionEnabled && Math.abs(startPageX - pageX) >= MIN_MANUAL_SELECTING_WIDTH) {
  36900. startPosition = startPageX - svgOffsetLeft;
  36901. endPosition = pageX - svgOffsetLeft;
  36902. slidersController.processManualSelection(startPosition, endPosition, e);
  36903. unselectedAreaProcessing = false;
  36904. processSelectionChanged(true)
  36905. }
  36906. }
  36907. },
  36908. eventsNames = that._eventsNames;
  36909. areaTracker.on(eventsNames.start, function(e) {
  36910. if (!that._enabled || !isLeftButtonPressed(e) || unselectedAreaProcessing)
  36911. return;
  36912. unselectedAreaProcessing = true;
  36913. isTouchEvent = isTouchEventArgs(e);
  36914. startPageX = getEventPageX(e)
  36915. });
  36916. $(document).on(eventsNames.end, areaEndHandler).on(eventsNames.move, areaMoveHandler);
  36917. that.__areaMoveEventHandler = areaMoveHandler
  36918. },
  36919. _initializeSelectedAreaEvents: function() {
  36920. var that = this,
  36921. renderer = that._renderer,
  36922. isTouchEvent,
  36923. slidersController = that._slidersController,
  36924. processSelectionChanged = that._processSelectionChanged,
  36925. selectedAreaTracker = slidersController.getSelectedAreaTracker(),
  36926. selectedAreaMoving = false,
  36927. offsetStartPosition,
  36928. selectedRangeInterval,
  36929. selectedAreaEndHandler = function(e) {
  36930. if (selectedAreaMoving) {
  36931. selectedAreaMoving = false;
  36932. slidersController.processDocking();
  36933. processSelectionChanged(false)
  36934. }
  36935. },
  36936. selectedAreaMoveHandler = function(e) {
  36937. var positionDelta,
  36938. pageX;
  36939. if (isTouchEvent !== isTouchEventArgs(e))
  36940. return;
  36941. if (selectedAreaMoving && !isLeftButtonPressed(e)) {
  36942. selectedAreaMoving = false;
  36943. slidersController.processDocking();
  36944. processSelectionChanged(false)
  36945. }
  36946. if (selectedAreaMoving) {
  36947. if (!isMultiTouches(e)) {
  36948. this.preventedDefault = true;
  36949. e.preventDefault()
  36950. }
  36951. pageX = getEventPageX(e);
  36952. positionDelta = pageX - slidersController.getSlider(START_VALUE_INDEX).getPosition() - offsetStartPosition;
  36953. slidersController.moveSliders(positionDelta, selectedRangeInterval);
  36954. processSelectionChanged(true)
  36955. }
  36956. },
  36957. eventsNames = that._eventsNames;
  36958. selectedAreaTracker.on(eventsNames.start, function(e) {
  36959. if (!that._enabled || !isLeftButtonPressed(e) || selectedAreaMoving)
  36960. return;
  36961. selectedAreaMoving = true;
  36962. isTouchEvent = isTouchEventArgs(e);
  36963. offsetStartPosition = getEventPageX(e) - slidersController.getSlider(START_VALUE_INDEX).getPosition();
  36964. selectedRangeInterval = slidersController.getSelectedRangeInterval();
  36965. if (!isMultiTouches(e)) {
  36966. this.preventedDefault = true;
  36967. e.stopPropagation();
  36968. e.preventDefault()
  36969. }
  36970. });
  36971. $(document).on(eventsNames.end, selectedAreaEndHandler).on(eventsNames.move, selectedAreaMoveHandler);
  36972. that.__selectedAreaMoveEventHandler = selectedAreaMoveHandler
  36973. },
  36974. applyOptions: function(options) {
  36975. this._options = options
  36976. },
  36977. dispose: function() {
  36978. $(document).off('.' + this._uniqueNS)
  36979. },
  36980. initialize: function() {
  36981. var that = this;
  36982. if (!that._renderer.isInitialized())
  36983. return;
  36984. that._initializeSelectedAreaEvents(that);
  36985. that._initializeAreaEvents();
  36986. that._initializeSliderEvents(START_VALUE_INDEX);
  36987. that._initializeSliderEvents(END_VALUE_INDEX)
  36988. },
  36989. setEnabled: function(enabled) {
  36990. this._enabled = enabled
  36991. }
  36992. };
  36993. rangeSelector.__setEvents = setEvents
  36994. })(jQuery, DevExpress);
  36995. /*! Module viz-rangeselector, file slider.js */
  36996. (function($, DX, undefined) {
  36997. var rangeSelector = DX.viz.rangeSelector,
  36998. utils = DX.utils;
  36999. var touchSupport = "ontouchstart" in window;
  37000. var msPointerEnabled = window.navigator.msPointerEnabled || window.navigator.pointerEnabled;
  37001. var animationOptions = {duration: 250};
  37002. var SPLITTER_WIDTH = 8,
  37003. TOUCH_SPLITTER_WIDTH = 20,
  37004. START_VALUE_INDEX = 0,
  37005. END_VALUE_INDEX = 1;
  37006. rangeSelector.Slider = rangeSelector.BaseVisualElement.inherit(function() {
  37007. return {
  37008. getText: function() {
  37009. if (this._marker)
  37010. return this._marker.getText()
  37011. },
  37012. getAvailableValues: function() {
  37013. return this._values
  37014. },
  37015. getShutter: function() {
  37016. return this._shutter
  37017. },
  37018. getMarker: function() {
  37019. return this._marker
  37020. },
  37021. _createSlider: function() {
  37022. var that = this,
  37023. sliderHandle,
  37024. sliderGroup,
  37025. sliderHandleOptions = that._options.sliderHandle;
  37026. sliderGroup = that._renderer.createGroup({'class': 'slider'});
  37027. sliderGroup.applySettings({
  37028. translateX: that._options.canvas.left,
  37029. translateY: that._options.canvas.top
  37030. });
  37031. sliderHandle = that._renderer.createLine(0, 0, 0, that._options.canvas.height, {
  37032. 'class': 'dx-range-selector-slider',
  37033. strokeWidth: sliderHandleOptions.width,
  37034. stroke: sliderHandleOptions.color,
  37035. strokeOpacity: sliderHandleOptions.opacity
  37036. });
  37037. sliderHandle.append(sliderGroup);
  37038. sliderGroup.setValid = function(correct) {
  37039. sliderHandle.applySettings({stroke: correct ? that._options.sliderHandle.color : that._options.sliderMarker.invalidRangeColor})
  37040. };
  37041. sliderGroup.updateHeight = function() {
  37042. sliderHandle.applySettings({points: [0, 0, 0, that._options.canvas.height]})
  37043. };
  37044. sliderGroup.applyOptions = function(options) {
  37045. sliderHandle.applySettings(options)
  37046. };
  37047. sliderGroup.__line = sliderHandle;
  37048. return sliderGroup
  37049. },
  37050. _createSliderTracker: function() {
  37051. var that = this,
  37052. sliderHandleWidth = that._options.sliderHandle.width,
  37053. splitterWidth = SPLITTER_WIDTH < sliderHandleWidth ? sliderHandleWidth : SPLITTER_WIDTH,
  37054. sliderWidth = touchSupport || msPointerEnabled ? TOUCH_SPLITTER_WIDTH : splitterWidth,
  37055. sliderTracker,
  37056. sliderTrackerGroup;
  37057. sliderTracker = that._renderer.createRect(-sliderWidth / 2, 0, sliderWidth, that._options.canvas.height, 0, {
  37058. fill: 'grey',
  37059. stroke: 'grey',
  37060. opacity: 0.0001,
  37061. style: {cursor: 'w-resize'}
  37062. });
  37063. sliderTrackerGroup = that._renderer.createGroup({'class': 'sliderTracker'});
  37064. sliderTrackerGroup.applySettings({
  37065. translateX: 0,
  37066. translateY: that._options.canvas.top
  37067. });
  37068. sliderTracker.append(sliderTrackerGroup);
  37069. sliderTrackerGroup.updateHeight = function() {
  37070. sliderTracker.applySettings({height: that._options.canvas.height})
  37071. };
  37072. sliderTrackerGroup.__rect = sliderTracker;
  37073. return sliderTrackerGroup
  37074. },
  37075. _drawSliderTracker: function(group) {
  37076. var that = this,
  37077. sliderTracker = that._createSliderTracker();
  37078. if (sliderTracker) {
  37079. sliderTracker.append(group);
  37080. that._sliderTracker = sliderTracker
  37081. }
  37082. },
  37083. _createSliderMarker: function(options) {
  37084. return rangeSelector.rangeSelectorFactory.createSliderMarker(options)
  37085. },
  37086. _setPosition: function(position, correctByMinMaxRange) {
  37087. var that = this,
  37088. correctedPosition = that._correctPosition(position),
  37089. value = that._options.translator.untranslate(correctedPosition);
  37090. that.setValue(value, correctByMinMaxRange, false);
  37091. that._position = correctedPosition
  37092. },
  37093. _setPositionForBothSliders: function(startPosition, interval) {
  37094. var that = this,
  37095. anotherSlider,
  37096. startValue,
  37097. endValue,
  37098. endPosition,
  37099. type = that._options.scale.type,
  37100. base = that._options.scale.logarithmBase,
  37101. inverted = that._options.scale.inverted;
  37102. var getNextValue = function(value, isNegative) {
  37103. var lgPower;
  37104. if (type === 'logarithmic') {
  37105. lgPower = utils.addInterval(utils.adjustValue(utils.getLog(value, base)), interval, isNegative);
  37106. return utils.raiseTo(lgPower, base)
  37107. }
  37108. else
  37109. return utils.addInterval(value, interval, isNegative)
  37110. };
  37111. anotherSlider = that.getAnotherSlider();
  37112. startPosition = that._correctBounds(startPosition);
  37113. startValue = that._options.translator.untranslate(startPosition);
  37114. endValue = getNextValue(startValue);
  37115. if (!inverted && endValue > that._options.scale.endValue || inverted && endValue < that._options.scale.endValue) {
  37116. endValue = that._options.scale.endValue;
  37117. endPosition = that._options.canvas.left + that._options.canvas.width;
  37118. startValue = getNextValue(endValue, true);
  37119. startPosition = that._options.translator.translate(startValue)
  37120. }
  37121. else
  37122. endPosition = that._options.translator.translate(endValue);
  37123. if (that._values)
  37124. if (!inverted ? startValue < that._values[0] : startValue > that._values[that._values.length - 1]) {
  37125. startValue = that._correctBusinessValueByAvailableValues(startValue, false);
  37126. endValue = getNextValue(startValue)
  37127. }
  37128. else {
  37129. endValue = that._correctBusinessValueByAvailableValues(endValue, false);
  37130. startValue = getNextValue(endValue, true)
  37131. }
  37132. anotherSlider.setValue(endValue, undefined, false);
  37133. that.setValue(startValue, undefined, false);
  37134. that._position = startPosition;
  37135. anotherSlider._position = endPosition
  37136. },
  37137. _correctPosition: function(position) {
  37138. var that = this,
  37139. correctedPosition = that._correctInversion(position);
  37140. correctedPosition = that._correctBounds(correctedPosition);
  37141. return correctedPosition
  37142. },
  37143. _correctInversion: function(position) {
  37144. var that = this,
  37145. correctedPosition = position,
  37146. anotherSliderPosition = that.getAnotherSlider().getPosition(),
  37147. slidersInverted = that.getIndex() === START_VALUE_INDEX ? position > anotherSliderPosition : position < anotherSliderPosition;
  37148. if (slidersInverted)
  37149. correctedPosition = anotherSliderPosition;
  37150. return correctedPosition
  37151. },
  37152. _correctBounds: function(position) {
  37153. var that = this,
  37154. correctedPosition = position,
  37155. canvas = that._options.canvas;
  37156. if (position < canvas.left)
  37157. correctedPosition = canvas.left;
  37158. if (position > canvas.left + canvas.width)
  37159. correctedPosition = canvas.left + canvas.width;
  37160. return correctedPosition
  37161. },
  37162. _correctBusinessValue: function(businessValue, correctByMinMaxRange, skipCorrection) {
  37163. var that = this,
  37164. result = that._correctBusinessValueByAvailableValues(businessValue, skipCorrection);
  37165. if (correctByMinMaxRange)
  37166. result = that._correctBusinessValueByMinMaxRangeFromAnotherSlider(result);
  37167. result = that._correctBusinessValueByMinRangeFromStartEndValues(result);
  37168. return result
  37169. },
  37170. _correctBusinessValueByAvailableValues: function(businessValue, skipCorrection) {
  37171. var values = this._values;
  37172. if (!skipCorrection && values)
  37173. return rangeSelector.utils.findNearValue(values, businessValue);
  37174. return businessValue
  37175. },
  37176. _correctBusinessValueByMinMaxRangeFromAnotherSlider: function(businessValue) {
  37177. var that = this,
  37178. result = businessValue,
  37179. scale = that._options.scale,
  37180. values = that._values,
  37181. sliderIndex = that.getIndex(),
  37182. anotherBusinessValue = that.getAnotherSlider().getValue(),
  37183. isValid = true,
  37184. minValue,
  37185. maxValue;
  37186. if (!scale.inverted && sliderIndex === START_VALUE_INDEX || scale.inverted && sliderIndex === END_VALUE_INDEX) {
  37187. if (scale.maxRange)
  37188. minValue = that._addInterval(anotherBusinessValue, scale.maxRange, true);
  37189. if (scale.minRange)
  37190. maxValue = that._addInterval(anotherBusinessValue, scale.minRange, true)
  37191. }
  37192. else {
  37193. if (scale.maxRange)
  37194. maxValue = that._addInterval(anotherBusinessValue, scale.maxRange);
  37195. if (scale.minRange)
  37196. minValue = that._addInterval(anotherBusinessValue, scale.minRange)
  37197. }
  37198. if (maxValue !== undefined && result > maxValue) {
  37199. result = values ? rangeSelector.utils.findLessOrEqualValue(values, maxValue) : maxValue;
  37200. isValid = false
  37201. }
  37202. else if (minValue !== undefined && result < minValue) {
  37203. result = values ? rangeSelector.utils.findGreaterOrEqualValue(values, minValue) : minValue;
  37204. isValid = false
  37205. }
  37206. that._setValid(isValid);
  37207. return result
  37208. },
  37209. _addInterval: function(value, interval, isNegative) {
  37210. var result,
  37211. type = this._options.scale.type,
  37212. base = type === "logarithmic" && this._options.scale.logarithmBase;
  37213. if (base) {
  37214. var power = utils.addInterval(utils.getLog(value, base), interval, isNegative);
  37215. result = Math.pow(base, power)
  37216. }
  37217. else
  37218. result = utils.addInterval(value, interval, isNegative);
  37219. return result
  37220. },
  37221. _correctBusinessValueByMinRangeFromStartEndValues: function(businessValue) {
  37222. var that = this,
  37223. values = that._values,
  37224. startValue,
  37225. endValue,
  37226. isValid = true,
  37227. scale = that._options.scale,
  37228. result = businessValue;
  37229. if (scale.minRange)
  37230. if (that.getIndex() === END_VALUE_INDEX) {
  37231. startValue = that._addInterval(scale.startValue, scale.minRange, scale.inverted);
  37232. if (!scale.inverted && result < startValue || scale.inverted && result > startValue)
  37233. result = startValue
  37234. }
  37235. else if (that.getIndex() === START_VALUE_INDEX) {
  37236. endValue = that._addInterval(scale.endValue, scale.minRange, !scale.inverted);
  37237. if (!scale.inverted && result > endValue || scale.inverted && result < endValue)
  37238. result = endValue
  37239. }
  37240. return result
  37241. },
  37242. _applySliderPosition: function(position, disableAnimation) {
  37243. var that = this,
  37244. isAnimation = that._options.behavior.animationEnabled && !disableAnimation,
  37245. top = that._options.canvas.top,
  37246. slider = that._slider;
  37247. if (isAnimation || slider.inAnimation) {
  37248. slider.inAnimation = true;
  37249. slider.animate({translate: {
  37250. x: position,
  37251. y: top
  37252. }}, isAnimation ? animationOptions : {duration: 0}, function() {
  37253. slider.inAnimation = false
  37254. });
  37255. that._sliderTracker.animate({translate: {
  37256. x: position,
  37257. y: top
  37258. }}, isAnimation ? animationOptions : {duration: 0})
  37259. }
  37260. else {
  37261. that._slider.applySettings({
  37262. translateX: position,
  37263. translateY: top
  37264. });
  37265. that._sliderTracker.applySettings({
  37266. translateX: position,
  37267. translateY: top
  37268. })
  37269. }
  37270. that._sliderTracker.updateHeight();
  37271. that._slider.updateHeight()
  37272. },
  37273. _applyShutterPosition: function(position, disableAnimation) {
  37274. var that = this,
  37275. shutterSettings,
  37276. shutter = that._shutter,
  37277. isAnimation = that._options.behavior.animationEnabled && !disableAnimation,
  37278. sliderIndex = that.getIndex();
  37279. if (sliderIndex == START_VALUE_INDEX)
  37280. shutterSettings = {
  37281. x: that._options.canvas.left,
  37282. y: that._options.canvas.top,
  37283. width: position - that._options.canvas.left,
  37284. height: that._options.canvas.height
  37285. };
  37286. else if (sliderIndex == END_VALUE_INDEX)
  37287. shutterSettings = {
  37288. x: position + 1,
  37289. y: that._options.canvas.top,
  37290. width: that._options.canvas.left + that._options.canvas.width - position,
  37291. height: that._options.canvas.height
  37292. };
  37293. if (shutterSettings)
  37294. if (isAnimation || shutter.inAnimation) {
  37295. shutter.inAnimation = true;
  37296. shutter.animate(shutterSettings, isAnimation ? animationOptions : {duration: 0}, function() {
  37297. shutter.inAnimation = false
  37298. })
  37299. }
  37300. else
  37301. shutter.applySettings(shutterSettings)
  37302. },
  37303. _setValid: function(isValid) {
  37304. var that = this;
  37305. if (that._marker)
  37306. that._marker.setValid(isValid);
  37307. that._slider.setValid(isValid)
  37308. },
  37309. _setText: function(text) {
  37310. var that = this;
  37311. if (that._marker)
  37312. that._marker.setText(text)
  37313. },
  37314. ctor: function(renderer, index) {
  37315. var that = this;
  37316. that.callBase(renderer);
  37317. that._index = index
  37318. },
  37319. getIndex: function() {
  37320. return this._index
  37321. },
  37322. setAvailableValues: function(values) {
  37323. this._values = values
  37324. },
  37325. setAnotherSlider: function(slider) {
  37326. this._anotherSlider = slider
  37327. },
  37328. getAnotherSlider: function(slider) {
  37329. return this._anotherSlider
  37330. },
  37331. appendTrackers: function(group) {
  37332. var that = this;
  37333. if (that._sliderTracker)
  37334. that._sliderTracker.append(group)
  37335. },
  37336. getSliderTracker: function() {
  37337. return this._sliderTracker
  37338. },
  37339. changeLocation: function() {
  37340. var that = this;
  37341. if (that._marker)
  37342. that._marker.changeLocation();
  37343. that._index = this._index === START_VALUE_INDEX ? END_VALUE_INDEX : START_VALUE_INDEX;
  37344. that._lastPosition = null
  37345. },
  37346. setPosition: function(position, correctByMinMaxRange, selectedRangeInterval) {
  37347. var that = this,
  37348. slider;
  37349. if (selectedRangeInterval !== undefined) {
  37350. slider = that.getIndex() === START_VALUE_INDEX ? that : that.getAnotherSlider();
  37351. slider._setPositionForBothSliders(position, selectedRangeInterval)
  37352. }
  37353. else
  37354. that._setPosition(position, correctByMinMaxRange)
  37355. },
  37356. getPosition: function() {
  37357. return this._position
  37358. },
  37359. _applyOptions: function(options) {
  37360. this._lastPosition = null
  37361. },
  37362. setValue: function(value, correctByMinMaxRange, skipCorrection) {
  37363. var that = this;
  37364. if (value === undefined) {
  37365. that._value = undefined;
  37366. that._valuePosition = that._position = that.getIndex() === START_VALUE_INDEX ? that._options.canvas.left : that._options.canvas.left + that._options.canvas.width;
  37367. that._setText(rangeSelector.consts.emptySliderMarkerText)
  37368. }
  37369. else {
  37370. that._value = that._correctBusinessValue(value, correctByMinMaxRange, utils.isDefined(skipCorrection) ? !!skipCorrection : true);
  37371. that._valuePosition = that._position = that._options.translator.translate(that._value);
  37372. that._setText(rangeSelector.formatValue(that._value, that._options.sliderMarker))
  37373. }
  37374. },
  37375. getValue: function() {
  37376. return this._value
  37377. },
  37378. canSwap: function() {
  37379. var that = this,
  37380. scale = that._options.scale,
  37381. startValue,
  37382. endValue,
  37383. anotherSliderValue;
  37384. if (that._options.behavior.allowSlidersSwap) {
  37385. if (scale.minRange) {
  37386. anotherSliderValue = that.getAnotherSlider().getValue();
  37387. if (that.getIndex() === START_VALUE_INDEX) {
  37388. endValue = utils.addInterval(scale.endValue, scale.minRange, !scale.inverted);
  37389. if (!scale.inverted && anotherSliderValue > endValue || scale.inverted && anotherSliderValue < endValue)
  37390. return false
  37391. }
  37392. else {
  37393. startValue = utils.addInterval(scale.startValue, scale.minRange, scale.inverted);
  37394. if (!scale.inverted && anotherSliderValue < startValue || scale.inverted && anotherSliderValue > startValue)
  37395. return false
  37396. }
  37397. }
  37398. return true
  37399. }
  37400. return false
  37401. },
  37402. processDocking: function() {
  37403. var that = this;
  37404. that._position = that._valuePosition;
  37405. that.applyPosition(false);
  37406. that._setValid(true)
  37407. },
  37408. applyPosition: function(disableAnimation) {
  37409. var that = this,
  37410. position = that.getPosition();
  37411. if (that._lastPosition !== position) {
  37412. that._applySliderPosition(position, disableAnimation);
  37413. that._applyShutterPosition(position, disableAnimation);
  37414. that._lastPosition = position
  37415. }
  37416. },
  37417. on: function(event, handler) {
  37418. var that = this;
  37419. that._sliderTracker.on(event, handler);
  37420. if (that._marker)
  37421. that._marker.getTracker().on(event, handler)
  37422. },
  37423. _update: function() {
  37424. var that = this;
  37425. that._marker && that._marker.applyOptions(that._options.sliderMarker);
  37426. that._shutter && that._shutter.applySettings({
  37427. fill: that._options.shutter.color,
  37428. fillOpacity: that._options.shutter.opacity
  37429. });
  37430. that._slider && that._slider.applyOptions({
  37431. strokeWidth: that._options.sliderHandle.width,
  37432. stroke: that._options.sliderHandle.color,
  37433. strokeOpacity: that._options.sliderHandle.opacity
  37434. })
  37435. },
  37436. _draw: function(group) {
  37437. var that = this,
  37438. slider,
  37439. marker,
  37440. sliderAreaGroup,
  37441. shutter,
  37442. startPos,
  37443. startWidth,
  37444. index = that.getIndex();
  37445. sliderAreaGroup = that._renderer.createGroup({'class': 'sliderArea'});
  37446. sliderAreaGroup.append(group);
  37447. if (index === START_VALUE_INDEX)
  37448. shutter = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, 0, that._options.canvas.height, 0);
  37449. else if (index === END_VALUE_INDEX)
  37450. shutter = that._renderer.createRect(that._options.canvas.left, that._options.canvas.top, that._options.canvas.width, that._options.canvas.height, 0);
  37451. if (shutter) {
  37452. shutter.append(sliderAreaGroup);
  37453. slider = that._createSlider();
  37454. if (slider)
  37455. slider.append(sliderAreaGroup);
  37456. if (that._options.sliderMarker.visible) {
  37457. marker = that._createSliderMarker({
  37458. renderer: that._renderer,
  37459. isLeftPointer: index === END_VALUE_INDEX,
  37460. sliderMarkerOptions: that._options.sliderMarker
  37461. });
  37462. marker.draw(slider)
  37463. }
  37464. that._shutter = shutter;
  37465. that._slider = slider;
  37466. that._marker = marker
  37467. }
  37468. that._drawSliderTracker(group)
  37469. }
  37470. }
  37471. }())
  37472. })(jQuery, DevExpress);
  37473. /*! Module viz-rangeselector, file sliderMarker.js */
  37474. (function($, DX, undefined) {
  37475. var rangeSelector = DX.viz.rangeSelector,
  37476. _SliderMarker;
  37477. _SliderMarker = rangeSelector.SliderMarker = function(options) {
  37478. var that = this;
  37479. that._renderer = options.renderer;
  37480. that._text = options.text;
  37481. that._isLeftPointer = options.isLeftPointer;
  37482. that._options = options.sliderMarkerOptions;
  37483. that._isValid = true;
  37484. initializeAreaPoints(that, {
  37485. width: 10,
  37486. height: 10
  37487. })
  37488. };
  37489. var applyOptions = function(options) {
  37490. this._options = options;
  37491. this.update()
  37492. };
  37493. var getRectSize = function(that, textSize) {
  37494. return {
  37495. width: Math.round(2 * that._options.padding + textSize.width),
  37496. height: Math.round(2 * that._options.padding + textSize.height * rangeSelector.consts.fontHeightRatio)
  37497. }
  37498. };
  37499. var initializeAreaPoints = function(that, textSize) {
  37500. var rectSize = getRectSize(that, textSize);
  37501. that._points = [];
  37502. if (that._isLeftPointer) {
  37503. that._points.push({
  37504. x: 0,
  37505. y: 0
  37506. });
  37507. that._points.push({
  37508. x: rectSize.width,
  37509. y: 0
  37510. });
  37511. that._points.push({
  37512. x: rectSize.width,
  37513. y: rectSize.height
  37514. });
  37515. that._points.push({
  37516. x: that._options.pointerSize,
  37517. y: rectSize.height
  37518. });
  37519. that._points.push({
  37520. x: 0,
  37521. y: rectSize.height + that._options.pointerSize
  37522. })
  37523. }
  37524. else {
  37525. that._points.push({
  37526. x: 0,
  37527. y: 0
  37528. });
  37529. that._points.push({
  37530. x: rectSize.width,
  37531. y: 0
  37532. });
  37533. that._points.push({
  37534. x: rectSize.width,
  37535. y: rectSize.height + that._options.pointerSize
  37536. });
  37537. that._points.push({
  37538. x: rectSize.width - that._options.pointerSize,
  37539. y: rectSize.height
  37540. });
  37541. that._points.push({
  37542. x: 0,
  37543. y: rectSize.height
  37544. })
  37545. }
  37546. };
  37547. var getPointerPosition = function(that, textSize) {
  37548. var rectSize = getRectSize(that, textSize);
  37549. if (that._isLeftPointer)
  37550. return {
  37551. x: 0,
  37552. y: rectSize.height + that._options.pointerSize
  37553. };
  37554. else
  37555. return {
  37556. x: rectSize.width - 1,
  37557. y: rectSize.height + that._options.pointerSize
  37558. }
  37559. };
  37560. var draw = function(group) {
  37561. var that = this;
  37562. var padding = that._options.padding;
  37563. that._sliderMarkerGroup = that._renderer.createGroup({'class': 'sliderMarker'});
  37564. that._sliderMarkerGroup.append(group);
  37565. that._area = that._renderer.createArea(that.points, {fill: that._options.color});
  37566. that._area.append(that._sliderMarkerGroup);
  37567. that._label = that._renderer.createText(that._text, padding, padding, {
  37568. font: that._options.font,
  37569. align: 'left',
  37570. style: {'-webkit-user-select': 'none'}
  37571. });
  37572. that._label.append(that._sliderMarkerGroup);
  37573. that._tracker = that._renderer.createRect(0, 0, 2 * padding, 2 * padding + that._options.pointerSize, 0, {
  37574. fill: 'grey',
  37575. stroke: 'grey',
  37576. opacity: 0.0001,
  37577. style: {cursor: 'pointer'}
  37578. });
  37579. that._tracker.append(that._sliderMarkerGroup);
  37580. that._drawn = true;
  37581. that.update()
  37582. };
  37583. var getTextSize = function(that) {
  37584. var textSize = that._label.getBBox();
  37585. if (!that._textHeight && isFinite(textSize.height))
  37586. that._textHeight = textSize.height;
  37587. return {
  37588. width: textSize.width,
  37589. height: that._textHeight
  37590. }
  37591. };
  37592. var update = function(stop) {
  37593. var that = this,
  37594. textSize,
  37595. rectSize,
  37596. pointerPosition;
  37597. that._interval && clearInterval(that._interval);
  37598. delete that._interval;
  37599. if (!that._drawn)
  37600. return;
  37601. that._label.updateText(that._text);
  37602. textSize = getTextSize(that);
  37603. if (!stop) {
  37604. that._textSize = that._textSize || textSize;
  37605. that._textSize = textSize.width > that._textSize.width || textSize.height > that._textSize.height ? textSize : that._textSize;
  37606. textSize = that._textSize;
  37607. that._interval = setInterval(function() {
  37608. update.call(that, [true])
  37609. }, 75)
  37610. }
  37611. else {
  37612. delete that._textSize;
  37613. that._textSize = textSize
  37614. }
  37615. rectSize = getRectSize(that, textSize);
  37616. pointerPosition = getPointerPosition(that, textSize);
  37617. that._sliderMarkerGroup.applySettings({
  37618. translateX: -pointerPosition.x,
  37619. translateY: -pointerPosition.y
  37620. });
  37621. initializeAreaPoints(that, textSize);
  37622. that._area.applySettings({
  37623. points: that._points,
  37624. fill: that._isValid ? that._options.color : that._options.invalidRangeColor
  37625. });
  37626. that._tracker.applySettings({
  37627. width: rectSize.width,
  37628. height: rectSize.height + that._options.pointerSize
  37629. });
  37630. that._label.applySettings({
  37631. x: that._options.padding,
  37632. y: rectSize.height - that._options.padding
  37633. })
  37634. };
  37635. var getText = function() {
  37636. var that = this;
  37637. return that._text
  37638. };
  37639. var setText = function(value) {
  37640. var that = this;
  37641. if (that._text !== value) {
  37642. that._text = value;
  37643. that.update()
  37644. }
  37645. };
  37646. var setValid = function(isValid) {
  37647. var that = this;
  37648. that._isValid = isValid;
  37649. that.update()
  37650. };
  37651. var changeLocation = function() {
  37652. var that = this;
  37653. that._isLeftPointer = !that._isLeftPointer;
  37654. that.update()
  37655. };
  37656. var getTracker = function() {
  37657. var that = this;
  37658. return that._tracker
  37659. };
  37660. _SliderMarker.prototype = {
  37661. constructor: _SliderMarker,
  37662. draw: draw,
  37663. update: update,
  37664. getText: getText,
  37665. setText: setText,
  37666. changeLocation: changeLocation,
  37667. applyOptions: applyOptions,
  37668. getTracker: getTracker,
  37669. setValid: setValid
  37670. }
  37671. })(jQuery, DevExpress);
  37672. /*! Module viz-rangeselector, file rangeView.js */
  37673. (function($, DX, undefined) {
  37674. var rangeSelector = DX.viz.rangeSelector;
  37675. rangeSelector.RangeView = rangeSelector.BaseVisualElement.inherit(function() {
  37676. return {_draw: function(group) {
  37677. var that = this,
  37678. viewRect,
  37679. viewImage,
  37680. backgroundColor,
  37681. series,
  37682. i,
  37683. showChart,
  37684. canvas,
  37685. options = that._options,
  37686. seriesOptions,
  37687. isEmpty = options.isEmpty;
  37688. showChart = options.seriesDataSource && options.seriesDataSource.isShowChart() && !isEmpty;
  37689. canvas = options.canvas;
  37690. if (showChart)
  37691. backgroundColor = options.seriesDataSource.getBackgroundColor();
  37692. else if (!isEmpty && options.background.visible)
  37693. backgroundColor = options.background.color;
  37694. if (options.background.visible && backgroundColor) {
  37695. viewRect = that._renderer.createRect(canvas.left, canvas.top, canvas.width + 1, canvas.height, 0, {
  37696. fill: backgroundColor,
  37697. 'class': 'dx-range-selector-background'
  37698. });
  37699. viewRect.append(group)
  37700. }
  37701. if (options.background.visible && options.background.image && options.background.image.url) {
  37702. viewImage = that._renderer.createImage(canvas.left, canvas.top, canvas.width + 1, canvas.height, options.background.image.url, {location: options.background.image.location});
  37703. viewImage.append(group)
  37704. }
  37705. if (showChart) {
  37706. series = options.seriesDataSource.getSeries();
  37707. options.seriesDataSource.adjustSeriesDimensions(options.translators, options.chart.useAggregation);
  37708. for (i = 0; i < series.length; i++) {
  37709. seriesOptions = series[i].getOptions();
  37710. seriesOptions.seriesGroup = group;
  37711. seriesOptions.labelsGroup = group;
  37712. series[i].draw(options.translators, options.behavior && options.behavior.animationEnabled && that._renderer.animationEnabled())
  37713. }
  37714. }
  37715. }}
  37716. }())
  37717. })(jQuery, DevExpress);
  37718. /*! Module viz-rangeselector, file seriesDataSource.js */
  37719. (function($, DX, undefined) {
  37720. var rangeSelector = DX.viz.rangeSelector,
  37721. charts = DX.viz.charts,
  37722. core = DX.viz.core,
  37723. coreFactory = core.CoreFactory,
  37724. utils = DX.utils;
  37725. rangeSelector.SeriesDataSource = DX.Class.inherit(function() {
  37726. var createThemeManager = function(chartOptions) {
  37727. return charts.factory.createThemeManager(chartOptions, 'rangeSelector.chart')
  37728. };
  37729. var isArrayOfSimpleTypes = function(data) {
  37730. return $.isArray(data) && data.length > 0 && (utils.isNumber(data[0]) || utils.isDate(data[0]))
  37731. };
  37732. var convertToArrayOfObjects = function(data) {
  37733. return $.map(data, function(item, i) {
  37734. return {
  37735. arg: item,
  37736. val: i
  37737. }
  37738. })
  37739. };
  37740. var calculateSeries = function(that, options, templatedSeries) {
  37741. var series = [],
  37742. particularSeriesOptions,
  37743. seriesTheme,
  37744. data,
  37745. parsedData,
  37746. chartThemeManager = that.themeManager,
  37747. hasSeriesTemplate = !!chartThemeManager.getOptions('seriesTemplate'),
  37748. allSeriesOptions = hasSeriesTemplate ? templatedSeries : options.chart.series,
  37749. seriesValueType = options.chart.valueAxis && options.chart.valueAxis.valueType,
  37750. dataSourceField,
  37751. i;
  37752. that.teamplateData = [];
  37753. if (options.dataSource && !allSeriesOptions) {
  37754. if (isArrayOfSimpleTypes(options.dataSource))
  37755. options.dataSource = convertToArrayOfObjects(options.dataSource);
  37756. dataSourceField = options.dataSourceField || 'arg';
  37757. allSeriesOptions = {
  37758. argumentField: dataSourceField,
  37759. valueField: dataSourceField
  37760. };
  37761. that._hideChart = true
  37762. }
  37763. allSeriesOptions = $.isArray(allSeriesOptions) ? allSeriesOptions : allSeriesOptions ? [allSeriesOptions] : [];
  37764. that._backgroundColor = options.backgroundColor !== undefined ? options.backgroundColor : chartThemeManager.getOptions("backgroundColor");
  37765. for (i = 0; i < allSeriesOptions.length; i++) {
  37766. particularSeriesOptions = $.extend(true, {
  37767. argumentType: options.valueType,
  37768. argumentAxisType: options.axisType,
  37769. valueType: dataSourceField ? options.valueType : seriesValueType,
  37770. incidentOccured: options.incidentOccured
  37771. }, allSeriesOptions[i]);
  37772. particularSeriesOptions.rotated = false;
  37773. data = particularSeriesOptions.data || options.dataSource;
  37774. seriesTheme = chartThemeManager.getOptions("series", particularSeriesOptions);
  37775. seriesTheme.argumentField = seriesTheme.argumentField || options.dataSourceField;
  37776. if (data && data.length > 0) {
  37777. var newSeries = coreFactory.createSeries(options.renderer, seriesTheme);
  37778. series.push(newSeries)
  37779. }
  37780. if (hasSeriesTemplate) {
  37781. $.each(data, function(_, data) {
  37782. $.each(newSeries.getTeamplatedFields(), function(_, field) {
  37783. data[field.teamplateField] = data[field.originalField]
  37784. });
  37785. that.teamplateData.push(data)
  37786. });
  37787. newSeries.updateTeamplateFieldNames()
  37788. }
  37789. }
  37790. data = hasSeriesTemplate ? that.teamplateData : data;
  37791. that._dataValidator = charts.factory.createDataValidator(data, [series], options.incidentOccured, chartThemeManager.getOptions("dataPrepareSettings"));
  37792. parsedData = that._dataValidator.validate();
  37793. for (i = 0; i < series.length; i++) {
  37794. var particularSeries = series[i];
  37795. particularSeries.updateData(parsedData)
  37796. }
  37797. return series
  37798. };
  37799. var processSeriesFamilies = function(series, equalBarWidth, minBubbleSize, maxBubbleSize) {
  37800. var families = [],
  37801. types = [];
  37802. $.each(series, function(i, item) {
  37803. if ($.inArray(item.type, types) === -1)
  37804. types.push(item.type)
  37805. });
  37806. $.each(types, function(_, type) {
  37807. var family = new coreFactory.createSeriesFamily({
  37808. type: type,
  37809. equalBarWidth: equalBarWidth,
  37810. minBubbleSize: minBubbleSize,
  37811. maxBubbleSize: maxBubbleSize
  37812. });
  37813. family.add(series);
  37814. family.adjustSeriesValues();
  37815. families.push(family)
  37816. });
  37817. return families
  37818. };
  37819. var prototypeObject = {
  37820. ctor: function(options) {
  37821. var that = this,
  37822. templatedSeries,
  37823. seriesTemplate,
  37824. themeManager = that.themeManager = createThemeManager(options.chart),
  37825. topIndent = themeManager.getOptions('topIndent'),
  37826. bottomIndent = themeManager.getOptions('bottomIndent');
  37827. that._indent = {
  37828. top: topIndent >= 0 && topIndent < 1 ? topIndent : 0,
  37829. bottom: bottomIndent >= 0 && bottomIndent < 1 ? bottomIndent : 0
  37830. };
  37831. that._valueAxis = themeManager.getOptions('valueAxisRangeSelector') || {};
  37832. that._hideChart = false;
  37833. seriesTemplate = themeManager.getOptions('seriesTemplate');
  37834. if (options.dataSource && seriesTemplate)
  37835. templatedSeries = utils.processSeriesTemplate(seriesTemplate, options.dataSource);
  37836. that._series = calculateSeries(that, options, templatedSeries);
  37837. that._seriesFamilies = processSeriesFamilies(that._series, themeManager.getOptions('equalBarWidth'), themeManager.getOptions('minBubbleSize'), themeManager.getOptions('maxBubbleSize'))
  37838. },
  37839. adjustSeriesDimensions: function(translators, useAggregation) {
  37840. var that = this;
  37841. if (useAggregation)
  37842. $.each(that._series || [], function(_, s) {
  37843. s.resamplePoints(translators)
  37844. });
  37845. $.each(that._seriesFamilies, function() {
  37846. this.adjustSeriesDimensions(translators)
  37847. })
  37848. },
  37849. getBoundRange: function() {
  37850. var that = this,
  37851. rangeData,
  37852. valueAxisMin = that._valueAxis.min,
  37853. valueAxisMax = that._valueAxis.max,
  37854. valRange = new core.Range({
  37855. isValueRange: true,
  37856. min: valueAxisMin,
  37857. minVisible: valueAxisMin,
  37858. max: valueAxisMax,
  37859. maxVisible: valueAxisMax,
  37860. axisType: that._valueAxis.type,
  37861. base: that._valueAxis.logarithmBase
  37862. }),
  37863. argRange = new core.Range({}),
  37864. rangeYSize,
  37865. rangeVisibleSizeY,
  37866. i,
  37867. minIndent,
  37868. maxIndent;
  37869. for (i = 0; i < that._series.length; i++) {
  37870. rangeData = that._series[i].getRangeData();
  37871. valRange.addRange(rangeData.val);
  37872. argRange.addRange(rangeData.arg)
  37873. }
  37874. if (valRange.isDefined() && argRange.isDefined()) {
  37875. minIndent = that._valueAxis.inverted ? that._indent.top : that._indent.bottom;
  37876. maxIndent = that._valueAxis.inverted ? that._indent.bottom : that._indent.top;
  37877. rangeYSize = valRange.max - valRange.min;
  37878. rangeVisibleSizeY = ($.isNumeric(valRange.maxVisible) ? valRange.maxVisible : valRange.max) - ($.isNumeric(valRange.minVisible) ? valRange.minVisible : valRange.min);
  37879. if (utils.isDate(valRange.min))
  37880. valRange.min = new Date(valRange.min.valueOf() - rangeYSize * minIndent);
  37881. else
  37882. valRange.min -= rangeYSize * minIndent;
  37883. if (utils.isDate(valRange.max))
  37884. valRange.max = new Date(valRange.max.valueOf() + rangeYSize * maxIndent);
  37885. else
  37886. valRange.max += rangeYSize * maxIndent;
  37887. if ($.isNumeric(rangeVisibleSizeY)) {
  37888. valRange.maxVisible = valRange.maxVisible ? valRange.maxVisible + rangeVisibleSizeY * maxIndent : undefined;
  37889. valRange.minVisible = valRange.minVisible ? valRange.minVisible - rangeVisibleSizeY * minIndent : undefined
  37890. }
  37891. valRange.invert = that._valueAxis.inverted
  37892. }
  37893. return {
  37894. arg: argRange,
  37895. val: valRange
  37896. }
  37897. },
  37898. getSeries: function() {
  37899. var that = this;
  37900. return that._series
  37901. },
  37902. getBackgroundColor: function() {
  37903. var that = this;
  37904. return that._backgroundColor
  37905. },
  37906. isEmpty: function() {
  37907. var that = this;
  37908. return that.getSeries().length === 0
  37909. },
  37910. isShowChart: function() {
  37911. var that = this;
  37912. return !that.isEmpty() && !that._hideChart
  37913. },
  37914. getCalculatedValueType: function() {
  37915. var that = this,
  37916. result;
  37917. if (that._series.length)
  37918. result = that._series[0].argumentType;
  37919. return result
  37920. }
  37921. };
  37922. return prototypeObject
  37923. }())
  37924. })(jQuery, DevExpress);
  37925. /*! Module viz-rangeselector, file themeManager.js */
  37926. (function($, DX, undefined) {
  37927. DX.viz.rangeSelector = DX.viz.rangeSelector;
  37928. DX.viz.rangeSelector.ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  37929. _themeSection: 'rangeSelector',
  37930. ctor: function(userTheme) {
  37931. this.setTheme(userTheme)
  37932. },
  37933. _initializeTheme: function() {
  37934. this._initializeFont(this._theme.scale.label.font);
  37935. this._initializeFont(this._theme.sliderMarker.font);
  37936. this._initializeFont(this._theme.loadingIndicator.font)
  37937. },
  37938. applyRangeSelectorTheme: function(userOptions) {
  37939. var that = this,
  37940. chart = userOptions.chart,
  37941. dataSource = userOptions.dataSource,
  37942. result;
  37943. delete userOptions.dataSource;
  37944. delete userOptions.chart;
  37945. result = $.extend(true, {}, that._theme, userOptions);
  37946. result.dataSource = dataSource;
  37947. if (chart)
  37948. result.chart = chart;
  37949. return result
  37950. },
  37951. setBackgroundColor: function(containerBackgroundColor) {
  37952. var theme = this._theme;
  37953. if (containerBackgroundColor)
  37954. theme.containerBackgroundColor = containerBackgroundColor;
  37955. theme.shutter.color = theme.shutter.color || theme.containerBackgroundColor
  37956. }
  37957. })
  37958. })(jQuery, DevExpress);
  37959. /*! Module viz-rangeselector, file dxRangeSelector.js */
  37960. (function($, DX, undefined) {
  37961. var ui = DX.ui,
  37962. viz = DX.viz;
  37963. DX.registerComponent("dxRangeSelector", viz.rangeSelector.RangeSelector)
  37964. })(jQuery, DevExpress);
  37965. DevExpress.MOD_VIZ_RANGESELECTOR = true
  37966. }
  37967. if (!DevExpress.MOD_VIZ_VECTORMAP) {
  37968. if (!DevExpress.MOD_VIZ_CORE)
  37969. throw Error('Required module is not referenced: viz-core');
  37970. /*! Module viz-vectormap, file map.js */
  37971. (function(DX, $, undefined) {
  37972. DX.viz.map = {};
  37973. var _Number = window.Number,
  37974. _isFunction = DX.utils.isFunction,
  37975. _getRootOffset = DX.utils.getRootOffset;
  37976. var DEFAULT_WIDTH = 800,
  37977. DEFAULT_HEIGHT = 400;
  37978. var DATA_KEY = DX.viz.map.__DATA_KEY = 'vectormap-data';
  37979. DX.viz.map.Map = DX.viz.core.BaseWidget.inherit({
  37980. _init: function() {
  37981. var that = this;
  37982. that.callBase.apply(that, arguments);
  37983. that.renderer = that._renderer = that._factory.createRenderer({
  37984. width: 1,
  37985. height: 1,
  37986. pathModified: that.option('pathModified'),
  37987. rtl: that.option('rtlEnabled')
  37988. });
  37989. that.renderer.draw(that._element().get(0));
  37990. that._root = that._renderer.getRoot();
  37991. that._root.applySettings({
  37992. 'class': 'dxm',
  37993. stroke: 'none',
  37994. strokeWidth: 0,
  37995. fill: 'none',
  37996. align: 'center',
  37997. cursor: 'default',
  37998. style: {overflow: 'hidden'}
  37999. });
  38000. that._themeManager = that._factory.createThemeManager();
  38001. that._projection = that._factory.createProjection();
  38002. that._tracker = that._factory.createTracker({root: that._root});
  38003. that._background = that._renderer.createRect(0, 0, 0, 0, 0, {'class': 'dxm-background'}).data(DATA_KEY, {type: 'background'});
  38004. that._areasManager = that._factory.createAreasManager({
  38005. container: that._root,
  38006. renderer: that._renderer,
  38007. projection: that._projection,
  38008. themeManager: that._themeManager,
  38009. tracker: that._tracker,
  38010. ready: function() {
  38011. that.hideLoadingIndicator()
  38012. }
  38013. });
  38014. that._areasManager.setData(that.option('mapData'));
  38015. that._markersManager = that._factory.createMarkersManager({
  38016. container: that._root,
  38017. renderer: that._renderer,
  38018. projection: that._projection,
  38019. themeManager: that._themeManager,
  38020. tracker: that._tracker
  38021. });
  38022. that._markersManager.setData(that.option('markers'));
  38023. that._controlBar = that._factory.createControlBar({
  38024. container: that._root,
  38025. renderer: that._renderer,
  38026. context: that,
  38027. resetCallback: controlResetCallback,
  38028. beginMoveCallback: controlBeginMoveCallback,
  38029. endMoveCallback: controlEndMoveCallback,
  38030. moveCallback: controlMoveCallback,
  38031. zoomCallback: controlZoomCallback
  38032. });
  38033. that._legend = that._factory.createLegend({
  38034. container: that._root,
  38035. renderer: that._renderer,
  38036. themeManager: that._themeManager
  38037. });
  38038. that._tooltip = that._factory.createTooltip({
  38039. container: that._root,
  38040. renderer: that._renderer,
  38041. tracker: that._tracker
  38042. });
  38043. that._projection.setBounds(that.option('bounds')).setMaxZoom(that.option('maxZoomFactor')).setZoom(that.option('zoomFactor')).setCenter(that.option('center'));
  38044. that._themeManager.setTheme(that.option('theme'));
  38045. that._themeManager.patchRtlSettings(that.option('rtlEnabled'));
  38046. that._setClickCallback(that.option('click'));
  38047. that._setCenterChangedCallback(that.option('centerChanged'));
  38048. that._setZoomFactorChangedCallback(that.option('zoomFactorChanged'));
  38049. that._setTrackerCallbacks()
  38050. },
  38051. _dispose: function() {
  38052. var that = this;
  38053. that.callBase.apply(that, arguments);
  38054. that._resetTrackerCallbacks();
  38055. that._themeManager.dispose();
  38056. that._tracker.dispose();
  38057. that._areasManager.dispose();
  38058. that._markersManager.dispose();
  38059. that._controlBar.dispose();
  38060. that._legend.dispose();
  38061. that._tooltip.dispose();
  38062. that._renderer.dispose();
  38063. that._disposeLoadIndicator();
  38064. 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
  38065. },
  38066. _setTrackerCallbacks: function() {
  38067. var that = this,
  38068. renderer = that._renderer,
  38069. managers = {
  38070. area: that._areasManager,
  38071. marker: that._markersManager
  38072. },
  38073. projection = that._projection,
  38074. controlBar = that._controlBar,
  38075. tooltip = that._tooltip,
  38076. xdrag,
  38077. ydrag,
  38078. isControlDrag = false;
  38079. that._tracker.setCallbacks({
  38080. click: function(arg) {
  38081. var offset = _getRootOffset(renderer);
  38082. arg.$event.x = arg.x - offset.left;
  38083. arg.$event.y = arg.y - offset.top;
  38084. var manager = managers[arg.data.type];
  38085. if (manager)
  38086. manager.raiseClick(arg.data.index, arg.$event);
  38087. if (manager || arg.data.type === 'background')
  38088. that._raiseClick(arg.$event)
  38089. },
  38090. start: function(arg) {
  38091. isControlDrag = arg.data.type === 'control-bar';
  38092. if (isControlDrag) {
  38093. arg.data = arg.data.index;
  38094. controlBar.processStart(arg)
  38095. }
  38096. else {
  38097. xdrag = arg.x;
  38098. ydrag = arg.y;
  38099. projection.snapCenter()
  38100. }
  38101. },
  38102. move: function(arg) {
  38103. if (isControlDrag) {
  38104. arg.data = arg.data.index;
  38105. controlBar.processMove(arg)
  38106. }
  38107. else {
  38108. projection.moveCenter(xdrag - arg.x, ydrag - arg.y);
  38109. xdrag = arg.x;
  38110. ydrag = arg.y;
  38111. that._applyTranslate()
  38112. }
  38113. },
  38114. end: function(arg) {
  38115. if (isControlDrag) {
  38116. arg.data = arg.data.index;
  38117. controlBar.processEnd(arg)
  38118. }
  38119. else
  38120. projection.isCenterChanged() && that._raiseCenterChanged();
  38121. isControlDrag = false
  38122. },
  38123. zoom: function(arg) {
  38124. controlBar.processZoom(arg)
  38125. },
  38126. 'hover-on': function(arg) {
  38127. var manager = managers[arg.data.type];
  38128. if (manager)
  38129. manager.hoverItem(arg.data.index, true)
  38130. },
  38131. 'hover-off': function(arg) {
  38132. var manager = managers[arg.data.type];
  38133. if (manager)
  38134. manager.hoverItem(arg.data.index, false)
  38135. },
  38136. 'focus-on': function(arg, done) {
  38137. var result = false;
  38138. if (tooltip.enabled()) {
  38139. var proxy = managers[arg.data.type] ? managers[arg.data.type].getProxyItem(arg.data.index) : null;
  38140. if (!!proxy && tooltip.prepare(proxy, {offset: 12})) {
  38141. var offset = _getRootOffset(renderer);
  38142. tooltip.show().move(arg.x - offset.left, arg.y - offset.top);
  38143. result = true
  38144. }
  38145. }
  38146. done(result)
  38147. },
  38148. 'focus-move': function(arg) {
  38149. var offset = _getRootOffset(renderer);
  38150. tooltip.move(arg.x - offset.left, arg.y - offset.top)
  38151. },
  38152. 'focus-off': function(arg) {
  38153. tooltip.hide()
  38154. }
  38155. });
  38156. that._resetTrackerCallbacks = function() {
  38157. that._resetTrackerCallbacks = that = renderer = managers = projection = controlBar = tooltip = null
  38158. }
  38159. },
  38160. _adjustSize: function(force) {
  38161. var that = this,
  38162. size = that.option('size') || {},
  38163. width = size.width >= 0 ? _Number(size.width) : that._element().width(),
  38164. height = size.height >= 0 ? _Number(size.height) : that._element().height(),
  38165. hidden = false;
  38166. if (width === 0)
  38167. if (_Number(size.width) === 0)
  38168. hidden = true;
  38169. else
  38170. width = DEFAULT_WIDTH;
  38171. if (height === 0)
  38172. if (_Number(size.height) === 0)
  38173. hidden = true;
  38174. else
  38175. height = DEFAULT_HEIGHT;
  38176. if (hidden || !that._element().is(':visible')) {
  38177. that._incidentOccured("W2001", [that.NAME]);
  38178. that._width = that._height = 0;
  38179. return false
  38180. }
  38181. var needResize = that._width !== width || that._height !== height || force;
  38182. if (needResize) {
  38183. that._width = width;
  38184. that._height = height;
  38185. that._renderer.resize(width, height);
  38186. that._projection.setSize(width, height);
  38187. that._legend.applyLayout(width, height);
  38188. that._tooltip.setSize(width, height);
  38189. that._background.applySettings({
  38190. x: 0,
  38191. y: 0,
  38192. width: width,
  38193. height: height
  38194. });
  38195. that._applyTranslate();
  38196. that._updateLoadIndicator(undefined, width, height)
  38197. }
  38198. return needResize
  38199. },
  38200. _clean: function() {
  38201. var that = this;
  38202. that._tracker.clean();
  38203. that._background.detach();
  38204. that._areasManager.clean();
  38205. that._markersManager.clean();
  38206. that._controlBar.clean();
  38207. that._legend.clean();
  38208. that._tooltip.clean()
  38209. },
  38210. _render: function() {
  38211. var that = this;
  38212. if (!that._adjustSize(true))
  38213. return;
  38214. that._tooltip.update(that._themeManager.getTooltipSettings(that.option('tooltip')));
  38215. that._tracker.setOptions(that.option('interaction') || {});
  38216. that._controlBar.setZoomPartition(that._projection.getZoomScalePartition()).setZoom(that._projection.getScaledZoom()).setOptions(that._themeManager.getControlBarSettings(that.option('controlBar')), that.option('interaction'));
  38217. that._background.applySettings(that._themeManager.getBackgroundSettings(that.option('background')));
  38218. that._background.append(that._root);
  38219. that._areasManager.render(that.option('areaSettings'));
  38220. that._markersManager.render(that.option('markerSettings'));
  38221. that._controlBar.render();
  38222. that._legend.render(that._themeManager.getLegendSettings(that.option('legend')));
  38223. that._tooltip.render();
  38224. that._tracker.render();
  38225. that._drawn()
  38226. },
  38227. _optionChanged: function(name, value) {
  38228. var that = this;
  38229. switch (name) {
  38230. case'theme':
  38231. that._themeManager.setTheme(value);
  38232. that._themeManager.patchRtlSettings(that.option('rtlEnabled'));
  38233. that._invalidate();
  38234. break;
  38235. case'click':
  38236. that._setClickCallback(value);
  38237. break;
  38238. case'centerChanged':
  38239. that._setCenterChangedCallback(value);
  38240. break;
  38241. case'zoomFactorChanged':
  38242. that._setZoomFactorChangedCallback(value);
  38243. break;
  38244. case'mapData':
  38245. that._areasManager.setData(value);
  38246. break;
  38247. case'markers':
  38248. that._markersManager.setData(value);
  38249. break;
  38250. case'bounds':
  38251. that._projection.setBounds(value);
  38252. that._invalidate();
  38253. break;
  38254. case'maxZoomFactor':
  38255. that._projection.setMaxZoom(value);
  38256. that._invalidate();
  38257. break;
  38258. case'zoomFactor':
  38259. that._updateZoomFactor(value);
  38260. break;
  38261. case'center':
  38262. that._updateCenter(value);
  38263. break;
  38264. default:
  38265. that.callBase.apply(that, arguments);
  38266. break
  38267. }
  38268. },
  38269. _getLoadIndicatorOption: function() {
  38270. return this._themeManager.getLoadIndicatorSettings(this.option('loadingIndicator'))
  38271. },
  38272. _setClickCallback: function(callback) {
  38273. this._clickCallback = _isFunction(callback) ? callback : null
  38274. },
  38275. _setCenterChangedCallback: function(callback) {
  38276. var that = this;
  38277. that._centerChangedCallback = _isFunction(callback) ? function() {
  38278. that._centerChangedCallback && callback.call(that, that._projection.getCenter())
  38279. } : null
  38280. },
  38281. _setZoomFactorChangedCallback: function(callback) {
  38282. var that = this;
  38283. that._zoomFactorChangedCallback = _isFunction(callback) ? function() {
  38284. that._zoomFactorChangedCallback && callback.call(that, that._projection.getZoom())
  38285. } : null
  38286. },
  38287. _raiseClick: function(arg) {
  38288. var that = this;
  38289. that._clickCallback && setTimeout(function() {
  38290. that._clickCallback && that._clickCallback.call(that, arg)
  38291. }, 0)
  38292. },
  38293. _raiseCenterChanged: function() {
  38294. this._centerChangedCallback && setTimeout(this._centerChangedCallback, 0)
  38295. },
  38296. _raiseZoomFactorChanged: function() {
  38297. this._zoomFactorChangedCallback && setTimeout(this._zoomFactorChangedCallback, 0)
  38298. },
  38299. _updateCenter: function(center, _noEvent) {
  38300. this._projection.snapCenter().setCenter(center);
  38301. if (this._projection.isCenterChanged()) {
  38302. this._applyTransform();
  38303. _noEvent || this._raiseCenterChanged()
  38304. }
  38305. },
  38306. _updateZoomFactor: function(zoomFactor, _noEvent) {
  38307. var that = this;
  38308. that._projection.snapZoom().setZoom(zoomFactor);
  38309. if (that._projection.isZoomChanged()) {
  38310. that._controlBar.setZoom(that._projection.getScaledZoom());
  38311. that._applyTransform(true);
  38312. _noEvent || that._raiseZoomFactorChanged()
  38313. }
  38314. },
  38315. _updateViewport: function(viewport, _noEvent) {
  38316. var that = this;
  38317. that._projection.snapCenter().snapZoom().setViewport(viewport);
  38318. that._applyTransform(that._projection.isZoomChanged());
  38319. if (that._projection.isCenterChanged())
  38320. _noEvent || that._raiseCenterChanged();
  38321. if (that._projection.isZoomChanged()) {
  38322. that._controlBar.setZoom(that._projection.getScaledZoom());
  38323. _noEvent || that._raiseZoomFactorChanged()
  38324. }
  38325. },
  38326. _resize: function() {
  38327. if (this._adjustSize())
  38328. this._applyTransform(true)
  38329. },
  38330. _applyTranslate: function() {
  38331. var transform = this._projection.getTransform();
  38332. this._areasManager.transform(transform);
  38333. this._markersManager.transform(transform)
  38334. },
  38335. _applyTransform: function(redraw, _noTrackerReset) {
  38336. _noTrackerReset || this._tracker.reset();
  38337. this._applyTranslate();
  38338. if (redraw) {
  38339. this._areasManager.redraw();
  38340. this._markersManager.redraw()
  38341. }
  38342. },
  38343. _refresh: function() {
  38344. var that = this,
  38345. callBase = that.callBase;
  38346. that._endLoading(function() {
  38347. callBase.call(that)
  38348. })
  38349. },
  38350. render: function() {
  38351. var that = this;
  38352. if (that._width === 0 && that._height === 0)
  38353. that._refresh();
  38354. else
  38355. that._resize();
  38356. return that
  38357. },
  38358. getAreas: function() {
  38359. return this._areasManager.getProxyItems()
  38360. },
  38361. getMarkers: function() {
  38362. return this._markersManager.getProxyItems()
  38363. },
  38364. clearAreaSelection: function(_noEvent) {
  38365. this._areasManager.clearSelection(_noEvent);
  38366. return this
  38367. },
  38368. clearMarkerSelection: function(_noEvent) {
  38369. this._markersManager.clearSelection(_noEvent);
  38370. return this
  38371. },
  38372. clearSelection: function(_noEvent) {
  38373. return this.clearAreaSelection(_noEvent).clearMarkerSelection(_noEvent)
  38374. },
  38375. center: function(value, _noEvent) {
  38376. if (value === undefined)
  38377. return this._projection.getCenter();
  38378. else {
  38379. this._updateCenter(value, _noEvent);
  38380. return this
  38381. }
  38382. },
  38383. zoomFactor: function(value, _noEvent) {
  38384. if (value === undefined)
  38385. return this._projection.getZoom();
  38386. else {
  38387. this._updateZoomFactor(value, _noEvent);
  38388. return this
  38389. }
  38390. },
  38391. viewport: function(value, _noEvent) {
  38392. if (value === undefined)
  38393. return this._projection.getViewport();
  38394. else {
  38395. this._updateViewport(value, _noEvent);
  38396. return this
  38397. }
  38398. },
  38399. convertCoordinates: function(x, y) {
  38400. return this._projection.fromScreenPointStrict(x, y)
  38401. },
  38402. showLoadingIndicator: function() {
  38403. this._showLoadIndicator(this._themeManager.getLoadIndicatorSettings(this.option('loadingIndicator')), {
  38404. width: this._width,
  38405. height: this._height
  38406. })
  38407. },
  38408. _factory: {
  38409. createRenderer: function(options) {
  38410. return new DX.viz.renderers.Renderer(options)
  38411. },
  38412. createTooltip: function(parameters) {
  38413. return new Tooltip(parameters)
  38414. },
  38415. createLegend: function(parameters) {
  38416. return new Legend(parameters)
  38417. }
  38418. }
  38419. });
  38420. var Tooltip = DX.viz.core.Tooltip.inherit({
  38421. ctor: function(parameters) {
  38422. var that = this;
  38423. that._container = parameters.container;
  38424. that._root = parameters.renderer.createGroup({'class': 'dxm-tooltip'});
  38425. that.callBase(null, that._root, parameters.renderer);
  38426. that._tracker = parameters.tracker;
  38427. that._enabled = false
  38428. },
  38429. dispose: function() {
  38430. var that = this;
  38431. that._container = that._root = that._tracker = null;
  38432. return that.callBase.apply(that, arguments)
  38433. },
  38434. clean: function() {
  38435. this._root.detach();
  38436. return this
  38437. },
  38438. render: function() {
  38439. this._root.append(this._container);
  38440. return this
  38441. }
  38442. });
  38443. var Legend = DX.viz.core.Legend.inherit({
  38444. ctor: function(parameters) {
  38445. var that = this;
  38446. that._container = parameters.container;
  38447. that._root = parameters.renderer.createGroup({'class': 'dxm-legend'});
  38448. that._themeManager = parameters.themeManager;
  38449. that.callBase(null, null, parameters.renderer, that._root)
  38450. },
  38451. dispose: function() {
  38452. var that = this;
  38453. that._container = that._root = that._themeManager = null;
  38454. return that.callBase.apply(that, arguments)
  38455. },
  38456. clean: function() {
  38457. this._root.detach();
  38458. return this
  38459. },
  38460. render: function(options) {
  38461. var that = this,
  38462. items = [],
  38463. i = 0,
  38464. ii = options.items ? options.items.length : 0;
  38465. for (; i < ii; ++i)
  38466. items.push(that._themeManager.getLegendItemSettings(options.items[i] || {}));
  38467. that.update(items, options);
  38468. that._root.append(that._container);
  38469. return that.applyLayout(that._size.width, that._size.height)
  38470. },
  38471. applyLayout: function(width, height) {
  38472. var that = this,
  38473. layoutOptions;
  38474. that.setSize({
  38475. width: width,
  38476. height: height
  38477. });
  38478. that.draw();
  38479. layoutOptions = that.getLayoutOptions();
  38480. if (layoutOptions) {
  38481. var left,
  38482. top;
  38483. if (layoutOptions.horizontalAlignment === 'left')
  38484. left = 0;
  38485. else if (layoutOptions.horizontalAlignment === 'center')
  38486. left = width / 2 - layoutOptions.width / 2;
  38487. else
  38488. left = width - layoutOptions.width;
  38489. if (layoutOptions.verticalAlignment === 'top')
  38490. top = 0;
  38491. else
  38492. top = height - layoutOptions.height;
  38493. that.shift(left, top)
  38494. }
  38495. return that
  38496. }
  38497. });
  38498. function projectAreaDefault(dataItem) {
  38499. return this._projection.projectArea(dataItem.coordinates)
  38500. }
  38501. function projectAreaGeoJson(dataItem) {
  38502. if (dataItem.geometry) {
  38503. var type = dataItem.geometry.type,
  38504. coordinates = dataItem.geometry.coordinates;
  38505. if (coordinates && (type === 'Polygon' || type === 'MultiPolygon')) {
  38506. type === 'MultiPolygon' && (coordinates = [].concat.apply([], coordinates));
  38507. return this._projection.projectArea(coordinates)
  38508. }
  38509. }
  38510. return []
  38511. }
  38512. function controlResetCallback() {
  38513. var projection = this._projection,
  38514. isCenterChanged,
  38515. isZoomChanged;
  38516. projection.snapCenter().snapZoom().setCenter(null).setZoom(null);
  38517. isCenterChanged = projection.isCenterChanged();
  38518. isZoomChanged = projection.isZoomChanged();
  38519. if (isCenterChanged || isZoomChanged)
  38520. this._applyTransform(isZoomChanged, true);
  38521. isCenterChanged && this._raiseCenterChanged();
  38522. isZoomChanged && this._raiseZoomFactorChanged()
  38523. }
  38524. function controlBeginMoveCallback() {
  38525. this._projection.snapCenter()
  38526. }
  38527. function controlEndMoveCallback() {
  38528. this._projection.isCenterChanged() && this._raiseCenterChanged()
  38529. }
  38530. function controlMoveCallback(dx, dy) {
  38531. this._projection.moveCenter(dx, dy);
  38532. this._applyTranslate()
  38533. }
  38534. function controlZoomCallback(zoom, x, y) {
  38535. var that = this,
  38536. keepPosition = x !== undefined && y !== undefined,
  38537. coords,
  38538. screenPosition;
  38539. if (keepPosition) {
  38540. screenPosition = _getRootOffset(that._renderer);
  38541. screenPosition = [x - screenPosition.left, y - screenPosition.top];
  38542. coords = that._projection.fromScreenPoint(screenPosition[0], screenPosition[1])
  38543. }
  38544. that._projection.snapZoom().setScaledZoom(zoom);
  38545. if (that._projection.isZoomChanged()) {
  38546. keepPosition && that._projection.snapCenter().setCenterByPoint(coords, screenPosition);
  38547. that._applyTransform(true, true);
  38548. that._raiseZoomFactorChanged();
  38549. keepPosition && that._projection.isCenterChanged() && that._raiseCenterChanged()
  38550. }
  38551. }
  38552. DX.registerComponent('dxVectorMap', DX.viz.map.Map);
  38553. DX.viz.map._internal = {};
  38554. DX.viz.map.sources = {};
  38555. DX.viz.map._tests = {};
  38556. DX.viz.map._tests.Legend = Legend;
  38557. DX.viz.map._tests.Tooltip = Tooltip
  38558. })(DevExpress, jQuery);
  38559. /*! Module viz-vectormap, file projection.js */
  38560. (function(DX, $, undefined) {
  38561. var _Number = Number,
  38562. _isFinite = isFinite,
  38563. _min = Math.min,
  38564. _max = Math.max,
  38565. _abs = Math.abs,
  38566. _tan = Math.tan,
  38567. _atan = Math.atan,
  38568. _exp = Math.exp,
  38569. _round = Math.round,
  38570. _ln = Math.log,
  38571. _pow = Math.pow,
  38572. _isArray = DX.utils.isArray,
  38573. _buildPath = DX.viz.renderers.buildPath;
  38574. var PI = Math.PI,
  38575. QUARTER_PI = PI / 4,
  38576. PI_TO_360 = PI / 360,
  38577. TWO_TO_LN2 = 2 / Math.LN2;
  38578. var DEFAULT_MIN_ZOOM = 1,
  38579. DEFAULT_MAX_ZOOM = 1 << 8;
  38580. var MERCATOR_MIN_LON = -180,
  38581. MERCATOR_MAX_LON = 180,
  38582. MERCATOR_MIN_LAT = -85.0511,
  38583. MERCATOR_MAX_LAT = 85.0511;
  38584. var mercator = {
  38585. aspectRatio: 1,
  38586. project: function(coordinates) {
  38587. var lon = coordinates[0],
  38588. lat = coordinates[1];
  38589. 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]
  38590. },
  38591. unproject: function(coordinates) {
  38592. var x = coordinates[0],
  38593. y = coordinates[1];
  38594. 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]
  38595. }
  38596. };
  38597. function createProjectUnprojectMethods(p1, p2, delta) {
  38598. var x0 = (p1[0] + p2[0]) / 2 - delta / 2,
  38599. y0 = (p1[1] + p2[1]) / 2 - delta / 2,
  38600. k = 2 / delta;
  38601. return {
  38602. project: function(coordinates) {
  38603. var p = mercator.project(coordinates);
  38604. return [-1 + (p[0] - x0) * k, -1 + (p[1] - y0) * k]
  38605. },
  38606. unproject: function(coordinates) {
  38607. var p = [x0 + (coordinates[0] + 1) / k, y0 + (coordinates[1] + 1) / k];
  38608. return mercator.unproject(p)
  38609. }
  38610. }
  38611. }
  38612. function floatsEqual(f1, f2) {
  38613. return _abs(f1 - f2) < 1E-8
  38614. }
  38615. function truncate(value, min, max, fallback) {
  38616. var _value = _Number(value);
  38617. if (_value < min)
  38618. _value = min;
  38619. else if (_value > max)
  38620. _value = max;
  38621. else if (!(min <= _value && _value <= max))
  38622. _value = fallback;
  38623. return _value
  38624. }
  38625. function truncateQuad(quad, min, max) {
  38626. return {
  38627. lt: [truncate(quad[0], min[0], max[0], min[0]), truncate(quad[1], min[1], max[1], min[1])],
  38628. rb: [truncate(quad[2], min[0], max[0], max[0]), truncate(quad[3], min[1], max[1], max[1])]
  38629. }
  38630. }
  38631. function parseBounds(bounds) {
  38632. var p1 = mercator.unproject([-1, -1]),
  38633. p2 = mercator.unproject([+1, +1]),
  38634. min = [_min(p1[0], p2[0]), _min(p1[1], p2[1])],
  38635. max = [_max(p1[0], p2[0]), _max(p1[1], p2[1])],
  38636. quad = bounds;
  38637. if (quad && quad.minLon)
  38638. quad = [quad.minLon, quad.minLat, quad.maxLon, quad.maxLat];
  38639. if (quad)
  38640. quad = truncateQuad(quad, min, max);
  38641. return {
  38642. minBase: min,
  38643. maxBase: max,
  38644. min: quad ? [_min(quad.lt[0], quad.rb[0]), _min(quad.lt[1], quad.rb[1])] : min,
  38645. max: quad ? [_max(quad.lt[0], quad.rb[0]), _max(quad.lt[1], quad.rb[1])] : max
  38646. }
  38647. }
  38648. function selectCenterValue(value1, value2, center1, center2) {
  38649. var result;
  38650. if (value1 > -1 && value2 >= +1)
  38651. result = center1;
  38652. else if (value1 <= -1 && value2 < +1)
  38653. result = center2;
  38654. else
  38655. result = (center1 + center2) / 2;
  38656. return result
  38657. }
  38658. function Projection() {
  38659. this.setBounds(null)
  38660. }
  38661. Projection.prototype = {
  38662. constructor: Projection,
  38663. _minZoom: DEFAULT_MIN_ZOOM,
  38664. _maxZoom: DEFAULT_MAX_ZOOM,
  38665. _zoom: DEFAULT_MIN_ZOOM,
  38666. setSize: function(width, height) {
  38667. var that = this;
  38668. that._x0 = width / 2;
  38669. that._y0 = height / 2;
  38670. if (width / height <= mercator.aspectRatio) {
  38671. that._xradius = width / 2;
  38672. that._yradius = width / 2 / mercator.aspectRatio
  38673. }
  38674. else {
  38675. that._xradius = height / 2 * mercator.aspectRatio;
  38676. that._yradius = height / 2
  38677. }
  38678. return that
  38679. },
  38680. setBounds: function(bounds) {
  38681. var that = this,
  38682. _bounds = parseBounds(bounds);
  38683. that._minBase = _bounds.minBase;
  38684. that._maxBase = _bounds.maxBase;
  38685. that._minBound = _bounds.min;
  38686. that._maxBound = _bounds.max;
  38687. var p1 = mercator.project(_bounds.min),
  38688. p2 = mercator.project(_bounds.max),
  38689. delta = _min(truncate(_abs(p2[0] - p1[0]), 0.1, 2, 2), truncate(_abs(p2[1] - p1[1]), 0.1, 2, 2)),
  38690. methods = delta < 2 ? createProjectUnprojectMethods(p1, p2, delta) : mercator;
  38691. that._project = methods.project;
  38692. that._unproject = methods.unproject;
  38693. var minv = that._project(_bounds.minBase),
  38694. maxv = that._project(_bounds.maxBase);
  38695. that._minv = [_min(minv[0], maxv[0]), _min(minv[1], maxv[1])];
  38696. that._maxv = [_max(minv[0], maxv[0]), _max(minv[1], maxv[1])];
  38697. that._defaultCenter = that._unproject([0, 0]);
  38698. return that.setCenter(that._defaultCenter)
  38699. },
  38700. _toScreen: function(coordinates) {
  38701. return [this._x0 + this._xradius * coordinates[0], this._y0 + this._yradius * coordinates[1]]
  38702. },
  38703. _fromScreen: function(coordinates) {
  38704. return [(coordinates[0] - this._x0) / this._xradius, (coordinates[1] - this._y0) / this._yradius]
  38705. },
  38706. _toTransformed: function(coordinates) {
  38707. return [coordinates[0] * this._zoom + this._dxcenter, coordinates[1] * this._zoom + this._dycenter, ]
  38708. },
  38709. _toTransformedFast: function(coordinates) {
  38710. return [coordinates[0] * this._zoom, coordinates[1] * this._zoom]
  38711. },
  38712. _fromTransformed: function(coordinates) {
  38713. return [(coordinates[0] - this._dxcenter) / this._zoom, (coordinates[1] - this._dycenter) / this._zoom]
  38714. },
  38715. _adjustCenter: function() {
  38716. var that = this,
  38717. center = that._project(that._center);
  38718. that._dxcenter = -center[0] * that._zoom;
  38719. that._dycenter = -center[1] * that._zoom
  38720. },
  38721. projectArea: function(coordinates) {
  38722. var i = 0,
  38723. ii = _isArray(coordinates) ? coordinates.length : 0,
  38724. subcoords,
  38725. j,
  38726. jj,
  38727. subresult,
  38728. result = [];
  38729. for (; i < ii; ++i) {
  38730. subcoords = coordinates[i];
  38731. subresult = [];
  38732. for (j = 0, jj = _isArray(subcoords) ? subcoords.length : 0; j < jj; ++j)
  38733. subresult.push(this._project(subcoords[j]));
  38734. result.push(subresult)
  38735. }
  38736. return result
  38737. },
  38738. projectPoint: function(coordinates) {
  38739. return coordinates ? this._project(coordinates) : []
  38740. },
  38741. getAreaCoordinates: function(data) {
  38742. var k = 0,
  38743. kk = data.length,
  38744. partialData,
  38745. i,
  38746. ii,
  38747. list = [],
  38748. partialPath,
  38749. point;
  38750. for (; k < kk; ++k) {
  38751. partialData = data[k];
  38752. partialPath = [];
  38753. for (i = 0, ii = partialData.length; i < ii; ++i) {
  38754. point = this._toScreen(this._toTransformedFast(partialData[i]));
  38755. partialPath.push(point[0], point[1])
  38756. }
  38757. list.push(_buildPath(partialPath))
  38758. }
  38759. return list.join(' ')
  38760. },
  38761. getPointCoordinates: function(data) {
  38762. var point = this._toScreen(this._toTransformedFast(data));
  38763. return {
  38764. x: _round(point[0]),
  38765. y: _round(point[1])
  38766. }
  38767. },
  38768. getZoom: function() {
  38769. return this._zoom
  38770. },
  38771. setZoom: function(zoom) {
  38772. var that = this;
  38773. that._zoom = truncate(zoom, that._minZoom, that._maxZoom, that._minZoom);
  38774. that._adjustCenter();
  38775. return that
  38776. },
  38777. getScaledZoom: function() {
  38778. return _round((this._scale.length - 1) * _ln(this._zoom) / _ln(this._maxZoom))
  38779. },
  38780. setScaledZoom: function(scaledZoom) {
  38781. return this.setZoom(this._scale[_round(scaledZoom)])
  38782. },
  38783. getZoomScalePartition: function() {
  38784. return this._scale.length - 1
  38785. },
  38786. _setupScaling: function() {
  38787. var that = this,
  38788. k = _round(TWO_TO_LN2 * _ln(that._maxZoom));
  38789. k = k > 4 ? k : 4;
  38790. var step = _pow(that._maxZoom, 1 / k),
  38791. zoom = that._minZoom,
  38792. i = 1;
  38793. that._scale = [zoom];
  38794. for (; i <= k; ++i)
  38795. that._scale.push(zoom *= step)
  38796. },
  38797. setMaxZoom: function(maxZoom) {
  38798. var that = this;
  38799. that._minZoom = DEFAULT_MIN_ZOOM;
  38800. that._maxZoom = truncate(maxZoom, that._minZoom, _Number.MAX_VALUE, DEFAULT_MAX_ZOOM);
  38801. that._setupScaling();
  38802. if (that._zoom > that._maxZoom)
  38803. that.setZoom(that._maxZoom);
  38804. return that
  38805. },
  38806. getMinZoom: function() {
  38807. return this._minZoom
  38808. },
  38809. getMaxZoom: function() {
  38810. return this._maxZoom
  38811. },
  38812. getCenter: function() {
  38813. return [this._center[0], this._center[1]]
  38814. },
  38815. setCenter: function(center) {
  38816. var _center = _isArray(center) ? center : null;
  38817. _center = _center || center && (center.lon || center.lat) && [center.lon, center.lat] || [];
  38818. var that = this;
  38819. 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])];
  38820. that._adjustCenter();
  38821. return that
  38822. },
  38823. setCenterByPoint: function(coordinates, screenPosition) {
  38824. var that = this,
  38825. p = that._project(coordinates),
  38826. q = that._fromScreen(screenPosition);
  38827. return that.setCenter(that._unproject([-q[0] / that._zoom + p[0], -q[1] / that._zoom + p[1]]))
  38828. },
  38829. moveCenter: function(screenDx, screenDy) {
  38830. var that = this,
  38831. current = that._toScreen(that._toTransformed(that._project(that._center))),
  38832. center = that._unproject(that._fromTransformed(that._fromScreen([current[0] + screenDx, current[1] + screenDy])));
  38833. return that.setCenter(center)
  38834. },
  38835. getViewport: function() {
  38836. var p1 = this._unproject(this._fromTransformed([-1, -1])),
  38837. p2 = this._unproject(this._fromTransformed([+1, +1]));
  38838. return [p1[0], p1[1], p2[0], p2[1]]
  38839. },
  38840. setViewport: function(viewport) {
  38841. var that = this;
  38842. if (!_isArray(viewport))
  38843. return that.setZoom(that._minZoom).setCenter(that._defaultCenter);
  38844. var _viewport = truncateQuad(viewport, that._minBase, that._maxBase),
  38845. lt = that._project(_viewport.lt),
  38846. rb = that._project(_viewport.rb),
  38847. l = _min(lt[0], rb[0]),
  38848. t = _min(lt[1], rb[1]),
  38849. r = _max(lt[0], rb[0]),
  38850. b = _max(lt[1], rb[1]),
  38851. zoom = 2 / _max(r - l, b - t),
  38852. xc = selectCenterValue(l, r, -1 - zoom * l, +1 - zoom * r),
  38853. yc = selectCenterValue(t, b, -1 - zoom * t, +1 - zoom * b);
  38854. return that.setZoom(zoom).setCenter(that._unproject([-xc / zoom, -yc / zoom]))
  38855. },
  38856. getTransform: function() {
  38857. return {
  38858. translateX: this._dxcenter * this._xradius,
  38859. translateY: this._dycenter * this._yradius
  38860. }
  38861. },
  38862. fromScreenPoint: function(x, y) {
  38863. return this._unproject(this._fromTransformed(this._fromScreen([x, y])))
  38864. },
  38865. fromScreenPointStrict: function(x, y) {
  38866. var that = this,
  38867. p = that._fromTransformed(that._fromScreen([x, y])),
  38868. q = that._unproject(p);
  38869. 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]
  38870. },
  38871. snapCenter: function() {
  38872. this._snappedCenter = this.getCenter();
  38873. return this
  38874. },
  38875. isCenterChanged: function() {
  38876. var center = this.getCenter();
  38877. return !floatsEqual(this._snappedCenter[0], center[0]) || !floatsEqual(this._snappedCenter[1], center[1])
  38878. },
  38879. snapZoom: function() {
  38880. this._snappedZoom = this.getZoom();
  38881. return this
  38882. },
  38883. isZoomChanged: function() {
  38884. return !floatsEqual(this._snappedZoom, this.getZoom())
  38885. }
  38886. };
  38887. DX.viz.map._tests.Projection = Projection;
  38888. DX.viz.map._tests.mercator = mercator;
  38889. DX.viz.map._tests._DEBUG_stubMercator = function(stub) {
  38890. mercator = stub
  38891. };
  38892. DX.viz.map._tests._DEBUG_restoreMercator = function() {
  38893. mercator = DX.viz.map._tests.mercator
  38894. };
  38895. DX.viz.map.Map.prototype._factory.createProjection = function() {
  38896. return new Projection
  38897. }
  38898. })(DevExpress, jQuery);
  38899. /*! Module viz-vectormap, file controlBar.js */
  38900. (function(DX, undefined) {
  38901. var _buildPath = DX.viz.renderers.buildPath,
  38902. _setTimeout = setTimeout,
  38903. _clearTimeout = clearTimeout,
  38904. _round = Math.round,
  38905. _pow = Math.pow,
  38906. _ln = Math.log;
  38907. var _LN2 = Math.LN2;
  38908. var COMMAND_RESET = 'command-reset',
  38909. COMMAND_MOVE_UP = 'command-move-up',
  38910. COMMAND_MOVE_RIGHT = 'command-move-right',
  38911. COMMAND_MOVE_DOWN = 'command-move-down',
  38912. COMMAND_MOVE_LEFT = 'command-move-left',
  38913. COMMAND_ZOOM_IN = 'command-zoom-in',
  38914. COMMAND_ZOOM_OUT = 'command-zoom-out',
  38915. COMMAND_ZOOM_DRAG = 'command-zoom-drag';
  38916. var _DATA_KEY = DX.viz.map.__DATA_KEY,
  38917. EVENT_TARGET_TYPE = 'control-bar';
  38918. var COMMAND_TO_TYPE_MAP = {};
  38919. COMMAND_TO_TYPE_MAP[COMMAND_RESET] = ResetCommand;
  38920. 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;
  38921. COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_IN] = COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_OUT] = ZoomCommand;
  38922. COMMAND_TO_TYPE_MAP[COMMAND_ZOOM_DRAG] = ZoomDragCommand;
  38923. var ControlBar = DX.Class.inherit({
  38924. ctor: function(parameters) {
  38925. var that = this;
  38926. that._container = parameters.container;
  38927. that._createElements(parameters.renderer);
  38928. var context = parameters.context,
  38929. resetCallback = parameters.resetCallback,
  38930. beginMoveCallback = parameters.beginMoveCallback,
  38931. endMoveCallback = parameters.endMoveCallback,
  38932. moveCallback = parameters.moveCallback,
  38933. zoomCallback = parameters.zoomCallback;
  38934. parameters = null;
  38935. that._reset = function() {
  38936. resetCallback.call(context)
  38937. };
  38938. that._beginMove = function() {
  38939. beginMoveCallback.call(context)
  38940. };
  38941. that._endMove = function() {
  38942. endMoveCallback.call(context)
  38943. };
  38944. that._move = function(dx, dy) {
  38945. moveCallback.call(context, dx, dy)
  38946. };
  38947. that._zoom = function(zoom, x, y) {
  38948. zoomCallback.call(context, zoom, x, y)
  38949. };
  38950. that._dispose = function() {
  38951. this._reset = this._move = this._zoom = this._dispose = context = resetCallback = moveCallback = zoomCallback = null
  38952. }
  38953. },
  38954. _createElements: function(renderer) {
  38955. var that = this;
  38956. that._root = renderer.createGroup({'class': 'dxm-control-bar'});
  38957. that._buttonsGroup = renderer.createGroup({'class': 'dxm-control-buttons'}).append(that._root);
  38958. that._trackersGroup = renderer.createGroup({
  38959. stroke: 'none',
  38960. strokeWidth: 0,
  38961. fill: '#000000',
  38962. opacity: 0.0001,
  38963. cursor: 'pointer'
  38964. }).append(that._root);
  38965. var options = {
  38966. bigCircleSize: 58,
  38967. smallCircleSize: 28,
  38968. buttonSize: 10,
  38969. arrowButtonOffset: 20,
  38970. incdecButtonSize: 11,
  38971. incButtonOffset: 66,
  38972. decButtonOffset: 227,
  38973. sliderLineStartOffset: 88.5,
  38974. sliderLineEndOffset: 205.5,
  38975. sliderLength: 20,
  38976. sliderWidth: 8,
  38977. trackerGap: 4
  38978. };
  38979. that._createButtons(renderer, options);
  38980. that._createTrackers(renderer, options);
  38981. that._root.applySettings({
  38982. translateX: 50.5,
  38983. translateY: 50.5
  38984. })
  38985. },
  38986. _createButtons: function(renderer, options) {
  38987. var group = this._buttonsGroup,
  38988. size = options.buttonSize / 2,
  38989. offset1 = options.arrowButtonOffset - size,
  38990. offset2 = options.arrowButtonOffset,
  38991. incdecButtonSize = options.incdecButtonSize / 2;
  38992. renderer.createCircle(0, 0, options.bigCircleSize / 2).append(group);
  38993. renderer.createCircle(0, 0, size).append(group);
  38994. renderer.createPath([-size, -offset1, 0, -offset2, size, -offset1]).append(group);
  38995. renderer.createPath([offset1, -size, offset2, 0, offset1, size]).append(group);
  38996. renderer.createPath([size, offset1, 0, offset2, -size, offset1]).append(group);
  38997. renderer.createPath([-offset1, size, -offset2, 0, -offset1, -size]).append(group);
  38998. renderer.createCircle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group);
  38999. renderer.createSimplePath({d: _buildPath([-incdecButtonSize, options.incButtonOffset, incdecButtonSize, options.incButtonOffset]) + ' ' + _buildPath([0, options.incButtonOffset - incdecButtonSize, 0, options.incButtonOffset + incdecButtonSize])}).append(group);
  39000. renderer.createCircle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group);
  39001. renderer.createSimplePath({d: _buildPath([-incdecButtonSize, options.decButtonOffset, incdecButtonSize, options.decButtonOffset])}).append(group);
  39002. renderer.createSimplePath({d: _buildPath([0, options.sliderLineStartOffset, 0, options.sliderLineEndOffset])}).append(group);
  39003. this._zoomDrag = renderer.createRect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).append(group);
  39004. this._sliderLineLength = options.sliderLineEndOffset - options.sliderLineStartOffset
  39005. },
  39006. _createTrackers: function(renderer, options) {
  39007. var group = this._trackersGroup,
  39008. size = _round((options.arrowButtonOffset - options.trackerGap) / 2),
  39009. offset1 = options.arrowButtonOffset - size,
  39010. offset2 = _round(_pow(options.bigCircleSize * options.bigCircleSize / 4 - size * size, 0.5)),
  39011. size2 = offset2 - offset1,
  39012. element;
  39013. renderer.createRect(-size, -size, size * 2, size * 2).append(group).data(_DATA_KEY, {
  39014. index: COMMAND_RESET,
  39015. type: EVENT_TARGET_TYPE
  39016. });
  39017. renderer.createRect(-size, -offset2, size * 2, size2).append(group).data(_DATA_KEY, {
  39018. index: COMMAND_MOVE_UP,
  39019. type: EVENT_TARGET_TYPE
  39020. });
  39021. renderer.createRect(offset1, -size, size2, size * 2).append(group).data(_DATA_KEY, {
  39022. index: COMMAND_MOVE_RIGHT,
  39023. type: EVENT_TARGET_TYPE
  39024. });
  39025. renderer.createRect(-size, offset1, size * 2, size2).append(group).data(_DATA_KEY, {
  39026. index: COMMAND_MOVE_DOWN,
  39027. type: EVENT_TARGET_TYPE
  39028. });
  39029. renderer.createRect(-offset2, -size, size2, size * 2).append(group).data(_DATA_KEY, {
  39030. index: COMMAND_MOVE_LEFT,
  39031. type: EVENT_TARGET_TYPE
  39032. });
  39033. renderer.createCircle(0, options.incButtonOffset, options.smallCircleSize / 2).append(group).data(_DATA_KEY, {
  39034. index: COMMAND_ZOOM_IN,
  39035. type: EVENT_TARGET_TYPE
  39036. });
  39037. renderer.createCircle(0, options.decButtonOffset, options.smallCircleSize / 2).append(group).data(_DATA_KEY, {
  39038. index: COMMAND_ZOOM_OUT,
  39039. type: EVENT_TARGET_TYPE
  39040. });
  39041. this._zoomDragCover = renderer.createRect(-options.sliderLength / 2, options.sliderLineEndOffset - options.sliderWidth / 2, options.sliderLength, options.sliderWidth).append(group).data(_DATA_KEY, {
  39042. index: COMMAND_ZOOM_DRAG,
  39043. type: EVENT_TARGET_TYPE
  39044. })
  39045. },
  39046. dispose: function() {
  39047. var that = this;
  39048. delete that._container;
  39049. that._dispose();
  39050. that._root.clear();
  39051. delete that._root;
  39052. delete that._buttonsGroup;
  39053. delete that._zoomDrag;
  39054. delete that._zoomDragCover;
  39055. return that
  39056. },
  39057. setZoomPartition: function(partition) {
  39058. this._zoomPartition = partition;
  39059. this._sliderUnitLength = this._sliderLineLength / partition;
  39060. return this
  39061. },
  39062. setZoom: function(zoom) {
  39063. this._adjustZoom(zoom);
  39064. return this
  39065. },
  39066. setOptions: function(options, interactionOptions) {
  39067. options = options || {};
  39068. interactionOptions = interactionOptions || {};
  39069. this._dragAndZoomEnabled = interactionOptions.dragAndZoomEnabled !== undefined ? !!interactionOptions.dragAndZoomEnabled : true;
  39070. this._enabled = this._dragAndZoomEnabled && (options.enabled !== undefined ? !!options.enabled : true);
  39071. this._buttonsGroup.applySettings(options.shape);
  39072. return this
  39073. },
  39074. clean: function() {
  39075. this._enabled && this._root.detach();
  39076. return this
  39077. },
  39078. render: function() {
  39079. this._enabled && this._root.append(this._container);
  39080. return this
  39081. },
  39082. _adjustZoom: function(zoom) {
  39083. var that = this;
  39084. that._zoomFactor = _round(zoom);
  39085. that._zoomFactor >= 0 || (that._zoomFactor = 0);
  39086. that._zoomFactor <= that._zoomPartition || (that._zoomFactor = that._zoomPartition);
  39087. var transform = {translateY: -that._zoomFactor * that._sliderUnitLength};
  39088. that._zoomDrag.applySettings(transform);
  39089. that._zoomDragCover.applySettings(transform)
  39090. },
  39091. _applyZoom: function(x, y) {
  39092. this._zoom(this._zoomFactor, x, y)
  39093. },
  39094. processStart: function(arg) {
  39095. if (this._dragAndZoomEnabled) {
  39096. var commandType = COMMAND_TO_TYPE_MAP[arg.data];
  39097. this._command = new commandType(this, arg)
  39098. }
  39099. return this
  39100. },
  39101. processMove: function(arg) {
  39102. if (this._dragAndZoomEnabled)
  39103. this._command.update(arg);
  39104. return this
  39105. },
  39106. processEnd: function(arg) {
  39107. if (this._dragAndZoomEnabled)
  39108. this._command.finish(arg);
  39109. return this
  39110. },
  39111. processZoom: function(arg) {
  39112. var that = this,
  39113. zoomFactor;
  39114. if (that._dragAndZoomEnabled) {
  39115. if (arg.delta)
  39116. zoomFactor = arg.delta;
  39117. else if (arg.ratio)
  39118. zoomFactor = _ln(arg.ratio) / _LN2;
  39119. that._adjustZoom(that._zoomFactor + zoomFactor);
  39120. that._applyZoom(arg.x, arg.y)
  39121. }
  39122. return that
  39123. }
  39124. });
  39125. function disposeCommand(command) {
  39126. delete command._owner;
  39127. command.update = function(){};
  39128. command.finish = function(){}
  39129. }
  39130. function ResetCommand(owner, arg) {
  39131. this._owner = owner;
  39132. this._command = arg.data
  39133. }
  39134. ResetCommand.prototype.update = function(arg) {
  39135. arg.data !== this._command && disposeCommand(this)
  39136. };
  39137. ResetCommand.prototype.finish = function() {
  39138. this._owner._reset();
  39139. this._owner._adjustZoom(0);
  39140. disposeCommand(this)
  39141. };
  39142. function MoveCommand(owner, arg) {
  39143. this._command = arg.data;
  39144. var timeout = null,
  39145. interval = 100,
  39146. dx = 0,
  39147. dy = 0;
  39148. switch (this._command) {
  39149. case COMMAND_MOVE_UP:
  39150. dy = -10;
  39151. break;
  39152. case COMMAND_MOVE_RIGHT:
  39153. dx = 10;
  39154. break;
  39155. case COMMAND_MOVE_DOWN:
  39156. dy = 10;
  39157. break;
  39158. case COMMAND_MOVE_LEFT:
  39159. dx = -10;
  39160. break
  39161. }
  39162. function callback() {
  39163. owner._move(dx, dy);
  39164. timeout = _setTimeout(callback, interval)
  39165. }
  39166. this._stop = function() {
  39167. _clearTimeout(timeout);
  39168. owner._endMove();
  39169. this._stop = owner = callback = null;
  39170. return this
  39171. };
  39172. arg = null;
  39173. owner._beginMove();
  39174. callback()
  39175. }
  39176. MoveCommand.prototype.update = function(arg) {
  39177. this._command !== arg.data && this.finish()
  39178. };
  39179. MoveCommand.prototype.finish = function() {
  39180. disposeCommand(this._stop())
  39181. };
  39182. function ZoomCommand(owner, arg) {
  39183. this._owner = owner;
  39184. this._command = arg.data;
  39185. var timeout = null,
  39186. interval = 150,
  39187. dzoom = this._command === COMMAND_ZOOM_IN ? 1 : -1;
  39188. function callback() {
  39189. owner._adjustZoom(owner._zoomFactor + dzoom);
  39190. timeout = _setTimeout(callback, interval)
  39191. }
  39192. this._stop = function() {
  39193. _clearTimeout(timeout);
  39194. this._stop = owner = callback = null;
  39195. return this
  39196. };
  39197. arg = null;
  39198. callback()
  39199. }
  39200. ZoomCommand.prototype.update = function(arg) {
  39201. this._command !== arg.data && this.finish()
  39202. };
  39203. ZoomCommand.prototype.finish = function() {
  39204. this._owner._applyZoom();
  39205. disposeCommand(this._stop())
  39206. };
  39207. function ZoomDragCommand(owner, arg) {
  39208. this._owner = owner;
  39209. this._zoomFactor = owner._zoomFactor;
  39210. this._pos = arg.y
  39211. }
  39212. ZoomDragCommand.prototype.update = function(arg) {
  39213. var owner = this._owner;
  39214. owner._adjustZoom(this._zoomFactor + owner._zoomPartition * (this._pos - arg.y) / owner._sliderLineLength)
  39215. };
  39216. ZoomDragCommand.prototype.finish = function() {
  39217. this._owner._applyZoom();
  39218. disposeCommand(this)
  39219. };
  39220. DX.viz.map._tests.ControlBar = ControlBar;
  39221. DX.viz.map.Map.prototype._factory.createControlBar = function(parameters) {
  39222. return new ControlBar(parameters)
  39223. }
  39224. })(DevExpress);
  39225. /*! Module viz-vectormap, file tracker.js */
  39226. (function(DX, $, undefined) {
  39227. var _addNamespace = DX.ui.events.addNamespace,
  39228. _abs = Math.abs,
  39229. _sqrt = Math.sqrt,
  39230. _round = Math.round,
  39231. _max = Math.max,
  39232. _min = Math.min,
  39233. _now = $.now,
  39234. _extend = $.extend;
  39235. var _NAME = DX.viz.map.Map.prototype.NAME,
  39236. _DATA_KEY = DX.viz.map.__DATA_KEY;
  39237. var $doc = $(document);
  39238. var EVENTS = {};
  39239. setupEvents();
  39240. var EVENT_START = 'start',
  39241. EVENT_MOVE = 'move',
  39242. EVENT_END = 'end',
  39243. EVENT_ZOOM = 'zoom',
  39244. EVENT_HOVER_ON = 'hover-on',
  39245. EVENT_HOVER_OFF = 'hover-off',
  39246. EVENT_CLICK = 'click',
  39247. EVENT_FOCUS_ON = 'focus-on',
  39248. EVENT_FOCUS_MOVE = 'focus-move',
  39249. EVENT_FOCUS_OFF = 'focus-off';
  39250. var CLICK_TIME_THRESHOLD = 500,
  39251. CLICK_COORD_THRESHOLD = 5,
  39252. DRAG_COORD_THRESHOLD_MOUSE = 5,
  39253. DRAG_COORD_THRESHOLD_TOUCH = 10,
  39254. FOCUS_ON_DELAY_MOUSE = 300,
  39255. FOCUS_OFF_DELAY_MOUSE = 300,
  39256. FOCUS_ON_DELAY_TOUCH = 300,
  39257. FOCUS_OFF_DELAY_TOUCH = 400,
  39258. FOCUS_COORD_THRESHOLD_MOUSE = 5;
  39259. function Tracker(parameters) {
  39260. this._root = parameters.root;
  39261. this._callbacks = {};
  39262. this._createEventHandlers();
  39263. this._focus = new Focus(this._callbacks)
  39264. }
  39265. _extend(Tracker.prototype, {
  39266. dispose: function() {
  39267. var that = this;
  39268. that._focus.dispose();
  39269. that._root = that._callbacks = that._focus = that._rootClickEvents = that._$docClickEvents = that._rootZoomEvents = that._$docZoomEvents = that._rootHoverEvents = that._$docHoverEvents = that._rootFocusEvents = that._$docFocusEvents = null;
  39270. return that
  39271. },
  39272. _createEventHandlers: function() {
  39273. var that = this;
  39274. that._rootClickEvents = {};
  39275. that._rootClickEvents[EVENTS.start] = function(event) {
  39276. var isTouch = isTouchEvent(event);
  39277. if (isTouch && !that._isTouchEnabled)
  39278. return;
  39279. event.preventDefault();
  39280. var coords = getEventCoords(event);
  39281. that._clickState = {
  39282. x: coords.x,
  39283. y: coords.y,
  39284. time: _now()
  39285. }
  39286. };
  39287. that._$docClickEvents = {};
  39288. that._$docClickEvents[EVENTS.end] = function(event) {
  39289. var state = that._clickState;
  39290. if (!state)
  39291. return;
  39292. var isTouch = isTouchEvent(event);
  39293. if (isTouch && !that._isTouchEnabled)
  39294. return;
  39295. if (_now() - state.time <= CLICK_TIME_THRESHOLD) {
  39296. var coords = getEventCoords(event);
  39297. if (_abs(coords.x - state.x) <= CLICK_COORD_THRESHOLD && _abs(coords.y - state.y) <= CLICK_COORD_THRESHOLD)
  39298. that._callbacks[EVENT_CLICK]({
  39299. data: $(event.target).data(_DATA_KEY) || {},
  39300. x: coords.x,
  39301. y: coords.y,
  39302. $event: event
  39303. })
  39304. }
  39305. that._clickState = null
  39306. };
  39307. that._rootDragEvents = {};
  39308. that._rootDragEvents[EVENTS.start] = function(event) {
  39309. var isTouch = isTouchEvent(event);
  39310. if (isTouch && !that._isTouchEnabled)
  39311. return;
  39312. var coords = getEventCoords(event);
  39313. that._dragState = {
  39314. x: coords.x,
  39315. y: coords.y,
  39316. data: $(event.target).data(_DATA_KEY) || {}
  39317. };
  39318. if (that._isDragEnabled)
  39319. that._callbacks[EVENT_START]({
  39320. data: that._dragState.data,
  39321. x: coords.x,
  39322. y: coords.y
  39323. })
  39324. };
  39325. that._$docDragEvents = {};
  39326. that._$docDragEvents[EVENTS.move] = function(event) {
  39327. var state = that._dragState;
  39328. if (!state)
  39329. return;
  39330. var isTouch = isTouchEvent(event);
  39331. if (isTouch && !that._isTouchEnabled)
  39332. return;
  39333. var coords = getEventCoords(event),
  39334. threshold = isTouch ? DRAG_COORD_THRESHOLD_TOUCH : DRAG_COORD_THRESHOLD_MOUSE;
  39335. if (state.active || _abs(coords.x - state.x) > threshold || _abs(coords.y - state.y) > threshold) {
  39336. state.x = coords.x;
  39337. state.y = coords.y;
  39338. state.active = true;
  39339. state.data = $(event.target).data(_DATA_KEY) || {};
  39340. if (that._isDragEnabled)
  39341. that._callbacks[EVENT_MOVE]({
  39342. data: state.data,
  39343. x: coords.x,
  39344. y: coords.y
  39345. })
  39346. }
  39347. };
  39348. that._$docDragEvents[EVENTS.end] = function(event) {
  39349. var state = that._dragState;
  39350. if (!state)
  39351. return;
  39352. var isTouch = isTouchEvent(event);
  39353. if (isTouch && !that._isTouchEnabled)
  39354. return;
  39355. that._endDragging()
  39356. };
  39357. that._rootZoomEvents = {};
  39358. that._rootZoomEvents[EVENTS.wheel] = function(event) {
  39359. if (!that._isWheelEnabled)
  39360. return;
  39361. event.preventDefault();
  39362. if (that._zoomState)
  39363. return;
  39364. var delta = event.originalEvent.wheelDelta / 120 || event.originalEvent.detail / -3 || 0;
  39365. if (delta === 0)
  39366. return;
  39367. delta = delta > 0 ? _min(_round(delta) || +1, +4) : _max(_round(delta) || -1, -4);
  39368. var coords = getEventCoords(event);
  39369. if (that._isZoomEnabled)
  39370. that._callbacks[EVENT_ZOOM]({
  39371. delta: delta,
  39372. x: coords.x,
  39373. y: coords.y
  39374. });
  39375. that._zoomState = setTimeout(function() {
  39376. that._zoomState = null
  39377. }, 50)
  39378. };
  39379. that._rootZoomEvents[EVENTS.start] = function(event) {
  39380. var isTouch = isTouchEvent(event);
  39381. if (!isTouch || !that._isTouchEnabled)
  39382. return;
  39383. var state = that._zoomState = that._zoomState || {};
  39384. if (state.pointer1 && state.pointer2)
  39385. return;
  39386. var coords;
  39387. if (state.pointer1 === undefined) {
  39388. state.pointer1 = getPointerId(event) || 0;
  39389. coords = getMultitouchEventCoords(event, state.pointer1);
  39390. state.x1 = state.x1_0 = coords.x;
  39391. state.y1 = state.y1_0 = coords.y
  39392. }
  39393. if (state.pointer2 === undefined) {
  39394. var pointer2 = getPointerId(event) || 1;
  39395. if (pointer2 !== state.pointer1) {
  39396. coords = getMultitouchEventCoords(event, pointer2);
  39397. if (coords) {
  39398. state.x2 = state.x2_0 = coords.x;
  39399. state.y2 = state.y2_0 = coords.y;
  39400. state.pointer2 = pointer2;
  39401. state.ready = true;
  39402. that._endDragging()
  39403. }
  39404. }
  39405. }
  39406. };
  39407. that._$docZoomEvents = {};
  39408. that._$docZoomEvents[EVENTS.move] = function(event) {
  39409. var state = that._zoomState;
  39410. if (!state)
  39411. return;
  39412. var isTouch = isTouchEvent(event);
  39413. if (!isTouch || !that._isTouchEnabled)
  39414. return;
  39415. var coords;
  39416. if (state.pointer1 !== undefined) {
  39417. coords = getMultitouchEventCoords(event, state.pointer1);
  39418. if (coords) {
  39419. state.x1 = coords.x;
  39420. state.y1 = coords.y
  39421. }
  39422. }
  39423. if (state.pointer2 !== undefined) {
  39424. coords = getMultitouchEventCoords(event, state.pointer2);
  39425. if (coords) {
  39426. state.x2 = coords.x;
  39427. state.y2 = coords.y
  39428. }
  39429. }
  39430. };
  39431. that._$docZoomEvents[EVENTS.end] = function(event) {
  39432. var state = that._zoomState;
  39433. if (!state)
  39434. return;
  39435. var isTouch = isTouchEvent(event);
  39436. if (!isTouch || !that._isTouchEnabled)
  39437. return;
  39438. if (state.ready) {
  39439. var startDistance = getDistance(state.x1_0, state.y1_0, state.x2_0, state.y2_0),
  39440. currentDistance = getDistance(state.x1, state.y1, state.x2, state.y2);
  39441. if (that._isZoomEnabled)
  39442. that._callbacks[EVENT_ZOOM]({
  39443. ratio: currentDistance / startDistance,
  39444. x: (state.x1_0 + state.x2_0) / 2,
  39445. y: (state.y1_0 + state.y2_0) / 2
  39446. })
  39447. }
  39448. that._zoomState = null
  39449. };
  39450. that._rootHoverEvents = {};
  39451. that._rootHoverEvents[EVENTS.over] = function(event) {
  39452. if (that._hoverTarget === event.target)
  39453. return;
  39454. var isTouch = isTouchEvent(event);
  39455. if (isTouch)
  39456. return;
  39457. var data = $(event.target).data(_DATA_KEY);
  39458. if (!data)
  39459. return;
  39460. that._hoverTarget && that._endHovering();
  39461. that._hoverTarget = event.target;
  39462. that._hoverState = {data: data};
  39463. that._callbacks[EVENT_HOVER_ON]({data: data})
  39464. };
  39465. that._$docHoverEvents = {};
  39466. that._$docHoverEvents[EVENTS.out] = function(event) {
  39467. var state = that._hoverState;
  39468. if (!state)
  39469. return;
  39470. var isTouch = isTouchEvent(event);
  39471. if (isTouch)
  39472. return;
  39473. var data = $(event.target).data(_DATA_KEY);
  39474. if (!data)
  39475. return;
  39476. that._endHovering()
  39477. };
  39478. that._rootFocusEvents = {};
  39479. that._rootFocusEvents[EVENTS.start] = function(event) {
  39480. var isTouch = isTouchEvent(event);
  39481. if (!isTouch || !that._isTouchEnabled)
  39482. return;
  39483. var data = $(event.target).data(_DATA_KEY);
  39484. if (!data)
  39485. return;
  39486. that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
  39487. that._focus.turnOn(event.target, data, getEventCoords(event), FOCUS_ON_DELAY_TOUCH);
  39488. that._skip$docEvent = true
  39489. };
  39490. that._rootFocusEvents[EVENTS.over] = function(event) {
  39491. if (that._focusTarget === event.target)
  39492. return;
  39493. that._focusTarget = event.target;
  39494. var isTouch = isTouchEvent(event);
  39495. if (isTouch)
  39496. return;
  39497. var data = $(event.target).data(_DATA_KEY);
  39498. if (!data)
  39499. return;
  39500. if (that._focusTarget)
  39501. that._focus.turnOff(FOCUS_OFF_DELAY_MOUSE);
  39502. var coords = getEventCoords(event);
  39503. if (that._focus.active)
  39504. that._focus.move(event.target, data, coords);
  39505. else
  39506. that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE)
  39507. };
  39508. that._$docFocusEvents = {};
  39509. that._$docFocusEvents[EVENTS.start] = function(event) {
  39510. that._focusTarget = event.target;
  39511. var isTouch = isTouchEvent(event);
  39512. if (!isTouch || !that._isTouchEnabled)
  39513. return;
  39514. if (!that._skip$docEvent)
  39515. that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
  39516. that._skip$docEvent = null
  39517. };
  39518. that._$docFocusEvents[EVENTS.move] = function(event) {
  39519. if (that._focus.disabled)
  39520. return;
  39521. if (that._focusTarget !== event.target)
  39522. return;
  39523. var isTouch = isTouchEvent(event);
  39524. if (isTouch && !that._isTouchEnabled)
  39525. return;
  39526. var data = $(event.target).data(_DATA_KEY);
  39527. if (!data)
  39528. return;
  39529. var coords = getEventCoords(event);
  39530. if (isTouch) {
  39531. if (that._dragState && that._dragState.active || that._zoomState && that._zoomState.ready)
  39532. that._focus.cancel()
  39533. }
  39534. else if (that._focus.active)
  39535. if (that._dragState && that._dragState.active) {
  39536. that._focus.cancel();
  39537. that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE * 4)
  39538. }
  39539. else
  39540. that._focus.move(event.target, data, coords);
  39541. else if (_abs(coords.x - that._focus.x) > FOCUS_COORD_THRESHOLD_MOUSE || _abs(coords.y - that._focus.y) > FOCUS_COORD_THRESHOLD_MOUSE)
  39542. that._focus.turnOn(event.target, data, coords, FOCUS_ON_DELAY_MOUSE)
  39543. };
  39544. that._$docFocusEvents[EVENTS.end] = function(event) {
  39545. if (that._focus.disabled)
  39546. return;
  39547. var isTouch = isTouchEvent(event);
  39548. if (!isTouch || !that._isTouchEnabled)
  39549. return;
  39550. that._focusTarget = null;
  39551. if (!that._focus.active)
  39552. that._focus.turnOff(FOCUS_OFF_DELAY_TOUCH);
  39553. else if (that._focus.changing)
  39554. that._focus.cancel()
  39555. };
  39556. that._$docFocusEvents[EVENTS.out] = function(event) {
  39557. if (that._focus.disabled)
  39558. return;
  39559. var isTouch = isTouchEvent(event);
  39560. if (isTouch)
  39561. return;
  39562. that._focusTarget = null;
  39563. var data = $(event.target).data(_DATA_KEY);
  39564. if (!data)
  39565. return;
  39566. that._focus.turnOff(FOCUS_OFF_DELAY_MOUSE)
  39567. }
  39568. },
  39569. _endDragging: function() {
  39570. var that = this,
  39571. state = that._dragState;
  39572. that._dragState = null;
  39573. if (state && that._isDragEnabled)
  39574. that._callbacks[EVENT_END]({
  39575. data: state.data,
  39576. x: state.x,
  39577. y: state.y
  39578. })
  39579. },
  39580. _endHovering: function() {
  39581. var that = this,
  39582. state = that._hoverState;
  39583. that._hoverState = that._hoverTarget = null;
  39584. if (state)
  39585. that._callbacks[EVENT_HOVER_OFF]({data: state.data})
  39586. },
  39587. reset: function() {
  39588. var that = this;
  39589. that._clickState = null;
  39590. that._endDragging();
  39591. that._endHovering();
  39592. that._focus.cancel();
  39593. that._focusTarget = null;
  39594. return that
  39595. },
  39596. setCallbacks: function(callbacks) {
  39597. _extend(this._callbacks, callbacks);
  39598. return this
  39599. },
  39600. setOptions: function(options) {
  39601. this._isTouchEnabled = options.touchEnabled === undefined || !!options.touchEnabled;
  39602. this._isWheelEnabled = options.wheelEnabled === undefined || !!options.wheelEnabled;
  39603. this._isDragEnabled = options.dragAndZoomEnabled === undefined || !!options.dragAndZoomEnabled;
  39604. this._isZoomEnabled = options.dragAndZoomEnabled === undefined || !!options.dragAndZoomEnabled;
  39605. return this
  39606. },
  39607. clean: function() {
  39608. var that = this;
  39609. if (that._isTouchEnabled) {
  39610. that._root.applySettings({style: {
  39611. 'touch-action': '',
  39612. '-ms-touch-action': '',
  39613. '-webkit-user-select': ''
  39614. }});
  39615. that._root.off(_addNamespace('MSHoldVisual', _NAME)).off(_addNamespace('contextmenu', _NAME))
  39616. }
  39617. that._detachEventHandlers();
  39618. that.reset();
  39619. return that
  39620. },
  39621. render: function() {
  39622. var that = this;
  39623. if (that._isTouchEnabled) {
  39624. that._root.applySettings({style: {
  39625. 'touch-action': 'none',
  39626. '-ms-touch-action': 'none',
  39627. '-webkit-user-select': 'none'
  39628. }});
  39629. that._root.on(_addNamespace('MSHoldVisual', _NAME), function(event) {
  39630. event.preventDefault()
  39631. }).on(_addNamespace('contextmenu', _NAME), function(event) {
  39632. isTouchEvent(event) && event.preventDefault()
  39633. })
  39634. }
  39635. that._attachEventHandlers();
  39636. return that
  39637. },
  39638. _attachEventHandlers: function() {
  39639. var that = this;
  39640. that._root.on(that._rootClickEvents).on(that._rootDragEvents).on(that._rootZoomEvents).on(that._rootHoverEvents).on(that._rootFocusEvents);
  39641. $doc.on(that._$docClickEvents).on(that._$docDragEvents).on(that._$docZoomEvents).on(that._$docHoverEvents).on(that._$docFocusEvents)
  39642. },
  39643. _detachEventHandlers: function() {
  39644. var that = this;
  39645. that._root.off(that._rootClickEvents).off(that._rootDragEvents).off(that._rootZoomEvents).off(that._rootHoverEvents).off(that._rootFocusEvents);
  39646. $doc.off(that._$docClickEvents).off(that._$docDragEvents).off(that._$docZoomEvents).off(that._$docHoverEvents).off(that._$docFocusEvents)
  39647. }
  39648. });
  39649. function Focus(callbacks) {
  39650. this._callbacks = callbacks;
  39651. this.disabled = true
  39652. }
  39653. _extend(Focus.prototype, {
  39654. dispose: function() {
  39655. var that = this;
  39656. clearTimeout(that._onTimer);
  39657. clearTimeout(that._offTimer);
  39658. that._callbacks = that._onTimer = that._offTimer = that.active = that._data = null
  39659. },
  39660. _createCallback: function(target, data, coords) {
  39661. var that = this;
  39662. return function() {
  39663. if (that.active === target) {
  39664. that._callbacks[EVENT_FOCUS_MOVE]({
  39665. data: that._data,
  39666. x: coords.x,
  39667. y: coords.y
  39668. });
  39669. onCheck(true)
  39670. }
  39671. else
  39672. that._callbacks[EVENT_FOCUS_ON]({
  39673. data: data,
  39674. x: coords.x,
  39675. y: coords.y
  39676. }, onCheck)
  39677. };
  39678. function onCheck(result) {
  39679. that.changing = null;
  39680. that.disabled = !result;
  39681. if (result) {
  39682. that._data = data;
  39683. that.active = target;
  39684. clearTimeout(that._offTimer);
  39685. that._offTimer = null
  39686. }
  39687. }
  39688. },
  39689. turnOn: function(target, data, coords, timeout) {
  39690. var that = this;
  39691. that.disabled = false;
  39692. that.x = coords.x;
  39693. that.y = coords.y;
  39694. clearTimeout(that._onTimer);
  39695. that.changing = true;
  39696. that._onTimer = setTimeout(that._createCallback(target, data, coords), timeout)
  39697. },
  39698. move: function(target, data, coords) {
  39699. this.x = coords.x;
  39700. this.y = coords.y;
  39701. this._createCallback(target, data, coords)()
  39702. },
  39703. turnOff: function(timeout) {
  39704. var that = this;
  39705. if (that.active)
  39706. that._offTimer = that._offTimer || setTimeout(function() {
  39707. that._offTimer = null;
  39708. that._callbacks[EVENT_FOCUS_OFF]({data: that._data});
  39709. that._data = that.active = null;
  39710. that.disabled = true
  39711. }, timeout);
  39712. else {
  39713. clearTimeout(that._onTimer);
  39714. that._onTimer = null;
  39715. that.disabled = true
  39716. }
  39717. },
  39718. cancel: function() {
  39719. var that = this;
  39720. if (that.active)
  39721. that._callbacks[EVENT_FOCUS_OFF]({data: that._data});
  39722. clearTimeout(that._onTimer);
  39723. clearTimeout(that._offTimer);
  39724. that._data = that.active = that._onTimer = that._offTimer = null;
  39725. that.disabled = true
  39726. }
  39727. });
  39728. DX.viz.map._tests.Tracker = Tracker;
  39729. DX.viz.map._tests._DEBUG_forceEventMode = function(mode) {
  39730. setupEvents(mode)
  39731. };
  39732. DX.viz.map._tests.Focus = Focus;
  39733. DX.viz.map._tests._DEBUG_stubFocusType = function(focusType) {
  39734. Focus = focusType
  39735. };
  39736. DX.viz.map._tests._DEBUG_restoreFocusType = function() {
  39737. Focus = DX.viz.map._tests.Focus
  39738. };
  39739. DX.viz.map.Map.prototype._factory.createTracker = function(parameters) {
  39740. return new Tracker(parameters)
  39741. };
  39742. function getDistance(x1, y1, x2, y2) {
  39743. return _sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))
  39744. }
  39745. function isTouchEvent(event) {
  39746. var type = event.originalEvent.type,
  39747. pointerType = event.originalEvent.pointerType;
  39748. return /^touch/.test(type) || /^MSPointer/.test(type) && pointerType !== 4 || /^pointer/.test(type) && pointerType !== 'mouse'
  39749. }
  39750. function selectItem(flags, items) {
  39751. var i = 0,
  39752. ii = flags.length,
  39753. item;
  39754. for (; i < ii; ++i)
  39755. if (flags[i]) {
  39756. item = items[i];
  39757. break
  39758. }
  39759. return _addNamespace(item || items[i], _NAME)
  39760. }
  39761. function setupEvents() {
  39762. var flags = [navigator.pointerEnabled, navigator.msPointerEnabled, 'ontouchstart' in window];
  39763. if (arguments.length)
  39764. flags = [arguments[0] === 'pointer', arguments[0] === 'MSPointer', arguments[0] === 'touch'];
  39765. EVENTS = {
  39766. start: selectItem(flags, ['pointerdown', 'MSPointerDown', 'touchstart mousedown', 'mousedown']),
  39767. move: selectItem(flags, ['pointermove', 'MSPointerMove', 'touchmove mousemove', 'mousemove']),
  39768. end: selectItem(flags, ['pointerup', 'MSPointerUp', 'touchend mouseup', 'mouseup']),
  39769. over: selectItem(flags, ['pointerover', 'MSPointerOver', 'mouseover', 'mouseover']),
  39770. out: selectItem(flags, ['pointerout', 'MSPointerOut', 'mouseout', 'mouseout']),
  39771. wheel: selectItem([], ['mousewheel DOMMouseScroll'])
  39772. }
  39773. }
  39774. function getEventCoords(event) {
  39775. var originalEvent = event.originalEvent,
  39776. touch = originalEvent.touches && originalEvent.touches[0] || {};
  39777. return {
  39778. x: touch.pageX || originalEvent.pageX || event.pageX,
  39779. y: touch.pageY || originalEvent.pageY || event.pageY
  39780. }
  39781. }
  39782. function getPointerId(event) {
  39783. return event.originalEvent.pointerId
  39784. }
  39785. function getMultitouchEventCoords(event, pointerId) {
  39786. var originalEvent = event.originalEvent;
  39787. if (originalEvent.pointerId !== undefined)
  39788. originalEvent = originalEvent.pointerId === pointerId ? originalEvent : null;
  39789. else
  39790. originalEvent = originalEvent.touches[pointerId];
  39791. return originalEvent ? {
  39792. x: originalEvent.pageX || event.pageX,
  39793. y: originalEvent.pageY || event.pageY
  39794. } : null
  39795. }
  39796. })(DevExpress, jQuery);
  39797. /*! Module viz-vectormap, file themeManager.js */
  39798. (function(DX, $, undefined) {
  39799. var _Number = Number,
  39800. _extend = $.extend,
  39801. _each = $.each;
  39802. var ThemeManager = DX.viz.core.BaseThemeManager.inherit({
  39803. _themeSection: 'map',
  39804. _initializeTheme: function() {
  39805. var that = this;
  39806. that._initializeFont(that._theme.marker.font);
  39807. that._initializeFont(that._theme.tooltip.font);
  39808. that._initializeFont(that._theme.legend.font);
  39809. that._initializeFont(that._theme.loadingIndicator.font)
  39810. },
  39811. dispose: function() {
  39812. var that = this;
  39813. that.callBase.apply(that, arguments);
  39814. that._areasPalette = that._markersPalette = null;
  39815. return that
  39816. },
  39817. getBackgroundSettings: function(options) {
  39818. var theme = this._theme.background,
  39819. merged = _extend({}, theme, options);
  39820. return {
  39821. strokeWidth: merged.borderWidth,
  39822. stroke: merged.borderColor,
  39823. fill: merged.color
  39824. }
  39825. },
  39826. getCommonAreaSettings: function(options) {
  39827. var settings = _extend({}, this._theme.area, options);
  39828. this._areasPalette = new DX.viz.core.GradientPalette(settings.palette, settings.paletteSize);
  39829. this._DEBUG_areasPalette = this._areasPalette;
  39830. return settings
  39831. },
  39832. getAreaSettings: function(commonSettings, options) {
  39833. options = options || {};
  39834. var settings = _extend({}, commonSettings, options);
  39835. settings.borderWidth = _Number(settings.borderWidth) || 0;
  39836. settings.borderColor = settings.borderColor || null;
  39837. if (options.color === undefined && options.paletteIndex >= 0)
  39838. settings.color = this._areasPalette.getColor(options.paletteIndex);
  39839. settings.color = settings.color || null;
  39840. settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
  39841. settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
  39842. settings.hoveredColor = settings.hoveredColor || settings.color;
  39843. settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
  39844. settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
  39845. settings.selectedColor = settings.selectedColor || settings.color;
  39846. return settings
  39847. },
  39848. getCommonMarkerSettings: function(options) {
  39849. options = options || {};
  39850. var theme = this._theme.marker,
  39851. allSettings = {};
  39852. _each(theme, function(name) {
  39853. if (name[0] === '_') {
  39854. var partialTheme = theme[name] || {},
  39855. partialOptions = options[name] || {},
  39856. settings = _extend({}, theme, partialTheme, options, partialOptions);
  39857. settings.font = _extend({}, theme.font, partialTheme.font, options.font, partialOptions.font);
  39858. allSettings[name.substr(1)] = settings
  39859. }
  39860. });
  39861. this._markersPalette = new DX.viz.core.Palette(options.palette || theme.palette, {
  39862. stepHighlight: 50,
  39863. theme: this.themeName()
  39864. });
  39865. this._DEBUG_markersPalette = this._markersPalette;
  39866. return allSettings
  39867. },
  39868. getMarkerSettings: function(commonSettings, options, type) {
  39869. options = options || {};
  39870. var common = commonSettings[type],
  39871. settings = _extend({}, common, options);
  39872. settings.font = _extend({}, common.font, options.font);
  39873. settings.borderWidth = _Number(settings.borderWidth) || 0;
  39874. settings.borderColor = settings.borderColor || null;
  39875. settings.color = settings.color || null;
  39876. settings.opacity = settings.opacity || null;
  39877. settings.hoveredBorderWidth = _Number(settings.hoveredBorderWidth) || settings.borderWidth;
  39878. settings.hoveredBorderColor = settings.hoveredBorderColor || settings.borderColor;
  39879. settings.hoveredColor = settings.hoveredColor || settings.color;
  39880. settings.hoveredOpacity = settings.hoveredOpacity || settings.opacity;
  39881. settings.selectedBorderWidth = _Number(settings.selectedBorderWidth) || settings.borderWidth;
  39882. settings.selectedBorderColor = settings.selectedBorderColor || settings.borderColor;
  39883. settings.selectedColor = settings.selectedColor || settings.color;
  39884. settings.selectedOpacity = settings.selectedOpacity || settings.opacity;
  39885. return settings
  39886. },
  39887. getMarkerColors: function(count) {
  39888. var i = 0,
  39889. colors = [];
  39890. for (; i < count; ++i)
  39891. colors.push(this._markersPalette.getNextColor());
  39892. this._markersPalette.reset();
  39893. return colors
  39894. },
  39895. getControlBarSettings: function(options) {
  39896. var theme = this._theme.controlBar,
  39897. merged = _extend({}, theme, options);
  39898. return _extend({}, options, {shape: {
  39899. strokeWidth: merged.borderWidth,
  39900. stroke: merged.borderColor,
  39901. fill: merged.color
  39902. }})
  39903. },
  39904. getLoadIndicatorSettings: function(options) {
  39905. var theme = this._theme.loadingIndicator;
  39906. return _extend(true, {}, theme, options)
  39907. },
  39908. getTooltipSettings: function(options) {
  39909. var theme = this._theme.tooltip,
  39910. merged = _extend({}, theme, options),
  39911. borderOptions = _extend({}, theme.border, options && options.border, options && !options.border && {color: options.borderColor});
  39912. return _extend({}, options, {
  39913. color: merged.color,
  39914. border: borderOptions,
  39915. text: {
  39916. strokeWidth: 0,
  39917. stroke: 'none',
  39918. fill: 'none',
  39919. font: _extend({}, theme.font, merged.font),
  39920. 'class': 'dxm-tooltip-text'
  39921. },
  39922. arrowLength: merged.arrowLength,
  39923. paddingLeftRight: merged.paddingLeftRight,
  39924. paddingTopBottom: merged.paddingTopBottom,
  39925. opacity: merged.opacity,
  39926. shadow: _extend({}, theme.shadow, merged.shadow)
  39927. })
  39928. },
  39929. getLegendSettings: function(options) {
  39930. return _extend(true, {}, this._theme.legend, options)
  39931. },
  39932. getLegendItemSettings: function(item) {
  39933. var color = item.color;
  39934. if (color === undefined && item.paletteIndex >= 0)
  39935. color = this._areasPalette.getColor(item.paletteIndex);
  39936. return {
  39937. text: item.text,
  39938. color: color
  39939. }
  39940. },
  39941. patchRtlSettings: function(rtlEnabledOption) {
  39942. var theme = this._theme;
  39943. if (rtlEnabledOption || theme.rtlEnabled && rtlEnabledOption !== false)
  39944. $.extend(true, theme, theme._rtl)
  39945. }
  39946. });
  39947. DX.viz.map._tests.ThemeManager = ThemeManager;
  39948. DX.viz.map.Map.prototype._factory.createThemeManager = function() {
  39949. return new ThemeManager
  39950. }
  39951. })(DevExpress, jQuery);
  39952. /*! Module viz-vectormap, file mapItemsManager.js */
  39953. (function(DX, $, undefined) {
  39954. var _String = String,
  39955. _isString = DX.utils.isString,
  39956. _isArray = DX.utils.isArray,
  39957. _isFunction = DX.utils.isFunction,
  39958. _extend = $.extend,
  39959. _each = $.each,
  39960. _map = $.map;
  39961. var SELECTION_MODE_NONE = 'none',
  39962. SELECTION_MODE_SINGLE = 'single',
  39963. SELECTION_MODE_MULTIPLE = 'multiple';
  39964. var MapItemsManager = DX.Class.inherit({
  39965. _rootClass: null,
  39966. ctor: function(parameters) {
  39967. var that = this;
  39968. that._container = parameters.container;
  39969. that._renderer = parameters.renderer;
  39970. that._projection = parameters.projection;
  39971. that._themeManager = parameters.themeManager;
  39972. that._tracker = parameters.tracker;
  39973. that._ready = parameters.ready;
  39974. that._root = that._renderer.createGroup({'class': that._rootClass});
  39975. that._items = [];
  39976. that._context = {
  39977. renderer: that._renderer,
  39978. root: that._root,
  39979. projection: that._projection,
  39980. selectItem: function(index, state, noCallback) {
  39981. that.selectItem(index, state, noCallback)
  39982. }
  39983. }
  39984. },
  39985. dispose: function() {
  39986. var that = this;
  39987. that._container = that._renderer = that._projection = that._themeManager = that._tracker = that._ready = that._root = that._source = that._context = null;
  39988. return that
  39989. },
  39990. clean: function() {
  39991. var that = this;
  39992. that._rendered = false;
  39993. that._root.detach();
  39994. that._customizeCallback = that._clickCallback = that._selectionChangedCallback = null;
  39995. that._destroyItems();
  39996. return that
  39997. },
  39998. render: function(options) {
  39999. options = options || {};
  40000. var that = this;
  40001. that._rendered = true;
  40002. that._customizeCallback = _isFunction(options.customize) ? options.customize : null;
  40003. that._clickCallback = _isFunction(options.click) ? options.click : null;
  40004. that._selectionChangedCallback = _isFunction(options.selectionChanged) ? options.selectionChanged : null;
  40005. that._hoverEnabled = 'hoverEnabled' in options ? !!options.hoverEnabled : true;
  40006. var selectionMode = _String(options.selectionMode).toLowerCase();
  40007. that._selectionMode = selectionMode === SELECTION_MODE_NONE || selectionMode === SELECTION_MODE_SINGLE || selectionMode === SELECTION_MODE_MULTIPLE ? selectionMode : SELECTION_MODE_SINGLE;
  40008. that._root.append(that._container);
  40009. if (that._source !== null)
  40010. that._createItems();
  40011. return that
  40012. },
  40013. _destroyItems: function() {
  40014. var that = this;
  40015. that._root.clear();
  40016. _each(that._items, function(_, item) {
  40017. item.clean().dispose()
  40018. });
  40019. that._items = [];
  40020. that._selectedItems = null
  40021. },
  40022. _getItemSettings: null,
  40023. _createItem: null,
  40024. _isItemSelected: null,
  40025. _arrangeItems: null,
  40026. _createItems: function() {
  40027. var that = this;
  40028. that._selectedItems = that._selectionMode === SELECTION_MODE_MULTIPLE ? {} : null;
  40029. var selectedList = [];
  40030. _each(_isArray(that._source) ? that._source : [], function(i, dataItem) {
  40031. dataItem = dataItem || {};
  40032. var settings = that._customizeCallback && that._customizeCallback.call(dataItem, dataItem) || {};
  40033. var source = {
  40034. item: dataItem,
  40035. coords: that._getItemCoordinates(dataItem),
  40036. attrs: that._getItemAttributes(dataItem)
  40037. };
  40038. settings = that._getItemSettings(source, settings);
  40039. var item = that._createItem(settings);
  40040. item.init(that._context, source, i).render(settings).locate();
  40041. that._items.push(item);
  40042. if (that._isItemSelected(source, settings))
  40043. selectedList.push(i)
  40044. });
  40045. if (that._selectionMode !== SELECTION_MODE_NONE && selectedList.length > 0) {
  40046. if (that._selectionMode === SELECTION_MODE_SINGLE)
  40047. selectedList = [selectedList[selectedList.length - 1]];
  40048. _each(selectedList, function(_, index) {
  40049. that.selectItem(index, true, true)
  40050. })
  40051. }
  40052. that._arrangeItems();
  40053. that._ready && that._ready()
  40054. },
  40055. _processSource: null,
  40056. setData: function(data) {
  40057. var that = this;
  40058. that._source = null;
  40059. if (_isString(data))
  40060. $.getJSON(data).done(updateSource).fail(function(_0, _1, error) {
  40061. updateSource(null)
  40062. });
  40063. else
  40064. updateSource(data);
  40065. return that;
  40066. function updateSource(source) {
  40067. that._source = that._processSource(source) || 0;
  40068. if (that._rendered) {
  40069. that._tracker.reset();
  40070. that._destroyItems();
  40071. that._createItems()
  40072. }
  40073. }
  40074. },
  40075. transform: function(transform) {
  40076. this._root.applySettings(transform);
  40077. return this
  40078. },
  40079. redraw: function() {
  40080. _each(this._items, function(_, item) {
  40081. item.locate()
  40082. });
  40083. return this
  40084. },
  40085. hoverItem: function(index, state) {
  40086. if (this._hoverEnabled)
  40087. this._items[index].setHovered(!!state);
  40088. return this
  40089. },
  40090. _raiseSelectionChanged: function(item) {
  40091. var that = this;
  40092. if (that._selectionChangedCallback)
  40093. setTimeout(function() {
  40094. that._selectionChangedCallback && that._selectionChangedCallback.call(item.proxy, item.proxy)
  40095. }, 0)
  40096. },
  40097. selectItem: function(index, state, noCallback) {
  40098. var that = this;
  40099. if (that._selectionMode === SELECTION_MODE_NONE)
  40100. return that;
  40101. var item = that._items[index],
  40102. previous = item.selected;
  40103. item.setSelected(!!state);
  40104. if (item.selected === previous)
  40105. return that;
  40106. if (!noCallback)
  40107. that._raiseSelectionChanged(item);
  40108. if (item.selected && that._selectionMode === SELECTION_MODE_SINGLE && that._selectedItems) {
  40109. that._selectedItems.setSelected(false);
  40110. if (!noCallback)
  40111. that._raiseSelectionChanged(that._selectedItems);
  40112. that._selectedItems = null
  40113. }
  40114. if (that._selectionMode === SELECTION_MODE_SINGLE)
  40115. that._selectedItems = item.selected ? item : null;
  40116. else if (item.selected)
  40117. that._selectedItems[index] = item;
  40118. else
  40119. delete that._selectedItems[index];
  40120. return that
  40121. },
  40122. clearSelection: function() {
  40123. var that = this;
  40124. if (that._selectionMode === SELECTION_MODE_NONE)
  40125. return that;
  40126. if (that._selectionMode === SELECTION_MODE_SINGLE) {
  40127. if (that._selectedItems) {
  40128. that._selectedItems.setSelected(false);
  40129. that._raiseSelectionChanged(that._selectedItems);
  40130. that._selectedItems = null
  40131. }
  40132. }
  40133. else
  40134. _each(that._selectedItems, function(i, item) {
  40135. item.setSelected(false);
  40136. that._raiseSelectionChanged(item);
  40137. delete that._selectedItems[i]
  40138. });
  40139. return that
  40140. },
  40141. raiseClick: function(index, $event) {
  40142. var that = this,
  40143. item = that._items[index];
  40144. if (that._clickCallback)
  40145. setTimeout(function() {
  40146. that._clickCallback && that._clickCallback.call(item.proxy, item.proxy, $event)
  40147. }, 0);
  40148. return that
  40149. },
  40150. getProxyItems: function() {
  40151. return _map(this._items, function(item) {
  40152. return item.proxy
  40153. })
  40154. },
  40155. getProxyItem: function(index) {
  40156. return this._items[index].proxy
  40157. }
  40158. });
  40159. DX.viz.map._internal.mapItemBehavior = {
  40160. init: function(ctx, src, index) {
  40161. var that = this;
  40162. that._ctx = ctx;
  40163. that._src = src;
  40164. that._coords = that._project(ctx.projection, src.coords);
  40165. that._data = {
  40166. index: index,
  40167. type: that._type
  40168. };
  40169. that.hovered = that.selected = false;
  40170. that.proxy = createProxy(that, src.attrs, ctx.selectItem);
  40171. that.proxy.type = that._type;
  40172. that._init();
  40173. return that
  40174. },
  40175. dispose: function() {
  40176. disposeItem(this.proxy);
  40177. disposeItem(this);
  40178. return this
  40179. },
  40180. locate: function() {
  40181. var that = this;
  40182. that._locate(that._transform(that._ctx.projection, that._coords));
  40183. return that
  40184. },
  40185. clean: function() {
  40186. this._root.detach();
  40187. return this
  40188. },
  40189. render: function(settings) {
  40190. var that = this;
  40191. that._root = that._createRoot().append(that._ctx.root);
  40192. that._render(settings);
  40193. return that
  40194. },
  40195. setHovered: function(state) {
  40196. var that = this;
  40197. that.hovered = !!state;
  40198. that._onHover();
  40199. if (!that.selected)
  40200. if (that.hovered)
  40201. that._setHoveredState();
  40202. else
  40203. that._setDefaultState();
  40204. return that
  40205. },
  40206. setSelected: function(state) {
  40207. var that = this;
  40208. that.selected = !!state;
  40209. if (that.selected)
  40210. that._setSelectedState();
  40211. else
  40212. that.setHovered(that.hovered);
  40213. return that
  40214. }
  40215. };
  40216. function createProxy(item, attributes, selectItem) {
  40217. attributes = attributes || {};
  40218. return {
  40219. attribute: function(name) {
  40220. return name !== undefined ? attributes[name] : _extend({}, attributes)
  40221. },
  40222. selected: function(state, _noEvent) {
  40223. if (state !== undefined) {
  40224. if (item.selected !== !!state)
  40225. selectItem(item._data.index, !!state, _noEvent);
  40226. return this
  40227. }
  40228. else
  40229. return item.selected
  40230. }
  40231. }
  40232. }
  40233. function disposeItem(item) {
  40234. _each(item, function(name) {
  40235. item[name] = null
  40236. })
  40237. }
  40238. DX.viz.map._tests.MapItemsManager = MapItemsManager;
  40239. DX.viz.map.Map.prototype._factory.MapItemsManager = MapItemsManager
  40240. })(DevExpress, jQuery);
  40241. /*! Module viz-vectormap, file areasManager.js */
  40242. (function(DX, $, undefined) {
  40243. var _DATA_KEY = DX.viz.map.__DATA_KEY;
  40244. var AreasManager = DX.viz.map.Map.prototype._factory.MapItemsManager.inherit({
  40245. _rootClass: 'dxm-areas',
  40246. _processSource: function(source) {
  40247. var isGeoJson = source && source.type === 'FeatureCollection';
  40248. this._getItemCoordinates = isGeoJson ? getCoordinatesGeoJson : getCoordinatesDefault;
  40249. this._getItemAttributes = isGeoJson ? getAttributesGeoJson : getAttributesDefault;
  40250. return isGeoJson ? source.features : source
  40251. },
  40252. clean: function() {
  40253. this._commonSettings = null;
  40254. return this.callBase.apply(this, arguments)
  40255. },
  40256. render: function(options) {
  40257. this._commonSettings = this._themeManager.getCommonAreaSettings(options || {});
  40258. return this.callBase.apply(this, arguments)
  40259. },
  40260. _getItemSettings: function(_, options) {
  40261. return this._themeManager.getAreaSettings(this._commonSettings, options)
  40262. },
  40263. _createItem: function() {
  40264. return new Area
  40265. },
  40266. _isItemSelected: function(source, settings) {
  40267. return source.attrs.isSelected || settings.isSelected
  40268. },
  40269. _arrangeItems: $.noop
  40270. });
  40271. function getCoordinatesDefault(dataItem) {
  40272. return dataItem.coordinates
  40273. }
  40274. function getCoordinatesGeoJson(dataItem) {
  40275. var coordinates;
  40276. if (dataItem.geometry) {
  40277. var type = dataItem.geometry.type;
  40278. coordinates = dataItem.geometry.coordinates;
  40279. if (coordinates && (type === 'Polygon' || type === 'MultiPolygon'))
  40280. type === 'MultiPolygon' && (coordinates = [].concat.apply([], coordinates));
  40281. else
  40282. coordinates = undefined
  40283. }
  40284. return coordinates
  40285. }
  40286. function getAttributesDefault(dataItem) {
  40287. return dataItem.attributes
  40288. }
  40289. function getAttributesGeoJson(dataItem) {
  40290. return dataItem.properties
  40291. }
  40292. function Area(){}
  40293. $.extend(Area.prototype, DX.viz.map._internal.mapItemBehavior, {
  40294. _type: 'area',
  40295. _project: function(projection, coords) {
  40296. return projection.projectArea(coords)
  40297. },
  40298. _init: $.noop,
  40299. _createRoot: function() {
  40300. return this._ctx.renderer.createSimplePath()
  40301. },
  40302. _render: function(settings) {
  40303. var that = this;
  40304. that._styles = {
  40305. normal: {
  40306. 'class': 'dxm-area',
  40307. stroke: settings.borderColor,
  40308. strokeWidth: settings.borderWidth,
  40309. fill: settings.color
  40310. },
  40311. hovered: {
  40312. 'class': 'dxm-area dxm-area-hovered',
  40313. stroke: settings.hoveredBorderColor,
  40314. strokeWidth: settings.hoveredBorderWidth,
  40315. fill: settings.hoveredColor
  40316. },
  40317. selected: {
  40318. 'class': 'dxm-area dxm-area-selected',
  40319. stroke: settings.selectedBorderColor,
  40320. strokeWidth: settings.selectedBorderWidth,
  40321. fill: settings.selectedColor
  40322. }
  40323. };
  40324. that._root.applySettings(that._styles.normal).data(_DATA_KEY, that._data);
  40325. return that
  40326. },
  40327. _transform: function(projection, coords) {
  40328. return projection.getAreaCoordinates(coords)
  40329. },
  40330. _locate: function(coords) {
  40331. this._root.applySettings({d: coords})
  40332. },
  40333. _onHover: $.noop,
  40334. _setDefaultState: function() {
  40335. this._root.applySettings(this._styles.normal).toBackground()
  40336. },
  40337. _setHoveredState: function() {
  40338. this._root.applySettings(this._styles.hovered).toForeground()
  40339. },
  40340. _setSelectedState: function() {
  40341. this._root.applySettings(this._styles.selected).toForeground()
  40342. }
  40343. });
  40344. DX.viz.map._tests.AreasManager = AreasManager;
  40345. DX.viz.map._tests.Area = Area;
  40346. DX.viz.map.Map.prototype._factory.createAreasManager = function(parameters) {
  40347. return new AreasManager(parameters)
  40348. }
  40349. })(DevExpress, jQuery);
  40350. /*! Module viz-vectormap, file markersManager.js */
  40351. (function(DX, $, undefined) {
  40352. var _Number = Number,
  40353. _String = String,
  40354. _isFinite = isFinite,
  40355. _round = Math.round,
  40356. _max = Math.max,
  40357. _min = Math.min,
  40358. _extend = $.extend,
  40359. _isArray = DX.utils.isArray,
  40360. _processCircleSettings = DX.viz.renderers.processCircleSettings;
  40361. var CLASS_DEFAULT = 'dxm-marker',
  40362. CLASS_HOVERED = 'dxm-marker dxm-marker-hovered',
  40363. CLASS_SELECTED = 'dxm-marker dxm-marker-selected',
  40364. TRACKER_SETTINGS = {
  40365. stroke: 'none',
  40366. strokeWidth: 0,
  40367. fill: '#000000',
  40368. opacity: 0.0001
  40369. };
  40370. var _DATA_KEY = DX.viz.map.__DATA_KEY;
  40371. var DEFAULT_MARKER_TYPE = 'dot',
  40372. MARKER_TYPES = {};
  40373. var MarkersManager = DX.viz.map.Map.prototype._factory.MapItemsManager.inherit({
  40374. _rootClass: 'dxm-markers',
  40375. ctor: function() {
  40376. var that = this;
  40377. that.callBase.apply(that, arguments);
  40378. that._context.getColors = function(count) {
  40379. return that._themeManager.getMarkerColors(count)
  40380. };
  40381. that._filter = that._renderer.createFilter('shadow').applySettings({
  40382. x: '-40%',
  40383. y: '-40%',
  40384. width: '180%',
  40385. height: '200%',
  40386. color: '#000000',
  40387. opacity: 0.2,
  40388. dx: 0,
  40389. dy: 1,
  40390. blur: 1
  40391. }).append()
  40392. },
  40393. dispose: function() {
  40394. this._filter.dispose();
  40395. this._filter = null;
  40396. return this.callBase.apply(this, arguments)
  40397. },
  40398. _getItemCoordinates: function(dataItem) {
  40399. return dataItem.coordinates
  40400. },
  40401. _getItemAttributes: function(dataItem) {
  40402. return dataItem.attributes
  40403. },
  40404. _processSource: function(source) {
  40405. return source
  40406. },
  40407. clean: function() {
  40408. var that = this;
  40409. that._commonSettings = null;
  40410. return that.callBase.apply(that, arguments)
  40411. },
  40412. render: function(options) {
  40413. var that = this;
  40414. that._commonSettings = that._themeManager.getCommonMarkerSettings(options);
  40415. that._commonSettings._filter = that._filter.ref;
  40416. that._commonType = parseMarkerType(options && options.type);
  40417. return that.callBase.apply(that, arguments)
  40418. },
  40419. _arrangeBubbles: function() {
  40420. var markers = this._items,
  40421. bubbles = [],
  40422. i,
  40423. ii = markers.length,
  40424. marker,
  40425. values = [];
  40426. for (i = 0; i < ii; ++i) {
  40427. marker = markers[i];
  40428. if (marker.type === 'bubble') {
  40429. bubbles.push(marker);
  40430. if (marker.value !== null)
  40431. values.push(marker.value)
  40432. }
  40433. }
  40434. var minValue = _min.apply(null, values),
  40435. maxValue = _max.apply(null, values),
  40436. deltaValue = maxValue - minValue || 1;
  40437. for (i = 0, ii = bubbles.length; i < ii; ++i) {
  40438. marker = bubbles[i];
  40439. marker.setSize(marker.value !== null ? (marker.value - minValue) / deltaValue : 0)
  40440. }
  40441. },
  40442. _getItemSettings: function(source, options) {
  40443. var type = parseMarkerType(source.item.type, this._commonType),
  40444. style = _extend(source.item.style, options);
  40445. style = this._themeManager.getMarkerSettings(this._commonSettings, style, type);
  40446. _extend(source.item, {text: source.item.text || style.text});
  40447. style._type = type;
  40448. return style
  40449. },
  40450. _createItem: function(settings) {
  40451. return new MARKER_TYPES[settings._type]
  40452. },
  40453. _isItemSelected: function(source, settings) {
  40454. return source.item.isSelected || settings.isSelected
  40455. },
  40456. _arrangeItems: function() {
  40457. this._arrangeBubbles()
  40458. },
  40459. addMarker: function(dataItem) {
  40460. var that = this,
  40461. index = that._items.length,
  40462. marker = that._createItem(dataItem, index);
  40463. that._items.push(marker);
  40464. if (marker._selected)
  40465. that.selectItem(index, true, true);
  40466. that._arrangeItems();
  40467. return that
  40468. }
  40469. });
  40470. var baseMarkerBehavior = _extend({}, DX.viz.map._internal.mapItemBehavior, {
  40471. _type: 'marker',
  40472. _project: function(projection, coords) {
  40473. return projection.projectPoint(coords)
  40474. },
  40475. _init: function() {
  40476. this.proxy.coordinates = createCoordinatesGetter(this._src.coords);
  40477. this.proxy.text = this._src.item.text
  40478. },
  40479. _createRoot: function() {
  40480. return this._ctx.renderer.createGroup()
  40481. },
  40482. _render: function(settings) {
  40483. var that = this;
  40484. that._root.applySettings({'class': CLASS_DEFAULT});
  40485. that._create(settings, that._ctx.renderer, that._root);
  40486. that._createText(settings, that._ctx.renderer, that._root);
  40487. return that
  40488. },
  40489. _createText: function(settings, renderer, root) {
  40490. var that = this;
  40491. if (!that._src.item.text)
  40492. return;
  40493. var rootbox = that._root.getBBox(),
  40494. text = renderer.createText(that._src.item.text, 0, 0, {
  40495. align: 'center',
  40496. font: settings.font
  40497. }).append(root),
  40498. textBox = text.getBBox(),
  40499. x = _round(-textBox.x + rootbox.width / 2) + 2,
  40500. y = _round(-textBox.y - textBox.height / 2) - 1;
  40501. text.applySettings({
  40502. x: x,
  40503. y: y
  40504. });
  40505. 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)
  40506. },
  40507. _transform: function(projection, coords) {
  40508. return projection.getPointCoordinates(coords)
  40509. },
  40510. _locate: function(coords) {
  40511. this._root.applySettings({
  40512. translateX: coords.x,
  40513. translateY: coords.y
  40514. })
  40515. },
  40516. _onHover: function() {
  40517. this.hovered && this._root.toForeground()
  40518. },
  40519. _setDefaultState: function() {
  40520. this._root.applySettings({'class': CLASS_DEFAULT}).toBackground();
  40521. this._applyDefault()
  40522. },
  40523. _setHoveredState: function() {
  40524. this._root.applySettings({'class': CLASS_HOVERED});
  40525. this._applyHovered()
  40526. },
  40527. _setSelectedState: function() {
  40528. this._root.applySettings({'class': CLASS_SELECTED}).toForeground();
  40529. this._applySelected()
  40530. }
  40531. });
  40532. function createCoordinatesGetter(coordinates) {
  40533. return function() {
  40534. return [_Number(coordinates[0]), _Number(coordinates[1])]
  40535. }
  40536. }
  40537. function DotMarker(){}
  40538. _extend(DotMarker.prototype, baseMarkerBehavior, {
  40539. type: 'dot',
  40540. _create: function(style, renderer, root) {
  40541. var that = this,
  40542. size = style.size > 0 ? _Number(style.size) : 0,
  40543. hoveredSize = size,
  40544. selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0),
  40545. hoveredBackSize = hoveredSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
  40546. selectedBackSize = selectedSize + (style.backStep > 0 ? _Number(style.backStep) : 0),
  40547. settings = _processCircleSettings(0, 0, size, style.borderWidth);
  40548. that._dotDefault = {
  40549. cx: settings.cx,
  40550. cy: settings.cy,
  40551. r: settings.r,
  40552. stroke: style.borderColor,
  40553. strokeWidth: style.borderWidth,
  40554. fill: style.color,
  40555. filter: style.shadow ? style._filter : null
  40556. };
  40557. that._dotHovered = {
  40558. cx: settings.cx,
  40559. cy: settings.cy,
  40560. r: hoveredSize / 2,
  40561. stroke: style.hoveredBorderColor,
  40562. strokeWidth: style.hoveredBorderWidth,
  40563. fill: style.hoveredColor
  40564. };
  40565. that._dotSelected = {
  40566. cx: settings.cx,
  40567. cy: settings.cy,
  40568. r: selectedSize / 2,
  40569. stroke: style.selectedBorderColor,
  40570. strokeWidth: style.selectedBorderWidth,
  40571. fill: style.selectedColor
  40572. };
  40573. that._backDefault = {
  40574. cx: settings.cx,
  40575. cy: settings.cy,
  40576. r: settings.r,
  40577. stroke: 'none',
  40578. strokeWidth: 0,
  40579. fill: style.backColor,
  40580. opacity: style.backOpacity
  40581. };
  40582. that._backHovered = {
  40583. cx: settings.cx,
  40584. cy: settings.cy,
  40585. r: hoveredBackSize / 2,
  40586. stroke: 'none',
  40587. strokeWidth: 0,
  40588. fill: style.backColor,
  40589. opacity: style.backOpacity
  40590. };
  40591. that._backSelected = {
  40592. cx: settings.cx,
  40593. cy: settings.cy,
  40594. r: selectedBackSize / 2,
  40595. stroke: 'none',
  40596. strokeWidth: 0,
  40597. fill: style.backColor,
  40598. opacity: style.backOpacity
  40599. };
  40600. that._back = renderer.createCircle().applySettings(that._backDefault).data(_DATA_KEY, that._data).append(root);
  40601. that._dot = renderer.createCircle().applySettings(that._dotDefault).data(_DATA_KEY, that._data).append(root)
  40602. },
  40603. _destroy: function() {
  40604. this._back = this._dot = null
  40605. },
  40606. _applyDefault: function() {
  40607. this._back.applySettings(this._backDefault);
  40608. this._dot.applySettings(this._dotDefault)
  40609. },
  40610. _applyHovered: function() {
  40611. this._back.applySettings(this._backHovered);
  40612. this._dot.applySettings(this._dotHovered)
  40613. },
  40614. _applySelected: function() {
  40615. this._back.applySettings(this._backSelected);
  40616. this._dot.applySettings(this._dotSelected)
  40617. }
  40618. });
  40619. function BubbleMarker(){}
  40620. _extend(BubbleMarker.prototype, baseMarkerBehavior, {
  40621. type: 'bubble',
  40622. _create: function(style, renderer, root) {
  40623. var that = this;
  40624. that._minSize = style.minSize > 0 ? _Number(style.minSize) : 0;
  40625. that._maxSize = style.maxSize > that._minSize ? _Number(style.maxSize) : that._minSize;
  40626. that.value = _isFinite(that._src.item.value) ? _Number(that._src.item.value) : null;
  40627. that._default = {
  40628. stroke: style.borderColor,
  40629. strokeWidth: style.borderWidth,
  40630. fill: style.color,
  40631. opacity: style.opacity
  40632. };
  40633. that._hovered = {
  40634. stroke: style.hoveredBorderColor,
  40635. strokeWidth: style.hoveredBorderWidth,
  40636. fill: style.hoveredColor,
  40637. opacity: style.hoveredOpacity
  40638. };
  40639. that._selected = {
  40640. stroke: style.selectedBorderColor,
  40641. strokeWidth: style.selectedBorderWidth,
  40642. fill: style.selectedColor,
  40643. opacity: style.selectedOpacity
  40644. };
  40645. that._bubble = renderer.createCircle(0, 0, style.maxSize / 2).applySettings(that._default).data(_DATA_KEY, that._data).append(root)
  40646. },
  40647. _destroy: function() {
  40648. this._bubble = null
  40649. },
  40650. _applyDefault: function() {
  40651. this._bubble.applySettings(this._default)
  40652. },
  40653. _applyHovered: function() {
  40654. this._bubble.applySettings(this._hovered)
  40655. },
  40656. _applySelected: function() {
  40657. this._bubble.applySettings(this._selected)
  40658. },
  40659. setSize: function(ratio) {
  40660. var that = this,
  40661. settings = _processCircleSettings(0, 0, that._minSize + ratio * (that._maxSize - that._minSize), that._default.strokeWidth);
  40662. that._default.cx = that._hovered.cx = that._selected.cx = settings.cx;
  40663. that._default.cy = that._hovered.cy = that._selected.cy = settings.cy;
  40664. that._default.r = that._hovered.r = that._selected.r = settings.r;
  40665. that._bubble.applySettings(settings);
  40666. return that
  40667. }
  40668. });
  40669. function PieMarker(){}
  40670. _extend(PieMarker.prototype, baseMarkerBehavior, {
  40671. type: 'pie',
  40672. _create: function(style, renderer, root) {
  40673. var that = this,
  40674. settings = _processCircleSettings(0, 0, style.size > 0 ? _Number(style.size) : 0, style.borderWidth);
  40675. that._pieDefault = {opacity: style.opacity};
  40676. that._pieHovered = {opacity: style.hoveredOpacity};
  40677. that._pieSelected = {opacity: style.selectedOpacity};
  40678. that._borderDefault = {
  40679. stroke: style.borderColor,
  40680. strokeWidth: style.borderWidth
  40681. };
  40682. that._borderHovered = {
  40683. stroke: style.hoveredBorderColor,
  40684. strokeWidth: style.hoveredBorderWidth
  40685. };
  40686. that._borderSelected = {
  40687. stroke: style.selectedBorderColor,
  40688. strokeWidth: style.selectedBorderWidth
  40689. };
  40690. var srcValues = that._src.item.values,
  40691. i = 0,
  40692. ii = _isArray(srcValues) ? srcValues.length : 0,
  40693. values = [],
  40694. value,
  40695. sum = 0;
  40696. for (; i < ii; ++i) {
  40697. value = _Number(srcValues[i]);
  40698. if (_isFinite(value)) {
  40699. values.push(value);
  40700. sum += value
  40701. }
  40702. }
  40703. that._pie = renderer.createGroup(that._pieDefault);
  40704. var translator = new DX.viz.core.Translator1D(0, sum, 90, 450),
  40705. startAngle = translator.translate(0),
  40706. endAngle,
  40707. colors = that._ctx.getColors(values.length);
  40708. for (value = 0, i = 0, ii = values.length; i < ii; ++i) {
  40709. value += values[i];
  40710. endAngle = translator.translate(value);
  40711. renderer.createArc(settings.cx, settings.cy, settings.r, 0, startAngle, endAngle, {fill: colors[i]}).data(_DATA_KEY, that._data).append(that._pie);
  40712. startAngle = endAngle
  40713. }
  40714. that._pie.append(root);
  40715. that._border = renderer.createCircle(settings.cx, settings.cy, settings.r, that._borderDefault).data(_DATA_KEY, that._data).append(root)
  40716. },
  40717. _destroy: function() {
  40718. this._pie = this._border = null
  40719. },
  40720. _applyDefault: function() {
  40721. this._pie.applySettings(this._pieDefault);
  40722. this._border.applySettings(this._borderDefault)
  40723. },
  40724. _applyHovered: function() {
  40725. this._pie.applySettings(this._pieHovered);
  40726. this._border.applySettings(this._borderHovered)
  40727. },
  40728. _applySelected: function() {
  40729. this._pie.applySettings(this._pieSelected);
  40730. this._border.applySettings(this._borderSelected)
  40731. }
  40732. });
  40733. function ImageMarker(){}
  40734. _extend(ImageMarker.prototype, baseMarkerBehavior, {
  40735. type: 'image',
  40736. _create: function(style, renderer, root) {
  40737. var that = this,
  40738. size = style.size > 0 ? _Number(style.size) : 0,
  40739. hoveredSize = size + (style.hoveredStep > 0 ? _Number(style.hoveredStep) : 0),
  40740. selectedSize = size + (style.selectedStep > 0 ? _Number(style.selectedStep) : 0);
  40741. that._default = {
  40742. x: -size / 2,
  40743. y: -size / 2,
  40744. width: size,
  40745. height: size
  40746. };
  40747. that._hovered = {
  40748. x: -hoveredSize / 2,
  40749. y: -hoveredSize / 2,
  40750. width: hoveredSize,
  40751. height: hoveredSize
  40752. };
  40753. that._selected = {
  40754. x: -selectedSize / 2,
  40755. y: -selectedSize / 2,
  40756. width: selectedSize,
  40757. height: selectedSize
  40758. };
  40759. that._image = renderer.createImage().applySettings(that._default).applySettings({
  40760. href: that._src.item.url,
  40761. location: 'center'
  40762. }).append(root);
  40763. that._tracker = renderer.createRect().applySettings(that._default).applySettings(TRACKER_SETTINGS).data(_DATA_KEY, that._data).append(root)
  40764. },
  40765. _destroy: function() {
  40766. this._image = this._tracker = null
  40767. },
  40768. _applyDefault: function() {
  40769. this._image.applySettings(this._default);
  40770. this._tracker.applySettings(this._default)
  40771. },
  40772. _applyHovered: function() {
  40773. this._image.applySettings(this._hovered);
  40774. this._tracker.applySettings(this._hovered)
  40775. },
  40776. _applySelected: function() {
  40777. this._image.applySettings(this._selected);
  40778. this._tracker.applySettings(this._selected)
  40779. }
  40780. });
  40781. MARKER_TYPES['dot'] = DotMarker;
  40782. MARKER_TYPES['bubble'] = BubbleMarker;
  40783. MARKER_TYPES['pie'] = PieMarker;
  40784. MARKER_TYPES['image'] = ImageMarker;
  40785. function parseMarkerType(type, defaultType) {
  40786. return MARKER_TYPES[type] && type || defaultType || DEFAULT_MARKER_TYPE
  40787. }
  40788. var __originalDefaultMarkerType = DEFAULT_MARKER_TYPE,
  40789. __originalMarkerTypes = $.extend({}, MARKER_TYPES);
  40790. DX.viz.map._tests.stubMarkerTypes = function(markerTypes, defaultMarkerType) {
  40791. DEFAULT_MARKER_TYPE = defaultMarkerType;
  40792. MARKER_TYPES = markerTypes
  40793. };
  40794. DX.viz.map._tests.restoreMarkerTypes = function() {
  40795. DEFAULT_MARKER_TYPE = __originalDefaultMarkerType;
  40796. MARKER_TYPES = __originalMarkerTypes
  40797. };
  40798. DX.viz.map._tests.baseMarkerBehavior = baseMarkerBehavior;
  40799. DX.viz.map._tests.MarkersManager = MarkersManager;
  40800. DX.viz.map._tests.DotMarker = DotMarker;
  40801. DX.viz.map._tests.BubbleMarker = BubbleMarker;
  40802. DX.viz.map._tests.PieMarker = PieMarker;
  40803. DX.viz.map._tests.ImageMarker = ImageMarker;
  40804. DX.viz.map.Map.prototype._factory.createMarkersManager = function(parameters) {
  40805. return new MarkersManager(parameters)
  40806. }
  40807. })(DevExpress, jQuery);
  40808. DevExpress.MOD_VIZ_VECTORMAP = true
  40809. }
  40810. if (!DevExpress.MOD_VIZ_SPARKLINES) {
  40811. if (!DevExpress.MOD_VIZ_CORE)
  40812. throw Error('Required module is not referenced: viz-core');
  40813. /*! Module viz-sparklines, file baseSparkline.js */
  40814. (function($, DX) {
  40815. var TOOLTIP_MARGIN = 100,
  40816. TOOLTIP_ARROW_MARGIN = 10,
  40817. DEFAULT_LINE_SPACING = 6,
  40818. DEFAULT_EVENTS_DELAY = 200,
  40819. TOUCH_EVENTS_DELAY = 1000,
  40820. _extend = $.extend,
  40821. _abs = Math.abs,
  40822. _Number = Number,
  40823. _round = Math.round,
  40824. core = DX.viz.core,
  40825. CoreFactory = core.CoreFactory;
  40826. function DEFAULT_CUSTOMIZE_TOOLTIP(customizeObject) {
  40827. return {text: customizeObject.valueText.join('<br/>')}
  40828. }
  40829. DX.viz.sparklines = {};
  40830. DX.viz.sparklines.DEFAULT_CUSTOMIZE_TOOLTIP = DEFAULT_CUSTOMIZE_TOOLTIP;
  40831. DX.viz.sparklines.BaseSparkline = core.BaseWidget.inherit({
  40832. render: function() {
  40833. this._refresh();
  40834. return this
  40835. },
  40836. _rendererType: DX.viz.renderers.Renderer,
  40837. _clean: function() {
  40838. if (this._tooltipShown) {
  40839. this._tooltip.dispose();
  40840. this._tooltip = null;
  40841. this._tooltipShown = null;
  40842. this._tooltipGroup.clear()
  40843. }
  40844. this._tooltipContainer.detach();
  40845. this._cleanWidgetElements()
  40846. },
  40847. _optionChanged: function(optionName, value) {
  40848. if (optionName === 'size' && this._allOptions) {
  40849. this._clean();
  40850. this._canvas = this._calculateCanvas();
  40851. this._renderer.resize(this._canvas.width, this._canvas.height);
  40852. if (!this._isContainerVisible())
  40853. return;
  40854. this._allOptions.size = value;
  40855. this._redrawWidgetElements();
  40856. this._prepareTooltipContainer()
  40857. }
  40858. else if (optionName === 'dataSource' && this._allOptions)
  40859. this._refreshDataSource();
  40860. else
  40861. this.callBase.apply(this, arguments)
  40862. },
  40863. _init: function() {
  40864. this.callBase();
  40865. this._canvas = this._calculateCanvas();
  40866. this._renderer = new this._rendererType({
  40867. cssClass: this._widgetClass + ' ' + this._widgetClass + '-' + this._widgetType,
  40868. pathModified: this.option('pathModified'),
  40869. rtl: this.option('rtlEnabled')
  40870. });
  40871. this._renderer.recreateCanvas(this._canvas.width, this._canvas.height);
  40872. this._createHtmlElements();
  40873. this._createTooltipGroups();
  40874. this._initTooltipEvents();
  40875. this._drawContainer()
  40876. },
  40877. _dispose: function() {
  40878. var that = this;
  40879. that.callBase();
  40880. that._disposeWidgetElements();
  40881. that._disposeTooltipEvents();
  40882. that._renderer.dispose();
  40883. that._tooltipRenderer.dispose();
  40884. that._translatorX = null;
  40885. that._translatorY = null;
  40886. delete that._renderer;
  40887. delete that._tooltipRenderer;
  40888. delete that._tooltipTrackerGroup;
  40889. delete that._tooltipGroup;
  40890. delete that._tooltipContainer
  40891. },
  40892. _render: function() {
  40893. var that = this;
  40894. that._canvas = that._calculateCanvas();
  40895. that._renderer.resize(that._canvas.width, that._canvas.height);
  40896. if (!that._isContainerVisible()) {
  40897. that._incidentOccured('W2001', [that.NAME]);
  40898. return
  40899. }
  40900. that._prepareOptions();
  40901. that._createWidgetElements();
  40902. that._drawWidgetElements();
  40903. that._drawn()
  40904. },
  40905. _isContainerVisible: function() {
  40906. var that = this,
  40907. canvas = that._canvas,
  40908. enoughWidth = canvas.width - canvas.left - canvas.right > 0,
  40909. enoughHeight = canvas.height - canvas.top - canvas.bottom > 0;
  40910. return canvas.height && canvas.width && enoughHeight && enoughWidth
  40911. },
  40912. _createWidgetElements: function() {
  40913. this._createRange();
  40914. this._createTranslator()
  40915. },
  40916. _prepareOptions: function(defaultOptions) {
  40917. var that = this,
  40918. userOptions = that.option() || {},
  40919. options,
  40920. defaultTheme,
  40921. theme;
  40922. defaultTheme = core.findTheme('default');
  40923. defaultTheme = defaultTheme[this._widgetType];
  40924. options = _extend(true, {}, defaultOptions, userOptions);
  40925. if (typeof options.theme === 'string') {
  40926. theme = core.findTheme(options.theme);
  40927. theme = theme[this._widgetType]
  40928. }
  40929. else
  40930. theme = options.theme;
  40931. return _extend(true, {}, defaultTheme, theme, options)
  40932. },
  40933. _calculateCanvas: function() {
  40934. var that = this,
  40935. canvas = {},
  40936. sizeOptions = that.option('size') || {},
  40937. marginOptions = that.option('margin') || {},
  40938. defaultSize = that._defaultSize,
  40939. container = that._element(),
  40940. width = sizeOptions.width >= 0 ? _Number(sizeOptions.width) : container.width(),
  40941. height = sizeOptions.height >= 0 ? _Number(sizeOptions.height) : container.height();
  40942. if (!width && _Number(sizeOptions.width) !== 0)
  40943. width = defaultSize.width;
  40944. if (!height && _Number(sizeOptions.height) !== 0)
  40945. height = defaultSize.height;
  40946. return {
  40947. width: width,
  40948. height: height,
  40949. top: _Number(marginOptions.top) || defaultSize.top,
  40950. bottom: _Number(marginOptions.bottom) || defaultSize.bottom,
  40951. left: _Number(marginOptions.left) || defaultSize.left,
  40952. right: _Number(marginOptions.right) || defaultSize.right
  40953. }
  40954. },
  40955. _createTooltipGroups: function() {
  40956. var that = this,
  40957. renderer,
  40958. root,
  40959. widgetClass = that._widgetClass;
  40960. that._tooltipRenderer = renderer = new that._rendererType({
  40961. cssClass: widgetClass + ' ' + widgetClass + '-tooltip',
  40962. pathModified: this.option('pathModified'),
  40963. rtl: this.option('rtlEnabled')
  40964. });
  40965. renderer.recreateCanvas(1, 1);
  40966. that._tooltipContainer = $('<div style="position: relative">');
  40967. renderer.draw(that._tooltipContainer[0]);
  40968. root = renderer.getRoot();
  40969. that._tooltipGroup = renderer.createGroup({
  40970. 'class': widgetClass + '-tooltip-group',
  40971. style: {'z-index': '1'}
  40972. }).append(root);
  40973. that._tooltipTrackerGroup = renderer.createGroup({'class': widgetClass + '-tooltip-tracker-group'}).append(root);
  40974. that._tooltipTracker = that._createTooltipTracker().append(that._tooltipTrackerGroup)
  40975. },
  40976. _createTooltipTracker: function() {
  40977. return this._tooltipRenderer.createRect(0, 0, 0, 0, 0, {
  40978. fill: 'grey',
  40979. opacity: 0
  40980. })
  40981. },
  40982. _initTooltipEvents: function() {
  40983. var that = this,
  40984. data = {
  40985. widget: that,
  40986. container: that._tooltipTracker
  40987. };
  40988. that._showTooltipCallback = function() {
  40989. that._showTooltipTimeout = null;
  40990. if (!that._tooltipShown) {
  40991. that._tooltipShown = true;
  40992. that._showTooltip()
  40993. }
  40994. that._DEBUG_showCallback && that._DEBUG_showCallback()
  40995. };
  40996. that._hideTooltipCallback = function() {
  40997. that._hideTooltipTimeout = null;
  40998. if (that._tooltipShown) {
  40999. that._tooltipShown = false;
  41000. that._hideTooltip()
  41001. }
  41002. that._DEBUG_hideCallback && that._DEBUG_hideCallback()
  41003. };
  41004. that._disposeCallbacks = function() {
  41005. that = that._showTooltipCallback = that._hideTooltipCallback = that._disposeCallbacks = null
  41006. };
  41007. that._tooltipTracker.on(mouseEvents, data).on(touchEvents, data);
  41008. that._tooltipTracker.on(menuEvents)
  41009. },
  41010. _disposeTooltipEvents: function() {
  41011. clearTimeout(this._showTooltipTimeout);
  41012. clearTimeout(this._hideTooltipTimeout);
  41013. this._showTooltipTimeout = this._showTooltipTimeout = null;
  41014. this._tooltipTracker.off();
  41015. this._disposeCallbacks()
  41016. },
  41017. _drawContainer: function() {
  41018. this._renderer.draw(this._element()[0])
  41019. },
  41020. _createTranslator: function() {
  41021. this._translatorX = CoreFactory.createTranslator2D(this._ranges.arg, this._canvas, {direction: "horizontal"});
  41022. this._translatorY = CoreFactory.createTranslator2D(this._ranges.val, this._canvas)
  41023. },
  41024. _prepareTooltipOptions: function() {
  41025. var that = this,
  41026. canvas = that._canvas,
  41027. tooltipOpt = that._allOptions.tooltip,
  41028. size = that._getTooltipSize(true),
  41029. defaultOptions = {
  41030. canvasWidth: size.width,
  41031. canvasHeight: size.height,
  41032. paddingLeftRight: tooltipOpt.paddingLeftRight,
  41033. paddingTopBottom: tooltipOpt.paddingTopBottom,
  41034. arrowLength: tooltipOpt.arrowLength,
  41035. cloudHorizontalPosition: tooltipOpt.horizontalAlignment,
  41036. cloudVerticalPosition: tooltipOpt.verticalAlignment,
  41037. lineSpacing: tooltipOpt.font.lineSpacing !== undefined && tooltipOpt.font.lineSpacing !== null ? tooltipOpt.font.lineSpacing : DEFAULT_LINE_SPACING
  41038. },
  41039. autoJustify = !$.isFunction(that._allOptions.tooltip.customizeText) && !$.isFunction(that._allOptions.tooltip.customizeTooltip),
  41040. options = $.extend(defaultOptions, that._allOptions.tooltip, {
  41041. customizeTooltip: autoJustify ? DEFAULT_CUSTOMIZE_TOOLTIP : that._allOptions.tooltip.customizeTooltip,
  41042. _justify: that._allOptions.tooltip._justify || autoJustify,
  41043. _rtl: that.option('rtlEnabled')
  41044. });
  41045. that._tooltipOptions = {
  41046. size: size,
  41047. options: options
  41048. };
  41049. return options
  41050. },
  41051. _prepareTooltipContainer: function() {
  41052. var that = this,
  41053. canvas = that._canvas,
  41054. width = canvas.width,
  41055. height = canvas.height,
  41056. renderer = that._tooltipRenderer;
  41057. that._updateTooltipSizeToNormal();
  41058. that._tooltipTracker.applySettings({
  41059. width: width,
  41060. height: height
  41061. });
  41062. that._tooltipContainer.appendTo(that._element());
  41063. that._tooltipInitializated = false;
  41064. that._canShowTooltip = that._allOptions.tooltip.enabled
  41065. },
  41066. _isTooltipVisible: function() {
  41067. return this._tooltip.enabled() && this._tooltip.prepare(this._getTooltipData(), {offset: 0})
  41068. },
  41069. _createTooltip: function() {
  41070. var that = this;
  41071. that._tooltip = CoreFactory.createTooltip(that._prepareTooltipOptions(), that._tooltipGroup, that._tooltipRenderer);
  41072. if (that._isTooltipVisible()) {
  41073. that._tooltip.show();
  41074. that._updateTooltipSizeToWide();
  41075. that._checkTooltipSize();
  41076. that._updateTooltipSizeToNormal()
  41077. }
  41078. else
  41079. that._canShowTooltip = false
  41080. },
  41081. _doShowTooltip: function(delay) {
  41082. var that = this;
  41083. if (!that._canShowTooltip)
  41084. return;
  41085. ++that._DEBUG_clearHideTooltipTimeout;
  41086. clearTimeout(that._hideTooltipTimeout);
  41087. that._hideTooltipTimeout = null;
  41088. clearTimeout(that._showTooltipTimeout);
  41089. ++that._DEBUG_showTooltipTimeoutSet;
  41090. that._showTooltipTimeout = setTimeout(that._showTooltipCallback, delay)
  41091. },
  41092. _doHideTooltip: function(delay) {
  41093. var that = this;
  41094. if (!that._canShowTooltip)
  41095. return;
  41096. ++that._DEBUG_clearShowTooltipTimeout;
  41097. clearTimeout(that._showTooltipTimeout);
  41098. that._showTooltipTimeout = null;
  41099. clearTimeout(that._hideTooltipTimeout);
  41100. ++that._DEBUG_hideTooltipTimeoutSet;
  41101. that._hideTooltipTimeout = setTimeout(that._hideTooltipCallback, delay)
  41102. },
  41103. _getNormalTooltipSize: function() {
  41104. var size = {};
  41105. size.width = this._canvas.width;
  41106. size.left = 0;
  41107. size.tooltipLeft = _round(size.width / 2);
  41108. return size
  41109. },
  41110. _getWideTooltipSize: function(leftWidthDelta, rightWidthDelta) {
  41111. var that = this,
  41112. canvas = that._canvas,
  41113. horizontalPos = that._allOptions.tooltip.horizontalAlignment,
  41114. widthDelta = leftWidthDelta + rightWidthDelta,
  41115. size = {};
  41116. size.width = canvas.width + widthDelta;
  41117. size.left = -leftWidthDelta;
  41118. if (horizontalPos === 'right')
  41119. size.tooltipLeft = _round(canvas.width / 2);
  41120. else if (horizontalPos === 'left')
  41121. size.tooltipLeft = _round(canvas.width / 2) + widthDelta;
  41122. else
  41123. size.tooltipLeft = _round(size.width / 2);
  41124. return size
  41125. },
  41126. _getTooltipSize: function(isNormal, leftWidthDelta, rightWidthDelta, heightDelta) {
  41127. var that = this,
  41128. canvas = that._canvas,
  41129. isVerticalPosTop = !(that._allOptions.tooltip.verticalAlignment === 'bottom'),
  41130. size = !isNormal && (leftWidthDelta || rightWidthDelta) ? that._getWideTooltipSize(leftWidthDelta, rightWidthDelta) : that._getNormalTooltipSize(),
  41131. yDelta = heightDelta > 0 ? heightDelta + TOOLTIP_MARGIN : TOOLTIP_MARGIN;
  41132. size.height = canvas.height + yDelta;
  41133. size.top = isVerticalPosTop ? -size.height : -canvas.height;
  41134. size.trackerY = isVerticalPosTop ? yDelta : 0;
  41135. size.tooltipY = isVerticalPosTop ? _round(canvas.height / 2) + yDelta - TOOLTIP_ARROW_MARGIN : _round(canvas.height / 2);
  41136. return size
  41137. },
  41138. _checkTooltipSize: function() {
  41139. var that = this,
  41140. tooltip = that._tooltip,
  41141. options = that._tooltipOptions.options,
  41142. tooltipBBox = tooltip.getBBox(),
  41143. getWide = that._allOptions.tooltip.allowContainerResizing,
  41144. leftDelta = -tooltipBBox.x,
  41145. rightDelta = tooltipBBox.x + tooltipBBox.width - that._canvas.width,
  41146. topDelta = tooltipBBox.height - TOOLTIP_MARGIN,
  41147. size;
  41148. if (leftDelta > 0 || rightDelta > 0 || topDelta > 0)
  41149. if (getWide) {
  41150. that._tooltipOptions.size = size = that._getTooltipSize(false, leftDelta > 0 ? leftDelta : 0, rightDelta > 0 ? rightDelta : 0, topDelta > 0 ? topDelta : 0);
  41151. tooltip.setSize(size.width, size.height);
  41152. that._updateTooltipSizeToWide()
  41153. }
  41154. else {
  41155. that._canShowTooltip = false;
  41156. tooltip.hide()
  41157. }
  41158. },
  41159. _updateTooltipSizeToWide: function() {
  41160. var that = this,
  41161. size = that._tooltipOptions.size,
  41162. renderer = that._tooltipRenderer;
  41163. renderer.resize(size.width, size.height);
  41164. renderer.getRoot().applySettings({style: {
  41165. left: size.left,
  41166. top: size.top,
  41167. position: 'absolute',
  41168. overflow: 'hidden'
  41169. }});
  41170. that._tooltipTracker.applySettings({
  41171. y: size.trackerY,
  41172. x: -size.left
  41173. });
  41174. that._tooltip.move(size.tooltipLeft, size.tooltipY)
  41175. },
  41176. _updateTooltipSizeToNormal: function() {
  41177. var that = this,
  41178. renderer = that._tooltipRenderer,
  41179. canvas = that._canvas;
  41180. renderer.resize(canvas.width, canvas.height);
  41181. renderer.getRoot().applySettings({style: {
  41182. left: 0,
  41183. top: -canvas.height,
  41184. position: 'absolute'
  41185. }});
  41186. that._tooltipTracker.applySettings({
  41187. y: 0,
  41188. x: 0
  41189. })
  41190. },
  41191. _showTooltip: function() {
  41192. if (!this._tooltipInitializated) {
  41193. this._createTooltip();
  41194. this._tooltipInitializated = true;
  41195. if (!this._canShowTooltip)
  41196. return
  41197. }
  41198. this._updateTooltipSizeToWide();
  41199. this._tooltip.show()
  41200. },
  41201. _hideTooltip: function() {
  41202. this._updateTooltipSizeToNormal();
  41203. this._tooltip.hide()
  41204. },
  41205. showLoadingIndicator: $.noop
  41206. });
  41207. var menuEvents = {
  41208. 'contextmenu.sparkline-tooltip': function(event) {
  41209. if (DX.ui.events.isTouchEvent(event) || DX.ui.events.isPointerEvent(event))
  41210. event.preventDefault()
  41211. },
  41212. 'MSHoldVisual.sparkline-tooltip': function(event) {
  41213. event.preventDefault()
  41214. }
  41215. };
  41216. var mouseEvents = {
  41217. 'mouseover.sparkline-tooltip': function(event) {
  41218. isPointerDownCalled = false;
  41219. var widget = event.data.widget;
  41220. widget._x = event.pageX;
  41221. widget._y = event.pageY;
  41222. widget._tooltipTracker.off(mouseMoveEvents).on(mouseMoveEvents, event.data);
  41223. widget._doShowTooltip(DEFAULT_EVENTS_DELAY)
  41224. },
  41225. 'mouseout.sparkline-tooltip': function(event) {
  41226. if (isPointerDownCalled)
  41227. return;
  41228. var widget = event.data.widget;
  41229. widget._tooltipTracker.off(mouseMoveEvents);
  41230. widget._doHideTooltip(DEFAULT_EVENTS_DELAY)
  41231. }
  41232. };
  41233. var mouseMoveEvents = {'mousemove.sparkline-tooltip': function(event) {
  41234. var widget = event.data.widget;
  41235. if (widget._showTooltipTimeout && (_abs(widget._x - event.pageX) > 3 || _abs(widget._y - event.pageY) > 3)) {
  41236. widget._x = event.pageX;
  41237. widget._y = event.pageY;
  41238. widget._doShowTooltip(DEFAULT_EVENTS_DELAY)
  41239. }
  41240. }};
  41241. var active_touch_tooltip_widget = null,
  41242. touchstartTooltipProcessing = function(event) {
  41243. event.preventDefault();
  41244. var widget = active_touch_tooltip_widget;
  41245. if (widget && widget !== event.data.widget)
  41246. widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
  41247. widget = active_touch_tooltip_widget = event.data.widget;
  41248. widget._doShowTooltip(TOUCH_EVENTS_DELAY);
  41249. widget._touch = true
  41250. },
  41251. touchstartDocumentProcessing = function() {
  41252. var widget = active_touch_tooltip_widget;
  41253. if (widget) {
  41254. if (!widget._touch) {
  41255. widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
  41256. active_touch_tooltip_widget = null
  41257. }
  41258. widget._touch = null
  41259. }
  41260. },
  41261. touchendDocumentProcessing = function() {
  41262. var widget = active_touch_tooltip_widget;
  41263. if (widget)
  41264. if (widget._showTooltipTimeout) {
  41265. widget._doHideTooltip(DEFAULT_EVENTS_DELAY);
  41266. active_touch_tooltip_widget = null
  41267. }
  41268. },
  41269. isPointerDownCalled = false;
  41270. var touchEvents = {
  41271. 'pointerdown.sparkline-tooltip': function(event) {
  41272. touchstartTooltipProcessing(event)
  41273. },
  41274. 'touchstart.sparkline-tooltip': function(event) {
  41275. touchstartTooltipProcessing(event)
  41276. }
  41277. };
  41278. $(document).on({
  41279. 'pointerdown.sparkline-tooltip': function() {
  41280. isPointerDownCalled = true;
  41281. touchstartDocumentProcessing()
  41282. },
  41283. 'touchstart.sparkline-tooltip': function() {
  41284. touchstartDocumentProcessing()
  41285. },
  41286. 'pointerup.sparkline-tooltip': function() {
  41287. touchendDocumentProcessing()
  41288. },
  41289. 'touchend.sparkline-tooltip': function() {
  41290. touchendDocumentProcessing()
  41291. }
  41292. });
  41293. DX.viz.sparklines.BaseSparkline._DEBUG_reset = function() {
  41294. active_touch_tooltip_widget = null
  41295. }
  41296. })(jQuery, DevExpress);
  41297. /*! Module viz-sparklines, file sparkline.js */
  41298. (function($, DX) {
  41299. var viz = DX.viz,
  41300. charts = viz.charts,
  41301. core = viz.core,
  41302. MIN_BAR_WIDTH = 1,
  41303. MAX_BAR_WIDTH = 50,
  41304. DEFAULT_BAR_INTERVAL = 4,
  41305. DEFAULT_CANVAS_WIDTH = 250,
  41306. DEFAULT_CANVAS_HEIGHT = 30,
  41307. DEFAULT_HORIZONTAL_MARGIN = 5,
  41308. DEFAULT_VERTICAL_MARGIN = 3,
  41309. DEFAULT_OPTIONS = {
  41310. disabled: false,
  41311. theme: 'default',
  41312. dataSource: [],
  41313. size: {},
  41314. margin: {},
  41315. type: 'line',
  41316. argumentField: 'arg',
  41317. valueField: 'val',
  41318. winlossThreshold: 0,
  41319. showFirstLast: true,
  41320. showMinMax: false,
  41321. redrawOnResize: false
  41322. },
  41323. ALLOWED_TYPES = {
  41324. line: true,
  41325. spline: true,
  41326. stepline: true,
  41327. area: true,
  41328. steparea: true,
  41329. splinearea: true,
  41330. bar: true,
  41331. winloss: true
  41332. },
  41333. _map = $.map,
  41334. _extend = $.extend,
  41335. _abs = Math.abs,
  41336. _round = Math.round,
  41337. _isFinite = isFinite,
  41338. _Number = Number,
  41339. _String = String;
  41340. viz.sparklines.Sparkline = viz.sparklines.BaseSparkline.inherit({
  41341. _widgetType: 'sparkline',
  41342. _widgetClass: 'dxsl',
  41343. _defaultSize: {
  41344. width: DEFAULT_CANVAS_WIDTH,
  41345. height: DEFAULT_CANVAS_HEIGHT,
  41346. left: DEFAULT_HORIZONTAL_MARGIN,
  41347. right: DEFAULT_HORIZONTAL_MARGIN,
  41348. top: DEFAULT_VERTICAL_MARGIN,
  41349. bottom: DEFAULT_VERTICAL_MARGIN
  41350. },
  41351. _init: function() {
  41352. this.callBase();
  41353. this._refreshDataSource()
  41354. },
  41355. _handleDataSourceChanged: function() {
  41356. if (this._initialized) {
  41357. this._clean();
  41358. this._createWidgetElements();
  41359. this._drawWidgetElements()
  41360. }
  41361. },
  41362. _dataSourceOptions: function() {
  41363. return {
  41364. paginate: false,
  41365. _preferSync: true
  41366. }
  41367. },
  41368. _redrawWidgetElements: function() {
  41369. this._createTranslator();
  41370. this._correctPoints();
  41371. this._series.draw({
  41372. x: this._translatorX,
  41373. y: this._translatorY
  41374. });
  41375. this._seriesGroup.append(this._renderer.getRoot())
  41376. },
  41377. _disposeWidgetElements: function() {
  41378. delete this._seriesGroup;
  41379. delete this._seriesLabelGroup
  41380. },
  41381. _cleanWidgetElements: function() {
  41382. this._seriesGroup.detach();
  41383. this._seriesLabelGroup.detach();
  41384. this._seriesGroup.clear();
  41385. this._seriesLabelGroup.clear()
  41386. },
  41387. _createWidgetElements: function() {
  41388. this._createSeries();
  41389. this.callBase()
  41390. },
  41391. _drawWidgetElements: function() {
  41392. if (this._dataSource && this._dataSource.isLoaded())
  41393. this._drawSeries()
  41394. },
  41395. _prepareOptions: function() {
  41396. this._allOptions = this.callBase(DEFAULT_OPTIONS);
  41397. this._allOptions.type = _String(this._allOptions.type).toLowerCase();
  41398. if (!ALLOWED_TYPES[this._allOptions.type])
  41399. this._allOptions.type = 'line'
  41400. },
  41401. _createHtmlElements: function() {
  41402. this._seriesGroup = this._renderer.createGroup({'class': 'dxsl-series'});
  41403. this._seriesLabelGroup = this._renderer.createGroup({'class': 'dxsl-series-labels'})
  41404. },
  41405. _createSeries: function() {
  41406. var that = this,
  41407. renderer = that._renderer,
  41408. dataValidator;
  41409. that._prepareDataSource();
  41410. that._prepareSeriesOptions();
  41411. that._series = core.CoreFactory.createSeries(renderer, that._seriesOptions);
  41412. dataValidator = charts.factory.createDataValidator(that._simpleDataSource, [[that._series]], that._incidentOccured, {
  41413. checkTypeForAllData: false,
  41414. convertToAxisDataType: true,
  41415. sortingMethod: true
  41416. });
  41417. that._simpleDataSource = dataValidator.validate();
  41418. that._series._options.customizePoint = that._getCustomizeFunction();
  41419. that._series.updateData(that._simpleDataSource)
  41420. },
  41421. _parseNumericDataSource: function(data, argField, valField) {
  41422. var ignoreEmptyPoints = this.option('ignoreEmptyPoints');
  41423. return _map(data, function(dataItem, index) {
  41424. var item = null,
  41425. isDataNumber,
  41426. value;
  41427. if (dataItem !== undefined) {
  41428. item = {};
  41429. isDataNumber = _isFinite(dataItem);
  41430. item[argField] = isDataNumber ? _String(index) : dataItem[argField];
  41431. value = isDataNumber ? dataItem : dataItem[valField];
  41432. item[valField] = value === null ? ignoreEmptyPoints ? undefined : value : _Number(value);
  41433. item = item[argField] !== undefined && item[valField] !== undefined ? item : null
  41434. }
  41435. return item
  41436. })
  41437. },
  41438. _parseWinlossDataSource: function(data, argField, valField) {
  41439. var lowBarValue = -1,
  41440. zeroBarValue = 0,
  41441. highBarValue = 1,
  41442. delta = 0.0001,
  41443. target = this._allOptions.winlossThreshold;
  41444. return _map(data, function(dataItem) {
  41445. var item = {};
  41446. item[argField] = dataItem[argField];
  41447. if (_abs(dataItem[valField] - target) < delta)
  41448. item[valField] = zeroBarValue;
  41449. else if (dataItem[valField] > target)
  41450. item[valField] = highBarValue;
  41451. else
  41452. item[valField] = lowBarValue;
  41453. return item
  41454. })
  41455. },
  41456. _prepareDataSource: function() {
  41457. var that = this,
  41458. options = that._allOptions,
  41459. argField = options.argumentField,
  41460. valField = options.valueField,
  41461. dataSource = that._dataSource ? that._dataSource.items() : [],
  41462. data = that._parseNumericDataSource(dataSource, argField, valField);
  41463. if (options.type === 'winloss') {
  41464. that._winlossDataSource = data;
  41465. that._simpleDataSource = that._parseWinlossDataSource(data, argField, valField)
  41466. }
  41467. else
  41468. that._simpleDataSource = data
  41469. },
  41470. _prepareSeriesOptions: function() {
  41471. var that = this,
  41472. options = that._allOptions,
  41473. defaultPointOptions = {
  41474. border: {},
  41475. hoverStyle: {border: {}},
  41476. selectionStyle: {border: {}}
  41477. },
  41478. customPointOptions = {
  41479. size: options.pointSize,
  41480. symbol: options.pointSymbol,
  41481. border: {
  41482. visible: true,
  41483. width: 2
  41484. },
  41485. color: options.pointColor
  41486. };
  41487. that._seriesOptions = {
  41488. visible: true,
  41489. argumentField: options.argumentField,
  41490. valueField: options.valueField,
  41491. color: options.lineColor,
  41492. width: options.lineWidth,
  41493. widgetType: "chart"
  41494. };
  41495. that._seriesOptions.border = {
  41496. color: that._seriesOptions.color,
  41497. width: that._seriesOptions.width,
  41498. visible: true
  41499. };
  41500. that._seriesOptions.type = options.type === 'winloss' ? 'bar' : options.type;
  41501. if (options.type === 'winloss' || options.type === 'bar') {
  41502. that._seriesOptions.argumentAxisType = 'discrete';
  41503. that._seriesOptions.border.visible = false
  41504. }
  41505. if (~~options.type.indexOf('area') !== -1)
  41506. that._seriesOptions.opacity = that._allOptions.areaOpacity;
  41507. that._seriesOptions.seriesGroup = that._seriesGroup;
  41508. that._seriesOptions.seriesLabelsGroup = that._seriesLabelGroup;
  41509. that._seriesOptions.point = _extend(defaultPointOptions, customPointOptions);
  41510. that._seriesOptions.point.visible = false
  41511. },
  41512. _createBarCustomizeFunction: function(pointIndexes) {
  41513. var that = this,
  41514. options = that._allOptions,
  41515. winlossData = that._winlossDataSource;
  41516. return function() {
  41517. var index = this.index,
  41518. isWinloss = options.type === 'winloss',
  41519. target = isWinloss ? options.winlossThreshold : 0,
  41520. value = isWinloss ? winlossData[index][options.valueField] : this.value,
  41521. positiveColor = isWinloss ? options.winColor : options.barPositiveColor,
  41522. negativeColor = isWinloss ? options.lossColor : options.barNegativeColor,
  41523. color;
  41524. if (value >= target)
  41525. color = positiveColor;
  41526. else
  41527. color = negativeColor;
  41528. if (index === pointIndexes.first || index === pointIndexes.last)
  41529. color = options.firstLastColor;
  41530. if (index === pointIndexes.min)
  41531. color = options.minColor;
  41532. if (index === pointIndexes.max)
  41533. color = options.maxColor;
  41534. return {color: color}
  41535. }
  41536. },
  41537. _createLineCustomizeFunction: function(pointIndexes) {
  41538. var that = this,
  41539. options = that._allOptions;
  41540. return function() {
  41541. var color,
  41542. index = this.index;
  41543. if (index === pointIndexes.first || index === pointIndexes.last)
  41544. color = options.firstLastColor;
  41545. if (index === pointIndexes.min)
  41546. color = options.minColor;
  41547. if (index === pointIndexes.max)
  41548. color = options.maxColor;
  41549. return color ? {
  41550. visible: true,
  41551. border: {color: color}
  41552. } : {}
  41553. }
  41554. },
  41555. _getCustomizeFunction: function() {
  41556. var that = this,
  41557. options = that._allOptions,
  41558. dataSource = that._winlossDataSource || that._simpleDataSource,
  41559. drawnPointIndexes = that._getExtremumPointsIndexes(dataSource),
  41560. customizeFunction;
  41561. if (options.type === 'winloss' || options.type === 'bar')
  41562. customizeFunction = that._createBarCustomizeFunction(drawnPointIndexes);
  41563. else
  41564. customizeFunction = that._createLineCustomizeFunction(drawnPointIndexes);
  41565. return customizeFunction
  41566. },
  41567. _getExtremumPointsIndexes: function(data) {
  41568. var that = this,
  41569. options = that._allOptions,
  41570. lastIndex = data.length - 1,
  41571. indexes = {};
  41572. that._minMaxIndexes = that._findMinMax(data);
  41573. if (options.showFirstLast) {
  41574. indexes.first = 0;
  41575. indexes.last = lastIndex
  41576. }
  41577. if (options.showMinMax) {
  41578. indexes.min = that._minMaxIndexes.minIndex;
  41579. indexes.max = that._minMaxIndexes.maxIndex
  41580. }
  41581. return indexes
  41582. },
  41583. _findMinMax: function(data) {
  41584. var that = this,
  41585. valField = that._allOptions.valueField,
  41586. firstItem = data[0] || {},
  41587. firstValue = firstItem[valField] || 0,
  41588. min = firstValue,
  41589. max = firstValue,
  41590. minIndex = 0,
  41591. maxIndex = 0,
  41592. dataLength = data.length,
  41593. value,
  41594. i;
  41595. for (i = 1; i < dataLength; i++) {
  41596. value = data[i][valField];
  41597. if (value < min) {
  41598. min = value;
  41599. minIndex = i
  41600. }
  41601. if (value > max) {
  41602. max = value;
  41603. maxIndex = i
  41604. }
  41605. }
  41606. return {
  41607. minIndex: minIndex,
  41608. maxIndex: maxIndex
  41609. }
  41610. },
  41611. _createRange: function() {
  41612. var that = this,
  41613. series = that._series,
  41614. isBarType = series.type === 'bar',
  41615. DEFAULT_VALUE_RANGE_MARGIN = 0.15,
  41616. DEFAULT_ARGUMENT_RANGE_MARGIN = isBarType ? 0.1 : 0,
  41617. rangeData = series.getRangeData();
  41618. that._ranges = {
  41619. arg: new core.Range({
  41620. stick: !isBarType && series.getPoints().length > 1,
  41621. minValueMargin: DEFAULT_ARGUMENT_RANGE_MARGIN,
  41622. maxValueMargin: DEFAULT_ARGUMENT_RANGE_MARGIN
  41623. }),
  41624. val: new core.Range({
  41625. isValueRange: true,
  41626. keepValueMargins: true,
  41627. minValueMargin: DEFAULT_VALUE_RANGE_MARGIN,
  41628. maxValueMargin: DEFAULT_VALUE_RANGE_MARGIN
  41629. })
  41630. };
  41631. that._ranges.arg.addRange(rangeData.arg);
  41632. that._ranges.val.addRange(rangeData.val);
  41633. that._ranges.arg.applyValueMargins();
  41634. that._ranges.val.applyValueMargins()
  41635. },
  41636. _getBarWidth: function(pointsCount) {
  41637. var that = this,
  41638. canvas = that._canvas,
  41639. intervalWidth = pointsCount * DEFAULT_BAR_INTERVAL,
  41640. rangeWidth = canvas.width - canvas.left - canvas.right - intervalWidth,
  41641. width = _round(rangeWidth / pointsCount);
  41642. if (width < MIN_BAR_WIDTH)
  41643. width = MIN_BAR_WIDTH;
  41644. if (width > MAX_BAR_WIDTH)
  41645. width = MAX_BAR_WIDTH;
  41646. return width
  41647. },
  41648. _correctPoints: function() {
  41649. var that = this,
  41650. seriesType = that._allOptions.type,
  41651. seriesPoints = that._series.getPoints(),
  41652. pointsLength = seriesPoints.length,
  41653. barWidth,
  41654. i;
  41655. if (seriesType === 'bar' || seriesType === 'winloss') {
  41656. barWidth = that._getBarWidth(pointsLength);
  41657. for (i = 0; i < pointsLength; i++)
  41658. seriesPoints[i].correctCoordinates({
  41659. width: barWidth,
  41660. offset: 0
  41661. })
  41662. }
  41663. },
  41664. _drawSeries: function() {
  41665. var that = this;
  41666. if (that._simpleDataSource.length !== 0) {
  41667. that._correctPoints();
  41668. that._series.draw({
  41669. x: that._translatorX,
  41670. y: that._translatorY
  41671. });
  41672. that._seriesGroup.append(that._renderer.getRoot());
  41673. that._prepareTooltipContainer()
  41674. }
  41675. },
  41676. _isTooltipVisible: function() {
  41677. return this.callBase() && this._dataSource.length !== 0
  41678. },
  41679. _getTooltipData: function() {
  41680. var that = this,
  41681. options = that._allOptions,
  41682. dataSource = that._winlossDataSource || that._simpleDataSource,
  41683. tooltip = that._tooltip;
  41684. if (dataSource.length === 0)
  41685. return {};
  41686. var minMax = that._minMaxIndexes,
  41687. valueField = options.valueField,
  41688. first = dataSource[0][valueField],
  41689. last = dataSource[dataSource.length - 1][valueField],
  41690. min = dataSource[minMax.minIndex][valueField],
  41691. max = dataSource[minMax.maxIndex][valueField],
  41692. formattedFirst = tooltip.formatValue(first),
  41693. formattedLast = tooltip.formatValue(last),
  41694. formattedMin = tooltip.formatValue(min),
  41695. formattedMax = tooltip.formatValue(max),
  41696. customizeObject = {
  41697. firstValue: formattedFirst,
  41698. lastValue: formattedLast,
  41699. minValue: formattedMin,
  41700. maxValue: formattedMax,
  41701. originalFirstValue: first,
  41702. originalLastValue: last,
  41703. originalMinValue: min,
  41704. originalMaxValue: max,
  41705. valueText: ['Start:', formattedFirst, 'End:', formattedLast, 'Min:', formattedMin, 'Max:', formattedMax]
  41706. };
  41707. if (options.type === 'winloss') {
  41708. customizeObject.originalThresholdValue = options.winlossThreshold;
  41709. customizeObject.thresholdValue = tooltip.formatValue(options.winlossThreshold)
  41710. }
  41711. return customizeObject
  41712. }
  41713. }).include(DX.ui.DataHelperMixin)
  41714. })(jQuery, DevExpress);
  41715. /*! Module viz-sparklines, file bullet.js */
  41716. (function($, DX) {
  41717. var charts = DX.viz.charts,
  41718. TARGET_MIN_Y = 0.02,
  41719. TARGET_MAX_Y = 0.98,
  41720. BAR_VALUE_MIN_Y = 0.1,
  41721. BAR_VALUE_MAX_Y = 0.9,
  41722. DEFAULT_CANVAS_WIDTH = 300,
  41723. DEFAULT_CANVAS_HEIGHT = 30,
  41724. DEFAULT_HORIZONTAL_MARGIN = 1,
  41725. DEFAULT_VERTICAL_MARGIN = 2,
  41726. DEFAULT_OPTIONS = {
  41727. disabled: false,
  41728. theme: 'default',
  41729. size: {},
  41730. margin: {}
  41731. },
  41732. _String = String,
  41733. _Number = Number,
  41734. _round = Math.round,
  41735. _isFinite = isFinite;
  41736. DX.viz.sparklines.Bullet = DX.viz.sparklines.BaseSparkline.inherit({
  41737. _widgetType: 'bullet',
  41738. _widgetClass: 'dxb',
  41739. _defaultSize: {
  41740. width: DEFAULT_CANVAS_WIDTH,
  41741. height: DEFAULT_CANVAS_HEIGHT,
  41742. left: DEFAULT_HORIZONTAL_MARGIN,
  41743. right: DEFAULT_HORIZONTAL_MARGIN,
  41744. top: DEFAULT_VERTICAL_MARGIN,
  41745. bottom: DEFAULT_VERTICAL_MARGIN
  41746. },
  41747. _disposeWidgetElements: function() {
  41748. delete this._zeroLevelPath;
  41749. delete this._targetPath;
  41750. delete this._barValuePath
  41751. },
  41752. _redrawWidgetElements: function() {
  41753. this._createTranslator();
  41754. this._drawBarValue();
  41755. this._drawTarget();
  41756. this._drawZeroLevel()
  41757. },
  41758. _cleanWidgetElements: function() {
  41759. this._zeroLevelPath.detach();
  41760. this._targetPath.detach();
  41761. this._barValuePath.detach()
  41762. },
  41763. _drawWidgetElements: function() {
  41764. this._drawBullet()
  41765. },
  41766. _createHtmlElements: function() {
  41767. var renderer = this._renderer;
  41768. this._zeroLevelPath = renderer.createPath(undefined, {'class': 'dxb-zero-level'});
  41769. this._targetPath = renderer.createPath(undefined, {'class': 'dxb-target'});
  41770. this._barValuePath = renderer.createPath(undefined, {'class': 'dxb-bar-value'})
  41771. },
  41772. _prepareOptions: function() {
  41773. var that = this,
  41774. options,
  41775. startScaleValue,
  41776. endScaleValue,
  41777. level,
  41778. value,
  41779. target;
  41780. that._allOptions = options = that.callBase(DEFAULT_OPTIONS);
  41781. if (that._allOptions.value === undefined)
  41782. that._allOptions.value = 0;
  41783. if (that._allOptions.target === undefined)
  41784. that._allOptions.target = 0;
  41785. options.value = value = _Number(options.value);
  41786. options.target = target = _Number(options.target);
  41787. if (that._allOptions.startScaleValue === undefined) {
  41788. that._allOptions.startScaleValue = target < value ? target : value;
  41789. that._allOptions.startScaleValue = that._allOptions.startScaleValue < 0 ? that._allOptions.startScaleValue : 0
  41790. }
  41791. if (that._allOptions.endScaleValue === undefined)
  41792. that._allOptions.endScaleValue = target > value ? target : value;
  41793. options.startScaleValue = startScaleValue = _Number(options.startScaleValue);
  41794. options.endScaleValue = endScaleValue = _Number(options.endScaleValue);
  41795. if (endScaleValue < startScaleValue) {
  41796. level = endScaleValue;
  41797. that._allOptions.endScaleValue = startScaleValue;
  41798. that._allOptions.startScaleValue = level;
  41799. that._allOptions.inverted = true
  41800. }
  41801. },
  41802. _createRange: function() {
  41803. var that = this,
  41804. options = that._allOptions;
  41805. that._ranges = {
  41806. arg: {
  41807. invert: options.inverted,
  41808. min: options.startScaleValue,
  41809. max: options.endScaleValue,
  41810. axisType: "continuous",
  41811. dataType: "numeric"
  41812. },
  41813. val: {
  41814. min: 0,
  41815. max: 1,
  41816. axisType: "continuous",
  41817. dataType: "numeric"
  41818. }
  41819. }
  41820. },
  41821. _drawBullet: function() {
  41822. var that = this,
  41823. options = that._allOptions,
  41824. isValidBounds = options.startScaleValue !== options.endScaleValue,
  41825. isValidMin = _isFinite(options.startScaleValue),
  41826. isValidMax = _isFinite(options.endScaleValue),
  41827. isValidValue = _isFinite(options.value),
  41828. isValidTarget = _isFinite(options.target);
  41829. if (isValidBounds && isValidMax && isValidMin && isValidTarget && isValidValue) {
  41830. this._drawBarValue();
  41831. this._drawTarget();
  41832. this._drawZeroLevel();
  41833. this._prepareTooltipContainer()
  41834. }
  41835. },
  41836. _getTargetParams: function() {
  41837. var that = this,
  41838. options = that._allOptions,
  41839. translatorX = that._translatorX,
  41840. translatorY = that._translatorY,
  41841. minY = translatorY.translate(TARGET_MIN_Y),
  41842. maxY = translatorY.translate(TARGET_MAX_Y),
  41843. x = translatorX.translate(options.target),
  41844. points = [{
  41845. x: x,
  41846. y: minY
  41847. }, {
  41848. x: x,
  41849. y: maxY
  41850. }];
  41851. return {
  41852. points: points,
  41853. stroke: options.targetColor,
  41854. strokeWidth: options.targetWidth
  41855. }
  41856. },
  41857. _getBarValueParams: function() {
  41858. var that = this,
  41859. options = that._allOptions,
  41860. translatorX = that._translatorX,
  41861. translatorY = that._translatorY,
  41862. startLevel = options.startScaleValue,
  41863. endLevel = options.endScaleValue,
  41864. value = options.value,
  41865. y2 = translatorY.translate(BAR_VALUE_MIN_Y),
  41866. y1 = translatorY.translate(BAR_VALUE_MAX_Y),
  41867. x1,
  41868. x2;
  41869. if (value > 0) {
  41870. x1 = startLevel <= 0 ? 0 : startLevel;
  41871. x2 = value >= endLevel ? endLevel : value
  41872. }
  41873. else {
  41874. x1 = endLevel >= 0 ? 0 : endLevel;
  41875. x2 = value >= startLevel ? value : startLevel
  41876. }
  41877. x1 = translatorX.translate(x1);
  41878. x2 = translatorX.translate(x2);
  41879. return {
  41880. points: [{
  41881. x: x1,
  41882. y: y1
  41883. }, {
  41884. x: x2,
  41885. y: y1
  41886. }, {
  41887. x: x2,
  41888. y: y2
  41889. }, {
  41890. x: x1,
  41891. y: y2
  41892. }],
  41893. fill: options.color
  41894. }
  41895. },
  41896. _getZeroLevelParams: function() {
  41897. var that = this,
  41898. options = that._allOptions,
  41899. translatorX = that._translatorX,
  41900. translatorY = that._translatorY,
  41901. minY = translatorY.translate(TARGET_MIN_Y),
  41902. maxY = translatorY.translate(TARGET_MAX_Y),
  41903. x = translatorX.translate(0);
  41904. return {
  41905. points: [{
  41906. x: x,
  41907. y: minY
  41908. }, {
  41909. x: x,
  41910. y: maxY
  41911. }],
  41912. stroke: options.targetColor,
  41913. strokeWidth: 1
  41914. }
  41915. },
  41916. _drawZeroLevel: function() {
  41917. var that = this,
  41918. options = that._allOptions,
  41919. params;
  41920. if (0 > options.endScaleValue || 0 < options.startScaleValue || !options.showZeroLevel)
  41921. return;
  41922. params = that._getZeroLevelParams();
  41923. that._zeroLevelPath.applySettings(params);
  41924. that._zeroLevelPath.append(that._renderer.getRoot())
  41925. },
  41926. _drawTarget: function() {
  41927. var that = this,
  41928. options = that._allOptions,
  41929. target = options.target,
  41930. startLevel = options.startScaleValue,
  41931. endLevel = options.endScaleValue,
  41932. params;
  41933. if (target > endLevel || target < startLevel || !options.showTarget)
  41934. return;
  41935. params = that._getTargetParams();
  41936. that._targetPath.applySettings(params);
  41937. that._targetPath.append(that._renderer.getRoot())
  41938. },
  41939. _drawBarValue: function() {
  41940. var that = this,
  41941. params = that._getBarValueParams();
  41942. that._barValuePath.applySettings(params);
  41943. that._barValuePath.append(that._renderer.getRoot())
  41944. },
  41945. _getTooltipData: function() {
  41946. var that = this,
  41947. tooltip = that._tooltip,
  41948. options = that._allOptions,
  41949. value = options.value,
  41950. target = options.target;
  41951. return {
  41952. originalValue: value,
  41953. originalTarget: target,
  41954. value: tooltip.formatValue(value),
  41955. target: tooltip.formatValue(target),
  41956. valueText: ['Actual Value:', value, 'Target Value:', target]
  41957. }
  41958. },
  41959. _getNormalTooltipSize: function() {
  41960. var size = {},
  41961. bbox = this._barValuePath.getBBox();
  41962. size.width = this._canvas.width;
  41963. size.left = 0;
  41964. size.tooltipLeft = bbox.x + _round(bbox.width / 2);
  41965. return size
  41966. },
  41967. _getWideTooltipSize: function(leftWidthDelta, rightWidthDelta) {
  41968. var that = this,
  41969. bbox = that._barValuePath.getBBox(),
  41970. horizontalPos = that._allOptions.tooltip.horizontalAlignment,
  41971. size = {};
  41972. size.width = leftWidthDelta + rightWidthDelta + that._canvas.width;
  41973. size.left = -leftWidthDelta;
  41974. if (horizontalPos === 'right')
  41975. size.tooltipLeft = bbox.x + _round(bbox.width / 2);
  41976. else if (horizontalPos === 'left')
  41977. size.tooltipLeft = _round(bbox.width / 2) + leftWidthDelta + rightWidthDelta + bbox.x;
  41978. else
  41979. size.tooltipLeft = _round(bbox.width / 2) + bbox.x + leftWidthDelta;
  41980. return size
  41981. }
  41982. })
  41983. })(jQuery, DevExpress);
  41984. /*! Module viz-sparklines, file dxSparkline.js */
  41985. (function($, DX, undefined) {
  41986. var ui = DX.ui,
  41987. viz = DX.viz;
  41988. DX.registerComponent("dxSparkline", viz.sparklines.Sparkline)
  41989. })(jQuery, DevExpress);
  41990. /*! Module viz-sparklines, file dxBullet.js */
  41991. (function($, DX, undefined) {
  41992. var ui = DX.ui,
  41993. viz = DX.viz;
  41994. DX.registerComponent("dxBullet", viz.sparklines.Bullet)
  41995. })(jQuery, DevExpress);
  41996. DevExpress.MOD_VIZ_SPARKLINES = true
  41997. }