c3.js 383 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123
  1. /* @license C3.js v0.5.2 | (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.c3 = factory());
  6. }(this, (function () { 'use strict';
  7. var CLASS = {
  8. target: 'c3-target',
  9. chart: 'c3-chart',
  10. chartLine: 'c3-chart-line',
  11. chartLines: 'c3-chart-lines',
  12. chartBar: 'c3-chart-bar',
  13. chartBars: 'c3-chart-bars',
  14. chartText: 'c3-chart-text',
  15. chartTexts: 'c3-chart-texts',
  16. chartArc: 'c3-chart-arc',
  17. chartArcs: 'c3-chart-arcs',
  18. chartArcsTitle: 'c3-chart-arcs-title',
  19. chartArcsBackground: 'c3-chart-arcs-background',
  20. chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',
  21. chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',
  22. chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',
  23. selectedCircle: 'c3-selected-circle',
  24. selectedCircles: 'c3-selected-circles',
  25. eventRect: 'c3-event-rect',
  26. eventRects: 'c3-event-rects',
  27. eventRectsSingle: 'c3-event-rects-single',
  28. eventRectsMultiple: 'c3-event-rects-multiple',
  29. zoomRect: 'c3-zoom-rect',
  30. brush: 'c3-brush',
  31. focused: 'c3-focused',
  32. defocused: 'c3-defocused',
  33. region: 'c3-region',
  34. regions: 'c3-regions',
  35. title: 'c3-title',
  36. tooltipContainer: 'c3-tooltip-container',
  37. tooltip: 'c3-tooltip',
  38. tooltipName: 'c3-tooltip-name',
  39. shape: 'c3-shape',
  40. shapes: 'c3-shapes',
  41. line: 'c3-line',
  42. lines: 'c3-lines',
  43. bar: 'c3-bar',
  44. bars: 'c3-bars',
  45. circle: 'c3-circle',
  46. circles: 'c3-circles',
  47. arc: 'c3-arc',
  48. arcLabelLine: 'c3-arc-label-line',
  49. arcs: 'c3-arcs',
  50. area: 'c3-area',
  51. areas: 'c3-areas',
  52. empty: 'c3-empty',
  53. text: 'c3-text',
  54. texts: 'c3-texts',
  55. gaugeValue: 'c3-gauge-value',
  56. grid: 'c3-grid',
  57. gridLines: 'c3-grid-lines',
  58. xgrid: 'c3-xgrid',
  59. xgrids: 'c3-xgrids',
  60. xgridLine: 'c3-xgrid-line',
  61. xgridLines: 'c3-xgrid-lines',
  62. xgridFocus: 'c3-xgrid-focus',
  63. ygrid: 'c3-ygrid',
  64. ygrids: 'c3-ygrids',
  65. ygridLine: 'c3-ygrid-line',
  66. ygridLines: 'c3-ygrid-lines',
  67. axis: 'c3-axis',
  68. axisX: 'c3-axis-x',
  69. axisXLabel: 'c3-axis-x-label',
  70. axisY: 'c3-axis-y',
  71. axisYLabel: 'c3-axis-y-label',
  72. axisY2: 'c3-axis-y2',
  73. axisY2Label: 'c3-axis-y2-label',
  74. legendBackground: 'c3-legend-background',
  75. legendItem: 'c3-legend-item',
  76. legendItemEvent: 'c3-legend-item-event',
  77. legendItemTile: 'c3-legend-item-tile',
  78. legendItemHidden: 'c3-legend-item-hidden',
  79. legendItemFocused: 'c3-legend-item-focused',
  80. dragarea: 'c3-dragarea',
  81. EXPANDED: '_expanded_',
  82. SELECTED: '_selected_',
  83. INCLUDED: '_included_'
  84. };
  85. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  86. return typeof obj;
  87. } : function (obj) {
  88. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  89. };
  90. var classCallCheck = function (instance, Constructor) {
  91. if (!(instance instanceof Constructor)) {
  92. throw new TypeError("Cannot call a class as a function");
  93. }
  94. };
  95. var inherits = function (subClass, superClass) {
  96. if (typeof superClass !== "function" && superClass !== null) {
  97. throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
  98. }
  99. subClass.prototype = Object.create(superClass && superClass.prototype, {
  100. constructor: {
  101. value: subClass,
  102. enumerable: false,
  103. writable: true,
  104. configurable: true
  105. }
  106. });
  107. if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
  108. };
  109. var possibleConstructorReturn = function (self, call) {
  110. if (!self) {
  111. throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  112. }
  113. return call && (typeof call === "object" || typeof call === "function") ? call : self;
  114. };
  115. var isValue = function isValue(v) {
  116. return v || v === 0;
  117. };
  118. var isFunction = function isFunction(o) {
  119. return typeof o === 'function';
  120. };
  121. var isArray = function isArray(o) {
  122. return Array.isArray(o);
  123. };
  124. var isString = function isString(o) {
  125. return typeof o === 'string';
  126. };
  127. var isUndefined = function isUndefined(v) {
  128. return typeof v === 'undefined';
  129. };
  130. var isDefined = function isDefined(v) {
  131. return typeof v !== 'undefined';
  132. };
  133. var ceil10 = function ceil10(v) {
  134. return Math.ceil(v / 10) * 10;
  135. };
  136. var asHalfPixel = function asHalfPixel(n) {
  137. return Math.ceil(n) + 0.5;
  138. };
  139. var diffDomain = function diffDomain(d) {
  140. return d[1] - d[0];
  141. };
  142. var isEmpty = function isEmpty(o) {
  143. return typeof o === 'undefined' || o === null || isString(o) && o.length === 0 || (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === 'object' && Object.keys(o).length === 0;
  144. };
  145. var notEmpty = function notEmpty(o) {
  146. return !c3_chart_internal_fn.isEmpty(o);
  147. };
  148. var getOption = function getOption(options, key, defaultValue) {
  149. return isDefined(options[key]) ? options[key] : defaultValue;
  150. };
  151. var hasValue = function hasValue(dict, value) {
  152. var found = false;
  153. Object.keys(dict).forEach(function (key) {
  154. if (dict[key] === value) {
  155. found = true;
  156. }
  157. });
  158. return found;
  159. };
  160. var sanitise = function sanitise(str) {
  161. return typeof str === 'string' ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;') : str;
  162. };
  163. var getPathBox = function getPathBox(path) {
  164. var box = path.getBoundingClientRect(),
  165. items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],
  166. minX = items[0].x,
  167. minY = Math.min(items[0].y, items[1].y);
  168. return { x: minX, y: minY, width: box.width, height: box.height };
  169. };
  170. var c3_axis_fn;
  171. var c3_axis_internal_fn;
  172. function AxisInternal(component, params) {
  173. var internal = this;
  174. internal.component = component;
  175. internal.params = params || {};
  176. internal.d3 = component.d3;
  177. internal.scale = internal.d3.scaleLinear();
  178. internal.range;
  179. internal.orient = "bottom";
  180. internal.innerTickSize = 6;
  181. internal.outerTickSize = this.params.withOuterTick ? 6 : 0;
  182. internal.tickPadding = 3;
  183. internal.tickValues = null;
  184. internal.tickFormat;
  185. internal.tickArguments;
  186. internal.tickOffset = 0;
  187. internal.tickCulling = true;
  188. internal.tickCentered;
  189. internal.tickTextCharSize;
  190. internal.tickTextRotate = internal.params.tickTextRotate;
  191. internal.tickLength;
  192. internal.axis = internal.generateAxis();
  193. }
  194. c3_axis_internal_fn = AxisInternal.prototype;
  195. c3_axis_internal_fn.axisX = function (selection, x, tickOffset) {
  196. selection.attr("transform", function (d) {
  197. return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)";
  198. });
  199. };
  200. c3_axis_internal_fn.axisY = function (selection, y) {
  201. selection.attr("transform", function (d) {
  202. return "translate(0," + Math.ceil(y(d)) + ")";
  203. });
  204. };
  205. c3_axis_internal_fn.scaleExtent = function (domain) {
  206. var start = domain[0],
  207. stop = domain[domain.length - 1];
  208. return start < stop ? [start, stop] : [stop, start];
  209. };
  210. c3_axis_internal_fn.generateTicks = function (scale) {
  211. var internal = this;
  212. var i,
  213. domain,
  214. ticks = [];
  215. if (scale.ticks) {
  216. return scale.ticks.apply(scale, internal.tickArguments);
  217. }
  218. domain = scale.domain();
  219. for (i = Math.ceil(domain[0]); i < domain[1]; i++) {
  220. ticks.push(i);
  221. }
  222. if (ticks.length > 0 && ticks[0] > 0) {
  223. ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));
  224. }
  225. return ticks;
  226. };
  227. c3_axis_internal_fn.copyScale = function () {
  228. var internal = this;
  229. var newScale = internal.scale.copy(),
  230. domain;
  231. if (internal.params.isCategory) {
  232. domain = internal.scale.domain();
  233. newScale.domain([domain[0], domain[1] - 1]);
  234. }
  235. return newScale;
  236. };
  237. c3_axis_internal_fn.textFormatted = function (v) {
  238. var internal = this,
  239. formatted = internal.tickFormat ? internal.tickFormat(v) : v;
  240. return typeof formatted !== 'undefined' ? formatted : '';
  241. };
  242. c3_axis_internal_fn.updateRange = function () {
  243. var internal = this;
  244. internal.range = internal.scale.rangeExtent ? internal.scale.rangeExtent() : internal.scaleExtent(internal.scale.range());
  245. return internal.range;
  246. };
  247. c3_axis_internal_fn.updateTickTextCharSize = function (tick) {
  248. var internal = this;
  249. if (internal.tickTextCharSize) {
  250. return internal.tickTextCharSize;
  251. }
  252. var size = {
  253. h: 11.5,
  254. w: 5.5
  255. };
  256. tick.select('text').text(function (d) {
  257. return internal.textFormatted(d);
  258. }).each(function (d) {
  259. var box = this.getBoundingClientRect(),
  260. text = internal.textFormatted(d),
  261. h = box.height,
  262. w = text ? box.width / text.length : undefined;
  263. if (h && w) {
  264. size.h = h;
  265. size.w = w;
  266. }
  267. }).text('');
  268. internal.tickTextCharSize = size;
  269. return size;
  270. };
  271. c3_axis_internal_fn.isVertical = function () {
  272. return this.orient === 'left' || this.orient === 'right';
  273. };
  274. c3_axis_internal_fn.tspanData = function (d, i, scale) {
  275. var internal = this;
  276. var splitted = internal.params.tickMultiline ? internal.splitTickText(d, scale) : [].concat(internal.textFormatted(d));
  277. return splitted.map(function (s) {
  278. return { index: i, splitted: s, length: splitted.length };
  279. });
  280. };
  281. c3_axis_internal_fn.splitTickText = function (d, scale) {
  282. var internal = this,
  283. tickText = internal.textFormatted(d),
  284. maxWidth = internal.params.tickWidth,
  285. subtext,
  286. spaceIndex,
  287. textWidth,
  288. splitted = [];
  289. if (Object.prototype.toString.call(tickText) === "[object Array]") {
  290. return tickText;
  291. }
  292. if (!maxWidth || maxWidth <= 0) {
  293. maxWidth = internal.isVertical() ? 95 : internal.params.isCategory ? Math.ceil(scale(1) - scale(0)) - 12 : 110;
  294. }
  295. function split(splitted, text) {
  296. spaceIndex = undefined;
  297. for (var i = 1; i < text.length; i++) {
  298. if (text.charAt(i) === ' ') {
  299. spaceIndex = i;
  300. }
  301. subtext = text.substr(0, i + 1);
  302. textWidth = internal.tickTextCharSize.w * subtext.length;
  303. // if text width gets over tick width, split by space index or crrent index
  304. if (maxWidth < textWidth) {
  305. return split(splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), text.slice(spaceIndex ? spaceIndex + 1 : i));
  306. }
  307. }
  308. return splitted.concat(text);
  309. }
  310. return split(splitted, tickText + "");
  311. };
  312. c3_axis_internal_fn.updateTickLength = function () {
  313. var internal = this;
  314. internal.tickLength = Math.max(internal.innerTickSize, 0) + internal.tickPadding;
  315. };
  316. c3_axis_internal_fn.lineY2 = function (d) {
  317. var internal = this,
  318. tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);
  319. return internal.range[0] < tickPosition && tickPosition < internal.range[1] ? internal.innerTickSize : 0;
  320. };
  321. c3_axis_internal_fn.textY = function () {
  322. var internal = this,
  323. rotate = internal.tickTextRotate;
  324. return rotate ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) : internal.tickLength;
  325. };
  326. c3_axis_internal_fn.textTransform = function () {
  327. var internal = this,
  328. rotate = internal.tickTextRotate;
  329. return rotate ? "rotate(" + rotate + ")" : "";
  330. };
  331. c3_axis_internal_fn.textTextAnchor = function () {
  332. var internal = this,
  333. rotate = internal.tickTextRotate;
  334. return rotate ? rotate > 0 ? "start" : "end" : "middle";
  335. };
  336. c3_axis_internal_fn.tspanDx = function () {
  337. var internal = this,
  338. rotate = internal.tickTextRotate;
  339. return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0;
  340. };
  341. c3_axis_internal_fn.tspanDy = function (d, i) {
  342. var internal = this,
  343. dy = internal.tickTextCharSize.h;
  344. if (i === 0) {
  345. if (internal.isVertical()) {
  346. dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);
  347. } else {
  348. dy = ".71em";
  349. }
  350. }
  351. return dy;
  352. };
  353. c3_axis_internal_fn.generateAxis = function () {
  354. var internal = this,
  355. d3 = internal.d3,
  356. params = internal.params;
  357. function axis(g, transition) {
  358. var self;
  359. g.each(function () {
  360. var g = axis.g = d3.select(this);
  361. var scale0 = this.__chart__ || internal.scale,
  362. scale1 = this.__chart__ = internal.copyScale();
  363. var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1),
  364. ticks = g.selectAll(".tick").data(ticksValues, scale1),
  365. tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6),
  366. // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.
  367. tickExit = ticks.exit().remove(),
  368. tickUpdate = ticks.merge(tickEnter),
  369. tickTransform,
  370. tickX,
  371. tickY;
  372. if (params.isCategory) {
  373. internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
  374. tickX = internal.tickCentered ? 0 : internal.tickOffset;
  375. tickY = internal.tickCentered ? internal.tickOffset : 0;
  376. } else {
  377. internal.tickOffset = tickX = 0;
  378. }
  379. internal.updateRange();
  380. internal.updateTickLength();
  381. internal.updateTickTextCharSize(g.select('.tick'));
  382. var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")),
  383. textUpdate = tickUpdate.select("text").merge(tickEnter.append("text"));
  384. var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) {
  385. return internal.tspanData(d, i, scale1);
  386. }),
  387. tspanEnter = tspans.enter().append('tspan'),
  388. tspanUpdate = tspanEnter.merge(tspans).text(function (d) {
  389. return d.splitted;
  390. });
  391. tspans.exit().remove();
  392. var path = g.selectAll(".domain").data([0]),
  393. pathUpdate = path.enter().append("path").merge(path).attr("class", "domain");
  394. // TODO: each attr should be one function and change its behavior by internal.orient, probably
  395. switch (internal.orient) {
  396. case "bottom":
  397. {
  398. tickTransform = internal.axisX;
  399. lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) {
  400. return internal.lineY2(d, i);
  401. });
  402. textUpdate.attr("x", 0).attr("y", function (d, i) {
  403. return internal.textY(d, i);
  404. }).attr("transform", function (d, i) {
  405. return internal.textTransform(d, i);
  406. }).style("text-anchor", function (d, i) {
  407. return internal.textTextAnchor(d, i);
  408. });
  409. tspanUpdate.attr('x', 0).attr("dy", function (d, i) {
  410. return internal.tspanDy(d, i);
  411. }).attr('dx', function (d, i) {
  412. return internal.tspanDx(d, i);
  413. });
  414. pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize);
  415. break;
  416. }
  417. case "top":
  418. {
  419. // TODO: rotated tick text
  420. tickTransform = internal.axisX;
  421. lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) {
  422. return -1 * internal.lineY2(d, i);
  423. });
  424. textUpdate.attr("x", 0).attr("y", function (d, i) {
  425. return -1 * internal.textY(d, i) - (params.isCategory ? 2 : internal.tickLength - 2);
  426. }).attr("transform", function (d, i) {
  427. return internal.textTransform(d, i);
  428. }).style("text-anchor", function (d, i) {
  429. return internal.textTextAnchor(d, i);
  430. });
  431. tspanUpdate.attr('x', 0).attr("dy", function (d, i) {
  432. return internal.tspanDy(d, i);
  433. }).attr('dx', function (d, i) {
  434. return internal.tspanDx(d, i);
  435. });
  436. pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize);
  437. break;
  438. }
  439. case "left":
  440. {
  441. tickTransform = internal.axisY;
  442. lineUpdate.attr("x2", -internal.innerTickSize).attr("y1", tickY).attr("y2", tickY);
  443. textUpdate.attr("x", -internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "end");
  444. tspanUpdate.attr('x', -internal.tickLength).attr("dy", function (d, i) {
  445. return internal.tspanDy(d, i);
  446. });
  447. pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize);
  448. break;
  449. }
  450. case "right":
  451. {
  452. tickTransform = internal.axisY;
  453. lineUpdate.attr("x2", internal.innerTickSize).attr("y1", tickY).attr("y2", tickY);
  454. textUpdate.attr("x", internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "start");
  455. tspanUpdate.attr('x', internal.tickLength).attr("dy", function (d, i) {
  456. return internal.tspanDy(d, i);
  457. });
  458. pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize);
  459. break;
  460. }
  461. }
  462. if (scale1.rangeBand) {
  463. var x = scale1,
  464. dx = x.rangeBand() / 2;
  465. scale0 = scale1 = function scale1(d) {
  466. return x(d) + dx;
  467. };
  468. } else if (scale0.rangeBand) {
  469. scale0 = scale1;
  470. } else {
  471. tickExit.call(tickTransform, scale1, internal.tickOffset);
  472. }
  473. tickEnter.call(tickTransform, scale0, internal.tickOffset);
  474. self = (transition ? tickUpdate.transition(transition) : tickUpdate).style('opacity', 1).call(tickTransform, scale1, internal.tickOffset);
  475. });
  476. return self;
  477. }
  478. axis.scale = function (x) {
  479. if (!arguments.length) {
  480. return internal.scale;
  481. }
  482. internal.scale = x;
  483. return axis;
  484. };
  485. axis.orient = function (x) {
  486. if (!arguments.length) {
  487. return internal.orient;
  488. }
  489. internal.orient = x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + "" : "bottom";
  490. return axis;
  491. };
  492. axis.tickFormat = function (format) {
  493. if (!arguments.length) {
  494. return internal.tickFormat;
  495. }
  496. internal.tickFormat = format;
  497. return axis;
  498. };
  499. axis.tickCentered = function (isCentered) {
  500. if (!arguments.length) {
  501. return internal.tickCentered;
  502. }
  503. internal.tickCentered = isCentered;
  504. return axis;
  505. };
  506. axis.tickOffset = function () {
  507. return internal.tickOffset;
  508. };
  509. axis.tickInterval = function () {
  510. var interval, length;
  511. if (params.isCategory) {
  512. interval = internal.tickOffset * 2;
  513. } else {
  514. length = axis.g.select('path.domain').node().getTotalLength() - internal.outerTickSize * 2;
  515. interval = length / axis.g.selectAll('line').size();
  516. }
  517. return interval === Infinity ? 0 : interval;
  518. };
  519. axis.ticks = function () {
  520. if (!arguments.length) {
  521. return internal.tickArguments;
  522. }
  523. internal.tickArguments = arguments;
  524. return axis;
  525. };
  526. axis.tickCulling = function (culling) {
  527. if (!arguments.length) {
  528. return internal.tickCulling;
  529. }
  530. internal.tickCulling = culling;
  531. return axis;
  532. };
  533. axis.tickValues = function (x) {
  534. if (typeof x === 'function') {
  535. internal.tickValues = function () {
  536. return x(internal.scale.domain());
  537. };
  538. } else {
  539. if (!arguments.length) {
  540. return internal.tickValues;
  541. }
  542. internal.tickValues = x;
  543. }
  544. return axis;
  545. };
  546. return axis;
  547. };
  548. var Axis = function (_Component) {
  549. inherits(Axis, _Component);
  550. function Axis(owner) {
  551. classCallCheck(this, Axis);
  552. var fn = {
  553. fn: c3_axis_fn,
  554. internal: {
  555. fn: c3_axis_internal_fn
  556. }
  557. };
  558. var _this = possibleConstructorReturn(this, (Axis.__proto__ || Object.getPrototypeOf(Axis)).call(this, owner, 'axis', fn));
  559. _this.d3 = owner.d3;
  560. _this.internal = AxisInternal;
  561. return _this;
  562. }
  563. return Axis;
  564. }(Component);
  565. c3_axis_fn = Axis.prototype;
  566. c3_axis_fn.init = function init() {
  567. var $$ = this.owner,
  568. config = $$.config,
  569. main = $$.main;
  570. $$.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');
  571. $$.axes.x.append("text").attr("class", CLASS.axisXLabel).attr("transform", config.axis_rotated ? "rotate(-90)" : "").style("text-anchor", this.textAnchorForXAxisLabel.bind(this));
  572. $$.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');
  573. $$.axes.y.append("text").attr("class", CLASS.axisYLabel).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForYAxisLabel.bind(this));
  574. $$.axes.y2 = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY2)
  575. // clip-path?
  576. .attr("transform", $$.getTranslate('y2')).style("visibility", config.axis_y2_show ? 'visible' : 'hidden');
  577. $$.axes.y2.append("text").attr("class", CLASS.axisY2Label).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForY2AxisLabel.bind(this));
  578. };
  579. c3_axis_fn.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  580. var $$ = this.owner,
  581. config = $$.config,
  582. axisParams = {
  583. isCategory: $$.isCategorized(),
  584. withOuterTick: withOuterTick,
  585. tickMultiline: config.axis_x_tick_multiline,
  586. tickWidth: config.axis_x_tick_width,
  587. tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,
  588. withoutTransition: withoutTransition
  589. },
  590. axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);
  591. if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") {
  592. tickValues = tickValues.map(function (v) {
  593. return $$.parseDate(v);
  594. });
  595. }
  596. // Set tick
  597. axis.tickFormat(tickFormat).tickValues(tickValues);
  598. if ($$.isCategorized()) {
  599. axis.tickCentered(config.axis_x_tick_centered);
  600. if (isEmpty(config.axis_x_tick_culling)) {
  601. config.axis_x_tick_culling = false;
  602. }
  603. }
  604. return axis;
  605. };
  606. c3_axis_fn.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) {
  607. var $$ = this.owner,
  608. config = $$.config,
  609. tickValues;
  610. if (config.axis_x_tick_fit || config.axis_x_tick_count) {
  611. tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries());
  612. }
  613. if (axis) {
  614. axis.tickValues(tickValues);
  615. } else {
  616. $$.xAxis.tickValues(tickValues);
  617. $$.subXAxis.tickValues(tickValues);
  618. }
  619. return tickValues;
  620. };
  621. c3_axis_fn.getYAxis = function getYAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  622. var $$ = this.owner,
  623. config = $$.config,
  624. axisParams = {
  625. withOuterTick: withOuterTick,
  626. withoutTransition: withoutTransition,
  627. tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate
  628. },
  629. axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient).tickFormat(tickFormat);
  630. if ($$.isTimeSeriesY()) {
  631. axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);
  632. } else {
  633. axis.tickValues(tickValues);
  634. }
  635. return axis;
  636. };
  637. c3_axis_fn.getId = function getId(id) {
  638. var config = this.owner.config;
  639. return id in config.data_axes ? config.data_axes[id] : 'y';
  640. };
  641. c3_axis_fn.getXAxisTickFormat = function getXAxisTickFormat() {
  642. var $$ = this.owner,
  643. config = $$.config,
  644. format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) {
  645. return v < 0 ? v.toFixed(0) : v;
  646. };
  647. if (config.axis_x_tick_format) {
  648. if (isFunction(config.axis_x_tick_format)) {
  649. format = config.axis_x_tick_format;
  650. } else if ($$.isTimeSeries()) {
  651. format = function format(date) {
  652. return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : "";
  653. };
  654. }
  655. }
  656. return isFunction(format) ? function (v) {
  657. return format.call($$, v);
  658. } : format;
  659. };
  660. c3_axis_fn.getTickValues = function getTickValues(tickValues, axis) {
  661. return tickValues ? tickValues : axis ? axis.tickValues() : undefined;
  662. };
  663. c3_axis_fn.getXAxisTickValues = function getXAxisTickValues() {
  664. return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis);
  665. };
  666. c3_axis_fn.getYAxisTickValues = function getYAxisTickValues() {
  667. return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis);
  668. };
  669. c3_axis_fn.getY2AxisTickValues = function getY2AxisTickValues() {
  670. return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis);
  671. };
  672. c3_axis_fn.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) {
  673. var $$ = this.owner,
  674. config = $$.config,
  675. option;
  676. if (axisId === 'y') {
  677. option = config.axis_y_label;
  678. } else if (axisId === 'y2') {
  679. option = config.axis_y2_label;
  680. } else if (axisId === 'x') {
  681. option = config.axis_x_label;
  682. }
  683. return option;
  684. };
  685. c3_axis_fn.getLabelText = function getLabelText(axisId) {
  686. var option = this.getLabelOptionByAxisId(axisId);
  687. return isString(option) ? option : option ? option.text : null;
  688. };
  689. c3_axis_fn.setLabelText = function setLabelText(axisId, text) {
  690. var $$ = this.owner,
  691. config = $$.config,
  692. option = this.getLabelOptionByAxisId(axisId);
  693. if (isString(option)) {
  694. if (axisId === 'y') {
  695. config.axis_y_label = text;
  696. } else if (axisId === 'y2') {
  697. config.axis_y2_label = text;
  698. } else if (axisId === 'x') {
  699. config.axis_x_label = text;
  700. }
  701. } else if (option) {
  702. option.text = text;
  703. }
  704. };
  705. c3_axis_fn.getLabelPosition = function getLabelPosition(axisId, defaultPosition) {
  706. var option = this.getLabelOptionByAxisId(axisId),
  707. position = option && (typeof option === 'undefined' ? 'undefined' : _typeof(option)) === 'object' && option.position ? option.position : defaultPosition;
  708. return {
  709. isInner: position.indexOf('inner') >= 0,
  710. isOuter: position.indexOf('outer') >= 0,
  711. isLeft: position.indexOf('left') >= 0,
  712. isCenter: position.indexOf('center') >= 0,
  713. isRight: position.indexOf('right') >= 0,
  714. isTop: position.indexOf('top') >= 0,
  715. isMiddle: position.indexOf('middle') >= 0,
  716. isBottom: position.indexOf('bottom') >= 0
  717. };
  718. };
  719. c3_axis_fn.getXAxisLabelPosition = function getXAxisLabelPosition() {
  720. return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right');
  721. };
  722. c3_axis_fn.getYAxisLabelPosition = function getYAxisLabelPosition() {
  723. return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  724. };
  725. c3_axis_fn.getY2AxisLabelPosition = function getY2AxisLabelPosition() {
  726. return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  727. };
  728. c3_axis_fn.getLabelPositionById = function getLabelPositionById(id) {
  729. return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition();
  730. };
  731. c3_axis_fn.textForXAxisLabel = function textForXAxisLabel() {
  732. return this.getLabelText('x');
  733. };
  734. c3_axis_fn.textForYAxisLabel = function textForYAxisLabel() {
  735. return this.getLabelText('y');
  736. };
  737. c3_axis_fn.textForY2AxisLabel = function textForY2AxisLabel() {
  738. return this.getLabelText('y2');
  739. };
  740. c3_axis_fn.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {
  741. var $$ = this.owner;
  742. if (forHorizontal) {
  743. return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;
  744. } else {
  745. return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0;
  746. }
  747. };
  748. c3_axis_fn.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) {
  749. if (forHorizontal) {
  750. return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0";
  751. } else {
  752. return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0";
  753. }
  754. };
  755. c3_axis_fn.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) {
  756. if (forHorizontal) {
  757. return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';
  758. } else {
  759. return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';
  760. }
  761. };
  762. c3_axis_fn.xForXAxisLabel = function xForXAxisLabel() {
  763. return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  764. };
  765. c3_axis_fn.xForYAxisLabel = function xForYAxisLabel() {
  766. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  767. };
  768. c3_axis_fn.xForY2AxisLabel = function xForY2AxisLabel() {
  769. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  770. };
  771. c3_axis_fn.dxForXAxisLabel = function dxForXAxisLabel() {
  772. return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  773. };
  774. c3_axis_fn.dxForYAxisLabel = function dxForYAxisLabel() {
  775. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  776. };
  777. c3_axis_fn.dxForY2AxisLabel = function dxForY2AxisLabel() {
  778. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  779. };
  780. c3_axis_fn.dyForXAxisLabel = function dyForXAxisLabel() {
  781. var $$ = this.owner,
  782. config = $$.config,
  783. position = this.getXAxisLabelPosition();
  784. if (config.axis_rotated) {
  785. return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'));
  786. } else {
  787. return position.isInner ? "-0.5em" : config.axis_x_height ? config.axis_x_height - 10 : "3em";
  788. }
  789. };
  790. c3_axis_fn.dyForYAxisLabel = function dyForYAxisLabel() {
  791. var $$ = this.owner,
  792. position = this.getYAxisLabelPosition();
  793. if ($$.config.axis_rotated) {
  794. return position.isInner ? "-0.5em" : "3em";
  795. } else {
  796. return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10);
  797. }
  798. };
  799. c3_axis_fn.dyForY2AxisLabel = function dyForY2AxisLabel() {
  800. var $$ = this.owner,
  801. position = this.getY2AxisLabelPosition();
  802. if ($$.config.axis_rotated) {
  803. return position.isInner ? "1.2em" : "-2.2em";
  804. } else {
  805. return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15);
  806. }
  807. };
  808. c3_axis_fn.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {
  809. var $$ = this.owner;
  810. return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition());
  811. };
  812. c3_axis_fn.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {
  813. var $$ = this.owner;
  814. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition());
  815. };
  816. c3_axis_fn.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {
  817. var $$ = this.owner;
  818. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition());
  819. };
  820. c3_axis_fn.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) {
  821. var $$ = this.owner,
  822. config = $$.config,
  823. maxWidth = 0,
  824. targetsToShow,
  825. scale,
  826. axis,
  827. dummy,
  828. svg;
  829. if (withoutRecompute && $$.currentMaxTickWidths[id]) {
  830. return $$.currentMaxTickWidths[id];
  831. }
  832. if ($$.svg) {
  833. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  834. if (id === 'y') {
  835. scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
  836. axis = this.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, false, true, true);
  837. } else if (id === 'y2') {
  838. scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
  839. axis = this.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, false, true, true);
  840. } else {
  841. scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
  842. axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);
  843. this.updateXAxisTickValues(targetsToShow, axis);
  844. }
  845. dummy = $$.d3.select('body').append('div').classed('c3', true);
  846. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () {
  847. $$.d3.select(this).selectAll('text').each(function () {
  848. var box = this.getBoundingClientRect();
  849. if (maxWidth < box.width) {
  850. maxWidth = box.width;
  851. }
  852. });
  853. dummy.remove();
  854. });
  855. }
  856. $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;
  857. return $$.currentMaxTickWidths[id];
  858. };
  859. c3_axis_fn.updateLabels = function updateLabels(withTransition) {
  860. var $$ = this.owner;
  861. var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),
  862. axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),
  863. axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label);
  864. (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));
  865. (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));
  866. (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));
  867. };
  868. c3_axis_fn.getPadding = function getPadding(padding, key, defaultValue, domainLength) {
  869. var p = typeof padding === 'number' ? padding : padding[key];
  870. if (!isValue(p)) {
  871. return defaultValue;
  872. }
  873. if (padding.unit === 'ratio') {
  874. return padding[key] * domainLength;
  875. }
  876. // assume padding is pixels if unit is not specified
  877. return this.convertPixelsToAxisPadding(p, domainLength);
  878. };
  879. c3_axis_fn.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) {
  880. var $$ = this.owner,
  881. length = $$.config.axis_rotated ? $$.width : $$.height;
  882. return domainLength * (pixels / length);
  883. };
  884. c3_axis_fn.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) {
  885. var tickValues = values,
  886. targetCount,
  887. start,
  888. end,
  889. count,
  890. interval,
  891. i,
  892. tickValue;
  893. if (tickCount) {
  894. targetCount = isFunction(tickCount) ? tickCount() : tickCount;
  895. // compute ticks according to tickCount
  896. if (targetCount === 1) {
  897. tickValues = [values[0]];
  898. } else if (targetCount === 2) {
  899. tickValues = [values[0], values[values.length - 1]];
  900. } else if (targetCount > 2) {
  901. count = targetCount - 2;
  902. start = values[0];
  903. end = values[values.length - 1];
  904. interval = (end - start) / (count + 1);
  905. // re-construct unique values
  906. tickValues = [start];
  907. for (i = 0; i < count; i++) {
  908. tickValue = +start + interval * (i + 1);
  909. tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);
  910. }
  911. tickValues.push(end);
  912. }
  913. }
  914. if (!forTimeSeries) {
  915. tickValues = tickValues.sort(function (a, b) {
  916. return a - b;
  917. });
  918. }
  919. return tickValues;
  920. };
  921. c3_axis_fn.generateTransitions = function generateTransitions(duration) {
  922. var $$ = this.owner,
  923. axes = $$.axes;
  924. return {
  925. axisX: duration ? axes.x.transition().duration(duration) : axes.x,
  926. axisY: duration ? axes.y.transition().duration(duration) : axes.y,
  927. axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,
  928. axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx
  929. };
  930. };
  931. c3_axis_fn.redraw = function redraw(duration, isHidden) {
  932. var $$ = this.owner,
  933. transition = duration ? $$.d3.transition().duration(duration) : null;
  934. $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition);
  935. $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition);
  936. $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition);
  937. $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition);
  938. };
  939. var c3 = { version: "0.5.2" };
  940. var c3_chart_fn;
  941. var c3_chart_internal_fn;
  942. function Component(owner, componentKey, fn) {
  943. this.owner = owner;
  944. c3.chart.internal[componentKey] = fn;
  945. }
  946. function Chart(config) {
  947. var $$ = this.internal = new ChartInternal(this);
  948. $$.loadConfig(config);
  949. $$.beforeInit(config);
  950. $$.init();
  951. $$.afterInit(config);
  952. // bind "this" to nested API
  953. (function bindThis(fn, target, argThis) {
  954. Object.keys(fn).forEach(function (key) {
  955. target[key] = fn[key].bind(argThis);
  956. if (Object.keys(fn[key]).length > 0) {
  957. bindThis(fn[key], target[key], argThis);
  958. }
  959. });
  960. })(c3_chart_fn, this, this);
  961. }
  962. function ChartInternal(api) {
  963. var $$ = this;
  964. $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
  965. $$.api = api;
  966. $$.config = $$.getDefaultConfig();
  967. $$.data = {};
  968. $$.cache = {};
  969. $$.axes = {};
  970. }
  971. c3.generate = function (config) {
  972. return new Chart(config);
  973. };
  974. c3.chart = {
  975. fn: Chart.prototype,
  976. internal: {
  977. fn: ChartInternal.prototype
  978. }
  979. };
  980. c3_chart_fn = c3.chart.fn;
  981. c3_chart_internal_fn = c3.chart.internal.fn;
  982. c3_chart_internal_fn.beforeInit = function () {
  983. // can do something
  984. };
  985. c3_chart_internal_fn.afterInit = function () {
  986. // can do something
  987. };
  988. c3_chart_internal_fn.init = function () {
  989. var $$ = this,
  990. config = $$.config;
  991. $$.initParams();
  992. if (config.data_url) {
  993. $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);
  994. } else if (config.data_json) {
  995. $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
  996. } else if (config.data_rows) {
  997. $$.initWithData($$.convertRowsToData(config.data_rows));
  998. } else if (config.data_columns) {
  999. $$.initWithData($$.convertColumnsToData(config.data_columns));
  1000. } else {
  1001. throw Error('url or json or rows or columns is required.');
  1002. }
  1003. };
  1004. c3_chart_internal_fn.initParams = function () {
  1005. var $$ = this,
  1006. d3 = $$.d3,
  1007. config = $$.config;
  1008. // MEMO: clipId needs to be unique because it conflicts when multiple charts exist
  1009. $$.clipId = "c3-" + +new Date() + '-clip', $$.clipIdForXAxis = $$.clipId + '-xaxis', $$.clipIdForYAxis = $$.clipId + '-yaxis', $$.clipIdForGrid = $$.clipId + '-grid', $$.clipIdForSubchart = $$.clipId + '-subchart', $$.clipPath = $$.getClipPath($$.clipId), $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis), $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
  1010. $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid), $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart), $$.dragStart = null;
  1011. $$.dragging = false;
  1012. $$.flowing = false;
  1013. $$.cancelClick = false;
  1014. $$.mouseover = false;
  1015. $$.transiting = false;
  1016. $$.color = $$.generateColor();
  1017. $$.levelColor = $$.generateLevelColor();
  1018. $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat);
  1019. $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;
  1020. $$.defaultAxisTimeFormat = function (date) {
  1021. if (date.getMilliseconds()) {
  1022. return d3.timeFormat(".%L")(date);
  1023. }
  1024. if (date.getSeconds()) {
  1025. return d3.timeFormat(":%S")(date);
  1026. }
  1027. if (date.getMinutes()) {
  1028. return d3.timeFormat("%I:%M")(date);
  1029. }
  1030. if (date.getHours()) {
  1031. return d3.timeFormat("%I %p")(date);
  1032. }
  1033. if (date.getDay() && date.getDate() !== 1) {
  1034. return d3.timeFormat("%-m/%-d")(date);
  1035. }
  1036. if (date.getDate() !== 1) {
  1037. return d3.timeFormat("%-m/%-d")(date);
  1038. }
  1039. if (date.getMonth()) {
  1040. return d3.timeFormat("%-m/%-d")(date);
  1041. }
  1042. return d3.timeFormat("%Y/%-m/%-d")(date);
  1043. };
  1044. $$.hiddenTargetIds = [];
  1045. $$.hiddenLegendIds = [];
  1046. $$.focusedTargetIds = [];
  1047. $$.defocusedTargetIds = [];
  1048. $$.xOrient = config.axis_rotated ? config.axis_x_inner ? "right" : "left" : config.axis_x_inner ? "top" : "bottom";
  1049. $$.yOrient = config.axis_rotated ? config.axis_y_inner ? "top" : "bottom" : config.axis_y_inner ? "right" : "left";
  1050. $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? "bottom" : "top" : config.axis_y2_inner ? "left" : "right";
  1051. $$.subXOrient = config.axis_rotated ? "left" : "bottom";
  1052. $$.isLegendRight = config.legend_position === 'right';
  1053. $$.isLegendInset = config.legend_position === 'inset';
  1054. $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right';
  1055. $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left';
  1056. $$.legendStep = 0;
  1057. $$.legendItemWidth = 0;
  1058. $$.legendItemHeight = 0;
  1059. $$.currentMaxTickWidths = {
  1060. x: 0,
  1061. y: 0,
  1062. y2: 0
  1063. };
  1064. $$.rotated_padding_left = 30;
  1065. $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;
  1066. $$.rotated_padding_top = 5;
  1067. $$.withoutFadeIn = {};
  1068. $$.intervalForObserveInserted = undefined;
  1069. $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
  1070. };
  1071. c3_chart_internal_fn.initChartElements = function () {
  1072. if (this.initBar) {
  1073. this.initBar();
  1074. }
  1075. if (this.initLine) {
  1076. this.initLine();
  1077. }
  1078. if (this.initArc) {
  1079. this.initArc();
  1080. }
  1081. if (this.initGauge) {
  1082. this.initGauge();
  1083. }
  1084. if (this.initText) {
  1085. this.initText();
  1086. }
  1087. };
  1088. c3_chart_internal_fn.initWithData = function (data) {
  1089. var $$ = this,
  1090. d3 = $$.d3,
  1091. config = $$.config;
  1092. var defs,
  1093. main,
  1094. binding = true;
  1095. $$.axis = new Axis($$);
  1096. if (!config.bindto) {
  1097. $$.selectChart = d3.selectAll([]);
  1098. } else if (typeof config.bindto.node === 'function') {
  1099. $$.selectChart = config.bindto;
  1100. } else {
  1101. $$.selectChart = d3.select(config.bindto);
  1102. }
  1103. if ($$.selectChart.empty()) {
  1104. $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0);
  1105. $$.observeInserted($$.selectChart);
  1106. binding = false;
  1107. }
  1108. $$.selectChart.html("").classed("c3", true);
  1109. // Init data as targets
  1110. $$.data.xs = {};
  1111. $$.data.targets = $$.convertDataToTargets(data);
  1112. if (config.data_filter) {
  1113. $$.data.targets = $$.data.targets.filter(config.data_filter);
  1114. }
  1115. // Set targets to hide if needed
  1116. if (config.data_hide) {
  1117. $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide);
  1118. }
  1119. if (config.legend_hide) {
  1120. $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide);
  1121. }
  1122. // Init sizes and scales
  1123. $$.updateSizes();
  1124. $$.updateScales();
  1125. // Set domains for each scale
  1126. $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));
  1127. $$.y.domain($$.getYDomain($$.data.targets, 'y'));
  1128. $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));
  1129. $$.subX.domain($$.x.domain());
  1130. $$.subY.domain($$.y.domain());
  1131. $$.subY2.domain($$.y2.domain());
  1132. // Save original x domain for zoom update
  1133. $$.orgXDomain = $$.x.domain();
  1134. /*-- Basic Elements --*/
  1135. // Define svgs
  1136. $$.svg = $$.selectChart.append("svg").style("overflow", "hidden").on('mouseenter', function () {
  1137. return config.onmouseover.call($$);
  1138. }).on('mouseleave', function () {
  1139. return config.onmouseout.call($$);
  1140. });
  1141. if ($$.config.svg_classname) {
  1142. $$.svg.attr('class', $$.config.svg_classname);
  1143. }
  1144. // Define defs
  1145. defs = $$.svg.append("defs");
  1146. $$.clipChart = $$.appendClip(defs, $$.clipId);
  1147. $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);
  1148. $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);
  1149. $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);
  1150. $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);
  1151. $$.updateSvgSize();
  1152. // Define regions
  1153. main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main'));
  1154. if ($$.initPie) {
  1155. $$.initPie();
  1156. }
  1157. if ($$.initSubchart) {
  1158. $$.initSubchart();
  1159. }
  1160. if ($$.initTooltip) {
  1161. $$.initTooltip();
  1162. }
  1163. if ($$.initLegend) {
  1164. $$.initLegend();
  1165. }
  1166. if ($$.initTitle) {
  1167. $$.initTitle();
  1168. }
  1169. if ($$.initZoom) {
  1170. $$.initZoom();
  1171. }
  1172. // Update selection based on size and scale
  1173. // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.
  1174. if ($$.initSubchartBrush) {
  1175. $$.initSubchartBrush();
  1176. }
  1177. /*-- Main Region --*/
  1178. // text when empty
  1179. main.append("text").attr("class", CLASS.text + ' ' + CLASS.empty).attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers.
  1180. .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE.
  1181. // Regions
  1182. $$.initRegion();
  1183. // Grids
  1184. $$.initGrid();
  1185. // Define g for chart area
  1186. main.append('g').attr("clip-path", $$.clipPath).attr('class', CLASS.chart);
  1187. // Grid lines
  1188. if (config.grid_lines_front) {
  1189. $$.initGridLines();
  1190. }
  1191. // Define g for chart
  1192. $$.initChartElements();
  1193. // Add Axis
  1194. $$.axis.init();
  1195. // Set targets
  1196. $$.updateTargets($$.data.targets);
  1197. // Cover whole with rects for events
  1198. $$.initEventRect();
  1199. // Set default extent if defined
  1200. if (config.axis_x_selection) {
  1201. $$.brush.selectionAsValue($$.getDefaultSelection());
  1202. }
  1203. // Draw with targets
  1204. if (binding) {
  1205. $$.updateDimension();
  1206. $$.config.oninit.call($$);
  1207. $$.redraw({
  1208. withTransition: false,
  1209. withTransform: true,
  1210. withUpdateXDomain: true,
  1211. withUpdateOrgXDomain: true,
  1212. withTransitionForAxis: false
  1213. });
  1214. }
  1215. // Bind resize event
  1216. $$.bindResize();
  1217. // export element of the chart
  1218. $$.api.element = $$.selectChart.node();
  1219. };
  1220. c3_chart_internal_fn.smoothLines = function (el, type) {
  1221. var $$ = this;
  1222. if (type === 'grid') {
  1223. el.each(function () {
  1224. var g = $$.d3.select(this),
  1225. x1 = g.attr('x1'),
  1226. x2 = g.attr('x2'),
  1227. y1 = g.attr('y1'),
  1228. y2 = g.attr('y2');
  1229. g.attr({
  1230. 'x1': Math.ceil(x1),
  1231. 'x2': Math.ceil(x2),
  1232. 'y1': Math.ceil(y1),
  1233. 'y2': Math.ceil(y2)
  1234. });
  1235. });
  1236. }
  1237. };
  1238. c3_chart_internal_fn.updateSizes = function () {
  1239. var $$ = this,
  1240. config = $$.config;
  1241. var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
  1242. legendWidth = $$.legend ? $$.getLegendWidth() : 0,
  1243. legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
  1244. hasArc = $$.hasArcType(),
  1245. xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),
  1246. subchartHeight = config.subchart_show && !hasArc ? config.subchart_size_height + xAxisHeight : 0;
  1247. $$.currentWidth = $$.getCurrentWidth();
  1248. $$.currentHeight = $$.getCurrentHeight();
  1249. // for main
  1250. $$.margin = config.axis_rotated ? {
  1251. top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),
  1252. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1253. bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1254. left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())
  1255. } : {
  1256. top: 4 + $$.getCurrentPaddingTop(), // for top tick text
  1257. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1258. bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1259. left: hasArc ? 0 : $$.getCurrentPaddingLeft()
  1260. };
  1261. // for subchart
  1262. $$.margin2 = config.axis_rotated ? {
  1263. top: $$.margin.top,
  1264. right: NaN,
  1265. bottom: 20 + legendHeightForBottom,
  1266. left: $$.rotated_padding_left
  1267. } : {
  1268. top: $$.currentHeight - subchartHeight - legendHeightForBottom,
  1269. right: NaN,
  1270. bottom: xAxisHeight + legendHeightForBottom,
  1271. left: $$.margin.left
  1272. };
  1273. // for legend
  1274. $$.margin3 = {
  1275. top: 0,
  1276. right: NaN,
  1277. bottom: 0,
  1278. left: 0
  1279. };
  1280. if ($$.updateSizeForLegend) {
  1281. $$.updateSizeForLegend(legendHeight, legendWidth);
  1282. }
  1283. $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;
  1284. $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;
  1285. if ($$.width < 0) {
  1286. $$.width = 0;
  1287. }
  1288. if ($$.height < 0) {
  1289. $$.height = 0;
  1290. }
  1291. $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width;
  1292. $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;
  1293. if ($$.width2 < 0) {
  1294. $$.width2 = 0;
  1295. }
  1296. if ($$.height2 < 0) {
  1297. $$.height2 = 0;
  1298. }
  1299. // for arc
  1300. $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
  1301. $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
  1302. if ($$.hasType('gauge') && !config.gauge_fullCircle) {
  1303. $$.arcHeight += $$.height - $$.getGaugeLabelHeight();
  1304. }
  1305. if ($$.updateRadius) {
  1306. $$.updateRadius();
  1307. }
  1308. if ($$.isLegendRight && hasArc) {
  1309. $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;
  1310. }
  1311. };
  1312. c3_chart_internal_fn.updateTargets = function (targets) {
  1313. var $$ = this;
  1314. /*-- Main --*/
  1315. //-- Text --//
  1316. $$.updateTargetsForText(targets);
  1317. //-- Bar --//
  1318. $$.updateTargetsForBar(targets);
  1319. //-- Line --//
  1320. $$.updateTargetsForLine(targets);
  1321. //-- Arc --//
  1322. if ($$.hasArcType() && $$.updateTargetsForArc) {
  1323. $$.updateTargetsForArc(targets);
  1324. }
  1325. /*-- Sub --*/
  1326. if ($$.updateTargetsForSubchart) {
  1327. $$.updateTargetsForSubchart(targets);
  1328. }
  1329. // Fade-in each chart
  1330. $$.showTargets();
  1331. };
  1332. c3_chart_internal_fn.showTargets = function () {
  1333. var $$ = this;
  1334. $$.svg.selectAll('.' + CLASS.target).filter(function (d) {
  1335. return $$.isTargetToShow(d.id);
  1336. }).transition().duration($$.config.transition_duration).style("opacity", 1);
  1337. };
  1338. c3_chart_internal_fn.redraw = function (options, transitions) {
  1339. var $$ = this,
  1340. main = $$.main,
  1341. d3 = $$.d3,
  1342. config = $$.config;
  1343. var areaIndices = $$.getShapeIndices($$.isAreaType),
  1344. barIndices = $$.getShapeIndices($$.isBarType),
  1345. lineIndices = $$.getShapeIndices($$.isLineType);
  1346. var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, withEventRect, withDimension, withUpdateXAxis;
  1347. var hideAxis = $$.hasArcType();
  1348. var drawArea, drawBar, drawLine, xForText, yForText;
  1349. var duration, durationForExit, durationForAxis;
  1350. var transitionsToWait, waitForDraw, flow, transition;
  1351. var targetsToShow = $$.filterTargetsToShow($$.data.targets),
  1352. tickValues,
  1353. i,
  1354. intervalForCulling,
  1355. xDomainForZoom;
  1356. var xv = $$.xv.bind($$),
  1357. cx,
  1358. cy;
  1359. options = options || {};
  1360. withY = getOption(options, "withY", true);
  1361. withSubchart = getOption(options, "withSubchart", true);
  1362. withTransition = getOption(options, "withTransition", true);
  1363. withTransform = getOption(options, "withTransform", false);
  1364. withUpdateXDomain = getOption(options, "withUpdateXDomain", false);
  1365. withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false);
  1366. withTrimXDomain = getOption(options, "withTrimXDomain", true);
  1367. withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain);
  1368. withLegend = getOption(options, "withLegend", false);
  1369. withEventRect = getOption(options, "withEventRect", true);
  1370. withDimension = getOption(options, "withDimension", true);
  1371. withTransitionForExit = getOption(options, "withTransitionForExit", withTransition);
  1372. withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition);
  1373. duration = withTransition ? config.transition_duration : 0;
  1374. durationForExit = withTransitionForExit ? duration : 0;
  1375. durationForAxis = withTransitionForAxis ? duration : 0;
  1376. transitions = transitions || $$.axis.generateTransitions(durationForAxis);
  1377. // update legend and transform each g
  1378. if (withLegend && config.legend_show) {
  1379. $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
  1380. } else if (withDimension) {
  1381. // need to update dimension (e.g. axis.y.tick.values) because y tick values should change
  1382. // no need to update axis in it because they will be updated in redraw()
  1383. $$.updateDimension(true);
  1384. }
  1385. // MEMO: needed for grids calculation
  1386. if ($$.isCategorized() && targetsToShow.length === 0) {
  1387. $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);
  1388. }
  1389. if (targetsToShow.length) {
  1390. $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);
  1391. if (!config.axis_x_tick_values) {
  1392. tickValues = $$.axis.updateXAxisTickValues(targetsToShow);
  1393. }
  1394. } else {
  1395. $$.xAxis.tickValues([]);
  1396. $$.subXAxis.tickValues([]);
  1397. }
  1398. if (config.zoom_rescale && !options.flow) {
  1399. xDomainForZoom = $$.x.orgDomain();
  1400. }
  1401. $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));
  1402. $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));
  1403. if (!config.axis_y_tick_values && config.axis_y_tick_count) {
  1404. $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count));
  1405. }
  1406. if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {
  1407. $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count));
  1408. }
  1409. // axes
  1410. $$.axis.redraw(durationForAxis, hideAxis);
  1411. // Update axis label
  1412. $$.axis.updateLabels(withTransition);
  1413. // show/hide if manual culling needed
  1414. if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {
  1415. if (config.axis_x_tick_culling && tickValues) {
  1416. for (i = 1; i < tickValues.length; i++) {
  1417. if (tickValues.length / i < config.axis_x_tick_culling_max) {
  1418. intervalForCulling = i;
  1419. break;
  1420. }
  1421. }
  1422. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {
  1423. var index = tickValues.indexOf(e);
  1424. if (index >= 0) {
  1425. d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');
  1426. }
  1427. });
  1428. } else {
  1429. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block');
  1430. }
  1431. }
  1432. // setup drawer - MEMO: these must be called after axis updated
  1433. drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined;
  1434. drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;
  1435. drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined;
  1436. xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
  1437. yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);
  1438. // update circleY based on updated parameters
  1439. $$.updateCircleY();
  1440. // generate circle x/y functions depending on updated params
  1441. cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
  1442. cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);
  1443. // Update sub domain
  1444. if (withY) {
  1445. $$.subY.domain($$.getYDomain(targetsToShow, 'y'));
  1446. $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));
  1447. }
  1448. // xgrid focus
  1449. $$.updateXgridFocus();
  1450. // Data empty label positioning and text.
  1451. 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);
  1452. // event rect
  1453. if (withEventRect) {
  1454. $$.redrawEventRect();
  1455. }
  1456. // grid
  1457. $$.updateGrid(duration);
  1458. // rect for regions
  1459. $$.updateRegion(duration);
  1460. // bars
  1461. $$.updateBar(durationForExit);
  1462. // lines, areas and cricles
  1463. $$.updateLine(durationForExit);
  1464. $$.updateArea(durationForExit);
  1465. $$.updateCircle(cx, cy);
  1466. // text
  1467. if ($$.hasDataLabel()) {
  1468. $$.updateText(xForText, yForText, durationForExit);
  1469. }
  1470. // title
  1471. if ($$.redrawTitle) {
  1472. $$.redrawTitle();
  1473. }
  1474. // arc
  1475. if ($$.redrawArc) {
  1476. $$.redrawArc(duration, durationForExit, withTransform);
  1477. }
  1478. // subchart
  1479. if ($$.redrawSubchart) {
  1480. $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);
  1481. }
  1482. // circles for select
  1483. main.selectAll('.' + CLASS.selectedCircles).filter($$.isBarType.bind($$)).selectAll('circle').remove();
  1484. if (options.flow) {
  1485. flow = $$.generateFlow({
  1486. targets: targetsToShow,
  1487. flow: options.flow,
  1488. duration: options.flow.duration,
  1489. drawBar: drawBar,
  1490. drawLine: drawLine,
  1491. drawArea: drawArea,
  1492. cx: cx,
  1493. cy: cy,
  1494. xv: xv,
  1495. xForText: xForText,
  1496. yForText: yForText
  1497. });
  1498. }
  1499. if ($$.isTabVisible()) {
  1500. // Only use transition if tab visible. See #938.
  1501. if (duration) {
  1502. // transition should be derived from one transition
  1503. transition = d3.transition().duration(duration);
  1504. transitionsToWait = [];
  1505. [$$.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) {
  1506. transitions.forEach(function (transition) {
  1507. transitionsToWait.push(transition);
  1508. });
  1509. });
  1510. // Wait for end of transitions to call flow and onrendered callback
  1511. waitForDraw = $$.generateWait();
  1512. transitionsToWait.forEach(function (t) {
  1513. waitForDraw.add(t);
  1514. });
  1515. waitForDraw(function () {
  1516. if (flow) {
  1517. flow();
  1518. }
  1519. if (config.onrendered) {
  1520. config.onrendered.call($$);
  1521. }
  1522. });
  1523. } else {
  1524. $$.redrawBar(drawBar);
  1525. $$.redrawLine(drawLine);
  1526. $$.redrawArea(drawArea);
  1527. $$.redrawCircle(cx, cy);
  1528. $$.redrawText(xForText, yForText, options.flow);
  1529. $$.redrawRegion();
  1530. $$.redrawGrid();
  1531. if (flow) {
  1532. flow();
  1533. }
  1534. if (config.onrendered) {
  1535. config.onrendered.call($$);
  1536. }
  1537. }
  1538. }
  1539. // update fadein condition
  1540. $$.mapToIds($$.data.targets).forEach(function (id) {
  1541. $$.withoutFadeIn[id] = true;
  1542. });
  1543. };
  1544. c3_chart_internal_fn.updateAndRedraw = function (options) {
  1545. var $$ = this,
  1546. config = $$.config,
  1547. transitions;
  1548. options = options || {};
  1549. // same with redraw
  1550. options.withTransition = getOption(options, "withTransition", true);
  1551. options.withTransform = getOption(options, "withTransform", false);
  1552. options.withLegend = getOption(options, "withLegend", false);
  1553. // NOT same with redraw
  1554. options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true);
  1555. options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true);
  1556. options.withTransitionForExit = false;
  1557. options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition);
  1558. // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)
  1559. $$.updateSizes();
  1560. // MEMO: called in updateLegend in redraw if withLegend
  1561. if (!(options.withLegend && config.legend_show)) {
  1562. transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0);
  1563. // Update scales
  1564. $$.updateScales();
  1565. $$.updateSvgSize();
  1566. // Update g positions
  1567. $$.transformAll(options.withTransitionForTransform, transitions);
  1568. }
  1569. // Draw with new sizes & scales
  1570. $$.redraw(options, transitions);
  1571. };
  1572. c3_chart_internal_fn.redrawWithoutRescale = function () {
  1573. this.redraw({
  1574. withY: false,
  1575. withSubchart: false,
  1576. withEventRect: false,
  1577. withTransitionForAxis: false
  1578. });
  1579. };
  1580. c3_chart_internal_fn.isTimeSeries = function () {
  1581. return this.config.axis_x_type === 'timeseries';
  1582. };
  1583. c3_chart_internal_fn.isCategorized = function () {
  1584. return this.config.axis_x_type.indexOf('categor') >= 0;
  1585. };
  1586. c3_chart_internal_fn.isCustomX = function () {
  1587. var $$ = this,
  1588. config = $$.config;
  1589. return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));
  1590. };
  1591. c3_chart_internal_fn.isTimeSeriesY = function () {
  1592. return this.config.axis_y_type === 'timeseries';
  1593. };
  1594. c3_chart_internal_fn.getTranslate = function (target) {
  1595. var $$ = this,
  1596. config = $$.config,
  1597. x,
  1598. y;
  1599. if (target === 'main') {
  1600. x = asHalfPixel($$.margin.left);
  1601. y = asHalfPixel($$.margin.top);
  1602. } else if (target === 'context') {
  1603. x = asHalfPixel($$.margin2.left);
  1604. y = asHalfPixel($$.margin2.top);
  1605. } else if (target === 'legend') {
  1606. x = $$.margin3.left;
  1607. y = $$.margin3.top;
  1608. } else if (target === 'x') {
  1609. x = 0;
  1610. y = config.axis_rotated ? 0 : $$.height;
  1611. } else if (target === 'y') {
  1612. x = 0;
  1613. y = config.axis_rotated ? $$.height : 0;
  1614. } else if (target === 'y2') {
  1615. x = config.axis_rotated ? 0 : $$.width;
  1616. y = config.axis_rotated ? 1 : 0;
  1617. } else if (target === 'subx') {
  1618. x = 0;
  1619. y = config.axis_rotated ? 0 : $$.height2;
  1620. } else if (target === 'arc') {
  1621. x = $$.arcWidth / 2;
  1622. y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label
  1623. }
  1624. return "translate(" + x + "," + y + ")";
  1625. };
  1626. c3_chart_internal_fn.initialOpacity = function (d) {
  1627. return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;
  1628. };
  1629. c3_chart_internal_fn.initialOpacityForCircle = function (d) {
  1630. return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0;
  1631. };
  1632. c3_chart_internal_fn.opacityForCircle = function (d) {
  1633. var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show;
  1634. var opacity = isPointShouldBeShown ? 1 : 0;
  1635. return isValue(d.value) ? this.isScatterType(d) ? 0.5 : opacity : 0;
  1636. };
  1637. c3_chart_internal_fn.opacityForText = function () {
  1638. return this.hasDataLabel() ? 1 : 0;
  1639. };
  1640. c3_chart_internal_fn.xx = function (d) {
  1641. return d ? this.x(d.x) : null;
  1642. };
  1643. c3_chart_internal_fn.xv = function (d) {
  1644. var $$ = this,
  1645. value = d.value;
  1646. if ($$.isTimeSeries()) {
  1647. value = $$.parseDate(d.value);
  1648. } else if ($$.isCategorized() && typeof d.value === 'string') {
  1649. value = $$.config.axis_x_categories.indexOf(d.value);
  1650. }
  1651. return Math.ceil($$.x(value));
  1652. };
  1653. c3_chart_internal_fn.yv = function (d) {
  1654. var $$ = this,
  1655. yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;
  1656. return Math.ceil(yScale(d.value));
  1657. };
  1658. c3_chart_internal_fn.subxx = function (d) {
  1659. return d ? this.subX(d.x) : null;
  1660. };
  1661. c3_chart_internal_fn.transformMain = function (withTransition, transitions) {
  1662. var $$ = this,
  1663. xAxis,
  1664. yAxis,
  1665. y2Axis;
  1666. if (transitions && transitions.axisX) {
  1667. xAxis = transitions.axisX;
  1668. } else {
  1669. xAxis = $$.main.select('.' + CLASS.axisX);
  1670. if (withTransition) {
  1671. xAxis = xAxis.transition();
  1672. }
  1673. }
  1674. if (transitions && transitions.axisY) {
  1675. yAxis = transitions.axisY;
  1676. } else {
  1677. yAxis = $$.main.select('.' + CLASS.axisY);
  1678. if (withTransition) {
  1679. yAxis = yAxis.transition();
  1680. }
  1681. }
  1682. if (transitions && transitions.axisY2) {
  1683. y2Axis = transitions.axisY2;
  1684. } else {
  1685. y2Axis = $$.main.select('.' + CLASS.axisY2);
  1686. if (withTransition) {
  1687. y2Axis = y2Axis.transition();
  1688. }
  1689. }
  1690. (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main'));
  1691. xAxis.attr("transform", $$.getTranslate('x'));
  1692. yAxis.attr("transform", $$.getTranslate('y'));
  1693. y2Axis.attr("transform", $$.getTranslate('y2'));
  1694. $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  1695. };
  1696. c3_chart_internal_fn.transformAll = function (withTransition, transitions) {
  1697. var $$ = this;
  1698. $$.transformMain(withTransition, transitions);
  1699. if ($$.config.subchart_show) {
  1700. $$.transformContext(withTransition, transitions);
  1701. }
  1702. if ($$.legend) {
  1703. $$.transformLegend(withTransition);
  1704. }
  1705. };
  1706. c3_chart_internal_fn.updateSvgSize = function () {
  1707. var $$ = this,
  1708. brush = $$.svg.select(".c3-brush .overlay");
  1709. $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
  1710. $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect').attr('width', $$.width).attr('height', $$.height);
  1711. $$.svg.select('#' + $$.clipIdForXAxis).select('rect').attr('x', $$.getXAxisClipX.bind($$)).attr('y', $$.getXAxisClipY.bind($$)).attr('width', $$.getXAxisClipWidth.bind($$)).attr('height', $$.getXAxisClipHeight.bind($$));
  1712. $$.svg.select('#' + $$.clipIdForYAxis).select('rect').attr('x', $$.getYAxisClipX.bind($$)).attr('y', $$.getYAxisClipY.bind($$)).attr('width', $$.getYAxisClipWidth.bind($$)).attr('height', $$.getYAxisClipHeight.bind($$));
  1713. $$.svg.select('#' + $$.clipIdForSubchart).select('rect').attr('width', $$.width).attr('height', brush.size() ? brush.attr('height') : 0);
  1714. // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
  1715. $$.selectChart.style('max-height', $$.currentHeight + "px");
  1716. };
  1717. c3_chart_internal_fn.updateDimension = function (withoutAxis) {
  1718. var $$ = this;
  1719. if (!withoutAxis) {
  1720. if ($$.config.axis_rotated) {
  1721. $$.axes.x.call($$.xAxis);
  1722. $$.axes.subx.call($$.subXAxis);
  1723. } else {
  1724. $$.axes.y.call($$.yAxis);
  1725. $$.axes.y2.call($$.y2Axis);
  1726. }
  1727. }
  1728. $$.updateSizes();
  1729. $$.updateScales();
  1730. $$.updateSvgSize();
  1731. $$.transformAll(false);
  1732. };
  1733. c3_chart_internal_fn.observeInserted = function (selection) {
  1734. var $$ = this,
  1735. observer;
  1736. if (typeof MutationObserver === 'undefined') {
  1737. window.console.error("MutationObserver not defined.");
  1738. return;
  1739. }
  1740. observer = new MutationObserver(function (mutations) {
  1741. mutations.forEach(function (mutation) {
  1742. if (mutation.type === 'childList' && mutation.previousSibling) {
  1743. observer.disconnect();
  1744. // need to wait for completion of load because size calculation requires the actual sizes determined after that completion
  1745. $$.intervalForObserveInserted = window.setInterval(function () {
  1746. // parentNode will NOT be null when completed
  1747. if (selection.node().parentNode) {
  1748. window.clearInterval($$.intervalForObserveInserted);
  1749. $$.updateDimension();
  1750. if ($$.brush) {
  1751. $$.brush.update();
  1752. }
  1753. $$.config.oninit.call($$);
  1754. $$.redraw({
  1755. withTransform: true,
  1756. withUpdateXDomain: true,
  1757. withUpdateOrgXDomain: true,
  1758. withTransition: false,
  1759. withTransitionForTransform: false,
  1760. withLegend: true
  1761. });
  1762. selection.transition().style('opacity', 1);
  1763. }
  1764. }, 10);
  1765. }
  1766. });
  1767. });
  1768. observer.observe(selection.node(), { attributes: true, childList: true, characterData: true });
  1769. };
  1770. c3_chart_internal_fn.bindResize = function () {
  1771. var $$ = this,
  1772. config = $$.config;
  1773. $$.resizeFunction = $$.generateResize(); // need to call .remove
  1774. $$.resizeFunction.add(function () {
  1775. config.onresize.call($$);
  1776. });
  1777. if (config.resize_auto) {
  1778. $$.resizeFunction.add(function () {
  1779. if ($$.resizeTimeout !== undefined) {
  1780. window.clearTimeout($$.resizeTimeout);
  1781. }
  1782. $$.resizeTimeout = window.setTimeout(function () {
  1783. delete $$.resizeTimeout;
  1784. $$.updateAndRedraw({
  1785. withUpdateXDomain: false,
  1786. withUpdateOrgXDomain: false,
  1787. withTransition: false,
  1788. withTransitionForTransform: false,
  1789. withLegend: true
  1790. });
  1791. if ($$.brush) {
  1792. $$.brush.update();
  1793. }
  1794. }, 100);
  1795. });
  1796. }
  1797. $$.resizeFunction.add(function () {
  1798. config.onresized.call($$);
  1799. });
  1800. $$.resizeIfElementDisplayed = function () {
  1801. // if element not displayed skip it
  1802. if ($$.api == null || !$$.api.element.offsetParent) {
  1803. return;
  1804. }
  1805. $$.resizeFunction();
  1806. };
  1807. if (window.attachEvent) {
  1808. window.attachEvent('onresize', $$.resizeIfElementDisplayed);
  1809. } else if (window.addEventListener) {
  1810. window.addEventListener('resize', $$.resizeIfElementDisplayed, false);
  1811. } else {
  1812. // fallback to this, if this is a very old browser
  1813. var wrapper = window.onresize;
  1814. if (!wrapper) {
  1815. // create a wrapper that will call all charts
  1816. wrapper = $$.generateResize();
  1817. } else if (!wrapper.add || !wrapper.remove) {
  1818. // there is already a handler registered, make sure we call it too
  1819. wrapper = $$.generateResize();
  1820. wrapper.add(window.onresize);
  1821. }
  1822. // add this graph to the wrapper, we will be removed if the user calls destroy
  1823. wrapper.add($$.resizeFunction);
  1824. window.onresize = function () {
  1825. // if element not displayed skip it
  1826. if (!$$.api.element.offsetParent) {
  1827. return;
  1828. }
  1829. wrapper();
  1830. };
  1831. }
  1832. };
  1833. c3_chart_internal_fn.generateResize = function () {
  1834. var resizeFunctions = [];
  1835. function callResizeFunctions() {
  1836. resizeFunctions.forEach(function (f) {
  1837. f();
  1838. });
  1839. }
  1840. callResizeFunctions.add = function (f) {
  1841. resizeFunctions.push(f);
  1842. };
  1843. callResizeFunctions.remove = function (f) {
  1844. for (var i = 0; i < resizeFunctions.length; i++) {
  1845. if (resizeFunctions[i] === f) {
  1846. resizeFunctions.splice(i, 1);
  1847. break;
  1848. }
  1849. }
  1850. };
  1851. return callResizeFunctions;
  1852. };
  1853. c3_chart_internal_fn.endall = function (transition, callback) {
  1854. var n = 0;
  1855. transition.each(function () {
  1856. ++n;
  1857. }).on("end", function () {
  1858. if (! --n) {
  1859. callback.apply(this, arguments);
  1860. }
  1861. });
  1862. };
  1863. c3_chart_internal_fn.generateWait = function () {
  1864. var transitionsToWait = [],
  1865. f = function f(callback) {
  1866. var timer = setInterval(function () {
  1867. var done = 0;
  1868. transitionsToWait.forEach(function (t) {
  1869. if (t.empty()) {
  1870. done += 1;
  1871. return;
  1872. }
  1873. try {
  1874. t.transition();
  1875. } catch (e) {
  1876. done += 1;
  1877. }
  1878. });
  1879. if (done === transitionsToWait.length) {
  1880. clearInterval(timer);
  1881. if (callback) {
  1882. callback();
  1883. }
  1884. }
  1885. }, 50);
  1886. };
  1887. f.add = function (transition) {
  1888. transitionsToWait.push(transition);
  1889. };
  1890. return f;
  1891. };
  1892. c3_chart_internal_fn.parseDate = function (date) {
  1893. var $$ = this,
  1894. parsedDate;
  1895. if (date instanceof Date) {
  1896. parsedDate = date;
  1897. } else if (typeof date === 'string') {
  1898. parsedDate = $$.dataTimeParse(date);
  1899. } else if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === 'object') {
  1900. parsedDate = new Date(+date);
  1901. } else if (typeof date === 'number' && !isNaN(date)) {
  1902. parsedDate = new Date(+date);
  1903. }
  1904. if (!parsedDate || isNaN(+parsedDate)) {
  1905. window.console.error("Failed to parse x '" + date + "' to Date object");
  1906. }
  1907. return parsedDate;
  1908. };
  1909. c3_chart_internal_fn.isTabVisible = function () {
  1910. var hidden;
  1911. if (typeof document.hidden !== "undefined") {
  1912. // Opera 12.10 and Firefox 18 and later support
  1913. hidden = "hidden";
  1914. } else if (typeof document.mozHidden !== "undefined") {
  1915. hidden = "mozHidden";
  1916. } else if (typeof document.msHidden !== "undefined") {
  1917. hidden = "msHidden";
  1918. } else if (typeof document.webkitHidden !== "undefined") {
  1919. hidden = "webkitHidden";
  1920. }
  1921. return document[hidden] ? false : true;
  1922. };
  1923. c3_chart_internal_fn.isValue = isValue;
  1924. c3_chart_internal_fn.isFunction = isFunction;
  1925. c3_chart_internal_fn.isString = isString;
  1926. c3_chart_internal_fn.isUndefined = isUndefined;
  1927. c3_chart_internal_fn.isDefined = isDefined;
  1928. c3_chart_internal_fn.ceil10 = ceil10;
  1929. c3_chart_internal_fn.asHalfPixel = asHalfPixel;
  1930. c3_chart_internal_fn.diffDomain = diffDomain;
  1931. c3_chart_internal_fn.isEmpty = isEmpty;
  1932. c3_chart_internal_fn.notEmpty = notEmpty;
  1933. c3_chart_internal_fn.notEmpty = notEmpty;
  1934. c3_chart_internal_fn.getOption = getOption;
  1935. c3_chart_internal_fn.hasValue = hasValue;
  1936. c3_chart_internal_fn.sanitise = sanitise;
  1937. c3_chart_internal_fn.getPathBox = getPathBox;
  1938. c3_chart_internal_fn.CLASS = CLASS;
  1939. /* jshint ignore:start */
  1940. // PhantomJS doesn't have support for Function.prototype.bind, which has caused confusion. Use
  1941. // this polyfill to avoid the confusion.
  1942. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Polyfill
  1943. if (!Function.prototype.bind) {
  1944. Function.prototype.bind = function (oThis) {
  1945. if (typeof this !== 'function') {
  1946. // closest thing possible to the ECMAScript 5
  1947. // internal IsCallable function
  1948. throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
  1949. }
  1950. var aArgs = Array.prototype.slice.call(arguments, 1),
  1951. fToBind = this,
  1952. fNOP = function fNOP() {},
  1953. fBound = function fBound() {
  1954. return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
  1955. };
  1956. fNOP.prototype = this.prototype;
  1957. fBound.prototype = new fNOP();
  1958. return fBound;
  1959. };
  1960. }
  1961. // SVGPathSeg API polyfill
  1962. // https://github.com/progers/pathseg
  1963. //
  1964. // This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from
  1965. // SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec
  1966. // changes which were implemented in Firefox 43 and Chrome 46.
  1967. (function () {
  1968. if (!("SVGPathSeg" in window)) {
  1969. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
  1970. window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {
  1971. this.pathSegType = type;
  1972. this.pathSegTypeAsLetter = typeAsLetter;
  1973. this._owningPathSegList = owningPathSegList;
  1974. };
  1975. window.SVGPathSeg.prototype.classname = "SVGPathSeg";
  1976. window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
  1977. window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
  1978. window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
  1979. window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
  1980. window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
  1981. window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
  1982. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
  1983. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
  1984. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
  1985. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
  1986. window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
  1987. window.SVGPathSeg.PATHSEG_ARC_REL = 11;
  1988. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
  1989. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
  1990. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
  1991. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
  1992. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
  1993. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
  1994. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
  1995. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
  1996. // Notify owning PathSegList on any changes so they can be synchronized back to the path element.
  1997. window.SVGPathSeg.prototype._segmentChanged = function () {
  1998. if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);
  1999. };
  2000. window.SVGPathSegClosePath = function (owningPathSegList) {
  2001. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
  2002. };
  2003. window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
  2004. window.SVGPathSegClosePath.prototype.toString = function () {
  2005. return "[object SVGPathSegClosePath]";
  2006. };
  2007. window.SVGPathSegClosePath.prototype._asPathString = function () {
  2008. return this.pathSegTypeAsLetter;
  2009. };
  2010. window.SVGPathSegClosePath.prototype.clone = function () {
  2011. return new window.SVGPathSegClosePath(undefined);
  2012. };
  2013. window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {
  2014. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
  2015. this._x = x;
  2016. this._y = y;
  2017. };
  2018. window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2019. window.SVGPathSegMovetoAbs.prototype.toString = function () {
  2020. return "[object SVGPathSegMovetoAbs]";
  2021. };
  2022. window.SVGPathSegMovetoAbs.prototype._asPathString = function () {
  2023. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2024. };
  2025. window.SVGPathSegMovetoAbs.prototype.clone = function () {
  2026. return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y);
  2027. };
  2028. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { get: function get() {
  2029. return this._x;
  2030. }, set: function set(x) {
  2031. this._x = x;this._segmentChanged();
  2032. }, enumerable: true });
  2033. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { get: function get() {
  2034. return this._y;
  2035. }, set: function set(y) {
  2036. this._y = y;this._segmentChanged();
  2037. }, enumerable: true });
  2038. window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {
  2039. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
  2040. this._x = x;
  2041. this._y = y;
  2042. };
  2043. window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2044. window.SVGPathSegMovetoRel.prototype.toString = function () {
  2045. return "[object SVGPathSegMovetoRel]";
  2046. };
  2047. window.SVGPathSegMovetoRel.prototype._asPathString = function () {
  2048. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2049. };
  2050. window.SVGPathSegMovetoRel.prototype.clone = function () {
  2051. return new window.SVGPathSegMovetoRel(undefined, this._x, this._y);
  2052. };
  2053. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { get: function get() {
  2054. return this._x;
  2055. }, set: function set(x) {
  2056. this._x = x;this._segmentChanged();
  2057. }, enumerable: true });
  2058. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { get: function get() {
  2059. return this._y;
  2060. }, set: function set(y) {
  2061. this._y = y;this._segmentChanged();
  2062. }, enumerable: true });
  2063. window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {
  2064. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
  2065. this._x = x;
  2066. this._y = y;
  2067. };
  2068. window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2069. window.SVGPathSegLinetoAbs.prototype.toString = function () {
  2070. return "[object SVGPathSegLinetoAbs]";
  2071. };
  2072. window.SVGPathSegLinetoAbs.prototype._asPathString = function () {
  2073. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2074. };
  2075. window.SVGPathSegLinetoAbs.prototype.clone = function () {
  2076. return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y);
  2077. };
  2078. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { get: function get() {
  2079. return this._x;
  2080. }, set: function set(x) {
  2081. this._x = x;this._segmentChanged();
  2082. }, enumerable: true });
  2083. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { get: function get() {
  2084. return this._y;
  2085. }, set: function set(y) {
  2086. this._y = y;this._segmentChanged();
  2087. }, enumerable: true });
  2088. window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {
  2089. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
  2090. this._x = x;
  2091. this._y = y;
  2092. };
  2093. window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2094. window.SVGPathSegLinetoRel.prototype.toString = function () {
  2095. return "[object SVGPathSegLinetoRel]";
  2096. };
  2097. window.SVGPathSegLinetoRel.prototype._asPathString = function () {
  2098. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2099. };
  2100. window.SVGPathSegLinetoRel.prototype.clone = function () {
  2101. return new window.SVGPathSegLinetoRel(undefined, this._x, this._y);
  2102. };
  2103. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { get: function get() {
  2104. return this._x;
  2105. }, set: function set(x) {
  2106. this._x = x;this._segmentChanged();
  2107. }, enumerable: true });
  2108. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { get: function get() {
  2109. return this._y;
  2110. }, set: function set(y) {
  2111. this._y = y;this._segmentChanged();
  2112. }, enumerable: true });
  2113. window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2114. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
  2115. this._x = x;
  2116. this._y = y;
  2117. this._x1 = x1;
  2118. this._y1 = y1;
  2119. this._x2 = x2;
  2120. this._y2 = y2;
  2121. };
  2122. window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2123. window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () {
  2124. return "[object SVGPathSegCurvetoCubicAbs]";
  2125. };
  2126. window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () {
  2127. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2128. };
  2129. window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () {
  2130. return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2131. };
  2132. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { get: function get() {
  2133. return this._x;
  2134. }, set: function set(x) {
  2135. this._x = x;this._segmentChanged();
  2136. }, enumerable: true });
  2137. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { get: function get() {
  2138. return this._y;
  2139. }, set: function set(y) {
  2140. this._y = y;this._segmentChanged();
  2141. }, enumerable: true });
  2142. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { get: function get() {
  2143. return this._x1;
  2144. }, set: function set(x1) {
  2145. this._x1 = x1;this._segmentChanged();
  2146. }, enumerable: true });
  2147. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { get: function get() {
  2148. return this._y1;
  2149. }, set: function set(y1) {
  2150. this._y1 = y1;this._segmentChanged();
  2151. }, enumerable: true });
  2152. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { get: function get() {
  2153. return this._x2;
  2154. }, set: function set(x2) {
  2155. this._x2 = x2;this._segmentChanged();
  2156. }, enumerable: true });
  2157. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { get: function get() {
  2158. return this._y2;
  2159. }, set: function set(y2) {
  2160. this._y2 = y2;this._segmentChanged();
  2161. }, enumerable: true });
  2162. window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2163. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
  2164. this._x = x;
  2165. this._y = y;
  2166. this._x1 = x1;
  2167. this._y1 = y1;
  2168. this._x2 = x2;
  2169. this._y2 = y2;
  2170. };
  2171. window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2172. window.SVGPathSegCurvetoCubicRel.prototype.toString = function () {
  2173. return "[object SVGPathSegCurvetoCubicRel]";
  2174. };
  2175. window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () {
  2176. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2177. };
  2178. window.SVGPathSegCurvetoCubicRel.prototype.clone = function () {
  2179. return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2180. };
  2181. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { get: function get() {
  2182. return this._x;
  2183. }, set: function set(x) {
  2184. this._x = x;this._segmentChanged();
  2185. }, enumerable: true });
  2186. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { get: function get() {
  2187. return this._y;
  2188. }, set: function set(y) {
  2189. this._y = y;this._segmentChanged();
  2190. }, enumerable: true });
  2191. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { get: function get() {
  2192. return this._x1;
  2193. }, set: function set(x1) {
  2194. this._x1 = x1;this._segmentChanged();
  2195. }, enumerable: true });
  2196. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { get: function get() {
  2197. return this._y1;
  2198. }, set: function set(y1) {
  2199. this._y1 = y1;this._segmentChanged();
  2200. }, enumerable: true });
  2201. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { get: function get() {
  2202. return this._x2;
  2203. }, set: function set(x2) {
  2204. this._x2 = x2;this._segmentChanged();
  2205. }, enumerable: true });
  2206. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { get: function get() {
  2207. return this._y2;
  2208. }, set: function set(y2) {
  2209. this._y2 = y2;this._segmentChanged();
  2210. }, enumerable: true });
  2211. window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {
  2212. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
  2213. this._x = x;
  2214. this._y = y;
  2215. this._x1 = x1;
  2216. this._y1 = y1;
  2217. };
  2218. window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2219. window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () {
  2220. return "[object SVGPathSegCurvetoQuadraticAbs]";
  2221. };
  2222. window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () {
  2223. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2224. };
  2225. window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () {
  2226. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1);
  2227. };
  2228. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { get: function get() {
  2229. return this._x;
  2230. }, set: function set(x) {
  2231. this._x = x;this._segmentChanged();
  2232. }, enumerable: true });
  2233. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { get: function get() {
  2234. return this._y;
  2235. }, set: function set(y) {
  2236. this._y = y;this._segmentChanged();
  2237. }, enumerable: true });
  2238. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { get: function get() {
  2239. return this._x1;
  2240. }, set: function set(x1) {
  2241. this._x1 = x1;this._segmentChanged();
  2242. }, enumerable: true });
  2243. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { get: function get() {
  2244. return this._y1;
  2245. }, set: function set(y1) {
  2246. this._y1 = y1;this._segmentChanged();
  2247. }, enumerable: true });
  2248. window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {
  2249. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
  2250. this._x = x;
  2251. this._y = y;
  2252. this._x1 = x1;
  2253. this._y1 = y1;
  2254. };
  2255. window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2256. window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () {
  2257. return "[object SVGPathSegCurvetoQuadraticRel]";
  2258. };
  2259. window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () {
  2260. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2261. };
  2262. window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () {
  2263. return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1);
  2264. };
  2265. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { get: function get() {
  2266. return this._x;
  2267. }, set: function set(x) {
  2268. this._x = x;this._segmentChanged();
  2269. }, enumerable: true });
  2270. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { get: function get() {
  2271. return this._y;
  2272. }, set: function set(y) {
  2273. this._y = y;this._segmentChanged();
  2274. }, enumerable: true });
  2275. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { get: function get() {
  2276. return this._x1;
  2277. }, set: function set(x1) {
  2278. this._x1 = x1;this._segmentChanged();
  2279. }, enumerable: true });
  2280. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { get: function get() {
  2281. return this._y1;
  2282. }, set: function set(y1) {
  2283. this._y1 = y1;this._segmentChanged();
  2284. }, enumerable: true });
  2285. window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2286. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
  2287. this._x = x;
  2288. this._y = y;
  2289. this._r1 = r1;
  2290. this._r2 = r2;
  2291. this._angle = angle;
  2292. this._largeArcFlag = largeArcFlag;
  2293. this._sweepFlag = sweepFlag;
  2294. };
  2295. window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2296. window.SVGPathSegArcAbs.prototype.toString = function () {
  2297. return "[object SVGPathSegArcAbs]";
  2298. };
  2299. window.SVGPathSegArcAbs.prototype._asPathString = function () {
  2300. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2301. };
  2302. window.SVGPathSegArcAbs.prototype.clone = function () {
  2303. return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2304. };
  2305. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { get: function get() {
  2306. return this._x;
  2307. }, set: function set(x) {
  2308. this._x = x;this._segmentChanged();
  2309. }, enumerable: true });
  2310. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { get: function get() {
  2311. return this._y;
  2312. }, set: function set(y) {
  2313. this._y = y;this._segmentChanged();
  2314. }, enumerable: true });
  2315. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { get: function get() {
  2316. return this._r1;
  2317. }, set: function set(r1) {
  2318. this._r1 = r1;this._segmentChanged();
  2319. }, enumerable: true });
  2320. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { get: function get() {
  2321. return this._r2;
  2322. }, set: function set(r2) {
  2323. this._r2 = r2;this._segmentChanged();
  2324. }, enumerable: true });
  2325. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { get: function get() {
  2326. return this._angle;
  2327. }, set: function set(angle) {
  2328. this._angle = angle;this._segmentChanged();
  2329. }, enumerable: true });
  2330. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { get: function get() {
  2331. return this._largeArcFlag;
  2332. }, set: function set(largeArcFlag) {
  2333. this._largeArcFlag = largeArcFlag;this._segmentChanged();
  2334. }, enumerable: true });
  2335. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { get: function get() {
  2336. return this._sweepFlag;
  2337. }, set: function set(sweepFlag) {
  2338. this._sweepFlag = sweepFlag;this._segmentChanged();
  2339. }, enumerable: true });
  2340. window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2341. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
  2342. this._x = x;
  2343. this._y = y;
  2344. this._r1 = r1;
  2345. this._r2 = r2;
  2346. this._angle = angle;
  2347. this._largeArcFlag = largeArcFlag;
  2348. this._sweepFlag = sweepFlag;
  2349. };
  2350. window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2351. window.SVGPathSegArcRel.prototype.toString = function () {
  2352. return "[object SVGPathSegArcRel]";
  2353. };
  2354. window.SVGPathSegArcRel.prototype._asPathString = function () {
  2355. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2356. };
  2357. window.SVGPathSegArcRel.prototype.clone = function () {
  2358. return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2359. };
  2360. Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { get: function get() {
  2361. return this._x;
  2362. }, set: function set(x) {
  2363. this._x = x;this._segmentChanged();
  2364. }, enumerable: true });
  2365. Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { get: function get() {
  2366. return this._y;
  2367. }, set: function set(y) {
  2368. this._y = y;this._segmentChanged();
  2369. }, enumerable: true });
  2370. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { get: function get() {
  2371. return this._r1;
  2372. }, set: function set(r1) {
  2373. this._r1 = r1;this._segmentChanged();
  2374. }, enumerable: true });
  2375. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { get: function get() {
  2376. return this._r2;
  2377. }, set: function set(r2) {
  2378. this._r2 = r2;this._segmentChanged();
  2379. }, enumerable: true });
  2380. Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { get: function get() {
  2381. return this._angle;
  2382. }, set: function set(angle) {
  2383. this._angle = angle;this._segmentChanged();
  2384. }, enumerable: true });
  2385. Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { get: function get() {
  2386. return this._largeArcFlag;
  2387. }, set: function set(largeArcFlag) {
  2388. this._largeArcFlag = largeArcFlag;this._segmentChanged();
  2389. }, enumerable: true });
  2390. Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { get: function get() {
  2391. return this._sweepFlag;
  2392. }, set: function set(sweepFlag) {
  2393. this._sweepFlag = sweepFlag;this._segmentChanged();
  2394. }, enumerable: true });
  2395. window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {
  2396. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
  2397. this._x = x;
  2398. };
  2399. window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2400. window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () {
  2401. return "[object SVGPathSegLinetoHorizontalAbs]";
  2402. };
  2403. window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () {
  2404. return this.pathSegTypeAsLetter + " " + this._x;
  2405. };
  2406. window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () {
  2407. return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x);
  2408. };
  2409. Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { get: function get() {
  2410. return this._x;
  2411. }, set: function set(x) {
  2412. this._x = x;this._segmentChanged();
  2413. }, enumerable: true });
  2414. window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {
  2415. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
  2416. this._x = x;
  2417. };
  2418. window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2419. window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () {
  2420. return "[object SVGPathSegLinetoHorizontalRel]";
  2421. };
  2422. window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () {
  2423. return this.pathSegTypeAsLetter + " " + this._x;
  2424. };
  2425. window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () {
  2426. return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x);
  2427. };
  2428. Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { get: function get() {
  2429. return this._x;
  2430. }, set: function set(x) {
  2431. this._x = x;this._segmentChanged();
  2432. }, enumerable: true });
  2433. window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {
  2434. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
  2435. this._y = y;
  2436. };
  2437. window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2438. window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () {
  2439. return "[object SVGPathSegLinetoVerticalAbs]";
  2440. };
  2441. window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () {
  2442. return this.pathSegTypeAsLetter + " " + this._y;
  2443. };
  2444. window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () {
  2445. return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y);
  2446. };
  2447. Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { get: function get() {
  2448. return this._y;
  2449. }, set: function set(y) {
  2450. this._y = y;this._segmentChanged();
  2451. }, enumerable: true });
  2452. window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {
  2453. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
  2454. this._y = y;
  2455. };
  2456. window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2457. window.SVGPathSegLinetoVerticalRel.prototype.toString = function () {
  2458. return "[object SVGPathSegLinetoVerticalRel]";
  2459. };
  2460. window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () {
  2461. return this.pathSegTypeAsLetter + " " + this._y;
  2462. };
  2463. window.SVGPathSegLinetoVerticalRel.prototype.clone = function () {
  2464. return new window.SVGPathSegLinetoVerticalRel(undefined, this._y);
  2465. };
  2466. Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { get: function get() {
  2467. return this._y;
  2468. }, set: function set(y) {
  2469. this._y = y;this._segmentChanged();
  2470. }, enumerable: true });
  2471. window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {
  2472. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
  2473. this._x = x;
  2474. this._y = y;
  2475. this._x2 = x2;
  2476. this._y2 = y2;
  2477. };
  2478. window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2479. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () {
  2480. return "[object SVGPathSegCurvetoCubicSmoothAbs]";
  2481. };
  2482. window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () {
  2483. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2484. };
  2485. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () {
  2486. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2);
  2487. };
  2488. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { get: function get() {
  2489. return this._x;
  2490. }, set: function set(x) {
  2491. this._x = x;this._segmentChanged();
  2492. }, enumerable: true });
  2493. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { get: function get() {
  2494. return this._y;
  2495. }, set: function set(y) {
  2496. this._y = y;this._segmentChanged();
  2497. }, enumerable: true });
  2498. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { get: function get() {
  2499. return this._x2;
  2500. }, set: function set(x2) {
  2501. this._x2 = x2;this._segmentChanged();
  2502. }, enumerable: true });
  2503. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { get: function get() {
  2504. return this._y2;
  2505. }, set: function set(y2) {
  2506. this._y2 = y2;this._segmentChanged();
  2507. }, enumerable: true });
  2508. window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {
  2509. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
  2510. this._x = x;
  2511. this._y = y;
  2512. this._x2 = x2;
  2513. this._y2 = y2;
  2514. };
  2515. window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2516. window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () {
  2517. return "[object SVGPathSegCurvetoCubicSmoothRel]";
  2518. };
  2519. window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () {
  2520. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2521. };
  2522. window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () {
  2523. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2);
  2524. };
  2525. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { get: function get() {
  2526. return this._x;
  2527. }, set: function set(x) {
  2528. this._x = x;this._segmentChanged();
  2529. }, enumerable: true });
  2530. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { get: function get() {
  2531. return this._y;
  2532. }, set: function set(y) {
  2533. this._y = y;this._segmentChanged();
  2534. }, enumerable: true });
  2535. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { get: function get() {
  2536. return this._x2;
  2537. }, set: function set(x2) {
  2538. this._x2 = x2;this._segmentChanged();
  2539. }, enumerable: true });
  2540. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { get: function get() {
  2541. return this._y2;
  2542. }, set: function set(y2) {
  2543. this._y2 = y2;this._segmentChanged();
  2544. }, enumerable: true });
  2545. window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {
  2546. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
  2547. this._x = x;
  2548. this._y = y;
  2549. };
  2550. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2551. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () {
  2552. return "[object SVGPathSegCurvetoQuadraticSmoothAbs]";
  2553. };
  2554. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () {
  2555. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2556. };
  2557. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () {
  2558. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y);
  2559. };
  2560. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { get: function get() {
  2561. return this._x;
  2562. }, set: function set(x) {
  2563. this._x = x;this._segmentChanged();
  2564. }, enumerable: true });
  2565. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { get: function get() {
  2566. return this._y;
  2567. }, set: function set(y) {
  2568. this._y = y;this._segmentChanged();
  2569. }, enumerable: true });
  2570. window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {
  2571. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
  2572. this._x = x;
  2573. this._y = y;
  2574. };
  2575. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2576. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () {
  2577. return "[object SVGPathSegCurvetoQuadraticSmoothRel]";
  2578. };
  2579. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () {
  2580. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2581. };
  2582. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () {
  2583. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y);
  2584. };
  2585. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { get: function get() {
  2586. return this._x;
  2587. }, set: function set(x) {
  2588. this._x = x;this._segmentChanged();
  2589. }, enumerable: true });
  2590. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { get: function get() {
  2591. return this._y;
  2592. }, set: function set(y) {
  2593. this._y = y;this._segmentChanged();
  2594. }, enumerable: true });
  2595. // Add createSVGPathSeg* functions to window.SVGPathElement.
  2596. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
  2597. window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {
  2598. return new window.SVGPathSegClosePath(undefined);
  2599. };
  2600. window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) {
  2601. return new window.SVGPathSegMovetoAbs(undefined, x, y);
  2602. };
  2603. window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) {
  2604. return new window.SVGPathSegMovetoRel(undefined, x, y);
  2605. };
  2606. window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) {
  2607. return new window.SVGPathSegLinetoAbs(undefined, x, y);
  2608. };
  2609. window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) {
  2610. return new window.SVGPathSegLinetoRel(undefined, x, y);
  2611. };
  2612. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) {
  2613. return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2);
  2614. };
  2615. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) {
  2616. return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2);
  2617. };
  2618. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) {
  2619. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1);
  2620. };
  2621. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) {
  2622. return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1);
  2623. };
  2624. window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2625. return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  2626. };
  2627. window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2628. return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  2629. };
  2630. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) {
  2631. return new window.SVGPathSegLinetoHorizontalAbs(undefined, x);
  2632. };
  2633. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) {
  2634. return new window.SVGPathSegLinetoHorizontalRel(undefined, x);
  2635. };
  2636. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) {
  2637. return new window.SVGPathSegLinetoVerticalAbs(undefined, y);
  2638. };
  2639. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) {
  2640. return new window.SVGPathSegLinetoVerticalRel(undefined, y);
  2641. };
  2642. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) {
  2643. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2);
  2644. };
  2645. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) {
  2646. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2);
  2647. };
  2648. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) {
  2649. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y);
  2650. };
  2651. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) {
  2652. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y);
  2653. };
  2654. if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) {
  2655. // Add getPathSegAtLength to SVGPathElement.
  2656. // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
  2657. // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
  2658. window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {
  2659. if (distance === undefined || !isFinite(distance)) throw "Invalid arguments.";
  2660. var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  2661. measurementElement.setAttribute("d", this.getAttribute("d"));
  2662. var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;
  2663. // If the path is empty, return 0.
  2664. if (lastPathSegment <= 0) return 0;
  2665. do {
  2666. measurementElement.pathSegList.removeItem(lastPathSegment);
  2667. if (distance > measurementElement.getTotalLength()) break;
  2668. lastPathSegment--;
  2669. } while (lastPathSegment > 0);
  2670. return lastPathSegment;
  2671. };
  2672. }
  2673. }
  2674. if (!("SVGPathSegList" in window)) {
  2675. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
  2676. window.SVGPathSegList = function (pathElement) {
  2677. this._pathElement = pathElement;
  2678. this._list = this._parsePath(this._pathElement.getAttribute("d"));
  2679. // Use a MutationObserver to catch changes to the path's "d" attribute.
  2680. this._mutationObserverConfig = { "attributes": true, "attributeFilter": ["d"] };
  2681. this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
  2682. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  2683. };
  2684. window.SVGPathSegList.prototype.classname = "SVGPathSegList";
  2685. Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
  2686. get: function get() {
  2687. this._checkPathSynchronizedToList();
  2688. return this._list.length;
  2689. },
  2690. enumerable: true
  2691. });
  2692. // Add the pathSegList accessors to window.SVGPathElement.
  2693. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
  2694. Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
  2695. get: function get() {
  2696. if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this);
  2697. return this._pathSegList;
  2698. },
  2699. enumerable: true
  2700. });
  2701. // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
  2702. Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { get: function get() {
  2703. return this.pathSegList;
  2704. }, enumerable: true });
  2705. Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { get: function get() {
  2706. return this.pathSegList;
  2707. }, enumerable: true });
  2708. Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { get: function get() {
  2709. return this.pathSegList;
  2710. }, enumerable: true });
  2711. // Process any pending mutations to the path element and update the list as needed.
  2712. // This should be the first call of all public functions and is needed because
  2713. // MutationObservers are not synchronous so we can have pending asynchronous mutations.
  2714. window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {
  2715. this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
  2716. };
  2717. window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {
  2718. if (!this._pathElement) return;
  2719. var hasPathMutations = false;
  2720. mutationRecords.forEach(function (record) {
  2721. if (record.attributeName == "d") hasPathMutations = true;
  2722. });
  2723. if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d"));
  2724. };
  2725. // Serialize the list and update the path's 'd' attribute.
  2726. window.SVGPathSegList.prototype._writeListToPath = function () {
  2727. this._pathElementMutationObserver.disconnect();
  2728. this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
  2729. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  2730. };
  2731. // When a path segment changes the list needs to be synchronized back to the path element.
  2732. window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {
  2733. this._writeListToPath();
  2734. };
  2735. window.SVGPathSegList.prototype.clear = function () {
  2736. this._checkPathSynchronizedToList();
  2737. this._list.forEach(function (pathSeg) {
  2738. pathSeg._owningPathSegList = null;
  2739. });
  2740. this._list = [];
  2741. this._writeListToPath();
  2742. };
  2743. window.SVGPathSegList.prototype.initialize = function (newItem) {
  2744. this._checkPathSynchronizedToList();
  2745. this._list = [newItem];
  2746. newItem._owningPathSegList = this;
  2747. this._writeListToPath();
  2748. return newItem;
  2749. };
  2750. window.SVGPathSegList.prototype._checkValidIndex = function (index) {
  2751. if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR";
  2752. };
  2753. window.SVGPathSegList.prototype.getItem = function (index) {
  2754. this._checkPathSynchronizedToList();
  2755. this._checkValidIndex(index);
  2756. return this._list[index];
  2757. };
  2758. window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {
  2759. this._checkPathSynchronizedToList();
  2760. // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
  2761. if (index > this.numberOfItems) index = this.numberOfItems;
  2762. if (newItem._owningPathSegList) {
  2763. // SVG2 spec says to make a copy.
  2764. newItem = newItem.clone();
  2765. }
  2766. this._list.splice(index, 0, newItem);
  2767. newItem._owningPathSegList = this;
  2768. this._writeListToPath();
  2769. return newItem;
  2770. };
  2771. window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {
  2772. this._checkPathSynchronizedToList();
  2773. if (newItem._owningPathSegList) {
  2774. // SVG2 spec says to make a copy.
  2775. newItem = newItem.clone();
  2776. }
  2777. this._checkValidIndex(index);
  2778. this._list[index] = newItem;
  2779. newItem._owningPathSegList = this;
  2780. this._writeListToPath();
  2781. return newItem;
  2782. };
  2783. window.SVGPathSegList.prototype.removeItem = function (index) {
  2784. this._checkPathSynchronizedToList();
  2785. this._checkValidIndex(index);
  2786. var item = this._list[index];
  2787. this._list.splice(index, 1);
  2788. this._writeListToPath();
  2789. return item;
  2790. };
  2791. window.SVGPathSegList.prototype.appendItem = function (newItem) {
  2792. this._checkPathSynchronizedToList();
  2793. if (newItem._owningPathSegList) {
  2794. // SVG2 spec says to make a copy.
  2795. newItem = newItem.clone();
  2796. }
  2797. this._list.push(newItem);
  2798. newItem._owningPathSegList = this;
  2799. // TODO: Optimize this to just append to the existing attribute.
  2800. this._writeListToPath();
  2801. return newItem;
  2802. };
  2803. window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {
  2804. var string = "";
  2805. var first = true;
  2806. pathSegArray.forEach(function (pathSeg) {
  2807. if (first) {
  2808. first = false;
  2809. string += pathSeg._asPathString();
  2810. } else {
  2811. string += " " + pathSeg._asPathString();
  2812. }
  2813. });
  2814. return string;
  2815. };
  2816. // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
  2817. window.SVGPathSegList.prototype._parsePath = function (string) {
  2818. if (!string || string.length == 0) return [];
  2819. var owningPathSegList = this;
  2820. var Builder = function Builder() {
  2821. this.pathSegList = [];
  2822. };
  2823. Builder.prototype.appendSegment = function (pathSeg) {
  2824. this.pathSegList.push(pathSeg);
  2825. };
  2826. var Source = function Source(string) {
  2827. this._string = string;
  2828. this._currentIndex = 0;
  2829. this._endIndex = this._string.length;
  2830. this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
  2831. this._skipOptionalSpaces();
  2832. };
  2833. Source.prototype._isCurrentSpace = function () {
  2834. var character = this._string[this._currentIndex];
  2835. return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
  2836. };
  2837. Source.prototype._skipOptionalSpaces = function () {
  2838. while (this._currentIndex < this._endIndex && this._isCurrentSpace()) {
  2839. this._currentIndex++;
  2840. }return this._currentIndex < this._endIndex;
  2841. };
  2842. Source.prototype._skipOptionalSpacesOrDelimiter = function () {
  2843. if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false;
  2844. if (this._skipOptionalSpaces()) {
  2845. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
  2846. this._currentIndex++;
  2847. this._skipOptionalSpaces();
  2848. }
  2849. }
  2850. return this._currentIndex < this._endIndex;
  2851. };
  2852. Source.prototype.hasMoreData = function () {
  2853. return this._currentIndex < this._endIndex;
  2854. };
  2855. Source.prototype.peekSegmentType = function () {
  2856. var lookahead = this._string[this._currentIndex];
  2857. return this._pathSegTypeFromChar(lookahead);
  2858. };
  2859. Source.prototype._pathSegTypeFromChar = function (lookahead) {
  2860. switch (lookahead) {
  2861. case "Z":
  2862. case "z":
  2863. return window.SVGPathSeg.PATHSEG_CLOSEPATH;
  2864. case "M":
  2865. return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
  2866. case "m":
  2867. return window.SVGPathSeg.PATHSEG_MOVETO_REL;
  2868. case "L":
  2869. return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  2870. case "l":
  2871. return window.SVGPathSeg.PATHSEG_LINETO_REL;
  2872. case "C":
  2873. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
  2874. case "c":
  2875. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
  2876. case "Q":
  2877. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
  2878. case "q":
  2879. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
  2880. case "A":
  2881. return window.SVGPathSeg.PATHSEG_ARC_ABS;
  2882. case "a":
  2883. return window.SVGPathSeg.PATHSEG_ARC_REL;
  2884. case "H":
  2885. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
  2886. case "h":
  2887. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
  2888. case "V":
  2889. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
  2890. case "v":
  2891. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
  2892. case "S":
  2893. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
  2894. case "s":
  2895. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
  2896. case "T":
  2897. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
  2898. case "t":
  2899. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
  2900. default:
  2901. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  2902. }
  2903. };
  2904. Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {
  2905. // Check for remaining coordinates in the current command.
  2906. if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
  2907. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  2908. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL;
  2909. return previousCommand;
  2910. }
  2911. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  2912. };
  2913. Source.prototype.initialCommandIsMoveTo = function () {
  2914. // If the path is empty it is still valid, so return true.
  2915. if (!this.hasMoreData()) return true;
  2916. var command = this.peekSegmentType();
  2917. // Path must start with moveTo.
  2918. return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
  2919. };
  2920. // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
  2921. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
  2922. Source.prototype._parseNumber = function () {
  2923. var exponent = 0;
  2924. var integer = 0;
  2925. var frac = 1;
  2926. var decimal = 0;
  2927. var sign = 1;
  2928. var expsign = 1;
  2929. var startIndex = this._currentIndex;
  2930. this._skipOptionalSpaces();
  2931. // Read the sign.
  2932. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
  2933. this._currentIndex++;
  2934. sign = -1;
  2935. }
  2936. if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".")
  2937. // The first character of a number must be one of [0-9+-.].
  2938. return undefined;
  2939. // Read the integer part, build right-to-left.
  2940. var startIntPartIndex = this._currentIndex;
  2941. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  2942. this._currentIndex++;
  2943. } // Advance to first non-digit.
  2944. if (this._currentIndex != startIntPartIndex) {
  2945. var scanIntPartIndex = this._currentIndex - 1;
  2946. var multiplier = 1;
  2947. while (scanIntPartIndex >= startIntPartIndex) {
  2948. integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
  2949. multiplier *= 10;
  2950. }
  2951. }
  2952. // Read the decimals.
  2953. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
  2954. this._currentIndex++;
  2955. // There must be a least one digit following the .
  2956. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  2957. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  2958. frac *= 10;
  2959. decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
  2960. this._currentIndex += 1;
  2961. }
  2962. }
  2963. // Read the exponent part.
  2964. 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") {
  2965. this._currentIndex++;
  2966. // Read the sign of the exponent.
  2967. if (this._string.charAt(this._currentIndex) == "+") {
  2968. this._currentIndex++;
  2969. } else if (this._string.charAt(this._currentIndex) == "-") {
  2970. this._currentIndex++;
  2971. expsign = -1;
  2972. }
  2973. // There must be an exponent.
  2974. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  2975. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  2976. exponent *= 10;
  2977. exponent += this._string.charAt(this._currentIndex) - "0";
  2978. this._currentIndex++;
  2979. }
  2980. }
  2981. var number = integer + decimal;
  2982. number *= sign;
  2983. if (exponent) number *= Math.pow(10, expsign * exponent);
  2984. if (startIndex == this._currentIndex) return undefined;
  2985. this._skipOptionalSpacesOrDelimiter();
  2986. return number;
  2987. };
  2988. Source.prototype._parseArcFlag = function () {
  2989. if (this._currentIndex >= this._endIndex) return undefined;
  2990. var flag = false;
  2991. var flagChar = this._string.charAt(this._currentIndex++);
  2992. if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined;
  2993. this._skipOptionalSpacesOrDelimiter();
  2994. return flag;
  2995. };
  2996. Source.prototype.parseSegment = function () {
  2997. var lookahead = this._string[this._currentIndex];
  2998. var command = this._pathSegTypeFromChar(lookahead);
  2999. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
  3000. // Possibly an implicit command. Not allowed if this is the first command.
  3001. if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  3002. command = this._nextCommandHelper(lookahead, this._previousCommand);
  3003. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  3004. } else {
  3005. this._currentIndex++;
  3006. }
  3007. this._previousCommand = command;
  3008. switch (command) {
  3009. case window.SVGPathSeg.PATHSEG_MOVETO_REL:
  3010. return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3011. case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
  3012. return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3013. case window.SVGPathSeg.PATHSEG_LINETO_REL:
  3014. return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3015. case window.SVGPathSeg.PATHSEG_LINETO_ABS:
  3016. return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3017. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
  3018. return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
  3019. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
  3020. return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
  3021. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
  3022. return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
  3023. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
  3024. return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
  3025. case window.SVGPathSeg.PATHSEG_CLOSEPATH:
  3026. this._skipOptionalSpaces();
  3027. return new window.SVGPathSegClosePath(owningPathSegList);
  3028. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
  3029. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  3030. return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  3031. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
  3032. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  3033. return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  3034. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
  3035. var points = { x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  3036. return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
  3037. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
  3038. var points = { x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  3039. return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
  3040. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
  3041. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  3042. return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
  3043. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
  3044. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  3045. return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
  3046. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
  3047. return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3048. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
  3049. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3050. case window.SVGPathSeg.PATHSEG_ARC_REL:
  3051. var points = { x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber() };
  3052. return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  3053. case window.SVGPathSeg.PATHSEG_ARC_ABS:
  3054. var points = { x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber() };
  3055. return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  3056. default:
  3057. throw "Unknown path seg type.";
  3058. }
  3059. };
  3060. var builder = new Builder();
  3061. var source = new Source(string);
  3062. if (!source.initialCommandIsMoveTo()) return [];
  3063. while (source.hasMoreData()) {
  3064. var pathSeg = source.parseSegment();
  3065. if (!pathSeg) return [];
  3066. builder.appendSegment(pathSeg);
  3067. }
  3068. return builder.pathSegList;
  3069. };
  3070. }
  3071. })();
  3072. /* jshint ignore:end */
  3073. c3_chart_fn.axis = function () {};
  3074. c3_chart_fn.axis.labels = function (labels) {
  3075. var $$ = this.internal;
  3076. if (arguments.length) {
  3077. Object.keys(labels).forEach(function (axisId) {
  3078. $$.axis.setLabelText(axisId, labels[axisId]);
  3079. });
  3080. $$.axis.updateLabels();
  3081. }
  3082. // TODO: return some values?
  3083. };
  3084. c3_chart_fn.axis.max = function (max) {
  3085. var $$ = this.internal,
  3086. config = $$.config;
  3087. if (arguments.length) {
  3088. if ((typeof max === 'undefined' ? 'undefined' : _typeof(max)) === 'object') {
  3089. if (isValue(max.x)) {
  3090. config.axis_x_max = max.x;
  3091. }
  3092. if (isValue(max.y)) {
  3093. config.axis_y_max = max.y;
  3094. }
  3095. if (isValue(max.y2)) {
  3096. config.axis_y2_max = max.y2;
  3097. }
  3098. } else {
  3099. config.axis_y_max = config.axis_y2_max = max;
  3100. }
  3101. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3102. } else {
  3103. return {
  3104. x: config.axis_x_max,
  3105. y: config.axis_y_max,
  3106. y2: config.axis_y2_max
  3107. };
  3108. }
  3109. };
  3110. c3_chart_fn.axis.min = function (min) {
  3111. var $$ = this.internal,
  3112. config = $$.config;
  3113. if (arguments.length) {
  3114. if ((typeof min === 'undefined' ? 'undefined' : _typeof(min)) === 'object') {
  3115. if (isValue(min.x)) {
  3116. config.axis_x_min = min.x;
  3117. }
  3118. if (isValue(min.y)) {
  3119. config.axis_y_min = min.y;
  3120. }
  3121. if (isValue(min.y2)) {
  3122. config.axis_y2_min = min.y2;
  3123. }
  3124. } else {
  3125. config.axis_y_min = config.axis_y2_min = min;
  3126. }
  3127. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3128. } else {
  3129. return {
  3130. x: config.axis_x_min,
  3131. y: config.axis_y_min,
  3132. y2: config.axis_y2_min
  3133. };
  3134. }
  3135. };
  3136. c3_chart_fn.axis.range = function (range) {
  3137. if (arguments.length) {
  3138. if (isDefined(range.max)) {
  3139. this.axis.max(range.max);
  3140. }
  3141. if (isDefined(range.min)) {
  3142. this.axis.min(range.min);
  3143. }
  3144. } else {
  3145. return {
  3146. max: this.axis.max(),
  3147. min: this.axis.min()
  3148. };
  3149. }
  3150. };
  3151. c3_chart_fn.category = function (i, category) {
  3152. var $$ = this.internal,
  3153. config = $$.config;
  3154. if (arguments.length > 1) {
  3155. config.axis_x_categories[i] = category;
  3156. $$.redraw();
  3157. }
  3158. return config.axis_x_categories[i];
  3159. };
  3160. c3_chart_fn.categories = function (categories) {
  3161. var $$ = this.internal,
  3162. config = $$.config;
  3163. if (!arguments.length) {
  3164. return config.axis_x_categories;
  3165. }
  3166. config.axis_x_categories = categories;
  3167. $$.redraw();
  3168. return config.axis_x_categories;
  3169. };
  3170. c3_chart_fn.resize = function (size) {
  3171. var $$ = this.internal,
  3172. config = $$.config;
  3173. config.size_width = size ? size.width : null;
  3174. config.size_height = size ? size.height : null;
  3175. this.flush();
  3176. };
  3177. c3_chart_fn.flush = function () {
  3178. var $$ = this.internal;
  3179. $$.updateAndRedraw({ withLegend: true, withTransition: false, withTransitionForTransform: false });
  3180. };
  3181. c3_chart_fn.destroy = function () {
  3182. var $$ = this.internal;
  3183. window.clearInterval($$.intervalForObserveInserted);
  3184. if ($$.resizeTimeout !== undefined) {
  3185. window.clearTimeout($$.resizeTimeout);
  3186. }
  3187. if (window.detachEvent) {
  3188. window.detachEvent('onresize', $$.resizeIfElementDisplayed);
  3189. } else if (window.removeEventListener) {
  3190. window.removeEventListener('resize', $$.resizeIfElementDisplayed);
  3191. } else {
  3192. var wrapper = window.onresize;
  3193. // check if no one else removed our wrapper and remove our resizeFunction from it
  3194. if (wrapper && wrapper.add && wrapper.remove) {
  3195. wrapper.remove($$.resizeFunction);
  3196. }
  3197. }
  3198. // remove the inner resize functions
  3199. $$.resizeFunction.remove();
  3200. $$.selectChart.classed('c3', false).html("");
  3201. // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.
  3202. Object.keys($$).forEach(function (key) {
  3203. $$[key] = null;
  3204. });
  3205. return null;
  3206. };
  3207. // TODO: fix
  3208. c3_chart_fn.color = function (id) {
  3209. var $$ = this.internal;
  3210. return $$.color(id); // more patterns
  3211. };
  3212. c3_chart_fn.data = function (targetIds) {
  3213. var targets = this.internal.data.targets;
  3214. return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) {
  3215. return [].concat(targetIds).indexOf(t.id) >= 0;
  3216. });
  3217. };
  3218. c3_chart_fn.data.shown = function (targetIds) {
  3219. return this.internal.filterTargetsToShow(this.data(targetIds));
  3220. };
  3221. c3_chart_fn.data.values = function (targetId) {
  3222. var targets,
  3223. values = null;
  3224. if (targetId) {
  3225. targets = this.data(targetId);
  3226. values = targets[0] ? targets[0].values.map(function (d) {
  3227. return d.value;
  3228. }) : null;
  3229. }
  3230. return values;
  3231. };
  3232. c3_chart_fn.data.names = function (names) {
  3233. this.internal.clearLegendItemTextBoxCache();
  3234. return this.internal.updateDataAttributes('names', names);
  3235. };
  3236. c3_chart_fn.data.colors = function (colors) {
  3237. return this.internal.updateDataAttributes('colors', colors);
  3238. };
  3239. c3_chart_fn.data.axes = function (axes) {
  3240. return this.internal.updateDataAttributes('axes', axes);
  3241. };
  3242. c3_chart_fn.flow = function (args) {
  3243. var $$ = this.internal,
  3244. targets,
  3245. data,
  3246. notfoundIds = [],
  3247. orgDataCount = $$.getMaxDataCount(),
  3248. dataCount,
  3249. domain,
  3250. baseTarget,
  3251. baseValue,
  3252. length = 0,
  3253. tail = 0,
  3254. diff,
  3255. to;
  3256. if (args.json) {
  3257. data = $$.convertJsonToData(args.json, args.keys);
  3258. } else if (args.rows) {
  3259. data = $$.convertRowsToData(args.rows);
  3260. } else if (args.columns) {
  3261. data = $$.convertColumnsToData(args.columns);
  3262. } else {
  3263. return;
  3264. }
  3265. targets = $$.convertDataToTargets(data, true);
  3266. // Update/Add data
  3267. $$.data.targets.forEach(function (t) {
  3268. var found = false,
  3269. i,
  3270. j;
  3271. for (i = 0; i < targets.length; i++) {
  3272. if (t.id === targets[i].id) {
  3273. found = true;
  3274. if (t.values[t.values.length - 1]) {
  3275. tail = t.values[t.values.length - 1].index + 1;
  3276. }
  3277. length = targets[i].values.length;
  3278. for (j = 0; j < length; j++) {
  3279. targets[i].values[j].index = tail + j;
  3280. if (!$$.isTimeSeries()) {
  3281. targets[i].values[j].x = tail + j;
  3282. }
  3283. }
  3284. t.values = t.values.concat(targets[i].values);
  3285. targets.splice(i, 1);
  3286. break;
  3287. }
  3288. }
  3289. if (!found) {
  3290. notfoundIds.push(t.id);
  3291. }
  3292. });
  3293. // Append null for not found targets
  3294. $$.data.targets.forEach(function (t) {
  3295. var i, j;
  3296. for (i = 0; i < notfoundIds.length; i++) {
  3297. if (t.id === notfoundIds[i]) {
  3298. tail = t.values[t.values.length - 1].index + 1;
  3299. for (j = 0; j < length; j++) {
  3300. t.values.push({
  3301. id: t.id,
  3302. index: tail + j,
  3303. x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
  3304. value: null
  3305. });
  3306. }
  3307. }
  3308. }
  3309. });
  3310. // Generate null values for new target
  3311. if ($$.data.targets.length) {
  3312. targets.forEach(function (t) {
  3313. var i,
  3314. missing = [];
  3315. for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
  3316. missing.push({
  3317. id: t.id,
  3318. index: i,
  3319. x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
  3320. value: null
  3321. });
  3322. }
  3323. t.values.forEach(function (v) {
  3324. v.index += tail;
  3325. if (!$$.isTimeSeries()) {
  3326. v.x += tail;
  3327. }
  3328. });
  3329. t.values = missing.concat(t.values);
  3330. });
  3331. }
  3332. $$.data.targets = $$.data.targets.concat(targets); // add remained
  3333. // check data count because behavior needs to change when it's only one
  3334. dataCount = $$.getMaxDataCount();
  3335. baseTarget = $$.data.targets[0];
  3336. baseValue = baseTarget.values[0];
  3337. // Update length to flow if needed
  3338. if (isDefined(args.to)) {
  3339. length = 0;
  3340. to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
  3341. baseTarget.values.forEach(function (v) {
  3342. if (v.x < to) {
  3343. length++;
  3344. }
  3345. });
  3346. } else if (isDefined(args.length)) {
  3347. length = args.length;
  3348. }
  3349. // If only one data, update the domain to flow from left edge of the chart
  3350. if (!orgDataCount) {
  3351. if ($$.isTimeSeries()) {
  3352. if (baseTarget.values.length > 1) {
  3353. diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
  3354. } else {
  3355. diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
  3356. }
  3357. } else {
  3358. diff = 1;
  3359. }
  3360. domain = [baseValue.x - diff, baseValue.x];
  3361. $$.updateXDomain(null, true, true, false, domain);
  3362. } else if (orgDataCount === 1) {
  3363. if ($$.isTimeSeries()) {
  3364. diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
  3365. domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
  3366. $$.updateXDomain(null, true, true, false, domain);
  3367. }
  3368. }
  3369. // Set targets
  3370. $$.updateTargets($$.data.targets);
  3371. // Redraw with new targets
  3372. $$.redraw({
  3373. flow: {
  3374. index: baseValue.index,
  3375. length: length,
  3376. duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
  3377. done: args.done,
  3378. orgDataCount: orgDataCount
  3379. },
  3380. withLegend: true,
  3381. withTransition: orgDataCount > 1,
  3382. withTrimXDomain: false,
  3383. withUpdateXAxis: true
  3384. });
  3385. };
  3386. c3_chart_internal_fn.generateFlow = function (args) {
  3387. var $$ = this,
  3388. config = $$.config,
  3389. d3 = $$.d3;
  3390. return function () {
  3391. var targets = args.targets,
  3392. flow = args.flow,
  3393. drawBar = args.drawBar,
  3394. drawLine = args.drawLine,
  3395. drawArea = args.drawArea,
  3396. cx = args.cx,
  3397. cy = args.cy,
  3398. xv = args.xv,
  3399. xForText = args.xForText,
  3400. yForText = args.yForText,
  3401. duration = args.duration;
  3402. var translateX,
  3403. scaleX = 1,
  3404. transform,
  3405. flowIndex = flow.index,
  3406. flowLength = flow.length,
  3407. flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),
  3408. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength),
  3409. orgDomain = $$.x.domain(),
  3410. domain,
  3411. durationForFlow = flow.duration || duration,
  3412. done = flow.done || function () {},
  3413. wait = $$.generateWait();
  3414. var xgrid, xgridLines, mainRegion, mainText, mainBar, mainLine, mainArea, mainCircle;
  3415. // set flag
  3416. $$.flowing = true;
  3417. // remove head data after rendered
  3418. $$.data.targets.forEach(function (d) {
  3419. d.values.splice(0, flowLength);
  3420. });
  3421. // update x domain to generate axis elements for flow
  3422. domain = $$.updateXDomain(targets, true, true);
  3423. // update elements related to x scale
  3424. if ($$.updateXGrid) {
  3425. $$.updateXGrid(true);
  3426. }
  3427. xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid
  3428. xgridLines = $$.xgridLines || d3.selectAll([]);
  3429. mainRegion = $$.mainRegion || d3.selectAll([]);
  3430. mainText = $$.mainText || d3.selectAll([]);
  3431. mainBar = $$.mainBar || d3.selectAll([]);
  3432. mainLine = $$.mainLine || d3.selectAll([]);
  3433. mainArea = $$.mainArea || d3.selectAll([]);
  3434. mainCircle = $$.mainCircle || d3.selectAll([]);
  3435. // generate transform to flow
  3436. if (!flow.orgDataCount) {
  3437. // if empty
  3438. if ($$.data.targets[0].values.length !== 1) {
  3439. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3440. } else {
  3441. if ($$.isTimeSeries()) {
  3442. flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);
  3443. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);
  3444. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3445. } else {
  3446. translateX = diffDomain(domain) / 2;
  3447. }
  3448. }
  3449. } else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {
  3450. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3451. } else {
  3452. if ($$.isTimeSeries()) {
  3453. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3454. } else {
  3455. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3456. }
  3457. }
  3458. scaleX = diffDomain(orgDomain) / diffDomain(domain);
  3459. transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';
  3460. $$.hideXGridFocus();
  3461. var flowTransition = d3.transition().ease(d3.easeLinear).duration(durationForFlow);
  3462. wait.add($$.xAxis($$.axes.x, flowTransition));
  3463. wait.add(mainBar.transition(flowTransition).attr('transform', transform));
  3464. wait.add(mainLine.transition(flowTransition).attr('transform', transform));
  3465. wait.add(mainArea.transition(flowTransition).attr('transform', transform));
  3466. wait.add(mainCircle.transition(flowTransition).attr('transform', transform));
  3467. wait.add(mainText.transition(flowTransition).attr('transform', transform));
  3468. wait.add(mainRegion.filter($$.isRegionOnX).transition(flowTransition).attr('transform', transform));
  3469. wait.add(xgrid.transition(flowTransition).attr('transform', transform));
  3470. wait.add(xgridLines.transition(flowTransition).attr('transform', transform));
  3471. wait(function () {
  3472. var i,
  3473. shapes = [],
  3474. texts = [];
  3475. // remove flowed elements
  3476. if (flowLength) {
  3477. for (i = 0; i < flowLength; i++) {
  3478. shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));
  3479. texts.push('.' + CLASS.text + '-' + (flowIndex + i));
  3480. }
  3481. $$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove();
  3482. $$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove();
  3483. $$.svg.select('.' + CLASS.xgrid).remove();
  3484. }
  3485. // draw again for removing flowed elements and reverting attr
  3486. xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity);
  3487. xgridLines.attr('transform', null);
  3488. xgridLines.select('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv);
  3489. xgridLines.select('text').attr("x", config.axis_rotated ? $$.width : 0).attr("y", xv);
  3490. mainBar.attr('transform', null).attr("d", drawBar);
  3491. mainLine.attr('transform', null).attr("d", drawLine);
  3492. mainArea.attr('transform', null).attr("d", drawArea);
  3493. mainCircle.attr('transform', null).attr("cx", cx).attr("cy", cy);
  3494. mainText.attr('transform', null).attr('x', xForText).attr('y', yForText).style('fill-opacity', $$.opacityForText.bind($$));
  3495. mainRegion.attr('transform', null);
  3496. mainRegion.filter($$.isRegionOnX).attr("x", $$.regionX.bind($$)).attr("width", $$.regionWidth.bind($$));
  3497. // callback for end of flow
  3498. done();
  3499. $$.flowing = false;
  3500. });
  3501. };
  3502. };
  3503. c3_chart_fn.focus = function (targetIds) {
  3504. var $$ = this.internal,
  3505. candidates;
  3506. targetIds = $$.mapToTargetIds(targetIds);
  3507. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), this.revert();
  3508. this.defocus();
  3509. candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);
  3510. if ($$.hasArcType()) {
  3511. $$.expandArc(targetIds);
  3512. }
  3513. $$.toggleFocusLegend(targetIds, true);
  3514. $$.focusedTargetIds = targetIds;
  3515. $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) {
  3516. return targetIds.indexOf(id) < 0;
  3517. });
  3518. };
  3519. c3_chart_fn.defocus = function (targetIds) {
  3520. var $$ = this.internal,
  3521. candidates;
  3522. targetIds = $$.mapToTargetIds(targetIds);
  3523. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);
  3524. if ($$.hasArcType()) {
  3525. $$.unexpandArc(targetIds);
  3526. }
  3527. $$.toggleFocusLegend(targetIds, false);
  3528. $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) {
  3529. return targetIds.indexOf(id) < 0;
  3530. });
  3531. $$.defocusedTargetIds = targetIds;
  3532. };
  3533. c3_chart_fn.revert = function (targetIds) {
  3534. var $$ = this.internal,
  3535. candidates;
  3536. targetIds = $$.mapToTargetIds(targetIds);
  3537. candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets
  3538. candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);
  3539. if ($$.hasArcType()) {
  3540. $$.unexpandArc(targetIds);
  3541. }
  3542. if ($$.config.legend_show) {
  3543. $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));
  3544. $$.legend.selectAll($$.selectorLegends(targetIds)).filter(function () {
  3545. return $$.d3.select(this).classed(CLASS.legendItemFocused);
  3546. }).classed(CLASS.legendItemFocused, false);
  3547. }
  3548. $$.focusedTargetIds = [];
  3549. $$.defocusedTargetIds = [];
  3550. };
  3551. c3_chart_fn.xgrids = function (grids) {
  3552. var $$ = this.internal,
  3553. config = $$.config;
  3554. if (!grids) {
  3555. return config.grid_x_lines;
  3556. }
  3557. config.grid_x_lines = grids;
  3558. $$.redrawWithoutRescale();
  3559. return config.grid_x_lines;
  3560. };
  3561. c3_chart_fn.xgrids.add = function (grids) {
  3562. var $$ = this.internal;
  3563. return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []));
  3564. };
  3565. c3_chart_fn.xgrids.remove = function (params) {
  3566. // TODO: multiple
  3567. var $$ = this.internal;
  3568. $$.removeGridLines(params, true);
  3569. };
  3570. c3_chart_fn.ygrids = function (grids) {
  3571. var $$ = this.internal,
  3572. config = $$.config;
  3573. if (!grids) {
  3574. return config.grid_y_lines;
  3575. }
  3576. config.grid_y_lines = grids;
  3577. $$.redrawWithoutRescale();
  3578. return config.grid_y_lines;
  3579. };
  3580. c3_chart_fn.ygrids.add = function (grids) {
  3581. var $$ = this.internal;
  3582. return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []));
  3583. };
  3584. c3_chart_fn.ygrids.remove = function (params) {
  3585. // TODO: multiple
  3586. var $$ = this.internal;
  3587. $$.removeGridLines(params, false);
  3588. };
  3589. c3_chart_fn.groups = function (groups) {
  3590. var $$ = this.internal,
  3591. config = $$.config;
  3592. if (isUndefined(groups)) {
  3593. return config.data_groups;
  3594. }
  3595. config.data_groups = groups;
  3596. $$.redraw();
  3597. return config.data_groups;
  3598. };
  3599. c3_chart_fn.legend = function () {};
  3600. c3_chart_fn.legend.show = function (targetIds) {
  3601. var $$ = this.internal;
  3602. $$.showLegend($$.mapToTargetIds(targetIds));
  3603. $$.updateAndRedraw({ withLegend: true });
  3604. };
  3605. c3_chart_fn.legend.hide = function (targetIds) {
  3606. var $$ = this.internal;
  3607. $$.hideLegend($$.mapToTargetIds(targetIds));
  3608. $$.updateAndRedraw({ withLegend: true });
  3609. };
  3610. c3_chart_fn.load = function (args) {
  3611. var $$ = this.internal,
  3612. config = $$.config;
  3613. // update xs if specified
  3614. if (args.xs) {
  3615. $$.addXs(args.xs);
  3616. }
  3617. // update names if exists
  3618. if ('names' in args) {
  3619. c3_chart_fn.data.names.bind(this)(args.names);
  3620. }
  3621. // update classes if exists
  3622. if ('classes' in args) {
  3623. Object.keys(args.classes).forEach(function (id) {
  3624. config.data_classes[id] = args.classes[id];
  3625. });
  3626. }
  3627. // update categories if exists
  3628. if ('categories' in args && $$.isCategorized()) {
  3629. config.axis_x_categories = args.categories;
  3630. }
  3631. // update axes if exists
  3632. if ('axes' in args) {
  3633. Object.keys(args.axes).forEach(function (id) {
  3634. config.data_axes[id] = args.axes[id];
  3635. });
  3636. }
  3637. // update colors if exists
  3638. if ('colors' in args) {
  3639. Object.keys(args.colors).forEach(function (id) {
  3640. config.data_colors[id] = args.colors[id];
  3641. });
  3642. }
  3643. // use cache if exists
  3644. if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {
  3645. $$.load($$.getCaches(args.cacheIds), args.done);
  3646. return;
  3647. }
  3648. // unload if needed
  3649. if ('unload' in args) {
  3650. // TODO: do not unload if target will load (included in url/rows/columns)
  3651. $$.unload($$.mapToTargetIds(typeof args.unload === 'boolean' && args.unload ? null : args.unload), function () {
  3652. $$.loadFromArgs(args);
  3653. });
  3654. } else {
  3655. $$.loadFromArgs(args);
  3656. }
  3657. };
  3658. c3_chart_fn.unload = function (args) {
  3659. var $$ = this.internal;
  3660. args = args || {};
  3661. if (args instanceof Array) {
  3662. args = { ids: args };
  3663. } else if (typeof args === 'string') {
  3664. args = { ids: [args] };
  3665. }
  3666. $$.unload($$.mapToTargetIds(args.ids), function () {
  3667. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  3668. if (args.done) {
  3669. args.done();
  3670. }
  3671. });
  3672. };
  3673. c3_chart_fn.regions = function (regions) {
  3674. var $$ = this.internal,
  3675. config = $$.config;
  3676. if (!regions) {
  3677. return config.regions;
  3678. }
  3679. config.regions = regions;
  3680. $$.redrawWithoutRescale();
  3681. return config.regions;
  3682. };
  3683. c3_chart_fn.regions.add = function (regions) {
  3684. var $$ = this.internal,
  3685. config = $$.config;
  3686. if (!regions) {
  3687. return config.regions;
  3688. }
  3689. config.regions = config.regions.concat(regions);
  3690. $$.redrawWithoutRescale();
  3691. return config.regions;
  3692. };
  3693. c3_chart_fn.regions.remove = function (options) {
  3694. var $$ = this.internal,
  3695. config = $$.config,
  3696. duration,
  3697. classes,
  3698. regions;
  3699. options = options || {};
  3700. duration = $$.getOption(options, "duration", config.transition_duration);
  3701. classes = $$.getOption(options, "classes", [CLASS.region]);
  3702. regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) {
  3703. return '.' + c;
  3704. }));
  3705. (duration ? regions.transition().duration(duration) : regions).style('opacity', 0).remove();
  3706. config.regions = config.regions.filter(function (region) {
  3707. var found = false;
  3708. if (!region['class']) {
  3709. return true;
  3710. }
  3711. region['class'].split(' ').forEach(function (c) {
  3712. if (classes.indexOf(c) >= 0) {
  3713. found = true;
  3714. }
  3715. });
  3716. return !found;
  3717. });
  3718. return config.regions;
  3719. };
  3720. c3_chart_fn.selected = function (targetId) {
  3721. var $$ = this.internal,
  3722. d3 = $$.d3;
  3723. return d3.merge($$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape).filter(function () {
  3724. return d3.select(this).classed(CLASS.SELECTED);
  3725. }).map(function (d) {
  3726. return d.map(function (d) {
  3727. var data = d.__data__;return data.data ? data.data : data;
  3728. });
  3729. }));
  3730. };
  3731. c3_chart_fn.select = function (ids, indices, resetOther) {
  3732. var $$ = this.internal,
  3733. d3 = $$.d3,
  3734. config = $$.config;
  3735. if (!config.data_selection_enabled) {
  3736. return;
  3737. }
  3738. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  3739. var shape = d3.select(this),
  3740. id = d.data ? d.data.id : d.id,
  3741. toggle = $$.getToggle(this, d).bind($$),
  3742. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  3743. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  3744. isSelected = shape.classed(CLASS.SELECTED);
  3745. // line/area selection not supported yet
  3746. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  3747. return;
  3748. }
  3749. if (isTargetId && isTargetIndex) {
  3750. if (config.data_selection_isselectable(d) && !isSelected) {
  3751. toggle(true, shape.classed(CLASS.SELECTED, true), d, i);
  3752. }
  3753. } else if (isDefined(resetOther) && resetOther) {
  3754. if (isSelected) {
  3755. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  3756. }
  3757. }
  3758. });
  3759. };
  3760. c3_chart_fn.unselect = function (ids, indices) {
  3761. var $$ = this.internal,
  3762. d3 = $$.d3,
  3763. config = $$.config;
  3764. if (!config.data_selection_enabled) {
  3765. return;
  3766. }
  3767. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  3768. var shape = d3.select(this),
  3769. id = d.data ? d.data.id : d.id,
  3770. toggle = $$.getToggle(this, d).bind($$),
  3771. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  3772. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  3773. isSelected = shape.classed(CLASS.SELECTED);
  3774. // line/area selection not supported yet
  3775. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  3776. return;
  3777. }
  3778. if (isTargetId && isTargetIndex) {
  3779. if (config.data_selection_isselectable(d)) {
  3780. if (isSelected) {
  3781. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  3782. }
  3783. }
  3784. }
  3785. });
  3786. };
  3787. c3_chart_fn.show = function (targetIds, options) {
  3788. var $$ = this.internal,
  3789. targets;
  3790. targetIds = $$.mapToTargetIds(targetIds);
  3791. options = options || {};
  3792. $$.removeHiddenTargetIds(targetIds);
  3793. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  3794. targets.transition().style('opacity', 1, 'important').call($$.endall, function () {
  3795. targets.style('opacity', null).style('opacity', 1);
  3796. });
  3797. if (options.withLegend) {
  3798. $$.showLegend(targetIds);
  3799. }
  3800. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  3801. };
  3802. c3_chart_fn.hide = function (targetIds, options) {
  3803. var $$ = this.internal,
  3804. targets;
  3805. targetIds = $$.mapToTargetIds(targetIds);
  3806. options = options || {};
  3807. $$.addHiddenTargetIds(targetIds);
  3808. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  3809. targets.transition().style('opacity', 0, 'important').call($$.endall, function () {
  3810. targets.style('opacity', null).style('opacity', 0);
  3811. });
  3812. if (options.withLegend) {
  3813. $$.hideLegend(targetIds);
  3814. }
  3815. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  3816. };
  3817. c3_chart_fn.toggle = function (targetIds, options) {
  3818. var that = this,
  3819. $$ = this.internal;
  3820. $$.mapToTargetIds(targetIds).forEach(function (targetId) {
  3821. $$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options);
  3822. });
  3823. };
  3824. c3_chart_fn.tooltip = function () {};
  3825. c3_chart_fn.tooltip.show = function (args) {
  3826. var $$ = this.internal,
  3827. targets,
  3828. data,
  3829. mouse = {};
  3830. // determine mouse position on the chart
  3831. if (args.mouse) {
  3832. mouse = args.mouse;
  3833. } else {
  3834. // determine focus data
  3835. if (args.data) {
  3836. data = args.data;
  3837. } else if (typeof args.x !== 'undefined') {
  3838. if (args.id) {
  3839. targets = $$.data.targets.filter(function (t) {
  3840. return t.id === args.id;
  3841. });
  3842. } else {
  3843. targets = $$.data.targets;
  3844. }
  3845. data = $$.filterByX(targets, args.x).slice(0, 1)[0];
  3846. }
  3847. mouse = data ? $$.getMousePosition(data) : null;
  3848. }
  3849. // emulate mouse events to show
  3850. $$.dispatchEvent('mousemove', mouse);
  3851. $$.config.tooltip_onshow.call($$, data);
  3852. };
  3853. c3_chart_fn.tooltip.hide = function () {
  3854. // TODO: get target data by checking the state of focus
  3855. this.internal.dispatchEvent('mouseout', 0);
  3856. this.internal.config.tooltip_onhide.call(this);
  3857. };
  3858. c3_chart_fn.transform = function (type, targetIds) {
  3859. var $$ = this.internal,
  3860. options = ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;
  3861. $$.transformTo(targetIds, type, options);
  3862. };
  3863. c3_chart_internal_fn.transformTo = function (targetIds, type, optionsForRedraw) {
  3864. var $$ = this,
  3865. withTransitionForAxis = !$$.hasArcType(),
  3866. options = optionsForRedraw || { withTransitionForAxis: withTransitionForAxis };
  3867. options.withTransitionForTransform = false;
  3868. $$.transiting = false;
  3869. $$.setTargetType(targetIds, type);
  3870. $$.updateTargets($$.data.targets); // this is needed when transforming to arc
  3871. $$.updateAndRedraw(options);
  3872. };
  3873. c3_chart_fn.x = function (x) {
  3874. var $$ = this.internal;
  3875. if (arguments.length) {
  3876. $$.updateTargetX($$.data.targets, x);
  3877. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3878. }
  3879. return $$.data.xs;
  3880. };
  3881. c3_chart_fn.xs = function (xs) {
  3882. var $$ = this.internal;
  3883. if (arguments.length) {
  3884. $$.updateTargetXs($$.data.targets, xs);
  3885. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3886. }
  3887. return $$.data.xs;
  3888. };
  3889. c3_chart_fn.zoom = function (domain) {
  3890. var $$ = this.internal;
  3891. if (domain) {
  3892. if ($$.isTimeSeries()) {
  3893. domain = domain.map(function (x) {
  3894. return $$.parseDate(x);
  3895. });
  3896. }
  3897. if ($$.config.subchart_show) {
  3898. $$.brush.selectionAsValue(domain, true);
  3899. } else {
  3900. $$.updateXDomain(null, true, false, false, domain);
  3901. $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });
  3902. }
  3903. $$.config.zoom_onzoom.call(this, $$.x.orgDomain());
  3904. }
  3905. return domain;
  3906. };
  3907. c3_chart_fn.zoom.enable = function (enabled) {
  3908. var $$ = this.internal;
  3909. $$.config.zoom_enabled = enabled;
  3910. $$.updateAndRedraw();
  3911. };
  3912. c3_chart_fn.unzoom = function () {
  3913. var $$ = this.internal;
  3914. if ($$.config.subchart_show) {
  3915. $$.brush.clear();
  3916. } else {
  3917. $$.updateXDomain(null, true, false, false, $$.subX.domain());
  3918. $$.redraw({ withY: $$.config.zoom_rescale, withSubchart: false });
  3919. }
  3920. };
  3921. c3_chart_fn.zoom.max = function (max) {
  3922. var $$ = this.internal,
  3923. config = $$.config,
  3924. d3 = $$.d3;
  3925. if (max === 0 || max) {
  3926. config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);
  3927. } else {
  3928. return config.zoom_x_max;
  3929. }
  3930. };
  3931. c3_chart_fn.zoom.min = function (min) {
  3932. var $$ = this.internal,
  3933. config = $$.config,
  3934. d3 = $$.d3;
  3935. if (min === 0 || min) {
  3936. config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);
  3937. } else {
  3938. return config.zoom_x_min;
  3939. }
  3940. };
  3941. c3_chart_fn.zoom.range = function (range) {
  3942. if (arguments.length) {
  3943. if (isDefined(range.max)) {
  3944. this.domain.max(range.max);
  3945. }
  3946. if (isDefined(range.min)) {
  3947. this.domain.min(range.min);
  3948. }
  3949. } else {
  3950. return {
  3951. max: this.domain.max(),
  3952. min: this.domain.min()
  3953. };
  3954. }
  3955. };
  3956. c3_chart_internal_fn.initPie = function () {
  3957. var $$ = this,
  3958. d3 = $$.d3;
  3959. $$.pie = d3.pie().value(function (d) {
  3960. return d.values.reduce(function (a, b) {
  3961. return a + b.value;
  3962. }, 0);
  3963. });
  3964. var orderFct = $$.getOrderFunction();
  3965. // we need to reverse the returned order if asc or desc to have the slice in expected order.
  3966. if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {
  3967. var defaultSort = orderFct;
  3968. orderFct = function orderFct(t1, t2) {
  3969. return defaultSort(t1, t2) * -1;
  3970. };
  3971. }
  3972. $$.pie.sort(orderFct || null);
  3973. };
  3974. c3_chart_internal_fn.updateRadius = function () {
  3975. var $$ = this,
  3976. config = $$.config,
  3977. w = config.gauge_width || config.donut_width,
  3978. gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length * $$.config.gauge_arcs_minWidth;
  3979. $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2 * ($$.hasType('gauge') ? 0.85 : 1);
  3980. $$.radius = $$.radiusExpanded * 0.95;
  3981. $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;
  3982. $$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0;
  3983. $$.gaugeArcWidth = w ? w : gaugeArcWidth <= $$.radius - $$.innerRadius ? $$.radius - $$.innerRadius : gaugeArcWidth <= $$.radius ? gaugeArcWidth : $$.radius;
  3984. };
  3985. c3_chart_internal_fn.updateArc = function () {
  3986. var $$ = this;
  3987. $$.svgArc = $$.getSvgArc();
  3988. $$.svgArcExpanded = $$.getSvgArcExpanded();
  3989. $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);
  3990. };
  3991. c3_chart_internal_fn.updateAngle = function (d) {
  3992. var $$ = this,
  3993. config = $$.config,
  3994. found = false,
  3995. index = 0,
  3996. gMin,
  3997. gMax,
  3998. gTic,
  3999. gValue;
  4000. if (!config) {
  4001. return null;
  4002. }
  4003. $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) {
  4004. if (!found && t.data.id === d.data.id) {
  4005. found = true;
  4006. d = t;
  4007. d.index = index;
  4008. }
  4009. index++;
  4010. });
  4011. if (isNaN(d.startAngle)) {
  4012. d.startAngle = 0;
  4013. }
  4014. if (isNaN(d.endAngle)) {
  4015. d.endAngle = d.startAngle;
  4016. }
  4017. if ($$.isGaugeType(d.data)) {
  4018. gMin = config.gauge_min;
  4019. gMax = config.gauge_max;
  4020. gTic = Math.PI * (config.gauge_fullCircle ? 2 : 1) / (gMax - gMin);
  4021. gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;
  4022. d.startAngle = config.gauge_startingAngle;
  4023. d.endAngle = d.startAngle + gTic * gValue;
  4024. }
  4025. return found ? d : null;
  4026. };
  4027. c3_chart_internal_fn.getSvgArc = function () {
  4028. var $$ = this,
  4029. hasGaugeType = $$.hasType('gauge'),
  4030. singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,
  4031. arc = $$.d3.arc().outerRadius(function (d) {
  4032. return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius;
  4033. }).innerRadius(function (d) {
  4034. return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius;
  4035. }),
  4036. newArc = function newArc(d, withoutUpdate) {
  4037. var updated;
  4038. if (withoutUpdate) {
  4039. return arc(d);
  4040. } // for interpolate
  4041. updated = $$.updateAngle(d);
  4042. return updated ? arc(updated) : "M 0 0";
  4043. };
  4044. // TODO: extends all function
  4045. newArc.centroid = arc.centroid;
  4046. return newArc;
  4047. };
  4048. c3_chart_internal_fn.getSvgArcExpanded = function (rate) {
  4049. rate = rate || 1;
  4050. var $$ = this,
  4051. hasGaugeType = $$.hasType('gauge'),
  4052. singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,
  4053. expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100),
  4054. arc = $$.d3.arc().outerRadius(function (d) {
  4055. return hasGaugeType ? $$.radius - singleArcWidth * d.index + expandWidth : $$.radiusExpanded * rate;
  4056. }).innerRadius(function (d) {
  4057. return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius;
  4058. });
  4059. return function (d) {
  4060. var updated = $$.updateAngle(d);
  4061. return updated ? arc(updated) : "M 0 0";
  4062. };
  4063. };
  4064. c3_chart_internal_fn.getArc = function (d, withoutUpdate, force) {
  4065. return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0";
  4066. };
  4067. c3_chart_internal_fn.transformForArcLabel = function (d) {
  4068. var $$ = this,
  4069. config = $$.config,
  4070. updated = $$.updateAngle(d),
  4071. c,
  4072. x,
  4073. y,
  4074. h,
  4075. ratio,
  4076. translate = "",
  4077. hasGauge = $$.hasType('gauge');
  4078. if (updated && !hasGauge) {
  4079. c = this.svgArc.centroid(updated);
  4080. x = isNaN(c[0]) ? 0 : c[0];
  4081. y = isNaN(c[1]) ? 0 : c[1];
  4082. h = Math.sqrt(x * x + y * y);
  4083. if ($$.hasType('donut') && config.donut_label_ratio) {
  4084. ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio;
  4085. } else if ($$.hasType('pie') && config.pie_label_ratio) {
  4086. ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio;
  4087. } else {
  4088. ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0;
  4089. }
  4090. translate = "translate(" + x * ratio + ',' + y * ratio + ")";
  4091. } else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) {
  4092. var y1 = Math.sin(updated.endAngle - Math.PI / 2);
  4093. x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25);
  4094. y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3;
  4095. translate = "translate(" + x + ',' + y + ")";
  4096. }
  4097. return translate;
  4098. };
  4099. c3_chart_internal_fn.getArcRatio = function (d) {
  4100. var $$ = this,
  4101. config = $$.config,
  4102. whole = Math.PI * ($$.hasType('gauge') && !config.gauge_fullCircle ? 1 : 2);
  4103. return d ? (d.endAngle - d.startAngle) / whole : null;
  4104. };
  4105. c3_chart_internal_fn.convertToArcData = function (d) {
  4106. return this.addName({
  4107. id: d.data.id,
  4108. value: d.value,
  4109. ratio: this.getArcRatio(d),
  4110. index: d.index
  4111. });
  4112. };
  4113. c3_chart_internal_fn.textForArcLabel = function (d) {
  4114. var $$ = this,
  4115. updated,
  4116. value,
  4117. ratio,
  4118. id,
  4119. format;
  4120. if (!$$.shouldShowArcLabel()) {
  4121. return "";
  4122. }
  4123. updated = $$.updateAngle(d);
  4124. value = updated ? updated.value : null;
  4125. ratio = $$.getArcRatio(updated);
  4126. id = d.data.id;
  4127. if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {
  4128. return "";
  4129. }
  4130. format = $$.getArcLabelFormat();
  4131. return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio);
  4132. };
  4133. c3_chart_internal_fn.textForGaugeMinMax = function (value, isMax) {
  4134. var $$ = this,
  4135. format = $$.getGaugeLabelExtents();
  4136. return format ? format(value, isMax) : value;
  4137. };
  4138. c3_chart_internal_fn.expandArc = function (targetIds) {
  4139. var $$ = this,
  4140. interval;
  4141. // MEMO: avoid to cancel transition
  4142. if ($$.transiting) {
  4143. interval = window.setInterval(function () {
  4144. if (!$$.transiting) {
  4145. window.clearInterval(interval);
  4146. if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {
  4147. $$.expandArc(targetIds);
  4148. }
  4149. }
  4150. }, 10);
  4151. return;
  4152. }
  4153. targetIds = $$.mapToTargetIds(targetIds);
  4154. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).each(function (d) {
  4155. if (!$$.shouldExpand(d.data.id)) {
  4156. return;
  4157. }
  4158. $$.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) {
  4159. if ($$.isDonutType(d.data)) {
  4160. // callback here
  4161. }
  4162. });
  4163. });
  4164. };
  4165. c3_chart_internal_fn.unexpandArc = function (targetIds) {
  4166. var $$ = this;
  4167. if ($$.transiting) {
  4168. return;
  4169. }
  4170. targetIds = $$.mapToTargetIds(targetIds);
  4171. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path').transition().duration(function (d) {
  4172. return $$.expandDuration(d.data.id);
  4173. }).attr("d", $$.svgArc);
  4174. $$.svg.selectAll('.' + CLASS.arc);
  4175. };
  4176. c3_chart_internal_fn.expandDuration = function (id) {
  4177. var $$ = this,
  4178. config = $$.config;
  4179. if ($$.isDonutType(id)) {
  4180. return config.donut_expand_duration;
  4181. } else if ($$.isGaugeType(id)) {
  4182. return config.gauge_expand_duration;
  4183. } else if ($$.isPieType(id)) {
  4184. return config.pie_expand_duration;
  4185. } else {
  4186. return 50;
  4187. }
  4188. };
  4189. c3_chart_internal_fn.shouldExpand = function (id) {
  4190. var $$ = this,
  4191. config = $$.config;
  4192. return $$.isDonutType(id) && config.donut_expand || $$.isGaugeType(id) && config.gauge_expand || $$.isPieType(id) && config.pie_expand;
  4193. };
  4194. c3_chart_internal_fn.shouldShowArcLabel = function () {
  4195. var $$ = this,
  4196. config = $$.config,
  4197. shouldShow = true;
  4198. if ($$.hasType('donut')) {
  4199. shouldShow = config.donut_label_show;
  4200. } else if ($$.hasType('pie')) {
  4201. shouldShow = config.pie_label_show;
  4202. }
  4203. // when gauge, always true
  4204. return shouldShow;
  4205. };
  4206. c3_chart_internal_fn.meetsArcLabelThreshold = function (ratio) {
  4207. var $$ = this,
  4208. config = $$.config,
  4209. threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold;
  4210. return ratio >= threshold;
  4211. };
  4212. c3_chart_internal_fn.getArcLabelFormat = function () {
  4213. var $$ = this,
  4214. config = $$.config,
  4215. format = config.pie_label_format;
  4216. if ($$.hasType('gauge')) {
  4217. format = config.gauge_label_format;
  4218. } else if ($$.hasType('donut')) {
  4219. format = config.donut_label_format;
  4220. }
  4221. return format;
  4222. };
  4223. c3_chart_internal_fn.getGaugeLabelExtents = function () {
  4224. var $$ = this,
  4225. config = $$.config;
  4226. return config.gauge_label_extents;
  4227. };
  4228. c3_chart_internal_fn.getArcTitle = function () {
  4229. var $$ = this;
  4230. return $$.hasType('donut') ? $$.config.donut_title : "";
  4231. };
  4232. c3_chart_internal_fn.updateTargetsForArc = function (targets) {
  4233. var $$ = this,
  4234. main = $$.main,
  4235. mainPies,
  4236. mainPieEnter,
  4237. classChartArc = $$.classChartArc.bind($$),
  4238. classArcs = $$.classArcs.bind($$),
  4239. classFocus = $$.classFocus.bind($$);
  4240. mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr("class", function (d) {
  4241. return classChartArc(d) + classFocus(d.data);
  4242. });
  4243. mainPieEnter = mainPies.enter().append("g").attr("class", classChartArc);
  4244. mainPieEnter.append('g').attr('class', classArcs);
  4245. mainPieEnter.append("text").attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em").style("opacity", 0).style("text-anchor", "middle").style("pointer-events", "none");
  4246. // MEMO: can not keep same color..., but not bad to update color in redraw
  4247. //mainPieUpdate.exit().remove();
  4248. };
  4249. c3_chart_internal_fn.initArc = function () {
  4250. var $$ = this;
  4251. $$.arcs = $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  4252. $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style("text-anchor", "middle").text($$.getArcTitle());
  4253. };
  4254. c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransform) {
  4255. var $$ = this,
  4256. d3 = $$.d3,
  4257. config = $$.config,
  4258. main = $$.main,
  4259. arcs,
  4260. mainArc,
  4261. backgroundArc,
  4262. arcLabelLines,
  4263. mainArcLabelLine,
  4264. hasGaugeType = $$.hasType('gauge');
  4265. arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc).data($$.arcData.bind($$));
  4266. mainArc = arcs.enter().append('path').attr("class", $$.classArc.bind($$)).style("fill", function (d) {
  4267. return $$.color(d.data);
  4268. }).style("cursor", function (d) {
  4269. return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null;
  4270. }).each(function (d) {
  4271. if ($$.isGaugeType(d.data)) {
  4272. d.startAngle = d.endAngle = config.gauge_startingAngle;
  4273. }
  4274. this._current = d;
  4275. }).merge(arcs);
  4276. if (hasGaugeType) {
  4277. arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine).data($$.arcData.bind($$));
  4278. mainArcLabelLine = arcLabelLines.enter().append('rect').attr("class", function (d) {
  4279. return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id;
  4280. }).merge(arcLabelLines);
  4281. if ($$.filterTargetsToShow($$.data.targets).length === 1) {
  4282. mainArcLabelLine.style("display", "none");
  4283. } else {
  4284. mainArcLabelLine.style("fill", function (d) {
  4285. return config.color_pattern.length > 0 ? $$.levelColor(d.data.values[0].value) : $$.color(d.data);
  4286. }).style("display", config.gauge_labelLine_show ? "" : "none").each(function (d) {
  4287. var lineLength = 0,
  4288. lineThickness = 2,
  4289. x = 0,
  4290. y = 0,
  4291. transform = "";
  4292. if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {
  4293. var updated = $$.updateAngle(d),
  4294. innerLineLength = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length * (updated.index + 1),
  4295. lineAngle = updated.endAngle - Math.PI / 2,
  4296. arcInnerRadius = $$.radius - innerLineLength,
  4297. linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius);
  4298. lineLength = $$.radiusExpanded - $$.radius + innerLineLength;
  4299. x = Math.cos(linePositioningAngle) * arcInnerRadius;
  4300. y = Math.sin(linePositioningAngle) * arcInnerRadius;
  4301. transform = "rotate(" + lineAngle * 180 / Math.PI + ", " + x + ", " + y + ")";
  4302. }
  4303. 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");
  4304. });
  4305. }
  4306. }
  4307. mainArc.attr("transform", function (d) {
  4308. return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : "";
  4309. }).on('mouseover', config.interaction_enabled ? function (d) {
  4310. var updated, arcData;
  4311. if ($$.transiting) {
  4312. // skip while transiting
  4313. return;
  4314. }
  4315. updated = $$.updateAngle(d);
  4316. if (updated) {
  4317. arcData = $$.convertToArcData(updated);
  4318. // transitions
  4319. $$.expandArc(updated.data.id);
  4320. $$.api.focus(updated.data.id);
  4321. $$.toggleFocusLegend(updated.data.id, true);
  4322. $$.config.data_onmouseover(arcData, this);
  4323. }
  4324. } : null).on('mousemove', config.interaction_enabled ? function (d) {
  4325. var updated = $$.updateAngle(d),
  4326. arcData,
  4327. selectedData;
  4328. if (updated) {
  4329. arcData = $$.convertToArcData(updated), selectedData = [arcData];
  4330. $$.showTooltip(selectedData, this);
  4331. }
  4332. } : null).on('mouseout', config.interaction_enabled ? function (d) {
  4333. var updated, arcData;
  4334. if ($$.transiting) {
  4335. // skip while transiting
  4336. return;
  4337. }
  4338. updated = $$.updateAngle(d);
  4339. if (updated) {
  4340. arcData = $$.convertToArcData(updated);
  4341. // transitions
  4342. $$.unexpandArc(updated.data.id);
  4343. $$.api.revert();
  4344. $$.revertLegend();
  4345. $$.hideTooltip();
  4346. $$.config.data_onmouseout(arcData, this);
  4347. }
  4348. } : null).on('click', config.interaction_enabled ? function (d, i) {
  4349. var updated = $$.updateAngle(d),
  4350. arcData;
  4351. if (updated) {
  4352. arcData = $$.convertToArcData(updated);
  4353. if ($$.toggleShape) {
  4354. $$.toggleShape(this, arcData, i);
  4355. }
  4356. $$.config.data_onclick.call($$.api, arcData, this);
  4357. }
  4358. } : null).each(function () {
  4359. $$.transiting = true;
  4360. }).transition().duration(duration).attrTween("d", function (d) {
  4361. var updated = $$.updateAngle(d),
  4362. interpolate;
  4363. if (!updated) {
  4364. return function () {
  4365. return "M 0 0";
  4366. };
  4367. }
  4368. // if (this._current === d) {
  4369. // this._current = {
  4370. // startAngle: Math.PI*2,
  4371. // endAngle: Math.PI*2,
  4372. // };
  4373. // }
  4374. if (isNaN(this._current.startAngle)) {
  4375. this._current.startAngle = 0;
  4376. }
  4377. if (isNaN(this._current.endAngle)) {
  4378. this._current.endAngle = this._current.startAngle;
  4379. }
  4380. interpolate = d3.interpolate(this._current, updated);
  4381. this._current = interpolate(0);
  4382. return function (t) {
  4383. var interpolated = interpolate(t);
  4384. interpolated.data = d.data; // data.id will be updated by interporator
  4385. return $$.getArc(interpolated, true);
  4386. };
  4387. }).attr("transform", withTransform ? "scale(1)" : "").style("fill", function (d) {
  4388. return $$.levelColor ? $$.levelColor(d.data.values[0].value) : $$.color(d.data.id);
  4389. }) // Where gauge reading color would receive customization.
  4390. .call($$.endall, function () {
  4391. $$.transiting = false;
  4392. });
  4393. arcs.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  4394. main.selectAll('.' + CLASS.chartArc).select('text').style("opacity", 0).attr('class', function (d) {
  4395. return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '';
  4396. }).text($$.textForArcLabel.bind($$)).attr("transform", $$.transformForArcLabel.bind($$)).style('font-size', function (d) {
  4397. return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : '';
  4398. }).transition().duration(duration).style("opacity", function (d) {
  4399. return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0;
  4400. });
  4401. main.select('.' + CLASS.chartArcsTitle).style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0);
  4402. if (hasGaugeType) {
  4403. var index = 0;
  4404. backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets);
  4405. backgroundArc.enter().append("path");
  4406. backgroundArc.attr("class", function (d, i) {
  4407. return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i;
  4408. }).attr("d", function (d1) {
  4409. if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {
  4410. return "M 0 0";
  4411. }
  4412. var d = {
  4413. data: [{ value: config.gauge_max }],
  4414. startAngle: config.gauge_startingAngle,
  4415. endAngle: -1 * config.gauge_startingAngle * (config.gauge_fullCircle ? Math.PI : 1),
  4416. index: index++
  4417. };
  4418. return $$.getArc(d, true, true);
  4419. });
  4420. backgroundArc.exit().remove();
  4421. $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr("dy", ".75em").text(config.gauge_label_show ? config.gauge_units : '');
  4422. $$.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) : '');
  4423. $$.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) : '');
  4424. }
  4425. };
  4426. c3_chart_internal_fn.initGauge = function () {
  4427. var arcs = this.arcs;
  4428. if (this.hasType('gauge')) {
  4429. arcs.append('g').attr("class", CLASS.chartArcsBackground);
  4430. arcs.append("text").attr("class", CLASS.chartArcsGaugeUnit).style("text-anchor", "middle").style("pointer-events", "none");
  4431. arcs.append("text").attr("class", CLASS.chartArcsGaugeMin).style("text-anchor", "middle").style("pointer-events", "none");
  4432. arcs.append("text").attr("class", CLASS.chartArcsGaugeMax).style("text-anchor", "middle").style("pointer-events", "none");
  4433. }
  4434. };
  4435. c3_chart_internal_fn.getGaugeLabelHeight = function () {
  4436. return this.config.gauge_label_show ? 20 : 0;
  4437. };
  4438. c3_chart_internal_fn.hasCaches = function (ids) {
  4439. for (var i = 0; i < ids.length; i++) {
  4440. if (!(ids[i] in this.cache)) {
  4441. return false;
  4442. }
  4443. }
  4444. return true;
  4445. };
  4446. c3_chart_internal_fn.addCache = function (id, target) {
  4447. this.cache[id] = this.cloneTarget(target);
  4448. };
  4449. c3_chart_internal_fn.getCaches = function (ids) {
  4450. var targets = [],
  4451. i;
  4452. for (i = 0; i < ids.length; i++) {
  4453. if (ids[i] in this.cache) {
  4454. targets.push(this.cloneTarget(this.cache[ids[i]]));
  4455. }
  4456. }
  4457. return targets;
  4458. };
  4459. c3_chart_internal_fn.categoryName = function (i) {
  4460. var config = this.config;
  4461. return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;
  4462. };
  4463. c3_chart_internal_fn.generateTargetClass = function (targetId) {
  4464. return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : '';
  4465. };
  4466. c3_chart_internal_fn.generateClass = function (prefix, targetId) {
  4467. return " " + prefix + " " + prefix + this.generateTargetClass(targetId);
  4468. };
  4469. c3_chart_internal_fn.classText = function (d) {
  4470. return this.generateClass(CLASS.text, d.index);
  4471. };
  4472. c3_chart_internal_fn.classTexts = function (d) {
  4473. return this.generateClass(CLASS.texts, d.id);
  4474. };
  4475. c3_chart_internal_fn.classShape = function (d) {
  4476. return this.generateClass(CLASS.shape, d.index);
  4477. };
  4478. c3_chart_internal_fn.classShapes = function (d) {
  4479. return this.generateClass(CLASS.shapes, d.id);
  4480. };
  4481. c3_chart_internal_fn.classLine = function (d) {
  4482. return this.classShape(d) + this.generateClass(CLASS.line, d.id);
  4483. };
  4484. c3_chart_internal_fn.classLines = function (d) {
  4485. return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);
  4486. };
  4487. c3_chart_internal_fn.classCircle = function (d) {
  4488. return this.classShape(d) + this.generateClass(CLASS.circle, d.index);
  4489. };
  4490. c3_chart_internal_fn.classCircles = function (d) {
  4491. return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);
  4492. };
  4493. c3_chart_internal_fn.classBar = function (d) {
  4494. return this.classShape(d) + this.generateClass(CLASS.bar, d.index);
  4495. };
  4496. c3_chart_internal_fn.classBars = function (d) {
  4497. return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);
  4498. };
  4499. c3_chart_internal_fn.classArc = function (d) {
  4500. return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);
  4501. };
  4502. c3_chart_internal_fn.classArcs = function (d) {
  4503. return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);
  4504. };
  4505. c3_chart_internal_fn.classArea = function (d) {
  4506. return this.classShape(d) + this.generateClass(CLASS.area, d.id);
  4507. };
  4508. c3_chart_internal_fn.classAreas = function (d) {
  4509. return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);
  4510. };
  4511. c3_chart_internal_fn.classRegion = function (d, i) {
  4512. return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '');
  4513. };
  4514. c3_chart_internal_fn.classEvent = function (d) {
  4515. return this.generateClass(CLASS.eventRect, d.index);
  4516. };
  4517. c3_chart_internal_fn.classTarget = function (id) {
  4518. var $$ = this;
  4519. var additionalClassSuffix = $$.config.data_classes[id],
  4520. additionalClass = '';
  4521. if (additionalClassSuffix) {
  4522. additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;
  4523. }
  4524. return $$.generateClass(CLASS.target, id) + additionalClass;
  4525. };
  4526. c3_chart_internal_fn.classFocus = function (d) {
  4527. return this.classFocused(d) + this.classDefocused(d);
  4528. };
  4529. c3_chart_internal_fn.classFocused = function (d) {
  4530. return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');
  4531. };
  4532. c3_chart_internal_fn.classDefocused = function (d) {
  4533. return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '');
  4534. };
  4535. c3_chart_internal_fn.classChartText = function (d) {
  4536. return CLASS.chartText + this.classTarget(d.id);
  4537. };
  4538. c3_chart_internal_fn.classChartLine = function (d) {
  4539. return CLASS.chartLine + this.classTarget(d.id);
  4540. };
  4541. c3_chart_internal_fn.classChartBar = function (d) {
  4542. return CLASS.chartBar + this.classTarget(d.id);
  4543. };
  4544. c3_chart_internal_fn.classChartArc = function (d) {
  4545. return CLASS.chartArc + this.classTarget(d.data.id);
  4546. };
  4547. c3_chart_internal_fn.getTargetSelectorSuffix = function (targetId) {
  4548. return this.generateTargetClass(targetId).replace(/([?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1');
  4549. };
  4550. c3_chart_internal_fn.selectorTarget = function (id, prefix) {
  4551. return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);
  4552. };
  4553. c3_chart_internal_fn.selectorTargets = function (ids, prefix) {
  4554. var $$ = this;
  4555. ids = ids || [];
  4556. return ids.length ? ids.map(function (id) {
  4557. return $$.selectorTarget(id, prefix);
  4558. }) : null;
  4559. };
  4560. c3_chart_internal_fn.selectorLegend = function (id) {
  4561. return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);
  4562. };
  4563. c3_chart_internal_fn.selectorLegends = function (ids) {
  4564. var $$ = this;
  4565. return ids && ids.length ? ids.map(function (id) {
  4566. return $$.selectorLegend(id);
  4567. }) : null;
  4568. };
  4569. c3_chart_internal_fn.getClipPath = function (id) {
  4570. var isIE9 = window.navigator.appVersion.toLowerCase().indexOf("msie 9.") >= 0;
  4571. return "url(" + (isIE9 ? "" : document.URL.split('#')[0]) + "#" + id + ")";
  4572. };
  4573. c3_chart_internal_fn.appendClip = function (parent, id) {
  4574. return parent.append("clipPath").attr("id", id).append("rect");
  4575. };
  4576. c3_chart_internal_fn.getAxisClipX = function (forHorizontal) {
  4577. // axis line width + padding for left
  4578. var left = Math.max(30, this.margin.left);
  4579. return forHorizontal ? -(1 + left) : -(left - 1);
  4580. };
  4581. c3_chart_internal_fn.getAxisClipY = function (forHorizontal) {
  4582. return forHorizontal ? -20 : -this.margin.top;
  4583. };
  4584. c3_chart_internal_fn.getXAxisClipX = function () {
  4585. var $$ = this;
  4586. return $$.getAxisClipX(!$$.config.axis_rotated);
  4587. };
  4588. c3_chart_internal_fn.getXAxisClipY = function () {
  4589. var $$ = this;
  4590. return $$.getAxisClipY(!$$.config.axis_rotated);
  4591. };
  4592. c3_chart_internal_fn.getYAxisClipX = function () {
  4593. var $$ = this;
  4594. return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated);
  4595. };
  4596. c3_chart_internal_fn.getYAxisClipY = function () {
  4597. var $$ = this;
  4598. return $$.getAxisClipY($$.config.axis_rotated);
  4599. };
  4600. c3_chart_internal_fn.getAxisClipWidth = function (forHorizontal) {
  4601. var $$ = this,
  4602. left = Math.max(30, $$.margin.left),
  4603. right = Math.max(30, $$.margin.right);
  4604. // width + axis line width + padding for left/right
  4605. return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20;
  4606. };
  4607. c3_chart_internal_fn.getAxisClipHeight = function (forHorizontal) {
  4608. // less than 20 is not enough to show the axis label 'outer' without legend
  4609. return (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20;
  4610. };
  4611. c3_chart_internal_fn.getXAxisClipWidth = function () {
  4612. var $$ = this;
  4613. return $$.getAxisClipWidth(!$$.config.axis_rotated);
  4614. };
  4615. c3_chart_internal_fn.getXAxisClipHeight = function () {
  4616. var $$ = this;
  4617. return $$.getAxisClipHeight(!$$.config.axis_rotated);
  4618. };
  4619. c3_chart_internal_fn.getYAxisClipWidth = function () {
  4620. var $$ = this;
  4621. return $$.getAxisClipWidth($$.config.axis_rotated) + ($$.config.axis_y_inner ? 20 : 0);
  4622. };
  4623. c3_chart_internal_fn.getYAxisClipHeight = function () {
  4624. var $$ = this;
  4625. return $$.getAxisClipHeight($$.config.axis_rotated);
  4626. };
  4627. c3_chart_internal_fn.generateColor = function () {
  4628. var $$ = this,
  4629. config = $$.config,
  4630. d3 = $$.d3,
  4631. colors = config.data_colors,
  4632. pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.schemeCategory10,
  4633. callback = config.data_color,
  4634. ids = [];
  4635. return function (d) {
  4636. var id = d.id || d.data && d.data.id || d,
  4637. color;
  4638. // if callback function is provided
  4639. if (colors[id] instanceof Function) {
  4640. color = colors[id](d);
  4641. }
  4642. // if specified, choose that color
  4643. else if (colors[id]) {
  4644. color = colors[id];
  4645. }
  4646. // if not specified, choose from pattern
  4647. else {
  4648. if (ids.indexOf(id) < 0) {
  4649. ids.push(id);
  4650. }
  4651. color = pattern[ids.indexOf(id) % pattern.length];
  4652. colors[id] = color;
  4653. }
  4654. return callback instanceof Function ? callback(color, d) : color;
  4655. };
  4656. };
  4657. c3_chart_internal_fn.generateLevelColor = function () {
  4658. var $$ = this,
  4659. config = $$.config,
  4660. colors = config.color_pattern,
  4661. threshold = config.color_threshold,
  4662. asValue = threshold.unit === 'value',
  4663. values = threshold.values && threshold.values.length ? threshold.values : [],
  4664. max = threshold.max || 100;
  4665. return notEmpty(config.color_threshold) ? function (value) {
  4666. var i,
  4667. v,
  4668. color = colors[colors.length - 1];
  4669. for (i = 0; i < values.length; i++) {
  4670. v = asValue ? value : value * 100 / max;
  4671. if (v < values[i]) {
  4672. color = colors[i];
  4673. break;
  4674. }
  4675. }
  4676. return color;
  4677. } : null;
  4678. };
  4679. c3_chart_internal_fn.getDefaultConfig = function () {
  4680. var config = {
  4681. bindto: '#chart',
  4682. svg_classname: undefined,
  4683. size_width: undefined,
  4684. size_height: undefined,
  4685. padding_left: undefined,
  4686. padding_right: undefined,
  4687. padding_top: undefined,
  4688. padding_bottom: undefined,
  4689. resize_auto: true,
  4690. zoom_enabled: false,
  4691. zoom_initialRange: undefined,
  4692. zoom_privileged: false,
  4693. zoom_rescale: false,
  4694. zoom_onzoom: function zoom_onzoom() {},
  4695. zoom_onzoomstart: function zoom_onzoomstart() {},
  4696. zoom_onzoomend: function zoom_onzoomend() {},
  4697. zoom_x_min: undefined,
  4698. zoom_x_max: undefined,
  4699. interaction_brighten: true,
  4700. interaction_enabled: true,
  4701. onmouseover: function onmouseover() {},
  4702. onmouseout: function onmouseout() {},
  4703. onresize: function onresize() {},
  4704. onresized: function onresized() {},
  4705. oninit: function oninit() {},
  4706. onrendered: function onrendered() {},
  4707. transition_duration: 350,
  4708. data_x: undefined,
  4709. data_xs: {},
  4710. data_xFormat: '%Y-%m-%d',
  4711. data_xLocaltime: true,
  4712. data_xSort: true,
  4713. data_idConverter: function data_idConverter(id) {
  4714. return id;
  4715. },
  4716. data_names: {},
  4717. data_classes: {},
  4718. data_groups: [],
  4719. data_axes: {},
  4720. data_type: undefined,
  4721. data_types: {},
  4722. data_labels: {},
  4723. data_order: 'desc',
  4724. data_regions: {},
  4725. data_color: undefined,
  4726. data_colors: {},
  4727. data_hide: false,
  4728. data_filter: undefined,
  4729. data_selection_enabled: false,
  4730. data_selection_grouped: false,
  4731. data_selection_isselectable: function data_selection_isselectable() {
  4732. return true;
  4733. },
  4734. data_selection_multiple: true,
  4735. data_selection_draggable: false,
  4736. data_onclick: function data_onclick() {},
  4737. data_onmouseover: function data_onmouseover() {},
  4738. data_onmouseout: function data_onmouseout() {},
  4739. data_onselected: function data_onselected() {},
  4740. data_onunselected: function data_onunselected() {},
  4741. data_url: undefined,
  4742. data_headers: undefined,
  4743. data_json: undefined,
  4744. data_rows: undefined,
  4745. data_columns: undefined,
  4746. data_mimeType: undefined,
  4747. data_keys: undefined,
  4748. // configuration for no plot-able data supplied.
  4749. data_empty_label_text: "",
  4750. // subchart
  4751. subchart_show: false,
  4752. subchart_size_height: 60,
  4753. subchart_axis_x_show: true,
  4754. subchart_onbrush: function subchart_onbrush() {},
  4755. // color
  4756. color_pattern: [],
  4757. color_threshold: {},
  4758. // legend
  4759. legend_show: true,
  4760. legend_hide: false,
  4761. legend_position: 'bottom',
  4762. legend_inset_anchor: 'top-left',
  4763. legend_inset_x: 10,
  4764. legend_inset_y: 0,
  4765. legend_inset_step: undefined,
  4766. legend_item_onclick: undefined,
  4767. legend_item_onmouseover: undefined,
  4768. legend_item_onmouseout: undefined,
  4769. legend_equally: false,
  4770. legend_padding: 0,
  4771. legend_item_tile_width: 10,
  4772. legend_item_tile_height: 10,
  4773. // axis
  4774. axis_rotated: false,
  4775. axis_x_show: true,
  4776. axis_x_type: 'indexed',
  4777. axis_x_localtime: true,
  4778. axis_x_categories: [],
  4779. axis_x_tick_centered: false,
  4780. axis_x_tick_format: undefined,
  4781. axis_x_tick_culling: {},
  4782. axis_x_tick_culling_max: 10,
  4783. axis_x_tick_count: undefined,
  4784. axis_x_tick_fit: true,
  4785. axis_x_tick_values: null,
  4786. axis_x_tick_rotate: 0,
  4787. axis_x_tick_outer: true,
  4788. axis_x_tick_multiline: true,
  4789. axis_x_tick_width: null,
  4790. axis_x_max: undefined,
  4791. axis_x_min: undefined,
  4792. axis_x_padding: {},
  4793. axis_x_height: undefined,
  4794. axis_x_selection: undefined,
  4795. axis_x_label: {},
  4796. axis_x_inner: undefined,
  4797. axis_y_show: true,
  4798. axis_y_type: undefined,
  4799. axis_y_max: undefined,
  4800. axis_y_min: undefined,
  4801. axis_y_inverted: false,
  4802. axis_y_center: undefined,
  4803. axis_y_inner: undefined,
  4804. axis_y_label: {},
  4805. axis_y_tick_format: undefined,
  4806. axis_y_tick_outer: true,
  4807. axis_y_tick_values: null,
  4808. axis_y_tick_rotate: 0,
  4809. axis_y_tick_count: undefined,
  4810. axis_y_tick_time_type: undefined,
  4811. axis_y_tick_time_interval: undefined,
  4812. axis_y_padding: {},
  4813. axis_y_default: undefined,
  4814. axis_y2_show: false,
  4815. axis_y2_max: undefined,
  4816. axis_y2_min: undefined,
  4817. axis_y2_inverted: false,
  4818. axis_y2_center: undefined,
  4819. axis_y2_inner: undefined,
  4820. axis_y2_label: {},
  4821. axis_y2_tick_format: undefined,
  4822. axis_y2_tick_outer: true,
  4823. axis_y2_tick_values: null,
  4824. axis_y2_tick_count: undefined,
  4825. axis_y2_padding: {},
  4826. axis_y2_default: undefined,
  4827. // grid
  4828. grid_x_show: false,
  4829. grid_x_type: 'tick',
  4830. grid_x_lines: [],
  4831. grid_y_show: false,
  4832. // not used
  4833. // grid_y_type: 'tick',
  4834. grid_y_lines: [],
  4835. grid_y_ticks: 10,
  4836. grid_focus_show: true,
  4837. grid_lines_front: true,
  4838. // point - point of each data
  4839. point_show: true,
  4840. point_r: 2.5,
  4841. point_sensitivity: 10,
  4842. point_focus_expand_enabled: true,
  4843. point_focus_expand_r: undefined,
  4844. point_select_r: undefined,
  4845. // line
  4846. line_connectNull: false,
  4847. line_step_type: 'step',
  4848. // bar
  4849. bar_width: undefined,
  4850. bar_width_ratio: 0.6,
  4851. bar_width_max: undefined,
  4852. bar_zerobased: true,
  4853. bar_space: 0,
  4854. // area
  4855. area_zerobased: true,
  4856. area_above: false,
  4857. // pie
  4858. pie_label_show: true,
  4859. pie_label_format: undefined,
  4860. pie_label_threshold: 0.05,
  4861. pie_label_ratio: undefined,
  4862. pie_expand: {},
  4863. pie_expand_duration: 50,
  4864. // gauge
  4865. gauge_fullCircle: false,
  4866. gauge_label_show: true,
  4867. gauge_labelLine_show: true,
  4868. gauge_label_format: undefined,
  4869. gauge_min: 0,
  4870. gauge_max: 100,
  4871. gauge_startingAngle: -1 * Math.PI / 2,
  4872. gauge_label_extents: undefined,
  4873. gauge_units: undefined,
  4874. gauge_width: undefined,
  4875. gauge_arcs_minWidth: 5,
  4876. gauge_expand: {},
  4877. gauge_expand_duration: 50,
  4878. // donut
  4879. donut_label_show: true,
  4880. donut_label_format: undefined,
  4881. donut_label_threshold: 0.05,
  4882. donut_label_ratio: undefined,
  4883. donut_width: undefined,
  4884. donut_title: "",
  4885. donut_expand: {},
  4886. donut_expand_duration: 50,
  4887. // spline
  4888. spline_interpolation_type: 'cardinal',
  4889. // region - region to change style
  4890. regions: [],
  4891. // tooltip - show when mouseover on each data
  4892. tooltip_show: true,
  4893. tooltip_grouped: true,
  4894. tooltip_order: undefined,
  4895. tooltip_format_title: undefined,
  4896. tooltip_format_name: undefined,
  4897. tooltip_format_value: undefined,
  4898. tooltip_position: undefined,
  4899. tooltip_contents: function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) {
  4900. return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
  4901. },
  4902. tooltip_init_show: false,
  4903. tooltip_init_x: 0,
  4904. tooltip_init_position: { top: '0px', left: '50px' },
  4905. tooltip_onshow: function tooltip_onshow() {},
  4906. tooltip_onhide: function tooltip_onhide() {},
  4907. // title
  4908. title_text: undefined,
  4909. title_padding: {
  4910. top: 0,
  4911. right: 0,
  4912. bottom: 0,
  4913. left: 0
  4914. },
  4915. title_position: 'top-center'
  4916. };
  4917. Object.keys(this.additionalConfig).forEach(function (key) {
  4918. config[key] = this.additionalConfig[key];
  4919. }, this);
  4920. return config;
  4921. };
  4922. c3_chart_internal_fn.additionalConfig = {};
  4923. c3_chart_internal_fn.loadConfig = function (config) {
  4924. var this_config = this.config,
  4925. target,
  4926. keys,
  4927. read;
  4928. function find() {
  4929. var key = keys.shift();
  4930. // console.log("key =>", key, ", target =>", target);
  4931. if (key && target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && key in target) {
  4932. target = target[key];
  4933. return find();
  4934. } else if (!key) {
  4935. return target;
  4936. } else {
  4937. return undefined;
  4938. }
  4939. }
  4940. Object.keys(this_config).forEach(function (key) {
  4941. target = config;
  4942. keys = key.split('_');
  4943. read = find();
  4944. // console.log("CONFIG : ", key, read);
  4945. if (isDefined(read)) {
  4946. this_config[key] = read;
  4947. }
  4948. });
  4949. };
  4950. c3_chart_internal_fn.convertUrlToData = function (url, mimeType, headers, keys, done) {
  4951. var $$ = this,
  4952. type = mimeType ? mimeType : 'csv';
  4953. var req = $$.d3.request(url);
  4954. if (headers) {
  4955. Object.keys(headers).forEach(function (header) {
  4956. req.header(header, headers[header]);
  4957. });
  4958. }
  4959. req.get(function (error, data) {
  4960. var d;
  4961. var dataResponse = data.response || data.responseText; // Fixes IE9 XHR issue; see #1345
  4962. if (!data) {
  4963. throw new Error(error.responseURL + ' ' + error.status + ' (' + error.statusText + ')');
  4964. }
  4965. if (type === 'json') {
  4966. d = $$.convertJsonToData(JSON.parse(dataResponse), keys);
  4967. } else if (type === 'tsv') {
  4968. d = $$.convertTsvToData(dataResponse);
  4969. } else {
  4970. d = $$.convertCsvToData(dataResponse);
  4971. }
  4972. done.call($$, d);
  4973. });
  4974. };
  4975. c3_chart_internal_fn.convertXsvToData = function (xsv, parser) {
  4976. var rows = parser(xsv),
  4977. d;
  4978. if (rows.length === 1) {
  4979. d = [{}];
  4980. rows[0].forEach(function (id) {
  4981. d[0][id] = null;
  4982. });
  4983. } else {
  4984. d = parser(xsv);
  4985. }
  4986. return d;
  4987. };
  4988. c3_chart_internal_fn.convertCsvToData = function (csv) {
  4989. return this.convertXsvToData(csv, this.d3.csvParse);
  4990. };
  4991. c3_chart_internal_fn.convertTsvToData = function (tsv) {
  4992. return this.convertXsvToData(tsv, this.d3.tsvParse);
  4993. };
  4994. c3_chart_internal_fn.convertJsonToData = function (json, keys) {
  4995. var $$ = this,
  4996. new_rows = [],
  4997. targetKeys,
  4998. data;
  4999. if (keys) {
  5000. // when keys specified, json would be an array that includes objects
  5001. if (keys.x) {
  5002. targetKeys = keys.value.concat(keys.x);
  5003. $$.config.data_x = keys.x;
  5004. } else {
  5005. targetKeys = keys.value;
  5006. }
  5007. new_rows.push(targetKeys);
  5008. json.forEach(function (o) {
  5009. var new_row = [];
  5010. targetKeys.forEach(function (key) {
  5011. // convert undefined to null because undefined data will be removed in convertDataToTargets()
  5012. var v = $$.findValueInJson(o, key);
  5013. if (isUndefined(v)) {
  5014. v = null;
  5015. }
  5016. new_row.push(v);
  5017. });
  5018. new_rows.push(new_row);
  5019. });
  5020. data = $$.convertRowsToData(new_rows);
  5021. } else {
  5022. Object.keys(json).forEach(function (key) {
  5023. new_rows.push([key].concat(json[key]));
  5024. });
  5025. data = $$.convertColumnsToData(new_rows);
  5026. }
  5027. return data;
  5028. };
  5029. c3_chart_internal_fn.findValueInJson = function (object, path) {
  5030. path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
  5031. path = path.replace(/^\./, ''); // strip a leading dot
  5032. var pathArray = path.split('.');
  5033. for (var i = 0; i < pathArray.length; ++i) {
  5034. var k = pathArray[i];
  5035. if (k in object) {
  5036. object = object[k];
  5037. } else {
  5038. return;
  5039. }
  5040. }
  5041. return object;
  5042. };
  5043. /**
  5044. * Converts the rows to normalized data.
  5045. * @param {any[][]} rows The row data
  5046. * @return {Object[]}
  5047. */
  5048. c3_chart_internal_fn.convertRowsToData = function (rows) {
  5049. var newRows = [];
  5050. var keys = rows[0];
  5051. for (var i = 1; i < rows.length; i++) {
  5052. var newRow = {};
  5053. for (var j = 0; j < rows[i].length; j++) {
  5054. if (isUndefined(rows[i][j])) {
  5055. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  5056. }
  5057. newRow[keys[j]] = rows[i][j];
  5058. }
  5059. newRows.push(newRow);
  5060. }
  5061. return newRows;
  5062. };
  5063. /**
  5064. * Converts the columns to normalized data.
  5065. * @param {any[][]} columns The column data
  5066. * @return {Object[]}
  5067. */
  5068. c3_chart_internal_fn.convertColumnsToData = function (columns) {
  5069. var newRows = [];
  5070. for (var i = 0; i < columns.length; i++) {
  5071. var key = columns[i][0];
  5072. for (var j = 1; j < columns[i].length; j++) {
  5073. if (isUndefined(newRows[j - 1])) {
  5074. newRows[j - 1] = {};
  5075. }
  5076. if (isUndefined(columns[i][j])) {
  5077. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  5078. }
  5079. newRows[j - 1][key] = columns[i][j];
  5080. }
  5081. }
  5082. return newRows;
  5083. };
  5084. c3_chart_internal_fn.convertDataToTargets = function (data, appendXs) {
  5085. var $$ = this,
  5086. config = $$.config,
  5087. ids = $$.d3.keys(data[0]).filter($$.isNotX, $$),
  5088. xs = $$.d3.keys(data[0]).filter($$.isX, $$),
  5089. targets;
  5090. // save x for update data by load when custom x and c3.x API
  5091. ids.forEach(function (id) {
  5092. var xKey = $$.getXKey(id);
  5093. if ($$.isCustomX() || $$.isTimeSeries()) {
  5094. // if included in input data
  5095. if (xs.indexOf(xKey) >= 0) {
  5096. $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat(data.map(function (d) {
  5097. return d[xKey];
  5098. }).filter(isValue).map(function (rawX, i) {
  5099. return $$.generateTargetX(rawX, id, i);
  5100. }));
  5101. }
  5102. // if not included in input data, find from preloaded data of other id's x
  5103. else if (config.data_x) {
  5104. $$.data.xs[id] = $$.getOtherTargetXs();
  5105. }
  5106. // if not included in input data, find from preloaded data
  5107. else if (notEmpty(config.data_xs)) {
  5108. $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);
  5109. }
  5110. // MEMO: if no x included, use same x of current will be used
  5111. } else {
  5112. $$.data.xs[id] = data.map(function (d, i) {
  5113. return i;
  5114. });
  5115. }
  5116. });
  5117. // check x is defined
  5118. ids.forEach(function (id) {
  5119. if (!$$.data.xs[id]) {
  5120. throw new Error('x is not defined for id = "' + id + '".');
  5121. }
  5122. });
  5123. // convert to target
  5124. targets = ids.map(function (id, index) {
  5125. var convertedId = config.data_idConverter(id);
  5126. return {
  5127. id: convertedId,
  5128. id_org: id,
  5129. values: data.map(function (d, i) {
  5130. var xKey = $$.getXKey(id),
  5131. rawX = d[xKey],
  5132. value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null,
  5133. x;
  5134. // use x as categories if custom x and categorized
  5135. if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {
  5136. if (index === 0 && i === 0) {
  5137. config.axis_x_categories = [];
  5138. }
  5139. x = config.axis_x_categories.indexOf(rawX);
  5140. if (x === -1) {
  5141. x = config.axis_x_categories.length;
  5142. config.axis_x_categories.push(rawX);
  5143. }
  5144. } else {
  5145. x = $$.generateTargetX(rawX, id, i);
  5146. }
  5147. // mark as x = undefined if value is undefined and filter to remove after mapped
  5148. if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {
  5149. x = undefined;
  5150. }
  5151. return { x: x, value: value, id: convertedId };
  5152. }).filter(function (v) {
  5153. return isDefined(v.x);
  5154. })
  5155. };
  5156. });
  5157. // finish targets
  5158. targets.forEach(function (t) {
  5159. var i;
  5160. // sort values by its x
  5161. if (config.data_xSort) {
  5162. t.values = t.values.sort(function (v1, v2) {
  5163. var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,
  5164. x2 = v2.x || v2.x === 0 ? v2.x : Infinity;
  5165. return x1 - x2;
  5166. });
  5167. }
  5168. // indexing each value
  5169. i = 0;
  5170. t.values.forEach(function (v) {
  5171. v.index = i++;
  5172. });
  5173. // this needs to be sorted because its index and value.index is identical
  5174. $$.data.xs[t.id].sort(function (v1, v2) {
  5175. return v1 - v2;
  5176. });
  5177. });
  5178. // cache information about values
  5179. $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  5180. $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets);
  5181. // set target types
  5182. if (config.data_type) {
  5183. $$.setTargetType($$.mapToIds(targets).filter(function (id) {
  5184. return !(id in config.data_types);
  5185. }), config.data_type);
  5186. }
  5187. // cache as original id keyed
  5188. targets.forEach(function (d) {
  5189. $$.addCache(d.id_org, d);
  5190. });
  5191. return targets;
  5192. };
  5193. c3_chart_internal_fn.isX = function (key) {
  5194. var $$ = this,
  5195. config = $$.config;
  5196. return config.data_x && key === config.data_x || notEmpty(config.data_xs) && hasValue(config.data_xs, key);
  5197. };
  5198. c3_chart_internal_fn.isNotX = function (key) {
  5199. return !this.isX(key);
  5200. };
  5201. c3_chart_internal_fn.getXKey = function (id) {
  5202. var $$ = this,
  5203. config = $$.config;
  5204. return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null;
  5205. };
  5206. c3_chart_internal_fn.getXValuesOfXKey = function (key, targets) {
  5207. var $$ = this,
  5208. xValues,
  5209. ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];
  5210. ids.forEach(function (id) {
  5211. if ($$.getXKey(id) === key) {
  5212. xValues = $$.data.xs[id];
  5213. }
  5214. });
  5215. return xValues;
  5216. };
  5217. c3_chart_internal_fn.getXValue = function (id, i) {
  5218. var $$ = this;
  5219. return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
  5220. };
  5221. c3_chart_internal_fn.getOtherTargetXs = function () {
  5222. var $$ = this,
  5223. idsForX = Object.keys($$.data.xs);
  5224. return idsForX.length ? $$.data.xs[idsForX[0]] : null;
  5225. };
  5226. c3_chart_internal_fn.getOtherTargetX = function (index) {
  5227. var xs = this.getOtherTargetXs();
  5228. return xs && index < xs.length ? xs[index] : null;
  5229. };
  5230. c3_chart_internal_fn.addXs = function (xs) {
  5231. var $$ = this;
  5232. Object.keys(xs).forEach(function (id) {
  5233. $$.config.data_xs[id] = xs[id];
  5234. });
  5235. };
  5236. c3_chart_internal_fn.addName = function (data) {
  5237. var $$ = this,
  5238. name;
  5239. if (data) {
  5240. name = $$.config.data_names[data.id];
  5241. data.name = name !== undefined ? name : data.id;
  5242. }
  5243. return data;
  5244. };
  5245. c3_chart_internal_fn.getValueOnIndex = function (values, index) {
  5246. var valueOnIndex = values.filter(function (v) {
  5247. return v.index === index;
  5248. });
  5249. return valueOnIndex.length ? valueOnIndex[0] : null;
  5250. };
  5251. c3_chart_internal_fn.updateTargetX = function (targets, x) {
  5252. var $$ = this;
  5253. targets.forEach(function (t) {
  5254. t.values.forEach(function (v, i) {
  5255. v.x = $$.generateTargetX(x[i], t.id, i);
  5256. });
  5257. $$.data.xs[t.id] = x;
  5258. });
  5259. };
  5260. c3_chart_internal_fn.updateTargetXs = function (targets, xs) {
  5261. var $$ = this;
  5262. targets.forEach(function (t) {
  5263. if (xs[t.id]) {
  5264. $$.updateTargetX([t], xs[t.id]);
  5265. }
  5266. });
  5267. };
  5268. c3_chart_internal_fn.generateTargetX = function (rawX, id, index) {
  5269. var $$ = this,
  5270. x;
  5271. if ($$.isTimeSeries()) {
  5272. x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));
  5273. } else if ($$.isCustomX() && !$$.isCategorized()) {
  5274. x = isValue(rawX) ? +rawX : $$.getXValue(id, index);
  5275. } else {
  5276. x = index;
  5277. }
  5278. return x;
  5279. };
  5280. c3_chart_internal_fn.cloneTarget = function (target) {
  5281. return {
  5282. id: target.id,
  5283. id_org: target.id_org,
  5284. values: target.values.map(function (d) {
  5285. return { x: d.x, value: d.value, id: d.id };
  5286. })
  5287. };
  5288. };
  5289. c3_chart_internal_fn.getMaxDataCount = function () {
  5290. var $$ = this;
  5291. return $$.d3.max($$.data.targets, function (t) {
  5292. return t.values.length;
  5293. });
  5294. };
  5295. c3_chart_internal_fn.mapToIds = function (targets) {
  5296. return targets.map(function (d) {
  5297. return d.id;
  5298. });
  5299. };
  5300. c3_chart_internal_fn.mapToTargetIds = function (ids) {
  5301. var $$ = this;
  5302. return ids ? [].concat(ids) : $$.mapToIds($$.data.targets);
  5303. };
  5304. c3_chart_internal_fn.hasTarget = function (targets, id) {
  5305. var ids = this.mapToIds(targets),
  5306. i;
  5307. for (i = 0; i < ids.length; i++) {
  5308. if (ids[i] === id) {
  5309. return true;
  5310. }
  5311. }
  5312. return false;
  5313. };
  5314. c3_chart_internal_fn.isTargetToShow = function (targetId) {
  5315. return this.hiddenTargetIds.indexOf(targetId) < 0;
  5316. };
  5317. c3_chart_internal_fn.isLegendToShow = function (targetId) {
  5318. return this.hiddenLegendIds.indexOf(targetId) < 0;
  5319. };
  5320. c3_chart_internal_fn.filterTargetsToShow = function (targets) {
  5321. var $$ = this;
  5322. return targets.filter(function (t) {
  5323. return $$.isTargetToShow(t.id);
  5324. });
  5325. };
  5326. c3_chart_internal_fn.mapTargetsToUniqueXs = function (targets) {
  5327. var $$ = this;
  5328. var xs = $$.d3.set($$.d3.merge(targets.map(function (t) {
  5329. return t.values.map(function (v) {
  5330. return +v.x;
  5331. });
  5332. }))).values();
  5333. xs = $$.isTimeSeries() ? xs.map(function (x) {
  5334. return new Date(+x);
  5335. }) : xs.map(function (x) {
  5336. return +x;
  5337. });
  5338. return xs.sort(function (a, b) {
  5339. return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
  5340. });
  5341. };
  5342. c3_chart_internal_fn.addHiddenTargetIds = function (targetIds) {
  5343. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  5344. for (var i = 0; i < targetIds.length; i++) {
  5345. if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {
  5346. this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);
  5347. }
  5348. }
  5349. };
  5350. c3_chart_internal_fn.removeHiddenTargetIds = function (targetIds) {
  5351. this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) {
  5352. return targetIds.indexOf(id) < 0;
  5353. });
  5354. };
  5355. c3_chart_internal_fn.addHiddenLegendIds = function (targetIds) {
  5356. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  5357. for (var i = 0; i < targetIds.length; i++) {
  5358. if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {
  5359. this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);
  5360. }
  5361. }
  5362. };
  5363. c3_chart_internal_fn.removeHiddenLegendIds = function (targetIds) {
  5364. this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) {
  5365. return targetIds.indexOf(id) < 0;
  5366. });
  5367. };
  5368. c3_chart_internal_fn.getValuesAsIdKeyed = function (targets) {
  5369. var ys = {};
  5370. targets.forEach(function (t) {
  5371. ys[t.id] = [];
  5372. t.values.forEach(function (v) {
  5373. ys[t.id].push(v.value);
  5374. });
  5375. });
  5376. return ys;
  5377. };
  5378. c3_chart_internal_fn.checkValueInTargets = function (targets, checker) {
  5379. var ids = Object.keys(targets),
  5380. i,
  5381. j,
  5382. values;
  5383. for (i = 0; i < ids.length; i++) {
  5384. values = targets[ids[i]].values;
  5385. for (j = 0; j < values.length; j++) {
  5386. if (checker(values[j].value)) {
  5387. return true;
  5388. }
  5389. }
  5390. }
  5391. return false;
  5392. };
  5393. c3_chart_internal_fn.hasNegativeValueInTargets = function (targets) {
  5394. return this.checkValueInTargets(targets, function (v) {
  5395. return v < 0;
  5396. });
  5397. };
  5398. c3_chart_internal_fn.hasPositiveValueInTargets = function (targets) {
  5399. return this.checkValueInTargets(targets, function (v) {
  5400. return v > 0;
  5401. });
  5402. };
  5403. c3_chart_internal_fn.isOrderDesc = function () {
  5404. var config = this.config;
  5405. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'desc';
  5406. };
  5407. c3_chart_internal_fn.isOrderAsc = function () {
  5408. var config = this.config;
  5409. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'asc';
  5410. };
  5411. c3_chart_internal_fn.getOrderFunction = function () {
  5412. var $$ = this,
  5413. config = $$.config,
  5414. orderAsc = $$.isOrderAsc(),
  5415. orderDesc = $$.isOrderDesc();
  5416. if (orderAsc || orderDesc) {
  5417. var reducer = function reducer(p, c) {
  5418. return p + Math.abs(c.value);
  5419. };
  5420. return function (t1, t2) {
  5421. var t1Sum = t1.values.reduce(reducer, 0),
  5422. t2Sum = t2.values.reduce(reducer, 0);
  5423. return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;
  5424. };
  5425. } else if (isFunction(config.data_order)) {
  5426. return config.data_order;
  5427. } else if (isArray(config.data_order)) {
  5428. var order = config.data_order;
  5429. return function (t1, t2) {
  5430. return order.indexOf(t1.id) - order.indexOf(t2.id);
  5431. };
  5432. }
  5433. };
  5434. c3_chart_internal_fn.orderTargets = function (targets) {
  5435. var fct = this.getOrderFunction();
  5436. if (fct) {
  5437. targets.sort(fct);
  5438. }
  5439. return targets;
  5440. };
  5441. c3_chart_internal_fn.filterByX = function (targets, x) {
  5442. return this.d3.merge(targets.map(function (t) {
  5443. return t.values;
  5444. })).filter(function (v) {
  5445. return v.x - x === 0;
  5446. });
  5447. };
  5448. c3_chart_internal_fn.filterRemoveNull = function (data) {
  5449. return data.filter(function (d) {
  5450. return isValue(d.value);
  5451. });
  5452. };
  5453. c3_chart_internal_fn.filterByXDomain = function (targets, xDomain) {
  5454. return targets.map(function (t) {
  5455. return {
  5456. id: t.id,
  5457. id_org: t.id_org,
  5458. values: t.values.filter(function (v) {
  5459. return xDomain[0] <= v.x && v.x <= xDomain[1];
  5460. })
  5461. };
  5462. });
  5463. };
  5464. c3_chart_internal_fn.hasDataLabel = function () {
  5465. var config = this.config;
  5466. if (typeof config.data_labels === 'boolean' && config.data_labels) {
  5467. return true;
  5468. } else if (_typeof(config.data_labels) === 'object' && notEmpty(config.data_labels)) {
  5469. return true;
  5470. }
  5471. return false;
  5472. };
  5473. c3_chart_internal_fn.getDataLabelLength = function (min, max, key) {
  5474. var $$ = this,
  5475. lengths = [0, 0],
  5476. paddingCoef = 1.3;
  5477. $$.selectChart.select('svg').selectAll('.dummy').data([min, max]).enter().append('text').text(function (d) {
  5478. return $$.dataLabelFormat(d.id)(d);
  5479. }).each(function (d, i) {
  5480. lengths[i] = this.getBoundingClientRect()[key] * paddingCoef;
  5481. }).remove();
  5482. return lengths;
  5483. };
  5484. c3_chart_internal_fn.isNoneArc = function (d) {
  5485. return this.hasTarget(this.data.targets, d.id);
  5486. }, c3_chart_internal_fn.isArc = function (d) {
  5487. return 'data' in d && this.hasTarget(this.data.targets, d.data.id);
  5488. };
  5489. c3_chart_internal_fn.findClosestFromTargets = function (targets, pos) {
  5490. var $$ = this,
  5491. candidates;
  5492. // map to array of closest points of each target
  5493. candidates = targets.map(function (target) {
  5494. return $$.findClosest(target.values, pos);
  5495. });
  5496. // decide closest point and return
  5497. return $$.findClosest(candidates, pos);
  5498. };
  5499. c3_chart_internal_fn.findClosest = function (values, pos) {
  5500. var $$ = this,
  5501. minDist = $$.config.point_sensitivity,
  5502. closest;
  5503. // find mouseovering bar
  5504. values.filter(function (v) {
  5505. return v && $$.isBarType(v.id);
  5506. }).forEach(function (v) {
  5507. var shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node();
  5508. if (!closest && $$.isWithinBar($$.d3.mouse(shape), shape)) {
  5509. closest = v;
  5510. }
  5511. });
  5512. // find closest point from non-bar
  5513. values.filter(function (v) {
  5514. return v && !$$.isBarType(v.id);
  5515. }).forEach(function (v) {
  5516. var d = $$.dist(v, pos);
  5517. if (d < minDist) {
  5518. minDist = d;
  5519. closest = v;
  5520. }
  5521. });
  5522. return closest;
  5523. };
  5524. c3_chart_internal_fn.dist = function (data, pos) {
  5525. var $$ = this,
  5526. config = $$.config,
  5527. xIndex = config.axis_rotated ? 1 : 0,
  5528. yIndex = config.axis_rotated ? 0 : 1,
  5529. y = $$.circleY(data, data.index),
  5530. x = $$.x(data.x);
  5531. return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));
  5532. };
  5533. c3_chart_internal_fn.convertValuesToStep = function (values) {
  5534. var converted = [].concat(values),
  5535. i;
  5536. if (!this.isCategorized()) {
  5537. return values;
  5538. }
  5539. for (i = values.length + 1; 0 < i; i--) {
  5540. converted[i] = converted[i - 1];
  5541. }
  5542. converted[0] = {
  5543. x: converted[0].x - 1,
  5544. value: converted[0].value,
  5545. id: converted[0].id
  5546. };
  5547. converted[values.length + 1] = {
  5548. x: converted[values.length].x + 1,
  5549. value: converted[values.length].value,
  5550. id: converted[values.length].id
  5551. };
  5552. return converted;
  5553. };
  5554. c3_chart_internal_fn.updateDataAttributes = function (name, attrs) {
  5555. var $$ = this,
  5556. config = $$.config,
  5557. current = config['data_' + name];
  5558. if (typeof attrs === 'undefined') {
  5559. return current;
  5560. }
  5561. Object.keys(attrs).forEach(function (id) {
  5562. current[id] = attrs[id];
  5563. });
  5564. $$.redraw({ withLegend: true });
  5565. return current;
  5566. };
  5567. c3_chart_internal_fn.load = function (targets, args) {
  5568. var $$ = this;
  5569. if (targets) {
  5570. // filter loading targets if needed
  5571. if (args.filter) {
  5572. targets = targets.filter(args.filter);
  5573. }
  5574. // set type if args.types || args.type specified
  5575. if (args.type || args.types) {
  5576. targets.forEach(function (t) {
  5577. var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;
  5578. $$.setTargetType(t.id, type);
  5579. });
  5580. }
  5581. // Update/Add data
  5582. $$.data.targets.forEach(function (d) {
  5583. for (var i = 0; i < targets.length; i++) {
  5584. if (d.id === targets[i].id) {
  5585. d.values = targets[i].values;
  5586. targets.splice(i, 1);
  5587. break;
  5588. }
  5589. }
  5590. });
  5591. $$.data.targets = $$.data.targets.concat(targets); // add remained
  5592. }
  5593. // Set targets
  5594. $$.updateTargets($$.data.targets);
  5595. // Redraw with new targets
  5596. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  5597. if (args.done) {
  5598. args.done();
  5599. }
  5600. };
  5601. c3_chart_internal_fn.loadFromArgs = function (args) {
  5602. var $$ = this;
  5603. if (args.data) {
  5604. $$.load($$.convertDataToTargets(args.data), args);
  5605. } else if (args.url) {
  5606. $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {
  5607. $$.load($$.convertDataToTargets(data), args);
  5608. });
  5609. } else if (args.json) {
  5610. $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);
  5611. } else if (args.rows) {
  5612. $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);
  5613. } else if (args.columns) {
  5614. $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);
  5615. } else {
  5616. $$.load(null, args);
  5617. }
  5618. };
  5619. c3_chart_internal_fn.unload = function (targetIds, done) {
  5620. var $$ = this;
  5621. if (!done) {
  5622. done = function done() {};
  5623. }
  5624. // filter existing target
  5625. targetIds = targetIds.filter(function (id) {
  5626. return $$.hasTarget($$.data.targets, id);
  5627. });
  5628. // If no target, call done and return
  5629. if (!targetIds || targetIds.length === 0) {
  5630. done();
  5631. return;
  5632. }
  5633. $$.svg.selectAll(targetIds.map(function (id) {
  5634. return $$.selectorTarget(id);
  5635. })).transition().style('opacity', 0).remove().call($$.endall, done);
  5636. targetIds.forEach(function (id) {
  5637. // Reset fadein for future load
  5638. $$.withoutFadeIn[id] = false;
  5639. // Remove target's elements
  5640. if ($$.legend) {
  5641. $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove();
  5642. }
  5643. // Remove target
  5644. $$.data.targets = $$.data.targets.filter(function (t) {
  5645. return t.id !== id;
  5646. });
  5647. });
  5648. };
  5649. c3_chart_internal_fn.getYDomainMin = function (targets) {
  5650. var $$ = this,
  5651. config = $$.config,
  5652. ids = $$.mapToIds(targets),
  5653. ys = $$.getValuesAsIdKeyed(targets),
  5654. j,
  5655. k,
  5656. baseId,
  5657. idsInGroup,
  5658. id,
  5659. hasNegativeValue;
  5660. if (config.data_groups.length > 0) {
  5661. hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  5662. for (j = 0; j < config.data_groups.length; j++) {
  5663. // Determine baseId
  5664. idsInGroup = config.data_groups[j].filter(function (id) {
  5665. return ids.indexOf(id) >= 0;
  5666. });
  5667. if (idsInGroup.length === 0) {
  5668. continue;
  5669. }
  5670. baseId = idsInGroup[0];
  5671. // Consider negative values
  5672. if (hasNegativeValue && ys[baseId]) {
  5673. ys[baseId].forEach(function (v, i) {
  5674. ys[baseId][i] = v < 0 ? v : 0;
  5675. });
  5676. }
  5677. // Compute min
  5678. for (k = 1; k < idsInGroup.length; k++) {
  5679. id = idsInGroup[k];
  5680. if (!ys[id]) {
  5681. continue;
  5682. }
  5683. ys[id].forEach(function (v, i) {
  5684. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) {
  5685. ys[baseId][i] += +v;
  5686. }
  5687. });
  5688. }
  5689. }
  5690. }
  5691. return $$.d3.min(Object.keys(ys).map(function (key) {
  5692. return $$.d3.min(ys[key]);
  5693. }));
  5694. };
  5695. c3_chart_internal_fn.getYDomainMax = function (targets) {
  5696. var $$ = this,
  5697. config = $$.config,
  5698. ids = $$.mapToIds(targets),
  5699. ys = $$.getValuesAsIdKeyed(targets),
  5700. j,
  5701. k,
  5702. baseId,
  5703. idsInGroup,
  5704. id,
  5705. hasPositiveValue;
  5706. if (config.data_groups.length > 0) {
  5707. hasPositiveValue = $$.hasPositiveValueInTargets(targets);
  5708. for (j = 0; j < config.data_groups.length; j++) {
  5709. // Determine baseId
  5710. idsInGroup = config.data_groups[j].filter(function (id) {
  5711. return ids.indexOf(id) >= 0;
  5712. });
  5713. if (idsInGroup.length === 0) {
  5714. continue;
  5715. }
  5716. baseId = idsInGroup[0];
  5717. // Consider positive values
  5718. if (hasPositiveValue && ys[baseId]) {
  5719. ys[baseId].forEach(function (v, i) {
  5720. ys[baseId][i] = v > 0 ? v : 0;
  5721. });
  5722. }
  5723. // Compute max
  5724. for (k = 1; k < idsInGroup.length; k++) {
  5725. id = idsInGroup[k];
  5726. if (!ys[id]) {
  5727. continue;
  5728. }
  5729. ys[id].forEach(function (v, i) {
  5730. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) {
  5731. ys[baseId][i] += +v;
  5732. }
  5733. });
  5734. }
  5735. }
  5736. }
  5737. return $$.d3.max(Object.keys(ys).map(function (key) {
  5738. return $$.d3.max(ys[key]);
  5739. }));
  5740. };
  5741. c3_chart_internal_fn.getYDomain = function (targets, axisId, xDomain) {
  5742. var $$ = this,
  5743. config = $$.config,
  5744. targetsByAxisId = targets.filter(function (t) {
  5745. return $$.axis.getId(t.id) === axisId;
  5746. }),
  5747. yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId,
  5748. yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,
  5749. yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,
  5750. yDomainMin = $$.getYDomainMin(yTargets),
  5751. yDomainMax = $$.getYDomainMax(yTargets),
  5752. domain,
  5753. domainLength,
  5754. padding,
  5755. padding_top,
  5756. padding_bottom,
  5757. center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,
  5758. yDomainAbs,
  5759. lengths,
  5760. diff,
  5761. ratio,
  5762. isAllPositive,
  5763. isAllNegative,
  5764. isZeroBased = $$.hasType('bar', yTargets) && config.bar_zerobased || $$.hasType('area', yTargets) && config.area_zerobased,
  5765. isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,
  5766. showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,
  5767. showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;
  5768. // MEMO: avoid inverting domain unexpectedly
  5769. yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? yDomainMin < yMax ? yDomainMin : yMax - 10 : yDomainMin;
  5770. yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? yMin < yDomainMax ? yDomainMax : yMin + 10 : yDomainMax;
  5771. if (yTargets.length === 0) {
  5772. // use current domain if target of axisId is none
  5773. return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();
  5774. }
  5775. if (isNaN(yDomainMin)) {
  5776. // set minimum to zero when not number
  5777. yDomainMin = 0;
  5778. }
  5779. if (isNaN(yDomainMax)) {
  5780. // set maximum to have same value as yDomainMin
  5781. yDomainMax = yDomainMin;
  5782. }
  5783. if (yDomainMin === yDomainMax) {
  5784. yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0;
  5785. }
  5786. isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;
  5787. isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;
  5788. // Cancel zerobased if axis_*_min / axis_*_max specified
  5789. if (isValue(yMin) && isAllPositive || isValue(yMax) && isAllNegative) {
  5790. isZeroBased = false;
  5791. }
  5792. // Bar/Area chart should be 0-based if all positive|negative
  5793. if (isZeroBased) {
  5794. if (isAllPositive) {
  5795. yDomainMin = 0;
  5796. }
  5797. if (isAllNegative) {
  5798. yDomainMax = 0;
  5799. }
  5800. }
  5801. domainLength = Math.abs(yDomainMax - yDomainMin);
  5802. padding = padding_top = padding_bottom = domainLength * 0.1;
  5803. if (typeof center !== 'undefined') {
  5804. yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));
  5805. yDomainMax = center + yDomainAbs;
  5806. yDomainMin = center - yDomainAbs;
  5807. }
  5808. // add padding for data label
  5809. if (showHorizontalDataLabel) {
  5810. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');
  5811. diff = diffDomain($$.y.range());
  5812. ratio = [lengths[0] / diff, lengths[1] / diff];
  5813. padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));
  5814. padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));
  5815. } else if (showVerticalDataLabel) {
  5816. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');
  5817. padding_top += $$.axis.convertPixelsToAxisPadding(lengths[1], domainLength);
  5818. padding_bottom += $$.axis.convertPixelsToAxisPadding(lengths[0], domainLength);
  5819. }
  5820. if (axisId === 'y' && notEmpty(config.axis_y_padding)) {
  5821. padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength);
  5822. padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength);
  5823. }
  5824. if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {
  5825. padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength);
  5826. padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength);
  5827. }
  5828. // Bar/Area chart should be 0-based if all positive|negative
  5829. if (isZeroBased) {
  5830. if (isAllPositive) {
  5831. padding_bottom = yDomainMin;
  5832. }
  5833. if (isAllNegative) {
  5834. padding_top = -yDomainMax;
  5835. }
  5836. }
  5837. domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];
  5838. return isInverted ? domain.reverse() : domain;
  5839. };
  5840. c3_chart_internal_fn.getXDomainMin = function (targets) {
  5841. var $$ = this,
  5842. config = $$.config;
  5843. return isDefined(config.axis_x_min) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min : $$.d3.min(targets, function (t) {
  5844. return $$.d3.min(t.values, function (v) {
  5845. return v.x;
  5846. });
  5847. });
  5848. };
  5849. c3_chart_internal_fn.getXDomainMax = function (targets) {
  5850. var $$ = this,
  5851. config = $$.config;
  5852. return isDefined(config.axis_x_max) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max : $$.d3.max(targets, function (t) {
  5853. return $$.d3.max(t.values, function (v) {
  5854. return v.x;
  5855. });
  5856. });
  5857. };
  5858. c3_chart_internal_fn.getXDomainPadding = function (domain) {
  5859. var $$ = this,
  5860. config = $$.config,
  5861. diff = domain[1] - domain[0],
  5862. maxDataCount,
  5863. padding,
  5864. paddingLeft,
  5865. paddingRight;
  5866. if ($$.isCategorized()) {
  5867. padding = 0;
  5868. } else if ($$.hasType('bar')) {
  5869. maxDataCount = $$.getMaxDataCount();
  5870. padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;
  5871. } else {
  5872. padding = diff * 0.01;
  5873. }
  5874. if (_typeof(config.axis_x_padding) === 'object' && notEmpty(config.axis_x_padding)) {
  5875. paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding;
  5876. paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding;
  5877. } else if (typeof config.axis_x_padding === 'number') {
  5878. paddingLeft = paddingRight = config.axis_x_padding;
  5879. } else {
  5880. paddingLeft = paddingRight = padding;
  5881. }
  5882. return { left: paddingLeft, right: paddingRight };
  5883. };
  5884. c3_chart_internal_fn.getXDomain = function (targets) {
  5885. var $$ = this,
  5886. xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],
  5887. firstX = xDomain[0],
  5888. lastX = xDomain[1],
  5889. padding = $$.getXDomainPadding(xDomain),
  5890. min = 0,
  5891. max = 0;
  5892. // show center of x domain if min and max are the same
  5893. if (firstX - lastX === 0 && !$$.isCategorized()) {
  5894. if ($$.isTimeSeries()) {
  5895. firstX = new Date(firstX.getTime() * 0.5);
  5896. lastX = new Date(lastX.getTime() * 1.5);
  5897. } else {
  5898. firstX = firstX === 0 ? 1 : firstX * 0.5;
  5899. lastX = lastX === 0 ? -1 : lastX * 1.5;
  5900. }
  5901. }
  5902. if (firstX || firstX === 0) {
  5903. min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;
  5904. }
  5905. if (lastX || lastX === 0) {
  5906. max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right;
  5907. }
  5908. return [min, max];
  5909. };
  5910. c3_chart_internal_fn.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {
  5911. var $$ = this,
  5912. config = $$.config;
  5913. if (withUpdateOrgXDomain) {
  5914. $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));
  5915. $$.orgXDomain = $$.x.domain();
  5916. if (config.zoom_enabled) {
  5917. $$.zoom.update();
  5918. }
  5919. $$.subX.domain($$.x.domain());
  5920. if ($$.brush) {
  5921. $$.brush.updateScale($$.subX);
  5922. }
  5923. }
  5924. if (withUpdateXDomain) {
  5925. $$.x.domain(domain ? domain : !$$.brush || $$.brush.empty() ? $$.orgXDomain : $$.brush.selectionAsValue());
  5926. }
  5927. // Trim domain when too big by zoom mousemove event
  5928. if (withTrim) {
  5929. $$.x.domain($$.trimXDomain($$.x.orgDomain()));
  5930. }
  5931. return $$.x.domain();
  5932. };
  5933. c3_chart_internal_fn.trimXDomain = function (domain) {
  5934. var zoomDomain = this.getZoomDomain(),
  5935. min = zoomDomain[0],
  5936. max = zoomDomain[1];
  5937. if (domain[0] <= min) {
  5938. domain[1] = +domain[1] + (min - domain[0]);
  5939. domain[0] = min;
  5940. }
  5941. if (max <= domain[1]) {
  5942. domain[0] = +domain[0] - (domain[1] - max);
  5943. domain[1] = max;
  5944. }
  5945. return domain;
  5946. };
  5947. c3_chart_internal_fn.drag = function (mouse) {
  5948. var $$ = this,
  5949. config = $$.config,
  5950. main = $$.main,
  5951. d3 = $$.d3;
  5952. var sx, sy, mx, my, minX, maxX, minY, maxY;
  5953. if ($$.hasArcType()) {
  5954. return;
  5955. }
  5956. if (!config.data_selection_enabled) {
  5957. return;
  5958. } // do nothing if not selectable
  5959. if (!config.data_selection_multiple) {
  5960. return;
  5961. } // skip when single selection because drag is used for multiple selection
  5962. sx = $$.dragStart[0];
  5963. sy = $$.dragStart[1];
  5964. mx = mouse[0];
  5965. my = mouse[1];
  5966. minX = Math.min(sx, mx);
  5967. maxX = Math.max(sx, mx);
  5968. minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);
  5969. maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);
  5970. main.select('.' + CLASS.dragarea).attr('x', minX).attr('y', minY).attr('width', maxX - minX).attr('height', maxY - minY);
  5971. // TODO: binary search when multiple xs
  5972. main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).filter(function (d) {
  5973. return config.data_selection_isselectable(d);
  5974. }).each(function (d, i) {
  5975. var shape = d3.select(this),
  5976. isSelected = shape.classed(CLASS.SELECTED),
  5977. isIncluded = shape.classed(CLASS.INCLUDED),
  5978. _x,
  5979. _y,
  5980. _w,
  5981. _h,
  5982. toggle,
  5983. isWithin = false,
  5984. box;
  5985. if (shape.classed(CLASS.circle)) {
  5986. _x = shape.attr("cx") * 1;
  5987. _y = shape.attr("cy") * 1;
  5988. toggle = $$.togglePoint;
  5989. isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;
  5990. } else if (shape.classed(CLASS.bar)) {
  5991. box = getPathBox(this);
  5992. _x = box.x;
  5993. _y = box.y;
  5994. _w = box.width;
  5995. _h = box.height;
  5996. toggle = $$.togglePath;
  5997. isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);
  5998. } else {
  5999. // line/area selection not supported yet
  6000. return;
  6001. }
  6002. if (isWithin ^ isIncluded) {
  6003. shape.classed(CLASS.INCLUDED, !isIncluded);
  6004. // TODO: included/unincluded callback here
  6005. shape.classed(CLASS.SELECTED, !isSelected);
  6006. toggle.call($$, !isSelected, shape, d, i);
  6007. }
  6008. });
  6009. };
  6010. c3_chart_internal_fn.dragstart = function (mouse) {
  6011. var $$ = this,
  6012. config = $$.config;
  6013. if ($$.hasArcType()) {
  6014. return;
  6015. }
  6016. if (!config.data_selection_enabled) {
  6017. return;
  6018. } // do nothing if not selectable
  6019. $$.dragStart = mouse;
  6020. $$.main.select('.' + CLASS.chart).append('rect').attr('class', CLASS.dragarea).style('opacity', 0.1);
  6021. $$.dragging = true;
  6022. };
  6023. c3_chart_internal_fn.dragend = function () {
  6024. var $$ = this,
  6025. config = $$.config;
  6026. if ($$.hasArcType()) {
  6027. return;
  6028. }
  6029. if (!config.data_selection_enabled) {
  6030. return;
  6031. } // do nothing if not selectable
  6032. $$.main.select('.' + CLASS.dragarea).transition().duration(100).style('opacity', 0).remove();
  6033. $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);
  6034. $$.dragging = false;
  6035. };
  6036. c3_chart_internal_fn.getYFormat = function (forArc) {
  6037. var $$ = this,
  6038. formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,
  6039. formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;
  6040. return function (v, ratio, id) {
  6041. var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;
  6042. return format.call($$, v, ratio);
  6043. };
  6044. };
  6045. c3_chart_internal_fn.yFormat = function (v) {
  6046. var $$ = this,
  6047. config = $$.config,
  6048. format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat;
  6049. return format(v);
  6050. };
  6051. c3_chart_internal_fn.y2Format = function (v) {
  6052. var $$ = this,
  6053. config = $$.config,
  6054. format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat;
  6055. return format(v);
  6056. };
  6057. c3_chart_internal_fn.defaultValueFormat = function (v) {
  6058. return isValue(v) ? +v : "";
  6059. };
  6060. c3_chart_internal_fn.defaultArcValueFormat = function (v, ratio) {
  6061. return (ratio * 100).toFixed(1) + '%';
  6062. };
  6063. c3_chart_internal_fn.dataLabelFormat = function (targetId) {
  6064. var $$ = this,
  6065. data_labels = $$.config.data_labels,
  6066. format,
  6067. defaultFormat = function defaultFormat(v) {
  6068. return isValue(v) ? +v : "";
  6069. };
  6070. // find format according to axis id
  6071. if (typeof data_labels.format === 'function') {
  6072. format = data_labels.format;
  6073. } else if (_typeof(data_labels.format) === 'object') {
  6074. if (data_labels.format[targetId]) {
  6075. format = data_labels.format[targetId] === true ? defaultFormat : data_labels.format[targetId];
  6076. } else {
  6077. format = function format() {
  6078. return '';
  6079. };
  6080. }
  6081. } else {
  6082. format = defaultFormat;
  6083. }
  6084. return format;
  6085. };
  6086. c3_chart_internal_fn.initGrid = function () {
  6087. var $$ = this,
  6088. config = $$.config,
  6089. d3 = $$.d3;
  6090. $$.grid = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid);
  6091. if (config.grid_x_show) {
  6092. $$.grid.append("g").attr("class", CLASS.xgrids);
  6093. }
  6094. if (config.grid_y_show) {
  6095. $$.grid.append('g').attr('class', CLASS.ygrids);
  6096. }
  6097. if (config.grid_focus_show) {
  6098. $$.grid.append('g').attr("class", CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus);
  6099. }
  6100. $$.xgrid = d3.selectAll([]);
  6101. if (!config.grid_lines_front) {
  6102. $$.initGridLines();
  6103. }
  6104. };
  6105. c3_chart_internal_fn.initGridLines = function () {
  6106. var $$ = this,
  6107. d3 = $$.d3;
  6108. $$.gridLines = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines);
  6109. $$.gridLines.append('g').attr("class", CLASS.xgridLines);
  6110. $$.gridLines.append('g').attr('class', CLASS.ygridLines);
  6111. $$.xgridLines = d3.selectAll([]);
  6112. };
  6113. c3_chart_internal_fn.updateXGrid = function (withoutUpdate) {
  6114. var $$ = this,
  6115. config = $$.config,
  6116. d3 = $$.d3,
  6117. xgridData = $$.generateGridData(config.grid_x_type, $$.x),
  6118. tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;
  6119. $$.xgridAttr = config.axis_rotated ? {
  6120. 'x1': 0,
  6121. 'x2': $$.width,
  6122. 'y1': function y1(d) {
  6123. return $$.x(d) - tickOffset;
  6124. },
  6125. 'y2': function y2(d) {
  6126. return $$.x(d) - tickOffset;
  6127. }
  6128. } : {
  6129. 'x1': function x1(d) {
  6130. return $$.x(d) + tickOffset;
  6131. },
  6132. 'x2': function x2(d) {
  6133. return $$.x(d) + tickOffset;
  6134. },
  6135. 'y1': 0,
  6136. 'y2': $$.height
  6137. };
  6138. $$.xgridAttr.opacity = function () {
  6139. var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');
  6140. return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1;
  6141. };
  6142. var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid).data(xgridData);
  6143. 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);
  6144. $$.xgrid = xgridEnter.merge(xgrid);
  6145. if (!withoutUpdate) {
  6146. $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity);
  6147. }
  6148. xgrid.exit().remove();
  6149. };
  6150. c3_chart_internal_fn.updateYGrid = function () {
  6151. var $$ = this,
  6152. config = $$.config,
  6153. gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);
  6154. var ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid).data(gridValues);
  6155. var ygridEnter = ygrid.enter().append('line')
  6156. // TODO: x1, x2, y1, y2, opacity need to be set here maybe
  6157. .attr('class', CLASS.ygrid);
  6158. $$.ygrid = ygridEnter.merge(ygrid);
  6159. $$.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);
  6160. ygrid.exit().remove();
  6161. $$.smoothLines($$.ygrid, 'grid');
  6162. };
  6163. c3_chart_internal_fn.gridTextAnchor = function (d) {
  6164. return d.position ? d.position : "end";
  6165. };
  6166. c3_chart_internal_fn.gridTextDx = function (d) {
  6167. return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4;
  6168. };
  6169. c3_chart_internal_fn.xGridTextX = function (d) {
  6170. return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0;
  6171. };
  6172. c3_chart_internal_fn.yGridTextX = function (d) {
  6173. return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width;
  6174. };
  6175. c3_chart_internal_fn.updateGrid = function (duration) {
  6176. var $$ = this,
  6177. main = $$.main,
  6178. config = $$.config,
  6179. xgridLine,
  6180. xgridLineEnter,
  6181. ygridLine,
  6182. ygridLineEnter,
  6183. xv = $$.xv.bind($$),
  6184. yv = $$.yv.bind($$),
  6185. xGridTextX = $$.xGridTextX.bind($$),
  6186. yGridTextX = $$.yGridTextX.bind($$);
  6187. // hide if arc type
  6188. $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  6189. main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  6190. if (config.grid_x_show) {
  6191. $$.updateXGrid();
  6192. }
  6193. xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine).data(config.grid_x_lines);
  6194. // enter
  6195. xgridLineEnter = xgridLine.enter().append('g').attr("class", function (d) {
  6196. return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '');
  6197. });
  6198. 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);
  6199. 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);
  6200. // udpate
  6201. $$.xgridLines = xgridLineEnter.merge(xgridLine);
  6202. // done in d3.transition() of the end of this function
  6203. // exit
  6204. xgridLine.exit().transition().duration(duration).style("opacity", 0).remove();
  6205. // Y-Grid
  6206. if (config.grid_y_show) {
  6207. $$.updateYGrid();
  6208. }
  6209. ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine).data(config.grid_y_lines);
  6210. // enter
  6211. ygridLineEnter = ygridLine.enter().append('g').attr("class", function (d) {
  6212. return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '');
  6213. });
  6214. 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);
  6215. 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);
  6216. // update
  6217. $$.ygridLines = ygridLineEnter.merge(ygridLine);
  6218. $$.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);
  6219. $$.ygridLines.select('text').transition().duration(duration).attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr("y", yv).text(function (d) {
  6220. return d.text;
  6221. }).style("opacity", 1);
  6222. // exit
  6223. ygridLine.exit().transition().duration(duration).style("opacity", 0).remove();
  6224. };
  6225. c3_chart_internal_fn.redrawGrid = function (withTransition, transition) {
  6226. var $$ = this,
  6227. config = $$.config,
  6228. xv = $$.xv.bind($$),
  6229. lines = $$.xgridLines.select('line'),
  6230. texts = $$.xgridLines.select('text');
  6231. 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) {
  6232. return d.text;
  6233. }).style("opacity", 1)];
  6234. };
  6235. c3_chart_internal_fn.showXGridFocus = function (selectedData) {
  6236. var $$ = this,
  6237. config = $$.config,
  6238. dataToShow = selectedData.filter(function (d) {
  6239. return d && isValue(d.value);
  6240. }),
  6241. focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),
  6242. xx = $$.xx.bind($$);
  6243. if (!config.tooltip_show) {
  6244. return;
  6245. }
  6246. // Hide when scatter plot exists
  6247. if ($$.hasType('scatter') || $$.hasArcType()) {
  6248. return;
  6249. }
  6250. focusEl.style("visibility", "visible").data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx);
  6251. $$.smoothLines(focusEl, 'grid');
  6252. };
  6253. c3_chart_internal_fn.hideXGridFocus = function () {
  6254. this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  6255. };
  6256. c3_chart_internal_fn.updateXgridFocus = function () {
  6257. var $$ = this,
  6258. config = $$.config;
  6259. $$.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);
  6260. };
  6261. c3_chart_internal_fn.generateGridData = function (type, scale) {
  6262. var $$ = this,
  6263. gridData = [],
  6264. xDomain,
  6265. firstYear,
  6266. lastYear,
  6267. i,
  6268. tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size();
  6269. if (type === 'year') {
  6270. xDomain = $$.getXDomain();
  6271. firstYear = xDomain[0].getFullYear();
  6272. lastYear = xDomain[1].getFullYear();
  6273. for (i = firstYear; i <= lastYear; i++) {
  6274. gridData.push(new Date(i + '-01-01 00:00:00'));
  6275. }
  6276. } else {
  6277. gridData = scale.ticks(10);
  6278. if (gridData.length > tickNum) {
  6279. // use only int
  6280. gridData = gridData.filter(function (d) {
  6281. return ("" + d).indexOf('.') < 0;
  6282. });
  6283. }
  6284. }
  6285. return gridData;
  6286. };
  6287. c3_chart_internal_fn.getGridFilterToRemove = function (params) {
  6288. return params ? function (line) {
  6289. var found = false;
  6290. [].concat(params).forEach(function (param) {
  6291. if ('value' in param && line.value === param.value || 'class' in param && line['class'] === param['class']) {
  6292. found = true;
  6293. }
  6294. });
  6295. return found;
  6296. } : function () {
  6297. return true;
  6298. };
  6299. };
  6300. c3_chart_internal_fn.removeGridLines = function (params, forX) {
  6301. var $$ = this,
  6302. config = $$.config,
  6303. toRemove = $$.getGridFilterToRemove(params),
  6304. toShow = function toShow(line) {
  6305. return !toRemove(line);
  6306. },
  6307. classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,
  6308. classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;
  6309. $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove).transition().duration(config.transition_duration).style('opacity', 0).remove();
  6310. if (forX) {
  6311. config.grid_x_lines = config.grid_x_lines.filter(toShow);
  6312. } else {
  6313. config.grid_y_lines = config.grid_y_lines.filter(toShow);
  6314. }
  6315. };
  6316. c3_chart_internal_fn.initEventRect = function () {
  6317. var $$ = this,
  6318. config = $$.config;
  6319. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.eventRects).style('fill-opacity', 0);
  6320. $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect').attr('class', CLASS.eventRect);
  6321. // event rect handle zoom event as well
  6322. if (config.zoom_enabled && $$.zoom) {
  6323. $$.eventRect.call($$.zoom).on("dblclick.zoom", null);
  6324. if (config.zoom_initialRange) {
  6325. // WORKAROUND: Add transition to apply transform immediately when no subchart
  6326. $$.eventRect.transition().duration(0).call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange));
  6327. }
  6328. }
  6329. };
  6330. c3_chart_internal_fn.redrawEventRect = function () {
  6331. var $$ = this,
  6332. d3 = $$.d3,
  6333. config = $$.config,
  6334. x,
  6335. y,
  6336. w,
  6337. h;
  6338. // TODO: rotated not supported yet
  6339. x = 0;
  6340. y = 0;
  6341. w = $$.width;
  6342. h = $$.height;
  6343. function mouseout() {
  6344. $$.svg.select('.' + CLASS.eventRect).style('cursor', null);
  6345. $$.hideXGridFocus();
  6346. $$.hideTooltip();
  6347. $$.unexpandCircles();
  6348. $$.unexpandBars();
  6349. }
  6350. // rects for mouseover
  6351. $$.main.select('.' + CLASS.eventRects).style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null);
  6352. $$.eventRect.attr('x', x).attr('y', y).attr('width', w).attr('height', h).on('mouseout', config.interaction_enabled ? function () {
  6353. if (!config) {
  6354. return;
  6355. } // chart is destroyed
  6356. if ($$.hasArcType()) {
  6357. return;
  6358. }
  6359. mouseout();
  6360. } : null).on('mousemove', config.interaction_enabled ? function () {
  6361. var targetsToShow, mouse, closest, sameXData, selectedData;
  6362. if ($$.dragging) {
  6363. return;
  6364. } // do nothing when dragging
  6365. if ($$.hasArcType(targetsToShow)) {
  6366. return;
  6367. }
  6368. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  6369. mouse = d3.mouse(this);
  6370. closest = $$.findClosestFromTargets(targetsToShow, mouse);
  6371. if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id)) {
  6372. config.data_onmouseout.call($$.api, $$.mouseover);
  6373. $$.mouseover = undefined;
  6374. }
  6375. if (!closest) {
  6376. mouseout();
  6377. return;
  6378. }
  6379. if ($$.isScatterType(closest) || !config.tooltip_grouped) {
  6380. sameXData = [closest];
  6381. } else {
  6382. sameXData = $$.filterByX(targetsToShow, closest.x);
  6383. }
  6384. // show tooltip when cursor is close to some point
  6385. selectedData = sameXData.map(function (d) {
  6386. return $$.addName(d);
  6387. });
  6388. $$.showTooltip(selectedData, this);
  6389. // expand points
  6390. if (config.point_focus_expand_enabled) {
  6391. $$.unexpandCircles();
  6392. selectedData.forEach(function (d) {
  6393. $$.expandCircles(d.index, d.id, false);
  6394. });
  6395. }
  6396. $$.expandBars(closest.index, closest.id, true);
  6397. // Show xgrid focus line
  6398. $$.showXGridFocus(selectedData);
  6399. // Show cursor as pointer if point is close to mouse position
  6400. if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
  6401. $$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer');
  6402. if (!$$.mouseover) {
  6403. config.data_onmouseover.call($$.api, closest);
  6404. $$.mouseover = closest;
  6405. }
  6406. }
  6407. } : null).on('click', config.interaction_enabled ? function () {
  6408. var targetsToShow, mouse, closest, sameXData;
  6409. if ($$.hasArcType(targetsToShow)) {
  6410. return;
  6411. }
  6412. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  6413. mouse = d3.mouse(this);
  6414. closest = $$.findClosestFromTargets(targetsToShow, mouse);
  6415. if (!closest) {
  6416. return;
  6417. }
  6418. // select if selection enabled
  6419. if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
  6420. if ($$.isScatterType(closest) || !config.data_selection_grouped) {
  6421. sameXData = [closest];
  6422. } else {
  6423. sameXData = $$.filterByX(targetsToShow, closest.x);
  6424. }
  6425. sameXData.forEach(function (d) {
  6426. $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.shape + '-' + d.index).each(function () {
  6427. if (config.data_selection_grouped || $$.isWithinShape(this, d)) {
  6428. $$.toggleShape(this, d, d.index);
  6429. config.data_onclick.call($$.api, d, this);
  6430. }
  6431. });
  6432. });
  6433. }
  6434. } : null).call(config.interaction_enabled && config.data_selection_draggable && $$.drag ? d3.drag().on('drag', function () {
  6435. $$.drag(d3.mouse(this));
  6436. }).on('start', function () {
  6437. $$.dragstart(d3.mouse(this));
  6438. }).on('end', function () {
  6439. $$.dragend();
  6440. }) : function () {});
  6441. };
  6442. c3_chart_internal_fn.getMousePosition = function (data) {
  6443. var $$ = this;
  6444. return [$$.x(data.x), $$.getYScale(data.id)(data.value)];
  6445. };
  6446. c3_chart_internal_fn.dispatchEvent = function (type, mouse) {
  6447. var $$ = this,
  6448. selector = '.' + CLASS.eventRect,
  6449. eventRect = $$.main.select(selector).node(),
  6450. box = eventRect.getBoundingClientRect(),
  6451. x = box.left + (mouse ? mouse[0] : 0),
  6452. y = box.top + (mouse ? mouse[1] : 0),
  6453. event = document.createEvent("MouseEvents");
  6454. event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null);
  6455. eventRect.dispatchEvent(event);
  6456. };
  6457. c3_chart_internal_fn.initLegend = function () {
  6458. var $$ = this;
  6459. $$.legendItemTextBox = {};
  6460. $$.legendHasRendered = false;
  6461. $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend'));
  6462. if (!$$.config.legend_show) {
  6463. $$.legend.style('visibility', 'hidden');
  6464. $$.hiddenLegendIds = $$.mapToIds($$.data.targets);
  6465. return;
  6466. }
  6467. // MEMO: call here to update legend box and tranlate for all
  6468. // MEMO: translate will be upated by this, so transform not needed in updateLegend()
  6469. $$.updateLegendWithDefaults();
  6470. };
  6471. c3_chart_internal_fn.updateLegendWithDefaults = function () {
  6472. var $$ = this;
  6473. $$.updateLegend($$.mapToIds($$.data.targets), { withTransform: false, withTransitionForTransform: false, withTransition: false });
  6474. };
  6475. c3_chart_internal_fn.updateSizeForLegend = function (legendHeight, legendWidth) {
  6476. var $$ = this,
  6477. config = $$.config,
  6478. insetLegendPosition = {
  6479. top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y,
  6480. left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5
  6481. };
  6482. $$.margin3 = {
  6483. top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight,
  6484. right: NaN,
  6485. bottom: 0,
  6486. left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0
  6487. };
  6488. };
  6489. c3_chart_internal_fn.transformLegend = function (withTransition) {
  6490. var $$ = this;
  6491. (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend'));
  6492. };
  6493. c3_chart_internal_fn.updateLegendStep = function (step) {
  6494. this.legendStep = step;
  6495. };
  6496. c3_chart_internal_fn.updateLegendItemWidth = function (w) {
  6497. this.legendItemWidth = w;
  6498. };
  6499. c3_chart_internal_fn.updateLegendItemHeight = function (h) {
  6500. this.legendItemHeight = h;
  6501. };
  6502. c3_chart_internal_fn.getLegendWidth = function () {
  6503. var $$ = this;
  6504. return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0;
  6505. };
  6506. c3_chart_internal_fn.getLegendHeight = function () {
  6507. var $$ = this,
  6508. h = 0;
  6509. if ($$.config.legend_show) {
  6510. if ($$.isLegendRight) {
  6511. h = $$.currentHeight;
  6512. } else {
  6513. h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);
  6514. }
  6515. }
  6516. return h;
  6517. };
  6518. c3_chart_internal_fn.opacityForLegend = function (legendItem) {
  6519. return legendItem.classed(CLASS.legendItemHidden) ? null : 1;
  6520. };
  6521. c3_chart_internal_fn.opacityForUnfocusedLegend = function (legendItem) {
  6522. return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3;
  6523. };
  6524. c3_chart_internal_fn.toggleFocusLegend = function (targetIds, focus) {
  6525. var $$ = this;
  6526. targetIds = $$.mapToTargetIds(targetIds);
  6527. $$.legend.selectAll('.' + CLASS.legendItem).filter(function (id) {
  6528. return targetIds.indexOf(id) >= 0;
  6529. }).classed(CLASS.legendItemFocused, focus).transition().duration(100).style('opacity', function () {
  6530. var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;
  6531. return opacity.call($$, $$.d3.select(this));
  6532. });
  6533. };
  6534. c3_chart_internal_fn.revertLegend = function () {
  6535. var $$ = this,
  6536. d3 = $$.d3;
  6537. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemFocused, false).transition().duration(100).style('opacity', function () {
  6538. return $$.opacityForLegend(d3.select(this));
  6539. });
  6540. };
  6541. c3_chart_internal_fn.showLegend = function (targetIds) {
  6542. var $$ = this,
  6543. config = $$.config;
  6544. if (!config.legend_show) {
  6545. config.legend_show = true;
  6546. $$.legend.style('visibility', 'visible');
  6547. if (!$$.legendHasRendered) {
  6548. $$.updateLegendWithDefaults();
  6549. }
  6550. }
  6551. $$.removeHiddenLegendIds(targetIds);
  6552. $$.legend.selectAll($$.selectorLegends(targetIds)).style('visibility', 'visible').transition().style('opacity', function () {
  6553. return $$.opacityForLegend($$.d3.select(this));
  6554. });
  6555. };
  6556. c3_chart_internal_fn.hideLegend = function (targetIds) {
  6557. var $$ = this,
  6558. config = $$.config;
  6559. if (config.legend_show && isEmpty(targetIds)) {
  6560. config.legend_show = false;
  6561. $$.legend.style('visibility', 'hidden');
  6562. }
  6563. $$.addHiddenLegendIds(targetIds);
  6564. $$.legend.selectAll($$.selectorLegends(targetIds)).style('opacity', 0).style('visibility', 'hidden');
  6565. };
  6566. c3_chart_internal_fn.clearLegendItemTextBoxCache = function () {
  6567. this.legendItemTextBox = {};
  6568. };
  6569. c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
  6570. var $$ = this,
  6571. config = $$.config;
  6572. var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile;
  6573. var paddingTop = 4,
  6574. paddingRight = 10,
  6575. maxWidth = 0,
  6576. maxHeight = 0,
  6577. posMin = 10,
  6578. tileWidth = config.legend_item_tile_width + 5;
  6579. var l,
  6580. totalLength = 0,
  6581. offsets = {},
  6582. widths = {},
  6583. heights = {},
  6584. margins = [0],
  6585. steps = {},
  6586. step = 0;
  6587. var withTransition, withTransitionForTransform;
  6588. var texts, rects, tiles, background;
  6589. // Skip elements when their name is set to null
  6590. targetIds = targetIds.filter(function (id) {
  6591. return !isDefined(config.data_names[id]) || config.data_names[id] !== null;
  6592. });
  6593. options = options || {};
  6594. withTransition = getOption(options, "withTransition", true);
  6595. withTransitionForTransform = getOption(options, "withTransitionForTransform", true);
  6596. function getTextBox(textElement, id) {
  6597. if (!$$.legendItemTextBox[id]) {
  6598. $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement);
  6599. }
  6600. return $$.legendItemTextBox[id];
  6601. }
  6602. function updatePositions(textElement, id, index) {
  6603. var reset = index === 0,
  6604. isLast = index === targetIds.length - 1,
  6605. box = getTextBox(textElement, id),
  6606. itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + config.legend_padding,
  6607. itemHeight = box.height + paddingTop,
  6608. itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,
  6609. areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(),
  6610. margin,
  6611. maxLength;
  6612. // MEMO: care about condifion of step, totalLength
  6613. function updateValues(id, withoutStep) {
  6614. if (!withoutStep) {
  6615. margin = (areaLength - totalLength - itemLength) / 2;
  6616. if (margin < posMin) {
  6617. margin = (areaLength - itemLength) / 2;
  6618. totalLength = 0;
  6619. step++;
  6620. }
  6621. }
  6622. steps[id] = step;
  6623. margins[step] = $$.isLegendInset ? 10 : margin;
  6624. offsets[id] = totalLength;
  6625. totalLength += itemLength;
  6626. }
  6627. if (reset) {
  6628. totalLength = 0;
  6629. step = 0;
  6630. maxWidth = 0;
  6631. maxHeight = 0;
  6632. }
  6633. if (config.legend_show && !$$.isLegendToShow(id)) {
  6634. widths[id] = heights[id] = steps[id] = offsets[id] = 0;
  6635. return;
  6636. }
  6637. widths[id] = itemWidth;
  6638. heights[id] = itemHeight;
  6639. if (!maxWidth || itemWidth >= maxWidth) {
  6640. maxWidth = itemWidth;
  6641. }
  6642. if (!maxHeight || itemHeight >= maxHeight) {
  6643. maxHeight = itemHeight;
  6644. }
  6645. maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;
  6646. if (config.legend_equally) {
  6647. Object.keys(widths).forEach(function (id) {
  6648. widths[id] = maxWidth;
  6649. });
  6650. Object.keys(heights).forEach(function (id) {
  6651. heights[id] = maxHeight;
  6652. });
  6653. margin = (areaLength - maxLength * targetIds.length) / 2;
  6654. if (margin < posMin) {
  6655. totalLength = 0;
  6656. step = 0;
  6657. targetIds.forEach(function (id) {
  6658. updateValues(id);
  6659. });
  6660. } else {
  6661. updateValues(id, true);
  6662. }
  6663. } else {
  6664. updateValues(id);
  6665. }
  6666. }
  6667. if ($$.isLegendInset) {
  6668. step = config.legend_inset_step ? config.legend_inset_step : targetIds.length;
  6669. $$.updateLegendStep(step);
  6670. }
  6671. if ($$.isLegendRight) {
  6672. xForLegend = function xForLegend(id) {
  6673. return maxWidth * steps[id];
  6674. };
  6675. yForLegend = function yForLegend(id) {
  6676. return margins[steps[id]] + offsets[id];
  6677. };
  6678. } else if ($$.isLegendInset) {
  6679. xForLegend = function xForLegend(id) {
  6680. return maxWidth * steps[id] + 10;
  6681. };
  6682. yForLegend = function yForLegend(id) {
  6683. return margins[steps[id]] + offsets[id];
  6684. };
  6685. } else {
  6686. xForLegend = function xForLegend(id) {
  6687. return margins[steps[id]] + offsets[id];
  6688. };
  6689. yForLegend = function yForLegend(id) {
  6690. return maxHeight * steps[id];
  6691. };
  6692. }
  6693. xForLegendText = function xForLegendText(id, i) {
  6694. return xForLegend(id, i) + 4 + config.legend_item_tile_width;
  6695. };
  6696. yForLegendText = function yForLegendText(id, i) {
  6697. return yForLegend(id, i) + 9;
  6698. };
  6699. xForLegendRect = function xForLegendRect(id, i) {
  6700. return xForLegend(id, i);
  6701. };
  6702. yForLegendRect = function yForLegendRect(id, i) {
  6703. return yForLegend(id, i) - 5;
  6704. };
  6705. x1ForLegendTile = function x1ForLegendTile(id, i) {
  6706. return xForLegend(id, i) - 2;
  6707. };
  6708. x2ForLegendTile = function x2ForLegendTile(id, i) {
  6709. return xForLegend(id, i) - 2 + config.legend_item_tile_width;
  6710. };
  6711. yForLegendTile = function yForLegendTile(id, i) {
  6712. return yForLegend(id, i) + 4;
  6713. };
  6714. // Define g for legend area
  6715. l = $$.legend.selectAll('.' + CLASS.legendItem).data(targetIds).enter().append('g').attr('class', function (id) {
  6716. return $$.generateClass(CLASS.legendItem, id);
  6717. }).style('visibility', function (id) {
  6718. return $$.isLegendToShow(id) ? 'visible' : 'hidden';
  6719. }).style('cursor', 'pointer').on('click', function (id) {
  6720. if (config.legend_item_onclick) {
  6721. config.legend_item_onclick.call($$, id);
  6722. } else {
  6723. if ($$.d3.event.altKey) {
  6724. $$.api.hide();
  6725. $$.api.show(id);
  6726. } else {
  6727. $$.api.toggle(id);
  6728. $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();
  6729. }
  6730. }
  6731. }).on('mouseover', function (id) {
  6732. if (config.legend_item_onmouseover) {
  6733. config.legend_item_onmouseover.call($$, id);
  6734. } else {
  6735. $$.d3.select(this).classed(CLASS.legendItemFocused, true);
  6736. if (!$$.transiting && $$.isTargetToShow(id)) {
  6737. $$.api.focus(id);
  6738. }
  6739. }
  6740. }).on('mouseout', function (id) {
  6741. if (config.legend_item_onmouseout) {
  6742. config.legend_item_onmouseout.call($$, id);
  6743. } else {
  6744. $$.d3.select(this).classed(CLASS.legendItemFocused, false);
  6745. $$.api.revert();
  6746. }
  6747. });
  6748. l.append('text').text(function (id) {
  6749. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  6750. }).each(function (id, i) {
  6751. updatePositions(this, id, i);
  6752. }).style("pointer-events", "none").attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);
  6753. l.append('rect').attr("class", CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);
  6754. 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);
  6755. // Set background for inset legend
  6756. background = $$.legend.select('.' + CLASS.legendBackground + ' rect');
  6757. if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {
  6758. background = $$.legend.insert('g', '.' + CLASS.legendItem).attr("class", CLASS.legendBackground).append('rect');
  6759. }
  6760. texts = $$.legend.selectAll('text').data(targetIds).text(function (id) {
  6761. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  6762. }) // MEMO: needed for update
  6763. .each(function (id, i) {
  6764. updatePositions(this, id, i);
  6765. });
  6766. (withTransition ? texts.transition() : texts).attr('x', xForLegendText).attr('y', yForLegendText);
  6767. rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds);
  6768. (withTransition ? rects.transition() : rects).attr('width', function (id) {
  6769. return widths[id];
  6770. }).attr('height', function (id) {
  6771. return heights[id];
  6772. }).attr('x', xForLegendRect).attr('y', yForLegendRect);
  6773. tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds);
  6774. (withTransition ? tiles.transition() : tiles).style('stroke', $$.levelColor ? function (id) {
  6775. return $$.levelColor($$.cache[id].values[0].value);
  6776. } : $$.color).attr('x1', x1ForLegendTile).attr('y1', yForLegendTile).attr('x2', x2ForLegendTile).attr('y2', yForLegendTile);
  6777. if (background) {
  6778. (withTransition ? background.transition() : background).attr('height', $$.getLegendHeight() - 12).attr('width', maxWidth * (step + 1) + 10);
  6779. }
  6780. // toggle legend state
  6781. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemHidden, function (id) {
  6782. return !$$.isTargetToShow(id);
  6783. });
  6784. // Update all to reflect change of legend
  6785. $$.updateLegendItemWidth(maxWidth);
  6786. $$.updateLegendItemHeight(maxHeight);
  6787. $$.updateLegendStep(step);
  6788. // Update size and scale
  6789. $$.updateSizes();
  6790. $$.updateScales();
  6791. $$.updateSvgSize();
  6792. // Update g positions
  6793. $$.transformAll(withTransitionForTransform, transitions);
  6794. $$.legendHasRendered = true;
  6795. };
  6796. c3_chart_internal_fn.initRegion = function () {
  6797. var $$ = this;
  6798. $$.region = $$.main.append('g').attr("clip-path", $$.clipPath).attr("class", CLASS.regions);
  6799. };
  6800. c3_chart_internal_fn.updateRegion = function (duration) {
  6801. var $$ = this,
  6802. config = $$.config;
  6803. // hide if arc type
  6804. $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  6805. var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region).data(config.regions);
  6806. var mainRegionEnter = mainRegion.enter().append('rect').attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", 0);
  6807. $$.mainRegion = mainRegionEnter.merge(mainRegion).attr('class', $$.classRegion.bind($$));
  6808. mainRegion.exit().transition().duration(duration).style("opacity", 0).remove();
  6809. };
  6810. c3_chart_internal_fn.redrawRegion = function (withTransition, transition) {
  6811. var $$ = this,
  6812. regions = $$.mainRegion;
  6813. 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) {
  6814. return isValue(d.opacity) ? d.opacity : 0.1;
  6815. })];
  6816. };
  6817. c3_chart_internal_fn.regionX = function (d) {
  6818. var $$ = this,
  6819. config = $$.config,
  6820. xPos,
  6821. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6822. if (d.axis === 'y' || d.axis === 'y2') {
  6823. xPos = config.axis_rotated ? 'start' in d ? yScale(d.start) : 0 : 0;
  6824. } else {
  6825. xPos = config.axis_rotated ? 0 : 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0;
  6826. }
  6827. return xPos;
  6828. };
  6829. c3_chart_internal_fn.regionY = function (d) {
  6830. var $$ = this,
  6831. config = $$.config,
  6832. yPos,
  6833. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6834. if (d.axis === 'y' || d.axis === 'y2') {
  6835. yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;
  6836. } else {
  6837. yPos = config.axis_rotated ? 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0 : 0;
  6838. }
  6839. return yPos;
  6840. };
  6841. c3_chart_internal_fn.regionWidth = function (d) {
  6842. var $$ = this,
  6843. config = $$.config,
  6844. start = $$.regionX(d),
  6845. end,
  6846. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6847. if (d.axis === 'y' || d.axis === 'y2') {
  6848. end = config.axis_rotated ? 'end' in d ? yScale(d.end) : $$.width : $$.width;
  6849. } else {
  6850. end = config.axis_rotated ? $$.width : 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width;
  6851. }
  6852. return end < start ? 0 : end - start;
  6853. };
  6854. c3_chart_internal_fn.regionHeight = function (d) {
  6855. var $$ = this,
  6856. config = $$.config,
  6857. start = this.regionY(d),
  6858. end,
  6859. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6860. if (d.axis === 'y' || d.axis === 'y2') {
  6861. end = config.axis_rotated ? $$.height : 'start' in d ? yScale(d.start) : $$.height;
  6862. } else {
  6863. end = config.axis_rotated ? 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height : $$.height;
  6864. }
  6865. return end < start ? 0 : end - start;
  6866. };
  6867. c3_chart_internal_fn.isRegionOnX = function (d) {
  6868. return !d.axis || d.axis === 'x';
  6869. };
  6870. c3_chart_internal_fn.getScale = function (min, max, forTimeseries) {
  6871. return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([min, max]);
  6872. };
  6873. c3_chart_internal_fn.getX = function (min, max, domain, offset) {
  6874. var $$ = this,
  6875. scale = $$.getScale(min, max, $$.isTimeSeries()),
  6876. _scale = domain ? scale.domain(domain) : scale,
  6877. key;
  6878. // Define customized scale if categorized axis
  6879. if ($$.isCategorized()) {
  6880. offset = offset || function () {
  6881. return 0;
  6882. };
  6883. scale = function scale(d, raw) {
  6884. var v = _scale(d) + offset(d);
  6885. return raw ? v : Math.ceil(v);
  6886. };
  6887. } else {
  6888. scale = function scale(d, raw) {
  6889. var v = _scale(d);
  6890. return raw ? v : Math.ceil(v);
  6891. };
  6892. }
  6893. // define functions
  6894. for (key in _scale) {
  6895. scale[key] = _scale[key];
  6896. }
  6897. scale.orgDomain = function () {
  6898. return _scale.domain();
  6899. };
  6900. // define custom domain() for categorized axis
  6901. if ($$.isCategorized()) {
  6902. scale.domain = function (domain) {
  6903. if (!arguments.length) {
  6904. domain = this.orgDomain();
  6905. return [domain[0], domain[1] + 1];
  6906. }
  6907. _scale.domain(domain);
  6908. return scale;
  6909. };
  6910. }
  6911. return scale;
  6912. };
  6913. c3_chart_internal_fn.getY = function (min, max, domain) {
  6914. var scale = this.getScale(min, max, this.isTimeSeriesY());
  6915. if (domain) {
  6916. scale.domain(domain);
  6917. }
  6918. return scale;
  6919. };
  6920. c3_chart_internal_fn.getYScale = function (id) {
  6921. return this.axis.getId(id) === 'y2' ? this.y2 : this.y;
  6922. };
  6923. c3_chart_internal_fn.getSubYScale = function (id) {
  6924. return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY;
  6925. };
  6926. c3_chart_internal_fn.updateScales = function () {
  6927. var $$ = this,
  6928. config = $$.config,
  6929. forInit = !$$.x;
  6930. // update edges
  6931. $$.xMin = config.axis_rotated ? 1 : 0;
  6932. $$.xMax = config.axis_rotated ? $$.height : $$.width;
  6933. $$.yMin = config.axis_rotated ? 0 : $$.height;
  6934. $$.yMax = config.axis_rotated ? $$.width : 1;
  6935. $$.subXMin = $$.xMin;
  6936. $$.subXMax = $$.xMax;
  6937. $$.subYMin = config.axis_rotated ? 0 : $$.height2;
  6938. $$.subYMax = config.axis_rotated ? $$.width2 : 1;
  6939. // update scales
  6940. $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () {
  6941. return $$.xAxis.tickOffset();
  6942. });
  6943. $$.y = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y_default : $$.y.domain());
  6944. $$.y2 = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y2_default : $$.y2.domain());
  6945. $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) {
  6946. return d % 1 ? 0 : $$.subXAxis.tickOffset();
  6947. });
  6948. $$.subY = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y_default : $$.subY.domain());
  6949. $$.subY2 = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y2_default : $$.subY2.domain());
  6950. // update axes
  6951. $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();
  6952. $$.xAxisTickValues = $$.axis.getXAxisTickValues();
  6953. $$.yAxisTickValues = $$.axis.getYAxisTickValues();
  6954. $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();
  6955. $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  6956. $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  6957. $$.yAxis = $$.axis.getYAxis($$.y, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, config.axis_y_tick_outer);
  6958. $$.y2Axis = $$.axis.getYAxis($$.y2, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, config.axis_y2_tick_outer);
  6959. // Set initialized scales to brush and zoom
  6960. if (!forInit) {
  6961. if ($$.brush) {
  6962. $$.brush.updateScale($$.subX);
  6963. }
  6964. }
  6965. // update for arc
  6966. if ($$.updateArc) {
  6967. $$.updateArc();
  6968. }
  6969. };
  6970. c3_chart_internal_fn.selectPoint = function (target, d, i) {
  6971. var $$ = this,
  6972. config = $$.config,
  6973. cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),
  6974. cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),
  6975. r = $$.pointSelectR.bind($$);
  6976. config.data_onselected.call($$.api, d, target.node());
  6977. // add selected-circle on low layer g
  6978. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr("class", function () {
  6979. return $$.generateClass(CLASS.selectedCircle, i);
  6980. }).attr("cx", cx).attr("cy", cy).attr("stroke", function () {
  6981. return $$.color(d);
  6982. }).attr("r", function (d) {
  6983. return $$.pointSelectR(d) * 1.4;
  6984. }).transition().duration(100).attr("r", r);
  6985. };
  6986. c3_chart_internal_fn.unselectPoint = function (target, d, i) {
  6987. var $$ = this;
  6988. $$.config.data_onunselected.call($$.api, d, target.node());
  6989. // remove selected-circle from low layer g
  6990. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).transition().duration(100).attr('r', 0).remove();
  6991. };
  6992. c3_chart_internal_fn.togglePoint = function (selected, target, d, i) {
  6993. selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);
  6994. };
  6995. c3_chart_internal_fn.selectPath = function (target, d) {
  6996. var $$ = this;
  6997. $$.config.data_onselected.call($$, d, target.node());
  6998. if ($$.config.interaction_brighten) {
  6999. target.transition().duration(100).style("fill", function () {
  7000. return $$.d3.rgb($$.color(d)).brighter(0.75);
  7001. });
  7002. }
  7003. };
  7004. c3_chart_internal_fn.unselectPath = function (target, d) {
  7005. var $$ = this;
  7006. $$.config.data_onunselected.call($$, d, target.node());
  7007. if ($$.config.interaction_brighten) {
  7008. target.transition().duration(100).style("fill", function () {
  7009. return $$.color(d);
  7010. });
  7011. }
  7012. };
  7013. c3_chart_internal_fn.togglePath = function (selected, target, d, i) {
  7014. selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);
  7015. };
  7016. c3_chart_internal_fn.getToggle = function (that, d) {
  7017. var $$ = this,
  7018. toggle;
  7019. if (that.nodeName === 'circle') {
  7020. if ($$.isStepType(d)) {
  7021. // circle is hidden in step chart, so treat as within the click area
  7022. toggle = function toggle() {}; // TODO: how to select step chart?
  7023. } else {
  7024. toggle = $$.togglePoint;
  7025. }
  7026. } else if (that.nodeName === 'path') {
  7027. toggle = $$.togglePath;
  7028. }
  7029. return toggle;
  7030. };
  7031. c3_chart_internal_fn.toggleShape = function (that, d, i) {
  7032. var $$ = this,
  7033. d3 = $$.d3,
  7034. config = $$.config,
  7035. shape = d3.select(that),
  7036. isSelected = shape.classed(CLASS.SELECTED),
  7037. toggle = $$.getToggle(that, d).bind($$);
  7038. if (config.data_selection_enabled && config.data_selection_isselectable(d)) {
  7039. if (!config.data_selection_multiple) {
  7040. $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) {
  7041. var shape = d3.select(this);
  7042. if (shape.classed(CLASS.SELECTED)) {
  7043. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  7044. }
  7045. });
  7046. }
  7047. shape.classed(CLASS.SELECTED, !isSelected);
  7048. toggle(!isSelected, shape, d, i);
  7049. }
  7050. };
  7051. c3_chart_internal_fn.initBar = function () {
  7052. var $$ = this;
  7053. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars);
  7054. };
  7055. c3_chart_internal_fn.updateTargetsForBar = function (targets) {
  7056. var $$ = this,
  7057. config = $$.config,
  7058. mainBars,
  7059. mainBarEnter,
  7060. classChartBar = $$.classChartBar.bind($$),
  7061. classBars = $$.classBars.bind($$),
  7062. classFocus = $$.classFocus.bind($$);
  7063. mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', function (d) {
  7064. return classChartBar(d) + classFocus(d);
  7065. });
  7066. mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style("pointer-events", "none");
  7067. // Bars for each data
  7068. mainBarEnter.append('g').attr("class", classBars).style("cursor", function (d) {
  7069. return config.data_selection_isselectable(d) ? "pointer" : null;
  7070. });
  7071. };
  7072. c3_chart_internal_fn.updateBar = function (durationForExit) {
  7073. var $$ = this,
  7074. barData = $$.barData.bind($$),
  7075. classBar = $$.classBar.bind($$),
  7076. initialOpacity = $$.initialOpacity.bind($$),
  7077. color = function color(d) {
  7078. return $$.color(d.id);
  7079. };
  7080. var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data(barData);
  7081. var mainBarEnter = mainBar.enter().append('path').attr("class", classBar).style("stroke", color).style("fill", color);
  7082. $$.mainBar = mainBarEnter.merge(mainBar).style("opacity", initialOpacity);
  7083. mainBar.exit().transition().duration(durationForExit).style("opacity", 0);
  7084. };
  7085. c3_chart_internal_fn.redrawBar = function (drawBar, withTransition, transition) {
  7086. return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style("stroke", this.color).style("fill", this.color).style("opacity", 1)];
  7087. };
  7088. c3_chart_internal_fn.getBarW = function (axis, barTargetsNum) {
  7089. var $$ = this,
  7090. config = $$.config,
  7091. w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? axis.tickInterval() * config.bar_width_ratio / barTargetsNum : 0;
  7092. return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w;
  7093. };
  7094. c3_chart_internal_fn.getBars = function (i, id) {
  7095. var $$ = this;
  7096. return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
  7097. };
  7098. c3_chart_internal_fn.expandBars = function (i, id, reset) {
  7099. var $$ = this;
  7100. if (reset) {
  7101. $$.unexpandBars();
  7102. }
  7103. $$.getBars(i, id).classed(CLASS.EXPANDED, true);
  7104. };
  7105. c3_chart_internal_fn.unexpandBars = function (i) {
  7106. var $$ = this;
  7107. $$.getBars(i).classed(CLASS.EXPANDED, false);
  7108. };
  7109. c3_chart_internal_fn.generateDrawBar = function (barIndices, isSub) {
  7110. var $$ = this,
  7111. config = $$.config,
  7112. getPoints = $$.generateGetBarPoints(barIndices, isSub);
  7113. return function (d, i) {
  7114. // 4 points that make a bar
  7115. var points = getPoints(d, i);
  7116. // switch points if axis is rotated, not applicable for sub chart
  7117. var indexX = config.axis_rotated ? 1 : 0;
  7118. var indexY = config.axis_rotated ? 0 : 1;
  7119. 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';
  7120. return path;
  7121. };
  7122. };
  7123. c3_chart_internal_fn.generateGetBarPoints = function (barIndices, isSub) {
  7124. var $$ = this,
  7125. axis = isSub ? $$.subXAxis : $$.xAxis,
  7126. barTargetsNum = barIndices.__max__ + 1,
  7127. barW = $$.getBarW(axis, barTargetsNum),
  7128. barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),
  7129. barY = $$.getShapeY(!!isSub),
  7130. barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),
  7131. barSpaceOffset = barW * ($$.config.bar_space / 2),
  7132. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  7133. return function (d, i) {
  7134. var y0 = yScale.call($$, d.id)(0),
  7135. offset = barOffset(d, i) || y0,
  7136. // offset is for stacked bar chart
  7137. posX = barX(d),
  7138. posY = barY(d);
  7139. // fix posY not to overflow opposite quadrant
  7140. if ($$.config.axis_rotated) {
  7141. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  7142. posY = y0;
  7143. }
  7144. }
  7145. // 4 points that make a bar
  7146. return [[posX + barSpaceOffset, offset], [posX + barSpaceOffset, posY - (y0 - offset)], [posX + barW - barSpaceOffset, posY - (y0 - offset)], [posX + barW - barSpaceOffset, offset]];
  7147. };
  7148. };
  7149. c3_chart_internal_fn.isWithinBar = function (mouse, that) {
  7150. var box = that.getBoundingClientRect(),
  7151. seg0 = that.pathSegList.getItem(0),
  7152. seg1 = that.pathSegList.getItem(1),
  7153. x = Math.min(seg0.x, seg1.x),
  7154. y = Math.min(seg0.y, seg1.y),
  7155. w = box.width,
  7156. h = box.height,
  7157. offset = 2,
  7158. sx = x - offset,
  7159. ex = x + w + offset,
  7160. sy = y + h + offset,
  7161. ey = y - offset;
  7162. return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy;
  7163. };
  7164. c3_chart_internal_fn.getShapeIndices = function (typeFilter) {
  7165. var $$ = this,
  7166. config = $$.config,
  7167. indices = {},
  7168. i = 0,
  7169. j,
  7170. k;
  7171. $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {
  7172. for (j = 0; j < config.data_groups.length; j++) {
  7173. if (config.data_groups[j].indexOf(d.id) < 0) {
  7174. continue;
  7175. }
  7176. for (k = 0; k < config.data_groups[j].length; k++) {
  7177. if (config.data_groups[j][k] in indices) {
  7178. indices[d.id] = indices[config.data_groups[j][k]];
  7179. break;
  7180. }
  7181. }
  7182. }
  7183. if (isUndefined(indices[d.id])) {
  7184. indices[d.id] = i++;
  7185. }
  7186. });
  7187. indices.__max__ = i - 1;
  7188. return indices;
  7189. };
  7190. c3_chart_internal_fn.getShapeX = function (offset, targetsNum, indices, isSub) {
  7191. var $$ = this,
  7192. scale = isSub ? $$.subX : $$.x;
  7193. return function (d) {
  7194. var index = d.id in indices ? indices[d.id] : 0;
  7195. return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;
  7196. };
  7197. };
  7198. c3_chart_internal_fn.getShapeY = function (isSub) {
  7199. var $$ = this;
  7200. return function (d) {
  7201. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);
  7202. return scale(d.value);
  7203. };
  7204. };
  7205. c3_chart_internal_fn.getShapeOffset = function (typeFilter, indices, isSub) {
  7206. var $$ = this,
  7207. targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))),
  7208. targetIds = targets.map(function (t) {
  7209. return t.id;
  7210. });
  7211. return function (d, i) {
  7212. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),
  7213. y0 = scale(0),
  7214. offset = y0;
  7215. targets.forEach(function (t) {
  7216. var values = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values;
  7217. if (t.id === d.id || indices[t.id] !== indices[d.id]) {
  7218. return;
  7219. }
  7220. if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {
  7221. // check if the x values line up
  7222. if (typeof values[i] === 'undefined' || +values[i].x !== +d.x) {
  7223. // "+" for timeseries
  7224. // if not, try to find the value that does line up
  7225. i = -1;
  7226. values.forEach(function (v, j) {
  7227. if (v.x === d.x) {
  7228. i = j;
  7229. }
  7230. });
  7231. }
  7232. if (i in values && values[i].value * d.value >= 0) {
  7233. offset += scale(values[i].value) - y0;
  7234. }
  7235. }
  7236. });
  7237. return offset;
  7238. };
  7239. };
  7240. c3_chart_internal_fn.isWithinShape = function (that, d) {
  7241. var $$ = this,
  7242. shape = $$.d3.select(that),
  7243. isWithin;
  7244. if (!$$.isTargetToShow(d.id)) {
  7245. isWithin = false;
  7246. } else if (that.nodeName === 'circle') {
  7247. isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);
  7248. } else if (that.nodeName === 'path') {
  7249. isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar($$.d3.mouse(that), that) : true;
  7250. }
  7251. return isWithin;
  7252. };
  7253. c3_chart_internal_fn.getInterpolate = function (d) {
  7254. var $$ = this,
  7255. d3 = $$.d3,
  7256. types = {
  7257. 'linear': d3.curveLinear,
  7258. 'linear-closed': d3.curveLinearClosed,
  7259. 'basis': d3.curveBasis,
  7260. 'basis-open': d3.curveBasisOpen,
  7261. 'basis-closed': d3.curveBasisClosed,
  7262. 'bundle': d3.curveBundle,
  7263. 'cardinal': d3.curveCardinal,
  7264. 'cardinal-open': d3.curveCardinalOpen,
  7265. 'cardinal-closed': d3.curveCardinalClosed,
  7266. 'monotone': d3.curveMonotoneX,
  7267. 'step': d3.curveStep
  7268. },
  7269. type;
  7270. if ($$.isSplineType(d)) {
  7271. type = types[$$.config.spline_interpolation_type] || types.cardinal;
  7272. } else if ($$.isStepType(d)) {
  7273. type = types[$$.config.line_step_type];
  7274. } else {
  7275. type = types.linear;
  7276. }
  7277. return type;
  7278. };
  7279. c3_chart_internal_fn.initLine = function () {
  7280. var $$ = this;
  7281. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines);
  7282. };
  7283. c3_chart_internal_fn.updateTargetsForLine = function (targets) {
  7284. var $$ = this,
  7285. config = $$.config,
  7286. mainLines,
  7287. mainLineEnter,
  7288. classChartLine = $$.classChartLine.bind($$),
  7289. classLines = $$.classLines.bind($$),
  7290. classAreas = $$.classAreas.bind($$),
  7291. classCircles = $$.classCircles.bind($$),
  7292. classFocus = $$.classFocus.bind($$);
  7293. mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', function (d) {
  7294. return classChartLine(d) + classFocus(d);
  7295. });
  7296. mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style("pointer-events", "none");
  7297. // Lines for each data
  7298. mainLineEnter.append('g').attr("class", classLines);
  7299. // Areas
  7300. mainLineEnter.append('g').attr('class', classAreas);
  7301. // Circles for each data point on lines
  7302. mainLineEnter.append('g').attr("class", function (d) {
  7303. return $$.generateClass(CLASS.selectedCircles, d.id);
  7304. });
  7305. mainLineEnter.append('g').attr("class", classCircles).style("cursor", function (d) {
  7306. return config.data_selection_isselectable(d) ? "pointer" : null;
  7307. });
  7308. // Update date for selected circles
  7309. targets.forEach(function (t) {
  7310. $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) {
  7311. d.value = t.values[d.index].value;
  7312. });
  7313. });
  7314. // MEMO: can not keep same color...
  7315. //mainLineUpdate.exit().remove();
  7316. };
  7317. c3_chart_internal_fn.updateLine = function (durationForExit) {
  7318. var $$ = this;
  7319. var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  7320. var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style("stroke", $$.color);
  7321. $$.mainLine = mainLineEnter.merge(mainLine).style("opacity", $$.initialOpacity.bind($$)).style('shape-rendering', function (d) {
  7322. return $$.isStepType(d) ? 'crispEdges' : '';
  7323. }).attr('transform', null);
  7324. mainLine.exit().transition().duration(durationForExit).style('opacity', 0);
  7325. };
  7326. c3_chart_internal_fn.redrawLine = function (drawLine, withTransition, transition) {
  7327. return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr("d", drawLine).style("stroke", this.color).style("opacity", 1)];
  7328. };
  7329. c3_chart_internal_fn.generateDrawLine = function (lineIndices, isSub) {
  7330. var $$ = this,
  7331. config = $$.config,
  7332. line = $$.d3.line(),
  7333. getPoints = $$.generateGetLinePoints(lineIndices, isSub),
  7334. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  7335. xValue = function xValue(d) {
  7336. return (isSub ? $$.subxx : $$.xx).call($$, d);
  7337. },
  7338. yValue = function yValue(d, i) {
  7339. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value);
  7340. };
  7341. line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue);
  7342. if (!config.line_connectNull) {
  7343. line = line.defined(function (d) {
  7344. return d.value != null;
  7345. });
  7346. }
  7347. return function (d) {
  7348. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  7349. x = isSub ? $$.subX : $$.x,
  7350. y = yScaleGetter.call($$, d.id),
  7351. x0 = 0,
  7352. y0 = 0,
  7353. path;
  7354. if ($$.isLineType(d)) {
  7355. if (config.data_regions[d.id]) {
  7356. path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);
  7357. } else {
  7358. if ($$.isStepType(d)) {
  7359. values = $$.convertValuesToStep(values);
  7360. }
  7361. path = line.curve($$.getInterpolate(d))(values);
  7362. }
  7363. } else {
  7364. if (values[0]) {
  7365. x0 = x(values[0].x);
  7366. y0 = y(values[0].value);
  7367. }
  7368. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  7369. }
  7370. return path ? path : "M 0 0";
  7371. };
  7372. };
  7373. c3_chart_internal_fn.generateGetLinePoints = function (lineIndices, isSub) {
  7374. // partial duplication of generateGetBarPoints
  7375. var $$ = this,
  7376. config = $$.config,
  7377. lineTargetsNum = lineIndices.__max__ + 1,
  7378. x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),
  7379. y = $$.getShapeY(!!isSub),
  7380. lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),
  7381. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  7382. return function (d, i) {
  7383. var y0 = yScale.call($$, d.id)(0),
  7384. offset = lineOffset(d, i) || y0,
  7385. // offset is for stacked area chart
  7386. posX = x(d),
  7387. posY = y(d);
  7388. // fix posY not to overflow opposite quadrant
  7389. if (config.axis_rotated) {
  7390. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  7391. posY = y0;
  7392. }
  7393. }
  7394. // 1 point that marks the line position
  7395. return [[posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  7396. [posX, posY - (y0 - offset)], // needed for compatibility
  7397. [posX, posY - (y0 - offset)] // needed for compatibility
  7398. ];
  7399. };
  7400. };
  7401. c3_chart_internal_fn.lineWithRegions = function (d, x, y, _regions) {
  7402. var $$ = this,
  7403. config = $$.config,
  7404. prev = -1,
  7405. i,
  7406. j,
  7407. s = "M",
  7408. sWithRegion,
  7409. xp,
  7410. yp,
  7411. dx,
  7412. dy,
  7413. dd,
  7414. diff,
  7415. diffx2,
  7416. xOffset = $$.isCategorized() ? 0.5 : 0,
  7417. xValue,
  7418. yValue,
  7419. regions = [];
  7420. function isWithinRegions(x, regions) {
  7421. var i;
  7422. for (i = 0; i < regions.length; i++) {
  7423. if (regions[i].start < x && x <= regions[i].end) {
  7424. return true;
  7425. }
  7426. }
  7427. return false;
  7428. }
  7429. // Check start/end of regions
  7430. if (isDefined(_regions)) {
  7431. for (i = 0; i < _regions.length; i++) {
  7432. regions[i] = {};
  7433. if (isUndefined(_regions[i].start)) {
  7434. regions[i].start = d[0].x;
  7435. } else {
  7436. regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start;
  7437. }
  7438. if (isUndefined(_regions[i].end)) {
  7439. regions[i].end = d[d.length - 1].x;
  7440. } else {
  7441. regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end;
  7442. }
  7443. }
  7444. }
  7445. // Set scales
  7446. xValue = config.axis_rotated ? function (d) {
  7447. return y(d.value);
  7448. } : function (d) {
  7449. return x(d.x);
  7450. };
  7451. yValue = config.axis_rotated ? function (d) {
  7452. return x(d.x);
  7453. } : function (d) {
  7454. return y(d.value);
  7455. };
  7456. // Define svg generator function for region
  7457. function generateM(points) {
  7458. return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1];
  7459. }
  7460. if ($$.isTimeSeries()) {
  7461. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  7462. var x0 = d0.x.getTime(),
  7463. x_diff = d1.x - d0.x,
  7464. xv0 = new Date(x0 + x_diff * j),
  7465. xv1 = new Date(x0 + x_diff * (j + diff)),
  7466. points;
  7467. if (config.axis_rotated) {
  7468. points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]];
  7469. } else {
  7470. points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]];
  7471. }
  7472. return generateM(points);
  7473. };
  7474. } else {
  7475. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  7476. var points;
  7477. if (config.axis_rotated) {
  7478. points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]];
  7479. } else {
  7480. points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]];
  7481. }
  7482. return generateM(points);
  7483. };
  7484. }
  7485. // Generate
  7486. for (i = 0; i < d.length; i++) {
  7487. // Draw as normal
  7488. if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {
  7489. s += " " + xValue(d[i]) + " " + yValue(d[i]);
  7490. }
  7491. // Draw with region // TODO: Fix for horizotal charts
  7492. else {
  7493. xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries());
  7494. yp = $$.getScale(d[i - 1].value, d[i].value);
  7495. dx = x(d[i].x) - x(d[i - 1].x);
  7496. dy = y(d[i].value) - y(d[i - 1].value);
  7497. dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
  7498. diff = 2 / dd;
  7499. diffx2 = diff * 2;
  7500. for (j = diff; j <= 1; j += diffx2) {
  7501. s += sWithRegion(d[i - 1], d[i], j, diff);
  7502. }
  7503. }
  7504. prev = d[i].x;
  7505. }
  7506. return s;
  7507. };
  7508. c3_chart_internal_fn.updateArea = function (durationForExit) {
  7509. var $$ = this,
  7510. d3 = $$.d3;
  7511. var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  7512. var mainAreaEnter = mainArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  7513. $$.orgAreaOpacity = +d3.select(this).style('opacity');return 0;
  7514. });
  7515. $$.mainArea = mainAreaEnter.merge(mainArea).style("opacity", $$.orgAreaOpacity);
  7516. mainArea.exit().transition().duration(durationForExit).style('opacity', 0);
  7517. };
  7518. c3_chart_internal_fn.redrawArea = function (drawArea, withTransition, transition) {
  7519. return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr("d", drawArea).style("fill", this.color).style("opacity", this.orgAreaOpacity)];
  7520. };
  7521. c3_chart_internal_fn.generateDrawArea = function (areaIndices, isSub) {
  7522. var $$ = this,
  7523. config = $$.config,
  7524. area = $$.d3.area(),
  7525. getPoints = $$.generateGetAreaPoints(areaIndices, isSub),
  7526. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  7527. xValue = function xValue(d) {
  7528. return (isSub ? $$.subxx : $$.xx).call($$, d);
  7529. },
  7530. value0 = function value0(d, i) {
  7531. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id));
  7532. },
  7533. value1 = function value1(d, i) {
  7534. return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value);
  7535. };
  7536. area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1);
  7537. if (!config.line_connectNull) {
  7538. area = area.defined(function (d) {
  7539. return d.value !== null;
  7540. });
  7541. }
  7542. return function (d) {
  7543. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  7544. x0 = 0,
  7545. y0 = 0,
  7546. path;
  7547. if ($$.isAreaType(d)) {
  7548. if ($$.isStepType(d)) {
  7549. values = $$.convertValuesToStep(values);
  7550. }
  7551. path = area.curve($$.getInterpolate(d))(values);
  7552. } else {
  7553. if (values[0]) {
  7554. x0 = $$.x(values[0].x);
  7555. y0 = $$.getYScale(d.id)(values[0].value);
  7556. }
  7557. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  7558. }
  7559. return path ? path : "M 0 0";
  7560. };
  7561. };
  7562. c3_chart_internal_fn.getAreaBaseValue = function () {
  7563. return 0;
  7564. };
  7565. c3_chart_internal_fn.generateGetAreaPoints = function (areaIndices, isSub) {
  7566. // partial duplication of generateGetBarPoints
  7567. var $$ = this,
  7568. config = $$.config,
  7569. areaTargetsNum = areaIndices.__max__ + 1,
  7570. x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),
  7571. y = $$.getShapeY(!!isSub),
  7572. areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),
  7573. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  7574. return function (d, i) {
  7575. var y0 = yScale.call($$, d.id)(0),
  7576. offset = areaOffset(d, i) || y0,
  7577. // offset is for stacked area chart
  7578. posX = x(d),
  7579. posY = y(d);
  7580. // fix posY not to overflow opposite quadrant
  7581. if (config.axis_rotated) {
  7582. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  7583. posY = y0;
  7584. }
  7585. }
  7586. // 1 point that marks the area position
  7587. return [[posX, offset], [posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  7588. [posX, offset] // needed for compatibility
  7589. ];
  7590. };
  7591. };
  7592. c3_chart_internal_fn.updateCircle = function (cx, cy) {
  7593. var $$ = this;
  7594. var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle).data($$.lineOrScatterData.bind($$));
  7595. var mainCircleEnter = mainCircle.enter().append("circle").attr("class", $$.classCircle.bind($$)).attr("cx", cx).attr("cy", cy).attr("r", $$.pointR.bind($$)).style("fill", $$.color);
  7596. $$.mainCircle = mainCircleEnter.merge(mainCircle).style("opacity", $$.initialOpacityForCircle.bind($$));
  7597. mainCircle.exit().style("opacity", 0);
  7598. };
  7599. c3_chart_internal_fn.redrawCircle = function (cx, cy, withTransition, transition) {
  7600. var $$ = this,
  7601. selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);
  7602. return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style("fill", $$.color).attr("cx", cx).attr("cy", cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr("cx", cx).attr("cy", cy)];
  7603. };
  7604. c3_chart_internal_fn.circleX = function (d) {
  7605. return d.x || d.x === 0 ? this.x(d.x) : null;
  7606. };
  7607. c3_chart_internal_fn.updateCircleY = function () {
  7608. var $$ = this,
  7609. lineIndices,
  7610. getPoints;
  7611. if ($$.config.data_groups.length > 0) {
  7612. lineIndices = $$.getShapeIndices($$.isLineType), getPoints = $$.generateGetLinePoints(lineIndices);
  7613. $$.circleY = function (d, i) {
  7614. return getPoints(d, i)[0][1];
  7615. };
  7616. } else {
  7617. $$.circleY = function (d) {
  7618. return $$.getYScale(d.id)(d.value);
  7619. };
  7620. }
  7621. };
  7622. c3_chart_internal_fn.getCircles = function (i, id) {
  7623. var $$ = this;
  7624. return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
  7625. };
  7626. c3_chart_internal_fn.expandCircles = function (i, id, reset) {
  7627. var $$ = this,
  7628. r = $$.pointExpandedR.bind($$);
  7629. if (reset) {
  7630. $$.unexpandCircles();
  7631. }
  7632. $$.getCircles(i, id).classed(CLASS.EXPANDED, true).attr('r', r);
  7633. };
  7634. c3_chart_internal_fn.unexpandCircles = function (i) {
  7635. var $$ = this,
  7636. r = $$.pointR.bind($$);
  7637. $$.getCircles(i).filter(function () {
  7638. return $$.d3.select(this).classed(CLASS.EXPANDED);
  7639. }).classed(CLASS.EXPANDED, false).attr('r', r);
  7640. };
  7641. c3_chart_internal_fn.pointR = function (d) {
  7642. var $$ = this,
  7643. config = $$.config;
  7644. return $$.isStepType(d) ? 0 : isFunction(config.point_r) ? config.point_r(d) : config.point_r;
  7645. };
  7646. c3_chart_internal_fn.pointExpandedR = function (d) {
  7647. var $$ = this,
  7648. config = $$.config;
  7649. if (config.point_focus_expand_enabled) {
  7650. 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;
  7651. } else {
  7652. return $$.pointR(d);
  7653. }
  7654. };
  7655. c3_chart_internal_fn.pointSelectR = function (d) {
  7656. var $$ = this,
  7657. config = $$.config;
  7658. return isFunction(config.point_select_r) ? config.point_select_r(d) : config.point_select_r ? config.point_select_r : $$.pointR(d) * 4;
  7659. };
  7660. c3_chart_internal_fn.isWithinCircle = function (that, r) {
  7661. var d3 = this.d3,
  7662. mouse = d3.mouse(that),
  7663. d3_this = d3.select(that),
  7664. cx = +d3_this.attr("cx"),
  7665. cy = +d3_this.attr("cy");
  7666. return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r;
  7667. };
  7668. c3_chart_internal_fn.isWithinStep = function (that, y) {
  7669. return Math.abs(y - this.d3.mouse(that)[1]) < 30;
  7670. };
  7671. c3_chart_internal_fn.getCurrentWidth = function () {
  7672. var $$ = this,
  7673. config = $$.config;
  7674. return config.size_width ? config.size_width : $$.getParentWidth();
  7675. };
  7676. c3_chart_internal_fn.getCurrentHeight = function () {
  7677. var $$ = this,
  7678. config = $$.config,
  7679. h = config.size_height ? config.size_height : $$.getParentHeight();
  7680. return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);
  7681. };
  7682. c3_chart_internal_fn.getCurrentPaddingTop = function () {
  7683. var $$ = this,
  7684. config = $$.config,
  7685. padding = isValue(config.padding_top) ? config.padding_top : 0;
  7686. if ($$.title && $$.title.node()) {
  7687. padding += $$.getTitlePadding();
  7688. }
  7689. return padding;
  7690. };
  7691. c3_chart_internal_fn.getCurrentPaddingBottom = function () {
  7692. var config = this.config;
  7693. return isValue(config.padding_bottom) ? config.padding_bottom : 0;
  7694. };
  7695. c3_chart_internal_fn.getCurrentPaddingLeft = function (withoutRecompute) {
  7696. var $$ = this,
  7697. config = $$.config;
  7698. if (isValue(config.padding_left)) {
  7699. return config.padding_left;
  7700. } else if (config.axis_rotated) {
  7701. return !config.axis_x_show || config.axis_x_inner ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);
  7702. } else if (!config.axis_y_show || config.axis_y_inner) {
  7703. // && !config.axis_rotated
  7704. return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1;
  7705. } else {
  7706. return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));
  7707. }
  7708. };
  7709. c3_chart_internal_fn.getCurrentPaddingRight = function () {
  7710. var $$ = this,
  7711. config = $$.config,
  7712. defaultPadding = 10,
  7713. legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;
  7714. if (isValue(config.padding_right)) {
  7715. return config.padding_right + 1; // 1 is needed not to hide tick line
  7716. } else if (config.axis_rotated) {
  7717. return defaultPadding + legendWidthOnRight;
  7718. } else if (!config.axis_y2_show || config.axis_y2_inner) {
  7719. // && !config.axis_rotated
  7720. return 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);
  7721. } else {
  7722. return ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;
  7723. }
  7724. };
  7725. c3_chart_internal_fn.getParentRectValue = function (key) {
  7726. var parent = this.selectChart.node(),
  7727. v;
  7728. while (parent && parent.tagName !== 'BODY') {
  7729. try {
  7730. v = parent.getBoundingClientRect()[key];
  7731. } catch (e) {
  7732. if (key === 'width') {
  7733. // In IE in certain cases getBoundingClientRect
  7734. // will cause an "unspecified error"
  7735. v = parent.offsetWidth;
  7736. }
  7737. }
  7738. if (v) {
  7739. break;
  7740. }
  7741. parent = parent.parentNode;
  7742. }
  7743. return v;
  7744. };
  7745. c3_chart_internal_fn.getParentWidth = function () {
  7746. return this.getParentRectValue('width');
  7747. };
  7748. c3_chart_internal_fn.getParentHeight = function () {
  7749. var h = this.selectChart.style('height');
  7750. return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;
  7751. };
  7752. c3_chart_internal_fn.getSvgLeft = function (withoutRecompute) {
  7753. var $$ = this,
  7754. config = $$.config,
  7755. hasLeftAxisRect = config.axis_rotated || !config.axis_rotated && !config.axis_y_inner,
  7756. leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,
  7757. leftAxis = $$.main.select('.' + leftAxisClass).node(),
  7758. svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : { right: 0 },
  7759. chartRect = $$.selectChart.node().getBoundingClientRect(),
  7760. hasArc = $$.hasArcType(),
  7761. svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));
  7762. return svgLeft > 0 ? svgLeft : 0;
  7763. };
  7764. c3_chart_internal_fn.getAxisWidthByAxisId = function (id, withoutRecompute) {
  7765. var $$ = this,
  7766. position = $$.axis.getLabelPositionById(id);
  7767. return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40);
  7768. };
  7769. c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) {
  7770. var $$ = this,
  7771. config = $$.config,
  7772. h = 30;
  7773. if (axisId === 'x' && !config.axis_x_show) {
  7774. return 8;
  7775. }
  7776. if (axisId === 'x' && config.axis_x_height) {
  7777. return config.axis_x_height;
  7778. }
  7779. if (axisId === 'y' && !config.axis_y_show) {
  7780. return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;
  7781. }
  7782. if (axisId === 'y2' && !config.axis_y2_show) {
  7783. return $$.rotated_padding_top;
  7784. }
  7785. // Calculate x axis height when tick rotated
  7786. if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
  7787. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_x_tick_rotate)) / 180);
  7788. }
  7789. // Calculate y axis height when tick rotated
  7790. if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {
  7791. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_y_tick_rotate)) / 180);
  7792. }
  7793. return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0);
  7794. };
  7795. c3_chart_internal_fn.initBrush = function (scale) {
  7796. var $$ = this,
  7797. d3 = $$.d3;
  7798. // TODO: dynamically change brushY/brushX according to axis_rotated.
  7799. $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () {
  7800. var event = d3.event.sourceEvent;
  7801. if (event && event.type === "zoom") {
  7802. return;
  7803. }
  7804. $$.redrawForBrush();
  7805. }).on("end", function () {
  7806. var event = d3.event.sourceEvent;
  7807. if (event && event.type === "zoom") {
  7808. return;
  7809. }
  7810. if ($$.brush.empty() && event && event.type !== 'end') {
  7811. $$.brush.clear();
  7812. }
  7813. });
  7814. $$.brush.updateExtent = function () {
  7815. var range = this.scale.range(),
  7816. extent;
  7817. if ($$.config.axis_rotated) {
  7818. extent = [[0, range[0]], [$$.width2, range[1]]];
  7819. } else {
  7820. extent = [[range[0], 0], [range[1], $$.height2]];
  7821. }
  7822. this.extent(extent);
  7823. return this;
  7824. };
  7825. $$.brush.updateScale = function (scale) {
  7826. this.scale = scale;
  7827. return this;
  7828. };
  7829. $$.brush.update = function (scale) {
  7830. this.updateScale(scale || $$.subX).updateExtent();
  7831. $$.context.select('.' + CLASS.brush).call(this);
  7832. };
  7833. $$.brush.clear = function () {
  7834. $$.context.select('.' + CLASS.brush).call($$.brush.move, null);
  7835. };
  7836. $$.brush.selection = function () {
  7837. return d3.brushSelection($$.context.select('.' + CLASS.brush).node());
  7838. };
  7839. $$.brush.selectionAsValue = function (selectionAsValue, withTransition) {
  7840. var selection, brush;
  7841. if (selectionAsValue) {
  7842. if ($$.context) {
  7843. selection = [this.scale(selectionAsValue[0]), this.scale(selectionAsValue[1])];
  7844. brush = $$.context.select('.' + CLASS.brush);
  7845. if (withTransition) {
  7846. brush = brush.transition();
  7847. }
  7848. $$.brush.move(brush, selection);
  7849. }
  7850. return [];
  7851. }
  7852. selection = $$.brush.selection() || [0, 0];
  7853. return [this.scale.invert(selection[0]), this.scale.invert(selection[1])];
  7854. };
  7855. $$.brush.empty = function () {
  7856. var selection = $$.brush.selection();
  7857. return !selection || selection[0] === selection[1];
  7858. };
  7859. return $$.brush.updateScale(scale);
  7860. };
  7861. c3_chart_internal_fn.initSubchart = function () {
  7862. var $$ = this,
  7863. config = $$.config,
  7864. context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')),
  7865. visibility = config.subchart_show ? 'visible' : 'hidden';
  7866. // set style
  7867. context.style('visibility', visibility);
  7868. // Define g for chart area
  7869. context.append('g').attr("clip-path", $$.clipPathForSubchart).attr('class', CLASS.chart);
  7870. // Define g for bar chart area
  7871. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars);
  7872. // Define g for line chart area
  7873. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines);
  7874. // Add extent rect for Brush
  7875. context.append("g").attr("clip-path", $$.clipPath).attr("class", CLASS.brush);
  7876. // ATTENTION: This must be called AFTER chart added
  7877. // Add Axis
  7878. $$.axes.subx = context.append("g").attr("class", CLASS.axisX).attr("transform", $$.getTranslate('subx')).attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis);
  7879. };
  7880. c3_chart_internal_fn.initSubchartBrush = function () {
  7881. var $$ = this;
  7882. // Add extent rect for Brush
  7883. $$.initBrush($$.subX).updateExtent();
  7884. $$.context.select('.' + CLASS.brush).call($$.brush);
  7885. };
  7886. c3_chart_internal_fn.updateTargetsForSubchart = function (targets) {
  7887. var $$ = this,
  7888. context = $$.context,
  7889. config = $$.config,
  7890. contextLineEnter,
  7891. contextLine,
  7892. contextBarEnter,
  7893. contextBar,
  7894. classChartBar = $$.classChartBar.bind($$),
  7895. classBars = $$.classBars.bind($$),
  7896. classChartLine = $$.classChartLine.bind($$),
  7897. classLines = $$.classLines.bind($$),
  7898. classAreas = $$.classAreas.bind($$);
  7899. if (config.subchart_show) {
  7900. //-- Bar --//
  7901. contextBar = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets);
  7902. contextBarEnter = contextBar.enter().append('g').style('opacity', 0);
  7903. contextBarEnter.merge(contextBar).attr('class', classChartBar);
  7904. // Bars for each data
  7905. contextBarEnter.append('g').attr("class", classBars);
  7906. //-- Line --//
  7907. contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets);
  7908. contextLineEnter = contextLine.enter().append('g').style('opacity', 0);
  7909. contextLineEnter.merge(contextLine).attr('class', classChartLine);
  7910. // Lines for each data
  7911. contextLineEnter.append("g").attr("class", classLines);
  7912. // Area
  7913. contextLineEnter.append("g").attr("class", classAreas);
  7914. //-- Brush --//
  7915. context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2);
  7916. }
  7917. };
  7918. c3_chart_internal_fn.updateBarForSubchart = function (durationForExit) {
  7919. var $$ = this;
  7920. var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data($$.barData.bind($$));
  7921. var contextBarEnter = contextBar.enter().append('path').attr("class", $$.classBar.bind($$)).style("stroke", 'none').style("fill", $$.color);
  7922. contextBar.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7923. $$.contextBar = contextBarEnter.merge(contextBar).style("opacity", $$.initialOpacity.bind($$));
  7924. };
  7925. c3_chart_internal_fn.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) {
  7926. (withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar).attr('d', drawBarOnSub).style('opacity', 1);
  7927. };
  7928. c3_chart_internal_fn.updateLineForSubchart = function (durationForExit) {
  7929. var $$ = this;
  7930. var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  7931. var contextLineEnter = contextLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color);
  7932. contextLine.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7933. $$.contextLine = contextLineEnter.merge(contextLine).style("opacity", $$.initialOpacity.bind($$));
  7934. };
  7935. c3_chart_internal_fn.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) {
  7936. (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr("d", drawLineOnSub).style('opacity', 1);
  7937. };
  7938. c3_chart_internal_fn.updateAreaForSubchart = function (durationForExit) {
  7939. var $$ = this,
  7940. d3 = $$.d3;
  7941. var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  7942. var contextAreaEnter = contextArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  7943. $$.orgAreaOpacity = +d3.select(this).style('opacity');return 0;
  7944. });
  7945. contextArea.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7946. $$.contextArea = contextAreaEnter.merge(contextArea).style("opacity", 0);
  7947. };
  7948. c3_chart_internal_fn.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) {
  7949. (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr("d", drawAreaOnSub).style("fill", this.color).style("opacity", this.orgAreaOpacity);
  7950. };
  7951. c3_chart_internal_fn.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) {
  7952. var $$ = this,
  7953. d3 = $$.d3,
  7954. config = $$.config,
  7955. drawAreaOnSub,
  7956. drawBarOnSub,
  7957. drawLineOnSub;
  7958. $$.context.style('visibility', config.subchart_show ? 'visible' : 'hidden');
  7959. // subchart
  7960. if (config.subchart_show) {
  7961. // reflect main chart to extent on subchart if zoomed
  7962. if (d3.event && d3.event.type === 'zoom') {
  7963. $$.brush.selectionAsValue($$.x.orgDomain());
  7964. }
  7965. // update subchart elements if needed
  7966. if (withSubchart) {
  7967. // extent rect
  7968. if (!$$.brush.empty()) {
  7969. $$.brush.selectionAsValue($$.x.orgDomain());
  7970. }
  7971. // setup drawer - MEMO: this must be called after axis updated
  7972. drawAreaOnSub = $$.generateDrawArea(areaIndices, true);
  7973. drawBarOnSub = $$.generateDrawBar(barIndices, true);
  7974. drawLineOnSub = $$.generateDrawLine(lineIndices, true);
  7975. $$.updateBarForSubchart(duration);
  7976. $$.updateLineForSubchart(duration);
  7977. $$.updateAreaForSubchart(duration);
  7978. $$.redrawBarForSubchart(drawBarOnSub, duration, duration);
  7979. $$.redrawLineForSubchart(drawLineOnSub, duration, duration);
  7980. $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);
  7981. }
  7982. }
  7983. };
  7984. c3_chart_internal_fn.redrawForBrush = function () {
  7985. var $$ = this,
  7986. x = $$.x,
  7987. d3 = $$.d3,
  7988. s;
  7989. $$.redraw({
  7990. withTransition: false,
  7991. withY: $$.config.zoom_rescale,
  7992. withSubchart: false,
  7993. withUpdateXDomain: true,
  7994. withEventRect: false,
  7995. withDimension: false
  7996. });
  7997. // update zoom transation binded to event rect
  7998. s = d3.event.selection || $$.brush.scale.range();
  7999. $$.main.select('.' + CLASS.eventRect).call($$.zoom.transform, d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0));
  8000. $$.config.subchart_onbrush.call($$.api, x.orgDomain());
  8001. };
  8002. c3_chart_internal_fn.transformContext = function (withTransition, transitions) {
  8003. var $$ = this,
  8004. subXAxis;
  8005. if (transitions && transitions.axisSubX) {
  8006. subXAxis = transitions.axisSubX;
  8007. } else {
  8008. subXAxis = $$.context.select('.' + CLASS.axisX);
  8009. if (withTransition) {
  8010. subXAxis = subXAxis.transition();
  8011. }
  8012. }
  8013. $$.context.attr("transform", $$.getTranslate('context'));
  8014. subXAxis.attr("transform", $$.getTranslate('subx'));
  8015. };
  8016. c3_chart_internal_fn.getDefaultSelection = function () {
  8017. var $$ = this,
  8018. config = $$.config,
  8019. selection = isFunction(config.axis_x_selection) ? config.axis_x_selection($$.getXDomain($$.data.targets)) : config.axis_x_selection;
  8020. if ($$.isTimeSeries()) {
  8021. selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])];
  8022. }
  8023. return selection;
  8024. };
  8025. c3_chart_internal_fn.initText = function () {
  8026. var $$ = this;
  8027. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartTexts);
  8028. $$.mainText = $$.d3.selectAll([]);
  8029. };
  8030. c3_chart_internal_fn.updateTargetsForText = function (targets) {
  8031. var $$ = this,
  8032. classChartText = $$.classChartText.bind($$),
  8033. classTexts = $$.classTexts.bind($$),
  8034. classFocus = $$.classFocus.bind($$);
  8035. var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText).data(targets);
  8036. var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style("pointer-events", "none");
  8037. mainTextEnter.append('g').attr('class', classTexts);
  8038. mainTextEnter.merge(mainText).attr('class', function (d) {
  8039. return classChartText(d) + classFocus(d);
  8040. });
  8041. };
  8042. c3_chart_internal_fn.updateText = function (xForText, yForText, durationForExit) {
  8043. var $$ = this,
  8044. config = $$.config,
  8045. barOrLineData = $$.barOrLineData.bind($$),
  8046. classText = $$.classText.bind($$);
  8047. var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text).data(barOrLineData);
  8048. var mainTextEnter = mainText.enter().append('text').attr("class", classText).attr('text-anchor', function (d) {
  8049. return config.axis_rotated ? d.value < 0 ? 'end' : 'start' : 'middle';
  8050. }).style("stroke", 'none').attr('x', xForText).attr('y', yForText).style("fill", function (d) {
  8051. return $$.color(d);
  8052. }).style("fill-opacity", 0);
  8053. $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) {
  8054. return $$.dataLabelFormat(d.id)(d.value, d.id, i, j);
  8055. });
  8056. mainText.exit().transition().duration(durationForExit).style('fill-opacity', 0).remove();
  8057. };
  8058. c3_chart_internal_fn.redrawText = function (xForText, yForText, forFlow, withTransition, transition) {
  8059. 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))];
  8060. };
  8061. c3_chart_internal_fn.getTextRect = function (text, cls, element) {
  8062. var dummy = this.d3.select('body').append('div').classed('c3', true),
  8063. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0),
  8064. font = this.d3.select(element).style('font'),
  8065. rect;
  8066. svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : "", true).style('font', font).text(text).each(function () {
  8067. rect = this.getBoundingClientRect();
  8068. });
  8069. dummy.remove();
  8070. return rect;
  8071. };
  8072. c3_chart_internal_fn.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {
  8073. var $$ = this,
  8074. getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),
  8075. getBarPoints = $$.generateGetBarPoints(barIndices, false),
  8076. getLinePoints = $$.generateGetLinePoints(lineIndices, false),
  8077. getter = forX ? $$.getXForText : $$.getYForText;
  8078. return function (d, i) {
  8079. var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints;
  8080. return getter.call($$, getPoints(d, i), d, this);
  8081. };
  8082. };
  8083. c3_chart_internal_fn.getXForText = function (points, d, textElement) {
  8084. var $$ = this,
  8085. box = textElement.getBoundingClientRect(),
  8086. xPos,
  8087. padding;
  8088. if ($$.config.axis_rotated) {
  8089. padding = $$.isBarType(d) ? 4 : 6;
  8090. xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);
  8091. } else {
  8092. xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];
  8093. }
  8094. // show labels regardless of the domain if value is null
  8095. if (d.value === null) {
  8096. if (xPos > $$.width) {
  8097. xPos = $$.width - box.width;
  8098. } else if (xPos < 0) {
  8099. xPos = 4;
  8100. }
  8101. }
  8102. return xPos;
  8103. };
  8104. c3_chart_internal_fn.getYForText = function (points, d, textElement) {
  8105. var $$ = this,
  8106. box = textElement.getBoundingClientRect(),
  8107. yPos;
  8108. if ($$.config.axis_rotated) {
  8109. yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;
  8110. } else {
  8111. yPos = points[2][1];
  8112. if (d.value < 0 || d.value === 0 && !$$.hasPositiveValue) {
  8113. yPos += box.height;
  8114. if ($$.isBarType(d) && $$.isSafari()) {
  8115. yPos -= 3;
  8116. } else if (!$$.isBarType(d) && $$.isChrome()) {
  8117. yPos += 3;
  8118. }
  8119. } else {
  8120. yPos += $$.isBarType(d) ? -3 : -6;
  8121. }
  8122. }
  8123. // show labels regardless of the domain if value is null
  8124. if (d.value === null && !$$.config.axis_rotated) {
  8125. if (yPos < box.height) {
  8126. yPos = box.height;
  8127. } else if (yPos > this.height) {
  8128. yPos = this.height - 4;
  8129. }
  8130. }
  8131. return yPos;
  8132. };
  8133. c3_chart_internal_fn.initTitle = function () {
  8134. var $$ = this;
  8135. $$.title = $$.svg.append("text").text($$.config.title_text).attr("class", $$.CLASS.title);
  8136. };
  8137. c3_chart_internal_fn.redrawTitle = function () {
  8138. var $$ = this;
  8139. $$.title.attr("x", $$.xForTitle.bind($$)).attr("y", $$.yForTitle.bind($$));
  8140. };
  8141. c3_chart_internal_fn.xForTitle = function () {
  8142. var $$ = this,
  8143. config = $$.config,
  8144. position = config.title_position || 'left',
  8145. x;
  8146. if (position.indexOf('right') >= 0) {
  8147. x = $$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width - config.title_padding.right;
  8148. } else if (position.indexOf('center') >= 0) {
  8149. x = ($$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) / 2;
  8150. } else {
  8151. // left
  8152. x = config.title_padding.left;
  8153. }
  8154. return x;
  8155. };
  8156. c3_chart_internal_fn.yForTitle = function () {
  8157. var $$ = this;
  8158. return $$.config.title_padding.top + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).height;
  8159. };
  8160. c3_chart_internal_fn.getTitlePadding = function () {
  8161. var $$ = this;
  8162. return $$.yForTitle() + $$.config.title_padding.bottom;
  8163. };
  8164. c3_chart_internal_fn.initTooltip = function () {
  8165. var $$ = this,
  8166. config = $$.config,
  8167. i;
  8168. $$.tooltip = $$.selectChart.style("position", "relative").append("div").attr('class', CLASS.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none");
  8169. // Show tooltip if needed
  8170. if (config.tooltip_init_show) {
  8171. if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {
  8172. config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);
  8173. for (i = 0; i < $$.data.targets[0].values.length; i++) {
  8174. if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {
  8175. break;
  8176. }
  8177. }
  8178. config.tooltip_init_x = i;
  8179. }
  8180. $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {
  8181. return $$.addName(d.values[config.tooltip_init_x]);
  8182. }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));
  8183. $$.tooltip.style("top", config.tooltip_init_position.top).style("left", config.tooltip_init_position.left).style("display", "block");
  8184. }
  8185. };
  8186. c3_chart_internal_fn.getTooltipSortFunction = function () {
  8187. var $$ = this,
  8188. config = $$.config;
  8189. if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {
  8190. // if data are not grouped or if an order is specified
  8191. // for the tooltip values we sort them by their values
  8192. var order = config.tooltip_order;
  8193. if (order === undefined) {
  8194. order = config.data_order;
  8195. }
  8196. var valueOf = function valueOf(obj) {
  8197. return obj ? obj.value : null;
  8198. };
  8199. // if data are not grouped, we sort them by their value
  8200. if (isString(order) && order.toLowerCase() === 'asc') {
  8201. return function (a, b) {
  8202. return valueOf(a) - valueOf(b);
  8203. };
  8204. } else if (isString(order) && order.toLowerCase() === 'desc') {
  8205. return function (a, b) {
  8206. return valueOf(b) - valueOf(a);
  8207. };
  8208. } else if (isFunction(order)) {
  8209. // if the function is from data_order we need
  8210. // to wrap the returned function in order to format
  8211. // the sorted value to the expected format
  8212. var sortFunction = order;
  8213. if (config.tooltip_order === undefined) {
  8214. sortFunction = function sortFunction(a, b) {
  8215. return order(a ? {
  8216. id: a.id,
  8217. values: [a]
  8218. } : null, b ? {
  8219. id: b.id,
  8220. values: [b]
  8221. } : null);
  8222. };
  8223. }
  8224. return sortFunction;
  8225. } else if (isArray(order)) {
  8226. return function (a, b) {
  8227. return order.indexOf(a.id) - order.indexOf(b.id);
  8228. };
  8229. }
  8230. } else {
  8231. // if data are grouped, we follow the order of grouped targets
  8232. var ids = $$.orderTargets($$.data.targets).map(function (i) {
  8233. return i.id;
  8234. });
  8235. // if it was either asc or desc we need to invert the order
  8236. // returned by orderTargets
  8237. if ($$.isOrderAsc() || $$.isOrderDesc()) {
  8238. ids = ids.reverse();
  8239. }
  8240. return function (a, b) {
  8241. return ids.indexOf(a.id) - ids.indexOf(b.id);
  8242. };
  8243. }
  8244. };
  8245. c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {
  8246. var $$ = this,
  8247. config = $$.config,
  8248. titleFormat = config.tooltip_format_title || defaultTitleFormat,
  8249. nameFormat = config.tooltip_format_name || function (name) {
  8250. return name;
  8251. },
  8252. valueFormat = config.tooltip_format_value || defaultValueFormat,
  8253. text,
  8254. i,
  8255. title,
  8256. value,
  8257. name,
  8258. bgcolor;
  8259. var tooltipSortFunction = this.getTooltipSortFunction();
  8260. if (tooltipSortFunction) {
  8261. d.sort(tooltipSortFunction);
  8262. }
  8263. for (i = 0; i < d.length; i++) {
  8264. if (!(d[i] && (d[i].value || d[i].value === 0))) {
  8265. continue;
  8266. }
  8267. if (!text) {
  8268. title = sanitise(titleFormat ? titleFormat(d[i].x) : d[i].x);
  8269. text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
  8270. }
  8271. value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));
  8272. if (value !== undefined) {
  8273. // Skip elements when their name is set to null
  8274. if (d[i].name === null) {
  8275. continue;
  8276. }
  8277. name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));
  8278. bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
  8279. text += "<tr class='" + $$.CLASS.tooltipName + "-" + $$.getTargetSelectorSuffix(d[i].id) + "'>";
  8280. text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
  8281. text += "<td class='value'>" + value + "</td>";
  8282. text += "</tr>";
  8283. }
  8284. }
  8285. return text + "</table>";
  8286. };
  8287. c3_chart_internal_fn.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {
  8288. var $$ = this,
  8289. config = $$.config,
  8290. d3 = $$.d3;
  8291. var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
  8292. var forArc = $$.hasArcType(),
  8293. mouse = d3.mouse(element);
  8294. // Determin tooltip position
  8295. if (forArc) {
  8296. tooltipLeft = ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];
  8297. tooltipTop = ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20;
  8298. } else {
  8299. svgLeft = $$.getSvgLeft(true);
  8300. if (config.axis_rotated) {
  8301. tooltipLeft = svgLeft + mouse[0] + 100;
  8302. tooltipRight = tooltipLeft + tWidth;
  8303. chartRight = $$.currentWidth - $$.getCurrentPaddingRight();
  8304. tooltipTop = $$.x(dataToShow[0].x) + 20;
  8305. } else {
  8306. tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;
  8307. tooltipRight = tooltipLeft + tWidth;
  8308. chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();
  8309. tooltipTop = mouse[1] + 15;
  8310. }
  8311. if (tooltipRight > chartRight) {
  8312. // 20 is needed for Firefox to keep tooltip width
  8313. tooltipLeft -= tooltipRight - chartRight + 20;
  8314. }
  8315. if (tooltipTop + tHeight > $$.currentHeight) {
  8316. tooltipTop -= tHeight + 30;
  8317. }
  8318. }
  8319. if (tooltipTop < 0) {
  8320. tooltipTop = 0;
  8321. }
  8322. return { top: tooltipTop, left: tooltipLeft };
  8323. };
  8324. c3_chart_internal_fn.showTooltip = function (selectedData, element) {
  8325. var $$ = this,
  8326. config = $$.config;
  8327. var tWidth, tHeight, position;
  8328. var forArc = $$.hasArcType(),
  8329. dataToShow = selectedData.filter(function (d) {
  8330. return d && isValue(d.value);
  8331. }),
  8332. positionFunction = config.tooltip_position || c3_chart_internal_fn.tooltipPosition;
  8333. if (dataToShow.length === 0 || !config.tooltip_show) {
  8334. return;
  8335. }
  8336. $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block");
  8337. // Get tooltip dimensions
  8338. tWidth = $$.tooltip.property('offsetWidth');
  8339. tHeight = $$.tooltip.property('offsetHeight');
  8340. position = positionFunction.call(this, dataToShow, tWidth, tHeight, element);
  8341. // Set tooltip
  8342. $$.tooltip.style("top", position.top + "px").style("left", position.left + 'px');
  8343. };
  8344. c3_chart_internal_fn.hideTooltip = function () {
  8345. this.tooltip.style("display", "none");
  8346. };
  8347. c3_chart_internal_fn.setTargetType = function (targetIds, type) {
  8348. var $$ = this,
  8349. config = $$.config;
  8350. $$.mapToTargetIds(targetIds).forEach(function (id) {
  8351. $$.withoutFadeIn[id] = type === config.data_types[id];
  8352. config.data_types[id] = type;
  8353. });
  8354. if (!targetIds) {
  8355. config.data_type = type;
  8356. }
  8357. };
  8358. c3_chart_internal_fn.hasType = function (type, targets) {
  8359. var $$ = this,
  8360. types = $$.config.data_types,
  8361. has = false;
  8362. targets = targets || $$.data.targets;
  8363. if (targets && targets.length) {
  8364. targets.forEach(function (target) {
  8365. var t = types[target.id];
  8366. if (t && t.indexOf(type) >= 0 || !t && type === 'line') {
  8367. has = true;
  8368. }
  8369. });
  8370. } else if (Object.keys(types).length) {
  8371. Object.keys(types).forEach(function (id) {
  8372. if (types[id] === type) {
  8373. has = true;
  8374. }
  8375. });
  8376. } else {
  8377. has = $$.config.data_type === type;
  8378. }
  8379. return has;
  8380. };
  8381. c3_chart_internal_fn.hasArcType = function (targets) {
  8382. return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets);
  8383. };
  8384. c3_chart_internal_fn.isLineType = function (d) {
  8385. var config = this.config,
  8386. id = isString(d) ? d : d.id;
  8387. return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0;
  8388. };
  8389. c3_chart_internal_fn.isStepType = function (d) {
  8390. var id = isString(d) ? d : d.id;
  8391. return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  8392. };
  8393. c3_chart_internal_fn.isSplineType = function (d) {
  8394. var id = isString(d) ? d : d.id;
  8395. return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;
  8396. };
  8397. c3_chart_internal_fn.isAreaType = function (d) {
  8398. var id = isString(d) ? d : d.id;
  8399. return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  8400. };
  8401. c3_chart_internal_fn.isBarType = function (d) {
  8402. var id = isString(d) ? d : d.id;
  8403. return this.config.data_types[id] === 'bar';
  8404. };
  8405. c3_chart_internal_fn.isScatterType = function (d) {
  8406. var id = isString(d) ? d : d.id;
  8407. return this.config.data_types[id] === 'scatter';
  8408. };
  8409. c3_chart_internal_fn.isPieType = function (d) {
  8410. var id = isString(d) ? d : d.id;
  8411. return this.config.data_types[id] === 'pie';
  8412. };
  8413. c3_chart_internal_fn.isGaugeType = function (d) {
  8414. var id = isString(d) ? d : d.id;
  8415. return this.config.data_types[id] === 'gauge';
  8416. };
  8417. c3_chart_internal_fn.isDonutType = function (d) {
  8418. var id = isString(d) ? d : d.id;
  8419. return this.config.data_types[id] === 'donut';
  8420. };
  8421. c3_chart_internal_fn.isArcType = function (d) {
  8422. return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);
  8423. };
  8424. c3_chart_internal_fn.lineData = function (d) {
  8425. return this.isLineType(d) ? [d] : [];
  8426. };
  8427. c3_chart_internal_fn.arcData = function (d) {
  8428. return this.isArcType(d.data) ? [d] : [];
  8429. };
  8430. /* not used
  8431. function scatterData(d) {
  8432. return isScatterType(d) ? d.values : [];
  8433. }
  8434. */
  8435. c3_chart_internal_fn.barData = function (d) {
  8436. return this.isBarType(d) ? d.values : [];
  8437. };
  8438. c3_chart_internal_fn.lineOrScatterData = function (d) {
  8439. return this.isLineType(d) || this.isScatterType(d) ? d.values : [];
  8440. };
  8441. c3_chart_internal_fn.barOrLineData = function (d) {
  8442. return this.isBarType(d) || this.isLineType(d) ? d.values : [];
  8443. };
  8444. c3_chart_internal_fn.isSafari = function () {
  8445. var ua = window.navigator.userAgent;
  8446. return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0;
  8447. };
  8448. c3_chart_internal_fn.isChrome = function () {
  8449. var ua = window.navigator.userAgent;
  8450. return ua.indexOf('Chrome') >= 0;
  8451. };
  8452. c3_chart_internal_fn.initZoom = function () {
  8453. var $$ = this,
  8454. d3 = $$.d3,
  8455. config = $$.config,
  8456. startEvent;
  8457. $$.zoom = d3.zoom().on("start", function () {
  8458. var e = d3.event.sourceEvent;
  8459. if (e && e.type === "brush") {
  8460. return;
  8461. }
  8462. startEvent = e;
  8463. config.zoom_onzoomstart.call($$.api, e);
  8464. }).on("zoom", function () {
  8465. var e = d3.event.sourceEvent;
  8466. if (e && e.type === "brush") {
  8467. return;
  8468. }
  8469. $$.redrawForZoom.call($$);
  8470. }).on('end', function () {
  8471. var e = d3.event.sourceEvent;
  8472. if (e && e.type === "brush") {
  8473. return;
  8474. }
  8475. // if click, do nothing. otherwise, click interaction will be canceled.
  8476. if (e && startEvent.clientX === e.clientX && startEvent.clientY === e.clientY) {
  8477. return;
  8478. }
  8479. config.zoom_onzoomend.call($$.api, $$.x.orgDomain());
  8480. });
  8481. $$.zoom.updateDomain = function () {
  8482. if (d3.event && d3.event.transform) {
  8483. $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());
  8484. }
  8485. return this;
  8486. };
  8487. $$.zoom.updateExtent = function () {
  8488. this.scaleExtent([1, Infinity]).translateExtent([[0, 0], [$$.width, $$.height]]).extent([[0, 0], [$$.width, $$.height]]);
  8489. return this;
  8490. };
  8491. $$.zoom.update = function () {
  8492. return this.updateExtent().updateDomain();
  8493. };
  8494. return $$.zoom.updateExtent();
  8495. };
  8496. c3_chart_internal_fn.zoomTransform = function (range) {
  8497. var $$ = this,
  8498. s = [$$.x(range[0]), $$.x(range[1])];
  8499. return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0);
  8500. };
  8501. c3_chart_internal_fn.getZoomDomain = function () {
  8502. var $$ = this,
  8503. config = $$.config,
  8504. d3 = $$.d3,
  8505. min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),
  8506. max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);
  8507. return [min, max];
  8508. };
  8509. c3_chart_internal_fn.redrawForZoom = function () {
  8510. var $$ = this,
  8511. d3 = $$.d3,
  8512. config = $$.config,
  8513. zoom = $$.zoom,
  8514. x = $$.x;
  8515. if (!config.zoom_enabled) {
  8516. return;
  8517. }
  8518. if ($$.filterTargetsToShow($$.data.targets).length === 0) {
  8519. return;
  8520. }
  8521. zoom.update();
  8522. if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {
  8523. x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);
  8524. }
  8525. $$.redraw({
  8526. withTransition: false,
  8527. withY: config.zoom_rescale,
  8528. withSubchart: false,
  8529. withEventRect: false,
  8530. withDimension: false
  8531. });
  8532. if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {
  8533. $$.cancelClick = true;
  8534. }
  8535. config.zoom_onzoom.call($$.api, x.orgDomain());
  8536. };
  8537. return c3;
  8538. })));