c3.js 382 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979
  1. /* @license C3.js v0.7.15 | (c) C3 Team and other contributors | http://c3js.org/ */
  2. (function (global, factory) {
  3. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  4. typeof define === 'function' && define.amd ? define(factory) :
  5. (global = global || self, global.c3 = factory());
  6. }(this, (function () { 'use strict';
  7. function _typeof(obj) {
  8. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  9. _typeof = function (obj) {
  10. return typeof obj;
  11. };
  12. } else {
  13. _typeof = function (obj) {
  14. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  15. };
  16. }
  17. return _typeof(obj);
  18. }
  19. function _classCallCheck(instance, Constructor) {
  20. if (!(instance instanceof Constructor)) {
  21. throw new TypeError("Cannot call a class as a function");
  22. }
  23. }
  24. function _defineProperty(obj, key, value) {
  25. if (key in obj) {
  26. Object.defineProperty(obj, key, {
  27. value: value,
  28. enumerable: true,
  29. configurable: true,
  30. writable: true
  31. });
  32. } else {
  33. obj[key] = value;
  34. }
  35. return obj;
  36. }
  37. function _toConsumableArray(arr) {
  38. return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
  39. }
  40. function _arrayWithoutHoles(arr) {
  41. if (Array.isArray(arr)) {
  42. for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
  43. return arr2;
  44. }
  45. }
  46. function _iterableToArray(iter) {
  47. if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
  48. }
  49. function _nonIterableSpread() {
  50. throw new TypeError("Invalid attempt to spread non-iterable instance");
  51. }
  52. function ChartInternal(api) {
  53. var $$ = this; // Note: This part will be replaced by rollup-plugin-modify
  54. // When bundling esm output. Beware of changing this line.
  55. // TODO: Maybe we should check that the modification by rollup-plugin-modify
  56. // is valid during unit tests.
  57. $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
  58. $$.api = api;
  59. $$.config = $$.getDefaultConfig();
  60. $$.data = {};
  61. $$.cache = {};
  62. $$.axes = {};
  63. }
  64. /**
  65. * The Chart class
  66. *
  67. * The methods of this class is the public APIs of the chart object.
  68. */
  69. function Chart(config) {
  70. this.internal = new ChartInternal(this);
  71. this.internal.loadConfig(config);
  72. this.internal.beforeInit(config);
  73. this.internal.init();
  74. this.internal.afterInit(config); // bind "this" to nested API
  75. (function bindThis(fn, target, argThis) {
  76. Object.keys(fn).forEach(function (key) {
  77. target[key] = fn[key].bind(argThis);
  78. if (Object.keys(fn[key]).length > 0) {
  79. bindThis(fn[key], target[key], argThis);
  80. }
  81. });
  82. })(Chart.prototype, this, this);
  83. }
  84. var asHalfPixel = function asHalfPixel(n) {
  85. return Math.ceil(n) + 0.5;
  86. };
  87. var ceil10 = function ceil10(v) {
  88. return Math.ceil(v / 10) * 10;
  89. };
  90. var diffDomain = function diffDomain(d) {
  91. return d[1] - d[0];
  92. };
  93. var getOption = function getOption(options, key, defaultValue) {
  94. return isDefined(options[key]) ? options[key] : defaultValue;
  95. };
  96. var getPathBox = function getPathBox(path) {
  97. var box = getBBox(path),
  98. items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],
  99. minX = items[0].x,
  100. minY = Math.min(items[0].y, items[1].y);
  101. return {
  102. x: minX,
  103. y: minY,
  104. width: box.width,
  105. height: box.height
  106. };
  107. };
  108. var getBBox = function getBBox(element) {
  109. try {
  110. return element.getBBox();
  111. } catch (ignore) {
  112. // Firefox will throw an exception if getBBox() is called whereas the
  113. // element is rendered with display:none
  114. // See https://github.com/c3js/c3/issues/2692
  115. // The previous code was using `getBoundingClientRect` which was returning
  116. // everything at 0 in this case so let's reproduce this behavior here.
  117. return {
  118. x: 0,
  119. y: 0,
  120. width: 0,
  121. height: 0
  122. };
  123. }
  124. };
  125. var hasValue = function hasValue(dict, value) {
  126. var found = false;
  127. Object.keys(dict).forEach(function (key) {
  128. if (dict[key] === value) {
  129. found = true;
  130. }
  131. });
  132. return found;
  133. };
  134. var isArray = function isArray(o) {
  135. return Array.isArray(o);
  136. };
  137. var isDefined = function isDefined(v) {
  138. return typeof v !== 'undefined';
  139. };
  140. var isEmpty = function isEmpty(o) {
  141. return typeof o === 'undefined' || o === null || isString(o) && o.length === 0 || _typeof(o) === 'object' && Object.keys(o).length === 0;
  142. };
  143. var isFunction = function isFunction(o) {
  144. return typeof o === 'function';
  145. };
  146. var isNumber = function isNumber(o) {
  147. return typeof o === 'number';
  148. };
  149. var isString = function isString(o) {
  150. return typeof o === 'string';
  151. };
  152. var isUndefined = function isUndefined(v) {
  153. return typeof v === 'undefined';
  154. };
  155. var isValue = function isValue(v) {
  156. return v || v === 0;
  157. };
  158. var notEmpty = function notEmpty(o) {
  159. return !isEmpty(o);
  160. };
  161. var sanitise = function sanitise(str) {
  162. return typeof str === 'string' ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;') : str;
  163. };
  164. var flattenArray = function flattenArray(arr) {
  165. var _ref;
  166. return Array.isArray(arr) ? (_ref = []).concat.apply(_ref, _toConsumableArray(arr)) : [];
  167. };
  168. /**
  169. * Returns whether the point is within the given box.
  170. *
  171. * @param {Array} point An [x,y] coordinate
  172. * @param {Object} box An object with {x, y, width, height} keys
  173. * @param {Number} sensitivity An offset to ease check on very small boxes
  174. */
  175. var isWithinBox = function isWithinBox(point, box) {
  176. var sensitivity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
  177. var xStart = box.x - sensitivity;
  178. var xEnd = box.x + box.width + sensitivity;
  179. var yStart = box.y + box.height + sensitivity;
  180. var yEnd = box.y - sensitivity;
  181. return xStart < point[0] && point[0] < xEnd && yEnd < point[1] && point[1] < yStart;
  182. };
  183. /**
  184. * Returns Internet Explorer version number (or false if no Internet Explorer used).
  185. *
  186. * @param string agent Optional parameter to specify user agent
  187. */
  188. var getIEVersion = function getIEVersion(agent) {
  189. // https://stackoverflow.com/questions/19999388/check-if-user-is-using-ie
  190. if (typeof agent === 'undefined') {
  191. agent = window.navigator.userAgent;
  192. }
  193. var pos = agent.indexOf('MSIE '); // up to IE10
  194. if (pos > 0) {
  195. return parseInt(agent.substring(pos + 5, agent.indexOf('.', pos)), 10);
  196. }
  197. pos = agent.indexOf('Trident/'); // IE11
  198. if (pos > 0) {
  199. pos = agent.indexOf('rv:');
  200. return parseInt(agent.substring(pos + 3, agent.indexOf('.', pos)), 10);
  201. }
  202. return false;
  203. };
  204. /**
  205. * Returns whether the used browser is Internet Explorer.
  206. *
  207. * @param {Number} version Optional parameter to specify IE version
  208. */
  209. var isIE = function isIE(version) {
  210. var ver = getIEVersion();
  211. if (typeof version === 'undefined') {
  212. return !!ver;
  213. }
  214. return version === ver;
  215. };
  216. function AxisInternal(component, params) {
  217. var internal = this;
  218. internal.component = component;
  219. internal.params = params || {};
  220. internal.d3 = component.d3;
  221. internal.scale = internal.d3.scaleLinear();
  222. internal.range;
  223. internal.orient = "bottom";
  224. internal.innerTickSize = 6;
  225. internal.outerTickSize = this.params.withOuterTick ? 6 : 0;
  226. internal.tickPadding = 3;
  227. internal.tickValues = null;
  228. internal.tickFormat;
  229. internal.tickArguments;
  230. internal.tickOffset = 0;
  231. internal.tickCulling = true;
  232. internal.tickCentered;
  233. internal.tickTextCharSize;
  234. internal.tickTextRotate = internal.params.tickTextRotate;
  235. internal.tickLength;
  236. internal.axis = internal.generateAxis();
  237. }
  238. AxisInternal.prototype.axisX = function (selection, x, tickOffset) {
  239. selection.attr("transform", function (d) {
  240. return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)";
  241. });
  242. };
  243. AxisInternal.prototype.axisY = function (selection, y) {
  244. selection.attr("transform", function (d) {
  245. return "translate(0," + Math.ceil(y(d)) + ")";
  246. });
  247. };
  248. AxisInternal.prototype.scaleExtent = function (domain) {
  249. var start = domain[0],
  250. stop = domain[domain.length - 1];
  251. return start < stop ? [start, stop] : [stop, start];
  252. };
  253. AxisInternal.prototype.generateTicks = function (scale) {
  254. var internal = this;
  255. var i,
  256. domain,
  257. ticks = [];
  258. if (scale.ticks) {
  259. return scale.ticks.apply(scale, internal.tickArguments);
  260. }
  261. domain = scale.domain();
  262. for (i = Math.ceil(domain[0]); i < domain[1]; i++) {
  263. ticks.push(i);
  264. }
  265. if (ticks.length > 0 && ticks[0] > 0) {
  266. ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));
  267. }
  268. return ticks;
  269. };
  270. AxisInternal.prototype.copyScale = function () {
  271. var internal = this;
  272. var newScale = internal.scale.copy(),
  273. domain;
  274. if (internal.params.isCategory) {
  275. domain = internal.scale.domain();
  276. newScale.domain([domain[0], domain[1] - 1]);
  277. }
  278. return newScale;
  279. };
  280. AxisInternal.prototype.textFormatted = function (v) {
  281. var internal = this,
  282. formatted = internal.tickFormat ? internal.tickFormat(v) : v;
  283. return typeof formatted !== 'undefined' ? formatted : '';
  284. };
  285. AxisInternal.prototype.updateRange = function () {
  286. var internal = this;
  287. internal.range = internal.scale.rangeExtent ? internal.scale.rangeExtent() : internal.scaleExtent(internal.scale.range());
  288. return internal.range;
  289. };
  290. AxisInternal.prototype.updateTickTextCharSize = function (tick) {
  291. var internal = this;
  292. if (internal.tickTextCharSize) {
  293. return internal.tickTextCharSize;
  294. }
  295. var size = {
  296. h: 11.5,
  297. w: 5.5
  298. };
  299. tick.select('text').text(function (d) {
  300. return internal.textFormatted(d);
  301. }).each(function (d) {
  302. var box = getBBox(this),
  303. text = internal.textFormatted(d),
  304. h = box.height,
  305. w = text ? box.width / text.length : undefined;
  306. if (h && w) {
  307. size.h = h;
  308. size.w = w;
  309. }
  310. }).text('');
  311. internal.tickTextCharSize = size;
  312. return size;
  313. };
  314. AxisInternal.prototype.isVertical = function () {
  315. return this.orient === 'left' || this.orient === 'right';
  316. };
  317. AxisInternal.prototype.tspanData = function (d, i, scale) {
  318. var internal = this;
  319. var splitted = internal.params.tickMultiline ? internal.splitTickText(d, scale) : [].concat(internal.textFormatted(d));
  320. if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {
  321. splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax);
  322. }
  323. return splitted.map(function (s) {
  324. return {
  325. index: i,
  326. splitted: s,
  327. length: splitted.length
  328. };
  329. });
  330. };
  331. AxisInternal.prototype.splitTickText = function (d, scale) {
  332. var internal = this,
  333. tickText = internal.textFormatted(d),
  334. maxWidth = internal.params.tickWidth,
  335. subtext,
  336. spaceIndex,
  337. textWidth,
  338. splitted = [];
  339. if (Object.prototype.toString.call(tickText) === "[object Array]") {
  340. return tickText;
  341. }
  342. if (!maxWidth || maxWidth <= 0) {
  343. maxWidth = internal.isVertical() ? 95 : internal.params.isCategory ? Math.ceil(scale(1) - scale(0)) - 12 : 110;
  344. }
  345. function split(splitted, text) {
  346. spaceIndex = undefined;
  347. for (var i = 1; i < text.length; i++) {
  348. if (text.charAt(i) === ' ') {
  349. spaceIndex = i;
  350. }
  351. subtext = text.substr(0, i + 1);
  352. textWidth = internal.tickTextCharSize.w * subtext.length; // if text width gets over tick width, split by space index or crrent index
  353. if (maxWidth < textWidth) {
  354. return split(splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), text.slice(spaceIndex ? spaceIndex + 1 : i));
  355. }
  356. }
  357. return splitted.concat(text);
  358. }
  359. return split(splitted, tickText + "");
  360. };
  361. AxisInternal.prototype.ellipsify = function (splitted, max) {
  362. if (splitted.length <= max) {
  363. return splitted;
  364. }
  365. var ellipsified = splitted.slice(0, max);
  366. var remaining = 3;
  367. for (var i = max - 1; i >= 0; i--) {
  368. var available = ellipsified[i].length;
  369. ellipsified[i] = ellipsified[i].substr(0, available - remaining).padEnd(available, '.');
  370. remaining -= available;
  371. if (remaining <= 0) {
  372. break;
  373. }
  374. }
  375. return ellipsified;
  376. };
  377. AxisInternal.prototype.updateTickLength = function () {
  378. var internal = this;
  379. internal.tickLength = Math.max(internal.innerTickSize, 0) + internal.tickPadding;
  380. };
  381. AxisInternal.prototype.lineY2 = function (d) {
  382. var internal = this,
  383. tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);
  384. return internal.range[0] < tickPosition && tickPosition < internal.range[1] ? internal.innerTickSize : 0;
  385. };
  386. AxisInternal.prototype.textY = function () {
  387. var internal = this,
  388. rotate = internal.tickTextRotate;
  389. return rotate ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) : internal.tickLength;
  390. };
  391. AxisInternal.prototype.textTransform = function () {
  392. var internal = this,
  393. rotate = internal.tickTextRotate;
  394. return rotate ? "rotate(" + rotate + ")" : "";
  395. };
  396. AxisInternal.prototype.textTextAnchor = function () {
  397. var internal = this,
  398. rotate = internal.tickTextRotate;
  399. return rotate ? rotate > 0 ? "start" : "end" : "middle";
  400. };
  401. AxisInternal.prototype.tspanDx = function () {
  402. var internal = this,
  403. rotate = internal.tickTextRotate;
  404. return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0;
  405. };
  406. AxisInternal.prototype.tspanDy = function (d, i) {
  407. var internal = this,
  408. dy = internal.tickTextCharSize.h;
  409. if (i === 0) {
  410. if (internal.isVertical()) {
  411. dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);
  412. } else {
  413. dy = ".71em";
  414. }
  415. }
  416. return dy;
  417. };
  418. AxisInternal.prototype.generateAxis = function () {
  419. var internal = this,
  420. d3 = internal.d3,
  421. params = internal.params;
  422. function axis(g, transition) {
  423. var self;
  424. g.each(function () {
  425. var g = axis.g = d3.select(this);
  426. var scale0 = this.__chart__ || internal.scale,
  427. scale1 = this.__chart__ = internal.copyScale();
  428. var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1),
  429. ticks = g.selectAll(".tick").data(ticksValues, scale1),
  430. tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6),
  431. // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.
  432. tickExit = ticks.exit().remove(),
  433. tickUpdate = ticks.merge(tickEnter),
  434. tickTransform,
  435. tickX,
  436. tickY;
  437. if (params.isCategory) {
  438. internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
  439. tickX = internal.tickCentered ? 0 : internal.tickOffset;
  440. tickY = internal.tickCentered ? internal.tickOffset : 0;
  441. } else {
  442. internal.tickOffset = tickX = 0;
  443. }
  444. internal.updateRange();
  445. internal.updateTickLength();
  446. internal.updateTickTextCharSize(g.select('.tick'));
  447. var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")),
  448. textUpdate = tickUpdate.select("text").merge(tickEnter.append("text"));
  449. var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) {
  450. return internal.tspanData(d, i, scale1);
  451. }),
  452. tspanEnter = tspans.enter().append('tspan'),
  453. tspanUpdate = tspanEnter.merge(tspans).text(function (d) {
  454. return d.splitted;
  455. });
  456. tspans.exit().remove();
  457. var path = g.selectAll(".domain").data([0]),
  458. pathUpdate = path.enter().append("path").merge(path).attr("class", "domain"); // TODO: each attr should be one function and change its behavior by internal.orient, probably
  459. switch (internal.orient) {
  460. case "bottom":
  461. {
  462. tickTransform = internal.axisX;
  463. lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) {
  464. return internal.lineY2(d, i);
  465. });
  466. textUpdate.attr("x", 0).attr("y", function (d, i) {
  467. return internal.textY(d, i);
  468. }).attr("transform", function (d, i) {
  469. return internal.textTransform(d, i);
  470. }).style("text-anchor", function (d, i) {
  471. return internal.textTextAnchor(d, i);
  472. });
  473. tspanUpdate.attr('x', 0).attr("dy", function (d, i) {
  474. return internal.tspanDy(d, i);
  475. }).attr('dx', function (d, i) {
  476. return internal.tspanDx(d, i);
  477. });
  478. pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize);
  479. break;
  480. }
  481. case "top":
  482. {
  483. // TODO: rotated tick text
  484. tickTransform = internal.axisX;
  485. lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) {
  486. return -1 * internal.lineY2(d, i);
  487. });
  488. textUpdate.attr("x", 0).attr("y", function (d, i) {
  489. return -1 * internal.textY(d, i) - (params.isCategory ? 2 : internal.tickLength - 2);
  490. }).attr("transform", function (d, i) {
  491. return internal.textTransform(d, i);
  492. }).style("text-anchor", function (d, i) {
  493. return internal.textTextAnchor(d, i);
  494. });
  495. tspanUpdate.attr('x', 0).attr("dy", function (d, i) {
  496. return internal.tspanDy(d, i);
  497. }).attr('dx', function (d, i) {
  498. return internal.tspanDx(d, i);
  499. });
  500. pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize);
  501. break;
  502. }
  503. case "left":
  504. {
  505. tickTransform = internal.axisY;
  506. lineUpdate.attr("x2", -internal.innerTickSize).attr("y1", tickY).attr("y2", tickY);
  507. textUpdate.attr("x", -internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "end");
  508. tspanUpdate.attr('x', -internal.tickLength).attr("dy", function (d, i) {
  509. return internal.tspanDy(d, i);
  510. });
  511. pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize);
  512. break;
  513. }
  514. case "right":
  515. {
  516. tickTransform = internal.axisY;
  517. lineUpdate.attr("x2", internal.innerTickSize).attr("y1", tickY).attr("y2", tickY);
  518. textUpdate.attr("x", internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "start");
  519. tspanUpdate.attr('x', internal.tickLength).attr("dy", function (d, i) {
  520. return internal.tspanDy(d, i);
  521. });
  522. pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize);
  523. break;
  524. }
  525. }
  526. if (scale1.rangeBand) {
  527. var x = scale1,
  528. dx = x.rangeBand() / 2;
  529. scale0 = scale1 = function scale1(d) {
  530. return x(d) + dx;
  531. };
  532. } else if (scale0.rangeBand) {
  533. scale0 = scale1;
  534. } else {
  535. tickExit.call(tickTransform, scale1, internal.tickOffset);
  536. }
  537. tickEnter.call(tickTransform, scale0, internal.tickOffset);
  538. self = (transition ? tickUpdate.transition(transition) : tickUpdate).style('opacity', 1).call(tickTransform, scale1, internal.tickOffset);
  539. });
  540. return self;
  541. }
  542. axis.scale = function (x) {
  543. if (!arguments.length) {
  544. return internal.scale;
  545. }
  546. internal.scale = x;
  547. return axis;
  548. };
  549. axis.orient = function (x) {
  550. if (!arguments.length) {
  551. return internal.orient;
  552. }
  553. internal.orient = x in {
  554. top: 1,
  555. right: 1,
  556. bottom: 1,
  557. left: 1
  558. } ? x + "" : "bottom";
  559. return axis;
  560. };
  561. axis.tickFormat = function (format) {
  562. if (!arguments.length) {
  563. return internal.tickFormat;
  564. }
  565. internal.tickFormat = format;
  566. return axis;
  567. };
  568. axis.tickCentered = function (isCentered) {
  569. if (!arguments.length) {
  570. return internal.tickCentered;
  571. }
  572. internal.tickCentered = isCentered;
  573. return axis;
  574. };
  575. axis.tickOffset = function () {
  576. return internal.tickOffset;
  577. };
  578. axis.tickInterval = function () {
  579. var interval, length;
  580. if (params.isCategory) {
  581. interval = internal.tickOffset * 2;
  582. } else {
  583. length = axis.g.select('path.domain').node().getTotalLength() - internal.outerTickSize * 2;
  584. interval = length / axis.g.selectAll('line').size();
  585. }
  586. return interval === Infinity ? 0 : interval;
  587. };
  588. axis.ticks = function () {
  589. if (!arguments.length) {
  590. return internal.tickArguments;
  591. }
  592. internal.tickArguments = arguments;
  593. return axis;
  594. };
  595. axis.tickCulling = function (culling) {
  596. if (!arguments.length) {
  597. return internal.tickCulling;
  598. }
  599. internal.tickCulling = culling;
  600. return axis;
  601. };
  602. axis.tickValues = function (x) {
  603. if (typeof x === 'function') {
  604. internal.tickValues = function () {
  605. return x(internal.scale.domain());
  606. };
  607. } else {
  608. if (!arguments.length) {
  609. return internal.tickValues;
  610. }
  611. internal.tickValues = x;
  612. }
  613. return axis;
  614. };
  615. return axis;
  616. };
  617. var CLASS = {
  618. target: 'c3-target',
  619. chart: 'c3-chart',
  620. chartLine: 'c3-chart-line',
  621. chartLines: 'c3-chart-lines',
  622. chartBar: 'c3-chart-bar',
  623. chartBars: 'c3-chart-bars',
  624. chartText: 'c3-chart-text',
  625. chartTexts: 'c3-chart-texts',
  626. chartArc: 'c3-chart-arc',
  627. chartArcs: 'c3-chart-arcs',
  628. chartArcsTitle: 'c3-chart-arcs-title',
  629. chartArcsBackground: 'c3-chart-arcs-background',
  630. chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',
  631. chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',
  632. chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',
  633. selectedCircle: 'c3-selected-circle',
  634. selectedCircles: 'c3-selected-circles',
  635. eventRect: 'c3-event-rect',
  636. eventRects: 'c3-event-rects',
  637. eventRectsSingle: 'c3-event-rects-single',
  638. eventRectsMultiple: 'c3-event-rects-multiple',
  639. zoomRect: 'c3-zoom-rect',
  640. brush: 'c3-brush',
  641. dragZoom: 'c3-drag-zoom',
  642. focused: 'c3-focused',
  643. defocused: 'c3-defocused',
  644. region: 'c3-region',
  645. regions: 'c3-regions',
  646. title: 'c3-title',
  647. tooltipContainer: 'c3-tooltip-container',
  648. tooltip: 'c3-tooltip',
  649. tooltipName: 'c3-tooltip-name',
  650. shape: 'c3-shape',
  651. shapes: 'c3-shapes',
  652. line: 'c3-line',
  653. lines: 'c3-lines',
  654. bar: 'c3-bar',
  655. bars: 'c3-bars',
  656. circle: 'c3-circle',
  657. circles: 'c3-circles',
  658. arc: 'c3-arc',
  659. arcLabelLine: 'c3-arc-label-line',
  660. arcs: 'c3-arcs',
  661. area: 'c3-area',
  662. areas: 'c3-areas',
  663. empty: 'c3-empty',
  664. text: 'c3-text',
  665. texts: 'c3-texts',
  666. gaugeValue: 'c3-gauge-value',
  667. grid: 'c3-grid',
  668. gridLines: 'c3-grid-lines',
  669. xgrid: 'c3-xgrid',
  670. xgrids: 'c3-xgrids',
  671. xgridLine: 'c3-xgrid-line',
  672. xgridLines: 'c3-xgrid-lines',
  673. xgridFocus: 'c3-xgrid-focus',
  674. ygrid: 'c3-ygrid',
  675. ygrids: 'c3-ygrids',
  676. ygridLine: 'c3-ygrid-line',
  677. ygridLines: 'c3-ygrid-lines',
  678. colorScale: 'c3-colorscale',
  679. stanfordElements: 'c3-stanford-elements',
  680. stanfordLine: 'c3-stanford-line',
  681. stanfordLines: 'c3-stanford-lines',
  682. stanfordRegion: 'c3-stanford-region',
  683. stanfordRegions: 'c3-stanford-regions',
  684. stanfordText: 'c3-stanford-text',
  685. stanfordTexts: 'c3-stanford-texts',
  686. axis: 'c3-axis',
  687. axisX: 'c3-axis-x',
  688. axisXLabel: 'c3-axis-x-label',
  689. axisY: 'c3-axis-y',
  690. axisYLabel: 'c3-axis-y-label',
  691. axisY2: 'c3-axis-y2',
  692. axisY2Label: 'c3-axis-y2-label',
  693. legendBackground: 'c3-legend-background',
  694. legendItem: 'c3-legend-item',
  695. legendItemEvent: 'c3-legend-item-event',
  696. legendItemTile: 'c3-legend-item-tile',
  697. legendItemHidden: 'c3-legend-item-hidden',
  698. legendItemFocused: 'c3-legend-item-focused',
  699. dragarea: 'c3-dragarea',
  700. EXPANDED: '_expanded_',
  701. SELECTED: '_selected_',
  702. INCLUDED: '_included_'
  703. };
  704. var Axis = function Axis(owner) {
  705. _classCallCheck(this, Axis);
  706. this.owner = owner;
  707. this.d3 = owner.d3;
  708. this.internal = AxisInternal;
  709. };
  710. Axis.prototype.init = function init() {
  711. var $$ = this.owner,
  712. config = $$.config,
  713. main = $$.main;
  714. $$.axes.x = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisX).attr("clip-path", config.axis_x_inner ? "" : $$.clipPathForXAxis).attr("transform", $$.getTranslate('x')).style("visibility", config.axis_x_show ? 'visible' : 'hidden');
  715. $$.axes.x.append("text").attr("class", CLASS.axisXLabel).attr("transform", config.axis_rotated ? "rotate(-90)" : "").style("text-anchor", this.textAnchorForXAxisLabel.bind(this));
  716. $$.axes.y = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY).attr("clip-path", config.axis_y_inner ? "" : $$.clipPathForYAxis).attr("transform", $$.getTranslate('y')).style("visibility", config.axis_y_show ? 'visible' : 'hidden');
  717. $$.axes.y.append("text").attr("class", CLASS.axisYLabel).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForYAxisLabel.bind(this));
  718. $$.axes.y2 = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY2) // clip-path?
  719. .attr("transform", $$.getTranslate('y2')).style("visibility", config.axis_y2_show ? 'visible' : 'hidden');
  720. $$.axes.y2.append("text").attr("class", CLASS.axisY2Label).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForY2AxisLabel.bind(this));
  721. };
  722. Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  723. var $$ = this.owner,
  724. config = $$.config,
  725. axisParams = {
  726. isCategory: $$.isCategorized(),
  727. withOuterTick: withOuterTick,
  728. tickMultiline: config.axis_x_tick_multiline,
  729. tickMultilineMax: config.axis_x_tick_multiline ? Number(config.axis_x_tick_multilineMax) : 0,
  730. tickWidth: config.axis_x_tick_width,
  731. tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,
  732. withoutTransition: withoutTransition
  733. },
  734. axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);
  735. if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") {
  736. tickValues = tickValues.map(function (v) {
  737. return $$.parseDate(v);
  738. });
  739. } // Set tick
  740. axis.tickFormat(tickFormat).tickValues(tickValues);
  741. if ($$.isCategorized()) {
  742. axis.tickCentered(config.axis_x_tick_centered);
  743. if (isEmpty(config.axis_x_tick_culling)) {
  744. config.axis_x_tick_culling = false;
  745. }
  746. }
  747. return axis;
  748. };
  749. Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) {
  750. var $$ = this.owner,
  751. config = $$.config,
  752. tickValues;
  753. if (config.axis_x_tick_fit || config.axis_x_tick_count) {
  754. tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries());
  755. }
  756. if (axis) {
  757. axis.tickValues(tickValues);
  758. } else {
  759. $$.xAxis.tickValues(tickValues);
  760. $$.subXAxis.tickValues(tickValues);
  761. }
  762. return tickValues;
  763. };
  764. Axis.prototype.getYAxis = function getYAxis(axisId, scale, orient, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  765. var $$ = this.owner;
  766. var config = $$.config;
  767. var tickFormat = config["axis_".concat(axisId, "_tick_format")];
  768. if (!tickFormat && $$.isAxisNormalized(axisId)) {
  769. tickFormat = function tickFormat(x) {
  770. return "".concat(x, "%");
  771. };
  772. }
  773. var axis = new this.internal(this, {
  774. withOuterTick: withOuterTick,
  775. withoutTransition: withoutTransition,
  776. tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate
  777. }).axis.scale(scale).orient(orient);
  778. if (tickFormat) {
  779. axis.tickFormat(tickFormat);
  780. }
  781. if ($$.isTimeSeriesY()) {
  782. axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);
  783. } else {
  784. axis.tickValues(tickValues);
  785. }
  786. return axis;
  787. };
  788. Axis.prototype.getId = function getId(id) {
  789. var config = this.owner.config;
  790. return id in config.data_axes ? config.data_axes[id] : 'y';
  791. };
  792. Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {
  793. // #2251 previously set any negative values to a whole number,
  794. // however both should be truncated according to the users format specification
  795. var $$ = this.owner,
  796. config = $$.config;
  797. var format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) {
  798. return v;
  799. };
  800. if (config.axis_x_tick_format) {
  801. if (isFunction(config.axis_x_tick_format)) {
  802. format = config.axis_x_tick_format;
  803. } else if ($$.isTimeSeries()) {
  804. format = function format(date) {
  805. return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : "";
  806. };
  807. }
  808. }
  809. return isFunction(format) ? function (v) {
  810. return format.call($$, v);
  811. } : format;
  812. };
  813. Axis.prototype.getTickValues = function getTickValues(tickValues, axis) {
  814. return tickValues ? tickValues : axis ? axis.tickValues() : undefined;
  815. };
  816. Axis.prototype.getXAxisTickValues = function getXAxisTickValues() {
  817. return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis);
  818. };
  819. Axis.prototype.getYAxisTickValues = function getYAxisTickValues() {
  820. return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis);
  821. };
  822. Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {
  823. return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis);
  824. };
  825. Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) {
  826. var $$ = this.owner,
  827. config = $$.config,
  828. option;
  829. if (axisId === 'y') {
  830. option = config.axis_y_label;
  831. } else if (axisId === 'y2') {
  832. option = config.axis_y2_label;
  833. } else if (axisId === 'x') {
  834. option = config.axis_x_label;
  835. }
  836. return option;
  837. };
  838. Axis.prototype.getLabelText = function getLabelText(axisId) {
  839. var option = this.getLabelOptionByAxisId(axisId);
  840. return isString(option) ? option : option ? option.text : null;
  841. };
  842. Axis.prototype.setLabelText = function setLabelText(axisId, text) {
  843. var $$ = this.owner,
  844. config = $$.config,
  845. option = this.getLabelOptionByAxisId(axisId);
  846. if (isString(option)) {
  847. if (axisId === 'y') {
  848. config.axis_y_label = text;
  849. } else if (axisId === 'y2') {
  850. config.axis_y2_label = text;
  851. } else if (axisId === 'x') {
  852. config.axis_x_label = text;
  853. }
  854. } else if (option) {
  855. option.text = text;
  856. }
  857. };
  858. Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) {
  859. var option = this.getLabelOptionByAxisId(axisId),
  860. position = option && _typeof(option) === 'object' && option.position ? option.position : defaultPosition;
  861. return {
  862. isInner: position.indexOf('inner') >= 0,
  863. isOuter: position.indexOf('outer') >= 0,
  864. isLeft: position.indexOf('left') >= 0,
  865. isCenter: position.indexOf('center') >= 0,
  866. isRight: position.indexOf('right') >= 0,
  867. isTop: position.indexOf('top') >= 0,
  868. isMiddle: position.indexOf('middle') >= 0,
  869. isBottom: position.indexOf('bottom') >= 0
  870. };
  871. };
  872. Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {
  873. return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right');
  874. };
  875. Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {
  876. return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  877. };
  878. Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {
  879. return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  880. };
  881. Axis.prototype.getLabelPositionById = function getLabelPositionById(id) {
  882. return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition();
  883. };
  884. Axis.prototype.textForXAxisLabel = function textForXAxisLabel() {
  885. return this.getLabelText('x');
  886. };
  887. Axis.prototype.textForYAxisLabel = function textForYAxisLabel() {
  888. return this.getLabelText('y');
  889. };
  890. Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {
  891. return this.getLabelText('y2');
  892. };
  893. Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {
  894. var $$ = this.owner;
  895. if (forHorizontal) {
  896. return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;
  897. } else {
  898. return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0;
  899. }
  900. };
  901. Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) {
  902. if (forHorizontal) {
  903. return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0";
  904. } else {
  905. return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0";
  906. }
  907. };
  908. Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) {
  909. if (forHorizontal) {
  910. return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';
  911. } else {
  912. return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';
  913. }
  914. };
  915. Axis.prototype.xForXAxisLabel = function xForXAxisLabel() {
  916. return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  917. };
  918. Axis.prototype.xForYAxisLabel = function xForYAxisLabel() {
  919. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  920. };
  921. Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {
  922. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  923. };
  924. Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {
  925. return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  926. };
  927. Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {
  928. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  929. };
  930. Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {
  931. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  932. };
  933. Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {
  934. var $$ = this.owner,
  935. config = $$.config,
  936. position = this.getXAxisLabelPosition();
  937. if (config.axis_rotated) {
  938. return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'));
  939. } else {
  940. return position.isInner ? "-0.5em" : $$.getHorizontalAxisHeight('x') - 10;
  941. }
  942. };
  943. Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {
  944. var $$ = this.owner,
  945. position = this.getYAxisLabelPosition();
  946. if ($$.config.axis_rotated) {
  947. return position.isInner ? "-0.5em" : "3em";
  948. } else {
  949. return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10);
  950. }
  951. };
  952. Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {
  953. var $$ = this.owner,
  954. position = this.getY2AxisLabelPosition();
  955. if ($$.config.axis_rotated) {
  956. return position.isInner ? "1.2em" : "-2.2em";
  957. } else {
  958. return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15);
  959. }
  960. };
  961. Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {
  962. var $$ = this.owner;
  963. return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition());
  964. };
  965. Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {
  966. var $$ = this.owner;
  967. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition());
  968. };
  969. Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {
  970. var $$ = this.owner;
  971. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition());
  972. };
  973. Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) {
  974. var $$ = this.owner,
  975. maxWidth = 0,
  976. targetsToShow,
  977. scale,
  978. axis,
  979. dummy,
  980. svg;
  981. if (withoutRecompute && $$.currentMaxTickWidths[id]) {
  982. return $$.currentMaxTickWidths[id];
  983. }
  984. if ($$.svg) {
  985. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  986. if (id === 'y') {
  987. scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
  988. axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true);
  989. } else if (id === 'y2') {
  990. scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
  991. axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true);
  992. } else {
  993. scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
  994. axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);
  995. this.updateXAxisTickValues(targetsToShow, axis);
  996. }
  997. dummy = $$.d3.select('body').append('div').classed('c3', true);
  998. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () {
  999. $$.d3.select(this).selectAll('text').each(function () {
  1000. var box = getBBox(this);
  1001. if (maxWidth < box.width) {
  1002. maxWidth = box.width;
  1003. }
  1004. });
  1005. dummy.remove();
  1006. });
  1007. }
  1008. $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;
  1009. return $$.currentMaxTickWidths[id];
  1010. };
  1011. Axis.prototype.updateLabels = function updateLabels(withTransition) {
  1012. var $$ = this.owner;
  1013. var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),
  1014. axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),
  1015. axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label);
  1016. (withTransition ? axisXLabel.transition() : axisXLabel).attr("x", this.xForXAxisLabel.bind(this)).attr("dx", this.dxForXAxisLabel.bind(this)).attr("dy", this.dyForXAxisLabel.bind(this)).text(this.textForXAxisLabel.bind(this));
  1017. (withTransition ? axisYLabel.transition() : axisYLabel).attr("x", this.xForYAxisLabel.bind(this)).attr("dx", this.dxForYAxisLabel.bind(this)).attr("dy", this.dyForYAxisLabel.bind(this)).text(this.textForYAxisLabel.bind(this));
  1018. (withTransition ? axisY2Label.transition() : axisY2Label).attr("x", this.xForY2AxisLabel.bind(this)).attr("dx", this.dxForY2AxisLabel.bind(this)).attr("dy", this.dyForY2AxisLabel.bind(this)).text(this.textForY2AxisLabel.bind(this));
  1019. };
  1020. Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) {
  1021. var p = typeof padding === 'number' ? padding : padding[key];
  1022. if (!isValue(p)) {
  1023. return defaultValue;
  1024. }
  1025. if (padding.unit === 'ratio') {
  1026. return padding[key] * domainLength;
  1027. } // assume padding is pixels if unit is not specified
  1028. return this.convertPixelsToAxisPadding(p, domainLength);
  1029. };
  1030. Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) {
  1031. var $$ = this.owner,
  1032. length = $$.config.axis_rotated ? $$.width : $$.height;
  1033. return domainLength * (pixels / length);
  1034. };
  1035. Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) {
  1036. var tickValues = values,
  1037. targetCount,
  1038. start,
  1039. end,
  1040. count,
  1041. interval,
  1042. i,
  1043. tickValue;
  1044. if (tickCount) {
  1045. targetCount = isFunction(tickCount) ? tickCount() : tickCount; // compute ticks according to tickCount
  1046. if (targetCount === 1) {
  1047. tickValues = [values[0]];
  1048. } else if (targetCount === 2) {
  1049. tickValues = [values[0], values[values.length - 1]];
  1050. } else if (targetCount > 2) {
  1051. count = targetCount - 2;
  1052. start = values[0];
  1053. end = values[values.length - 1];
  1054. interval = (end - start) / (count + 1); // re-construct unique values
  1055. tickValues = [start];
  1056. for (i = 0; i < count; i++) {
  1057. tickValue = +start + interval * (i + 1);
  1058. tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);
  1059. }
  1060. tickValues.push(end);
  1061. }
  1062. }
  1063. if (!forTimeSeries) {
  1064. tickValues = tickValues.sort(function (a, b) {
  1065. return a - b;
  1066. });
  1067. }
  1068. return tickValues;
  1069. };
  1070. Axis.prototype.generateTransitions = function generateTransitions(duration) {
  1071. var $$ = this.owner,
  1072. axes = $$.axes;
  1073. return {
  1074. axisX: duration ? axes.x.transition().duration(duration) : axes.x,
  1075. axisY: duration ? axes.y.transition().duration(duration) : axes.y,
  1076. axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,
  1077. axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx
  1078. };
  1079. };
  1080. Axis.prototype.redraw = function redraw(duration, isHidden) {
  1081. var $$ = this.owner,
  1082. transition = duration ? $$.d3.transition().duration(duration) : null;
  1083. $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition);
  1084. $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition);
  1085. $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition);
  1086. $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition);
  1087. };
  1088. var c3 = {
  1089. version: "0.7.15",
  1090. chart: {
  1091. fn: Chart.prototype,
  1092. internal: {
  1093. fn: ChartInternal.prototype,
  1094. axis: {
  1095. fn: Axis.prototype,
  1096. internal: {
  1097. fn: AxisInternal.prototype
  1098. }
  1099. }
  1100. }
  1101. },
  1102. generate: function generate(config) {
  1103. return new Chart(config);
  1104. }
  1105. };
  1106. ChartInternal.prototype.beforeInit = function () {// can do something
  1107. };
  1108. ChartInternal.prototype.afterInit = function () {// can do something
  1109. };
  1110. ChartInternal.prototype.init = function () {
  1111. var $$ = this,
  1112. config = $$.config;
  1113. $$.initParams();
  1114. if (config.data_url) {
  1115. $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);
  1116. } else if (config.data_json) {
  1117. $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
  1118. } else if (config.data_rows) {
  1119. $$.initWithData($$.convertRowsToData(config.data_rows));
  1120. } else if (config.data_columns) {
  1121. $$.initWithData($$.convertColumnsToData(config.data_columns));
  1122. } else {
  1123. throw Error('url or json or rows or columns is required.');
  1124. }
  1125. };
  1126. ChartInternal.prototype.initParams = function () {
  1127. var $$ = this,
  1128. d3 = $$.d3,
  1129. config = $$.config; // MEMO: clipId needs to be unique because it conflicts when multiple charts exist
  1130. $$.clipId = "c3-" + +new Date() + '-clip';
  1131. $$.clipIdForXAxis = $$.clipId + '-xaxis';
  1132. $$.clipIdForYAxis = $$.clipId + '-yaxis';
  1133. $$.clipIdForGrid = $$.clipId + '-grid';
  1134. $$.clipIdForSubchart = $$.clipId + '-subchart';
  1135. $$.clipPath = $$.getClipPath($$.clipId);
  1136. $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis);
  1137. $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
  1138. $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid);
  1139. $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart);
  1140. $$.dragStart = null;
  1141. $$.dragging = false;
  1142. $$.flowing = false;
  1143. $$.cancelClick = false;
  1144. $$.mouseover = undefined;
  1145. $$.transiting = false;
  1146. $$.color = $$.generateColor();
  1147. $$.levelColor = $$.generateLevelColor();
  1148. $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat);
  1149. $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;
  1150. $$.defaultAxisTimeFormat = function (date) {
  1151. if (date.getMilliseconds()) {
  1152. return d3.timeFormat(".%L")(date);
  1153. }
  1154. if (date.getSeconds()) {
  1155. return d3.timeFormat(":%S")(date);
  1156. }
  1157. if (date.getMinutes()) {
  1158. return d3.timeFormat("%I:%M")(date);
  1159. }
  1160. if (date.getHours()) {
  1161. return d3.timeFormat("%I %p")(date);
  1162. }
  1163. if (date.getDay() && date.getDate() !== 1) {
  1164. return d3.timeFormat("%-m/%-d")(date);
  1165. }
  1166. if (date.getDate() !== 1) {
  1167. return d3.timeFormat("%-m/%-d")(date);
  1168. }
  1169. if (date.getMonth()) {
  1170. return d3.timeFormat("%-m/%-d")(date);
  1171. }
  1172. return d3.timeFormat("%Y/%-m/%-d")(date);
  1173. };
  1174. $$.hiddenTargetIds = [];
  1175. $$.hiddenLegendIds = [];
  1176. $$.focusedTargetIds = [];
  1177. $$.defocusedTargetIds = [];
  1178. $$.xOrient = config.axis_rotated ? config.axis_x_inner ? "right" : "left" : config.axis_x_inner ? "top" : "bottom";
  1179. $$.yOrient = config.axis_rotated ? config.axis_y_inner ? "top" : "bottom" : config.axis_y_inner ? "right" : "left";
  1180. $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? "bottom" : "top" : config.axis_y2_inner ? "left" : "right";
  1181. $$.subXOrient = config.axis_rotated ? "left" : "bottom";
  1182. $$.isLegendRight = config.legend_position === 'right';
  1183. $$.isLegendInset = config.legend_position === 'inset';
  1184. $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right';
  1185. $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left';
  1186. $$.legendStep = 0;
  1187. $$.legendItemWidth = 0;
  1188. $$.legendItemHeight = 0;
  1189. $$.currentMaxTickWidths = {
  1190. x: 0,
  1191. y: 0,
  1192. y2: 0
  1193. };
  1194. $$.rotated_padding_left = 30;
  1195. $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;
  1196. $$.rotated_padding_top = 5;
  1197. $$.withoutFadeIn = {};
  1198. $$.intervalForObserveInserted = undefined;
  1199. $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
  1200. };
  1201. ChartInternal.prototype.initChartElements = function () {
  1202. if (this.initBar) {
  1203. this.initBar();
  1204. }
  1205. if (this.initLine) {
  1206. this.initLine();
  1207. }
  1208. if (this.initArc) {
  1209. this.initArc();
  1210. }
  1211. if (this.initGauge) {
  1212. this.initGauge();
  1213. }
  1214. if (this.initText) {
  1215. this.initText();
  1216. }
  1217. };
  1218. ChartInternal.prototype.initWithData = function (data) {
  1219. var $$ = this,
  1220. d3 = $$.d3,
  1221. config = $$.config;
  1222. var defs,
  1223. main,
  1224. binding = true;
  1225. $$.axis = new Axis($$);
  1226. if (!config.bindto) {
  1227. $$.selectChart = d3.selectAll([]);
  1228. } else if (typeof config.bindto.node === 'function') {
  1229. $$.selectChart = config.bindto;
  1230. } else {
  1231. $$.selectChart = d3.select(config.bindto);
  1232. }
  1233. if ($$.selectChart.empty()) {
  1234. $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0);
  1235. $$.observeInserted($$.selectChart);
  1236. binding = false;
  1237. }
  1238. $$.selectChart.html("").classed("c3", true); // Init data as targets
  1239. $$.data.xs = {};
  1240. $$.data.targets = $$.convertDataToTargets(data);
  1241. if (config.data_filter) {
  1242. $$.data.targets = $$.data.targets.filter(config.data_filter);
  1243. } // Set targets to hide if needed
  1244. if (config.data_hide) {
  1245. $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide);
  1246. }
  1247. if (config.legend_hide) {
  1248. $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide);
  1249. }
  1250. if ($$.isStanfordGraphType()) {
  1251. $$.initStanfordData();
  1252. } // Init sizes and scales
  1253. $$.updateSizes();
  1254. $$.updateScales(); // Set domains for each scale
  1255. $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));
  1256. $$.y.domain($$.getYDomain($$.data.targets, 'y'));
  1257. $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));
  1258. $$.subX.domain($$.x.domain());
  1259. $$.subY.domain($$.y.domain());
  1260. $$.subY2.domain($$.y2.domain()); // Save original x domain for zoom update
  1261. $$.orgXDomain = $$.x.domain();
  1262. /*-- Basic Elements --*/
  1263. // Define svgs
  1264. $$.svg = $$.selectChart.append("svg").style("overflow", "hidden").on('mouseenter', function () {
  1265. return config.onmouseover.call($$);
  1266. }).on('mouseleave', function () {
  1267. return config.onmouseout.call($$);
  1268. });
  1269. if ($$.config.svg_classname) {
  1270. $$.svg.attr('class', $$.config.svg_classname);
  1271. } // Define defs
  1272. defs = $$.svg.append("defs");
  1273. $$.clipChart = $$.appendClip(defs, $$.clipId);
  1274. $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);
  1275. $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);
  1276. $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);
  1277. $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);
  1278. $$.updateSvgSize(); // Define regions
  1279. main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main'));
  1280. if ($$.initPie) {
  1281. $$.initPie();
  1282. }
  1283. if ($$.initDragZoom) {
  1284. $$.initDragZoom();
  1285. }
  1286. if (config.subchart_show && $$.initSubchart) {
  1287. $$.initSubchart();
  1288. }
  1289. if ($$.initTooltip) {
  1290. $$.initTooltip();
  1291. }
  1292. if ($$.initLegend) {
  1293. $$.initLegend();
  1294. }
  1295. if ($$.initTitle) {
  1296. $$.initTitle();
  1297. }
  1298. if ($$.initZoom) {
  1299. $$.initZoom();
  1300. }
  1301. if ($$.isStanfordGraphType()) {
  1302. $$.drawColorScale();
  1303. } // Update selection based on size and scale
  1304. // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.
  1305. if (config.subchart_show && $$.initSubchartBrush) {
  1306. $$.initSubchartBrush();
  1307. }
  1308. /*-- Main Region --*/
  1309. // text when empty
  1310. main.append("text").attr("class", CLASS.text + ' ' + CLASS.empty).attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers.
  1311. .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE.
  1312. // Regions
  1313. $$.initRegion(); // Grids
  1314. $$.initGrid(); // Define g for chart area
  1315. main.append('g').attr("clip-path", $$.clipPath).attr('class', CLASS.chart); // Grid lines
  1316. if (config.grid_lines_front) {
  1317. $$.initGridLines();
  1318. }
  1319. $$.initStanfordElements(); // Cover whole with rects for events
  1320. $$.initEventRect(); // Define g for chart
  1321. $$.initChartElements(); // Add Axis
  1322. $$.axis.init(); // Set targets
  1323. $$.updateTargets($$.data.targets); // Set default extent if defined
  1324. if (config.axis_x_selection) {
  1325. $$.brush.selectionAsValue($$.getDefaultSelection());
  1326. } // Draw with targets
  1327. if (binding) {
  1328. $$.updateDimension();
  1329. $$.config.oninit.call($$);
  1330. $$.redraw({
  1331. withTransition: false,
  1332. withTransform: true,
  1333. withUpdateXDomain: true,
  1334. withUpdateOrgXDomain: true,
  1335. withTransitionForAxis: false
  1336. });
  1337. } // Bind to resize event
  1338. $$.bindResize(); // Bind to window focus event
  1339. $$.bindWindowFocus(); // export element of the chart
  1340. $$.api.element = $$.selectChart.node();
  1341. };
  1342. ChartInternal.prototype.smoothLines = function (el, type) {
  1343. var $$ = this;
  1344. if (type === 'grid') {
  1345. el.each(function () {
  1346. var g = $$.d3.select(this),
  1347. x1 = g.attr('x1'),
  1348. x2 = g.attr('x2'),
  1349. y1 = g.attr('y1'),
  1350. y2 = g.attr('y2');
  1351. g.attr({
  1352. 'x1': Math.ceil(x1),
  1353. 'x2': Math.ceil(x2),
  1354. 'y1': Math.ceil(y1),
  1355. 'y2': Math.ceil(y2)
  1356. });
  1357. });
  1358. }
  1359. };
  1360. ChartInternal.prototype.updateSizes = function () {
  1361. var $$ = this,
  1362. config = $$.config;
  1363. var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
  1364. legendWidth = $$.legend ? $$.getLegendWidth() : 0,
  1365. legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
  1366. hasArc = $$.hasArcType(),
  1367. xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),
  1368. subchartHeight = config.subchart_show && !hasArc ? config.subchart_size_height + xAxisHeight : 0;
  1369. $$.currentWidth = $$.getCurrentWidth();
  1370. $$.currentHeight = $$.getCurrentHeight(); // for main
  1371. $$.margin = config.axis_rotated ? {
  1372. top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),
  1373. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1374. bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1375. left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())
  1376. } : {
  1377. top: 4 + $$.getCurrentPaddingTop(),
  1378. // for top tick text
  1379. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1380. bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1381. left: hasArc ? 0 : $$.getCurrentPaddingLeft()
  1382. }; // for subchart
  1383. $$.margin2 = config.axis_rotated ? {
  1384. top: $$.margin.top,
  1385. right: NaN,
  1386. bottom: 20 + legendHeightForBottom,
  1387. left: $$.rotated_padding_left
  1388. } : {
  1389. top: $$.currentHeight - subchartHeight - legendHeightForBottom,
  1390. right: NaN,
  1391. bottom: xAxisHeight + legendHeightForBottom,
  1392. left: $$.margin.left
  1393. }; // for legend
  1394. $$.margin3 = {
  1395. top: 0,
  1396. right: NaN,
  1397. bottom: 0,
  1398. left: 0
  1399. };
  1400. if ($$.updateSizeForLegend) {
  1401. $$.updateSizeForLegend(legendHeight, legendWidth);
  1402. }
  1403. $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;
  1404. $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;
  1405. if ($$.width < 0) {
  1406. $$.width = 0;
  1407. }
  1408. if ($$.height < 0) {
  1409. $$.height = 0;
  1410. }
  1411. $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width;
  1412. $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;
  1413. if ($$.width2 < 0) {
  1414. $$.width2 = 0;
  1415. }
  1416. if ($$.height2 < 0) {
  1417. $$.height2 = 0;
  1418. } // for arc
  1419. $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
  1420. $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
  1421. if ($$.hasType('gauge') && !config.gauge_fullCircle) {
  1422. $$.arcHeight += $$.height - $$.getGaugeLabelHeight();
  1423. }
  1424. if ($$.updateRadius) {
  1425. $$.updateRadius();
  1426. }
  1427. if ($$.isLegendRight && hasArc) {
  1428. $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;
  1429. }
  1430. };
  1431. ChartInternal.prototype.updateTargets = function (targets) {
  1432. var $$ = this,
  1433. config = $$.config;
  1434. /*-- Main --*/
  1435. //-- Text --//
  1436. $$.updateTargetsForText(targets); //-- Bar --//
  1437. $$.updateTargetsForBar(targets); //-- Line --//
  1438. $$.updateTargetsForLine(targets); //-- Arc --//
  1439. if ($$.hasArcType() && $$.updateTargetsForArc) {
  1440. $$.updateTargetsForArc(targets);
  1441. }
  1442. /*-- Sub --*/
  1443. if (config.subchart_show && $$.updateTargetsForSubchart) {
  1444. $$.updateTargetsForSubchart(targets);
  1445. } // Fade-in each chart
  1446. $$.showTargets();
  1447. };
  1448. ChartInternal.prototype.showTargets = function () {
  1449. var $$ = this;
  1450. $$.svg.selectAll('.' + CLASS.target).filter(function (d) {
  1451. return $$.isTargetToShow(d.id);
  1452. }).transition().duration($$.config.transition_duration).style("opacity", 1);
  1453. };
  1454. ChartInternal.prototype.redraw = function (options, transitions) {
  1455. var $$ = this,
  1456. main = $$.main,
  1457. d3 = $$.d3,
  1458. config = $$.config;
  1459. var areaIndices = $$.getShapeIndices($$.isAreaType),
  1460. barIndices = $$.getShapeIndices($$.isBarType),
  1461. lineIndices = $$.getShapeIndices($$.isLineType);
  1462. var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, withEventRect, withDimension, withUpdateXAxis;
  1463. var hideAxis = $$.hasArcType();
  1464. var drawArea, drawBar, drawLine, xForText, yForText;
  1465. var duration, durationForExit, durationForAxis;
  1466. var transitionsToWait, waitForDraw, flow, transition;
  1467. var targetsToShow = $$.filterTargetsToShow($$.data.targets),
  1468. tickValues,
  1469. i,
  1470. intervalForCulling,
  1471. xDomainForZoom;
  1472. var xv = $$.xv.bind($$),
  1473. cx,
  1474. cy;
  1475. options = options || {};
  1476. withY = getOption(options, "withY", true);
  1477. withSubchart = getOption(options, "withSubchart", true);
  1478. withTransition = getOption(options, "withTransition", true);
  1479. withTransform = getOption(options, "withTransform", false);
  1480. withUpdateXDomain = getOption(options, "withUpdateXDomain", false);
  1481. withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false);
  1482. withTrimXDomain = getOption(options, "withTrimXDomain", true);
  1483. withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain);
  1484. withLegend = getOption(options, "withLegend", false);
  1485. withEventRect = getOption(options, "withEventRect", true);
  1486. withDimension = getOption(options, "withDimension", true);
  1487. withTransitionForExit = getOption(options, "withTransitionForExit", withTransition);
  1488. withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition);
  1489. duration = withTransition ? config.transition_duration : 0;
  1490. durationForExit = withTransitionForExit ? duration : 0;
  1491. durationForAxis = withTransitionForAxis ? duration : 0;
  1492. transitions = transitions || $$.axis.generateTransitions(durationForAxis); // update legend and transform each g
  1493. if (withLegend && config.legend_show) {
  1494. $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
  1495. } else if (withDimension) {
  1496. // need to update dimension (e.g. axis.y.tick.values) because y tick values should change
  1497. // no need to update axis in it because they will be updated in redraw()
  1498. $$.updateDimension(true);
  1499. } // MEMO: needed for grids calculation
  1500. if ($$.isCategorized() && targetsToShow.length === 0) {
  1501. $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);
  1502. }
  1503. if (targetsToShow.length) {
  1504. $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);
  1505. if (!config.axis_x_tick_values) {
  1506. tickValues = $$.axis.updateXAxisTickValues(targetsToShow);
  1507. }
  1508. } else {
  1509. $$.xAxis.tickValues([]);
  1510. $$.subXAxis.tickValues([]);
  1511. }
  1512. if (config.zoom_rescale && !options.flow) {
  1513. xDomainForZoom = $$.x.orgDomain();
  1514. }
  1515. $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));
  1516. $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));
  1517. if (!config.axis_y_tick_values && config.axis_y_tick_count) {
  1518. $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count));
  1519. }
  1520. if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {
  1521. $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count));
  1522. } // axes
  1523. $$.axis.redraw(durationForAxis, hideAxis); // Update axis label
  1524. $$.axis.updateLabels(withTransition); // show/hide if manual culling needed
  1525. if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {
  1526. if (config.axis_x_tick_culling && tickValues) {
  1527. for (i = 1; i < tickValues.length; i++) {
  1528. if (tickValues.length / i < config.axis_x_tick_culling_max) {
  1529. intervalForCulling = i;
  1530. break;
  1531. }
  1532. }
  1533. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {
  1534. var index = tickValues.indexOf(e);
  1535. if (index >= 0) {
  1536. d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');
  1537. }
  1538. });
  1539. } else {
  1540. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block');
  1541. }
  1542. } // setup drawer - MEMO: these must be called after axis updated
  1543. drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined;
  1544. drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;
  1545. drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined;
  1546. xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
  1547. yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false); // update circleY based on updated parameters
  1548. $$.updateCircleY(); // generate circle x/y functions depending on updated params
  1549. cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
  1550. cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$); // Update sub domain
  1551. if (withY) {
  1552. $$.subY.domain($$.getYDomain(targetsToShow, 'y'));
  1553. $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));
  1554. } // xgrid focus
  1555. $$.updateXgridFocus(); // Data empty label positioning and text.
  1556. main.select("text." + CLASS.text + '.' + CLASS.empty).attr("x", $$.width / 2).attr("y", $$.height / 2).text(config.data_empty_label_text).transition().style('opacity', targetsToShow.length ? 0 : 1); // event rect
  1557. if (withEventRect) {
  1558. $$.redrawEventRect();
  1559. } // grid
  1560. $$.updateGrid(duration);
  1561. $$.updateStanfordElements(duration); // rect for regions
  1562. $$.updateRegion(duration); // bars
  1563. $$.updateBar(durationForExit); // lines, areas and circles
  1564. $$.updateLine(durationForExit);
  1565. $$.updateArea(durationForExit);
  1566. $$.updateCircle(cx, cy); // text
  1567. if ($$.hasDataLabel()) {
  1568. $$.updateText(xForText, yForText, durationForExit);
  1569. } // title
  1570. if ($$.redrawTitle) {
  1571. $$.redrawTitle();
  1572. } // arc
  1573. if ($$.redrawArc) {
  1574. $$.redrawArc(duration, durationForExit, withTransform);
  1575. } // subchart
  1576. if (config.subchart_show && $$.redrawSubchart) {
  1577. $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);
  1578. }
  1579. if ($$.isStanfordGraphType()) {
  1580. $$.drawColorScale();
  1581. } // circles for select
  1582. main.selectAll('.' + CLASS.selectedCircles).filter($$.isBarType.bind($$)).selectAll('circle').remove();
  1583. if (options.flow) {
  1584. flow = $$.generateFlow({
  1585. targets: targetsToShow,
  1586. flow: options.flow,
  1587. duration: options.flow.duration,
  1588. drawBar: drawBar,
  1589. drawLine: drawLine,
  1590. drawArea: drawArea,
  1591. cx: cx,
  1592. cy: cy,
  1593. xv: xv,
  1594. xForText: xForText,
  1595. yForText: yForText
  1596. });
  1597. }
  1598. if (duration && $$.isTabVisible()) {
  1599. // Only use transition if tab visible. See #938.
  1600. // transition should be derived from one transition
  1601. transition = d3.transition().duration(duration);
  1602. transitionsToWait = [];
  1603. [$$.redrawBar(drawBar, true, transition), $$.redrawLine(drawLine, true, transition), $$.redrawArea(drawArea, true, transition), $$.redrawCircle(cx, cy, true, transition), $$.redrawText(xForText, yForText, options.flow, true, transition), $$.redrawRegion(true, transition), $$.redrawGrid(true, transition)].forEach(function (transitions) {
  1604. transitions.forEach(function (transition) {
  1605. transitionsToWait.push(transition);
  1606. });
  1607. }); // Wait for end of transitions to call flow and onrendered callback
  1608. waitForDraw = $$.generateWait();
  1609. transitionsToWait.forEach(function (t) {
  1610. waitForDraw.add(t);
  1611. });
  1612. waitForDraw(function () {
  1613. if (flow) {
  1614. flow();
  1615. }
  1616. if (config.onrendered) {
  1617. config.onrendered.call($$);
  1618. }
  1619. });
  1620. } else {
  1621. $$.redrawBar(drawBar);
  1622. $$.redrawLine(drawLine);
  1623. $$.redrawArea(drawArea);
  1624. $$.redrawCircle(cx, cy);
  1625. $$.redrawText(xForText, yForText, options.flow);
  1626. $$.redrawRegion();
  1627. $$.redrawGrid();
  1628. if (flow) {
  1629. flow();
  1630. }
  1631. if (config.onrendered) {
  1632. config.onrendered.call($$);
  1633. }
  1634. } // update fadein condition
  1635. $$.mapToIds($$.data.targets).forEach(function (id) {
  1636. $$.withoutFadeIn[id] = true;
  1637. });
  1638. };
  1639. ChartInternal.prototype.updateAndRedraw = function (options) {
  1640. var $$ = this,
  1641. config = $$.config,
  1642. transitions;
  1643. options = options || {}; // same with redraw
  1644. options.withTransition = getOption(options, "withTransition", true);
  1645. options.withTransform = getOption(options, "withTransform", false);
  1646. options.withLegend = getOption(options, "withLegend", false); // NOT same with redraw
  1647. options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true);
  1648. options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true);
  1649. options.withTransitionForExit = false;
  1650. options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)
  1651. $$.updateSizes(); // MEMO: called in updateLegend in redraw if withLegend
  1652. if (!(options.withLegend && config.legend_show)) {
  1653. transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0); // Update scales
  1654. $$.updateScales();
  1655. $$.updateSvgSize(); // Update g positions
  1656. $$.transformAll(options.withTransitionForTransform, transitions);
  1657. } // Draw with new sizes & scales
  1658. $$.redraw(options, transitions);
  1659. };
  1660. ChartInternal.prototype.redrawWithoutRescale = function () {
  1661. this.redraw({
  1662. withY: false,
  1663. withSubchart: false,
  1664. withEventRect: false,
  1665. withTransitionForAxis: false
  1666. });
  1667. };
  1668. ChartInternal.prototype.isTimeSeries = function () {
  1669. return this.config.axis_x_type === 'timeseries';
  1670. };
  1671. ChartInternal.prototype.isCategorized = function () {
  1672. return this.config.axis_x_type.indexOf('categor') >= 0;
  1673. };
  1674. ChartInternal.prototype.isCustomX = function () {
  1675. var $$ = this,
  1676. config = $$.config;
  1677. return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));
  1678. };
  1679. ChartInternal.prototype.isTimeSeriesY = function () {
  1680. return this.config.axis_y_type === 'timeseries';
  1681. };
  1682. ChartInternal.prototype.getTranslate = function (target) {
  1683. var $$ = this,
  1684. config = $$.config,
  1685. x,
  1686. y;
  1687. if (target === 'main') {
  1688. x = asHalfPixel($$.margin.left);
  1689. y = asHalfPixel($$.margin.top);
  1690. } else if (target === 'context') {
  1691. x = asHalfPixel($$.margin2.left);
  1692. y = asHalfPixel($$.margin2.top);
  1693. } else if (target === 'legend') {
  1694. x = $$.margin3.left;
  1695. y = $$.margin3.top;
  1696. } else if (target === 'x') {
  1697. x = 0;
  1698. y = config.axis_rotated ? 0 : $$.height;
  1699. } else if (target === 'y') {
  1700. x = 0;
  1701. y = config.axis_rotated ? $$.height : 0;
  1702. } else if (target === 'y2') {
  1703. x = config.axis_rotated ? 0 : $$.width;
  1704. y = config.axis_rotated ? 1 : 0;
  1705. } else if (target === 'subx') {
  1706. x = 0;
  1707. y = config.axis_rotated ? 0 : $$.height2;
  1708. } else if (target === 'arc') {
  1709. x = $$.arcWidth / 2;
  1710. y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label
  1711. }
  1712. return "translate(" + x + "," + y + ")";
  1713. };
  1714. ChartInternal.prototype.initialOpacity = function (d) {
  1715. return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;
  1716. };
  1717. ChartInternal.prototype.initialOpacityForCircle = function (d) {
  1718. return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0;
  1719. };
  1720. ChartInternal.prototype.opacityForCircle = function (d) {
  1721. var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show;
  1722. var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0;
  1723. return isValue(d.value) ? this.isScatterType(d) ? 0.5 : opacity : 0;
  1724. };
  1725. ChartInternal.prototype.opacityForText = function () {
  1726. return this.hasDataLabel() ? 1 : 0;
  1727. };
  1728. ChartInternal.prototype.xx = function (d) {
  1729. return d ? this.x(d.x) : null;
  1730. };
  1731. ChartInternal.prototype.xvCustom = function (d, xyValue) {
  1732. var $$ = this,
  1733. value = xyValue ? d[xyValue] : d.value;
  1734. if ($$.isTimeSeries()) {
  1735. value = $$.parseDate(d.value);
  1736. } else if ($$.isCategorized() && typeof d.value === 'string') {
  1737. value = $$.config.axis_x_categories.indexOf(d.value);
  1738. }
  1739. return Math.ceil($$.x(value));
  1740. };
  1741. ChartInternal.prototype.yvCustom = function (d, xyValue) {
  1742. var $$ = this,
  1743. yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y,
  1744. value = xyValue ? d[xyValue] : d.value;
  1745. return Math.ceil(yScale(value));
  1746. };
  1747. ChartInternal.prototype.xv = function (d) {
  1748. var $$ = this,
  1749. value = d.value;
  1750. if ($$.isTimeSeries()) {
  1751. value = $$.parseDate(d.value);
  1752. } else if ($$.isCategorized() && typeof d.value === 'string') {
  1753. value = $$.config.axis_x_categories.indexOf(d.value);
  1754. }
  1755. return Math.ceil($$.x(value));
  1756. };
  1757. ChartInternal.prototype.yv = function (d) {
  1758. var $$ = this,
  1759. yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;
  1760. return Math.ceil(yScale(d.value));
  1761. };
  1762. ChartInternal.prototype.subxx = function (d) {
  1763. return d ? this.subX(d.x) : null;
  1764. };
  1765. ChartInternal.prototype.transformMain = function (withTransition, transitions) {
  1766. var $$ = this,
  1767. xAxis,
  1768. yAxis,
  1769. y2Axis;
  1770. if (transitions && transitions.axisX) {
  1771. xAxis = transitions.axisX;
  1772. } else {
  1773. xAxis = $$.main.select('.' + CLASS.axisX);
  1774. if (withTransition) {
  1775. xAxis = xAxis.transition();
  1776. }
  1777. }
  1778. if (transitions && transitions.axisY) {
  1779. yAxis = transitions.axisY;
  1780. } else {
  1781. yAxis = $$.main.select('.' + CLASS.axisY);
  1782. if (withTransition) {
  1783. yAxis = yAxis.transition();
  1784. }
  1785. }
  1786. if (transitions && transitions.axisY2) {
  1787. y2Axis = transitions.axisY2;
  1788. } else {
  1789. y2Axis = $$.main.select('.' + CLASS.axisY2);
  1790. if (withTransition) {
  1791. y2Axis = y2Axis.transition();
  1792. }
  1793. }
  1794. (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main'));
  1795. xAxis.attr("transform", $$.getTranslate('x'));
  1796. yAxis.attr("transform", $$.getTranslate('y'));
  1797. y2Axis.attr("transform", $$.getTranslate('y2'));
  1798. $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  1799. };
  1800. ChartInternal.prototype.transformAll = function (withTransition, transitions) {
  1801. var $$ = this;
  1802. $$.transformMain(withTransition, transitions);
  1803. if ($$.config.subchart_show) {
  1804. $$.transformContext(withTransition, transitions);
  1805. }
  1806. if ($$.legend) {
  1807. $$.transformLegend(withTransition);
  1808. }
  1809. };
  1810. ChartInternal.prototype.updateSvgSize = function () {
  1811. var $$ = this,
  1812. brush = $$.svg.select(".".concat(CLASS.brush, " .overlay"));
  1813. $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
  1814. $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect').attr('width', $$.width).attr('height', $$.height);
  1815. $$.svg.select('#' + $$.clipIdForXAxis).select('rect').attr('x', $$.getXAxisClipX.bind($$)).attr('y', $$.getXAxisClipY.bind($$)).attr('width', $$.getXAxisClipWidth.bind($$)).attr('height', $$.getXAxisClipHeight.bind($$));
  1816. $$.svg.select('#' + $$.clipIdForYAxis).select('rect').attr('x', $$.getYAxisClipX.bind($$)).attr('y', $$.getYAxisClipY.bind($$)).attr('width', $$.getYAxisClipWidth.bind($$)).attr('height', $$.getYAxisClipHeight.bind($$));
  1817. $$.svg.select('#' + $$.clipIdForSubchart).select('rect').attr('width', $$.width).attr('height', brush.size() && brush.attr('height') || 0); // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
  1818. $$.selectChart.style('max-height', $$.currentHeight + "px");
  1819. };
  1820. ChartInternal.prototype.updateDimension = function (withoutAxis) {
  1821. var $$ = this;
  1822. if (!withoutAxis) {
  1823. if ($$.config.axis_rotated) {
  1824. $$.axes.x.call($$.xAxis);
  1825. $$.axes.subx.call($$.subXAxis);
  1826. } else {
  1827. $$.axes.y.call($$.yAxis);
  1828. $$.axes.y2.call($$.y2Axis);
  1829. }
  1830. }
  1831. $$.updateSizes();
  1832. $$.updateScales();
  1833. $$.updateSvgSize();
  1834. $$.transformAll(false);
  1835. };
  1836. ChartInternal.prototype.observeInserted = function (selection) {
  1837. var $$ = this,
  1838. observer;
  1839. if (typeof MutationObserver === 'undefined') {
  1840. window.console.error("MutationObserver not defined.");
  1841. return;
  1842. }
  1843. observer = new MutationObserver(function (mutations) {
  1844. mutations.forEach(function (mutation) {
  1845. if (mutation.type === 'childList' && mutation.previousSibling) {
  1846. observer.disconnect(); // need to wait for completion of load because size calculation requires the actual sizes determined after that completion
  1847. $$.intervalForObserveInserted = window.setInterval(function () {
  1848. // parentNode will NOT be null when completed
  1849. if (selection.node().parentNode) {
  1850. window.clearInterval($$.intervalForObserveInserted);
  1851. $$.updateDimension();
  1852. if ($$.brush) {
  1853. $$.brush.update();
  1854. }
  1855. $$.config.oninit.call($$);
  1856. $$.redraw({
  1857. withTransform: true,
  1858. withUpdateXDomain: true,
  1859. withUpdateOrgXDomain: true,
  1860. withTransition: false,
  1861. withTransitionForTransform: false,
  1862. withLegend: true
  1863. });
  1864. selection.transition().style('opacity', 1);
  1865. }
  1866. }, 10);
  1867. }
  1868. });
  1869. });
  1870. observer.observe(selection.node(), {
  1871. attributes: true,
  1872. childList: true,
  1873. characterData: true
  1874. });
  1875. };
  1876. /**
  1877. * Binds handlers to the window resize event.
  1878. */
  1879. ChartInternal.prototype.bindResize = function () {
  1880. var $$ = this,
  1881. config = $$.config;
  1882. $$.resizeFunction = $$.generateResize(); // need to call .remove
  1883. $$.resizeFunction.add(function () {
  1884. config.onresize.call($$);
  1885. });
  1886. if (config.resize_auto) {
  1887. $$.resizeFunction.add(function () {
  1888. if ($$.resizeTimeout !== undefined) {
  1889. window.clearTimeout($$.resizeTimeout);
  1890. }
  1891. $$.resizeTimeout = window.setTimeout(function () {
  1892. delete $$.resizeTimeout;
  1893. $$.updateAndRedraw({
  1894. withUpdateXDomain: false,
  1895. withUpdateOrgXDomain: false,
  1896. withTransition: false,
  1897. withTransitionForTransform: false,
  1898. withLegend: true
  1899. });
  1900. if ($$.brush) {
  1901. $$.brush.update();
  1902. }
  1903. }, 100);
  1904. });
  1905. }
  1906. $$.resizeFunction.add(function () {
  1907. config.onresized.call($$);
  1908. });
  1909. $$.resizeIfElementDisplayed = function () {
  1910. // if element not displayed skip it
  1911. if ($$.api == null || !$$.api.element.offsetParent) {
  1912. return;
  1913. }
  1914. $$.resizeFunction();
  1915. };
  1916. if (window.attachEvent) {
  1917. window.attachEvent('onresize', $$.resizeIfElementDisplayed);
  1918. } else if (window.addEventListener) {
  1919. window.addEventListener('resize', $$.resizeIfElementDisplayed, false);
  1920. } else {
  1921. // fallback to this, if this is a very old browser
  1922. var wrapper = window.onresize;
  1923. if (!wrapper) {
  1924. // create a wrapper that will call all charts
  1925. wrapper = $$.generateResize();
  1926. } else if (!wrapper.add || !wrapper.remove) {
  1927. // there is already a handler registered, make sure we call it too
  1928. wrapper = $$.generateResize();
  1929. wrapper.add(window.onresize);
  1930. } // add this graph to the wrapper, we will be removed if the user calls destroy
  1931. wrapper.add($$.resizeFunction);
  1932. window.onresize = function () {
  1933. // if element not displayed skip it
  1934. if (!$$.api.element.offsetParent) {
  1935. return;
  1936. }
  1937. wrapper();
  1938. };
  1939. }
  1940. };
  1941. /**
  1942. * Binds handlers to the window focus event.
  1943. */
  1944. ChartInternal.prototype.bindWindowFocus = function () {
  1945. var _this = this;
  1946. if (this.windowFocusHandler) {
  1947. // The handler is already set
  1948. return;
  1949. }
  1950. this.windowFocusHandler = function () {
  1951. _this.redraw();
  1952. };
  1953. window.addEventListener('focus', this.windowFocusHandler);
  1954. };
  1955. /**
  1956. * Unbinds from the window focus event.
  1957. */
  1958. ChartInternal.prototype.unbindWindowFocus = function () {
  1959. window.removeEventListener('focus', this.windowFocusHandler);
  1960. delete this.windowFocusHandler;
  1961. };
  1962. ChartInternal.prototype.generateResize = function () {
  1963. var resizeFunctions = [];
  1964. function callResizeFunctions() {
  1965. resizeFunctions.forEach(function (f) {
  1966. f();
  1967. });
  1968. }
  1969. callResizeFunctions.add = function (f) {
  1970. resizeFunctions.push(f);
  1971. };
  1972. callResizeFunctions.remove = function (f) {
  1973. for (var i = 0; i < resizeFunctions.length; i++) {
  1974. if (resizeFunctions[i] === f) {
  1975. resizeFunctions.splice(i, 1);
  1976. break;
  1977. }
  1978. }
  1979. };
  1980. return callResizeFunctions;
  1981. };
  1982. ChartInternal.prototype.endall = function (transition, callback) {
  1983. var n = 0;
  1984. transition.each(function () {
  1985. ++n;
  1986. }).on("end", function () {
  1987. if (! --n) {
  1988. callback.apply(this, arguments);
  1989. }
  1990. });
  1991. };
  1992. ChartInternal.prototype.generateWait = function () {
  1993. var $$ = this;
  1994. var transitionsToWait = [],
  1995. f = function f(callback) {
  1996. var timer = setInterval(function () {
  1997. if (!$$.isTabVisible()) {
  1998. return;
  1999. }
  2000. var done = 0;
  2001. transitionsToWait.forEach(function (t) {
  2002. if (t.empty()) {
  2003. done += 1;
  2004. return;
  2005. }
  2006. try {
  2007. t.transition();
  2008. } catch (e) {
  2009. done += 1;
  2010. }
  2011. });
  2012. if (done === transitionsToWait.length) {
  2013. clearInterval(timer);
  2014. if (callback) {
  2015. callback();
  2016. }
  2017. }
  2018. }, 50);
  2019. };
  2020. f.add = function (transition) {
  2021. transitionsToWait.push(transition);
  2022. };
  2023. return f;
  2024. };
  2025. ChartInternal.prototype.parseDate = function (date) {
  2026. var $$ = this,
  2027. parsedDate;
  2028. if (date instanceof Date) {
  2029. parsedDate = date;
  2030. } else if (typeof date === 'string') {
  2031. parsedDate = $$.dataTimeParse(date);
  2032. } else if (_typeof(date) === 'object') {
  2033. parsedDate = new Date(+date);
  2034. } else if (typeof date === 'number' && !isNaN(date)) {
  2035. parsedDate = new Date(+date);
  2036. }
  2037. if (!parsedDate || isNaN(+parsedDate)) {
  2038. window.console.error("Failed to parse x '" + date + "' to Date object");
  2039. }
  2040. return parsedDate;
  2041. };
  2042. ChartInternal.prototype.isTabVisible = function () {
  2043. return !document.hidden;
  2044. };
  2045. ChartInternal.prototype.getPathBox = getPathBox;
  2046. ChartInternal.prototype.CLASS = CLASS;
  2047. /* jshint ignore:start */
  2048. // SVGPathSeg API polyfill
  2049. // https://github.com/progers/pathseg
  2050. //
  2051. // This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from
  2052. // SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec
  2053. // changes which were implemented in Firefox 43 and Chrome 46.
  2054. (function () {
  2055. if (!("SVGPathSeg" in window)) {
  2056. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
  2057. window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {
  2058. this.pathSegType = type;
  2059. this.pathSegTypeAsLetter = typeAsLetter;
  2060. this._owningPathSegList = owningPathSegList;
  2061. };
  2062. window.SVGPathSeg.prototype.classname = "SVGPathSeg";
  2063. window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
  2064. window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
  2065. window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
  2066. window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
  2067. window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
  2068. window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
  2069. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
  2070. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
  2071. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
  2072. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
  2073. window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
  2074. window.SVGPathSeg.PATHSEG_ARC_REL = 11;
  2075. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
  2076. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
  2077. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
  2078. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
  2079. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
  2080. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
  2081. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
  2082. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; // Notify owning PathSegList on any changes so they can be synchronized back to the path element.
  2083. window.SVGPathSeg.prototype._segmentChanged = function () {
  2084. if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);
  2085. };
  2086. window.SVGPathSegClosePath = function (owningPathSegList) {
  2087. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
  2088. };
  2089. window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
  2090. window.SVGPathSegClosePath.prototype.toString = function () {
  2091. return "[object SVGPathSegClosePath]";
  2092. };
  2093. window.SVGPathSegClosePath.prototype._asPathString = function () {
  2094. return this.pathSegTypeAsLetter;
  2095. };
  2096. window.SVGPathSegClosePath.prototype.clone = function () {
  2097. return new window.SVGPathSegClosePath(undefined);
  2098. };
  2099. window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {
  2100. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
  2101. this._x = x;
  2102. this._y = y;
  2103. };
  2104. window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2105. window.SVGPathSegMovetoAbs.prototype.toString = function () {
  2106. return "[object SVGPathSegMovetoAbs]";
  2107. };
  2108. window.SVGPathSegMovetoAbs.prototype._asPathString = function () {
  2109. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2110. };
  2111. window.SVGPathSegMovetoAbs.prototype.clone = function () {
  2112. return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y);
  2113. };
  2114. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", {
  2115. get: function get() {
  2116. return this._x;
  2117. },
  2118. set: function set(x) {
  2119. this._x = x;
  2120. this._segmentChanged();
  2121. },
  2122. enumerable: true
  2123. });
  2124. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", {
  2125. get: function get() {
  2126. return this._y;
  2127. },
  2128. set: function set(y) {
  2129. this._y = y;
  2130. this._segmentChanged();
  2131. },
  2132. enumerable: true
  2133. });
  2134. window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {
  2135. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
  2136. this._x = x;
  2137. this._y = y;
  2138. };
  2139. window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2140. window.SVGPathSegMovetoRel.prototype.toString = function () {
  2141. return "[object SVGPathSegMovetoRel]";
  2142. };
  2143. window.SVGPathSegMovetoRel.prototype._asPathString = function () {
  2144. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2145. };
  2146. window.SVGPathSegMovetoRel.prototype.clone = function () {
  2147. return new window.SVGPathSegMovetoRel(undefined, this._x, this._y);
  2148. };
  2149. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", {
  2150. get: function get() {
  2151. return this._x;
  2152. },
  2153. set: function set(x) {
  2154. this._x = x;
  2155. this._segmentChanged();
  2156. },
  2157. enumerable: true
  2158. });
  2159. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", {
  2160. get: function get() {
  2161. return this._y;
  2162. },
  2163. set: function set(y) {
  2164. this._y = y;
  2165. this._segmentChanged();
  2166. },
  2167. enumerable: true
  2168. });
  2169. window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {
  2170. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
  2171. this._x = x;
  2172. this._y = y;
  2173. };
  2174. window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2175. window.SVGPathSegLinetoAbs.prototype.toString = function () {
  2176. return "[object SVGPathSegLinetoAbs]";
  2177. };
  2178. window.SVGPathSegLinetoAbs.prototype._asPathString = function () {
  2179. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2180. };
  2181. window.SVGPathSegLinetoAbs.prototype.clone = function () {
  2182. return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y);
  2183. };
  2184. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", {
  2185. get: function get() {
  2186. return this._x;
  2187. },
  2188. set: function set(x) {
  2189. this._x = x;
  2190. this._segmentChanged();
  2191. },
  2192. enumerable: true
  2193. });
  2194. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", {
  2195. get: function get() {
  2196. return this._y;
  2197. },
  2198. set: function set(y) {
  2199. this._y = y;
  2200. this._segmentChanged();
  2201. },
  2202. enumerable: true
  2203. });
  2204. window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {
  2205. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
  2206. this._x = x;
  2207. this._y = y;
  2208. };
  2209. window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2210. window.SVGPathSegLinetoRel.prototype.toString = function () {
  2211. return "[object SVGPathSegLinetoRel]";
  2212. };
  2213. window.SVGPathSegLinetoRel.prototype._asPathString = function () {
  2214. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2215. };
  2216. window.SVGPathSegLinetoRel.prototype.clone = function () {
  2217. return new window.SVGPathSegLinetoRel(undefined, this._x, this._y);
  2218. };
  2219. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", {
  2220. get: function get() {
  2221. return this._x;
  2222. },
  2223. set: function set(x) {
  2224. this._x = x;
  2225. this._segmentChanged();
  2226. },
  2227. enumerable: true
  2228. });
  2229. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", {
  2230. get: function get() {
  2231. return this._y;
  2232. },
  2233. set: function set(y) {
  2234. this._y = y;
  2235. this._segmentChanged();
  2236. },
  2237. enumerable: true
  2238. });
  2239. window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2240. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
  2241. this._x = x;
  2242. this._y = y;
  2243. this._x1 = x1;
  2244. this._y1 = y1;
  2245. this._x2 = x2;
  2246. this._y2 = y2;
  2247. };
  2248. window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2249. window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () {
  2250. return "[object SVGPathSegCurvetoCubicAbs]";
  2251. };
  2252. window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () {
  2253. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2254. };
  2255. window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () {
  2256. return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2257. };
  2258. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", {
  2259. get: function get() {
  2260. return this._x;
  2261. },
  2262. set: function set(x) {
  2263. this._x = x;
  2264. this._segmentChanged();
  2265. },
  2266. enumerable: true
  2267. });
  2268. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", {
  2269. get: function get() {
  2270. return this._y;
  2271. },
  2272. set: function set(y) {
  2273. this._y = y;
  2274. this._segmentChanged();
  2275. },
  2276. enumerable: true
  2277. });
  2278. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", {
  2279. get: function get() {
  2280. return this._x1;
  2281. },
  2282. set: function set(x1) {
  2283. this._x1 = x1;
  2284. this._segmentChanged();
  2285. },
  2286. enumerable: true
  2287. });
  2288. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", {
  2289. get: function get() {
  2290. return this._y1;
  2291. },
  2292. set: function set(y1) {
  2293. this._y1 = y1;
  2294. this._segmentChanged();
  2295. },
  2296. enumerable: true
  2297. });
  2298. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", {
  2299. get: function get() {
  2300. return this._x2;
  2301. },
  2302. set: function set(x2) {
  2303. this._x2 = x2;
  2304. this._segmentChanged();
  2305. },
  2306. enumerable: true
  2307. });
  2308. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", {
  2309. get: function get() {
  2310. return this._y2;
  2311. },
  2312. set: function set(y2) {
  2313. this._y2 = y2;
  2314. this._segmentChanged();
  2315. },
  2316. enumerable: true
  2317. });
  2318. window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2319. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
  2320. this._x = x;
  2321. this._y = y;
  2322. this._x1 = x1;
  2323. this._y1 = y1;
  2324. this._x2 = x2;
  2325. this._y2 = y2;
  2326. };
  2327. window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2328. window.SVGPathSegCurvetoCubicRel.prototype.toString = function () {
  2329. return "[object SVGPathSegCurvetoCubicRel]";
  2330. };
  2331. window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () {
  2332. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2333. };
  2334. window.SVGPathSegCurvetoCubicRel.prototype.clone = function () {
  2335. return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2336. };
  2337. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", {
  2338. get: function get() {
  2339. return this._x;
  2340. },
  2341. set: function set(x) {
  2342. this._x = x;
  2343. this._segmentChanged();
  2344. },
  2345. enumerable: true
  2346. });
  2347. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", {
  2348. get: function get() {
  2349. return this._y;
  2350. },
  2351. set: function set(y) {
  2352. this._y = y;
  2353. this._segmentChanged();
  2354. },
  2355. enumerable: true
  2356. });
  2357. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", {
  2358. get: function get() {
  2359. return this._x1;
  2360. },
  2361. set: function set(x1) {
  2362. this._x1 = x1;
  2363. this._segmentChanged();
  2364. },
  2365. enumerable: true
  2366. });
  2367. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", {
  2368. get: function get() {
  2369. return this._y1;
  2370. },
  2371. set: function set(y1) {
  2372. this._y1 = y1;
  2373. this._segmentChanged();
  2374. },
  2375. enumerable: true
  2376. });
  2377. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", {
  2378. get: function get() {
  2379. return this._x2;
  2380. },
  2381. set: function set(x2) {
  2382. this._x2 = x2;
  2383. this._segmentChanged();
  2384. },
  2385. enumerable: true
  2386. });
  2387. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", {
  2388. get: function get() {
  2389. return this._y2;
  2390. },
  2391. set: function set(y2) {
  2392. this._y2 = y2;
  2393. this._segmentChanged();
  2394. },
  2395. enumerable: true
  2396. });
  2397. window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {
  2398. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
  2399. this._x = x;
  2400. this._y = y;
  2401. this._x1 = x1;
  2402. this._y1 = y1;
  2403. };
  2404. window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2405. window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () {
  2406. return "[object SVGPathSegCurvetoQuadraticAbs]";
  2407. };
  2408. window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () {
  2409. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2410. };
  2411. window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () {
  2412. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1);
  2413. };
  2414. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", {
  2415. get: function get() {
  2416. return this._x;
  2417. },
  2418. set: function set(x) {
  2419. this._x = x;
  2420. this._segmentChanged();
  2421. },
  2422. enumerable: true
  2423. });
  2424. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", {
  2425. get: function get() {
  2426. return this._y;
  2427. },
  2428. set: function set(y) {
  2429. this._y = y;
  2430. this._segmentChanged();
  2431. },
  2432. enumerable: true
  2433. });
  2434. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", {
  2435. get: function get() {
  2436. return this._x1;
  2437. },
  2438. set: function set(x1) {
  2439. this._x1 = x1;
  2440. this._segmentChanged();
  2441. },
  2442. enumerable: true
  2443. });
  2444. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", {
  2445. get: function get() {
  2446. return this._y1;
  2447. },
  2448. set: function set(y1) {
  2449. this._y1 = y1;
  2450. this._segmentChanged();
  2451. },
  2452. enumerable: true
  2453. });
  2454. window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {
  2455. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
  2456. this._x = x;
  2457. this._y = y;
  2458. this._x1 = x1;
  2459. this._y1 = y1;
  2460. };
  2461. window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2462. window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () {
  2463. return "[object SVGPathSegCurvetoQuadraticRel]";
  2464. };
  2465. window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () {
  2466. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2467. };
  2468. window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () {
  2469. return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1);
  2470. };
  2471. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", {
  2472. get: function get() {
  2473. return this._x;
  2474. },
  2475. set: function set(x) {
  2476. this._x = x;
  2477. this._segmentChanged();
  2478. },
  2479. enumerable: true
  2480. });
  2481. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", {
  2482. get: function get() {
  2483. return this._y;
  2484. },
  2485. set: function set(y) {
  2486. this._y = y;
  2487. this._segmentChanged();
  2488. },
  2489. enumerable: true
  2490. });
  2491. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", {
  2492. get: function get() {
  2493. return this._x1;
  2494. },
  2495. set: function set(x1) {
  2496. this._x1 = x1;
  2497. this._segmentChanged();
  2498. },
  2499. enumerable: true
  2500. });
  2501. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", {
  2502. get: function get() {
  2503. return this._y1;
  2504. },
  2505. set: function set(y1) {
  2506. this._y1 = y1;
  2507. this._segmentChanged();
  2508. },
  2509. enumerable: true
  2510. });
  2511. window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2512. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
  2513. this._x = x;
  2514. this._y = y;
  2515. this._r1 = r1;
  2516. this._r2 = r2;
  2517. this._angle = angle;
  2518. this._largeArcFlag = largeArcFlag;
  2519. this._sweepFlag = sweepFlag;
  2520. };
  2521. window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2522. window.SVGPathSegArcAbs.prototype.toString = function () {
  2523. return "[object SVGPathSegArcAbs]";
  2524. };
  2525. window.SVGPathSegArcAbs.prototype._asPathString = function () {
  2526. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2527. };
  2528. window.SVGPathSegArcAbs.prototype.clone = function () {
  2529. return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2530. };
  2531. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", {
  2532. get: function get() {
  2533. return this._x;
  2534. },
  2535. set: function set(x) {
  2536. this._x = x;
  2537. this._segmentChanged();
  2538. },
  2539. enumerable: true
  2540. });
  2541. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", {
  2542. get: function get() {
  2543. return this._y;
  2544. },
  2545. set: function set(y) {
  2546. this._y = y;
  2547. this._segmentChanged();
  2548. },
  2549. enumerable: true
  2550. });
  2551. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", {
  2552. get: function get() {
  2553. return this._r1;
  2554. },
  2555. set: function set(r1) {
  2556. this._r1 = r1;
  2557. this._segmentChanged();
  2558. },
  2559. enumerable: true
  2560. });
  2561. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", {
  2562. get: function get() {
  2563. return this._r2;
  2564. },
  2565. set: function set(r2) {
  2566. this._r2 = r2;
  2567. this._segmentChanged();
  2568. },
  2569. enumerable: true
  2570. });
  2571. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", {
  2572. get: function get() {
  2573. return this._angle;
  2574. },
  2575. set: function set(angle) {
  2576. this._angle = angle;
  2577. this._segmentChanged();
  2578. },
  2579. enumerable: true
  2580. });
  2581. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", {
  2582. get: function get() {
  2583. return this._largeArcFlag;
  2584. },
  2585. set: function set(largeArcFlag) {
  2586. this._largeArcFlag = largeArcFlag;
  2587. this._segmentChanged();
  2588. },
  2589. enumerable: true
  2590. });
  2591. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", {
  2592. get: function get() {
  2593. return this._sweepFlag;
  2594. },
  2595. set: function set(sweepFlag) {
  2596. this._sweepFlag = sweepFlag;
  2597. this._segmentChanged();
  2598. },
  2599. enumerable: true
  2600. });
  2601. window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2602. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
  2603. this._x = x;
  2604. this._y = y;
  2605. this._r1 = r1;
  2606. this._r2 = r2;
  2607. this._angle = angle;
  2608. this._largeArcFlag = largeArcFlag;
  2609. this._sweepFlag = sweepFlag;
  2610. };
  2611. window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2612. window.SVGPathSegArcRel.prototype.toString = function () {
  2613. return "[object SVGPathSegArcRel]";
  2614. };
  2615. window.SVGPathSegArcRel.prototype._asPathString = function () {
  2616. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2617. };
  2618. window.SVGPathSegArcRel.prototype.clone = function () {
  2619. return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2620. };
  2621. Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", {
  2622. get: function get() {
  2623. return this._x;
  2624. },
  2625. set: function set(x) {
  2626. this._x = x;
  2627. this._segmentChanged();
  2628. },
  2629. enumerable: true
  2630. });
  2631. Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", {
  2632. get: function get() {
  2633. return this._y;
  2634. },
  2635. set: function set(y) {
  2636. this._y = y;
  2637. this._segmentChanged();
  2638. },
  2639. enumerable: true
  2640. });
  2641. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", {
  2642. get: function get() {
  2643. return this._r1;
  2644. },
  2645. set: function set(r1) {
  2646. this._r1 = r1;
  2647. this._segmentChanged();
  2648. },
  2649. enumerable: true
  2650. });
  2651. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", {
  2652. get: function get() {
  2653. return this._r2;
  2654. },
  2655. set: function set(r2) {
  2656. this._r2 = r2;
  2657. this._segmentChanged();
  2658. },
  2659. enumerable: true
  2660. });
  2661. Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", {
  2662. get: function get() {
  2663. return this._angle;
  2664. },
  2665. set: function set(angle) {
  2666. this._angle = angle;
  2667. this._segmentChanged();
  2668. },
  2669. enumerable: true
  2670. });
  2671. Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", {
  2672. get: function get() {
  2673. return this._largeArcFlag;
  2674. },
  2675. set: function set(largeArcFlag) {
  2676. this._largeArcFlag = largeArcFlag;
  2677. this._segmentChanged();
  2678. },
  2679. enumerable: true
  2680. });
  2681. Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", {
  2682. get: function get() {
  2683. return this._sweepFlag;
  2684. },
  2685. set: function set(sweepFlag) {
  2686. this._sweepFlag = sweepFlag;
  2687. this._segmentChanged();
  2688. },
  2689. enumerable: true
  2690. });
  2691. window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {
  2692. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
  2693. this._x = x;
  2694. };
  2695. window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2696. window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () {
  2697. return "[object SVGPathSegLinetoHorizontalAbs]";
  2698. };
  2699. window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () {
  2700. return this.pathSegTypeAsLetter + " " + this._x;
  2701. };
  2702. window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () {
  2703. return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x);
  2704. };
  2705. Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", {
  2706. get: function get() {
  2707. return this._x;
  2708. },
  2709. set: function set(x) {
  2710. this._x = x;
  2711. this._segmentChanged();
  2712. },
  2713. enumerable: true
  2714. });
  2715. window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {
  2716. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
  2717. this._x = x;
  2718. };
  2719. window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2720. window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () {
  2721. return "[object SVGPathSegLinetoHorizontalRel]";
  2722. };
  2723. window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () {
  2724. return this.pathSegTypeAsLetter + " " + this._x;
  2725. };
  2726. window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () {
  2727. return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x);
  2728. };
  2729. Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", {
  2730. get: function get() {
  2731. return this._x;
  2732. },
  2733. set: function set(x) {
  2734. this._x = x;
  2735. this._segmentChanged();
  2736. },
  2737. enumerable: true
  2738. });
  2739. window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {
  2740. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
  2741. this._y = y;
  2742. };
  2743. window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2744. window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () {
  2745. return "[object SVGPathSegLinetoVerticalAbs]";
  2746. };
  2747. window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () {
  2748. return this.pathSegTypeAsLetter + " " + this._y;
  2749. };
  2750. window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () {
  2751. return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y);
  2752. };
  2753. Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", {
  2754. get: function get() {
  2755. return this._y;
  2756. },
  2757. set: function set(y) {
  2758. this._y = y;
  2759. this._segmentChanged();
  2760. },
  2761. enumerable: true
  2762. });
  2763. window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {
  2764. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
  2765. this._y = y;
  2766. };
  2767. window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2768. window.SVGPathSegLinetoVerticalRel.prototype.toString = function () {
  2769. return "[object SVGPathSegLinetoVerticalRel]";
  2770. };
  2771. window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () {
  2772. return this.pathSegTypeAsLetter + " " + this._y;
  2773. };
  2774. window.SVGPathSegLinetoVerticalRel.prototype.clone = function () {
  2775. return new window.SVGPathSegLinetoVerticalRel(undefined, this._y);
  2776. };
  2777. Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", {
  2778. get: function get() {
  2779. return this._y;
  2780. },
  2781. set: function set(y) {
  2782. this._y = y;
  2783. this._segmentChanged();
  2784. },
  2785. enumerable: true
  2786. });
  2787. window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {
  2788. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
  2789. this._x = x;
  2790. this._y = y;
  2791. this._x2 = x2;
  2792. this._y2 = y2;
  2793. };
  2794. window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2795. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () {
  2796. return "[object SVGPathSegCurvetoCubicSmoothAbs]";
  2797. };
  2798. window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () {
  2799. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2800. };
  2801. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () {
  2802. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2);
  2803. };
  2804. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", {
  2805. get: function get() {
  2806. return this._x;
  2807. },
  2808. set: function set(x) {
  2809. this._x = x;
  2810. this._segmentChanged();
  2811. },
  2812. enumerable: true
  2813. });
  2814. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", {
  2815. get: function get() {
  2816. return this._y;
  2817. },
  2818. set: function set(y) {
  2819. this._y = y;
  2820. this._segmentChanged();
  2821. },
  2822. enumerable: true
  2823. });
  2824. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", {
  2825. get: function get() {
  2826. return this._x2;
  2827. },
  2828. set: function set(x2) {
  2829. this._x2 = x2;
  2830. this._segmentChanged();
  2831. },
  2832. enumerable: true
  2833. });
  2834. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", {
  2835. get: function get() {
  2836. return this._y2;
  2837. },
  2838. set: function set(y2) {
  2839. this._y2 = y2;
  2840. this._segmentChanged();
  2841. },
  2842. enumerable: true
  2843. });
  2844. window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {
  2845. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
  2846. this._x = x;
  2847. this._y = y;
  2848. this._x2 = x2;
  2849. this._y2 = y2;
  2850. };
  2851. window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2852. window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () {
  2853. return "[object SVGPathSegCurvetoCubicSmoothRel]";
  2854. };
  2855. window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () {
  2856. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2857. };
  2858. window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () {
  2859. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2);
  2860. };
  2861. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", {
  2862. get: function get() {
  2863. return this._x;
  2864. },
  2865. set: function set(x) {
  2866. this._x = x;
  2867. this._segmentChanged();
  2868. },
  2869. enumerable: true
  2870. });
  2871. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", {
  2872. get: function get() {
  2873. return this._y;
  2874. },
  2875. set: function set(y) {
  2876. this._y = y;
  2877. this._segmentChanged();
  2878. },
  2879. enumerable: true
  2880. });
  2881. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", {
  2882. get: function get() {
  2883. return this._x2;
  2884. },
  2885. set: function set(x2) {
  2886. this._x2 = x2;
  2887. this._segmentChanged();
  2888. },
  2889. enumerable: true
  2890. });
  2891. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", {
  2892. get: function get() {
  2893. return this._y2;
  2894. },
  2895. set: function set(y2) {
  2896. this._y2 = y2;
  2897. this._segmentChanged();
  2898. },
  2899. enumerable: true
  2900. });
  2901. window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {
  2902. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
  2903. this._x = x;
  2904. this._y = y;
  2905. };
  2906. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2907. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () {
  2908. return "[object SVGPathSegCurvetoQuadraticSmoothAbs]";
  2909. };
  2910. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () {
  2911. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2912. };
  2913. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () {
  2914. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y);
  2915. };
  2916. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", {
  2917. get: function get() {
  2918. return this._x;
  2919. },
  2920. set: function set(x) {
  2921. this._x = x;
  2922. this._segmentChanged();
  2923. },
  2924. enumerable: true
  2925. });
  2926. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", {
  2927. get: function get() {
  2928. return this._y;
  2929. },
  2930. set: function set(y) {
  2931. this._y = y;
  2932. this._segmentChanged();
  2933. },
  2934. enumerable: true
  2935. });
  2936. window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {
  2937. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
  2938. this._x = x;
  2939. this._y = y;
  2940. };
  2941. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2942. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () {
  2943. return "[object SVGPathSegCurvetoQuadraticSmoothRel]";
  2944. };
  2945. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () {
  2946. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2947. };
  2948. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () {
  2949. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y);
  2950. };
  2951. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", {
  2952. get: function get() {
  2953. return this._x;
  2954. },
  2955. set: function set(x) {
  2956. this._x = x;
  2957. this._segmentChanged();
  2958. },
  2959. enumerable: true
  2960. });
  2961. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", {
  2962. get: function get() {
  2963. return this._y;
  2964. },
  2965. set: function set(y) {
  2966. this._y = y;
  2967. this._segmentChanged();
  2968. },
  2969. enumerable: true
  2970. }); // Add createSVGPathSeg* functions to window.SVGPathElement.
  2971. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
  2972. window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {
  2973. return new window.SVGPathSegClosePath(undefined);
  2974. };
  2975. window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) {
  2976. return new window.SVGPathSegMovetoAbs(undefined, x, y);
  2977. };
  2978. window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) {
  2979. return new window.SVGPathSegMovetoRel(undefined, x, y);
  2980. };
  2981. window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) {
  2982. return new window.SVGPathSegLinetoAbs(undefined, x, y);
  2983. };
  2984. window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) {
  2985. return new window.SVGPathSegLinetoRel(undefined, x, y);
  2986. };
  2987. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) {
  2988. return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2);
  2989. };
  2990. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) {
  2991. return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2);
  2992. };
  2993. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) {
  2994. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1);
  2995. };
  2996. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) {
  2997. return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1);
  2998. };
  2999. window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  3000. return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  3001. };
  3002. window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  3003. return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  3004. };
  3005. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) {
  3006. return new window.SVGPathSegLinetoHorizontalAbs(undefined, x);
  3007. };
  3008. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) {
  3009. return new window.SVGPathSegLinetoHorizontalRel(undefined, x);
  3010. };
  3011. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) {
  3012. return new window.SVGPathSegLinetoVerticalAbs(undefined, y);
  3013. };
  3014. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) {
  3015. return new window.SVGPathSegLinetoVerticalRel(undefined, y);
  3016. };
  3017. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) {
  3018. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2);
  3019. };
  3020. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) {
  3021. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2);
  3022. };
  3023. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) {
  3024. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y);
  3025. };
  3026. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) {
  3027. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y);
  3028. };
  3029. if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) {
  3030. // Add getPathSegAtLength to SVGPathElement.
  3031. // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
  3032. // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
  3033. window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {
  3034. if (distance === undefined || !isFinite(distance)) throw "Invalid arguments.";
  3035. var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  3036. measurementElement.setAttribute("d", this.getAttribute("d"));
  3037. var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; // If the path is empty, return 0.
  3038. if (lastPathSegment <= 0) return 0;
  3039. do {
  3040. measurementElement.pathSegList.removeItem(lastPathSegment);
  3041. if (distance > measurementElement.getTotalLength()) break;
  3042. lastPathSegment--;
  3043. } while (lastPathSegment > 0);
  3044. return lastPathSegment;
  3045. };
  3046. }
  3047. }
  3048. if (!("SVGPathSegList" in window)) {
  3049. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
  3050. window.SVGPathSegList = function (pathElement) {
  3051. this._pathElement = pathElement;
  3052. this._list = this._parsePath(this._pathElement.getAttribute("d")); // Use a MutationObserver to catch changes to the path's "d" attribute.
  3053. this._mutationObserverConfig = {
  3054. "attributes": true,
  3055. "attributeFilter": ["d"]
  3056. };
  3057. this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
  3058. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  3059. };
  3060. window.SVGPathSegList.prototype.classname = "SVGPathSegList";
  3061. Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
  3062. get: function get() {
  3063. this._checkPathSynchronizedToList();
  3064. return this._list.length;
  3065. },
  3066. enumerable: true
  3067. }); // Add the pathSegList accessors to window.SVGPathElement.
  3068. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
  3069. Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
  3070. get: function get() {
  3071. if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this);
  3072. return this._pathSegList;
  3073. },
  3074. enumerable: true
  3075. }); // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
  3076. Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", {
  3077. get: function get() {
  3078. return this.pathSegList;
  3079. },
  3080. enumerable: true
  3081. });
  3082. Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", {
  3083. get: function get() {
  3084. return this.pathSegList;
  3085. },
  3086. enumerable: true
  3087. });
  3088. Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", {
  3089. get: function get() {
  3090. return this.pathSegList;
  3091. },
  3092. enumerable: true
  3093. }); // Process any pending mutations to the path element and update the list as needed.
  3094. // This should be the first call of all public functions and is needed because
  3095. // MutationObservers are not synchronous so we can have pending asynchronous mutations.
  3096. window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {
  3097. this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
  3098. };
  3099. window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {
  3100. if (!this._pathElement) return;
  3101. var hasPathMutations = false;
  3102. mutationRecords.forEach(function (record) {
  3103. if (record.attributeName == "d") hasPathMutations = true;
  3104. });
  3105. if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d"));
  3106. }; // Serialize the list and update the path's 'd' attribute.
  3107. window.SVGPathSegList.prototype._writeListToPath = function () {
  3108. this._pathElementMutationObserver.disconnect();
  3109. this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
  3110. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  3111. }; // When a path segment changes the list needs to be synchronized back to the path element.
  3112. window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {
  3113. this._writeListToPath();
  3114. };
  3115. window.SVGPathSegList.prototype.clear = function () {
  3116. this._checkPathSynchronizedToList();
  3117. this._list.forEach(function (pathSeg) {
  3118. pathSeg._owningPathSegList = null;
  3119. });
  3120. this._list = [];
  3121. this._writeListToPath();
  3122. };
  3123. window.SVGPathSegList.prototype.initialize = function (newItem) {
  3124. this._checkPathSynchronizedToList();
  3125. this._list = [newItem];
  3126. newItem._owningPathSegList = this;
  3127. this._writeListToPath();
  3128. return newItem;
  3129. };
  3130. window.SVGPathSegList.prototype._checkValidIndex = function (index) {
  3131. if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR";
  3132. };
  3133. window.SVGPathSegList.prototype.getItem = function (index) {
  3134. this._checkPathSynchronizedToList();
  3135. this._checkValidIndex(index);
  3136. return this._list[index];
  3137. };
  3138. window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {
  3139. this._checkPathSynchronizedToList(); // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
  3140. if (index > this.numberOfItems) index = this.numberOfItems;
  3141. if (newItem._owningPathSegList) {
  3142. // SVG2 spec says to make a copy.
  3143. newItem = newItem.clone();
  3144. }
  3145. this._list.splice(index, 0, newItem);
  3146. newItem._owningPathSegList = this;
  3147. this._writeListToPath();
  3148. return newItem;
  3149. };
  3150. window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {
  3151. this._checkPathSynchronizedToList();
  3152. if (newItem._owningPathSegList) {
  3153. // SVG2 spec says to make a copy.
  3154. newItem = newItem.clone();
  3155. }
  3156. this._checkValidIndex(index);
  3157. this._list[index] = newItem;
  3158. newItem._owningPathSegList = this;
  3159. this._writeListToPath();
  3160. return newItem;
  3161. };
  3162. window.SVGPathSegList.prototype.removeItem = function (index) {
  3163. this._checkPathSynchronizedToList();
  3164. this._checkValidIndex(index);
  3165. var item = this._list[index];
  3166. this._list.splice(index, 1);
  3167. this._writeListToPath();
  3168. return item;
  3169. };
  3170. window.SVGPathSegList.prototype.appendItem = function (newItem) {
  3171. this._checkPathSynchronizedToList();
  3172. if (newItem._owningPathSegList) {
  3173. // SVG2 spec says to make a copy.
  3174. newItem = newItem.clone();
  3175. }
  3176. this._list.push(newItem);
  3177. newItem._owningPathSegList = this; // TODO: Optimize this to just append to the existing attribute.
  3178. this._writeListToPath();
  3179. return newItem;
  3180. };
  3181. window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {
  3182. var string = "";
  3183. var first = true;
  3184. pathSegArray.forEach(function (pathSeg) {
  3185. if (first) {
  3186. first = false;
  3187. string += pathSeg._asPathString();
  3188. } else {
  3189. string += " " + pathSeg._asPathString();
  3190. }
  3191. });
  3192. return string;
  3193. }; // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
  3194. window.SVGPathSegList.prototype._parsePath = function (string) {
  3195. if (!string || string.length == 0) return [];
  3196. var owningPathSegList = this;
  3197. var Builder = function Builder() {
  3198. this.pathSegList = [];
  3199. };
  3200. Builder.prototype.appendSegment = function (pathSeg) {
  3201. this.pathSegList.push(pathSeg);
  3202. };
  3203. var Source = function Source(string) {
  3204. this._string = string;
  3205. this._currentIndex = 0;
  3206. this._endIndex = this._string.length;
  3207. this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
  3208. this._skipOptionalSpaces();
  3209. };
  3210. Source.prototype._isCurrentSpace = function () {
  3211. var character = this._string[this._currentIndex];
  3212. return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
  3213. };
  3214. Source.prototype._skipOptionalSpaces = function () {
  3215. while (this._currentIndex < this._endIndex && this._isCurrentSpace()) {
  3216. this._currentIndex++;
  3217. }
  3218. return this._currentIndex < this._endIndex;
  3219. };
  3220. Source.prototype._skipOptionalSpacesOrDelimiter = function () {
  3221. if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false;
  3222. if (this._skipOptionalSpaces()) {
  3223. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
  3224. this._currentIndex++;
  3225. this._skipOptionalSpaces();
  3226. }
  3227. }
  3228. return this._currentIndex < this._endIndex;
  3229. };
  3230. Source.prototype.hasMoreData = function () {
  3231. return this._currentIndex < this._endIndex;
  3232. };
  3233. Source.prototype.peekSegmentType = function () {
  3234. var lookahead = this._string[this._currentIndex];
  3235. return this._pathSegTypeFromChar(lookahead);
  3236. };
  3237. Source.prototype._pathSegTypeFromChar = function (lookahead) {
  3238. switch (lookahead) {
  3239. case "Z":
  3240. case "z":
  3241. return window.SVGPathSeg.PATHSEG_CLOSEPATH;
  3242. case "M":
  3243. return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
  3244. case "m":
  3245. return window.SVGPathSeg.PATHSEG_MOVETO_REL;
  3246. case "L":
  3247. return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  3248. case "l":
  3249. return window.SVGPathSeg.PATHSEG_LINETO_REL;
  3250. case "C":
  3251. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
  3252. case "c":
  3253. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
  3254. case "Q":
  3255. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
  3256. case "q":
  3257. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
  3258. case "A":
  3259. return window.SVGPathSeg.PATHSEG_ARC_ABS;
  3260. case "a":
  3261. return window.SVGPathSeg.PATHSEG_ARC_REL;
  3262. case "H":
  3263. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
  3264. case "h":
  3265. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
  3266. case "V":
  3267. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
  3268. case "v":
  3269. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
  3270. case "S":
  3271. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
  3272. case "s":
  3273. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
  3274. case "T":
  3275. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
  3276. case "t":
  3277. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
  3278. default:
  3279. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  3280. }
  3281. };
  3282. Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {
  3283. // Check for remaining coordinates in the current command.
  3284. if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
  3285. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  3286. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL;
  3287. return previousCommand;
  3288. }
  3289. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  3290. };
  3291. Source.prototype.initialCommandIsMoveTo = function () {
  3292. // If the path is empty it is still valid, so return true.
  3293. if (!this.hasMoreData()) return true;
  3294. var command = this.peekSegmentType(); // Path must start with moveTo.
  3295. return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
  3296. }; // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
  3297. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
  3298. Source.prototype._parseNumber = function () {
  3299. var exponent = 0;
  3300. var integer = 0;
  3301. var frac = 1;
  3302. var decimal = 0;
  3303. var sign = 1;
  3304. var expsign = 1;
  3305. var startIndex = this._currentIndex;
  3306. this._skipOptionalSpaces(); // Read the sign.
  3307. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
  3308. this._currentIndex++;
  3309. sign = -1;
  3310. }
  3311. if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".") // The first character of a number must be one of [0-9+-.].
  3312. return undefined; // Read the integer part, build right-to-left.
  3313. var startIntPartIndex = this._currentIndex;
  3314. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  3315. this._currentIndex++;
  3316. } // Advance to first non-digit.
  3317. if (this._currentIndex != startIntPartIndex) {
  3318. var scanIntPartIndex = this._currentIndex - 1;
  3319. var multiplier = 1;
  3320. while (scanIntPartIndex >= startIntPartIndex) {
  3321. integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
  3322. multiplier *= 10;
  3323. }
  3324. } // Read the decimals.
  3325. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
  3326. this._currentIndex++; // There must be a least one digit following the .
  3327. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  3328. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  3329. frac *= 10;
  3330. decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
  3331. this._currentIndex += 1;
  3332. }
  3333. } // Read the exponent part.
  3334. if (this._currentIndex != startIndex && this._currentIndex + 1 < this._endIndex && (this._string.charAt(this._currentIndex) == "e" || this._string.charAt(this._currentIndex) == "E") && this._string.charAt(this._currentIndex + 1) != "x" && this._string.charAt(this._currentIndex + 1) != "m") {
  3335. this._currentIndex++; // Read the sign of the exponent.
  3336. if (this._string.charAt(this._currentIndex) == "+") {
  3337. this._currentIndex++;
  3338. } else if (this._string.charAt(this._currentIndex) == "-") {
  3339. this._currentIndex++;
  3340. expsign = -1;
  3341. } // There must be an exponent.
  3342. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  3343. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  3344. exponent *= 10;
  3345. exponent += this._string.charAt(this._currentIndex) - "0";
  3346. this._currentIndex++;
  3347. }
  3348. }
  3349. var number = integer + decimal;
  3350. number *= sign;
  3351. if (exponent) number *= Math.pow(10, expsign * exponent);
  3352. if (startIndex == this._currentIndex) return undefined;
  3353. this._skipOptionalSpacesOrDelimiter();
  3354. return number;
  3355. };
  3356. Source.prototype._parseArcFlag = function () {
  3357. if (this._currentIndex >= this._endIndex) return undefined;
  3358. var flag = false;
  3359. var flagChar = this._string.charAt(this._currentIndex++);
  3360. if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined;
  3361. this._skipOptionalSpacesOrDelimiter();
  3362. return flag;
  3363. };
  3364. Source.prototype.parseSegment = function () {
  3365. var lookahead = this._string[this._currentIndex];
  3366. var command = this._pathSegTypeFromChar(lookahead);
  3367. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
  3368. // Possibly an implicit command. Not allowed if this is the first command.
  3369. if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  3370. command = this._nextCommandHelper(lookahead, this._previousCommand);
  3371. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  3372. } else {
  3373. this._currentIndex++;
  3374. }
  3375. this._previousCommand = command;
  3376. switch (command) {
  3377. case window.SVGPathSeg.PATHSEG_MOVETO_REL:
  3378. return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3379. case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
  3380. return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3381. case window.SVGPathSeg.PATHSEG_LINETO_REL:
  3382. return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3383. case window.SVGPathSeg.PATHSEG_LINETO_ABS:
  3384. return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3385. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
  3386. return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
  3387. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
  3388. return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
  3389. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
  3390. return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
  3391. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
  3392. return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
  3393. case window.SVGPathSeg.PATHSEG_CLOSEPATH:
  3394. this._skipOptionalSpaces();
  3395. return new window.SVGPathSegClosePath(owningPathSegList);
  3396. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
  3397. var points = {
  3398. x1: this._parseNumber(),
  3399. y1: this._parseNumber(),
  3400. x2: this._parseNumber(),
  3401. y2: this._parseNumber(),
  3402. x: this._parseNumber(),
  3403. y: this._parseNumber()
  3404. };
  3405. return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  3406. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
  3407. var points = {
  3408. x1: this._parseNumber(),
  3409. y1: this._parseNumber(),
  3410. x2: this._parseNumber(),
  3411. y2: this._parseNumber(),
  3412. x: this._parseNumber(),
  3413. y: this._parseNumber()
  3414. };
  3415. return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  3416. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
  3417. var points = {
  3418. x2: this._parseNumber(),
  3419. y2: this._parseNumber(),
  3420. x: this._parseNumber(),
  3421. y: this._parseNumber()
  3422. };
  3423. return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
  3424. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
  3425. var points = {
  3426. x2: this._parseNumber(),
  3427. y2: this._parseNumber(),
  3428. x: this._parseNumber(),
  3429. y: this._parseNumber()
  3430. };
  3431. return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
  3432. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
  3433. var points = {
  3434. x1: this._parseNumber(),
  3435. y1: this._parseNumber(),
  3436. x: this._parseNumber(),
  3437. y: this._parseNumber()
  3438. };
  3439. return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
  3440. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
  3441. var points = {
  3442. x1: this._parseNumber(),
  3443. y1: this._parseNumber(),
  3444. x: this._parseNumber(),
  3445. y: this._parseNumber()
  3446. };
  3447. return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
  3448. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
  3449. return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3450. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
  3451. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3452. case window.SVGPathSeg.PATHSEG_ARC_REL:
  3453. var points = {
  3454. x1: this._parseNumber(),
  3455. y1: this._parseNumber(),
  3456. arcAngle: this._parseNumber(),
  3457. arcLarge: this._parseArcFlag(),
  3458. arcSweep: this._parseArcFlag(),
  3459. x: this._parseNumber(),
  3460. y: this._parseNumber()
  3461. };
  3462. return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  3463. case window.SVGPathSeg.PATHSEG_ARC_ABS:
  3464. var points = {
  3465. x1: this._parseNumber(),
  3466. y1: this._parseNumber(),
  3467. arcAngle: this._parseNumber(),
  3468. arcLarge: this._parseArcFlag(),
  3469. arcSweep: this._parseArcFlag(),
  3470. x: this._parseNumber(),
  3471. y: this._parseNumber()
  3472. };
  3473. return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  3474. default:
  3475. throw "Unknown path seg type.";
  3476. }
  3477. };
  3478. var builder = new Builder();
  3479. var source = new Source(string);
  3480. if (!source.initialCommandIsMoveTo()) return [];
  3481. while (source.hasMoreData()) {
  3482. var pathSeg = source.parseSegment();
  3483. if (!pathSeg) return [];
  3484. builder.appendSegment(pathSeg);
  3485. }
  3486. return builder.pathSegList;
  3487. };
  3488. }
  3489. })(); // String.padEnd polyfill for IE11
  3490. //
  3491. // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
  3492. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
  3493. if (!String.prototype.padEnd) {
  3494. String.prototype.padEnd = function padEnd(targetLength, padString) {
  3495. targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
  3496. padString = String(typeof padString !== 'undefined' ? padString : ' ');
  3497. if (this.length > targetLength) {
  3498. return String(this);
  3499. } else {
  3500. targetLength = targetLength - this.length;
  3501. if (targetLength > padString.length) {
  3502. padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
  3503. }
  3504. return String(this) + padString.slice(0, targetLength);
  3505. }
  3506. };
  3507. } // Object.assign polyfill for IE11
  3508. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill
  3509. if (typeof Object.assign !== 'function') {
  3510. // Must be writable: true, enumerable: false, configurable: true
  3511. Object.defineProperty(Object, "assign", {
  3512. value: function assign(target, varArgs) {
  3513. if (target === null || target === undefined) {
  3514. throw new TypeError('Cannot convert undefined or null to object');
  3515. }
  3516. var to = Object(target);
  3517. for (var index = 1; index < arguments.length; index++) {
  3518. var nextSource = arguments[index];
  3519. if (nextSource !== null && nextSource !== undefined) {
  3520. for (var nextKey in nextSource) {
  3521. // Avoid bugs when hasOwnProperty is shadowed
  3522. if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
  3523. to[nextKey] = nextSource[nextKey];
  3524. }
  3525. }
  3526. }
  3527. }
  3528. return to;
  3529. },
  3530. writable: true,
  3531. configurable: true
  3532. });
  3533. }
  3534. /* jshint ignore:end */
  3535. Chart.prototype.axis = function () {};
  3536. Chart.prototype.axis.labels = function (labels) {
  3537. var $$ = this.internal;
  3538. if (arguments.length) {
  3539. Object.keys(labels).forEach(function (axisId) {
  3540. $$.axis.setLabelText(axisId, labels[axisId]);
  3541. });
  3542. $$.axis.updateLabels();
  3543. } // TODO: return some values?
  3544. };
  3545. Chart.prototype.axis.max = function (max) {
  3546. var $$ = this.internal,
  3547. config = $$.config;
  3548. if (arguments.length) {
  3549. if (_typeof(max) === 'object') {
  3550. if (isValue(max.x)) {
  3551. config.axis_x_max = max.x;
  3552. }
  3553. if (isValue(max.y)) {
  3554. config.axis_y_max = max.y;
  3555. }
  3556. if (isValue(max.y2)) {
  3557. config.axis_y2_max = max.y2;
  3558. }
  3559. } else {
  3560. config.axis_y_max = config.axis_y2_max = max;
  3561. }
  3562. $$.redraw({
  3563. withUpdateOrgXDomain: true,
  3564. withUpdateXDomain: true
  3565. });
  3566. } else {
  3567. return {
  3568. x: config.axis_x_max,
  3569. y: config.axis_y_max,
  3570. y2: config.axis_y2_max
  3571. };
  3572. }
  3573. };
  3574. Chart.prototype.axis.min = function (min) {
  3575. var $$ = this.internal,
  3576. config = $$.config;
  3577. if (arguments.length) {
  3578. if (_typeof(min) === 'object') {
  3579. if (isValue(min.x)) {
  3580. config.axis_x_min = min.x;
  3581. }
  3582. if (isValue(min.y)) {
  3583. config.axis_y_min = min.y;
  3584. }
  3585. if (isValue(min.y2)) {
  3586. config.axis_y2_min = min.y2;
  3587. }
  3588. } else {
  3589. config.axis_y_min = config.axis_y2_min = min;
  3590. }
  3591. $$.redraw({
  3592. withUpdateOrgXDomain: true,
  3593. withUpdateXDomain: true
  3594. });
  3595. } else {
  3596. return {
  3597. x: config.axis_x_min,
  3598. y: config.axis_y_min,
  3599. y2: config.axis_y2_min
  3600. };
  3601. }
  3602. };
  3603. Chart.prototype.axis.range = function (range) {
  3604. if (arguments.length) {
  3605. if (isDefined(range.max)) {
  3606. this.axis.max(range.max);
  3607. }
  3608. if (isDefined(range.min)) {
  3609. this.axis.min(range.min);
  3610. }
  3611. } else {
  3612. return {
  3613. max: this.axis.max(),
  3614. min: this.axis.min()
  3615. };
  3616. }
  3617. };
  3618. Chart.prototype.axis.types = function (types) {
  3619. var $$ = this.internal;
  3620. if (types === undefined) {
  3621. return {
  3622. y: $$.config.axis_y_type,
  3623. y2: $$.config.axis_y2_type
  3624. };
  3625. } else {
  3626. if (isDefined(types.y)) {
  3627. $$.config.axis_y_type = types.y;
  3628. }
  3629. if (isDefined(types.y2)) {
  3630. $$.config.axis_y2_type = types.y2;
  3631. }
  3632. $$.updateScales();
  3633. $$.redraw();
  3634. }
  3635. };
  3636. Chart.prototype.category = function (i, category) {
  3637. var $$ = this.internal,
  3638. config = $$.config;
  3639. if (arguments.length > 1) {
  3640. config.axis_x_categories[i] = category;
  3641. $$.redraw();
  3642. }
  3643. return config.axis_x_categories[i];
  3644. };
  3645. Chart.prototype.categories = function (categories) {
  3646. var $$ = this.internal,
  3647. config = $$.config;
  3648. if (!arguments.length) {
  3649. return config.axis_x_categories;
  3650. }
  3651. config.axis_x_categories = categories;
  3652. $$.redraw();
  3653. return config.axis_x_categories;
  3654. };
  3655. Chart.prototype.resize = function (size) {
  3656. var $$ = this.internal,
  3657. config = $$.config;
  3658. config.size_width = size ? size.width : null;
  3659. config.size_height = size ? size.height : null;
  3660. this.flush();
  3661. };
  3662. Chart.prototype.flush = function () {
  3663. var $$ = this.internal;
  3664. $$.updateAndRedraw({
  3665. withLegend: true,
  3666. withTransition: false,
  3667. withTransitionForTransform: false
  3668. });
  3669. };
  3670. Chart.prototype.destroy = function () {
  3671. var $$ = this.internal;
  3672. window.clearInterval($$.intervalForObserveInserted);
  3673. if ($$.resizeTimeout !== undefined) {
  3674. window.clearTimeout($$.resizeTimeout);
  3675. }
  3676. if (window.detachEvent) {
  3677. window.detachEvent('onresize', $$.resizeIfElementDisplayed);
  3678. } else if (window.removeEventListener) {
  3679. window.removeEventListener('resize', $$.resizeIfElementDisplayed);
  3680. } else {
  3681. var wrapper = window.onresize; // check if no one else removed our wrapper and remove our resizeFunction from it
  3682. if (wrapper && wrapper.add && wrapper.remove) {
  3683. wrapper.remove($$.resizeFunction);
  3684. }
  3685. } // Removes the inner resize functions
  3686. $$.resizeFunction.remove(); // Unbinds from the window focus event
  3687. $$.unbindWindowFocus();
  3688. $$.selectChart.classed('c3', false).html(""); // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.
  3689. Object.keys($$).forEach(function (key) {
  3690. $$[key] = null;
  3691. });
  3692. return null;
  3693. };
  3694. Chart.prototype.color = function (id) {
  3695. var $$ = this.internal;
  3696. return $$.color(id); // more patterns
  3697. };
  3698. Chart.prototype.data = function (targetIds) {
  3699. var targets = this.internal.data.targets;
  3700. return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) {
  3701. return [].concat(targetIds).indexOf(t.id) >= 0;
  3702. });
  3703. };
  3704. Chart.prototype.data.shown = function (targetIds) {
  3705. return this.internal.filterTargetsToShow(this.data(targetIds));
  3706. };
  3707. /**
  3708. * Get values of the data loaded in the chart.
  3709. *
  3710. * @param {String|Array} targetId This API returns the value of specified target.
  3711. * @param flat
  3712. * @return {Array} Data values
  3713. */
  3714. Chart.prototype.data.values = function (targetId) {
  3715. var flat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  3716. var values = null;
  3717. if (targetId) {
  3718. var targets = this.data(targetId);
  3719. if (targets && isArray(targets)) {
  3720. values = targets.reduce(function (ret, v) {
  3721. var dataValue = v.values.map(function (d) {
  3722. return d.value;
  3723. });
  3724. if (flat) {
  3725. ret = ret.concat(dataValue);
  3726. } else {
  3727. ret.push(dataValue);
  3728. }
  3729. return ret;
  3730. }, []);
  3731. }
  3732. }
  3733. return values;
  3734. };
  3735. Chart.prototype.data.names = function (names) {
  3736. this.internal.clearLegendItemTextBoxCache();
  3737. return this.internal.updateDataAttributes('names', names);
  3738. };
  3739. Chart.prototype.data.colors = function (colors) {
  3740. return this.internal.updateDataAttributes('colors', colors);
  3741. };
  3742. Chart.prototype.data.axes = function (axes) {
  3743. return this.internal.updateDataAttributes('axes', axes);
  3744. };
  3745. Chart.prototype.data.stackNormalized = function (normalized) {
  3746. if (normalized === undefined) {
  3747. return this.internal.isStackNormalized();
  3748. }
  3749. this.internal.config.data_stack_normalize = !!normalized;
  3750. this.internal.redraw();
  3751. };
  3752. Chart.prototype.donut = function () {};
  3753. Chart.prototype.donut.padAngle = function (padAngle) {
  3754. if (padAngle === undefined) {
  3755. return this.internal.config.donut_padAngle;
  3756. }
  3757. this.internal.config.donut_padAngle = padAngle;
  3758. this.flush();
  3759. };
  3760. Chart.prototype.flow = function (args) {
  3761. var $$ = this.internal,
  3762. targets,
  3763. data,
  3764. notfoundIds = [],
  3765. orgDataCount = $$.getMaxDataCount(),
  3766. dataCount,
  3767. domain,
  3768. baseTarget,
  3769. baseValue,
  3770. length = 0,
  3771. tail = 0,
  3772. diff,
  3773. to;
  3774. if (args.json) {
  3775. data = $$.convertJsonToData(args.json, args.keys);
  3776. } else if (args.rows) {
  3777. data = $$.convertRowsToData(args.rows);
  3778. } else if (args.columns) {
  3779. data = $$.convertColumnsToData(args.columns);
  3780. } else {
  3781. return;
  3782. }
  3783. targets = $$.convertDataToTargets(data, true); // Update/Add data
  3784. $$.data.targets.forEach(function (t) {
  3785. var found = false,
  3786. i,
  3787. j;
  3788. for (i = 0; i < targets.length; i++) {
  3789. if (t.id === targets[i].id) {
  3790. found = true;
  3791. if (t.values[t.values.length - 1]) {
  3792. tail = t.values[t.values.length - 1].index + 1;
  3793. }
  3794. length = targets[i].values.length;
  3795. for (j = 0; j < length; j++) {
  3796. targets[i].values[j].index = tail + j;
  3797. if (!$$.isTimeSeries()) {
  3798. targets[i].values[j].x = tail + j;
  3799. }
  3800. }
  3801. t.values = t.values.concat(targets[i].values);
  3802. targets.splice(i, 1);
  3803. break;
  3804. }
  3805. }
  3806. if (!found) {
  3807. notfoundIds.push(t.id);
  3808. }
  3809. }); // Append null for not found targets
  3810. $$.data.targets.forEach(function (t) {
  3811. var i, j;
  3812. for (i = 0; i < notfoundIds.length; i++) {
  3813. if (t.id === notfoundIds[i]) {
  3814. tail = t.values[t.values.length - 1].index + 1;
  3815. for (j = 0; j < length; j++) {
  3816. t.values.push({
  3817. id: t.id,
  3818. index: tail + j,
  3819. x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
  3820. value: null
  3821. });
  3822. }
  3823. }
  3824. }
  3825. }); // Generate null values for new target
  3826. if ($$.data.targets.length) {
  3827. targets.forEach(function (t) {
  3828. var i,
  3829. missing = [];
  3830. for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
  3831. missing.push({
  3832. id: t.id,
  3833. index: i,
  3834. x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
  3835. value: null
  3836. });
  3837. }
  3838. t.values.forEach(function (v) {
  3839. v.index += tail;
  3840. if (!$$.isTimeSeries()) {
  3841. v.x += tail;
  3842. }
  3843. });
  3844. t.values = missing.concat(t.values);
  3845. });
  3846. }
  3847. $$.data.targets = $$.data.targets.concat(targets); // add remained
  3848. // check data count because behavior needs to change when it's only one
  3849. dataCount = $$.getMaxDataCount();
  3850. baseTarget = $$.data.targets[0];
  3851. baseValue = baseTarget.values[0]; // Update length to flow if needed
  3852. if (isDefined(args.to)) {
  3853. length = 0;
  3854. to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
  3855. baseTarget.values.forEach(function (v) {
  3856. if (v.x < to) {
  3857. length++;
  3858. }
  3859. });
  3860. } else if (isDefined(args.length)) {
  3861. length = args.length;
  3862. } // If only one data, update the domain to flow from left edge of the chart
  3863. if (!orgDataCount) {
  3864. if ($$.isTimeSeries()) {
  3865. if (baseTarget.values.length > 1) {
  3866. diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
  3867. } else {
  3868. diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
  3869. }
  3870. } else {
  3871. diff = 1;
  3872. }
  3873. domain = [baseValue.x - diff, baseValue.x];
  3874. $$.updateXDomain(null, true, true, false, domain);
  3875. } else if (orgDataCount === 1) {
  3876. if ($$.isTimeSeries()) {
  3877. diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
  3878. domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
  3879. $$.updateXDomain(null, true, true, false, domain);
  3880. }
  3881. } // Set targets
  3882. $$.updateTargets($$.data.targets); // Redraw with new targets
  3883. $$.redraw({
  3884. flow: {
  3885. index: baseValue.index,
  3886. length: length,
  3887. duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
  3888. done: args.done,
  3889. orgDataCount: orgDataCount
  3890. },
  3891. withLegend: true,
  3892. withTransition: orgDataCount > 1,
  3893. withTrimXDomain: false,
  3894. withUpdateXAxis: true
  3895. });
  3896. };
  3897. ChartInternal.prototype.generateFlow = function (args) {
  3898. var $$ = this,
  3899. config = $$.config,
  3900. d3 = $$.d3;
  3901. return function () {
  3902. var targets = args.targets,
  3903. flow = args.flow,
  3904. drawBar = args.drawBar,
  3905. drawLine = args.drawLine,
  3906. drawArea = args.drawArea,
  3907. cx = args.cx,
  3908. cy = args.cy,
  3909. xv = args.xv,
  3910. xForText = args.xForText,
  3911. yForText = args.yForText,
  3912. duration = args.duration;
  3913. var translateX,
  3914. scaleX = 1,
  3915. transform,
  3916. flowIndex = flow.index,
  3917. flowLength = flow.length,
  3918. flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),
  3919. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength),
  3920. orgDomain = $$.x.domain(),
  3921. domain,
  3922. durationForFlow = flow.duration || duration,
  3923. done = flow.done || function () {},
  3924. wait = $$.generateWait();
  3925. var xgrid, xgridLines, mainRegion, mainText, mainBar, mainLine, mainArea, mainCircle; // set flag
  3926. $$.flowing = true; // remove head data after rendered
  3927. $$.data.targets.forEach(function (d) {
  3928. d.values.splice(0, flowLength);
  3929. }); // update x domain to generate axis elements for flow
  3930. domain = $$.updateXDomain(targets, true, true); // update elements related to x scale
  3931. if ($$.updateXGrid) {
  3932. $$.updateXGrid(true);
  3933. }
  3934. xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid
  3935. xgridLines = $$.xgridLines || d3.selectAll([]);
  3936. mainRegion = $$.mainRegion || d3.selectAll([]);
  3937. mainText = $$.mainText || d3.selectAll([]);
  3938. mainBar = $$.mainBar || d3.selectAll([]);
  3939. mainLine = $$.mainLine || d3.selectAll([]);
  3940. mainArea = $$.mainArea || d3.selectAll([]);
  3941. mainCircle = $$.mainCircle || d3.selectAll([]); // generate transform to flow
  3942. if (!flow.orgDataCount) {
  3943. // if empty
  3944. if ($$.data.targets[0].values.length !== 1) {
  3945. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3946. } else {
  3947. if ($$.isTimeSeries()) {
  3948. flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);
  3949. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);
  3950. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3951. } else {
  3952. translateX = diffDomain(domain) / 2;
  3953. }
  3954. }
  3955. } else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {
  3956. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3957. } else {
  3958. if ($$.isTimeSeries()) {
  3959. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3960. } else {
  3961. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3962. }
  3963. }
  3964. scaleX = diffDomain(orgDomain) / diffDomain(domain);
  3965. transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';
  3966. $$.hideXGridFocus();
  3967. var flowTransition = d3.transition().ease(d3.easeLinear).duration(durationForFlow);
  3968. wait.add($$.xAxis($$.axes.x, flowTransition));
  3969. wait.add(mainBar.transition(flowTransition).attr('transform', transform));
  3970. wait.add(mainLine.transition(flowTransition).attr('transform', transform));
  3971. wait.add(mainArea.transition(flowTransition).attr('transform', transform));
  3972. wait.add(mainCircle.transition(flowTransition).attr('transform', transform));
  3973. wait.add(mainText.transition(flowTransition).attr('transform', transform));
  3974. wait.add(mainRegion.filter($$.isRegionOnX).transition(flowTransition).attr('transform', transform));
  3975. wait.add(xgrid.transition(flowTransition).attr('transform', transform));
  3976. wait.add(xgridLines.transition(flowTransition).attr('transform', transform));
  3977. wait(function () {
  3978. var i,
  3979. shapes = [],
  3980. texts = []; // remove flowed elements
  3981. if (flowLength) {
  3982. for (i = 0; i < flowLength; i++) {
  3983. shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));
  3984. texts.push('.' + CLASS.text + '-' + (flowIndex + i));
  3985. }
  3986. $$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove();
  3987. $$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove();
  3988. $$.svg.select('.' + CLASS.xgrid).remove();
  3989. } // draw again for removing flowed elements and reverting attr
  3990. xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity);
  3991. xgridLines.attr('transform', null);
  3992. xgridLines.select('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv);
  3993. xgridLines.select('text').attr("x", config.axis_rotated ? $$.width : 0).attr("y", xv);
  3994. mainBar.attr('transform', null).attr("d", drawBar);
  3995. mainLine.attr('transform', null).attr("d", drawLine);
  3996. mainArea.attr('transform', null).attr("d", drawArea);
  3997. mainCircle.attr('transform', null).attr("cx", cx).attr("cy", cy);
  3998. mainText.attr('transform', null).attr('x', xForText).attr('y', yForText).style('fill-opacity', $$.opacityForText.bind($$));
  3999. mainRegion.attr('transform', null);
  4000. mainRegion.filter($$.isRegionOnX).attr("x", $$.regionX.bind($$)).attr("width", $$.regionWidth.bind($$)); // callback for end of flow
  4001. done();
  4002. $$.flowing = false;
  4003. });
  4004. };
  4005. };
  4006. Chart.prototype.focus = function (targetIds) {
  4007. var $$ = this.internal,
  4008. candidates;
  4009. targetIds = $$.mapToTargetIds(targetIds);
  4010. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), this.revert();
  4011. this.defocus();
  4012. candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);
  4013. if ($$.hasArcType()) {
  4014. $$.expandArc(targetIds);
  4015. }
  4016. $$.toggleFocusLegend(targetIds, true);
  4017. $$.focusedTargetIds = targetIds;
  4018. $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) {
  4019. return targetIds.indexOf(id) < 0;
  4020. });
  4021. };
  4022. Chart.prototype.defocus = function (targetIds) {
  4023. var $$ = this.internal,
  4024. candidates;
  4025. targetIds = $$.mapToTargetIds(targetIds);
  4026. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);
  4027. if ($$.hasArcType()) {
  4028. $$.unexpandArc(targetIds);
  4029. }
  4030. $$.toggleFocusLegend(targetIds, false);
  4031. $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) {
  4032. return targetIds.indexOf(id) < 0;
  4033. });
  4034. $$.defocusedTargetIds = targetIds;
  4035. };
  4036. Chart.prototype.revert = function (targetIds) {
  4037. var $$ = this.internal,
  4038. candidates;
  4039. targetIds = $$.mapToTargetIds(targetIds);
  4040. candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets
  4041. candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);
  4042. if ($$.hasArcType()) {
  4043. $$.unexpandArc(targetIds);
  4044. }
  4045. if ($$.config.legend_show) {
  4046. $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));
  4047. $$.legend.selectAll($$.selectorLegends(targetIds)).filter(function () {
  4048. return $$.d3.select(this).classed(CLASS.legendItemFocused);
  4049. }).classed(CLASS.legendItemFocused, false);
  4050. }
  4051. $$.focusedTargetIds = [];
  4052. $$.defocusedTargetIds = [];
  4053. };
  4054. Chart.prototype.xgrids = function (grids) {
  4055. var $$ = this.internal,
  4056. config = $$.config;
  4057. if (!grids) {
  4058. return config.grid_x_lines;
  4059. }
  4060. config.grid_x_lines = grids;
  4061. $$.redrawWithoutRescale();
  4062. return config.grid_x_lines;
  4063. };
  4064. Chart.prototype.xgrids.add = function (grids) {
  4065. var $$ = this.internal;
  4066. return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []));
  4067. };
  4068. Chart.prototype.xgrids.remove = function (params) {
  4069. // TODO: multiple
  4070. var $$ = this.internal;
  4071. $$.removeGridLines(params, true);
  4072. };
  4073. Chart.prototype.ygrids = function (grids) {
  4074. var $$ = this.internal,
  4075. config = $$.config;
  4076. if (!grids) {
  4077. return config.grid_y_lines;
  4078. }
  4079. config.grid_y_lines = grids;
  4080. $$.redrawWithoutRescale();
  4081. return config.grid_y_lines;
  4082. };
  4083. Chart.prototype.ygrids.add = function (grids) {
  4084. var $$ = this.internal;
  4085. return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []));
  4086. };
  4087. Chart.prototype.ygrids.remove = function (params) {
  4088. // TODO: multiple
  4089. var $$ = this.internal;
  4090. $$.removeGridLines(params, false);
  4091. };
  4092. Chart.prototype.groups = function (groups) {
  4093. var $$ = this.internal,
  4094. config = $$.config;
  4095. if (isUndefined(groups)) {
  4096. return config.data_groups;
  4097. }
  4098. config.data_groups = groups;
  4099. $$.redraw();
  4100. return config.data_groups;
  4101. };
  4102. Chart.prototype.legend = function () {};
  4103. Chart.prototype.legend.show = function (targetIds) {
  4104. var $$ = this.internal;
  4105. $$.showLegend($$.mapToTargetIds(targetIds));
  4106. $$.updateAndRedraw({
  4107. withLegend: true
  4108. });
  4109. };
  4110. Chart.prototype.legend.hide = function (targetIds) {
  4111. var $$ = this.internal;
  4112. $$.hideLegend($$.mapToTargetIds(targetIds));
  4113. $$.updateAndRedraw({
  4114. withLegend: false
  4115. });
  4116. };
  4117. Chart.prototype.load = function (args) {
  4118. var $$ = this.internal,
  4119. config = $$.config; // update xs if specified
  4120. if (args.xs) {
  4121. $$.addXs(args.xs);
  4122. } // update names if exists
  4123. if ('names' in args) {
  4124. Chart.prototype.data.names.bind(this)(args.names);
  4125. } // update classes if exists
  4126. if ('classes' in args) {
  4127. Object.keys(args.classes).forEach(function (id) {
  4128. config.data_classes[id] = args.classes[id];
  4129. });
  4130. } // update categories if exists
  4131. if ('categories' in args && $$.isCategorized()) {
  4132. config.axis_x_categories = args.categories;
  4133. } // update axes if exists
  4134. if ('axes' in args) {
  4135. Object.keys(args.axes).forEach(function (id) {
  4136. config.data_axes[id] = args.axes[id];
  4137. });
  4138. } // update colors if exists
  4139. if ('colors' in args) {
  4140. Object.keys(args.colors).forEach(function (id) {
  4141. config.data_colors[id] = args.colors[id];
  4142. });
  4143. } // use cache if exists
  4144. if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {
  4145. $$.load($$.getCaches(args.cacheIds), args.done);
  4146. return;
  4147. } // unload if needed
  4148. if (args.unload) {
  4149. // TODO: do not unload if target will load (included in url/rows/columns)
  4150. $$.unload($$.mapToTargetIds(args.unload === true ? null : args.unload), function () {
  4151. $$.loadFromArgs(args);
  4152. });
  4153. } else {
  4154. $$.loadFromArgs(args);
  4155. }
  4156. };
  4157. Chart.prototype.unload = function (args) {
  4158. var $$ = this.internal;
  4159. args = args || {};
  4160. if (args instanceof Array) {
  4161. args = {
  4162. ids: args
  4163. };
  4164. } else if (typeof args === 'string') {
  4165. args = {
  4166. ids: [args]
  4167. };
  4168. }
  4169. $$.unload($$.mapToTargetIds(args.ids), function () {
  4170. $$.redraw({
  4171. withUpdateOrgXDomain: true,
  4172. withUpdateXDomain: true,
  4173. withLegend: true
  4174. });
  4175. if (args.done) {
  4176. args.done();
  4177. }
  4178. });
  4179. };
  4180. Chart.prototype.pie = function () {};
  4181. Chart.prototype.pie.padAngle = function (padAngle) {
  4182. if (padAngle === undefined) {
  4183. return this.internal.config.pie_padAngle;
  4184. }
  4185. this.internal.config.pie_padAngle = padAngle;
  4186. this.flush();
  4187. };
  4188. Chart.prototype.regions = function (regions) {
  4189. var $$ = this.internal,
  4190. config = $$.config;
  4191. if (!regions) {
  4192. return config.regions;
  4193. }
  4194. config.regions = regions;
  4195. $$.redrawWithoutRescale();
  4196. return config.regions;
  4197. };
  4198. Chart.prototype.regions.add = function (regions) {
  4199. var $$ = this.internal,
  4200. config = $$.config;
  4201. if (!regions) {
  4202. return config.regions;
  4203. }
  4204. config.regions = config.regions.concat(regions);
  4205. $$.redrawWithoutRescale();
  4206. return config.regions;
  4207. };
  4208. Chart.prototype.regions.remove = function (options) {
  4209. var $$ = this.internal,
  4210. config = $$.config,
  4211. duration,
  4212. classes,
  4213. regions;
  4214. options = options || {};
  4215. duration = getOption(options, "duration", config.transition_duration);
  4216. classes = getOption(options, "classes", [CLASS.region]);
  4217. regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) {
  4218. return '.' + c;
  4219. }));
  4220. (duration ? regions.transition().duration(duration) : regions).style('opacity', 0).remove();
  4221. config.regions = config.regions.filter(function (region) {
  4222. var found = false;
  4223. if (!region['class']) {
  4224. return true;
  4225. }
  4226. region['class'].split(' ').forEach(function (c) {
  4227. if (classes.indexOf(c) >= 0) {
  4228. found = true;
  4229. }
  4230. });
  4231. return !found;
  4232. });
  4233. return config.regions;
  4234. };
  4235. Chart.prototype.selected = function (targetId) {
  4236. var $$ = this.internal,
  4237. d3 = $$.d3;
  4238. return $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape).filter(function () {
  4239. return d3.select(this).classed(CLASS.SELECTED);
  4240. }).nodes().map(function (d) {
  4241. var data = d.__data__;
  4242. return data.data ? data.data : data;
  4243. });
  4244. };
  4245. Chart.prototype.select = function (ids, indices, resetOther) {
  4246. var $$ = this.internal,
  4247. d3 = $$.d3,
  4248. config = $$.config;
  4249. if (!config.data_selection_enabled) {
  4250. return;
  4251. }
  4252. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  4253. var shape = d3.select(this),
  4254. id = d.data ? d.data.id : d.id,
  4255. toggle = $$.getToggle(this, d).bind($$),
  4256. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  4257. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  4258. isSelected = shape.classed(CLASS.SELECTED); // line/area selection not supported yet
  4259. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  4260. return;
  4261. }
  4262. if (isTargetId && isTargetIndex) {
  4263. if (config.data_selection_isselectable(d) && !isSelected) {
  4264. toggle(true, shape.classed(CLASS.SELECTED, true), d, i);
  4265. }
  4266. } else if (isDefined(resetOther) && resetOther) {
  4267. if (isSelected) {
  4268. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  4269. }
  4270. }
  4271. });
  4272. };
  4273. Chart.prototype.unselect = function (ids, indices) {
  4274. var $$ = this.internal,
  4275. d3 = $$.d3,
  4276. config = $$.config;
  4277. if (!config.data_selection_enabled) {
  4278. return;
  4279. }
  4280. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  4281. var shape = d3.select(this),
  4282. id = d.data ? d.data.id : d.id,
  4283. toggle = $$.getToggle(this, d).bind($$),
  4284. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  4285. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  4286. isSelected = shape.classed(CLASS.SELECTED); // line/area selection not supported yet
  4287. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  4288. return;
  4289. }
  4290. if (isTargetId && isTargetIndex) {
  4291. if (config.data_selection_isselectable(d)) {
  4292. if (isSelected) {
  4293. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  4294. }
  4295. }
  4296. }
  4297. });
  4298. };
  4299. Chart.prototype.show = function (targetIds, options) {
  4300. var $$ = this.internal,
  4301. targets;
  4302. targetIds = $$.mapToTargetIds(targetIds);
  4303. options = options || {};
  4304. $$.removeHiddenTargetIds(targetIds);
  4305. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  4306. targets.transition().style('display', isIE() ? 'block' : 'initial', 'important').style('opacity', 1, 'important').call($$.endall, function () {
  4307. targets.style('opacity', null).style('opacity', 1);
  4308. });
  4309. if (options.withLegend) {
  4310. $$.showLegend(targetIds);
  4311. }
  4312. $$.redraw({
  4313. withUpdateOrgXDomain: true,
  4314. withUpdateXDomain: true,
  4315. withLegend: true
  4316. });
  4317. };
  4318. Chart.prototype.hide = function (targetIds, options) {
  4319. var $$ = this.internal,
  4320. targets;
  4321. targetIds = $$.mapToTargetIds(targetIds);
  4322. options = options || {};
  4323. $$.addHiddenTargetIds(targetIds);
  4324. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  4325. targets.transition().style('opacity', 0, 'important').call($$.endall, function () {
  4326. targets.style('opacity', null).style('opacity', 0);
  4327. targets.style('display', 'none');
  4328. });
  4329. if (options.withLegend) {
  4330. $$.hideLegend(targetIds);
  4331. }
  4332. $$.redraw({
  4333. withUpdateOrgXDomain: true,
  4334. withUpdateXDomain: true,
  4335. withLegend: true
  4336. });
  4337. };
  4338. Chart.prototype.toggle = function (targetIds, options) {
  4339. var that = this,
  4340. $$ = this.internal;
  4341. $$.mapToTargetIds(targetIds).forEach(function (targetId) {
  4342. $$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options);
  4343. });
  4344. };
  4345. Chart.prototype.subchart = function () {};
  4346. Chart.prototype.subchart.isShown = function () {
  4347. var $$ = this.internal;
  4348. return $$.config.subchart_show;
  4349. };
  4350. Chart.prototype.subchart.show = function () {
  4351. var $$ = this.internal;
  4352. if ($$.config.subchart_show) {
  4353. return;
  4354. }
  4355. $$.config.subchart_show = true; // insert DOM
  4356. $$.initSubchart(); // update dimensions with sub chart now visible
  4357. $$.updateDimension(); // insert brush (depends on sizes previously updated)
  4358. $$.initSubchartBrush(); // attach data
  4359. $$.updateTargetsForSubchart($$.getTargets()); // reset fade-in state
  4360. $$.mapToIds($$.data.targets).forEach(function (id) {
  4361. $$.withoutFadeIn[id] = false;
  4362. }); // redraw chart !
  4363. $$.updateAndRedraw(); // update visible targets !
  4364. $$.showTargets();
  4365. };
  4366. Chart.prototype.subchart.hide = function () {
  4367. var $$ = this.internal;
  4368. if (!$$.config.subchart_show) {
  4369. return;
  4370. }
  4371. $$.config.subchart_show = false; // remove DOM
  4372. $$.removeSubchart(); // re-render chart
  4373. $$.redraw();
  4374. };
  4375. Chart.prototype.tooltip = function () {};
  4376. Chart.prototype.tooltip.show = function (args) {
  4377. var $$ = this.internal,
  4378. targets,
  4379. data,
  4380. mouse = {}; // determine mouse position on the chart
  4381. if (args.mouse) {
  4382. mouse = args.mouse;
  4383. } else {
  4384. // determine focus data
  4385. if (args.data) {
  4386. data = args.data;
  4387. } else if (typeof args.x !== 'undefined') {
  4388. if (args.id) {
  4389. targets = $$.data.targets.filter(function (t) {
  4390. return t.id === args.id;
  4391. });
  4392. } else {
  4393. targets = $$.data.targets;
  4394. }
  4395. data = $$.filterByX(targets, args.x).slice(0, 1)[0];
  4396. }
  4397. mouse = data ? $$.getMousePosition(data) : null;
  4398. } // emulate mouse events to show
  4399. $$.dispatchEvent('mousemove', mouse);
  4400. $$.config.tooltip_onshow.call($$, data);
  4401. };
  4402. Chart.prototype.tooltip.hide = function () {
  4403. // TODO: get target data by checking the state of focus
  4404. this.internal.dispatchEvent('mouseout', 0);
  4405. this.internal.config.tooltip_onhide.call(this);
  4406. };
  4407. Chart.prototype.transform = function (type, targetIds) {
  4408. var $$ = this.internal,
  4409. options = ['pie', 'donut'].indexOf(type) >= 0 ? {
  4410. withTransform: true
  4411. } : null;
  4412. $$.transformTo(targetIds, type, options);
  4413. };
  4414. ChartInternal.prototype.transformTo = function (targetIds, type, optionsForRedraw) {
  4415. var $$ = this,
  4416. withTransitionForAxis = !$$.hasArcType(),
  4417. options = optionsForRedraw || {
  4418. withTransitionForAxis: withTransitionForAxis
  4419. };
  4420. options.withTransitionForTransform = false;
  4421. $$.transiting = false;
  4422. $$.setTargetType(targetIds, type);
  4423. $$.updateTargets($$.data.targets); // this is needed when transforming to arc
  4424. $$.updateAndRedraw(options);
  4425. };
  4426. Chart.prototype.x = function (x) {
  4427. var $$ = this.internal;
  4428. if (arguments.length) {
  4429. $$.updateTargetX($$.data.targets, x);
  4430. $$.redraw({
  4431. withUpdateOrgXDomain: true,
  4432. withUpdateXDomain: true
  4433. });
  4434. }
  4435. return $$.data.xs;
  4436. };
  4437. Chart.prototype.xs = function (xs) {
  4438. var $$ = this.internal;
  4439. if (arguments.length) {
  4440. $$.updateTargetXs($$.data.targets, xs);
  4441. $$.redraw({
  4442. withUpdateOrgXDomain: true,
  4443. withUpdateXDomain: true
  4444. });
  4445. }
  4446. return $$.data.xs;
  4447. };
  4448. Chart.prototype.zoom = function (domain) {
  4449. var $$ = this.internal;
  4450. if (domain) {
  4451. if ($$.isTimeSeries()) {
  4452. domain = domain.map(function (x) {
  4453. return $$.parseDate(x);
  4454. });
  4455. }
  4456. if ($$.config.subchart_show) {
  4457. $$.brush.selectionAsValue(domain, true);
  4458. } else {
  4459. $$.updateXDomain(null, true, false, false, domain);
  4460. $$.redraw({
  4461. withY: $$.config.zoom_rescale,
  4462. withSubchart: false
  4463. });
  4464. }
  4465. $$.config.zoom_onzoom.call(this, $$.x.orgDomain());
  4466. return domain;
  4467. } else {
  4468. return $$.x.domain();
  4469. }
  4470. };
  4471. Chart.prototype.zoom.enable = function (enabled) {
  4472. var $$ = this.internal;
  4473. $$.config.zoom_enabled = enabled;
  4474. $$.updateAndRedraw();
  4475. };
  4476. Chart.prototype.unzoom = function () {
  4477. var $$ = this.internal;
  4478. if ($$.config.subchart_show) {
  4479. $$.brush.clear();
  4480. } else {
  4481. $$.updateXDomain(null, true, false, false, $$.subX.domain());
  4482. $$.redraw({
  4483. withY: $$.config.zoom_rescale,
  4484. withSubchart: false
  4485. });
  4486. }
  4487. };
  4488. Chart.prototype.zoom.max = function (max) {
  4489. var $$ = this.internal,
  4490. config = $$.config,
  4491. d3 = $$.d3;
  4492. if (max === 0 || max) {
  4493. config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);
  4494. } else {
  4495. return config.zoom_x_max;
  4496. }
  4497. };
  4498. Chart.prototype.zoom.min = function (min) {
  4499. var $$ = this.internal,
  4500. config = $$.config,
  4501. d3 = $$.d3;
  4502. if (min === 0 || min) {
  4503. config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);
  4504. } else {
  4505. return config.zoom_x_min;
  4506. }
  4507. };
  4508. Chart.prototype.zoom.range = function (range) {
  4509. if (arguments.length) {
  4510. if (isDefined(range.max)) {
  4511. this.domain.max(range.max);
  4512. }
  4513. if (isDefined(range.min)) {
  4514. this.domain.min(range.min);
  4515. }
  4516. } else {
  4517. return {
  4518. max: this.domain.max(),
  4519. min: this.domain.min()
  4520. };
  4521. }
  4522. };
  4523. ChartInternal.prototype.initPie = function () {
  4524. var $$ = this,
  4525. d3 = $$.d3;
  4526. $$.pie = d3.pie().padAngle(this.getPadAngle.bind(this)).value(function (d) {
  4527. return d.values.reduce(function (a, b) {
  4528. return a + b.value;
  4529. }, 0);
  4530. });
  4531. var orderFct = $$.getOrderFunction(); // we need to reverse the returned order if asc or desc to have the slice in expected order.
  4532. if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {
  4533. var defaultSort = orderFct;
  4534. orderFct = function orderFct(t1, t2) {
  4535. return defaultSort(t1, t2) * -1;
  4536. };
  4537. }
  4538. $$.pie.sort(orderFct || null);
  4539. };
  4540. ChartInternal.prototype.updateRadius = function () {
  4541. var $$ = this,
  4542. config = $$.config,
  4543. w = config.gauge_width || config.donut_width,
  4544. gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length * $$.config.gauge_arcs_minWidth;
  4545. $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2 * ($$.hasType('gauge') ? 0.85 : 1);
  4546. $$.radius = $$.radiusExpanded * 0.95;
  4547. $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;
  4548. $$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0;
  4549. $$.gaugeArcWidth = w ? w : gaugeArcWidth <= $$.radius - $$.innerRadius ? $$.radius - $$.innerRadius : gaugeArcWidth <= $$.radius ? gaugeArcWidth : $$.radius;
  4550. };
  4551. ChartInternal.prototype.getPadAngle = function () {
  4552. if (this.hasType('pie')) {
  4553. return this.config.pie_padAngle || 0;
  4554. } else if (this.hasType('donut')) {
  4555. return this.config.donut_padAngle || 0;
  4556. } else {
  4557. return 0;
  4558. }
  4559. };
  4560. ChartInternal.prototype.updateArc = function () {
  4561. var $$ = this;
  4562. $$.svgArc = $$.getSvgArc();
  4563. $$.svgArcExpanded = $$.getSvgArcExpanded();
  4564. $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);
  4565. };
  4566. ChartInternal.prototype.updateAngle = function (d) {
  4567. var $$ = this,
  4568. config = $$.config,
  4569. found = false,
  4570. index = 0,
  4571. gMin,
  4572. gMax,
  4573. gTic,
  4574. gValue;
  4575. if (!config) {
  4576. return null;
  4577. }
  4578. $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) {
  4579. if (!found && t.data.id === d.data.id) {
  4580. found = true;
  4581. d = t;
  4582. d.index = index;
  4583. }
  4584. index++;
  4585. });
  4586. if (isNaN(d.startAngle)) {
  4587. d.startAngle = 0;
  4588. }
  4589. if (isNaN(d.endAngle)) {
  4590. d.endAngle = d.startAngle;
  4591. }
  4592. if ($$.isGaugeType(d.data)) {
  4593. gMin = config.gauge_min;
  4594. gMax = config.gauge_max;
  4595. gTic = Math.PI * (config.gauge_fullCircle ? 2 : 1) / (gMax - gMin);
  4596. gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;
  4597. d.startAngle = config.gauge_startingAngle;
  4598. d.endAngle = d.startAngle + gTic * gValue;
  4599. }
  4600. return found ? d : null;
  4601. };
  4602. ChartInternal.prototype.getSvgArc = function () {
  4603. var $$ = this,
  4604. hasGaugeType = $$.hasType('gauge'),
  4605. singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,
  4606. arc = $$.d3.arc().outerRadius(function (d) {
  4607. return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius;
  4608. }).innerRadius(function (d) {
  4609. return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius;
  4610. }),
  4611. newArc = function newArc(d, withoutUpdate) {
  4612. var updated;
  4613. if (withoutUpdate) {
  4614. return arc(d);
  4615. } // for interpolate
  4616. updated = $$.updateAngle(d);
  4617. return updated ? arc(updated) : "M 0 0";
  4618. }; // TODO: extends all function
  4619. newArc.centroid = arc.centroid;
  4620. return newArc;
  4621. };
  4622. ChartInternal.prototype.getSvgArcExpanded = function (rate) {
  4623. rate = rate || 1;
  4624. var $$ = this,
  4625. hasGaugeType = $$.hasType('gauge'),
  4626. singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,
  4627. expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100),
  4628. arc = $$.d3.arc().outerRadius(function (d) {
  4629. return hasGaugeType ? $$.radius - singleArcWidth * d.index + expandWidth : $$.radiusExpanded * rate;
  4630. }).innerRadius(function (d) {
  4631. return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius;
  4632. });
  4633. return function (d) {
  4634. var updated = $$.updateAngle(d);
  4635. return updated ? arc(updated) : "M 0 0";
  4636. };
  4637. };
  4638. ChartInternal.prototype.getArc = function (d, withoutUpdate, force) {
  4639. return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0";
  4640. };
  4641. ChartInternal.prototype.transformForArcLabel = function (d) {
  4642. var $$ = this,
  4643. config = $$.config,
  4644. updated = $$.updateAngle(d),
  4645. c,
  4646. x,
  4647. y,
  4648. h,
  4649. ratio,
  4650. translate = "",
  4651. hasGauge = $$.hasType('gauge');
  4652. if (updated && !hasGauge) {
  4653. c = this.svgArc.centroid(updated);
  4654. x = isNaN(c[0]) ? 0 : c[0];
  4655. y = isNaN(c[1]) ? 0 : c[1];
  4656. h = Math.sqrt(x * x + y * y);
  4657. if ($$.hasType('donut') && config.donut_label_ratio) {
  4658. ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio;
  4659. } else if ($$.hasType('pie') && config.pie_label_ratio) {
  4660. ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio;
  4661. } else {
  4662. ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0;
  4663. }
  4664. translate = "translate(" + x * ratio + ',' + y * ratio + ")";
  4665. } else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) {
  4666. var y1 = Math.sin(updated.endAngle - Math.PI / 2);
  4667. x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25);
  4668. y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3;
  4669. translate = "translate(" + x + ',' + y + ")";
  4670. }
  4671. return translate;
  4672. };
  4673. /**
  4674. * @deprecated Use `getRatio('arc', d)` instead.
  4675. */
  4676. ChartInternal.prototype.getArcRatio = function (d) {
  4677. return this.getRatio('arc', d);
  4678. };
  4679. ChartInternal.prototype.convertToArcData = function (d) {
  4680. return this.addName({
  4681. id: d.data.id,
  4682. value: d.value,
  4683. ratio: this.getRatio('arc', d),
  4684. index: d.index
  4685. });
  4686. };
  4687. ChartInternal.prototype.textForArcLabel = function (d) {
  4688. var $$ = this,
  4689. updated,
  4690. value,
  4691. ratio,
  4692. id,
  4693. format;
  4694. if (!$$.shouldShowArcLabel()) {
  4695. return "";
  4696. }
  4697. updated = $$.updateAngle(d);
  4698. value = updated ? updated.value : null;
  4699. ratio = $$.getRatio('arc', updated);
  4700. id = d.data.id;
  4701. if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {
  4702. return "";
  4703. }
  4704. format = $$.getArcLabelFormat();
  4705. return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio);
  4706. };
  4707. ChartInternal.prototype.textForGaugeMinMax = function (value, isMax) {
  4708. var $$ = this,
  4709. format = $$.getGaugeLabelExtents();
  4710. return format ? format(value, isMax) : value;
  4711. };
  4712. ChartInternal.prototype.expandArc = function (targetIds) {
  4713. var $$ = this,
  4714. interval; // MEMO: avoid to cancel transition
  4715. if ($$.transiting) {
  4716. interval = window.setInterval(function () {
  4717. if (!$$.transiting) {
  4718. window.clearInterval(interval);
  4719. if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {
  4720. $$.expandArc(targetIds);
  4721. }
  4722. }
  4723. }, 10);
  4724. return;
  4725. }
  4726. targetIds = $$.mapToTargetIds(targetIds);
  4727. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).each(function (d) {
  4728. if (!$$.shouldExpand(d.data.id)) {
  4729. return;
  4730. }
  4731. $$.d3.select(this).selectAll('path').transition().duration($$.expandDuration(d.data.id)).attr("d", $$.svgArcExpanded).transition().duration($$.expandDuration(d.data.id) * 2).attr("d", $$.svgArcExpandedSub).each(function (d) {
  4732. if ($$.isDonutType(d.data)) ;
  4733. });
  4734. });
  4735. };
  4736. ChartInternal.prototype.unexpandArc = function (targetIds) {
  4737. var $$ = this;
  4738. if ($$.transiting) {
  4739. return;
  4740. }
  4741. targetIds = $$.mapToTargetIds(targetIds);
  4742. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path').transition().duration(function (d) {
  4743. return $$.expandDuration(d.data.id);
  4744. }).attr("d", $$.svgArc);
  4745. $$.svg.selectAll('.' + CLASS.arc);
  4746. };
  4747. ChartInternal.prototype.expandDuration = function (id) {
  4748. var $$ = this,
  4749. config = $$.config;
  4750. if ($$.isDonutType(id)) {
  4751. return config.donut_expand_duration;
  4752. } else if ($$.isGaugeType(id)) {
  4753. return config.gauge_expand_duration;
  4754. } else if ($$.isPieType(id)) {
  4755. return config.pie_expand_duration;
  4756. } else {
  4757. return 50;
  4758. }
  4759. };
  4760. ChartInternal.prototype.shouldExpand = function (id) {
  4761. var $$ = this,
  4762. config = $$.config;
  4763. return $$.isDonutType(id) && config.donut_expand || $$.isGaugeType(id) && config.gauge_expand || $$.isPieType(id) && config.pie_expand;
  4764. };
  4765. ChartInternal.prototype.shouldShowArcLabel = function () {
  4766. var $$ = this,
  4767. config = $$.config,
  4768. shouldShow = true;
  4769. if ($$.hasType('donut')) {
  4770. shouldShow = config.donut_label_show;
  4771. } else if ($$.hasType('pie')) {
  4772. shouldShow = config.pie_label_show;
  4773. } // when gauge, always true
  4774. return shouldShow;
  4775. };
  4776. ChartInternal.prototype.meetsArcLabelThreshold = function (ratio) {
  4777. var $$ = this,
  4778. config = $$.config,
  4779. threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold;
  4780. return ratio >= threshold;
  4781. };
  4782. ChartInternal.prototype.getArcLabelFormat = function () {
  4783. var $$ = this,
  4784. config = $$.config,
  4785. format = config.pie_label_format;
  4786. if ($$.hasType('gauge')) {
  4787. format = config.gauge_label_format;
  4788. } else if ($$.hasType('donut')) {
  4789. format = config.donut_label_format;
  4790. }
  4791. return format;
  4792. };
  4793. ChartInternal.prototype.getGaugeLabelExtents = function () {
  4794. var $$ = this,
  4795. config = $$.config;
  4796. return config.gauge_label_extents;
  4797. };
  4798. ChartInternal.prototype.getArcTitle = function () {
  4799. var $$ = this;
  4800. return $$.hasType('donut') ? $$.config.donut_title : "";
  4801. };
  4802. ChartInternal.prototype.updateTargetsForArc = function (targets) {
  4803. var $$ = this,
  4804. main = $$.main,
  4805. mainPies,
  4806. mainPieEnter,
  4807. classChartArc = $$.classChartArc.bind($$),
  4808. classArcs = $$.classArcs.bind($$),
  4809. classFocus = $$.classFocus.bind($$);
  4810. mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr("class", function (d) {
  4811. return classChartArc(d) + classFocus(d.data);
  4812. });
  4813. mainPieEnter = mainPies.enter().append("g").attr("class", classChartArc);
  4814. mainPieEnter.append('g').attr('class', classArcs);
  4815. mainPieEnter.append("text").attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em").style("opacity", 0).style("text-anchor", "middle").style("pointer-events", "none"); // MEMO: can not keep same color..., but not bad to update color in redraw
  4816. //mainPieUpdate.exit().remove();
  4817. };
  4818. ChartInternal.prototype.initArc = function () {
  4819. var $$ = this;
  4820. $$.arcs = $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  4821. $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style("text-anchor", "middle").text($$.getArcTitle());
  4822. };
  4823. ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) {
  4824. var $$ = this,
  4825. d3 = $$.d3,
  4826. config = $$.config,
  4827. main = $$.main,
  4828. arcs,
  4829. mainArc,
  4830. arcLabelLines,
  4831. mainArcLabelLine,
  4832. hasGaugeType = $$.hasType('gauge');
  4833. arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc).data($$.arcData.bind($$));
  4834. mainArc = arcs.enter().append('path').attr("class", $$.classArc.bind($$)).style("fill", function (d) {
  4835. return $$.color(d.data);
  4836. }).style("cursor", function (d) {
  4837. return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null;
  4838. }).each(function (d) {
  4839. if ($$.isGaugeType(d.data)) {
  4840. d.startAngle = d.endAngle = config.gauge_startingAngle;
  4841. }
  4842. this._current = d;
  4843. }).merge(arcs);
  4844. if (hasGaugeType) {
  4845. arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine).data($$.arcData.bind($$));
  4846. mainArcLabelLine = arcLabelLines.enter().append('rect').attr("class", function (d) {
  4847. return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id;
  4848. }).merge(arcLabelLines);
  4849. if ($$.filterTargetsToShow($$.data.targets).length === 1) {
  4850. mainArcLabelLine.style("display", "none");
  4851. } else {
  4852. mainArcLabelLine.style("fill", function (d) {
  4853. return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) {
  4854. return total + item.value;
  4855. }, 0)) : $$.color(d.data);
  4856. }).style("display", config.gauge_labelLine_show ? "" : "none").each(function (d) {
  4857. var lineLength = 0,
  4858. lineThickness = 2,
  4859. x = 0,
  4860. y = 0,
  4861. transform = "";
  4862. if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {
  4863. var updated = $$.updateAngle(d),
  4864. innerLineLength = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length * (updated.index + 1),
  4865. lineAngle = updated.endAngle - Math.PI / 2,
  4866. arcInnerRadius = $$.radius - innerLineLength,
  4867. linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius);
  4868. lineLength = $$.radiusExpanded - $$.radius + innerLineLength;
  4869. x = Math.cos(linePositioningAngle) * arcInnerRadius;
  4870. y = Math.sin(linePositioningAngle) * arcInnerRadius;
  4871. transform = "rotate(" + lineAngle * 180 / Math.PI + ", " + x + ", " + y + ")";
  4872. }
  4873. d3.select(this).attr('x', x).attr('y', y).attr('width', lineLength).attr('height', lineThickness).attr('transform', transform).style("stroke-dasharray", "0, " + (lineLength + lineThickness) + ", 0");
  4874. });
  4875. }
  4876. }
  4877. mainArc.attr("transform", function (d) {
  4878. return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : "";
  4879. }).on('mouseover', config.interaction_enabled ? function (d) {
  4880. var updated, arcData;
  4881. if ($$.transiting) {
  4882. // skip while transiting
  4883. return;
  4884. }
  4885. updated = $$.updateAngle(d);
  4886. if (updated) {
  4887. arcData = $$.convertToArcData(updated); // transitions
  4888. $$.expandArc(updated.data.id);
  4889. $$.api.focus(updated.data.id);
  4890. $$.toggleFocusLegend(updated.data.id, true);
  4891. $$.config.data_onmouseover(arcData, this);
  4892. }
  4893. } : null).on('mousemove', config.interaction_enabled ? function (d) {
  4894. var updated = $$.updateAngle(d),
  4895. arcData,
  4896. selectedData;
  4897. if (updated) {
  4898. arcData = $$.convertToArcData(updated), selectedData = [arcData];
  4899. $$.showTooltip(selectedData, this);
  4900. }
  4901. } : null).on('mouseout', config.interaction_enabled ? function (d) {
  4902. var updated, arcData;
  4903. if ($$.transiting) {
  4904. // skip while transiting
  4905. return;
  4906. }
  4907. updated = $$.updateAngle(d);
  4908. if (updated) {
  4909. arcData = $$.convertToArcData(updated); // transitions
  4910. $$.unexpandArc(updated.data.id);
  4911. $$.api.revert();
  4912. $$.revertLegend();
  4913. $$.hideTooltip();
  4914. $$.config.data_onmouseout(arcData, this);
  4915. }
  4916. } : null).on('click', config.interaction_enabled ? function (d, i) {
  4917. var updated = $$.updateAngle(d),
  4918. arcData;
  4919. if (updated) {
  4920. arcData = $$.convertToArcData(updated);
  4921. if ($$.toggleShape) {
  4922. $$.toggleShape(this, arcData, i);
  4923. }
  4924. $$.config.data_onclick.call($$.api, arcData, this);
  4925. }
  4926. } : null).each(function () {
  4927. $$.transiting = true;
  4928. }).transition().duration(duration).attrTween("d", function (d) {
  4929. var updated = $$.updateAngle(d),
  4930. interpolate;
  4931. if (!updated) {
  4932. return function () {
  4933. return "M 0 0";
  4934. };
  4935. } // if (this._current === d) {
  4936. // this._current = {
  4937. // startAngle: Math.PI*2,
  4938. // endAngle: Math.PI*2,
  4939. // };
  4940. // }
  4941. if (isNaN(this._current.startAngle)) {
  4942. this._current.startAngle = 0;
  4943. }
  4944. if (isNaN(this._current.endAngle)) {
  4945. this._current.endAngle = this._current.startAngle;
  4946. }
  4947. interpolate = d3.interpolate(this._current, updated);
  4948. this._current = interpolate(0);
  4949. return function (t) {
  4950. // prevents crashing the charts once in transition and chart.destroy() has been called
  4951. if ($$.config === null) {
  4952. return "M 0 0";
  4953. }
  4954. var interpolated = interpolate(t);
  4955. interpolated.data = d.data; // data.id will be updated by interporator
  4956. return $$.getArc(interpolated, true);
  4957. };
  4958. }).attr("transform", withTransform ? "scale(1)" : "").style("fill", function (d) {
  4959. return $$.levelColor ? $$.levelColor(d.data.values.reduce(function (total, item) {
  4960. return total + item.value;
  4961. }, 0)) : $$.color(d.data.id);
  4962. }) // Where gauge reading color would receive customization.
  4963. .call($$.endall, function () {
  4964. $$.transiting = false;
  4965. });
  4966. arcs.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  4967. main.selectAll('.' + CLASS.chartArc).select('text').style("opacity", 0).attr('class', function (d) {
  4968. return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '';
  4969. }).text($$.textForArcLabel.bind($$)).attr("transform", $$.transformForArcLabel.bind($$)).style('font-size', function (d) {
  4970. return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : '';
  4971. }).transition().duration(duration).style("opacity", function (d) {
  4972. return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0;
  4973. });
  4974. main.select('.' + CLASS.chartArcsTitle).style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0);
  4975. if (hasGaugeType) {
  4976. var index = 0;
  4977. var backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets);
  4978. backgroundArc.enter().append("path").attr("class", function (d, i) {
  4979. return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i;
  4980. }).merge(backgroundArc).attr("d", function (d1) {
  4981. if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {
  4982. return "M 0 0";
  4983. }
  4984. var d = {
  4985. data: [{
  4986. value: config.gauge_max
  4987. }],
  4988. startAngle: config.gauge_startingAngle,
  4989. endAngle: -1 * config.gauge_startingAngle * (config.gauge_fullCircle ? Math.PI : 1),
  4990. index: index++
  4991. };
  4992. return $$.getArc(d, true, true);
  4993. });
  4994. backgroundArc.exit().remove();
  4995. $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr("dy", ".75em").text(config.gauge_label_show ? config.gauge_units : '');
  4996. $$.arcs.select('.' + CLASS.chartArcsGaugeMin).attr("dx", -1 * ($$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2)) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_min, false) : '');
  4997. $$.arcs.select('.' + CLASS.chartArcsGaugeMax).attr("dx", $$.innerRadius + ($$.radius - $$.innerRadius) / (config.gauge_fullCircle ? 1 : 2) + "px").attr("dy", "1.2em").text(config.gauge_label_show ? $$.textForGaugeMinMax(config.gauge_max, true) : '');
  4998. }
  4999. };
  5000. ChartInternal.prototype.initGauge = function () {
  5001. var arcs = this.arcs;
  5002. if (this.hasType('gauge')) {
  5003. arcs.append('g').attr("class", CLASS.chartArcsBackground);
  5004. arcs.append("text").attr("class", CLASS.chartArcsGaugeUnit).style("text-anchor", "middle").style("pointer-events", "none");
  5005. arcs.append("text").attr("class", CLASS.chartArcsGaugeMin).style("text-anchor", "middle").style("pointer-events", "none");
  5006. arcs.append("text").attr("class", CLASS.chartArcsGaugeMax).style("text-anchor", "middle").style("pointer-events", "none");
  5007. }
  5008. };
  5009. ChartInternal.prototype.getGaugeLabelHeight = function () {
  5010. return this.config.gauge_label_show ? 20 : 0;
  5011. };
  5012. /**
  5013. * Store value into cache
  5014. *
  5015. * @param key
  5016. * @param value
  5017. */
  5018. ChartInternal.prototype.addToCache = function (key, value) {
  5019. this.cache["$".concat(key)] = value;
  5020. };
  5021. /**
  5022. * Returns a cached value or undefined
  5023. *
  5024. * @param key
  5025. * @return {*}
  5026. */
  5027. ChartInternal.prototype.getFromCache = function (key) {
  5028. return this.cache["$".concat(key)];
  5029. };
  5030. /**
  5031. * Reset cached data
  5032. */
  5033. ChartInternal.prototype.resetCache = function () {
  5034. var _this = this;
  5035. Object.keys(this.cache).filter(function (key) {
  5036. return /^\$/.test(key);
  5037. }).forEach(function (key) {
  5038. delete _this.cache[key];
  5039. });
  5040. }; // Old API that stores Targets
  5041. ChartInternal.prototype.hasCaches = function (ids) {
  5042. for (var i = 0; i < ids.length; i++) {
  5043. if (!(ids[i] in this.cache)) {
  5044. return false;
  5045. }
  5046. }
  5047. return true;
  5048. };
  5049. ChartInternal.prototype.addCache = function (id, target) {
  5050. this.cache[id] = this.cloneTarget(target);
  5051. };
  5052. ChartInternal.prototype.getCaches = function (ids) {
  5053. var targets = [],
  5054. i;
  5055. for (i = 0; i < ids.length; i++) {
  5056. if (ids[i] in this.cache) {
  5057. targets.push(this.cloneTarget(this.cache[ids[i]]));
  5058. }
  5059. }
  5060. return targets;
  5061. };
  5062. ChartInternal.prototype.categoryName = function (i) {
  5063. var config = this.config;
  5064. return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;
  5065. };
  5066. ChartInternal.prototype.generateTargetClass = function (targetId) {
  5067. return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : '';
  5068. };
  5069. ChartInternal.prototype.generateClass = function (prefix, targetId) {
  5070. return " " + prefix + " " + prefix + this.generateTargetClass(targetId);
  5071. };
  5072. ChartInternal.prototype.classText = function (d) {
  5073. return this.generateClass(CLASS.text, d.index);
  5074. };
  5075. ChartInternal.prototype.classTexts = function (d) {
  5076. return this.generateClass(CLASS.texts, d.id);
  5077. };
  5078. ChartInternal.prototype.classShape = function (d) {
  5079. return this.generateClass(CLASS.shape, d.index);
  5080. };
  5081. ChartInternal.prototype.classShapes = function (d) {
  5082. return this.generateClass(CLASS.shapes, d.id);
  5083. };
  5084. ChartInternal.prototype.classLine = function (d) {
  5085. return this.classShape(d) + this.generateClass(CLASS.line, d.id);
  5086. };
  5087. ChartInternal.prototype.classLines = function (d) {
  5088. return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);
  5089. };
  5090. ChartInternal.prototype.classCircle = function (d) {
  5091. return this.classShape(d) + this.generateClass(CLASS.circle, d.index);
  5092. };
  5093. ChartInternal.prototype.classCircles = function (d) {
  5094. return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);
  5095. };
  5096. ChartInternal.prototype.classBar = function (d) {
  5097. return this.classShape(d) + this.generateClass(CLASS.bar, d.index);
  5098. };
  5099. ChartInternal.prototype.classBars = function (d) {
  5100. return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);
  5101. };
  5102. ChartInternal.prototype.classArc = function (d) {
  5103. return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);
  5104. };
  5105. ChartInternal.prototype.classArcs = function (d) {
  5106. return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);
  5107. };
  5108. ChartInternal.prototype.classArea = function (d) {
  5109. return this.classShape(d) + this.generateClass(CLASS.area, d.id);
  5110. };
  5111. ChartInternal.prototype.classAreas = function (d) {
  5112. return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);
  5113. };
  5114. ChartInternal.prototype.classRegion = function (d, i) {
  5115. return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '');
  5116. };
  5117. ChartInternal.prototype.classEvent = function (d) {
  5118. return this.generateClass(CLASS.eventRect, d.index);
  5119. };
  5120. ChartInternal.prototype.classTarget = function (id) {
  5121. var $$ = this;
  5122. var additionalClassSuffix = $$.config.data_classes[id],
  5123. additionalClass = '';
  5124. if (additionalClassSuffix) {
  5125. additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;
  5126. }
  5127. return $$.generateClass(CLASS.target, id) + additionalClass;
  5128. };
  5129. ChartInternal.prototype.classFocus = function (d) {
  5130. return this.classFocused(d) + this.classDefocused(d);
  5131. };
  5132. ChartInternal.prototype.classFocused = function (d) {
  5133. return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');
  5134. };
  5135. ChartInternal.prototype.classDefocused = function (d) {
  5136. return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '');
  5137. };
  5138. ChartInternal.prototype.classChartText = function (d) {
  5139. return CLASS.chartText + this.classTarget(d.id);
  5140. };
  5141. ChartInternal.prototype.classChartLine = function (d) {
  5142. return CLASS.chartLine + this.classTarget(d.id);
  5143. };
  5144. ChartInternal.prototype.classChartBar = function (d) {
  5145. return CLASS.chartBar + this.classTarget(d.id);
  5146. };
  5147. ChartInternal.prototype.classChartArc = function (d) {
  5148. return CLASS.chartArc + this.classTarget(d.data.id);
  5149. };
  5150. ChartInternal.prototype.getTargetSelectorSuffix = function (targetId) {
  5151. var targetClass = this.generateTargetClass(targetId);
  5152. if (window.CSS && window.CSS.escape) {
  5153. return window.CSS.escape(targetClass);
  5154. } // fallback on imperfect method for old browsers (does not handles unicode)
  5155. return targetClass.replace(/([?!@#$%^&*()=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1');
  5156. };
  5157. ChartInternal.prototype.selectorTarget = function (id, prefix) {
  5158. return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);
  5159. };
  5160. ChartInternal.prototype.selectorTargets = function (ids, prefix) {
  5161. var $$ = this;
  5162. ids = ids || [];
  5163. return ids.length ? ids.map(function (id) {
  5164. return $$.selectorTarget(id, prefix);
  5165. }) : null;
  5166. };
  5167. ChartInternal.prototype.selectorLegend = function (id) {
  5168. return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);
  5169. };
  5170. ChartInternal.prototype.selectorLegends = function (ids) {
  5171. var $$ = this;
  5172. return ids && ids.length ? ids.map(function (id) {
  5173. return $$.selectorLegend(id);
  5174. }) : null;
  5175. };
  5176. ChartInternal.prototype.getClipPath = function (id) {
  5177. return "url(" + (isIE(9) ? "" : document.URL.split('#')[0]) + "#" + id + ")";
  5178. };
  5179. ChartInternal.prototype.appendClip = function (parent, id) {
  5180. return parent.append("clipPath").attr("id", id).append("rect");
  5181. };
  5182. ChartInternal.prototype.getAxisClipX = function (forHorizontal) {
  5183. // axis line width + padding for left
  5184. var left = Math.max(30, this.margin.left);
  5185. return forHorizontal ? -(1 + left) : -(left - 1);
  5186. };
  5187. ChartInternal.prototype.getAxisClipY = function (forHorizontal) {
  5188. return forHorizontal ? -20 : -this.margin.top;
  5189. };
  5190. ChartInternal.prototype.getXAxisClipX = function () {
  5191. var $$ = this;
  5192. return $$.getAxisClipX(!$$.config.axis_rotated);
  5193. };
  5194. ChartInternal.prototype.getXAxisClipY = function () {
  5195. var $$ = this;
  5196. return $$.getAxisClipY(!$$.config.axis_rotated);
  5197. };
  5198. ChartInternal.prototype.getYAxisClipX = function () {
  5199. var $$ = this;
  5200. return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated);
  5201. };
  5202. ChartInternal.prototype.getYAxisClipY = function () {
  5203. var $$ = this;
  5204. return $$.getAxisClipY($$.config.axis_rotated);
  5205. };
  5206. ChartInternal.prototype.getAxisClipWidth = function (forHorizontal) {
  5207. var $$ = this,
  5208. left = Math.max(30, $$.margin.left),
  5209. right = Math.max(30, $$.margin.right); // width + axis line width + padding for left/right
  5210. return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20;
  5211. };
  5212. ChartInternal.prototype.getAxisClipHeight = function (forHorizontal) {
  5213. // less than 20 is not enough to show the axis label 'outer' without legend
  5214. return (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20;
  5215. };
  5216. ChartInternal.prototype.getXAxisClipWidth = function () {
  5217. var $$ = this;
  5218. return $$.getAxisClipWidth(!$$.config.axis_rotated);
  5219. };
  5220. ChartInternal.prototype.getXAxisClipHeight = function () {
  5221. var $$ = this;
  5222. return $$.getAxisClipHeight(!$$.config.axis_rotated);
  5223. };
  5224. ChartInternal.prototype.getYAxisClipWidth = function () {
  5225. var $$ = this;
  5226. return $$.getAxisClipWidth($$.config.axis_rotated) + ($$.config.axis_y_inner ? 20 : 0);
  5227. };
  5228. ChartInternal.prototype.getYAxisClipHeight = function () {
  5229. var $$ = this;
  5230. return $$.getAxisClipHeight($$.config.axis_rotated);
  5231. };
  5232. ChartInternal.prototype.generateColor = function () {
  5233. var $$ = this,
  5234. config = $$.config,
  5235. d3 = $$.d3,
  5236. colors = config.data_colors,
  5237. pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.schemeCategory10,
  5238. callback = config.data_color,
  5239. ids = [];
  5240. return function (d) {
  5241. var id = d.id || d.data && d.data.id || d,
  5242. color; // if callback function is provided
  5243. if (colors[id] instanceof Function) {
  5244. color = colors[id](d);
  5245. } // if specified, choose that color
  5246. else if (colors[id]) {
  5247. color = colors[id];
  5248. } // if not specified, choose from pattern
  5249. else {
  5250. if (ids.indexOf(id) < 0) {
  5251. ids.push(id);
  5252. }
  5253. color = pattern[ids.indexOf(id) % pattern.length];
  5254. colors[id] = color;
  5255. }
  5256. return callback instanceof Function ? callback(color, d) : color;
  5257. };
  5258. };
  5259. ChartInternal.prototype.generateLevelColor = function () {
  5260. var $$ = this,
  5261. config = $$.config,
  5262. colors = config.color_pattern,
  5263. threshold = config.color_threshold,
  5264. asValue = threshold.unit === 'value',
  5265. values = threshold.values && threshold.values.length ? threshold.values : [],
  5266. max = threshold.max || 100;
  5267. return notEmpty(threshold) && notEmpty(colors) ? function (value) {
  5268. var i,
  5269. v,
  5270. color = colors[colors.length - 1];
  5271. for (i = 0; i < values.length; i++) {
  5272. v = asValue ? value : value * 100 / max;
  5273. if (v < values[i]) {
  5274. color = colors[i];
  5275. break;
  5276. }
  5277. }
  5278. return color;
  5279. } : null;
  5280. };
  5281. ChartInternal.prototype.getDefaultConfig = function () {
  5282. var config = {
  5283. bindto: '#chart',
  5284. svg_classname: undefined,
  5285. size_width: undefined,
  5286. size_height: undefined,
  5287. padding_left: undefined,
  5288. padding_right: undefined,
  5289. padding_top: undefined,
  5290. padding_bottom: undefined,
  5291. resize_auto: true,
  5292. zoom_enabled: false,
  5293. zoom_initialRange: undefined,
  5294. zoom_type: 'scroll',
  5295. zoom_disableDefaultBehavior: false,
  5296. zoom_privileged: false,
  5297. zoom_rescale: false,
  5298. zoom_onzoom: function zoom_onzoom() {},
  5299. zoom_onzoomstart: function zoom_onzoomstart() {},
  5300. zoom_onzoomend: function zoom_onzoomend() {},
  5301. zoom_x_min: undefined,
  5302. zoom_x_max: undefined,
  5303. interaction_brighten: true,
  5304. interaction_enabled: true,
  5305. onmouseover: function onmouseover() {},
  5306. onmouseout: function onmouseout() {},
  5307. onresize: function onresize() {},
  5308. onresized: function onresized() {},
  5309. oninit: function oninit() {},
  5310. onrendered: function onrendered() {},
  5311. transition_duration: 350,
  5312. data_epochs: 'epochs',
  5313. data_x: undefined,
  5314. data_xs: {},
  5315. data_xFormat: '%Y-%m-%d',
  5316. data_xLocaltime: true,
  5317. data_xSort: true,
  5318. data_idConverter: function data_idConverter(id) {
  5319. return id;
  5320. },
  5321. data_names: {},
  5322. data_classes: {},
  5323. data_groups: [],
  5324. data_axes: {},
  5325. data_type: undefined,
  5326. data_types: {},
  5327. data_labels: {},
  5328. data_order: 'desc',
  5329. data_regions: {},
  5330. data_color: undefined,
  5331. data_colors: {},
  5332. data_hide: false,
  5333. data_filter: undefined,
  5334. data_selection_enabled: false,
  5335. data_selection_grouped: false,
  5336. data_selection_isselectable: function data_selection_isselectable() {
  5337. return true;
  5338. },
  5339. data_selection_multiple: true,
  5340. data_selection_draggable: false,
  5341. data_stack_normalize: false,
  5342. data_onclick: function data_onclick() {},
  5343. data_onmouseover: function data_onmouseover() {},
  5344. data_onmouseout: function data_onmouseout() {},
  5345. data_onselected: function data_onselected() {},
  5346. data_onunselected: function data_onunselected() {},
  5347. data_url: undefined,
  5348. data_headers: undefined,
  5349. data_json: undefined,
  5350. data_rows: undefined,
  5351. data_columns: undefined,
  5352. data_mimeType: undefined,
  5353. data_keys: undefined,
  5354. // configuration for no plot-able data supplied.
  5355. data_empty_label_text: "",
  5356. // subchart
  5357. subchart_show: false,
  5358. subchart_size_height: 60,
  5359. subchart_axis_x_show: true,
  5360. subchart_onbrush: function subchart_onbrush() {},
  5361. // color
  5362. color_pattern: [],
  5363. color_threshold: {},
  5364. // legend
  5365. legend_show: true,
  5366. legend_hide: false,
  5367. legend_position: 'bottom',
  5368. legend_inset_anchor: 'top-left',
  5369. legend_inset_x: 10,
  5370. legend_inset_y: 0,
  5371. legend_inset_step: undefined,
  5372. legend_item_onclick: undefined,
  5373. legend_item_onmouseover: undefined,
  5374. legend_item_onmouseout: undefined,
  5375. legend_equally: false,
  5376. legend_padding: 0,
  5377. legend_item_tile_width: 10,
  5378. legend_item_tile_height: 10,
  5379. // axis
  5380. axis_rotated: false,
  5381. axis_x_show: true,
  5382. axis_x_type: 'indexed',
  5383. axis_x_localtime: true,
  5384. axis_x_categories: [],
  5385. axis_x_tick_centered: false,
  5386. axis_x_tick_format: undefined,
  5387. axis_x_tick_culling: {},
  5388. axis_x_tick_culling_max: 10,
  5389. axis_x_tick_count: undefined,
  5390. axis_x_tick_fit: true,
  5391. axis_x_tick_values: null,
  5392. axis_x_tick_rotate: 0,
  5393. axis_x_tick_outer: true,
  5394. axis_x_tick_multiline: true,
  5395. axis_x_tick_multilineMax: 0,
  5396. axis_x_tick_width: null,
  5397. axis_x_max: undefined,
  5398. axis_x_min: undefined,
  5399. axis_x_padding: {},
  5400. axis_x_height: undefined,
  5401. axis_x_selection: undefined,
  5402. axis_x_label: {},
  5403. axis_x_inner: undefined,
  5404. axis_y_show: true,
  5405. axis_y_type: 'linear',
  5406. axis_y_max: undefined,
  5407. axis_y_min: undefined,
  5408. axis_y_inverted: false,
  5409. axis_y_center: undefined,
  5410. axis_y_inner: undefined,
  5411. axis_y_label: {},
  5412. axis_y_tick_format: undefined,
  5413. axis_y_tick_outer: true,
  5414. axis_y_tick_values: null,
  5415. axis_y_tick_rotate: 0,
  5416. axis_y_tick_count: undefined,
  5417. axis_y_tick_time_type: undefined,
  5418. axis_y_tick_time_interval: undefined,
  5419. axis_y_padding: {},
  5420. axis_y_default: undefined,
  5421. axis_y2_show: false,
  5422. axis_y2_type: 'linear',
  5423. axis_y2_max: undefined,
  5424. axis_y2_min: undefined,
  5425. axis_y2_inverted: false,
  5426. axis_y2_center: undefined,
  5427. axis_y2_inner: undefined,
  5428. axis_y2_label: {},
  5429. axis_y2_tick_format: undefined,
  5430. axis_y2_tick_outer: true,
  5431. axis_y2_tick_values: null,
  5432. axis_y2_tick_count: undefined,
  5433. axis_y2_padding: {},
  5434. axis_y2_default: undefined,
  5435. // grid
  5436. grid_x_show: false,
  5437. grid_x_type: 'tick',
  5438. grid_x_lines: [],
  5439. grid_y_show: false,
  5440. // not used
  5441. // grid_y_type: 'tick',
  5442. grid_y_lines: [],
  5443. grid_y_ticks: 10,
  5444. grid_focus_show: true,
  5445. grid_lines_front: true,
  5446. // point - point of each data
  5447. point_show: true,
  5448. point_r: 2.5,
  5449. point_sensitivity: 10,
  5450. point_focus_expand_enabled: true,
  5451. point_focus_expand_r: undefined,
  5452. point_select_r: undefined,
  5453. // line
  5454. line_connectNull: false,
  5455. line_step_type: 'step',
  5456. // bar
  5457. bar_width: undefined,
  5458. bar_width_ratio: 0.6,
  5459. bar_width_max: undefined,
  5460. bar_zerobased: true,
  5461. bar_space: 0,
  5462. // area
  5463. area_zerobased: true,
  5464. area_above: false,
  5465. // pie
  5466. pie_label_show: true,
  5467. pie_label_format: undefined,
  5468. pie_label_threshold: 0.05,
  5469. pie_label_ratio: undefined,
  5470. pie_expand: {},
  5471. pie_expand_duration: 50,
  5472. pie_padAngle: 0,
  5473. // gauge
  5474. gauge_fullCircle: false,
  5475. gauge_label_show: true,
  5476. gauge_labelLine_show: true,
  5477. gauge_label_format: undefined,
  5478. gauge_min: 0,
  5479. gauge_max: 100,
  5480. gauge_startingAngle: -1 * Math.PI / 2,
  5481. gauge_label_extents: undefined,
  5482. gauge_units: undefined,
  5483. gauge_width: undefined,
  5484. gauge_arcs_minWidth: 5,
  5485. gauge_expand: {},
  5486. gauge_expand_duration: 50,
  5487. // donut
  5488. donut_label_show: true,
  5489. donut_label_format: undefined,
  5490. donut_label_threshold: 0.05,
  5491. donut_label_ratio: undefined,
  5492. donut_width: undefined,
  5493. donut_title: "",
  5494. donut_expand: {},
  5495. donut_expand_duration: 50,
  5496. donut_padAngle: 0,
  5497. // spline
  5498. spline_interpolation_type: 'cardinal',
  5499. // stanford
  5500. stanford_lines: [],
  5501. stanford_regions: [],
  5502. stanford_texts: [],
  5503. stanford_scaleMin: undefined,
  5504. stanford_scaleMax: undefined,
  5505. stanford_scaleWidth: undefined,
  5506. stanford_scaleFormat: undefined,
  5507. stanford_scaleValues: undefined,
  5508. stanford_colors: undefined,
  5509. stanford_padding: {
  5510. top: 0,
  5511. right: 0,
  5512. bottom: 0,
  5513. left: 0
  5514. },
  5515. // region - region to change style
  5516. regions: [],
  5517. // tooltip - show when mouseover on each data
  5518. tooltip_show: true,
  5519. tooltip_grouped: true,
  5520. tooltip_order: undefined,
  5521. tooltip_format_title: undefined,
  5522. tooltip_format_name: undefined,
  5523. tooltip_format_value: undefined,
  5524. tooltip_horizontal: undefined,
  5525. tooltip_position: undefined,
  5526. tooltip_contents: function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) {
  5527. return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
  5528. },
  5529. tooltip_init_show: false,
  5530. tooltip_init_x: 0,
  5531. tooltip_init_position: {
  5532. top: '0px',
  5533. left: '50px'
  5534. },
  5535. tooltip_onshow: function tooltip_onshow() {},
  5536. tooltip_onhide: function tooltip_onhide() {},
  5537. // title
  5538. title_text: undefined,
  5539. title_padding: {
  5540. top: 0,
  5541. right: 0,
  5542. bottom: 0,
  5543. left: 0
  5544. },
  5545. title_position: 'top-center'
  5546. };
  5547. Object.keys(this.additionalConfig).forEach(function (key) {
  5548. config[key] = this.additionalConfig[key];
  5549. }, this);
  5550. return config;
  5551. };
  5552. ChartInternal.prototype.additionalConfig = {};
  5553. ChartInternal.prototype.loadConfig = function (config) {
  5554. var this_config = this.config,
  5555. target,
  5556. keys,
  5557. read;
  5558. function find() {
  5559. var key = keys.shift(); // console.log("key =>", key, ", target =>", target);
  5560. if (key && target && _typeof(target) === 'object' && key in target) {
  5561. target = target[key];
  5562. return find();
  5563. } else if (!key) {
  5564. return target;
  5565. } else {
  5566. return undefined;
  5567. }
  5568. }
  5569. Object.keys(this_config).forEach(function (key) {
  5570. target = config;
  5571. keys = key.split('_');
  5572. read = find(); // console.log("CONFIG : ", key, read);
  5573. if (isDefined(read)) {
  5574. this_config[key] = read;
  5575. }
  5576. });
  5577. };
  5578. ChartInternal.prototype.convertUrlToData = function (url, mimeType, headers, keys, done) {
  5579. var $$ = this,
  5580. type = mimeType ? mimeType : 'csv',
  5581. f,
  5582. converter;
  5583. if (type === 'json') {
  5584. f = $$.d3.json;
  5585. converter = $$.convertJsonToData;
  5586. } else if (type === 'tsv') {
  5587. f = $$.d3.tsv;
  5588. converter = $$.convertXsvToData;
  5589. } else {
  5590. f = $$.d3.csv;
  5591. converter = $$.convertXsvToData;
  5592. }
  5593. f(url, headers).then(function (data) {
  5594. done.call($$, converter.call($$, data, keys));
  5595. })["catch"](function (error) {
  5596. throw error;
  5597. });
  5598. };
  5599. ChartInternal.prototype.convertXsvToData = function (xsv) {
  5600. var keys = xsv.columns,
  5601. rows = xsv;
  5602. if (rows.length === 0) {
  5603. return {
  5604. keys: keys,
  5605. rows: [keys.reduce(function (row, key) {
  5606. return Object.assign(row, _defineProperty({}, key, null));
  5607. }, {})]
  5608. };
  5609. } else {
  5610. // [].concat() is to convert result into a plain array otherwise
  5611. // test is not happy because rows have properties.
  5612. return {
  5613. keys: keys,
  5614. rows: [].concat(xsv)
  5615. };
  5616. }
  5617. };
  5618. ChartInternal.prototype.convertJsonToData = function (json, keys) {
  5619. var $$ = this,
  5620. new_rows = [],
  5621. targetKeys,
  5622. data;
  5623. if (keys) {
  5624. // when keys specified, json would be an array that includes objects
  5625. if (keys.x) {
  5626. targetKeys = keys.value.concat(keys.x);
  5627. $$.config.data_x = keys.x;
  5628. } else {
  5629. targetKeys = keys.value;
  5630. }
  5631. new_rows.push(targetKeys);
  5632. json.forEach(function (o) {
  5633. var new_row = [];
  5634. targetKeys.forEach(function (key) {
  5635. // convert undefined to null because undefined data will be removed in convertDataToTargets()
  5636. var v = $$.findValueInJson(o, key);
  5637. if (isUndefined(v)) {
  5638. v = null;
  5639. }
  5640. new_row.push(v);
  5641. });
  5642. new_rows.push(new_row);
  5643. });
  5644. data = $$.convertRowsToData(new_rows);
  5645. } else {
  5646. Object.keys(json).forEach(function (key) {
  5647. new_rows.push([key].concat(json[key]));
  5648. });
  5649. data = $$.convertColumnsToData(new_rows);
  5650. }
  5651. return data;
  5652. };
  5653. /**
  5654. * Finds value from the given nested object by the given path.
  5655. * If it's not found, then this returns undefined.
  5656. * @param {Object} object the object
  5657. * @param {string} path the path
  5658. */
  5659. ChartInternal.prototype.findValueInJson = function (object, path) {
  5660. if (path in object) {
  5661. // If object has a key that contains . or [], return the key's value
  5662. // instead of searching for an inner object.
  5663. // See https://github.com/c3js/c3/issues/1691 for details.
  5664. return object[path];
  5665. }
  5666. path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
  5667. path = path.replace(/^\./, ''); // strip a leading dot
  5668. var pathArray = path.split('.');
  5669. for (var i = 0; i < pathArray.length; ++i) {
  5670. var k = pathArray[i];
  5671. if (k in object) {
  5672. object = object[k];
  5673. } else {
  5674. return;
  5675. }
  5676. }
  5677. return object;
  5678. };
  5679. /**
  5680. * Converts the rows to normalized data.
  5681. * @param {any[][]} rows The row data
  5682. * @return {Object}
  5683. */
  5684. ChartInternal.prototype.convertRowsToData = function (rows) {
  5685. var newRows = [];
  5686. var keys = rows[0];
  5687. for (var i = 1; i < rows.length; i++) {
  5688. var newRow = {};
  5689. for (var j = 0; j < rows[i].length; j++) {
  5690. if (isUndefined(rows[i][j])) {
  5691. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  5692. }
  5693. newRow[keys[j]] = rows[i][j];
  5694. }
  5695. newRows.push(newRow);
  5696. }
  5697. return {
  5698. keys: keys,
  5699. rows: newRows
  5700. };
  5701. };
  5702. /**
  5703. * Converts the columns to normalized data.
  5704. * @param {any[][]} columns The column data
  5705. * @return {Object}
  5706. */
  5707. ChartInternal.prototype.convertColumnsToData = function (columns) {
  5708. var newRows = [];
  5709. var keys = [];
  5710. for (var i = 0; i < columns.length; i++) {
  5711. var key = columns[i][0];
  5712. for (var j = 1; j < columns[i].length; j++) {
  5713. if (isUndefined(newRows[j - 1])) {
  5714. newRows[j - 1] = {};
  5715. }
  5716. if (isUndefined(columns[i][j])) {
  5717. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  5718. }
  5719. newRows[j - 1][key] = columns[i][j];
  5720. }
  5721. keys.push(key);
  5722. }
  5723. return {
  5724. keys: keys,
  5725. rows: newRows
  5726. };
  5727. };
  5728. /**
  5729. * Converts the data format into the target format.
  5730. * @param {!Object} data
  5731. * @param {!Array} data.keys Ordered list of target IDs.
  5732. * @param {!Array} data.rows Rows of data to convert.
  5733. * @param {boolean} appendXs True to append to $$.data.xs, False to replace.
  5734. * @return {!Array}
  5735. */
  5736. ChartInternal.prototype.convertDataToTargets = function (data, appendXs) {
  5737. var $$ = this,
  5738. config = $$.config,
  5739. targets,
  5740. ids,
  5741. xs,
  5742. keys,
  5743. epochs; // handles format where keys are not orderly provided
  5744. if (isArray(data)) {
  5745. keys = Object.keys(data[0]);
  5746. } else {
  5747. keys = data.keys;
  5748. data = data.rows;
  5749. }
  5750. xs = keys.filter($$.isX, $$);
  5751. if (!$$.isStanfordGraphType()) {
  5752. ids = keys.filter($$.isNotX, $$);
  5753. } else {
  5754. epochs = keys.filter($$.isEpochs, $$);
  5755. ids = keys.filter($$.isNotXAndNotEpochs, $$);
  5756. if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) {
  5757. throw new Error('You must define the \'x\' key name and the \'epochs\' for Stanford Diagrams');
  5758. }
  5759. } // save x for update data by load when custom x and c3.x API
  5760. ids.forEach(function (id) {
  5761. var xKey = $$.getXKey(id);
  5762. if ($$.isCustomX() || $$.isTimeSeries()) {
  5763. // if included in input data
  5764. if (xs.indexOf(xKey) >= 0) {
  5765. $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat(data.map(function (d) {
  5766. return d[xKey];
  5767. }).filter(isValue).map(function (rawX, i) {
  5768. return $$.generateTargetX(rawX, id, i);
  5769. }));
  5770. } // if not included in input data, find from preloaded data of other id's x
  5771. else if (config.data_x) {
  5772. $$.data.xs[id] = $$.getOtherTargetXs();
  5773. } // if not included in input data, find from preloaded data
  5774. else if (notEmpty(config.data_xs)) {
  5775. $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);
  5776. } // MEMO: if no x included, use same x of current will be used
  5777. } else {
  5778. $$.data.xs[id] = data.map(function (d, i) {
  5779. return i;
  5780. });
  5781. }
  5782. }); // check x is defined
  5783. ids.forEach(function (id) {
  5784. if (!$$.data.xs[id]) {
  5785. throw new Error('x is not defined for id = "' + id + '".');
  5786. }
  5787. }); // convert to target
  5788. targets = ids.map(function (id, index) {
  5789. var convertedId = config.data_idConverter(id);
  5790. return {
  5791. id: convertedId,
  5792. id_org: id,
  5793. values: data.map(function (d, i) {
  5794. var xKey = $$.getXKey(id),
  5795. rawX = d[xKey],
  5796. value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null,
  5797. x,
  5798. returnData; // use x as categories if custom x and categorized
  5799. if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {
  5800. if (index === 0 && i === 0) {
  5801. config.axis_x_categories = [];
  5802. }
  5803. x = config.axis_x_categories.indexOf(rawX);
  5804. if (x === -1) {
  5805. x = config.axis_x_categories.length;
  5806. config.axis_x_categories.push(rawX);
  5807. }
  5808. } else {
  5809. x = $$.generateTargetX(rawX, id, i);
  5810. } // mark as x = undefined if value is undefined and filter to remove after mapped
  5811. if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {
  5812. x = undefined;
  5813. }
  5814. returnData = {
  5815. x: x,
  5816. value: value,
  5817. id: convertedId
  5818. };
  5819. if ($$.isStanfordGraphType()) {
  5820. returnData.epochs = d[epochs];
  5821. }
  5822. return returnData;
  5823. }).filter(function (v) {
  5824. return isDefined(v.x);
  5825. })
  5826. };
  5827. }); // finish targets
  5828. targets.forEach(function (t) {
  5829. var i; // sort values by its x
  5830. if (config.data_xSort) {
  5831. t.values = t.values.sort(function (v1, v2) {
  5832. var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,
  5833. x2 = v2.x || v2.x === 0 ? v2.x : Infinity;
  5834. return x1 - x2;
  5835. });
  5836. } // indexing each value
  5837. i = 0;
  5838. t.values.forEach(function (v) {
  5839. v.index = i++;
  5840. }); // this needs to be sorted because its index and value.index is identical
  5841. $$.data.xs[t.id].sort(function (v1, v2) {
  5842. return v1 - v2;
  5843. });
  5844. }); // cache information about values
  5845. $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  5846. $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets); // set target types
  5847. if (config.data_type) {
  5848. $$.setTargetType($$.mapToIds(targets).filter(function (id) {
  5849. return !(id in config.data_types);
  5850. }), config.data_type);
  5851. } // cache as original id keyed
  5852. targets.forEach(function (d) {
  5853. $$.addCache(d.id_org, d);
  5854. });
  5855. return targets;
  5856. };
  5857. ChartInternal.prototype.isEpochs = function (key) {
  5858. var $$ = this,
  5859. config = $$.config;
  5860. return config.data_epochs && key === config.data_epochs;
  5861. };
  5862. ChartInternal.prototype.isX = function (key) {
  5863. var $$ = this,
  5864. config = $$.config;
  5865. return config.data_x && key === config.data_x || notEmpty(config.data_xs) && hasValue(config.data_xs, key);
  5866. };
  5867. ChartInternal.prototype.isNotX = function (key) {
  5868. return !this.isX(key);
  5869. };
  5870. ChartInternal.prototype.isNotXAndNotEpochs = function (key) {
  5871. return !this.isX(key) && !this.isEpochs(key);
  5872. };
  5873. /**
  5874. * Returns whether the normalized stack option is enabled or not.
  5875. *
  5876. * To be enabled it must also have data.groups defined.
  5877. *
  5878. * @return {boolean}
  5879. */
  5880. ChartInternal.prototype.isStackNormalized = function () {
  5881. return this.config.data_stack_normalize && this.config.data_groups.length > 0;
  5882. };
  5883. /**
  5884. * Returns whether the axis is normalized or not.
  5885. *
  5886. * An axis is normalized as long as one of its associated target
  5887. * is normalized.
  5888. *
  5889. * @param axisId Axis ID (y or y2)
  5890. * @return {Boolean}
  5891. */
  5892. ChartInternal.prototype.isAxisNormalized = function (axisId) {
  5893. var $$ = this;
  5894. if (!$$.isStackNormalized()) {
  5895. // shortcut
  5896. return false;
  5897. }
  5898. return $$.data.targets.filter(function (target) {
  5899. return $$.axis.getId(target.id) === axisId;
  5900. }).some(function (target) {
  5901. return $$.isTargetNormalized(target.id);
  5902. });
  5903. };
  5904. /**
  5905. * Returns whether the values for this target ID is normalized or not.
  5906. *
  5907. * To be normalized the option needs to be enabled and target needs
  5908. * to be defined in `data.groups`.
  5909. *
  5910. * @param targetId ID of the target
  5911. * @return {Boolean} True if the target is normalized, false otherwise.
  5912. */
  5913. ChartInternal.prototype.isTargetNormalized = function (targetId) {
  5914. var $$ = this;
  5915. return $$.isStackNormalized() && $$.config.data_groups.some(function (group) {
  5916. return group.includes(targetId);
  5917. });
  5918. };
  5919. ChartInternal.prototype.getXKey = function (id) {
  5920. var $$ = this,
  5921. config = $$.config;
  5922. return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null;
  5923. };
  5924. /**
  5925. * Get sum of visible data per index for given axis.
  5926. *
  5927. * Expect axisId to be either 'y' or 'y2'.
  5928. *
  5929. * @private
  5930. * @param axisId Compute sum for data associated to given axis.
  5931. * @return {Array}
  5932. */
  5933. ChartInternal.prototype.getTotalPerIndex = function (axisId) {
  5934. var $$ = this;
  5935. if (!$$.isStackNormalized()) {
  5936. return null;
  5937. }
  5938. var cached = $$.getFromCache('getTotalPerIndex');
  5939. if (cached !== undefined) {
  5940. return cached[axisId];
  5941. }
  5942. var sum = {
  5943. y: [],
  5944. y2: []
  5945. };
  5946. $$.data.targets // keep only target that are normalized
  5947. .filter(function (target) {
  5948. return $$.isTargetNormalized(target.id);
  5949. }) // keep only target that are visible
  5950. .filter(function (target) {
  5951. return $$.isTargetToShow(target.id);
  5952. }) // compute sum per axis
  5953. .forEach(function (target) {
  5954. var sumByAxis = sum[$$.axis.getId(target.id)];
  5955. target.values.forEach(function (v, i) {
  5956. if (!sumByAxis[i]) {
  5957. sumByAxis[i] = 0;
  5958. }
  5959. sumByAxis[i] += isNumber(v.value) ? v.value : 0;
  5960. });
  5961. });
  5962. $$.addToCache('getTotalPerIndex', sum);
  5963. return sum[axisId];
  5964. };
  5965. /**
  5966. * Get sum of visible data.
  5967. *
  5968. * Should be used for normalised data only since all values
  5969. * are expected to be positive.
  5970. *
  5971. * @private
  5972. * @return {Number}
  5973. */
  5974. ChartInternal.prototype.getTotalDataSum = function () {
  5975. var $$ = this;
  5976. var cached = $$.getFromCache('getTotalDataSum');
  5977. if (cached !== undefined) {
  5978. return cached;
  5979. }
  5980. var totalDataSum = flattenArray($$.data.targets.filter(function (target) {
  5981. return $$.isTargetToShow(target.id);
  5982. }).map(function (target) {
  5983. return target.values;
  5984. })).map(function (d) {
  5985. return d.value;
  5986. }).reduce(function (p, c) {
  5987. return p + c;
  5988. }, 0);
  5989. $$.addToCache('getTotalDataSum', totalDataSum);
  5990. return totalDataSum;
  5991. };
  5992. ChartInternal.prototype.getXValuesOfXKey = function (key, targets) {
  5993. var $$ = this,
  5994. xValues,
  5995. ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];
  5996. ids.forEach(function (id) {
  5997. if ($$.getXKey(id) === key) {
  5998. xValues = $$.data.xs[id];
  5999. }
  6000. });
  6001. return xValues;
  6002. };
  6003. ChartInternal.prototype.getXValue = function (id, i) {
  6004. var $$ = this;
  6005. return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
  6006. };
  6007. ChartInternal.prototype.getOtherTargetXs = function () {
  6008. var $$ = this,
  6009. idsForX = Object.keys($$.data.xs);
  6010. return idsForX.length ? $$.data.xs[idsForX[0]] : null;
  6011. };
  6012. ChartInternal.prototype.getOtherTargetX = function (index) {
  6013. var xs = this.getOtherTargetXs();
  6014. return xs && index < xs.length ? xs[index] : null;
  6015. };
  6016. ChartInternal.prototype.addXs = function (xs) {
  6017. var $$ = this;
  6018. Object.keys(xs).forEach(function (id) {
  6019. $$.config.data_xs[id] = xs[id];
  6020. });
  6021. };
  6022. ChartInternal.prototype.addName = function (data) {
  6023. var $$ = this,
  6024. name;
  6025. if (data) {
  6026. name = $$.config.data_names[data.id];
  6027. data.name = name !== undefined ? name : data.id;
  6028. }
  6029. return data;
  6030. };
  6031. ChartInternal.prototype.getValueOnIndex = function (values, index) {
  6032. var valueOnIndex = values.filter(function (v) {
  6033. return v.index === index;
  6034. });
  6035. return valueOnIndex.length ? valueOnIndex[0] : null;
  6036. };
  6037. ChartInternal.prototype.updateTargetX = function (targets, x) {
  6038. var $$ = this;
  6039. targets.forEach(function (t) {
  6040. t.values.forEach(function (v, i) {
  6041. v.x = $$.generateTargetX(x[i], t.id, i);
  6042. });
  6043. $$.data.xs[t.id] = x;
  6044. });
  6045. };
  6046. ChartInternal.prototype.updateTargetXs = function (targets, xs) {
  6047. var $$ = this;
  6048. targets.forEach(function (t) {
  6049. if (xs[t.id]) {
  6050. $$.updateTargetX([t], xs[t.id]);
  6051. }
  6052. });
  6053. };
  6054. ChartInternal.prototype.generateTargetX = function (rawX, id, index) {
  6055. var $$ = this,
  6056. x;
  6057. if ($$.isTimeSeries()) {
  6058. x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));
  6059. } else if ($$.isCustomX() && !$$.isCategorized()) {
  6060. x = isValue(rawX) ? +rawX : $$.getXValue(id, index);
  6061. } else {
  6062. x = index;
  6063. }
  6064. return x;
  6065. };
  6066. ChartInternal.prototype.cloneTarget = function (target) {
  6067. return {
  6068. id: target.id,
  6069. id_org: target.id_org,
  6070. values: target.values.map(function (d) {
  6071. return {
  6072. x: d.x,
  6073. value: d.value,
  6074. id: d.id
  6075. };
  6076. })
  6077. };
  6078. };
  6079. ChartInternal.prototype.getMaxDataCount = function () {
  6080. var $$ = this;
  6081. return $$.d3.max($$.data.targets, function (t) {
  6082. return t.values.length;
  6083. });
  6084. };
  6085. ChartInternal.prototype.mapToIds = function (targets) {
  6086. return targets.map(function (d) {
  6087. return d.id;
  6088. });
  6089. };
  6090. ChartInternal.prototype.mapToTargetIds = function (ids) {
  6091. var $$ = this;
  6092. return ids ? [].concat(ids) : $$.mapToIds($$.data.targets);
  6093. };
  6094. ChartInternal.prototype.hasTarget = function (targets, id) {
  6095. var ids = this.mapToIds(targets),
  6096. i;
  6097. for (i = 0; i < ids.length; i++) {
  6098. if (ids[i] === id) {
  6099. return true;
  6100. }
  6101. }
  6102. return false;
  6103. };
  6104. ChartInternal.prototype.isTargetToShow = function (targetId) {
  6105. return this.hiddenTargetIds.indexOf(targetId) < 0;
  6106. };
  6107. ChartInternal.prototype.isLegendToShow = function (targetId) {
  6108. return this.hiddenLegendIds.indexOf(targetId) < 0;
  6109. };
  6110. /**
  6111. * Returns only visible targets.
  6112. *
  6113. * This is the same as calling {@link filterTargetsToShow} on $$.data.targets.
  6114. *
  6115. * @return {Array}
  6116. */
  6117. ChartInternal.prototype.getTargetsToShow = function () {
  6118. var $$ = this;
  6119. return $$.filterTargetsToShow($$.data.targets);
  6120. };
  6121. ChartInternal.prototype.filterTargetsToShow = function (targets) {
  6122. var $$ = this;
  6123. return targets.filter(function (t) {
  6124. return $$.isTargetToShow(t.id);
  6125. });
  6126. };
  6127. /**
  6128. * @return {Array} Returns all the targets attached to the chart, visible or not
  6129. */
  6130. ChartInternal.prototype.getTargets = function () {
  6131. var $$ = this;
  6132. return $$.data.targets;
  6133. };
  6134. ChartInternal.prototype.mapTargetsToUniqueXs = function (targets) {
  6135. var $$ = this;
  6136. var xs = $$.d3.set($$.d3.merge(targets.map(function (t) {
  6137. return t.values.map(function (v) {
  6138. return +v.x;
  6139. });
  6140. }))).values();
  6141. xs = $$.isTimeSeries() ? xs.map(function (x) {
  6142. return new Date(+x);
  6143. }) : xs.map(function (x) {
  6144. return +x;
  6145. });
  6146. return xs.sort(function (a, b) {
  6147. return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
  6148. });
  6149. };
  6150. ChartInternal.prototype.addHiddenTargetIds = function (targetIds) {
  6151. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  6152. for (var i = 0; i < targetIds.length; i++) {
  6153. if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {
  6154. this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);
  6155. }
  6156. }
  6157. this.resetCache();
  6158. };
  6159. ChartInternal.prototype.removeHiddenTargetIds = function (targetIds) {
  6160. this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) {
  6161. return targetIds.indexOf(id) < 0;
  6162. });
  6163. this.resetCache();
  6164. };
  6165. ChartInternal.prototype.addHiddenLegendIds = function (targetIds) {
  6166. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  6167. for (var i = 0; i < targetIds.length; i++) {
  6168. if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {
  6169. this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);
  6170. }
  6171. }
  6172. };
  6173. ChartInternal.prototype.removeHiddenLegendIds = function (targetIds) {
  6174. this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) {
  6175. return targetIds.indexOf(id) < 0;
  6176. });
  6177. };
  6178. ChartInternal.prototype.getValuesAsIdKeyed = function (targets) {
  6179. var ys = {};
  6180. targets.forEach(function (t) {
  6181. ys[t.id] = [];
  6182. t.values.forEach(function (v) {
  6183. ys[t.id].push(v.value);
  6184. });
  6185. });
  6186. return ys;
  6187. };
  6188. ChartInternal.prototype.checkValueInTargets = function (targets, checker) {
  6189. var ids = Object.keys(targets),
  6190. i,
  6191. j,
  6192. values;
  6193. for (i = 0; i < ids.length; i++) {
  6194. values = targets[ids[i]].values;
  6195. for (j = 0; j < values.length; j++) {
  6196. if (checker(values[j].value)) {
  6197. return true;
  6198. }
  6199. }
  6200. }
  6201. return false;
  6202. };
  6203. ChartInternal.prototype.hasNegativeValueInTargets = function (targets) {
  6204. return this.checkValueInTargets(targets, function (v) {
  6205. return v < 0;
  6206. });
  6207. };
  6208. ChartInternal.prototype.hasPositiveValueInTargets = function (targets) {
  6209. return this.checkValueInTargets(targets, function (v) {
  6210. return v > 0;
  6211. });
  6212. };
  6213. ChartInternal.prototype.isOrderDesc = function () {
  6214. var config = this.config;
  6215. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'desc';
  6216. };
  6217. ChartInternal.prototype.isOrderAsc = function () {
  6218. var config = this.config;
  6219. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'asc';
  6220. };
  6221. ChartInternal.prototype.getOrderFunction = function () {
  6222. var $$ = this,
  6223. config = $$.config,
  6224. orderAsc = $$.isOrderAsc(),
  6225. orderDesc = $$.isOrderDesc();
  6226. if (orderAsc || orderDesc) {
  6227. var reducer = function reducer(p, c) {
  6228. return p + Math.abs(c.value);
  6229. };
  6230. return function (t1, t2) {
  6231. var t1Sum = t1.values.reduce(reducer, 0),
  6232. t2Sum = t2.values.reduce(reducer, 0);
  6233. return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;
  6234. };
  6235. } else if (isFunction(config.data_order)) {
  6236. return config.data_order;
  6237. } else if (isArray(config.data_order)) {
  6238. var order = config.data_order;
  6239. return function (t1, t2) {
  6240. return order.indexOf(t1.id) - order.indexOf(t2.id);
  6241. };
  6242. }
  6243. };
  6244. ChartInternal.prototype.orderTargets = function (targets) {
  6245. var fct = this.getOrderFunction();
  6246. if (fct) {
  6247. targets.sort(fct);
  6248. }
  6249. return targets;
  6250. };
  6251. /**
  6252. * Returns all the values from the given targets at the given index.
  6253. *
  6254. * @param {Array} targets
  6255. * @param {Number} index
  6256. * @return {Array}
  6257. */
  6258. ChartInternal.prototype.filterByIndex = function (targets, index) {
  6259. return this.d3.merge(targets.map(function (t) {
  6260. return t.values.filter(function (v) {
  6261. return v.index === index;
  6262. });
  6263. }));
  6264. };
  6265. ChartInternal.prototype.filterByX = function (targets, x) {
  6266. return this.d3.merge(targets.map(function (t) {
  6267. return t.values;
  6268. })).filter(function (v) {
  6269. return v.x - x === 0;
  6270. });
  6271. };
  6272. ChartInternal.prototype.filterRemoveNull = function (data) {
  6273. return data.filter(function (d) {
  6274. return isValue(d.value);
  6275. });
  6276. };
  6277. ChartInternal.prototype.filterByXDomain = function (targets, xDomain) {
  6278. return targets.map(function (t) {
  6279. return {
  6280. id: t.id,
  6281. id_org: t.id_org,
  6282. values: t.values.filter(function (v) {
  6283. return xDomain[0] <= v.x && v.x <= xDomain[1];
  6284. })
  6285. };
  6286. });
  6287. };
  6288. ChartInternal.prototype.hasDataLabel = function () {
  6289. var config = this.config;
  6290. if (typeof config.data_labels === 'boolean' && config.data_labels) {
  6291. return true;
  6292. } else if (_typeof(config.data_labels) === 'object' && notEmpty(config.data_labels)) {
  6293. return true;
  6294. }
  6295. return false;
  6296. };
  6297. ChartInternal.prototype.getDataLabelLength = function (min, max, key) {
  6298. var $$ = this,
  6299. lengths = [0, 0],
  6300. paddingCoef = 1.3;
  6301. $$.selectChart.select('svg').selectAll('.dummy').data([min, max]).enter().append('text').text(function (d) {
  6302. return $$.dataLabelFormat(d.id)(d);
  6303. }).each(function (d, i) {
  6304. lengths[i] = getBBox(this)[key] * paddingCoef;
  6305. }).remove();
  6306. return lengths;
  6307. };
  6308. /**
  6309. * Returns true if the given data point is not arc type, otherwise false.
  6310. * @param {Object} d The data point
  6311. * @return {boolean}
  6312. */
  6313. ChartInternal.prototype.isNoneArc = function (d) {
  6314. return this.hasTarget(this.data.targets, d.id);
  6315. };
  6316. /**
  6317. * Returns true if the given data point is arc type, otherwise false.
  6318. * @param {Object} d The data point
  6319. * @return {boolean}
  6320. */
  6321. ChartInternal.prototype.isArc = function (d) {
  6322. return 'data' in d && this.hasTarget(this.data.targets, d.data.id);
  6323. };
  6324. /**
  6325. * Find the closest point from the given pos among the given targets or
  6326. * undefined if none satisfies conditions.
  6327. *
  6328. * @param {Array} targets
  6329. * @param {Array} pos An [x,y] coordinate
  6330. * @return {Object|undefined}
  6331. */
  6332. ChartInternal.prototype.findClosestFromTargets = function (targets, pos) {
  6333. var $$ = this; // for each target, find the closest point
  6334. var candidates = targets.map(function (t) {
  6335. return $$.findClosest(t.values, pos, $$.config.tooltip_horizontal ? $$.horizontalDistance.bind($$) : $$.dist.bind($$), $$.config.point_sensitivity);
  6336. }).filter(function (v) {
  6337. return v;
  6338. }); // returns the closest of candidates
  6339. if (candidates.length === 0) {
  6340. return undefined;
  6341. } else if (candidates.length === 1) {
  6342. return candidates[0];
  6343. } else {
  6344. return $$.findClosest(candidates, pos, $$.dist.bind($$));
  6345. }
  6346. };
  6347. /**
  6348. * Find the closest point from the x value or undefined if none satisfies conditions.
  6349. *
  6350. * @param {Array} targets
  6351. * @param {Array} x A value on X axis
  6352. * @return {Object|undefined}
  6353. */
  6354. ChartInternal.prototype.findClosestFromTargetsByX = function (targets, x) {
  6355. var closest;
  6356. var diff;
  6357. targets.forEach(function (t) {
  6358. t.values.forEach(function (d) {
  6359. var newDiff = Math.abs(x - d.x);
  6360. if (diff === undefined || newDiff < diff) {
  6361. closest = d;
  6362. diff = newDiff;
  6363. }
  6364. });
  6365. });
  6366. return closest;
  6367. };
  6368. /**
  6369. * Using given compute distance method, returns the closest data point from the
  6370. * given position.
  6371. *
  6372. * Giving optionally a minimum distance to satisfy.
  6373. *
  6374. * @param {Array} dataPoints List of DataPoints
  6375. * @param {Array} pos An [x,y] coordinate
  6376. * @param {Function} computeDist Function to compute distance between 2 points
  6377. * @param {Number} minDist Minimal distance to satisfy
  6378. * @return {Object|undefined} Closest data point
  6379. */
  6380. ChartInternal.prototype.findClosest = function (dataPoints, pos, computeDist) {
  6381. var minDist = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : Infinity;
  6382. var $$ = this;
  6383. var closest; // find closest bar
  6384. dataPoints.filter(function (v) {
  6385. return v && $$.isBarType(v.id);
  6386. }).forEach(function (v) {
  6387. if (!closest) {
  6388. var shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node();
  6389. if ($$.isWithinBar(pos, shape)) {
  6390. closest = v;
  6391. }
  6392. }
  6393. }); // find closest point from non-bar
  6394. dataPoints.filter(function (v) {
  6395. return v && !$$.isBarType(v.id);
  6396. }).forEach(function (v) {
  6397. var d = computeDist(v, pos);
  6398. if (d < minDist) {
  6399. minDist = d;
  6400. closest = v;
  6401. }
  6402. });
  6403. return closest;
  6404. };
  6405. ChartInternal.prototype.dist = function (data, pos) {
  6406. var $$ = this,
  6407. config = $$.config,
  6408. xIndex = config.axis_rotated ? 1 : 0,
  6409. yIndex = config.axis_rotated ? 0 : 1,
  6410. y = $$.circleY(data, data.index),
  6411. x = $$.x(data.x);
  6412. return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));
  6413. };
  6414. ChartInternal.prototype.horizontalDistance = function (data, pos) {
  6415. var $$ = this,
  6416. config = $$.config,
  6417. xIndex = config.axis_rotated ? 1 : 0,
  6418. x = $$.x(data.x);
  6419. return Math.abs(x - pos[xIndex]);
  6420. };
  6421. ChartInternal.prototype.convertValuesToStep = function (values) {
  6422. var converted = [].concat(values),
  6423. i;
  6424. if (!this.isCategorized()) {
  6425. return values;
  6426. }
  6427. for (i = values.length + 1; 0 < i; i--) {
  6428. converted[i] = converted[i - 1];
  6429. }
  6430. converted[0] = {
  6431. x: converted[0].x - 1,
  6432. value: converted[0].value,
  6433. id: converted[0].id
  6434. };
  6435. converted[values.length + 1] = {
  6436. x: converted[values.length].x + 1,
  6437. value: converted[values.length].value,
  6438. id: converted[values.length].id
  6439. };
  6440. return converted;
  6441. };
  6442. /**
  6443. * Get ratio value
  6444. *
  6445. * @param {String} type Ratio for given type
  6446. * @param {Object} d Data value object
  6447. * @param {Boolean} asPercent Convert the return as percent or not
  6448. * @return {Number} Ratio value
  6449. * @private
  6450. */
  6451. ChartInternal.prototype.getRatio = function (type, d) {
  6452. var asPercent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  6453. var $$ = this;
  6454. var api = $$.api;
  6455. var ratio = 0;
  6456. if (d && api.data.shown.call(api).length) {
  6457. ratio = d.ratio || d.value;
  6458. if (type === "arc") {
  6459. if ($$.hasType('gauge')) {
  6460. ratio = (d.endAngle - d.startAngle) / (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1));
  6461. } else {
  6462. var total = $$.getTotalDataSum();
  6463. ratio = d.value / total;
  6464. }
  6465. } else if (type === "index") {
  6466. var _total = $$.getTotalPerIndex($$.axis.getId(d.id));
  6467. d.ratio = isNumber(d.value) && _total && _total[d.index] > 0 ? d.value / _total[d.index] : 0;
  6468. ratio = d.ratio;
  6469. }
  6470. }
  6471. return asPercent && ratio ? ratio * 100 : ratio;
  6472. };
  6473. ChartInternal.prototype.updateDataAttributes = function (name, attrs) {
  6474. var $$ = this,
  6475. config = $$.config,
  6476. current = config['data_' + name];
  6477. if (typeof attrs === 'undefined') {
  6478. return current;
  6479. }
  6480. Object.keys(attrs).forEach(function (id) {
  6481. current[id] = attrs[id];
  6482. });
  6483. $$.redraw({
  6484. withLegend: true
  6485. });
  6486. return current;
  6487. };
  6488. ChartInternal.prototype.load = function (targets, args) {
  6489. var $$ = this;
  6490. if (targets) {
  6491. // filter loading targets if needed
  6492. if (args.filter) {
  6493. targets = targets.filter(args.filter);
  6494. } // set type if args.types || args.type specified
  6495. if (args.type || args.types) {
  6496. targets.forEach(function (t) {
  6497. var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;
  6498. $$.setTargetType(t.id, type);
  6499. });
  6500. } // Update/Add data
  6501. $$.data.targets.forEach(function (d) {
  6502. for (var i = 0; i < targets.length; i++) {
  6503. if (d.id === targets[i].id) {
  6504. d.values = targets[i].values;
  6505. targets.splice(i, 1);
  6506. break;
  6507. }
  6508. }
  6509. });
  6510. $$.data.targets = $$.data.targets.concat(targets); // add remained
  6511. } // Set targets
  6512. $$.updateTargets($$.data.targets); // Redraw with new targets
  6513. $$.redraw({
  6514. withUpdateOrgXDomain: true,
  6515. withUpdateXDomain: true,
  6516. withLegend: true
  6517. });
  6518. if (args.done) {
  6519. args.done();
  6520. }
  6521. };
  6522. ChartInternal.prototype.loadFromArgs = function (args) {
  6523. var $$ = this;
  6524. $$.resetCache();
  6525. if (args.data) {
  6526. $$.load($$.convertDataToTargets(args.data), args);
  6527. } else if (args.url) {
  6528. $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {
  6529. $$.load($$.convertDataToTargets(data), args);
  6530. });
  6531. } else if (args.json) {
  6532. $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);
  6533. } else if (args.rows) {
  6534. $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);
  6535. } else if (args.columns) {
  6536. $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);
  6537. } else {
  6538. $$.load(null, args);
  6539. }
  6540. };
  6541. ChartInternal.prototype.unload = function (targetIds, done) {
  6542. var $$ = this;
  6543. $$.resetCache();
  6544. if (!done) {
  6545. done = function done() {};
  6546. } // filter existing target
  6547. targetIds = targetIds.filter(function (id) {
  6548. return $$.hasTarget($$.data.targets, id);
  6549. }); // If no target, call done and return
  6550. if (!targetIds || targetIds.length === 0) {
  6551. done();
  6552. return;
  6553. }
  6554. $$.svg.selectAll(targetIds.map(function (id) {
  6555. return $$.selectorTarget(id);
  6556. })).transition().style('opacity', 0).remove().call($$.endall, done);
  6557. targetIds.forEach(function (id) {
  6558. // Reset fadein for future load
  6559. $$.withoutFadeIn[id] = false; // Remove target's elements
  6560. if ($$.legend) {
  6561. $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove();
  6562. } // Remove target
  6563. $$.data.targets = $$.data.targets.filter(function (t) {
  6564. return t.id !== id;
  6565. });
  6566. });
  6567. };
  6568. ChartInternal.prototype.getYDomainMin = function (targets) {
  6569. var $$ = this,
  6570. config = $$.config,
  6571. ids = $$.mapToIds(targets),
  6572. ys = $$.getValuesAsIdKeyed(targets),
  6573. j,
  6574. k,
  6575. baseId,
  6576. idsInGroup,
  6577. id,
  6578. hasNegativeValue;
  6579. if (config.data_groups.length > 0) {
  6580. hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  6581. for (j = 0; j < config.data_groups.length; j++) {
  6582. // Determine baseId
  6583. idsInGroup = config.data_groups[j].filter(function (id) {
  6584. return ids.indexOf(id) >= 0;
  6585. });
  6586. if (idsInGroup.length === 0) {
  6587. continue;
  6588. }
  6589. baseId = idsInGroup[0]; // Consider negative values
  6590. if (hasNegativeValue && ys[baseId]) {
  6591. ys[baseId].forEach(function (v, i) {
  6592. ys[baseId][i] = v < 0 ? v : 0;
  6593. });
  6594. } // Compute min
  6595. for (k = 1; k < idsInGroup.length; k++) {
  6596. id = idsInGroup[k];
  6597. if (!ys[id]) {
  6598. continue;
  6599. }
  6600. ys[id].forEach(function (v, i) {
  6601. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) {
  6602. ys[baseId][i] += +v;
  6603. }
  6604. });
  6605. }
  6606. }
  6607. }
  6608. return $$.d3.min(Object.keys(ys).map(function (key) {
  6609. return $$.d3.min(ys[key]);
  6610. }));
  6611. };
  6612. ChartInternal.prototype.getYDomainMax = function (targets) {
  6613. var $$ = this,
  6614. config = $$.config,
  6615. ids = $$.mapToIds(targets),
  6616. ys = $$.getValuesAsIdKeyed(targets),
  6617. j,
  6618. k,
  6619. baseId,
  6620. idsInGroup,
  6621. id,
  6622. hasPositiveValue;
  6623. if (config.data_groups.length > 0) {
  6624. hasPositiveValue = $$.hasPositiveValueInTargets(targets);
  6625. for (j = 0; j < config.data_groups.length; j++) {
  6626. // Determine baseId
  6627. idsInGroup = config.data_groups[j].filter(function (id) {
  6628. return ids.indexOf(id) >= 0;
  6629. });
  6630. if (idsInGroup.length === 0) {
  6631. continue;
  6632. }
  6633. baseId = idsInGroup[0]; // Consider positive values
  6634. if (hasPositiveValue && ys[baseId]) {
  6635. ys[baseId].forEach(function (v, i) {
  6636. ys[baseId][i] = v > 0 ? v : 0;
  6637. });
  6638. } // Compute max
  6639. for (k = 1; k < idsInGroup.length; k++) {
  6640. id = idsInGroup[k];
  6641. if (!ys[id]) {
  6642. continue;
  6643. }
  6644. ys[id].forEach(function (v, i) {
  6645. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) {
  6646. ys[baseId][i] += +v;
  6647. }
  6648. });
  6649. }
  6650. }
  6651. }
  6652. return $$.d3.max(Object.keys(ys).map(function (key) {
  6653. return $$.d3.max(ys[key]);
  6654. }));
  6655. };
  6656. ChartInternal.prototype.getYDomain = function (targets, axisId, xDomain) {
  6657. var $$ = this,
  6658. config = $$.config;
  6659. if ($$.isAxisNormalized(axisId)) {
  6660. return [0, 100];
  6661. }
  6662. var targetsByAxisId = targets.filter(function (t) {
  6663. return $$.axis.getId(t.id) === axisId;
  6664. }),
  6665. yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId,
  6666. yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,
  6667. yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,
  6668. yDomainMin = $$.getYDomainMin(yTargets),
  6669. yDomainMax = $$.getYDomainMax(yTargets),
  6670. domain,
  6671. domainLength,
  6672. padding_top,
  6673. padding_bottom,
  6674. center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,
  6675. yDomainAbs,
  6676. lengths,
  6677. diff,
  6678. ratio,
  6679. isAllPositive,
  6680. isAllNegative,
  6681. isZeroBased = $$.hasType('bar', yTargets) && config.bar_zerobased || $$.hasType('area', yTargets) && config.area_zerobased,
  6682. isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,
  6683. showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,
  6684. showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; // MEMO: avoid inverting domain unexpectedly
  6685. yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? yDomainMin < yMax ? yDomainMin : yMax - 10 : yDomainMin;
  6686. yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? yMin < yDomainMax ? yDomainMax : yMin + 10 : yDomainMax;
  6687. if (yTargets.length === 0) {
  6688. // use current domain if target of axisId is none
  6689. return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();
  6690. }
  6691. if (isNaN(yDomainMin)) {
  6692. // set minimum to zero when not number
  6693. yDomainMin = 0;
  6694. }
  6695. if (isNaN(yDomainMax)) {
  6696. // set maximum to have same value as yDomainMin
  6697. yDomainMax = yDomainMin;
  6698. }
  6699. if (yDomainMin === yDomainMax) {
  6700. yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0;
  6701. }
  6702. isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;
  6703. isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; // Cancel zerobased if axis_*_min / axis_*_max specified
  6704. if (isValue(yMin) && isAllPositive || isValue(yMax) && isAllNegative) {
  6705. isZeroBased = false;
  6706. } // Bar/Area chart should be 0-based if all positive|negative
  6707. if (isZeroBased) {
  6708. if (isAllPositive) {
  6709. yDomainMin = 0;
  6710. }
  6711. if (isAllNegative) {
  6712. yDomainMax = 0;
  6713. }
  6714. }
  6715. domainLength = Math.abs(yDomainMax - yDomainMin);
  6716. padding_top = padding_bottom = domainLength * 0.1;
  6717. if (typeof center !== 'undefined') {
  6718. yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));
  6719. yDomainMax = center + yDomainAbs;
  6720. yDomainMin = center - yDomainAbs;
  6721. } // add padding for data label
  6722. if (showHorizontalDataLabel) {
  6723. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');
  6724. diff = diffDomain($$.y.range());
  6725. ratio = [lengths[0] / diff, lengths[1] / diff];
  6726. padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));
  6727. padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));
  6728. } else if (showVerticalDataLabel) {
  6729. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');
  6730. var pixelsToAxisPadding = $$.getY(config["axis_".concat(axisId, "_type")], // input domain as pixels
  6731. [0, config.axis_rotated ? $$.width : $$.height], // output range as axis padding
  6732. [0, domainLength]);
  6733. padding_top += pixelsToAxisPadding(lengths[1]);
  6734. padding_bottom += pixelsToAxisPadding(lengths[0]);
  6735. }
  6736. if (axisId === 'y' && notEmpty(config.axis_y_padding)) {
  6737. padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength);
  6738. padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength);
  6739. }
  6740. if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {
  6741. padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength);
  6742. padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength);
  6743. } // Bar/Area chart should be 0-based if all positive|negative
  6744. if (isZeroBased) {
  6745. if (isAllPositive) {
  6746. padding_bottom = yDomainMin;
  6747. }
  6748. if (isAllNegative) {
  6749. padding_top = -yDomainMax;
  6750. }
  6751. }
  6752. domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];
  6753. return isInverted ? domain.reverse() : domain;
  6754. };
  6755. ChartInternal.prototype.getXDomainMin = function (targets) {
  6756. var $$ = this,
  6757. config = $$.config;
  6758. return isDefined(config.axis_x_min) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min : $$.d3.min(targets, function (t) {
  6759. return $$.d3.min(t.values, function (v) {
  6760. return v.x;
  6761. });
  6762. });
  6763. };
  6764. ChartInternal.prototype.getXDomainMax = function (targets) {
  6765. var $$ = this,
  6766. config = $$.config;
  6767. return isDefined(config.axis_x_max) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max : $$.d3.max(targets, function (t) {
  6768. return $$.d3.max(t.values, function (v) {
  6769. return v.x;
  6770. });
  6771. });
  6772. };
  6773. ChartInternal.prototype.getXDomainPadding = function (domain) {
  6774. var $$ = this,
  6775. config = $$.config,
  6776. diff = domain[1] - domain[0],
  6777. maxDataCount,
  6778. padding,
  6779. paddingLeft,
  6780. paddingRight;
  6781. if ($$.isCategorized()) {
  6782. padding = 0;
  6783. } else if ($$.hasType('bar')) {
  6784. maxDataCount = $$.getMaxDataCount();
  6785. padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;
  6786. } else {
  6787. padding = diff * 0.01;
  6788. }
  6789. if (_typeof(config.axis_x_padding) === 'object' && notEmpty(config.axis_x_padding)) {
  6790. paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding;
  6791. paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding;
  6792. } else if (typeof config.axis_x_padding === 'number') {
  6793. paddingLeft = paddingRight = config.axis_x_padding;
  6794. } else {
  6795. paddingLeft = paddingRight = padding;
  6796. }
  6797. return {
  6798. left: paddingLeft,
  6799. right: paddingRight
  6800. };
  6801. };
  6802. ChartInternal.prototype.getXDomain = function (targets) {
  6803. var $$ = this,
  6804. xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],
  6805. firstX = xDomain[0],
  6806. lastX = xDomain[1],
  6807. padding = $$.getXDomainPadding(xDomain),
  6808. min = 0,
  6809. max = 0; // show center of x domain if min and max are the same
  6810. if (firstX - lastX === 0 && !$$.isCategorized()) {
  6811. if ($$.isTimeSeries()) {
  6812. firstX = new Date(firstX.getTime() * 0.5);
  6813. lastX = new Date(lastX.getTime() * 1.5);
  6814. } else {
  6815. firstX = firstX === 0 ? 1 : firstX * 0.5;
  6816. lastX = lastX === 0 ? -1 : lastX * 1.5;
  6817. }
  6818. }
  6819. if (firstX || firstX === 0) {
  6820. min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;
  6821. }
  6822. if (lastX || lastX === 0) {
  6823. max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right;
  6824. }
  6825. return [min, max];
  6826. };
  6827. ChartInternal.prototype.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {
  6828. var $$ = this,
  6829. config = $$.config;
  6830. if (withUpdateOrgXDomain) {
  6831. $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));
  6832. $$.orgXDomain = $$.x.domain();
  6833. if (config.zoom_enabled) {
  6834. $$.zoom.update();
  6835. }
  6836. $$.subX.domain($$.x.domain());
  6837. if ($$.brush) {
  6838. $$.brush.updateScale($$.subX);
  6839. }
  6840. }
  6841. if (withUpdateXDomain) {
  6842. $$.x.domain(domain ? domain : !$$.brush || $$.brush.empty() ? $$.orgXDomain : $$.brush.selectionAsValue());
  6843. } // Trim domain when too big by zoom mousemove event
  6844. if (withTrim) {
  6845. $$.x.domain($$.trimXDomain($$.x.orgDomain()));
  6846. }
  6847. return $$.x.domain();
  6848. };
  6849. ChartInternal.prototype.trimXDomain = function (domain) {
  6850. var zoomDomain = this.getZoomDomain(),
  6851. min = zoomDomain[0],
  6852. max = zoomDomain[1];
  6853. if (domain[0] <= min) {
  6854. domain[1] = +domain[1] + (min - domain[0]);
  6855. domain[0] = min;
  6856. }
  6857. if (max <= domain[1]) {
  6858. domain[0] = +domain[0] - (domain[1] - max);
  6859. domain[1] = max;
  6860. }
  6861. return domain;
  6862. };
  6863. ChartInternal.prototype.drag = function (mouse) {
  6864. var $$ = this,
  6865. config = $$.config,
  6866. main = $$.main,
  6867. d3 = $$.d3;
  6868. var sx, sy, mx, my, minX, maxX, minY, maxY;
  6869. if ($$.hasArcType()) {
  6870. return;
  6871. }
  6872. if (!config.data_selection_enabled) {
  6873. return;
  6874. } // do nothing if not selectable
  6875. if (!config.data_selection_multiple) {
  6876. return;
  6877. } // skip when single selection because drag is used for multiple selection
  6878. sx = $$.dragStart[0];
  6879. sy = $$.dragStart[1];
  6880. mx = mouse[0];
  6881. my = mouse[1];
  6882. minX = Math.min(sx, mx);
  6883. maxX = Math.max(sx, mx);
  6884. minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);
  6885. maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);
  6886. main.select('.' + CLASS.dragarea).attr('x', minX).attr('y', minY).attr('width', maxX - minX).attr('height', maxY - minY); // TODO: binary search when multiple xs
  6887. main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).filter(function (d) {
  6888. return config.data_selection_isselectable(d);
  6889. }).each(function (d, i) {
  6890. var shape = d3.select(this),
  6891. isSelected = shape.classed(CLASS.SELECTED),
  6892. isIncluded = shape.classed(CLASS.INCLUDED),
  6893. _x,
  6894. _y,
  6895. _w,
  6896. _h,
  6897. toggle,
  6898. isWithin = false,
  6899. box;
  6900. if (shape.classed(CLASS.circle)) {
  6901. _x = shape.attr("cx") * 1;
  6902. _y = shape.attr("cy") * 1;
  6903. toggle = $$.togglePoint;
  6904. isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;
  6905. } else if (shape.classed(CLASS.bar)) {
  6906. box = getPathBox(this);
  6907. _x = box.x;
  6908. _y = box.y;
  6909. _w = box.width;
  6910. _h = box.height;
  6911. toggle = $$.togglePath;
  6912. isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);
  6913. } else {
  6914. // line/area selection not supported yet
  6915. return;
  6916. }
  6917. if (isWithin ^ isIncluded) {
  6918. shape.classed(CLASS.INCLUDED, !isIncluded); // TODO: included/unincluded callback here
  6919. shape.classed(CLASS.SELECTED, !isSelected);
  6920. toggle.call($$, !isSelected, shape, d, i);
  6921. }
  6922. });
  6923. };
  6924. ChartInternal.prototype.dragstart = function (mouse) {
  6925. var $$ = this,
  6926. config = $$.config;
  6927. if ($$.hasArcType()) {
  6928. return;
  6929. }
  6930. if (!config.data_selection_enabled) {
  6931. return;
  6932. } // do nothing if not selectable
  6933. $$.dragStart = mouse;
  6934. $$.main.select('.' + CLASS.chart).append('rect').attr('class', CLASS.dragarea).style('opacity', 0.1);
  6935. $$.dragging = true;
  6936. };
  6937. ChartInternal.prototype.dragend = function () {
  6938. var $$ = this,
  6939. config = $$.config;
  6940. if ($$.hasArcType()) {
  6941. return;
  6942. }
  6943. if (!config.data_selection_enabled) {
  6944. return;
  6945. } // do nothing if not selectable
  6946. $$.main.select('.' + CLASS.dragarea).transition().duration(100).style('opacity', 0).remove();
  6947. $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);
  6948. $$.dragging = false;
  6949. };
  6950. ChartInternal.prototype.getYFormat = function (forArc) {
  6951. var $$ = this,
  6952. formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,
  6953. formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;
  6954. return function (v, ratio, id) {
  6955. var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;
  6956. return format.call($$, v, ratio);
  6957. };
  6958. };
  6959. ChartInternal.prototype.yFormat = function (v) {
  6960. var $$ = this,
  6961. config = $$.config,
  6962. format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat;
  6963. return format(v);
  6964. };
  6965. ChartInternal.prototype.y2Format = function (v) {
  6966. var $$ = this,
  6967. config = $$.config,
  6968. format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat;
  6969. return format(v);
  6970. };
  6971. ChartInternal.prototype.defaultValueFormat = function (v) {
  6972. return isValue(v) ? +v : "";
  6973. };
  6974. ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) {
  6975. return (ratio * 100).toFixed(1) + '%';
  6976. };
  6977. ChartInternal.prototype.dataLabelFormat = function (targetId) {
  6978. var $$ = this,
  6979. data_labels = $$.config.data_labels,
  6980. format,
  6981. defaultFormat = function defaultFormat(v) {
  6982. return isValue(v) ? +v : "";
  6983. }; // find format according to axis id
  6984. if (typeof data_labels.format === 'function') {
  6985. format = data_labels.format;
  6986. } else if (_typeof(data_labels.format) === 'object') {
  6987. if (data_labels.format[targetId]) {
  6988. format = data_labels.format[targetId] === true ? defaultFormat : data_labels.format[targetId];
  6989. } else {
  6990. format = function format() {
  6991. return '';
  6992. };
  6993. }
  6994. } else {
  6995. format = defaultFormat;
  6996. }
  6997. return format;
  6998. };
  6999. ChartInternal.prototype.initGrid = function () {
  7000. var $$ = this,
  7001. config = $$.config,
  7002. d3 = $$.d3;
  7003. $$.grid = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid);
  7004. if (config.grid_x_show) {
  7005. $$.grid.append("g").attr("class", CLASS.xgrids);
  7006. }
  7007. if (config.grid_y_show) {
  7008. $$.grid.append('g').attr('class', CLASS.ygrids);
  7009. }
  7010. if (config.grid_focus_show) {
  7011. $$.grid.append('g').attr("class", CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus);
  7012. }
  7013. $$.xgrid = d3.selectAll([]);
  7014. if (!config.grid_lines_front) {
  7015. $$.initGridLines();
  7016. }
  7017. };
  7018. ChartInternal.prototype.initGridLines = function () {
  7019. var $$ = this,
  7020. d3 = $$.d3;
  7021. $$.gridLines = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines);
  7022. $$.gridLines.append('g').attr("class", CLASS.xgridLines);
  7023. $$.gridLines.append('g').attr('class', CLASS.ygridLines);
  7024. $$.xgridLines = d3.selectAll([]);
  7025. };
  7026. ChartInternal.prototype.updateXGrid = function (withoutUpdate) {
  7027. var $$ = this,
  7028. config = $$.config,
  7029. d3 = $$.d3,
  7030. xgridData = $$.generateGridData(config.grid_x_type, $$.x),
  7031. tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;
  7032. $$.xgridAttr = config.axis_rotated ? {
  7033. 'x1': 0,
  7034. 'x2': $$.width,
  7035. 'y1': function y1(d) {
  7036. return $$.x(d) - tickOffset;
  7037. },
  7038. 'y2': function y2(d) {
  7039. return $$.x(d) - tickOffset;
  7040. }
  7041. } : {
  7042. 'x1': function x1(d) {
  7043. return $$.x(d) + tickOffset;
  7044. },
  7045. 'x2': function x2(d) {
  7046. return $$.x(d) + tickOffset;
  7047. },
  7048. 'y1': 0,
  7049. 'y2': $$.height
  7050. };
  7051. $$.xgridAttr.opacity = function () {
  7052. var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');
  7053. return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1;
  7054. };
  7055. var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid).data(xgridData);
  7056. var xgridEnter = xgrid.enter().append('line').attr("class", CLASS.xgrid).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", 0);
  7057. $$.xgrid = xgridEnter.merge(xgrid);
  7058. if (!withoutUpdate) {
  7059. $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity);
  7060. }
  7061. xgrid.exit().remove();
  7062. };
  7063. ChartInternal.prototype.updateYGrid = function () {
  7064. var $$ = this,
  7065. config = $$.config,
  7066. gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);
  7067. var ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid).data(gridValues);
  7068. var ygridEnter = ygrid.enter().append('line') // TODO: x1, x2, y1, y2, opacity need to be set here maybe
  7069. .attr('class', CLASS.ygrid);
  7070. $$.ygrid = ygridEnter.merge(ygrid);
  7071. $$.ygrid.attr("x1", config.axis_rotated ? $$.y : 0).attr("x2", config.axis_rotated ? $$.y : $$.width).attr("y1", config.axis_rotated ? 0 : $$.y).attr("y2", config.axis_rotated ? $$.height : $$.y);
  7072. ygrid.exit().remove();
  7073. $$.smoothLines($$.ygrid, 'grid');
  7074. };
  7075. ChartInternal.prototype.gridTextAnchor = function (d) {
  7076. return d.position ? d.position : "end";
  7077. };
  7078. ChartInternal.prototype.gridTextDx = function (d) {
  7079. return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4;
  7080. };
  7081. ChartInternal.prototype.xGridTextX = function (d) {
  7082. return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0;
  7083. };
  7084. ChartInternal.prototype.yGridTextX = function (d) {
  7085. return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width;
  7086. };
  7087. ChartInternal.prototype.updateGrid = function (duration) {
  7088. var $$ = this,
  7089. main = $$.main,
  7090. config = $$.config,
  7091. xgridLine,
  7092. xgridLineEnter,
  7093. ygridLine,
  7094. ygridLineEnter,
  7095. xv = $$.xv.bind($$),
  7096. yv = $$.yv.bind($$),
  7097. xGridTextX = $$.xGridTextX.bind($$),
  7098. yGridTextX = $$.yGridTextX.bind($$); // hide if arc type
  7099. $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  7100. main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  7101. if (config.grid_x_show) {
  7102. $$.updateXGrid();
  7103. }
  7104. xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine).data(config.grid_x_lines); // enter
  7105. xgridLineEnter = xgridLine.enter().append('g').attr("class", function (d) {
  7106. return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '');
  7107. });
  7108. xgridLineEnter.append('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 0);
  7109. xgridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "" : "rotate(-90)").attr("x", config.axis_rotated ? yGridTextX : xGridTextX).attr("y", xv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // udpate
  7110. $$.xgridLines = xgridLineEnter.merge(xgridLine); // done in d3.transition() of the end of this function
  7111. // exit
  7112. xgridLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Y-Grid
  7113. if (config.grid_y_show) {
  7114. $$.updateYGrid();
  7115. }
  7116. ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine).data(config.grid_y_lines); // enter
  7117. ygridLineEnter = ygridLine.enter().append('g').attr("class", function (d) {
  7118. return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '');
  7119. });
  7120. ygridLineEnter.append('line').attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 0);
  7121. ygridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "rotate(-90)" : "").attr("x", config.axis_rotated ? xGridTextX : yGridTextX).attr("y", yv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // update
  7122. $$.ygridLines = ygridLineEnter.merge(ygridLine);
  7123. $$.ygridLines.select('line').transition().duration(duration).attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 1);
  7124. $$.ygridLines.select('text').transition().duration(duration).attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr("y", yv).text(function (d) {
  7125. return d.text;
  7126. }).style("opacity", 1); // exit
  7127. ygridLine.exit().transition().duration(duration).style("opacity", 0).remove();
  7128. };
  7129. ChartInternal.prototype.redrawGrid = function (withTransition, transition) {
  7130. var $$ = this,
  7131. config = $$.config,
  7132. xv = $$.xv.bind($$),
  7133. lines = $$.xgridLines.select('line'),
  7134. texts = $$.xgridLines.select('text');
  7135. return [(withTransition ? lines.transition(transition) : lines).attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 1), (withTransition ? texts.transition(transition) : texts).attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr("y", xv).text(function (d) {
  7136. return d.text;
  7137. }).style("opacity", 1)];
  7138. };
  7139. ChartInternal.prototype.showXGridFocus = function (selectedData) {
  7140. var $$ = this,
  7141. config = $$.config,
  7142. dataToShow = selectedData.filter(function (d) {
  7143. return d && isValue(d.value);
  7144. }),
  7145. focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),
  7146. xx = $$.xx.bind($$);
  7147. if (!config.tooltip_show) {
  7148. return;
  7149. } // Hide when stanford plot exists
  7150. if ($$.hasType('stanford') || $$.hasArcType()) {
  7151. return;
  7152. }
  7153. focusEl.style("visibility", "visible").data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx);
  7154. $$.smoothLines(focusEl, 'grid');
  7155. };
  7156. ChartInternal.prototype.hideXGridFocus = function () {
  7157. this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  7158. };
  7159. ChartInternal.prototype.updateXgridFocus = function () {
  7160. var $$ = this,
  7161. config = $$.config;
  7162. $$.main.select('line.' + CLASS.xgridFocus).attr("x1", config.axis_rotated ? 0 : -10).attr("x2", config.axis_rotated ? $$.width : -10).attr("y1", config.axis_rotated ? -10 : 0).attr("y2", config.axis_rotated ? -10 : $$.height);
  7163. };
  7164. ChartInternal.prototype.generateGridData = function (type, scale) {
  7165. var $$ = this,
  7166. gridData = [],
  7167. xDomain,
  7168. firstYear,
  7169. lastYear,
  7170. i,
  7171. tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size();
  7172. if (type === 'year') {
  7173. xDomain = $$.getXDomain();
  7174. firstYear = xDomain[0].getFullYear();
  7175. lastYear = xDomain[1].getFullYear();
  7176. for (i = firstYear; i <= lastYear; i++) {
  7177. gridData.push(new Date(i + '-01-01 00:00:00'));
  7178. }
  7179. } else {
  7180. gridData = scale.ticks(10);
  7181. if (gridData.length > tickNum) {
  7182. // use only int
  7183. gridData = gridData.filter(function (d) {
  7184. return ("" + d).indexOf('.') < 0;
  7185. });
  7186. }
  7187. }
  7188. return gridData;
  7189. };
  7190. ChartInternal.prototype.getGridFilterToRemove = function (params) {
  7191. return params ? function (line) {
  7192. var found = false;
  7193. [].concat(params).forEach(function (param) {
  7194. if ('value' in param && line.value === param.value || 'class' in param && line['class'] === param['class']) {
  7195. found = true;
  7196. }
  7197. });
  7198. return found;
  7199. } : function () {
  7200. return true;
  7201. };
  7202. };
  7203. ChartInternal.prototype.removeGridLines = function (params, forX) {
  7204. var $$ = this,
  7205. config = $$.config,
  7206. toRemove = $$.getGridFilterToRemove(params),
  7207. toShow = function toShow(line) {
  7208. return !toRemove(line);
  7209. },
  7210. classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,
  7211. classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;
  7212. $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove).transition().duration(config.transition_duration).style('opacity', 0).remove();
  7213. if (forX) {
  7214. config.grid_x_lines = config.grid_x_lines.filter(toShow);
  7215. } else {
  7216. config.grid_y_lines = config.grid_y_lines.filter(toShow);
  7217. }
  7218. };
  7219. ChartInternal.prototype.initEventRect = function () {
  7220. var $$ = this,
  7221. config = $$.config;
  7222. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.eventRects).style('fill-opacity', 0);
  7223. $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect').attr('class', CLASS.eventRect); // event rect handle zoom event as well
  7224. if (config.zoom_enabled && $$.zoom) {
  7225. $$.eventRect.call($$.zoom).on("dblclick.zoom", null);
  7226. if (config.zoom_initialRange) {
  7227. // WORKAROUND: Add transition to apply transform immediately when no subchart
  7228. $$.eventRect.transition().duration(0).call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange));
  7229. }
  7230. }
  7231. };
  7232. ChartInternal.prototype.redrawEventRect = function () {
  7233. var $$ = this,
  7234. d3 = $$.d3,
  7235. config = $$.config;
  7236. function mouseout() {
  7237. $$.svg.select('.' + CLASS.eventRect).style('cursor', null);
  7238. $$.hideXGridFocus();
  7239. $$.hideTooltip();
  7240. $$.unexpandCircles();
  7241. $$.unexpandBars();
  7242. }
  7243. var isHoveringDataPoint = function isHoveringDataPoint(mouse, closest) {
  7244. return closest && ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity);
  7245. };
  7246. var withName = function withName(d) {
  7247. return d ? $$.addName(Object.assign({}, d)) : null;
  7248. }; // rects for mouseover
  7249. $$.main.select('.' + CLASS.eventRects).style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null);
  7250. $$.eventRect.attr('x', 0).attr('y', 0).attr('width', $$.width).attr('height', $$.height).on('mouseout', config.interaction_enabled ? function () {
  7251. if (!config) {
  7252. return;
  7253. } // chart is destroyed
  7254. if ($$.hasArcType()) {
  7255. return;
  7256. }
  7257. if ($$.mouseover) {
  7258. config.data_onmouseout.call($$.api, $$.mouseover);
  7259. $$.mouseover = undefined;
  7260. }
  7261. mouseout();
  7262. } : null).on('mousemove', config.interaction_enabled ? function () {
  7263. // do nothing when dragging
  7264. if ($$.dragging) {
  7265. return;
  7266. }
  7267. var targetsToShow = $$.getTargetsToShow(); // do nothing if arc type
  7268. if ($$.hasArcType(targetsToShow)) {
  7269. return;
  7270. }
  7271. var mouse = d3.mouse(this);
  7272. var closest = withName($$.findClosestFromTargets(targetsToShow, mouse));
  7273. var isMouseCloseToDataPoint = isHoveringDataPoint(mouse, closest); // ensure onmouseout is always called if mousemove switch between 2 targets
  7274. if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id || closest.index !== $$.mouseover.index)) {
  7275. config.data_onmouseout.call($$.api, $$.mouseover);
  7276. $$.mouseover = undefined;
  7277. }
  7278. if (closest && !$$.mouseover) {
  7279. config.data_onmouseover.call($$.api, closest);
  7280. $$.mouseover = closest;
  7281. } // show cursor as pointer if we're hovering a data point close enough
  7282. $$.svg.select('.' + CLASS.eventRect).style('cursor', isMouseCloseToDataPoint ? 'pointer' : null); // if tooltip not grouped, we want to display only data from closest data point
  7283. var showSingleDataPoint = !config.tooltip_grouped || $$.hasType('stanford', targetsToShow); // find data to highlight
  7284. var selectedData;
  7285. if (showSingleDataPoint) {
  7286. if (closest) {
  7287. selectedData = [closest];
  7288. }
  7289. } else {
  7290. var closestByX;
  7291. if (closest) {
  7292. // reuse closest value
  7293. closestByX = closest;
  7294. } else {
  7295. // try to find the closest value by X values from the mouse position
  7296. var mouseX = config.axis_rotated ? mouse[1] : mouse[0];
  7297. closestByX = $$.findClosestFromTargetsByX(targetsToShow, $$.x.invert(mouseX));
  7298. } // highlight all data for this 'x' value
  7299. if (closestByX) {
  7300. selectedData = $$.filterByX(targetsToShow, closestByX.x);
  7301. }
  7302. } // ensure we have data to show
  7303. if (!selectedData || selectedData.length === 0) {
  7304. return mouseout();
  7305. } // inject names for each point
  7306. selectedData = selectedData.map(withName); // show tooltip
  7307. $$.showTooltip(selectedData, this); // expand points
  7308. if (config.point_focus_expand_enabled) {
  7309. $$.unexpandCircles();
  7310. selectedData.forEach(function (d) {
  7311. $$.expandCircles(d.index, d.id, false);
  7312. });
  7313. } // expand bars
  7314. $$.unexpandBars();
  7315. selectedData.forEach(function (d) {
  7316. $$.expandBars(d.index, d.id, false);
  7317. }); // Show xgrid focus line
  7318. $$.showXGridFocus(selectedData);
  7319. } : null).on('click', config.interaction_enabled ? function () {
  7320. var targetsToShow = $$.getTargetsToShow();
  7321. if ($$.hasArcType(targetsToShow)) {
  7322. return;
  7323. }
  7324. var mouse = d3.mouse(this);
  7325. var closest = withName($$.findClosestFromTargets(targetsToShow, mouse));
  7326. if (!isHoveringDataPoint(mouse, closest)) {
  7327. return;
  7328. } // select if selection enabled
  7329. var sameXData;
  7330. if (!config.data_selection_grouped || $$.isStanfordType(closest)) {
  7331. sameXData = [closest];
  7332. } else {
  7333. sameXData = $$.filterByX(targetsToShow, closest.x);
  7334. } // toggle selected state
  7335. sameXData.forEach(function (d) {
  7336. $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.shape + '-' + d.index).each(function () {
  7337. if (config.data_selection_grouped || $$.isWithinShape(this, d)) {
  7338. $$.toggleShape(this, d, d.index);
  7339. }
  7340. });
  7341. }); // call data_onclick on the closest data point
  7342. if (closest) {
  7343. var shape = $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).select('.' + CLASS.shape + '-' + closest.index);
  7344. config.data_onclick.call($$.api, closest, shape.node());
  7345. }
  7346. } : null).call(config.interaction_enabled && config.data_selection_draggable && $$.drag ? d3.drag().on('drag', function () {
  7347. $$.drag(d3.mouse(this));
  7348. }).on('start', function () {
  7349. $$.dragstart(d3.mouse(this));
  7350. }).on('end', function () {
  7351. $$.dragend();
  7352. }) : function () {});
  7353. };
  7354. ChartInternal.prototype.getMousePosition = function (data) {
  7355. var $$ = this;
  7356. return [$$.x(data.x), $$.getYScale(data.id)(data.value)];
  7357. };
  7358. ChartInternal.prototype.dispatchEvent = function (type, mouse) {
  7359. var $$ = this,
  7360. selector = '.' + CLASS.eventRect,
  7361. eventRect = $$.main.select(selector).node(),
  7362. box = eventRect.getBoundingClientRect(),
  7363. x = box.left + (mouse ? mouse[0] : 0),
  7364. y = box.top + (mouse ? mouse[1] : 0),
  7365. event = document.createEvent("MouseEvents");
  7366. event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null);
  7367. eventRect.dispatchEvent(event);
  7368. };
  7369. ChartInternal.prototype.initLegend = function () {
  7370. var $$ = this;
  7371. $$.legendItemTextBox = {};
  7372. $$.legendHasRendered = false;
  7373. $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend'));
  7374. if (!$$.config.legend_show) {
  7375. $$.legend.style('visibility', 'hidden');
  7376. $$.hiddenLegendIds = $$.mapToIds($$.data.targets);
  7377. return;
  7378. } // MEMO: call here to update legend box and tranlate for all
  7379. // MEMO: translate will be upated by this, so transform not needed in updateLegend()
  7380. $$.updateLegendWithDefaults();
  7381. };
  7382. ChartInternal.prototype.updateLegendWithDefaults = function () {
  7383. var $$ = this;
  7384. $$.updateLegend($$.mapToIds($$.data.targets), {
  7385. withTransform: false,
  7386. withTransitionForTransform: false,
  7387. withTransition: false
  7388. });
  7389. };
  7390. ChartInternal.prototype.updateSizeForLegend = function (legendHeight, legendWidth) {
  7391. var $$ = this,
  7392. config = $$.config,
  7393. insetLegendPosition = {
  7394. top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y,
  7395. left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5
  7396. };
  7397. $$.margin3 = {
  7398. top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight,
  7399. right: NaN,
  7400. bottom: 0,
  7401. left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0
  7402. };
  7403. };
  7404. ChartInternal.prototype.transformLegend = function (withTransition) {
  7405. var $$ = this;
  7406. (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend'));
  7407. };
  7408. ChartInternal.prototype.updateLegendStep = function (step) {
  7409. this.legendStep = step;
  7410. };
  7411. ChartInternal.prototype.updateLegendItemWidth = function (w) {
  7412. this.legendItemWidth = w;
  7413. };
  7414. ChartInternal.prototype.updateLegendItemHeight = function (h) {
  7415. this.legendItemHeight = h;
  7416. };
  7417. ChartInternal.prototype.getLegendWidth = function () {
  7418. var $$ = this;
  7419. return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0;
  7420. };
  7421. ChartInternal.prototype.getLegendHeight = function () {
  7422. var $$ = this,
  7423. h = 0;
  7424. if ($$.config.legend_show) {
  7425. if ($$.isLegendRight) {
  7426. h = $$.currentHeight;
  7427. } else {
  7428. h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);
  7429. }
  7430. }
  7431. return h;
  7432. };
  7433. ChartInternal.prototype.opacityForLegend = function (legendItem) {
  7434. return legendItem.classed(CLASS.legendItemHidden) ? null : 1;
  7435. };
  7436. ChartInternal.prototype.opacityForUnfocusedLegend = function (legendItem) {
  7437. return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3;
  7438. };
  7439. ChartInternal.prototype.toggleFocusLegend = function (targetIds, focus) {
  7440. var $$ = this;
  7441. targetIds = $$.mapToTargetIds(targetIds);
  7442. $$.legend.selectAll('.' + CLASS.legendItem).filter(function (id) {
  7443. return targetIds.indexOf(id) >= 0;
  7444. }).classed(CLASS.legendItemFocused, focus).transition().duration(100).style('opacity', function () {
  7445. var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;
  7446. return opacity.call($$, $$.d3.select(this));
  7447. });
  7448. };
  7449. ChartInternal.prototype.revertLegend = function () {
  7450. var $$ = this,
  7451. d3 = $$.d3;
  7452. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemFocused, false).transition().duration(100).style('opacity', function () {
  7453. return $$.opacityForLegend(d3.select(this));
  7454. });
  7455. };
  7456. ChartInternal.prototype.showLegend = function (targetIds) {
  7457. var $$ = this,
  7458. config = $$.config;
  7459. if (!config.legend_show) {
  7460. config.legend_show = true;
  7461. $$.legend.style('visibility', 'visible');
  7462. if (!$$.legendHasRendered) {
  7463. $$.updateLegendWithDefaults();
  7464. }
  7465. }
  7466. $$.removeHiddenLegendIds(targetIds);
  7467. $$.legend.selectAll($$.selectorLegends(targetIds)).style('visibility', 'visible').transition().style('opacity', function () {
  7468. return $$.opacityForLegend($$.d3.select(this));
  7469. });
  7470. };
  7471. ChartInternal.prototype.hideLegend = function (targetIds) {
  7472. var $$ = this,
  7473. config = $$.config;
  7474. if (config.legend_show && isEmpty(targetIds)) {
  7475. config.legend_show = false;
  7476. $$.legend.style('visibility', 'hidden');
  7477. }
  7478. $$.addHiddenLegendIds(targetIds);
  7479. $$.legend.selectAll($$.selectorLegends(targetIds)).style('opacity', 0).style('visibility', 'hidden');
  7480. };
  7481. ChartInternal.prototype.clearLegendItemTextBoxCache = function () {
  7482. this.legendItemTextBox = {};
  7483. };
  7484. ChartInternal.prototype.updateLegend = function (targetIds, options, transitions) {
  7485. var $$ = this,
  7486. config = $$.config;
  7487. var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile;
  7488. var paddingTop = 4,
  7489. paddingRight = 10,
  7490. maxWidth = 0,
  7491. maxHeight = 0,
  7492. posMin = 10,
  7493. tileWidth = config.legend_item_tile_width + 5;
  7494. var l,
  7495. totalLength = 0,
  7496. offsets = {},
  7497. widths = {},
  7498. heights = {},
  7499. margins = [0],
  7500. steps = {},
  7501. step = 0;
  7502. var withTransition, withTransitionForTransform;
  7503. var texts, rects, tiles, background; // Skip elements when their name is set to null
  7504. targetIds = targetIds.filter(function (id) {
  7505. return !isDefined(config.data_names[id]) || config.data_names[id] !== null;
  7506. });
  7507. options = options || {};
  7508. withTransition = getOption(options, "withTransition", true);
  7509. withTransitionForTransform = getOption(options, "withTransitionForTransform", true);
  7510. function getTextBox(textElement, id) {
  7511. if (!$$.legendItemTextBox[id]) {
  7512. $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement);
  7513. }
  7514. return $$.legendItemTextBox[id];
  7515. }
  7516. function updatePositions(textElement, id, index) {
  7517. var reset = index === 0,
  7518. isLast = index === targetIds.length - 1,
  7519. box = getTextBox(textElement, id),
  7520. itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + config.legend_padding,
  7521. itemHeight = box.height + paddingTop,
  7522. itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,
  7523. areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(),
  7524. margin,
  7525. maxLength; // MEMO: care about condifion of step, totalLength
  7526. function updateValues(id, withoutStep) {
  7527. if (!withoutStep) {
  7528. margin = (areaLength - totalLength - itemLength) / 2;
  7529. if (margin < posMin) {
  7530. margin = (areaLength - itemLength) / 2;
  7531. totalLength = 0;
  7532. step++;
  7533. }
  7534. }
  7535. steps[id] = step;
  7536. margins[step] = $$.isLegendInset ? 10 : margin;
  7537. offsets[id] = totalLength;
  7538. totalLength += itemLength;
  7539. }
  7540. if (reset) {
  7541. totalLength = 0;
  7542. step = 0;
  7543. maxWidth = 0;
  7544. maxHeight = 0;
  7545. }
  7546. if (config.legend_show && !$$.isLegendToShow(id)) {
  7547. widths[id] = heights[id] = steps[id] = offsets[id] = 0;
  7548. return;
  7549. }
  7550. widths[id] = itemWidth;
  7551. heights[id] = itemHeight;
  7552. if (!maxWidth || itemWidth >= maxWidth) {
  7553. maxWidth = itemWidth;
  7554. }
  7555. if (!maxHeight || itemHeight >= maxHeight) {
  7556. maxHeight = itemHeight;
  7557. }
  7558. maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;
  7559. if (config.legend_equally) {
  7560. Object.keys(widths).forEach(function (id) {
  7561. widths[id] = maxWidth;
  7562. });
  7563. Object.keys(heights).forEach(function (id) {
  7564. heights[id] = maxHeight;
  7565. });
  7566. margin = (areaLength - maxLength * targetIds.length) / 2;
  7567. if (margin < posMin) {
  7568. totalLength = 0;
  7569. step = 0;
  7570. targetIds.forEach(function (id) {
  7571. updateValues(id);
  7572. });
  7573. } else {
  7574. updateValues(id, true);
  7575. }
  7576. } else {
  7577. updateValues(id);
  7578. }
  7579. }
  7580. if ($$.isLegendInset) {
  7581. step = config.legend_inset_step ? config.legend_inset_step : targetIds.length;
  7582. $$.updateLegendStep(step);
  7583. }
  7584. if ($$.isLegendRight) {
  7585. xForLegend = function xForLegend(id) {
  7586. return maxWidth * steps[id];
  7587. };
  7588. yForLegend = function yForLegend(id) {
  7589. return margins[steps[id]] + offsets[id];
  7590. };
  7591. } else if ($$.isLegendInset) {
  7592. xForLegend = function xForLegend(id) {
  7593. return maxWidth * steps[id] + 10;
  7594. };
  7595. yForLegend = function yForLegend(id) {
  7596. return margins[steps[id]] + offsets[id];
  7597. };
  7598. } else {
  7599. xForLegend = function xForLegend(id) {
  7600. return margins[steps[id]] + offsets[id];
  7601. };
  7602. yForLegend = function yForLegend(id) {
  7603. return maxHeight * steps[id];
  7604. };
  7605. }
  7606. xForLegendText = function xForLegendText(id, i) {
  7607. return xForLegend(id, i) + 4 + config.legend_item_tile_width;
  7608. };
  7609. yForLegendText = function yForLegendText(id, i) {
  7610. return yForLegend(id, i) + 9;
  7611. };
  7612. xForLegendRect = function xForLegendRect(id, i) {
  7613. return xForLegend(id, i);
  7614. };
  7615. yForLegendRect = function yForLegendRect(id, i) {
  7616. return yForLegend(id, i) - 5;
  7617. };
  7618. x1ForLegendTile = function x1ForLegendTile(id, i) {
  7619. return xForLegend(id, i) - 2;
  7620. };
  7621. x2ForLegendTile = function x2ForLegendTile(id, i) {
  7622. return xForLegend(id, i) - 2 + config.legend_item_tile_width;
  7623. };
  7624. yForLegendTile = function yForLegendTile(id, i) {
  7625. return yForLegend(id, i) + 4;
  7626. }; // Define g for legend area
  7627. l = $$.legend.selectAll('.' + CLASS.legendItem).data(targetIds).enter().append('g').attr('class', function (id) {
  7628. return $$.generateClass(CLASS.legendItem, id);
  7629. }).style('visibility', function (id) {
  7630. return $$.isLegendToShow(id) ? 'visible' : 'hidden';
  7631. }).style('cursor', 'pointer').on('click', function (id) {
  7632. if (config.legend_item_onclick) {
  7633. config.legend_item_onclick.call($$, id);
  7634. } else {
  7635. if ($$.d3.event.altKey) {
  7636. $$.api.hide();
  7637. $$.api.show(id);
  7638. } else {
  7639. $$.api.toggle(id);
  7640. $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();
  7641. }
  7642. }
  7643. }).on('mouseover', function (id) {
  7644. if (config.legend_item_onmouseover) {
  7645. config.legend_item_onmouseover.call($$, id);
  7646. } else {
  7647. $$.d3.select(this).classed(CLASS.legendItemFocused, true);
  7648. if (!$$.transiting && $$.isTargetToShow(id)) {
  7649. $$.api.focus(id);
  7650. }
  7651. }
  7652. }).on('mouseout', function (id) {
  7653. if (config.legend_item_onmouseout) {
  7654. config.legend_item_onmouseout.call($$, id);
  7655. } else {
  7656. $$.d3.select(this).classed(CLASS.legendItemFocused, false);
  7657. $$.api.revert();
  7658. }
  7659. });
  7660. l.append('text').text(function (id) {
  7661. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  7662. }).each(function (id, i) {
  7663. updatePositions(this, id, i);
  7664. }).style("pointer-events", "none").attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);
  7665. l.append('rect').attr("class", CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);
  7666. l.append('line').attr('class', CLASS.legendItemTile).style('stroke', $$.color).style("pointer-events", "none").attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200).attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200).attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('stroke-width', config.legend_item_tile_height); // Set background for inset legend
  7667. background = $$.legend.select('.' + CLASS.legendBackground + ' rect');
  7668. if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {
  7669. background = $$.legend.insert('g', '.' + CLASS.legendItem).attr("class", CLASS.legendBackground).append('rect');
  7670. }
  7671. texts = $$.legend.selectAll('text').data(targetIds).text(function (id) {
  7672. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  7673. }) // MEMO: needed for update
  7674. .each(function (id, i) {
  7675. updatePositions(this, id, i);
  7676. });
  7677. (withTransition ? texts.transition() : texts).attr('x', xForLegendText).attr('y', yForLegendText);
  7678. rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds);
  7679. (withTransition ? rects.transition() : rects).attr('width', function (id) {
  7680. return widths[id];
  7681. }).attr('height', function (id) {
  7682. return heights[id];
  7683. }).attr('x', xForLegendRect).attr('y', yForLegendRect);
  7684. tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds);
  7685. (withTransition ? tiles.transition() : tiles).style('stroke', $$.levelColor ? function (id) {
  7686. return $$.levelColor($$.cache[id].values.reduce(function (total, item) {
  7687. return total + item.value;
  7688. }, 0));
  7689. } : $$.color).attr('x1', x1ForLegendTile).attr('y1', yForLegendTile).attr('x2', x2ForLegendTile).attr('y2', yForLegendTile);
  7690. if (background) {
  7691. (withTransition ? background.transition() : background).attr('height', $$.getLegendHeight() - 12).attr('width', maxWidth * (step + 1) + 10);
  7692. } // toggle legend state
  7693. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemHidden, function (id) {
  7694. return !$$.isTargetToShow(id);
  7695. }); // Update all to reflect change of legend
  7696. $$.updateLegendItemWidth(maxWidth);
  7697. $$.updateLegendItemHeight(maxHeight);
  7698. $$.updateLegendStep(step); // Update size and scale
  7699. $$.updateSizes();
  7700. $$.updateScales();
  7701. $$.updateSvgSize(); // Update g positions
  7702. $$.transformAll(withTransitionForTransform, transitions);
  7703. $$.legendHasRendered = true;
  7704. };
  7705. ChartInternal.prototype.initRegion = function () {
  7706. var $$ = this;
  7707. $$.region = $$.main.append('g').attr("clip-path", $$.clipPath).attr("class", CLASS.regions);
  7708. };
  7709. ChartInternal.prototype.updateRegion = function (duration) {
  7710. var $$ = this,
  7711. config = $$.config; // hide if arc type
  7712. $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  7713. var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region).data(config.regions);
  7714. var g = mainRegion.enter().append('g');
  7715. g.append('rect').attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) {
  7716. return isValue(d.opacity) ? d.opacity : 0.1;
  7717. });
  7718. g.append('text').text($$.labelRegion.bind($$));
  7719. $$.mainRegion = g.merge(mainRegion).attr('class', $$.classRegion.bind($$));
  7720. mainRegion.exit().transition().duration(duration).style("opacity", 0).remove();
  7721. };
  7722. ChartInternal.prototype.redrawRegion = function (withTransition, transition) {
  7723. var $$ = this,
  7724. regions = $$.mainRegion,
  7725. regionLabels = $$.mainRegion.selectAll('text');
  7726. return [(withTransition ? regions.transition(transition) : regions).attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) {
  7727. return isValue(d.opacity) ? d.opacity : 0.1;
  7728. }), (withTransition ? regionLabels.transition(transition) : regionLabels).attr("x", $$.labelOffsetX.bind($$)).attr("y", $$.labelOffsetY.bind($$)).attr("transform", $$.labelTransform.bind($$)).attr("style", 'text-anchor: left;')];
  7729. };
  7730. ChartInternal.prototype.regionX = function (d) {
  7731. var $$ = this,
  7732. config = $$.config,
  7733. xPos,
  7734. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7735. if (d.axis === 'y' || d.axis === 'y2') {
  7736. xPos = config.axis_rotated ? 'start' in d ? yScale(d.start) : 0 : 0;
  7737. } else {
  7738. xPos = config.axis_rotated ? 0 : 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0;
  7739. }
  7740. return xPos;
  7741. };
  7742. ChartInternal.prototype.regionY = function (d) {
  7743. var $$ = this,
  7744. config = $$.config,
  7745. yPos,
  7746. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7747. if (d.axis === 'y' || d.axis === 'y2') {
  7748. yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;
  7749. } else {
  7750. yPos = config.axis_rotated ? 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0 : 0;
  7751. }
  7752. return yPos;
  7753. };
  7754. ChartInternal.prototype.regionWidth = function (d) {
  7755. var $$ = this,
  7756. config = $$.config,
  7757. start = $$.regionX(d),
  7758. end,
  7759. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7760. if (d.axis === 'y' || d.axis === 'y2') {
  7761. end = config.axis_rotated ? 'end' in d ? yScale(d.end) : $$.width : $$.width;
  7762. } else {
  7763. end = config.axis_rotated ? $$.width : 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width;
  7764. }
  7765. return end < start ? 0 : end - start;
  7766. };
  7767. ChartInternal.prototype.regionHeight = function (d) {
  7768. var $$ = this,
  7769. config = $$.config,
  7770. start = this.regionY(d),
  7771. end,
  7772. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7773. if (d.axis === 'y' || d.axis === 'y2') {
  7774. end = config.axis_rotated ? $$.height : 'start' in d ? yScale(d.start) : $$.height;
  7775. } else {
  7776. end = config.axis_rotated ? 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height : $$.height;
  7777. }
  7778. return end < start ? 0 : end - start;
  7779. };
  7780. ChartInternal.prototype.isRegionOnX = function (d) {
  7781. return !d.axis || d.axis === 'x';
  7782. };
  7783. ChartInternal.prototype.labelRegion = function (d) {
  7784. return 'label' in d ? d.label : '';
  7785. };
  7786. ChartInternal.prototype.labelTransform = function (d) {
  7787. return 'vertical' in d && d.vertical ? "rotate(90)" : "";
  7788. };
  7789. ChartInternal.prototype.labelOffsetX = function (d) {
  7790. var paddingX = 'paddingX' in d ? d.paddingX : 3;
  7791. var paddingY = 'paddingY' in d ? d.paddingY : 3;
  7792. return 'vertical' in d && d.vertical ? this.regionY(d) + paddingY : this.regionX(d) + paddingX;
  7793. };
  7794. ChartInternal.prototype.labelOffsetY = function (d) {
  7795. var paddingX = 'paddingX' in d ? d.paddingX : 3;
  7796. var paddingY = 'paddingY' in d ? d.paddingY : 3;
  7797. return 'vertical' in d && d.vertical ? -(this.regionX(d) + paddingX) : this.regionY(d) + 10 + paddingY;
  7798. };
  7799. function c3LogScale(d3, linearScale, logScale) {
  7800. var PROJECTION = [0.01, 10];
  7801. if (!linearScale) {
  7802. linearScale = d3.scaleLinear();
  7803. linearScale.range(PROJECTION);
  7804. }
  7805. if (!logScale) {
  7806. logScale = d3.scaleLog();
  7807. logScale.domain(PROJECTION);
  7808. logScale.nice();
  7809. } // copied from https://github.com/compute-io/logspace
  7810. function logspace(a, b, len) {
  7811. var arr, end, tmp, d;
  7812. if (arguments.length < 3) {
  7813. len = 10;
  7814. } else {
  7815. if (len === 0) {
  7816. return [];
  7817. }
  7818. } // Calculate the increment:
  7819. end = len - 1;
  7820. d = (b - a) / end; // Build the output array...
  7821. arr = new Array(len);
  7822. tmp = a;
  7823. arr[0] = Math.pow(10, tmp);
  7824. for (var i = 1; i < end; i++) {
  7825. tmp += d;
  7826. arr[i] = Math.pow(10, tmp);
  7827. }
  7828. arr[end] = Math.pow(10, b);
  7829. return arr;
  7830. }
  7831. function scale(x) {
  7832. return logScale(linearScale(x));
  7833. }
  7834. scale.domain = function (x) {
  7835. if (!arguments.length) {
  7836. return linearScale.domain();
  7837. }
  7838. linearScale.domain(x);
  7839. return scale;
  7840. };
  7841. scale.range = function (x) {
  7842. if (!arguments.length) {
  7843. return logScale.range();
  7844. }
  7845. logScale.range(x);
  7846. return scale;
  7847. };
  7848. scale.ticks = function (m) {
  7849. return logspace(-2, 1, m || 10).map(function (v) {
  7850. return linearScale.invert(v);
  7851. });
  7852. };
  7853. scale.copy = function () {
  7854. return c3LogScale(d3, linearScale.copy(), logScale.copy());
  7855. };
  7856. return scale;
  7857. }
  7858. ChartInternal.prototype.getScale = function (min, max, forTimeseries) {
  7859. return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([min, max]);
  7860. };
  7861. ChartInternal.prototype.getX = function (min, max, domain, offset) {
  7862. var $$ = this,
  7863. scale = $$.getScale(min, max, $$.isTimeSeries()),
  7864. _scale = domain ? scale.domain(domain) : scale,
  7865. key; // Define customized scale if categorized axis
  7866. if ($$.isCategorized()) {
  7867. offset = offset || function () {
  7868. return 0;
  7869. };
  7870. scale = function scale(d, raw) {
  7871. var v = _scale(d) + offset(d);
  7872. return raw ? v : Math.ceil(v);
  7873. };
  7874. } else {
  7875. scale = function scale(d, raw) {
  7876. var v = _scale(d);
  7877. return raw ? v : Math.ceil(v);
  7878. };
  7879. } // define functions
  7880. for (key in _scale) {
  7881. scale[key] = _scale[key];
  7882. }
  7883. scale.orgDomain = function () {
  7884. return _scale.domain();
  7885. }; // define custom domain() for categorized axis
  7886. if ($$.isCategorized()) {
  7887. scale.domain = function (domain) {
  7888. if (!arguments.length) {
  7889. domain = this.orgDomain();
  7890. return [domain[0], domain[1] + 1];
  7891. }
  7892. _scale.domain(domain);
  7893. return scale;
  7894. };
  7895. }
  7896. return scale;
  7897. };
  7898. /**
  7899. * Creates and configures a D3 scale instance for the given type.
  7900. *
  7901. * By defaults it returns a Linear scale.
  7902. *
  7903. * @param {String} type Type of d3-scale to create. Type can be 'linear', 'time', 'timeseries' or 'log'.
  7904. * @param {Array} domain The scale domain such as [from, to]
  7905. * @param {Array} range The scale's range such as [from, to]
  7906. *
  7907. * @return A d3-scale instance
  7908. */
  7909. ChartInternal.prototype.getY = function (type, domain, range) {
  7910. var scale;
  7911. if (type === 'timeseries' || type === 'time') {
  7912. scale = this.d3.scaleTime();
  7913. } else if (type === 'log') {
  7914. scale = c3LogScale(this.d3);
  7915. } else if (type === 'linear' || type === undefined) {
  7916. scale = this.d3.scaleLinear();
  7917. } else {
  7918. throw new Error("Invalid Y axis type: \"".concat(type, "\""));
  7919. }
  7920. if (domain) {
  7921. scale.domain(domain);
  7922. }
  7923. if (range) {
  7924. scale.range(range);
  7925. }
  7926. return scale;
  7927. };
  7928. ChartInternal.prototype.getYScale = function (id) {
  7929. return this.axis.getId(id) === 'y2' ? this.y2 : this.y;
  7930. };
  7931. ChartInternal.prototype.getSubYScale = function (id) {
  7932. return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY;
  7933. };
  7934. ChartInternal.prototype.updateScales = function () {
  7935. var $$ = this,
  7936. config = $$.config,
  7937. forInit = !$$.x; // update edges
  7938. $$.xMin = config.axis_rotated ? 1 : 0;
  7939. $$.xMax = config.axis_rotated ? $$.height : $$.width;
  7940. $$.yMin = config.axis_rotated ? 0 : $$.height;
  7941. $$.yMax = config.axis_rotated ? $$.width : 1;
  7942. $$.subXMin = $$.xMin;
  7943. $$.subXMax = $$.xMax;
  7944. $$.subYMin = config.axis_rotated ? 0 : $$.height2;
  7945. $$.subYMax = config.axis_rotated ? $$.width2 : 1; // update scales
  7946. $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () {
  7947. return $$.xAxis.tickOffset();
  7948. });
  7949. $$.y = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.y.domain(), [$$.yMin, $$.yMax]);
  7950. $$.y2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.y2.domain(), [$$.yMin, $$.yMax]);
  7951. $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) {
  7952. return d % 1 ? 0 : $$.subXAxis.tickOffset();
  7953. });
  7954. $$.subY = $$.getY(config.axis_y_type, forInit ? config.axis_y_default : $$.subY.domain(), [$$.subYMin, $$.subYMax]);
  7955. $$.subY2 = $$.getY(config.axis_y2_type, forInit ? config.axis_y2_default : $$.subY2.domain(), [$$.subYMin, $$.subYMax]); // update axes
  7956. $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();
  7957. $$.xAxisTickValues = $$.axis.getXAxisTickValues();
  7958. $$.yAxisTickValues = $$.axis.getYAxisTickValues();
  7959. $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();
  7960. $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  7961. $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  7962. $$.yAxis = $$.axis.getYAxis('y', $$.y, $$.yOrient, $$.yAxisTickValues, config.axis_y_tick_outer);
  7963. $$.y2Axis = $$.axis.getYAxis('y2', $$.y2, $$.y2Orient, $$.y2AxisTickValues, config.axis_y2_tick_outer); // Set initialized scales to brush and zoom
  7964. if (!forInit) {
  7965. if ($$.brush) {
  7966. $$.brush.updateScale($$.subX);
  7967. }
  7968. } // update for arc
  7969. if ($$.updateArc) {
  7970. $$.updateArc();
  7971. }
  7972. };
  7973. ChartInternal.prototype.selectPoint = function (target, d, i) {
  7974. var $$ = this,
  7975. config = $$.config,
  7976. cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),
  7977. cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),
  7978. r = $$.pointSelectR.bind($$);
  7979. config.data_onselected.call($$.api, d, target.node()); // add selected-circle on low layer g
  7980. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr("class", function () {
  7981. return $$.generateClass(CLASS.selectedCircle, i);
  7982. }).attr("cx", cx).attr("cy", cy).attr("stroke", function () {
  7983. return $$.color(d);
  7984. }).attr("r", function (d) {
  7985. return $$.pointSelectR(d) * 1.4;
  7986. }).transition().duration(100).attr("r", r);
  7987. };
  7988. ChartInternal.prototype.unselectPoint = function (target, d, i) {
  7989. var $$ = this;
  7990. $$.config.data_onunselected.call($$.api, d, target.node()); // remove selected-circle from low layer g
  7991. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).transition().duration(100).attr('r', 0).remove();
  7992. };
  7993. ChartInternal.prototype.togglePoint = function (selected, target, d, i) {
  7994. selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);
  7995. };
  7996. ChartInternal.prototype.selectPath = function (target, d) {
  7997. var $$ = this;
  7998. $$.config.data_onselected.call($$, d, target.node());
  7999. if ($$.config.interaction_brighten) {
  8000. target.transition().duration(100).style("fill", function () {
  8001. return $$.d3.rgb($$.color(d)).brighter(0.75);
  8002. });
  8003. }
  8004. };
  8005. ChartInternal.prototype.unselectPath = function (target, d) {
  8006. var $$ = this;
  8007. $$.config.data_onunselected.call($$, d, target.node());
  8008. if ($$.config.interaction_brighten) {
  8009. target.transition().duration(100).style("fill", function () {
  8010. return $$.color(d);
  8011. });
  8012. }
  8013. };
  8014. ChartInternal.prototype.togglePath = function (selected, target, d, i) {
  8015. selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);
  8016. };
  8017. ChartInternal.prototype.getToggle = function (that, d) {
  8018. var $$ = this,
  8019. toggle;
  8020. if (that.nodeName === 'circle') {
  8021. if ($$.isStepType(d)) {
  8022. // circle is hidden in step chart, so treat as within the click area
  8023. toggle = function toggle() {}; // TODO: how to select step chart?
  8024. } else {
  8025. toggle = $$.togglePoint;
  8026. }
  8027. } else if (that.nodeName === 'path') {
  8028. toggle = $$.togglePath;
  8029. }
  8030. return toggle;
  8031. };
  8032. ChartInternal.prototype.toggleShape = function (that, d, i) {
  8033. var $$ = this,
  8034. d3 = $$.d3,
  8035. config = $$.config,
  8036. shape = d3.select(that),
  8037. isSelected = shape.classed(CLASS.SELECTED),
  8038. toggle = $$.getToggle(that, d).bind($$);
  8039. if (config.data_selection_enabled && config.data_selection_isselectable(d)) {
  8040. if (!config.data_selection_multiple) {
  8041. $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) {
  8042. var shape = d3.select(this);
  8043. if (shape.classed(CLASS.SELECTED)) {
  8044. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  8045. }
  8046. });
  8047. }
  8048. shape.classed(CLASS.SELECTED, !isSelected);
  8049. toggle(!isSelected, shape, d, i);
  8050. }
  8051. };
  8052. ChartInternal.prototype.initBar = function () {
  8053. var $$ = this;
  8054. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars);
  8055. };
  8056. ChartInternal.prototype.updateTargetsForBar = function (targets) {
  8057. var $$ = this,
  8058. config = $$.config,
  8059. mainBars,
  8060. mainBarEnter,
  8061. classChartBar = $$.classChartBar.bind($$),
  8062. classBars = $$.classBars.bind($$),
  8063. classFocus = $$.classFocus.bind($$);
  8064. mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', function (d) {
  8065. return classChartBar(d) + classFocus(d);
  8066. });
  8067. mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style("pointer-events", "none"); // Bars for each data
  8068. mainBarEnter.append('g').attr("class", classBars).style("cursor", function (d) {
  8069. return config.data_selection_isselectable(d) ? "pointer" : null;
  8070. });
  8071. };
  8072. ChartInternal.prototype.updateBar = function (durationForExit) {
  8073. var $$ = this,
  8074. barData = $$.barData.bind($$),
  8075. classBar = $$.classBar.bind($$),
  8076. initialOpacity = $$.initialOpacity.bind($$),
  8077. color = function color(d) {
  8078. return $$.color(d.id);
  8079. };
  8080. var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data(barData);
  8081. var mainBarEnter = mainBar.enter().append('path').attr("class", classBar).style("stroke", color).style("fill", color);
  8082. $$.mainBar = mainBarEnter.merge(mainBar).style("opacity", initialOpacity);
  8083. mainBar.exit().transition().duration(durationForExit).style("opacity", 0);
  8084. };
  8085. ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) {
  8086. var $$ = this;
  8087. return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style("stroke", this.color).style("fill", this.color).style("opacity", function (d) {
  8088. return $$.isTargetToShow(d.id) ? 1 : 0;
  8089. })];
  8090. };
  8091. ChartInternal.prototype.getBarW = function (axis, barTargetsNum) {
  8092. var $$ = this,
  8093. config = $$.config,
  8094. w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? axis.tickInterval() * config.bar_width_ratio / barTargetsNum : 0;
  8095. return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w;
  8096. };
  8097. ChartInternal.prototype.getBars = function (i, id) {
  8098. var $$ = this;
  8099. return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
  8100. };
  8101. ChartInternal.prototype.expandBars = function (i, id, reset) {
  8102. var $$ = this;
  8103. if (reset) {
  8104. $$.unexpandBars();
  8105. }
  8106. $$.getBars(i, id).classed(CLASS.EXPANDED, true);
  8107. };
  8108. ChartInternal.prototype.unexpandBars = function (i) {
  8109. var $$ = this;
  8110. $$.getBars(i).classed(CLASS.EXPANDED, false);
  8111. };
  8112. ChartInternal.prototype.generateDrawBar = function (barIndices, isSub) {
  8113. var $$ = this,
  8114. config = $$.config,
  8115. getPoints = $$.generateGetBarPoints(barIndices, isSub);
  8116. return function (d, i) {
  8117. // 4 points that make a bar
  8118. var points = getPoints(d, i); // switch points if axis is rotated, not applicable for sub chart
  8119. var indexX = config.axis_rotated ? 1 : 0;
  8120. var indexY = config.axis_rotated ? 0 : 1;
  8121. var path = 'M ' + points[0][indexX] + ',' + points[0][indexY] + ' ' + 'L' + points[1][indexX] + ',' + points[1][indexY] + ' ' + 'L' + points[2][indexX] + ',' + points[2][indexY] + ' ' + 'L' + points[3][indexX] + ',' + points[3][indexY] + ' ' + 'z';
  8122. return path;
  8123. };
  8124. };
  8125. ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) {
  8126. var $$ = this,
  8127. axis = isSub ? $$.subXAxis : $$.xAxis,
  8128. barTargetsNum = barIndices.__max__ + 1,
  8129. barW = $$.getBarW(axis, barTargetsNum),
  8130. barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),
  8131. barY = $$.getShapeY(!!isSub),
  8132. barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),
  8133. barSpaceOffset = barW * ($$.config.bar_space / 2),
  8134. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  8135. return function (d, i) {
  8136. var y0 = yScale.call($$, d.id)(0),
  8137. offset = barOffset(d, i) || y0,
  8138. // offset is for stacked bar chart
  8139. posX = barX(d),
  8140. posY = barY(d); // fix posY not to overflow opposite quadrant
  8141. if ($$.config.axis_rotated) {
  8142. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  8143. posY = y0;
  8144. }
  8145. }
  8146. posY -= y0 - offset; // 4 points that make a bar
  8147. return [[posX + barSpaceOffset, offset], [posX + barSpaceOffset, posY], [posX + barW - barSpaceOffset, posY], [posX + barW - barSpaceOffset, offset]];
  8148. };
  8149. };
  8150. /**
  8151. * Returns whether the data point is within the given bar shape.
  8152. *
  8153. * @param mouse
  8154. * @param barShape
  8155. * @return {boolean}
  8156. */
  8157. ChartInternal.prototype.isWithinBar = function (mouse, barShape) {
  8158. return isWithinBox(mouse, getBBox(barShape), 2);
  8159. };
  8160. ChartInternal.prototype.getShapeIndices = function (typeFilter) {
  8161. var $$ = this,
  8162. config = $$.config,
  8163. indices = {},
  8164. i = 0,
  8165. j,
  8166. k;
  8167. $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {
  8168. for (j = 0; j < config.data_groups.length; j++) {
  8169. if (config.data_groups[j].indexOf(d.id) < 0) {
  8170. continue;
  8171. }
  8172. for (k = 0; k < config.data_groups[j].length; k++) {
  8173. if (config.data_groups[j][k] in indices) {
  8174. indices[d.id] = indices[config.data_groups[j][k]];
  8175. break;
  8176. }
  8177. }
  8178. }
  8179. if (isUndefined(indices[d.id])) {
  8180. indices[d.id] = i++;
  8181. }
  8182. });
  8183. indices.__max__ = i - 1;
  8184. return indices;
  8185. };
  8186. ChartInternal.prototype.getShapeX = function (offset, targetsNum, indices, isSub) {
  8187. var $$ = this,
  8188. scale = isSub ? $$.subX : $$.x;
  8189. return function (d) {
  8190. var index = d.id in indices ? indices[d.id] : 0;
  8191. return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;
  8192. };
  8193. };
  8194. ChartInternal.prototype.getShapeY = function (isSub) {
  8195. var $$ = this;
  8196. return function (d) {
  8197. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);
  8198. return scale($$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value);
  8199. };
  8200. };
  8201. ChartInternal.prototype.getShapeOffset = function (typeFilter, indices, isSub) {
  8202. var $$ = this,
  8203. targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))),
  8204. targetIds = targets.map(function (t) {
  8205. return t.id;
  8206. });
  8207. return function (d, i) {
  8208. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),
  8209. y0 = scale(0),
  8210. offset = y0;
  8211. targets.forEach(function (t) {
  8212. var rowValues = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values;
  8213. var isTargetNormalized = $$.isTargetNormalized(d.id);
  8214. var values = rowValues.map(function (v) {
  8215. return isTargetNormalized ? $$.getRatio("index", v, true) : v.value;
  8216. });
  8217. if (t.id === d.id || indices[t.id] !== indices[d.id]) {
  8218. return;
  8219. }
  8220. if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {
  8221. // check if the x values line up
  8222. if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {
  8223. // "+" for timeseries
  8224. // if not, try to find the value that does line up
  8225. i = -1;
  8226. rowValues.forEach(function (v, j) {
  8227. var x1 = v.x.constructor === Date ? +v.x : v.x;
  8228. var x2 = d.x.constructor === Date ? +d.x : d.x;
  8229. if (x1 === x2) {
  8230. i = j;
  8231. }
  8232. });
  8233. }
  8234. if (i in rowValues && rowValues[i].value * d.value >= 0) {
  8235. offset += scale(values[i]) - y0;
  8236. }
  8237. }
  8238. });
  8239. return offset;
  8240. };
  8241. };
  8242. ChartInternal.prototype.isWithinShape = function (that, d) {
  8243. var $$ = this,
  8244. shape = $$.d3.select(that),
  8245. isWithin;
  8246. if (!$$.isTargetToShow(d.id)) {
  8247. isWithin = false;
  8248. } else if (that.nodeName === 'circle') {
  8249. isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);
  8250. } else if (that.nodeName === 'path') {
  8251. isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar($$.d3.mouse(that), that) : true;
  8252. }
  8253. return isWithin;
  8254. };
  8255. ChartInternal.prototype.getInterpolate = function (d) {
  8256. var $$ = this,
  8257. d3 = $$.d3,
  8258. types = {
  8259. 'linear': d3.curveLinear,
  8260. 'linear-closed': d3.curveLinearClosed,
  8261. 'basis': d3.curveBasis,
  8262. 'basis-open': d3.curveBasisOpen,
  8263. 'basis-closed': d3.curveBasisClosed,
  8264. 'bundle': d3.curveBundle,
  8265. 'cardinal': d3.curveCardinal,
  8266. 'cardinal-open': d3.curveCardinalOpen,
  8267. 'cardinal-closed': d3.curveCardinalClosed,
  8268. 'monotone': d3.curveMonotoneX,
  8269. 'step': d3.curveStep,
  8270. 'step-before': d3.curveStepBefore,
  8271. 'step-after': d3.curveStepAfter
  8272. },
  8273. type;
  8274. if ($$.isSplineType(d)) {
  8275. type = types[$$.config.spline_interpolation_type] || types.cardinal;
  8276. } else if ($$.isStepType(d)) {
  8277. type = types[$$.config.line_step_type];
  8278. } else {
  8279. type = types.linear;
  8280. }
  8281. return type;
  8282. };
  8283. ChartInternal.prototype.initLine = function () {
  8284. var $$ = this;
  8285. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines);
  8286. };
  8287. ChartInternal.prototype.updateTargetsForLine = function (targets) {
  8288. var $$ = this,
  8289. config = $$.config,
  8290. mainLines,
  8291. mainLineEnter,
  8292. classChartLine = $$.classChartLine.bind($$),
  8293. classLines = $$.classLines.bind($$),
  8294. classAreas = $$.classAreas.bind($$),
  8295. classCircles = $$.classCircles.bind($$),
  8296. classFocus = $$.classFocus.bind($$);
  8297. mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', function (d) {
  8298. return classChartLine(d) + classFocus(d);
  8299. });
  8300. mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style("pointer-events", "none"); // Lines for each data
  8301. mainLineEnter.append('g').attr("class", classLines); // Areas
  8302. mainLineEnter.append('g').attr('class', classAreas); // Circles for each data point on lines
  8303. mainLineEnter.append('g').attr("class", function (d) {
  8304. return $$.generateClass(CLASS.selectedCircles, d.id);
  8305. });
  8306. mainLineEnter.append('g').attr("class", classCircles).style("cursor", function (d) {
  8307. return config.data_selection_isselectable(d) ? "pointer" : null;
  8308. }); // Update date for selected circles
  8309. targets.forEach(function (t) {
  8310. $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) {
  8311. d.value = t.values[d.index].value;
  8312. });
  8313. }); // MEMO: can not keep same color...
  8314. //mainLineUpdate.exit().remove();
  8315. };
  8316. ChartInternal.prototype.updateLine = function (durationForExit) {
  8317. var $$ = this;
  8318. var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  8319. var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style("stroke", $$.color);
  8320. $$.mainLine = mainLineEnter.merge(mainLine).style("opacity", $$.initialOpacity.bind($$)).style('shape-rendering', function (d) {
  8321. return $$.isStepType(d) ? 'crispEdges' : '';
  8322. }).attr('transform', null);
  8323. mainLine.exit().transition().duration(durationForExit).style('opacity', 0);
  8324. };
  8325. ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) {
  8326. return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr("d", drawLine).style("stroke", this.color).style("opacity", 1)];
  8327. };
  8328. ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) {
  8329. var $$ = this,
  8330. config = $$.config,
  8331. line = $$.d3.line(),
  8332. getPoints = $$.generateGetLinePoints(lineIndices, isSub),
  8333. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  8334. xValue = function xValue(d) {
  8335. return (isSub ? $$.subxx : $$.xx).call($$, d);
  8336. },
  8337. yValue = function yValue(d, i) {
  8338. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value);
  8339. };
  8340. line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue);
  8341. if (!config.line_connectNull) {
  8342. line = line.defined(function (d) {
  8343. return d.value != null;
  8344. });
  8345. }
  8346. return function (d) {
  8347. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  8348. x = isSub ? $$.subX : $$.x,
  8349. y = yScaleGetter.call($$, d.id),
  8350. x0 = 0,
  8351. y0 = 0,
  8352. path;
  8353. if ($$.isLineType(d)) {
  8354. if (config.data_regions[d.id]) {
  8355. path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);
  8356. } else {
  8357. if ($$.isStepType(d)) {
  8358. values = $$.convertValuesToStep(values);
  8359. }
  8360. path = line.curve($$.getInterpolate(d))(values);
  8361. }
  8362. } else {
  8363. if (values[0]) {
  8364. x0 = x(values[0].x);
  8365. y0 = y(values[0].value);
  8366. }
  8367. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  8368. }
  8369. return path ? path : "M 0 0";
  8370. };
  8371. };
  8372. ChartInternal.prototype.generateGetLinePoints = function (lineIndices, isSub) {
  8373. // partial duplication of generateGetBarPoints
  8374. var $$ = this,
  8375. config = $$.config,
  8376. lineTargetsNum = lineIndices.__max__ + 1,
  8377. x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),
  8378. y = $$.getShapeY(!!isSub),
  8379. lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),
  8380. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  8381. return function (d, i) {
  8382. var y0 = yScale.call($$, d.id)(0),
  8383. offset = lineOffset(d, i) || y0,
  8384. // offset is for stacked area chart
  8385. posX = x(d),
  8386. posY = y(d); // fix posY not to overflow opposite quadrant
  8387. if (config.axis_rotated) {
  8388. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  8389. posY = y0;
  8390. }
  8391. } // 1 point that marks the line position
  8392. return [[posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  8393. [posX, posY - (y0 - offset)], // needed for compatibility
  8394. [posX, posY - (y0 - offset)] // needed for compatibility
  8395. ];
  8396. };
  8397. };
  8398. ChartInternal.prototype.lineWithRegions = function (d, x, y, _regions) {
  8399. var $$ = this,
  8400. config = $$.config,
  8401. prev = -1,
  8402. i,
  8403. j,
  8404. s = "M",
  8405. sWithRegion,
  8406. xp,
  8407. yp,
  8408. dx,
  8409. dy,
  8410. dd,
  8411. diff,
  8412. diffx2,
  8413. xOffset = $$.isCategorized() ? 0.5 : 0,
  8414. xValue,
  8415. yValue,
  8416. regions = [];
  8417. function isWithinRegions(x, regions) {
  8418. var i;
  8419. for (i = 0; i < regions.length; i++) {
  8420. if (regions[i].start < x && x <= regions[i].end) {
  8421. return true;
  8422. }
  8423. }
  8424. return false;
  8425. } // Check start/end of regions
  8426. if (isDefined(_regions)) {
  8427. for (i = 0; i < _regions.length; i++) {
  8428. regions[i] = {};
  8429. if (isUndefined(_regions[i].start)) {
  8430. regions[i].start = d[0].x;
  8431. } else {
  8432. regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start;
  8433. }
  8434. if (isUndefined(_regions[i].end)) {
  8435. regions[i].end = d[d.length - 1].x;
  8436. } else {
  8437. regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end;
  8438. }
  8439. }
  8440. } // Set scales
  8441. xValue = config.axis_rotated ? function (d) {
  8442. return y(d.value);
  8443. } : function (d) {
  8444. return x(d.x);
  8445. };
  8446. yValue = config.axis_rotated ? function (d) {
  8447. return x(d.x);
  8448. } : function (d) {
  8449. return y(d.value);
  8450. }; // Define svg generator function for region
  8451. function generateM(points) {
  8452. return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1];
  8453. }
  8454. if ($$.isTimeSeries()) {
  8455. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  8456. var x0 = d0.x.getTime(),
  8457. x_diff = d1.x - d0.x,
  8458. xv0 = new Date(x0 + x_diff * j),
  8459. xv1 = new Date(x0 + x_diff * (j + diff)),
  8460. points;
  8461. if (config.axis_rotated) {
  8462. points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]];
  8463. } else {
  8464. points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]];
  8465. }
  8466. return generateM(points);
  8467. };
  8468. } else {
  8469. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  8470. var points;
  8471. if (config.axis_rotated) {
  8472. points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]];
  8473. } else {
  8474. points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]];
  8475. }
  8476. return generateM(points);
  8477. };
  8478. } // Generate
  8479. for (i = 0; i < d.length; i++) {
  8480. // Draw as normal
  8481. if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {
  8482. s += " " + xValue(d[i]) + " " + yValue(d[i]);
  8483. } // Draw with region // TODO: Fix for horizotal charts
  8484. else {
  8485. xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries());
  8486. yp = $$.getScale(d[i - 1].value, d[i].value);
  8487. dx = x(d[i].x) - x(d[i - 1].x);
  8488. dy = y(d[i].value) - y(d[i - 1].value);
  8489. dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
  8490. diff = 2 / dd;
  8491. diffx2 = diff * 2;
  8492. for (j = diff; j <= 1; j += diffx2) {
  8493. s += sWithRegion(d[i - 1], d[i], j, diff);
  8494. }
  8495. }
  8496. prev = d[i].x;
  8497. }
  8498. return s;
  8499. };
  8500. ChartInternal.prototype.updateArea = function (durationForExit) {
  8501. var $$ = this,
  8502. d3 = $$.d3;
  8503. var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  8504. var mainAreaEnter = mainArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  8505. $$.orgAreaOpacity = +d3.select(this).style('opacity');
  8506. return 0;
  8507. });
  8508. $$.mainArea = mainAreaEnter.merge(mainArea).style("opacity", $$.orgAreaOpacity);
  8509. mainArea.exit().transition().duration(durationForExit).style('opacity', 0);
  8510. };
  8511. ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) {
  8512. return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr("d", drawArea).style("fill", this.color).style("opacity", this.orgAreaOpacity)];
  8513. };
  8514. ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) {
  8515. var $$ = this,
  8516. config = $$.config,
  8517. area = $$.d3.area(),
  8518. getPoints = $$.generateGetAreaPoints(areaIndices, isSub),
  8519. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  8520. xValue = function xValue(d) {
  8521. return (isSub ? $$.subxx : $$.xx).call($$, d);
  8522. },
  8523. value0 = function value0(d, i) {
  8524. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id));
  8525. },
  8526. value1 = function value1(d, i) {
  8527. return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value);
  8528. };
  8529. area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1);
  8530. if (!config.line_connectNull) {
  8531. area = area.defined(function (d) {
  8532. return d.value !== null;
  8533. });
  8534. }
  8535. return function (d) {
  8536. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  8537. x0 = 0,
  8538. y0 = 0,
  8539. path;
  8540. if ($$.isAreaType(d)) {
  8541. if ($$.isStepType(d)) {
  8542. values = $$.convertValuesToStep(values);
  8543. }
  8544. path = area.curve($$.getInterpolate(d))(values);
  8545. } else {
  8546. if (values[0]) {
  8547. x0 = $$.x(values[0].x);
  8548. y0 = $$.getYScale(d.id)(values[0].value);
  8549. }
  8550. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  8551. }
  8552. return path ? path : "M 0 0";
  8553. };
  8554. };
  8555. ChartInternal.prototype.getAreaBaseValue = function () {
  8556. return 0;
  8557. };
  8558. ChartInternal.prototype.generateGetAreaPoints = function (areaIndices, isSub) {
  8559. // partial duplication of generateGetBarPoints
  8560. var $$ = this,
  8561. config = $$.config,
  8562. areaTargetsNum = areaIndices.__max__ + 1,
  8563. x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),
  8564. y = $$.getShapeY(!!isSub),
  8565. areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),
  8566. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  8567. return function (d, i) {
  8568. var y0 = yScale.call($$, d.id)(0),
  8569. offset = areaOffset(d, i) || y0,
  8570. // offset is for stacked area chart
  8571. posX = x(d),
  8572. posY = y(d); // fix posY not to overflow opposite quadrant
  8573. if (config.axis_rotated) {
  8574. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  8575. posY = y0;
  8576. }
  8577. } // 1 point that marks the area position
  8578. return [[posX, offset], [posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  8579. [posX, offset] // needed for compatibility
  8580. ];
  8581. };
  8582. };
  8583. ChartInternal.prototype.updateCircle = function (cx, cy) {
  8584. var $$ = this;
  8585. var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle).data($$.lineOrScatterOrStanfordData.bind($$));
  8586. var mainCircleEnter = mainCircle.enter().append("circle").attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '').attr("class", $$.classCircle.bind($$)).attr("cx", cx).attr("cy", cy).attr("r", $$.pointR.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color);
  8587. $$.mainCircle = mainCircleEnter.merge(mainCircle).style("opacity", $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$));
  8588. mainCircle.exit().style("opacity", 0);
  8589. };
  8590. ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) {
  8591. var $$ = this,
  8592. selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);
  8593. return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color).attr("cx", cx).attr("cy", cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr("cx", cx).attr("cy", cy)];
  8594. };
  8595. ChartInternal.prototype.circleX = function (d) {
  8596. return d.x || d.x === 0 ? this.x(d.x) : null;
  8597. };
  8598. ChartInternal.prototype.updateCircleY = function () {
  8599. var $$ = this,
  8600. lineIndices,
  8601. getPoints;
  8602. if ($$.config.data_groups.length > 0) {
  8603. lineIndices = $$.getShapeIndices($$.isLineType), getPoints = $$.generateGetLinePoints(lineIndices);
  8604. $$.circleY = function (d, i) {
  8605. return getPoints(d, i)[0][1];
  8606. };
  8607. } else {
  8608. $$.circleY = function (d) {
  8609. return $$.getYScale(d.id)(d.value);
  8610. };
  8611. }
  8612. };
  8613. ChartInternal.prototype.getCircles = function (i, id) {
  8614. var $$ = this;
  8615. return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
  8616. };
  8617. ChartInternal.prototype.expandCircles = function (i, id, reset) {
  8618. var $$ = this,
  8619. r = $$.pointExpandedR.bind($$);
  8620. if (reset) {
  8621. $$.unexpandCircles();
  8622. }
  8623. $$.getCircles(i, id).classed(CLASS.EXPANDED, true).attr('r', r);
  8624. };
  8625. ChartInternal.prototype.unexpandCircles = function (i) {
  8626. var $$ = this,
  8627. r = $$.pointR.bind($$);
  8628. $$.getCircles(i).filter(function () {
  8629. return $$.d3.select(this).classed(CLASS.EXPANDED);
  8630. }).classed(CLASS.EXPANDED, false).attr('r', r);
  8631. };
  8632. ChartInternal.prototype.pointR = function (d) {
  8633. var $$ = this,
  8634. config = $$.config;
  8635. return $$.isStepType(d) ? 0 : isFunction(config.point_r) ? config.point_r(d) : config.point_r;
  8636. };
  8637. ChartInternal.prototype.pointExpandedR = function (d) {
  8638. var $$ = this,
  8639. config = $$.config;
  8640. if (config.point_focus_expand_enabled) {
  8641. return isFunction(config.point_focus_expand_r) ? config.point_focus_expand_r(d) : config.point_focus_expand_r ? config.point_focus_expand_r : $$.pointR(d) * 1.75;
  8642. } else {
  8643. return $$.pointR(d);
  8644. }
  8645. };
  8646. ChartInternal.prototype.pointSelectR = function (d) {
  8647. var $$ = this,
  8648. config = $$.config;
  8649. return isFunction(config.point_select_r) ? config.point_select_r(d) : config.point_select_r ? config.point_select_r : $$.pointR(d) * 4;
  8650. };
  8651. ChartInternal.prototype.isWithinCircle = function (that, r) {
  8652. var d3 = this.d3,
  8653. mouse = d3.mouse(that),
  8654. d3_this = d3.select(that),
  8655. cx = +d3_this.attr("cx"),
  8656. cy = +d3_this.attr("cy");
  8657. return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r;
  8658. };
  8659. ChartInternal.prototype.isWithinStep = function (that, y) {
  8660. return Math.abs(y - this.d3.mouse(that)[1]) < 30;
  8661. };
  8662. ChartInternal.prototype.getCurrentWidth = function () {
  8663. var $$ = this,
  8664. config = $$.config;
  8665. return config.size_width ? config.size_width : $$.getParentWidth();
  8666. };
  8667. ChartInternal.prototype.getCurrentHeight = function () {
  8668. var $$ = this,
  8669. config = $$.config,
  8670. h = config.size_height ? config.size_height : $$.getParentHeight();
  8671. return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);
  8672. };
  8673. ChartInternal.prototype.getCurrentPaddingTop = function () {
  8674. var $$ = this,
  8675. config = $$.config,
  8676. padding = isValue(config.padding_top) ? config.padding_top : 0;
  8677. if ($$.title && $$.title.node()) {
  8678. padding += $$.getTitlePadding();
  8679. }
  8680. return padding;
  8681. };
  8682. ChartInternal.prototype.getCurrentPaddingBottom = function () {
  8683. var config = this.config;
  8684. return isValue(config.padding_bottom) ? config.padding_bottom : 0;
  8685. };
  8686. ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) {
  8687. var $$ = this,
  8688. config = $$.config;
  8689. if (isValue(config.padding_left)) {
  8690. return config.padding_left;
  8691. } else if (config.axis_rotated) {
  8692. return !config.axis_x_show || config.axis_x_inner ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);
  8693. } else if (!config.axis_y_show || config.axis_y_inner) {
  8694. // && !config.axis_rotated
  8695. return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1;
  8696. } else {
  8697. return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));
  8698. }
  8699. };
  8700. ChartInternal.prototype.getCurrentPaddingRight = function () {
  8701. var $$ = this,
  8702. config = $$.config,
  8703. padding = 0,
  8704. defaultPadding = 10,
  8705. legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;
  8706. if (isValue(config.padding_right)) {
  8707. padding = config.padding_right + 1; // 1 is needed not to hide tick line
  8708. } else if (config.axis_rotated) {
  8709. padding = defaultPadding + legendWidthOnRight;
  8710. } else if (!config.axis_y2_show || config.axis_y2_inner) {
  8711. // && !config.axis_rotated
  8712. padding = 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);
  8713. } else {
  8714. padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;
  8715. }
  8716. if ($$.colorScale && $$.colorScale.node()) {
  8717. padding += $$.getColorScalePadding();
  8718. }
  8719. return padding;
  8720. };
  8721. ChartInternal.prototype.getParentRectValue = function (key) {
  8722. var parent = this.selectChart.node(),
  8723. v;
  8724. while (parent && parent.tagName !== 'BODY') {
  8725. try {
  8726. v = parent.getBoundingClientRect()[key];
  8727. } catch (e) {
  8728. if (key === 'width') {
  8729. // In IE in certain cases getBoundingClientRect
  8730. // will cause an "unspecified error"
  8731. v = parent.offsetWidth;
  8732. }
  8733. }
  8734. if (v) {
  8735. break;
  8736. }
  8737. parent = parent.parentNode;
  8738. }
  8739. return v;
  8740. };
  8741. ChartInternal.prototype.getParentWidth = function () {
  8742. return this.getParentRectValue('width');
  8743. };
  8744. ChartInternal.prototype.getParentHeight = function () {
  8745. var h = this.selectChart.style('height');
  8746. return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;
  8747. };
  8748. ChartInternal.prototype.getSvgLeft = function (withoutRecompute) {
  8749. var $$ = this,
  8750. config = $$.config,
  8751. hasLeftAxisRect = config.axis_rotated || !config.axis_rotated && !config.axis_y_inner,
  8752. leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,
  8753. leftAxis = $$.main.select('.' + leftAxisClass).node(),
  8754. svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : {
  8755. right: 0
  8756. },
  8757. chartRect = $$.selectChart.node().getBoundingClientRect(),
  8758. hasArc = $$.hasArcType(),
  8759. svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));
  8760. return svgLeft > 0 ? svgLeft : 0;
  8761. };
  8762. ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) {
  8763. var $$ = this,
  8764. position = $$.axis.getLabelPositionById(id);
  8765. return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40);
  8766. };
  8767. ChartInternal.prototype.getHorizontalAxisHeight = function (axisId) {
  8768. var $$ = this,
  8769. config = $$.config,
  8770. h = 30;
  8771. if (axisId === 'x' && !config.axis_x_show) {
  8772. return 8;
  8773. }
  8774. if (axisId === 'x' && config.axis_x_height) {
  8775. return config.axis_x_height;
  8776. }
  8777. if (axisId === 'y' && !config.axis_y_show) {
  8778. return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;
  8779. }
  8780. if (axisId === 'y2' && !config.axis_y2_show) {
  8781. return $$.rotated_padding_top;
  8782. } // Calculate x axis height when tick rotated
  8783. if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
  8784. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_x_tick_rotate)) / 180);
  8785. } // Calculate y axis height when tick rotated
  8786. if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {
  8787. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_y_tick_rotate)) / 180);
  8788. }
  8789. return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0);
  8790. };
  8791. ChartInternal.prototype.initBrush = function (scale) {
  8792. var $$ = this,
  8793. d3 = $$.d3; // TODO: dynamically change brushY/brushX according to axis_rotated.
  8794. $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () {
  8795. var event = d3.event.sourceEvent;
  8796. if (event && event.type === "zoom") {
  8797. return;
  8798. }
  8799. $$.redrawForBrush();
  8800. }).on("end", function () {
  8801. var event = d3.event.sourceEvent;
  8802. if (event && event.type === "zoom") {
  8803. return;
  8804. }
  8805. if ($$.brush.empty() && event && event.type !== 'end') {
  8806. $$.brush.clear();
  8807. }
  8808. });
  8809. $$.brush.updateExtent = function () {
  8810. var range = this.scale.range(),
  8811. extent;
  8812. if ($$.config.axis_rotated) {
  8813. extent = [[0, range[0]], [$$.width2, range[1]]];
  8814. } else {
  8815. extent = [[range[0], 0], [range[1], $$.height2]];
  8816. }
  8817. this.extent(extent);
  8818. return this;
  8819. };
  8820. $$.brush.updateScale = function (scale) {
  8821. this.scale = scale;
  8822. return this;
  8823. };
  8824. $$.brush.update = function (scale) {
  8825. this.updateScale(scale || $$.subX).updateExtent();
  8826. $$.context.select('.' + CLASS.brush).call(this);
  8827. };
  8828. $$.brush.clear = function () {
  8829. $$.context.select('.' + CLASS.brush).call($$.brush.move, null);
  8830. };
  8831. $$.brush.selection = function () {
  8832. return d3.brushSelection($$.context.select('.' + CLASS.brush).node());
  8833. };
  8834. $$.brush.selectionAsValue = function (selectionAsValue, withTransition) {
  8835. var selection, brush;
  8836. if (selectionAsValue) {
  8837. if ($$.context) {
  8838. selection = [this.scale(selectionAsValue[0]), this.scale(selectionAsValue[1])];
  8839. brush = $$.context.select('.' + CLASS.brush);
  8840. if (withTransition) {
  8841. brush = brush.transition();
  8842. }
  8843. $$.brush.move(brush, selection);
  8844. }
  8845. return [];
  8846. }
  8847. selection = $$.brush.selection() || [0, 0];
  8848. return [this.scale.invert(selection[0]), this.scale.invert(selection[1])];
  8849. };
  8850. $$.brush.empty = function () {
  8851. var selection = $$.brush.selection();
  8852. return !selection || selection[0] === selection[1];
  8853. };
  8854. return $$.brush.updateScale(scale);
  8855. };
  8856. ChartInternal.prototype.initSubchart = function () {
  8857. var $$ = this,
  8858. config = $$.config,
  8859. context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')); // set style
  8860. context.style('visibility', 'visible'); // Define g for chart area
  8861. context.append('g').attr("clip-path", $$.clipPathForSubchart).attr('class', CLASS.chart); // Define g for bar chart area
  8862. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); // Define g for line chart area
  8863. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); // Add extent rect for Brush
  8864. context.append("g").attr("clip-path", $$.clipPath).attr("class", CLASS.brush); // ATTENTION: This must be called AFTER chart added
  8865. // Add Axis
  8866. $$.axes.subx = context.append("g").attr("class", CLASS.axisX).attr("transform", $$.getTranslate('subx')).attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis);
  8867. };
  8868. ChartInternal.prototype.initSubchartBrush = function () {
  8869. var $$ = this; // Add extent rect for Brush
  8870. $$.initBrush($$.subX).updateExtent();
  8871. $$.context.select('.' + CLASS.brush).call($$.brush);
  8872. };
  8873. ChartInternal.prototype.updateTargetsForSubchart = function (targets) {
  8874. var $$ = this,
  8875. context = $$.context,
  8876. config = $$.config,
  8877. contextLineEnter,
  8878. contextLine,
  8879. contextBarEnter,
  8880. contextBar,
  8881. classChartBar = $$.classChartBar.bind($$),
  8882. classBars = $$.classBars.bind($$),
  8883. classChartLine = $$.classChartLine.bind($$),
  8884. classLines = $$.classLines.bind($$),
  8885. classAreas = $$.classAreas.bind($$); //-- Bar --//
  8886. contextBar = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets);
  8887. contextBarEnter = contextBar.enter().append('g').style('opacity', 0);
  8888. contextBarEnter.merge(contextBar).attr('class', classChartBar); // Bars for each data
  8889. contextBarEnter.append('g').attr("class", classBars); //-- Line --//
  8890. contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets);
  8891. contextLineEnter = contextLine.enter().append('g').style('opacity', 0);
  8892. contextLineEnter.merge(contextLine).attr('class', classChartLine); // Lines for each data
  8893. contextLineEnter.append("g").attr("class", classLines); // Area
  8894. contextLineEnter.append("g").attr("class", classAreas); //-- Brush --//
  8895. context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2);
  8896. };
  8897. ChartInternal.prototype.updateBarForSubchart = function (durationForExit) {
  8898. var $$ = this;
  8899. var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data($$.barData.bind($$));
  8900. var contextBarEnter = contextBar.enter().append('path').attr("class", $$.classBar.bind($$)).style("stroke", 'none').style("fill", $$.color);
  8901. contextBar.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  8902. $$.contextBar = contextBarEnter.merge(contextBar).style("opacity", $$.initialOpacity.bind($$));
  8903. };
  8904. ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) {
  8905. (withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar).attr('d', drawBarOnSub).style('opacity', 1);
  8906. };
  8907. ChartInternal.prototype.updateLineForSubchart = function (durationForExit) {
  8908. var $$ = this;
  8909. var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  8910. var contextLineEnter = contextLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color);
  8911. contextLine.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  8912. $$.contextLine = contextLineEnter.merge(contextLine).style("opacity", $$.initialOpacity.bind($$));
  8913. };
  8914. ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) {
  8915. (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr("d", drawLineOnSub).style('opacity', 1);
  8916. };
  8917. ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) {
  8918. var $$ = this,
  8919. d3 = $$.d3;
  8920. var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  8921. var contextAreaEnter = contextArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  8922. $$.orgAreaOpacity = +d3.select(this).style('opacity');
  8923. return 0;
  8924. });
  8925. contextArea.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  8926. $$.contextArea = contextAreaEnter.merge(contextArea).style("opacity", 0);
  8927. };
  8928. ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) {
  8929. (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr("d", drawAreaOnSub).style("fill", this.color).style("opacity", this.orgAreaOpacity);
  8930. };
  8931. ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) {
  8932. var $$ = this,
  8933. d3 = $$.d3,
  8934. drawAreaOnSub,
  8935. drawBarOnSub,
  8936. drawLineOnSub; // reflect main chart to extent on subchart if zoomed
  8937. if (d3.event && d3.event.type === 'zoom') {
  8938. $$.brush.selectionAsValue($$.x.orgDomain());
  8939. } // update subchart elements if needed
  8940. if (withSubchart) {
  8941. // extent rect
  8942. if (!$$.brush.empty()) {
  8943. $$.brush.selectionAsValue($$.x.orgDomain());
  8944. } // setup drawer - MEMO: this must be called after axis updated
  8945. drawAreaOnSub = $$.generateDrawArea(areaIndices, true);
  8946. drawBarOnSub = $$.generateDrawBar(barIndices, true);
  8947. drawLineOnSub = $$.generateDrawLine(lineIndices, true);
  8948. $$.updateBarForSubchart(duration);
  8949. $$.updateLineForSubchart(duration);
  8950. $$.updateAreaForSubchart(duration);
  8951. $$.redrawBarForSubchart(drawBarOnSub, duration, duration);
  8952. $$.redrawLineForSubchart(drawLineOnSub, duration, duration);
  8953. $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);
  8954. }
  8955. };
  8956. ChartInternal.prototype.redrawForBrush = function () {
  8957. var $$ = this,
  8958. x = $$.x,
  8959. d3 = $$.d3,
  8960. s;
  8961. $$.redraw({
  8962. withTransition: false,
  8963. withY: $$.config.zoom_rescale,
  8964. withSubchart: false,
  8965. withUpdateXDomain: true,
  8966. withEventRect: false,
  8967. withDimension: false
  8968. }); // update zoom transation binded to event rect
  8969. s = d3.event.selection || $$.brush.scale.range();
  8970. $$.main.select('.' + CLASS.eventRect).call($$.zoom.transform, d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0));
  8971. $$.config.subchart_onbrush.call($$.api, x.orgDomain());
  8972. };
  8973. ChartInternal.prototype.transformContext = function (withTransition, transitions) {
  8974. var $$ = this,
  8975. subXAxis;
  8976. if (transitions && transitions.axisSubX) {
  8977. subXAxis = transitions.axisSubX;
  8978. } else {
  8979. subXAxis = $$.context.select('.' + CLASS.axisX);
  8980. if (withTransition) {
  8981. subXAxis = subXAxis.transition();
  8982. }
  8983. }
  8984. $$.context.attr("transform", $$.getTranslate('context'));
  8985. subXAxis.attr("transform", $$.getTranslate('subx'));
  8986. };
  8987. ChartInternal.prototype.getDefaultSelection = function () {
  8988. var $$ = this,
  8989. config = $$.config,
  8990. selection = isFunction(config.axis_x_selection) ? config.axis_x_selection($$.getXDomain($$.data.targets)) : config.axis_x_selection;
  8991. if ($$.isTimeSeries()) {
  8992. selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])];
  8993. }
  8994. return selection;
  8995. };
  8996. ChartInternal.prototype.removeSubchart = function () {
  8997. var $$ = this;
  8998. $$.brush = null;
  8999. $$.context.remove();
  9000. $$.context = null;
  9001. };
  9002. ChartInternal.prototype.initText = function () {
  9003. var $$ = this;
  9004. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartTexts);
  9005. $$.mainText = $$.d3.selectAll([]);
  9006. };
  9007. ChartInternal.prototype.updateTargetsForText = function (targets) {
  9008. var $$ = this,
  9009. classChartText = $$.classChartText.bind($$),
  9010. classTexts = $$.classTexts.bind($$),
  9011. classFocus = $$.classFocus.bind($$);
  9012. var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText).data(targets);
  9013. var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style("pointer-events", "none");
  9014. mainTextEnter.append('g').attr('class', classTexts);
  9015. mainTextEnter.merge(mainText).attr('class', function (d) {
  9016. return classChartText(d) + classFocus(d);
  9017. });
  9018. };
  9019. ChartInternal.prototype.updateText = function (xForText, yForText, durationForExit) {
  9020. var $$ = this,
  9021. config = $$.config,
  9022. barOrLineData = $$.barOrLineData.bind($$),
  9023. classText = $$.classText.bind($$);
  9024. var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text).data(barOrLineData);
  9025. var mainTextEnter = mainText.enter().append('text').attr("class", classText).attr('text-anchor', function (d) {
  9026. return config.axis_rotated ? d.value < 0 ? 'end' : 'start' : 'middle';
  9027. }).style("stroke", 'none').attr('x', xForText).attr('y', yForText).style("fill", function (d) {
  9028. return $$.color(d);
  9029. }).style("fill-opacity", 0);
  9030. $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) {
  9031. return $$.dataLabelFormat(d.id)(d.value, d.id, i, j);
  9032. });
  9033. mainText.exit().transition().duration(durationForExit).style('fill-opacity', 0).remove();
  9034. };
  9035. ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) {
  9036. return [(withTransition ? this.mainText.transition(transition) : this.mainText).attr('x', xForText).attr('y', yForText).style("fill", this.color).style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this))];
  9037. };
  9038. ChartInternal.prototype.getTextRect = function (text, cls, element) {
  9039. var dummy = this.d3.select('body').append('div').classed('c3', true),
  9040. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0),
  9041. font = this.d3.select(element).style('font'),
  9042. rect;
  9043. svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : "", true).style('font', font).text(text).each(function () {
  9044. rect = getBBox(this);
  9045. });
  9046. dummy.remove();
  9047. return rect;
  9048. };
  9049. ChartInternal.prototype.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {
  9050. var $$ = this,
  9051. getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),
  9052. getBarPoints = $$.generateGetBarPoints(barIndices, false),
  9053. getLinePoints = $$.generateGetLinePoints(lineIndices, false),
  9054. getter = forX ? $$.getXForText : $$.getYForText;
  9055. return function (d, i) {
  9056. var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints;
  9057. return getter.call($$, getPoints(d, i), d, this);
  9058. };
  9059. };
  9060. ChartInternal.prototype.getXForText = function (points, d, textElement) {
  9061. var $$ = this,
  9062. box = getBBox(textElement),
  9063. xPos,
  9064. padding;
  9065. if ($$.config.axis_rotated) {
  9066. padding = $$.isBarType(d) ? 4 : 6;
  9067. xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);
  9068. } else {
  9069. xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];
  9070. } // show labels regardless of the domain if value is null
  9071. if (d.value === null) {
  9072. if (xPos > $$.width) {
  9073. xPos = $$.width - box.width;
  9074. } else if (xPos < 0) {
  9075. xPos = 4;
  9076. }
  9077. }
  9078. return xPos;
  9079. };
  9080. ChartInternal.prototype.getYForText = function (points, d, textElement) {
  9081. var $$ = this,
  9082. box = getBBox(textElement),
  9083. yPos;
  9084. if ($$.config.axis_rotated) {
  9085. yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;
  9086. } else {
  9087. yPos = points[2][1];
  9088. if (d.value < 0 || d.value === 0 && !$$.hasPositiveValue) {
  9089. yPos += box.height;
  9090. if ($$.isBarType(d) && $$.isSafari()) {
  9091. yPos -= 3;
  9092. } else if (!$$.isBarType(d) && $$.isChrome()) {
  9093. yPos += 3;
  9094. }
  9095. } else {
  9096. yPos += $$.isBarType(d) ? -3 : -6;
  9097. }
  9098. } // show labels regardless of the domain if value is null
  9099. if (d.value === null && !$$.config.axis_rotated) {
  9100. if (yPos < box.height) {
  9101. yPos = box.height;
  9102. } else if (yPos > this.height) {
  9103. yPos = this.height - 4;
  9104. }
  9105. }
  9106. return yPos;
  9107. };
  9108. ChartInternal.prototype.initTitle = function () {
  9109. var $$ = this;
  9110. $$.title = $$.svg.append("text").text($$.config.title_text).attr("class", $$.CLASS.title);
  9111. };
  9112. ChartInternal.prototype.redrawTitle = function () {
  9113. var $$ = this;
  9114. $$.title.attr("x", $$.xForTitle.bind($$)).attr("y", $$.yForTitle.bind($$));
  9115. };
  9116. ChartInternal.prototype.xForTitle = function () {
  9117. var $$ = this,
  9118. config = $$.config,
  9119. position = config.title_position || 'left',
  9120. x;
  9121. if (position.indexOf('right') >= 0) {
  9122. x = $$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width - config.title_padding.right;
  9123. } else if (position.indexOf('center') >= 0) {
  9124. x = Math.max(($$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) / 2, 0);
  9125. } else {
  9126. // left
  9127. x = config.title_padding.left;
  9128. }
  9129. return x;
  9130. };
  9131. ChartInternal.prototype.yForTitle = function () {
  9132. var $$ = this;
  9133. return $$.config.title_padding.top + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).height;
  9134. };
  9135. ChartInternal.prototype.getTitlePadding = function () {
  9136. var $$ = this;
  9137. return $$.yForTitle() + $$.config.title_padding.bottom;
  9138. };
  9139. function powerOfTen(d) {
  9140. return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1;
  9141. }
  9142. ChartInternal.prototype.drawColorScale = function () {
  9143. var $$ = this,
  9144. d3 = $$.d3,
  9145. config = $$.config,
  9146. target = $$.data.targets[0],
  9147. barWidth,
  9148. barHeight,
  9149. axis,
  9150. points,
  9151. legendAxis,
  9152. axisScale,
  9153. inverseScale,
  9154. height;
  9155. barWidth = !isNaN(config.stanford_scaleWidth) ? config.stanford_scaleWidth : 20;
  9156. barHeight = 5;
  9157. if (barHeight < 0 || barWidth < 0) {
  9158. throw Error("Colorscale's barheight and barwidth must be greater than 0.");
  9159. }
  9160. height = $$.height - config.stanford_padding.bottom - config.stanford_padding.top;
  9161. points = d3.range(config.stanford_padding.bottom, height, barHeight);
  9162. inverseScale = d3.scaleSequential(target.colors).domain([points[points.length - 1], points[0]]);
  9163. if ($$.colorScale) {
  9164. $$.colorScale.remove();
  9165. }
  9166. $$.colorScale = $$.svg.append("g").attr('width', 50).attr('height', height).attr('class', CLASS.colorScale);
  9167. $$.colorScale.append('g').attr('transform', "translate(0, ".concat(config.stanford_padding.top, ")")).selectAll('bars').data(points).enter().append('rect').attr('y', function (d, i) {
  9168. return i * barHeight;
  9169. }).attr('x', 0).attr('width', barWidth).attr('height', barHeight).attr('fill', function (d) {
  9170. return inverseScale(d);
  9171. }); // Legend Axis
  9172. axisScale = d3.scaleLog().domain([target.minEpochs, target.maxEpochs]).range([points[0] + config.stanford_padding.top + points[points.length - 1] + barHeight - 1, points[0] + config.stanford_padding.top]);
  9173. legendAxis = d3.axisRight(axisScale);
  9174. if (config.stanford_scaleFormat === 'pow10') {
  9175. legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]);
  9176. } else if (isFunction(config.stanford_scaleFormat)) {
  9177. legendAxis.tickFormat(config.stanford_scaleFormat);
  9178. } else {
  9179. legendAxis.tickFormat(d3.format("d"));
  9180. }
  9181. if (isFunction(config.stanford_scaleValues)) {
  9182. legendAxis.tickValues(config.stanford_scaleValues(target.minEpochs, target.maxEpochs));
  9183. } // Draw Axis
  9184. axis = $$.colorScale.append("g").attr("class", "legend axis").attr("transform", "translate(".concat(barWidth, ",0)")).call(legendAxis);
  9185. if (config.stanford_scaleFormat === 'pow10') {
  9186. axis.selectAll(".tick text").text(null).filter(powerOfTen).text(10).append("tspan").attr("dy", "-.7em") // https://bl.ocks.org/mbostock/6738229
  9187. .text(function (d) {
  9188. return Math.round(Math.log(d) / Math.LN10);
  9189. });
  9190. }
  9191. $$.colorScale.attr('transform', "translate(".concat($$.currentWidth - $$.xForColorScale(), ", 0)"));
  9192. };
  9193. ChartInternal.prototype.xForColorScale = function () {
  9194. var $$ = this;
  9195. return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width;
  9196. };
  9197. ChartInternal.prototype.getColorScalePadding = function () {
  9198. var $$ = this;
  9199. return $$.xForColorScale() + $$.config.stanford_padding.left + 20;
  9200. };
  9201. ChartInternal.prototype.isStanfordGraphType = function () {
  9202. var $$ = this;
  9203. return $$.config.data_type === 'stanford';
  9204. };
  9205. ChartInternal.prototype.initStanfordData = function () {
  9206. var $$ = this,
  9207. d3 = $$.d3,
  9208. config = $$.config,
  9209. target = $$.data.targets[0],
  9210. epochs,
  9211. maxEpochs,
  9212. minEpochs; // Make larger values appear on top
  9213. target.values.sort(compareEpochs); // Get array of epochs
  9214. epochs = target.values.map(function (a) {
  9215. return a.epochs;
  9216. });
  9217. minEpochs = !isNaN(config.stanford_scaleMin) ? config.stanford_scaleMin : d3.min(epochs);
  9218. maxEpochs = !isNaN(config.stanford_scaleMax) ? config.stanford_scaleMax : d3.max(epochs);
  9219. if (minEpochs > maxEpochs) {
  9220. throw Error("Number of minEpochs has to be smaller than maxEpochs");
  9221. }
  9222. target.colors = isFunction(config.stanford_colors) ? config.stanford_colors : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5));
  9223. target.colorscale = d3.scaleSequentialLog(target.colors).domain([minEpochs, maxEpochs]);
  9224. target.minEpochs = minEpochs;
  9225. target.maxEpochs = maxEpochs;
  9226. };
  9227. ChartInternal.prototype.getStanfordPointColor = function (d) {
  9228. var $$ = this,
  9229. target = $$.data.targets[0];
  9230. return target.colorscale(d.epochs);
  9231. }; // http://jsfiddle.net/Xotic750/KtzLq/
  9232. ChartInternal.prototype.getCentroid = function (points) {
  9233. var area = getRegionArea(points);
  9234. var x = 0,
  9235. y = 0,
  9236. i,
  9237. j,
  9238. f,
  9239. point1,
  9240. point2;
  9241. for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
  9242. point1 = points[i];
  9243. point2 = points[j];
  9244. f = point1.x * point2.y - point2.x * point1.y;
  9245. x += (point1.x + point2.x) * f;
  9246. y += (point1.y + point2.y) * f;
  9247. }
  9248. f = area * 6;
  9249. return {
  9250. x: x / f,
  9251. y: y / f
  9252. };
  9253. };
  9254. ChartInternal.prototype.getStanfordTooltipTitle = function (d) {
  9255. var $$ = this,
  9256. labelX = $$.axis.getLabelText('x'),
  9257. labelY = $$.axis.getLabelText('y');
  9258. return "\n <tr><th>".concat(labelX ? sanitise(labelX) : "x", "</th><th class='value'>").concat(d.x, "</th></tr>\n <tr><th>").concat(labelY ? sanitise(labelY) : "y", "</th><th class='value'>").concat(d.value, "</th></tr>\n ");
  9259. };
  9260. ChartInternal.prototype.countEpochsInRegion = function (region) {
  9261. var $$ = this,
  9262. target = $$.data.targets[0],
  9263. total,
  9264. count;
  9265. total = target.values.reduce(function (accumulator, currentValue) {
  9266. return accumulator + Number(currentValue.epochs);
  9267. }, 0);
  9268. count = target.values.reduce(function (accumulator, currentValue) {
  9269. if (pointInRegion(currentValue, region)) {
  9270. return accumulator + Number(currentValue.epochs);
  9271. }
  9272. return accumulator;
  9273. }, 0);
  9274. return {
  9275. value: count,
  9276. percentage: count !== 0 ? (count / total * 100).toFixed(1) : 0
  9277. };
  9278. };
  9279. var getRegionArea = function getRegionArea(points) {
  9280. // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript
  9281. var area = 0,
  9282. i,
  9283. j,
  9284. point1,
  9285. point2;
  9286. for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
  9287. point1 = points[i];
  9288. point2 = points[j];
  9289. area += point1.x * point2.y;
  9290. area -= point1.y * point2.x;
  9291. }
  9292. area /= 2;
  9293. return area;
  9294. };
  9295. var pointInRegion = function pointInRegion(point, region) {
  9296. // thanks to: http://bl.ocks.org/bycoffe/5575904
  9297. // ray-casting algorithm based on
  9298. // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
  9299. var xi,
  9300. yi,
  9301. yj,
  9302. xj,
  9303. intersect,
  9304. x = point.x,
  9305. y = point.value,
  9306. inside = false;
  9307. for (var i = 0, j = region.length - 1; i < region.length; j = i++) {
  9308. xi = region[i].x;
  9309. yi = region[i].y;
  9310. xj = region[j].x;
  9311. yj = region[j].y;
  9312. intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
  9313. if (intersect) {
  9314. inside = !inside;
  9315. }
  9316. }
  9317. return inside;
  9318. };
  9319. var compareEpochs = function compareEpochs(a, b) {
  9320. if (a.epochs < b.epochs) {
  9321. return -1;
  9322. }
  9323. if (a.epochs > b.epochs) {
  9324. return 1;
  9325. }
  9326. return 0;
  9327. };
  9328. ChartInternal.prototype.initStanfordElements = function () {
  9329. var $$ = this; // Avoid blocking eventRect
  9330. $$.stanfordElements = $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.stanfordElements);
  9331. $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines);
  9332. $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts);
  9333. $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions);
  9334. };
  9335. ChartInternal.prototype.updateStanfordElements = function (duration) {
  9336. var $$ = this,
  9337. main = $$.main,
  9338. config = $$.config,
  9339. stanfordLine,
  9340. stanfordLineEnter,
  9341. stanfordRegion,
  9342. stanfordRegionEnter,
  9343. stanfordText,
  9344. stanfordTextEnter,
  9345. xvCustom = $$.xvCustom.bind($$),
  9346. yvCustom = $$.yvCustom.bind($$),
  9347. countPointsInRegion = $$.countEpochsInRegion.bind($$); // Stanford-Lines
  9348. stanfordLine = main.select('.' + CLASS.stanfordLines).style('shape-rendering', 'geometricprecision').selectAll('.' + CLASS.stanfordLine).data(config.stanford_lines); // enter
  9349. stanfordLineEnter = stanfordLine.enter().append('g').attr("class", function (d) {
  9350. return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '');
  9351. });
  9352. stanfordLineEnter.append('line').attr("x1", function (d) {
  9353. return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');
  9354. }).attr("x2", function (d) {
  9355. return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');
  9356. }).attr("y1", function (d) {
  9357. return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');
  9358. }).attr("y2", function (d) {
  9359. return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');
  9360. }).style("opacity", 0); // update
  9361. $$.stanfordLines = stanfordLineEnter.merge(stanfordLine);
  9362. $$.stanfordLines.select('line').transition().duration(duration).attr("x1", function (d) {
  9363. return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');
  9364. }).attr("x2", function (d) {
  9365. return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');
  9366. }).attr("y1", function (d) {
  9367. return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');
  9368. }).attr("y2", function (d) {
  9369. return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');
  9370. }).style("opacity", 1); // exit
  9371. stanfordLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Text
  9372. stanfordText = main.select('.' + CLASS.stanfordTexts).selectAll('.' + CLASS.stanfordText).data(config.stanford_texts); // enter
  9373. stanfordTextEnter = stanfordText.enter().append('g').attr("class", function (d) {
  9374. return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '');
  9375. });
  9376. stanfordTextEnter.append('text').attr("x", function (d) {
  9377. return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x');
  9378. }).attr("y", function (d) {
  9379. return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y');
  9380. }).style("opacity", 0); // update
  9381. $$.stanfordTexts = stanfordTextEnter.merge(stanfordText);
  9382. $$.stanfordTexts.select('text').transition().duration(duration).attr("x", function (d) {
  9383. return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x');
  9384. }).attr("y", function (d) {
  9385. return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y');
  9386. }).text(function (d) {
  9387. return d.content;
  9388. }).style("opacity", 1); // exit
  9389. stanfordText.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Regions
  9390. stanfordRegion = main.select('.' + CLASS.stanfordRegions).selectAll('.' + CLASS.stanfordRegion).data(config.stanford_regions); // enter
  9391. stanfordRegionEnter = stanfordRegion.enter().append('g').attr("class", function (d) {
  9392. return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '');
  9393. });
  9394. stanfordRegionEnter.append('polygon').attr("points", function (d) {
  9395. return d.points.map(function (value) {
  9396. return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(",");
  9397. }).join(" ");
  9398. }).style("opacity", 0);
  9399. stanfordRegionEnter.append('text').attr("x", function (d) {
  9400. return $$.getCentroid(d.points).x;
  9401. }).attr("y", function (d) {
  9402. return $$.getCentroid(d.points).y;
  9403. }).style("opacity", 0); // update
  9404. $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion);
  9405. $$.stanfordRegions.select('polygon').transition().duration(duration).attr("points", function (d) {
  9406. return d.points.map(function (value) {
  9407. return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(",");
  9408. }).join(" ");
  9409. }).style("opacity", function (d) {
  9410. return d.opacity ? d.opacity : 0.2;
  9411. });
  9412. $$.stanfordRegions.select('text').transition().duration(duration).attr("x", function (d) {
  9413. return config.axis_rotated ? yvCustom($$.getCentroid(d.points), 'y') : xvCustom($$.getCentroid(d.points), 'x');
  9414. }).attr("y", function (d) {
  9415. return config.axis_rotated ? xvCustom($$.getCentroid(d.points), 'x') : yvCustom($$.getCentroid(d.points), 'y');
  9416. }).text(function (d) {
  9417. if (d.text) {
  9418. var value, percentage, temp;
  9419. if ($$.isStanfordGraphType()) {
  9420. temp = countPointsInRegion(d.points);
  9421. value = temp.value;
  9422. percentage = temp.percentage;
  9423. }
  9424. return d.text(value, percentage);
  9425. }
  9426. return "";
  9427. }).attr("text-anchor", "middle").attr("dominant-baseline", "middle").style("opacity", 1); // exit
  9428. stanfordRegion.exit().transition().duration(duration).style("opacity", 0).remove();
  9429. };
  9430. ChartInternal.prototype.initTooltip = function () {
  9431. var $$ = this,
  9432. config = $$.config,
  9433. i;
  9434. $$.tooltip = $$.selectChart.style("position", "relative").append("div").attr('class', CLASS.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none"); // Show tooltip if needed
  9435. if (config.tooltip_init_show) {
  9436. if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {
  9437. config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);
  9438. for (i = 0; i < $$.data.targets[0].values.length; i++) {
  9439. if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {
  9440. break;
  9441. }
  9442. }
  9443. config.tooltip_init_x = i;
  9444. }
  9445. $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {
  9446. return $$.addName(d.values[config.tooltip_init_x]);
  9447. }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));
  9448. $$.tooltip.style("top", config.tooltip_init_position.top).style("left", config.tooltip_init_position.left).style("display", "block");
  9449. }
  9450. };
  9451. ChartInternal.prototype.getTooltipSortFunction = function () {
  9452. var $$ = this,
  9453. config = $$.config;
  9454. if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {
  9455. // if data are not grouped or if an order is specified
  9456. // for the tooltip values we sort them by their values
  9457. var order = config.tooltip_order;
  9458. if (order === undefined) {
  9459. order = config.data_order;
  9460. }
  9461. var valueOf = function valueOf(obj) {
  9462. return obj ? obj.value : null;
  9463. }; // if data are not grouped, we sort them by their value
  9464. if (isString(order) && order.toLowerCase() === 'asc') {
  9465. return function (a, b) {
  9466. return valueOf(a) - valueOf(b);
  9467. };
  9468. } else if (isString(order) && order.toLowerCase() === 'desc') {
  9469. return function (a, b) {
  9470. return valueOf(b) - valueOf(a);
  9471. };
  9472. } else if (isFunction(order)) {
  9473. // if the function is from data_order we need
  9474. // to wrap the returned function in order to format
  9475. // the sorted value to the expected format
  9476. var sortFunction = order;
  9477. if (config.tooltip_order === undefined) {
  9478. sortFunction = function sortFunction(a, b) {
  9479. return order(a ? {
  9480. id: a.id,
  9481. values: [a]
  9482. } : null, b ? {
  9483. id: b.id,
  9484. values: [b]
  9485. } : null);
  9486. };
  9487. }
  9488. return sortFunction;
  9489. } else if (isArray(order)) {
  9490. return function (a, b) {
  9491. return order.indexOf(a.id) - order.indexOf(b.id);
  9492. };
  9493. }
  9494. } else {
  9495. // if data are grouped, we follow the order of grouped targets
  9496. var ids = $$.orderTargets($$.data.targets).map(function (i) {
  9497. return i.id;
  9498. }); // if it was either asc or desc we need to invert the order
  9499. // returned by orderTargets
  9500. if ($$.isOrderAsc() || $$.isOrderDesc()) {
  9501. ids = ids.reverse();
  9502. }
  9503. return function (a, b) {
  9504. return ids.indexOf(a.id) - ids.indexOf(b.id);
  9505. };
  9506. }
  9507. };
  9508. ChartInternal.prototype.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {
  9509. var $$ = this,
  9510. config = $$.config,
  9511. titleFormat = config.tooltip_format_title || defaultTitleFormat,
  9512. nameFormat = config.tooltip_format_name || function (name) {
  9513. return name;
  9514. },
  9515. text,
  9516. i,
  9517. title,
  9518. value,
  9519. name,
  9520. bgcolor;
  9521. var valueFormat = config.tooltip_format_value;
  9522. if (!valueFormat) {
  9523. valueFormat = $$.isTargetNormalized(d.id) ? function (v, ratio) {
  9524. return "".concat((ratio * 100).toFixed(2), "%");
  9525. } : defaultValueFormat;
  9526. }
  9527. var tooltipSortFunction = this.getTooltipSortFunction();
  9528. if (tooltipSortFunction) {
  9529. d.sort(tooltipSortFunction);
  9530. }
  9531. for (i = 0; i < d.length; i++) {
  9532. if (!(d[i] && (d[i].value || d[i].value === 0))) {
  9533. continue;
  9534. }
  9535. if ($$.isStanfordGraphType()) {
  9536. // Custom tooltip for stanford plots
  9537. if (!text) {
  9538. title = $$.getStanfordTooltipTitle(d[i]);
  9539. text = "<table class='" + $$.CLASS.tooltip + "'>" + title;
  9540. }
  9541. bgcolor = $$.getStanfordPointColor(d[i]);
  9542. name = sanitise(config.data_epochs); // Epochs key name
  9543. value = d[i].epochs;
  9544. } else {
  9545. // Regular tooltip
  9546. if (!text) {
  9547. title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x);
  9548. text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
  9549. }
  9550. value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));
  9551. if (value !== undefined) {
  9552. // Skip elements when their name is set to null
  9553. if (d[i].name === null) {
  9554. continue;
  9555. }
  9556. name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));
  9557. bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
  9558. }
  9559. }
  9560. if (value !== undefined) {
  9561. text += "<tr class='" + $$.CLASS.tooltipName + "-" + $$.getTargetSelectorSuffix(d[i].id) + "'>";
  9562. text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
  9563. text += "<td class='value'>" + value + "</td>";
  9564. text += "</tr>";
  9565. }
  9566. }
  9567. return text + "</table>";
  9568. };
  9569. ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {
  9570. var $$ = this,
  9571. config = $$.config,
  9572. d3 = $$.d3;
  9573. var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
  9574. var forArc = $$.hasArcType(),
  9575. mouse = d3.mouse(element); // Determin tooltip position
  9576. if (forArc) {
  9577. tooltipLeft = ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];
  9578. tooltipTop = ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20;
  9579. } else {
  9580. svgLeft = $$.getSvgLeft(true);
  9581. if (config.axis_rotated) {
  9582. tooltipLeft = svgLeft + mouse[0] + 100;
  9583. tooltipRight = tooltipLeft + tWidth;
  9584. chartRight = $$.currentWidth - $$.getCurrentPaddingRight();
  9585. tooltipTop = $$.x(dataToShow[0].x) + 20;
  9586. } else {
  9587. tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;
  9588. tooltipRight = tooltipLeft + tWidth;
  9589. chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();
  9590. tooltipTop = mouse[1] + 15;
  9591. }
  9592. if (tooltipRight > chartRight) {
  9593. // 20 is needed for Firefox to keep tooltip width
  9594. tooltipLeft -= tooltipRight - chartRight + 20;
  9595. }
  9596. if (tooltipTop + tHeight > $$.currentHeight) {
  9597. tooltipTop -= tHeight + 30;
  9598. }
  9599. }
  9600. if (tooltipTop < 0) {
  9601. tooltipTop = 0;
  9602. }
  9603. return {
  9604. top: tooltipTop,
  9605. left: tooltipLeft
  9606. };
  9607. };
  9608. ChartInternal.prototype.showTooltip = function (selectedData, element) {
  9609. var $$ = this,
  9610. config = $$.config;
  9611. var tWidth, tHeight, position;
  9612. var forArc = $$.hasArcType(),
  9613. dataToShow = selectedData.filter(function (d) {
  9614. return d && isValue(d.value);
  9615. }),
  9616. positionFunction = config.tooltip_position || ChartInternal.prototype.tooltipPosition;
  9617. if (dataToShow.length === 0 || !config.tooltip_show) {
  9618. return;
  9619. }
  9620. $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block"); // Get tooltip dimensions
  9621. tWidth = $$.tooltip.property('offsetWidth');
  9622. tHeight = $$.tooltip.property('offsetHeight');
  9623. position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); // Set tooltip
  9624. $$.tooltip.style("top", position.top + "px").style("left", position.left + 'px');
  9625. };
  9626. ChartInternal.prototype.hideTooltip = function () {
  9627. this.tooltip.style("display", "none");
  9628. };
  9629. ChartInternal.prototype.setTargetType = function (targetIds, type) {
  9630. var $$ = this,
  9631. config = $$.config;
  9632. $$.mapToTargetIds(targetIds).forEach(function (id) {
  9633. $$.withoutFadeIn[id] = type === config.data_types[id];
  9634. config.data_types[id] = type;
  9635. });
  9636. if (!targetIds) {
  9637. config.data_type = type;
  9638. }
  9639. };
  9640. ChartInternal.prototype.hasType = function (type, targets) {
  9641. var $$ = this,
  9642. types = $$.config.data_types,
  9643. has = false;
  9644. targets = targets || $$.data.targets;
  9645. if (targets && targets.length) {
  9646. targets.forEach(function (target) {
  9647. var t = types[target.id];
  9648. if (t && t.indexOf(type) >= 0 || !t && type === 'line') {
  9649. has = true;
  9650. }
  9651. });
  9652. } else if (Object.keys(types).length) {
  9653. Object.keys(types).forEach(function (id) {
  9654. if (types[id] === type) {
  9655. has = true;
  9656. }
  9657. });
  9658. } else {
  9659. has = $$.config.data_type === type;
  9660. }
  9661. return has;
  9662. };
  9663. ChartInternal.prototype.hasArcType = function (targets) {
  9664. return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets);
  9665. };
  9666. ChartInternal.prototype.isLineType = function (d) {
  9667. var config = this.config,
  9668. id = isString(d) ? d : d.id;
  9669. return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0;
  9670. };
  9671. ChartInternal.prototype.isStepType = function (d) {
  9672. var id = isString(d) ? d : d.id;
  9673. return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  9674. };
  9675. ChartInternal.prototype.isSplineType = function (d) {
  9676. var id = isString(d) ? d : d.id;
  9677. return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;
  9678. };
  9679. ChartInternal.prototype.isAreaType = function (d) {
  9680. var id = isString(d) ? d : d.id;
  9681. return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  9682. };
  9683. ChartInternal.prototype.isBarType = function (d) {
  9684. var id = isString(d) ? d : d.id;
  9685. return this.config.data_types[id] === 'bar';
  9686. };
  9687. ChartInternal.prototype.isScatterType = function (d) {
  9688. var id = isString(d) ? d : d.id;
  9689. return this.config.data_types[id] === 'scatter';
  9690. };
  9691. ChartInternal.prototype.isStanfordType = function (d) {
  9692. var id = isString(d) ? d : d.id;
  9693. return this.config.data_types[id] === 'stanford';
  9694. };
  9695. ChartInternal.prototype.isPieType = function (d) {
  9696. var id = isString(d) ? d : d.id;
  9697. return this.config.data_types[id] === 'pie';
  9698. };
  9699. ChartInternal.prototype.isGaugeType = function (d) {
  9700. var id = isString(d) ? d : d.id;
  9701. return this.config.data_types[id] === 'gauge';
  9702. };
  9703. ChartInternal.prototype.isDonutType = function (d) {
  9704. var id = isString(d) ? d : d.id;
  9705. return this.config.data_types[id] === 'donut';
  9706. };
  9707. ChartInternal.prototype.isArcType = function (d) {
  9708. return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);
  9709. };
  9710. ChartInternal.prototype.lineData = function (d) {
  9711. return this.isLineType(d) ? [d] : [];
  9712. };
  9713. ChartInternal.prototype.arcData = function (d) {
  9714. return this.isArcType(d.data) ? [d] : [];
  9715. };
  9716. /* not used
  9717. function scatterData(d) {
  9718. return isScatterType(d) ? d.values : [];
  9719. }
  9720. */
  9721. ChartInternal.prototype.barData = function (d) {
  9722. return this.isBarType(d) ? d.values : [];
  9723. };
  9724. ChartInternal.prototype.lineOrScatterOrStanfordData = function (d) {
  9725. return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d) ? d.values : [];
  9726. };
  9727. ChartInternal.prototype.barOrLineData = function (d) {
  9728. return this.isBarType(d) || this.isLineType(d) ? d.values : [];
  9729. };
  9730. ChartInternal.prototype.isSafari = function () {
  9731. var ua = window.navigator.userAgent;
  9732. return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0;
  9733. };
  9734. ChartInternal.prototype.isChrome = function () {
  9735. var ua = window.navigator.userAgent;
  9736. return ua.indexOf('Chrome') >= 0;
  9737. };
  9738. ChartInternal.prototype.initZoom = function () {
  9739. var $$ = this,
  9740. d3 = $$.d3,
  9741. config = $$.config,
  9742. startEvent;
  9743. $$.zoom = d3.zoom().on("start", function () {
  9744. if (config.zoom_type !== 'scroll') {
  9745. return;
  9746. }
  9747. var e = d3.event.sourceEvent;
  9748. if (e && e.type === "brush") {
  9749. return;
  9750. }
  9751. startEvent = e;
  9752. config.zoom_onzoomstart.call($$.api, e);
  9753. }).on("zoom", function () {
  9754. if (config.zoom_type !== 'scroll') {
  9755. return;
  9756. }
  9757. var e = d3.event.sourceEvent;
  9758. if (e && e.type === "brush") {
  9759. return;
  9760. }
  9761. $$.redrawForZoom();
  9762. config.zoom_onzoom.call($$.api, $$.x.orgDomain());
  9763. }).on('end', function () {
  9764. if (config.zoom_type !== 'scroll') {
  9765. return;
  9766. }
  9767. var e = d3.event.sourceEvent;
  9768. if (e && e.type === "brush") {
  9769. return;
  9770. } // if click, do nothing. otherwise, click interaction will be canceled.
  9771. if (e && startEvent.clientX === e.clientX && startEvent.clientY === e.clientY) {
  9772. return;
  9773. }
  9774. config.zoom_onzoomend.call($$.api, $$.x.orgDomain());
  9775. });
  9776. $$.zoom.updateDomain = function () {
  9777. if (d3.event && d3.event.transform) {
  9778. $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());
  9779. }
  9780. return this;
  9781. };
  9782. $$.zoom.updateExtent = function () {
  9783. this.scaleExtent([1, Infinity]).translateExtent([[0, 0], [$$.width, $$.height]]).extent([[0, 0], [$$.width, $$.height]]);
  9784. return this;
  9785. };
  9786. $$.zoom.update = function () {
  9787. return this.updateExtent().updateDomain();
  9788. };
  9789. return $$.zoom.updateExtent();
  9790. };
  9791. ChartInternal.prototype.zoomTransform = function (range) {
  9792. var $$ = this,
  9793. s = [$$.x(range[0]), $$.x(range[1])];
  9794. return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0);
  9795. };
  9796. ChartInternal.prototype.initDragZoom = function () {
  9797. var $$ = this;
  9798. var d3 = $$.d3;
  9799. var config = $$.config;
  9800. var context = $$.context = $$.svg;
  9801. var brushXPos = $$.margin.left + 20.5;
  9802. var brushYPos = $$.margin.top + 0.5;
  9803. if (!(config.zoom_type === 'drag' && config.zoom_enabled)) {
  9804. return;
  9805. }
  9806. var getZoomedDomain = function getZoomedDomain(selection) {
  9807. return selection && selection.map(function (x) {
  9808. return $$.x.invert(x);
  9809. });
  9810. };
  9811. var brush = $$.dragZoomBrush = d3.brushX().on("start", function () {
  9812. $$.api.unzoom();
  9813. $$.svg.select("." + CLASS.dragZoom).classed("disabled", false);
  9814. config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);
  9815. }).on("brush", function () {
  9816. config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection));
  9817. }).on("end", function () {
  9818. if (d3.event.selection == null) {
  9819. return;
  9820. }
  9821. var zoomedDomain = getZoomedDomain(d3.event.selection);
  9822. if (!config.zoom_disableDefaultBehavior) {
  9823. $$.api.zoom(zoomedDomain);
  9824. }
  9825. $$.svg.select("." + CLASS.dragZoom).classed("disabled", true);
  9826. config.zoom_onzoomend.call($$.api, zoomedDomain);
  9827. });
  9828. context.append("g").classed(CLASS.dragZoom, true).attr("clip-path", $$.clipPath).attr("transform", "translate(" + brushXPos + "," + brushYPos + ")").call(brush);
  9829. };
  9830. ChartInternal.prototype.getZoomDomain = function () {
  9831. var $$ = this,
  9832. config = $$.config,
  9833. d3 = $$.d3,
  9834. min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),
  9835. max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);
  9836. return [min, max];
  9837. };
  9838. ChartInternal.prototype.redrawForZoom = function () {
  9839. var $$ = this,
  9840. d3 = $$.d3,
  9841. config = $$.config,
  9842. zoom = $$.zoom,
  9843. x = $$.x;
  9844. if (!config.zoom_enabled) {
  9845. return;
  9846. }
  9847. if ($$.filterTargetsToShow($$.data.targets).length === 0) {
  9848. return;
  9849. }
  9850. zoom.update();
  9851. if (config.zoom_disableDefaultBehavior) {
  9852. return;
  9853. }
  9854. if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {
  9855. x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);
  9856. }
  9857. $$.redraw({
  9858. withTransition: false,
  9859. withY: config.zoom_rescale,
  9860. withSubchart: false,
  9861. withEventRect: false,
  9862. withDimension: false
  9863. });
  9864. if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {
  9865. $$.cancelClick = true;
  9866. }
  9867. };
  9868. return c3;
  9869. })));