Dashboard sipadu mbip
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

c3.js 346KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  3. typeof define === 'function' && define.amd ? define(factory) :
  4. (global.c3 = factory());
  5. }(this, (function () { 'use strict';
  6. var CLASS = {
  7. target: 'c3-target',
  8. chart: 'c3-chart',
  9. chartLine: 'c3-chart-line',
  10. chartLines: 'c3-chart-lines',
  11. chartBar: 'c3-chart-bar',
  12. chartBars: 'c3-chart-bars',
  13. chartText: 'c3-chart-text',
  14. chartTexts: 'c3-chart-texts',
  15. chartArc: 'c3-chart-arc',
  16. chartArcs: 'c3-chart-arcs',
  17. chartArcsTitle: 'c3-chart-arcs-title',
  18. chartArcsBackground: 'c3-chart-arcs-background',
  19. chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',
  20. chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',
  21. chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',
  22. selectedCircle: 'c3-selected-circle',
  23. selectedCircles: 'c3-selected-circles',
  24. eventRect: 'c3-event-rect',
  25. eventRects: 'c3-event-rects',
  26. eventRectsSingle: 'c3-event-rects-single',
  27. eventRectsMultiple: 'c3-event-rects-multiple',
  28. zoomRect: 'c3-zoom-rect',
  29. brush: 'c3-brush',
  30. focused: 'c3-focused',
  31. defocused: 'c3-defocused',
  32. region: 'c3-region',
  33. regions: 'c3-regions',
  34. title: 'c3-title',
  35. tooltipContainer: 'c3-tooltip-container',
  36. tooltip: 'c3-tooltip',
  37. tooltipName: 'c3-tooltip-name',
  38. shape: 'c3-shape',
  39. shapes: 'c3-shapes',
  40. line: 'c3-line',
  41. lines: 'c3-lines',
  42. bar: 'c3-bar',
  43. bars: 'c3-bars',
  44. circle: 'c3-circle',
  45. circles: 'c3-circles',
  46. arc: 'c3-arc',
  47. arcs: 'c3-arcs',
  48. area: 'c3-area',
  49. areas: 'c3-areas',
  50. empty: 'c3-empty',
  51. text: 'c3-text',
  52. texts: 'c3-texts',
  53. gaugeValue: 'c3-gauge-value',
  54. grid: 'c3-grid',
  55. gridLines: 'c3-grid-lines',
  56. xgrid: 'c3-xgrid',
  57. xgrids: 'c3-xgrids',
  58. xgridLine: 'c3-xgrid-line',
  59. xgridLines: 'c3-xgrid-lines',
  60. xgridFocus: 'c3-xgrid-focus',
  61. ygrid: 'c3-ygrid',
  62. ygrids: 'c3-ygrids',
  63. ygridLine: 'c3-ygrid-line',
  64. ygridLines: 'c3-ygrid-lines',
  65. axis: 'c3-axis',
  66. axisX: 'c3-axis-x',
  67. axisXLabel: 'c3-axis-x-label',
  68. axisY: 'c3-axis-y',
  69. axisYLabel: 'c3-axis-y-label',
  70. axisY2: 'c3-axis-y2',
  71. axisY2Label: 'c3-axis-y2-label',
  72. legendBackground: 'c3-legend-background',
  73. legendItem: 'c3-legend-item',
  74. legendItemEvent: 'c3-legend-item-event',
  75. legendItemTile: 'c3-legend-item-tile',
  76. legendItemHidden: 'c3-legend-item-hidden',
  77. legendItemFocused: 'c3-legend-item-focused',
  78. dragarea: 'c3-dragarea',
  79. EXPANDED: '_expanded_',
  80. SELECTED: '_selected_',
  81. INCLUDED: '_included_'
  82. };
  83. var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
  84. return typeof obj;
  85. } : function (obj) {
  86. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  87. };
  88. var isValue = function isValue(v) {
  89. return v || v === 0;
  90. };
  91. var isFunction = function isFunction(o) {
  92. return typeof o === 'function';
  93. };
  94. var isArray = function isArray(o) {
  95. return Array.isArray(o);
  96. };
  97. var isString = function isString(o) {
  98. return typeof o === 'string';
  99. };
  100. var isUndefined = function isUndefined(v) {
  101. return typeof v === 'undefined';
  102. };
  103. var isDefined = function isDefined(v) {
  104. return typeof v !== 'undefined';
  105. };
  106. var ceil10 = function ceil10(v) {
  107. return Math.ceil(v / 10) * 10;
  108. };
  109. var asHalfPixel = function asHalfPixel(n) {
  110. return Math.ceil(n) + 0.5;
  111. };
  112. var diffDomain = function diffDomain(d) {
  113. return d[1] - d[0];
  114. };
  115. var isEmpty = function isEmpty(o) {
  116. return typeof o === 'undefined' || o === null || isString(o) && o.length === 0 || (typeof o === 'undefined' ? 'undefined' : _typeof(o)) === 'object' && Object.keys(o).length === 0;
  117. };
  118. var notEmpty = function notEmpty(o) {
  119. return !c3_chart_internal_fn.isEmpty(o);
  120. };
  121. var getOption = function getOption(options, key, defaultValue) {
  122. return isDefined(options[key]) ? options[key] : defaultValue;
  123. };
  124. var hasValue = function hasValue(dict, value) {
  125. var found = false;
  126. Object.keys(dict).forEach(function (key) {
  127. if (dict[key] === value) {
  128. found = true;
  129. }
  130. });
  131. return found;
  132. };
  133. var sanitise = function sanitise(str) {
  134. return typeof str === 'string' ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;') : str;
  135. };
  136. var getPathBox = function getPathBox(path) {
  137. var box = path.getBoundingClientRect(),
  138. items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],
  139. minX = items[0].x,
  140. minY = Math.min(items[0].y, items[1].y);
  141. return { x: minX, y: minY, width: box.width, height: box.height };
  142. };
  143. // Features:
  144. // 1. category axis
  145. // 2. ceil values of translate/x/y to int for half pixel antialiasing
  146. // 3. multiline tick text
  147. var tickTextCharSize;
  148. function c3_axis(d3, params) {
  149. var scale = d3.scale.linear(),
  150. orient = "bottom",
  151. innerTickSize = 6,
  152. outerTickSize,
  153. tickPadding = 3,
  154. tickValues = null,
  155. tickFormat,
  156. tickArguments;
  157. var tickOffset = 0,
  158. tickCulling = true,
  159. tickCentered;
  160. params = params || {};
  161. outerTickSize = params.withOuterTick ? 6 : 0;
  162. function axisX(selection, x) {
  163. selection.attr("transform", function (d) {
  164. return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)";
  165. });
  166. }
  167. function axisY(selection, y) {
  168. selection.attr("transform", function (d) {
  169. return "translate(0," + Math.ceil(y(d)) + ")";
  170. });
  171. }
  172. function scaleExtent(domain) {
  173. var start = domain[0],
  174. stop = domain[domain.length - 1];
  175. return start < stop ? [start, stop] : [stop, start];
  176. }
  177. function generateTicks(scale) {
  178. var i,
  179. domain,
  180. ticks = [];
  181. if (scale.ticks) {
  182. return scale.ticks.apply(scale, tickArguments);
  183. }
  184. domain = scale.domain();
  185. for (i = Math.ceil(domain[0]); i < domain[1]; i++) {
  186. ticks.push(i);
  187. }
  188. if (ticks.length > 0 && ticks[0] > 0) {
  189. ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));
  190. }
  191. return ticks;
  192. }
  193. function copyScale() {
  194. var newScale = scale.copy(),
  195. domain;
  196. if (params.isCategory) {
  197. domain = scale.domain();
  198. newScale.domain([domain[0], domain[1] - 1]);
  199. }
  200. return newScale;
  201. }
  202. function textFormatted(v) {
  203. var formatted = tickFormat ? tickFormat(v) : v;
  204. return typeof formatted !== 'undefined' ? formatted : '';
  205. }
  206. function getSizeFor1Char(tick) {
  207. if (tickTextCharSize) {
  208. return tickTextCharSize;
  209. }
  210. var size = {
  211. h: 11.5,
  212. w: 5.5
  213. };
  214. tick.select('text').text(textFormatted).each(function (d) {
  215. var box = this.getBoundingClientRect(),
  216. text = textFormatted(d),
  217. h = box.height,
  218. w = text ? box.width / text.length : undefined;
  219. if (h && w) {
  220. size.h = h;
  221. size.w = w;
  222. }
  223. }).text('');
  224. tickTextCharSize = size;
  225. return size;
  226. }
  227. function transitionise(selection) {
  228. return params.withoutTransition ? selection : d3.transition(selection);
  229. }
  230. function axis(g) {
  231. g.each(function () {
  232. var g = axis.g = d3.select(this);
  233. var scale0 = this.__chart__ || scale,
  234. scale1 = this.__chart__ = copyScale();
  235. var ticks = tickValues ? tickValues : generateTicks(scale1),
  236. tick = g.selectAll(".tick").data(ticks, scale1),
  237. tickEnter = tick.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6),
  238. // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.
  239. tickExit = tick.exit().remove(),
  240. tickUpdate = transitionise(tick).style("opacity", 1),
  241. tickTransform,
  242. tickX,
  243. tickY;
  244. var range = scale.rangeExtent ? scale.rangeExtent() : scaleExtent(scale.range()),
  245. path = g.selectAll(".domain").data([0]),
  246. pathUpdate = (path.enter().append("path").attr("class", "domain"), transitionise(path));
  247. tickEnter.append("line");
  248. tickEnter.append("text");
  249. var lineEnter = tickEnter.select("line"),
  250. lineUpdate = tickUpdate.select("line"),
  251. textEnter = tickEnter.select("text"),
  252. textUpdate = tickUpdate.select("text");
  253. if (params.isCategory) {
  254. tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
  255. tickX = tickCentered ? 0 : tickOffset;
  256. tickY = tickCentered ? tickOffset : 0;
  257. } else {
  258. tickOffset = tickX = 0;
  259. }
  260. var text,
  261. tspan,
  262. sizeFor1Char = getSizeFor1Char(g.select('.tick')),
  263. counts = [];
  264. var tickLength = Math.max(innerTickSize, 0) + tickPadding,
  265. isVertical = orient === 'left' || orient === 'right';
  266. // this should be called only when category axis
  267. function splitTickText(d, maxWidth) {
  268. var tickText = textFormatted(d),
  269. subtext,
  270. spaceIndex,
  271. textWidth,
  272. splitted = [];
  273. if (Object.prototype.toString.call(tickText) === "[object Array]") {
  274. return tickText;
  275. }
  276. if (!maxWidth || maxWidth <= 0) {
  277. maxWidth = isVertical ? 95 : params.isCategory ? Math.ceil(scale1(ticks[1]) - scale1(ticks[0])) - 12 : 110;
  278. }
  279. function split(splitted, text) {
  280. spaceIndex = undefined;
  281. for (var i = 1; i < text.length; i++) {
  282. if (text.charAt(i) === ' ') {
  283. spaceIndex = i;
  284. }
  285. subtext = text.substr(0, i + 1);
  286. textWidth = sizeFor1Char.w * subtext.length;
  287. // if text width gets over tick width, split by space index or crrent index
  288. if (maxWidth < textWidth) {
  289. return split(splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), text.slice(spaceIndex ? spaceIndex + 1 : i));
  290. }
  291. }
  292. return splitted.concat(text);
  293. }
  294. return split(splitted, tickText + "");
  295. }
  296. function tspanDy(d, i) {
  297. var dy = sizeFor1Char.h;
  298. if (i === 0) {
  299. if (orient === 'left' || orient === 'right') {
  300. dy = -((counts[d.index] - 1) * (sizeFor1Char.h / 2) - 3);
  301. } else {
  302. dy = ".71em";
  303. }
  304. }
  305. return dy;
  306. }
  307. function tickSize(d) {
  308. var tickPosition = scale(d) + (tickCentered ? 0 : tickOffset);
  309. return range[0] < tickPosition && tickPosition < range[1] ? innerTickSize : 0;
  310. }
  311. text = tick.select("text");
  312. tspan = text.selectAll('tspan').data(function (d, i) {
  313. var splitted = params.tickMultiline ? splitTickText(d, params.tickWidth) : [].concat(textFormatted(d));
  314. counts[i] = splitted.length;
  315. return splitted.map(function (s) {
  316. return { index: i, splitted: s };
  317. });
  318. });
  319. tspan.enter().append('tspan');
  320. tspan.exit().remove();
  321. tspan.text(function (d) {
  322. return d.splitted;
  323. });
  324. var rotate = params.tickTextRotate;
  325. function textAnchorForText(rotate) {
  326. if (!rotate) {
  327. return 'middle';
  328. }
  329. return rotate > 0 ? "start" : "end";
  330. }
  331. function textTransform(rotate) {
  332. if (!rotate) {
  333. return '';
  334. }
  335. return "rotate(" + rotate + ")";
  336. }
  337. function dxForText(rotate) {
  338. if (!rotate) {
  339. return 0;
  340. }
  341. return 8 * Math.sin(Math.PI * (rotate / 180));
  342. }
  343. function yForText(rotate) {
  344. if (!rotate) {
  345. return tickLength;
  346. }
  347. return 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1);
  348. }
  349. switch (orient) {
  350. case "bottom":
  351. {
  352. tickTransform = axisX;
  353. lineEnter.attr("y2", innerTickSize);
  354. textEnter.attr("y", tickLength);
  355. lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", tickSize);
  356. textUpdate.attr("x", 0).attr("y", yForText(rotate)).style("text-anchor", textAnchorForText(rotate)).attr("transform", textTransform(rotate));
  357. tspan.attr('x', 0).attr("dy", tspanDy).attr('dx', dxForText(rotate));
  358. pathUpdate.attr("d", "M" + range[0] + "," + outerTickSize + "V0H" + range[1] + "V" + outerTickSize);
  359. break;
  360. }
  361. case "top":
  362. {
  363. // TODO: rotated tick text
  364. tickTransform = axisX;
  365. lineEnter.attr("y2", -innerTickSize);
  366. textEnter.attr("y", -tickLength);
  367. lineUpdate.attr("x2", 0).attr("y2", -innerTickSize);
  368. textUpdate.attr("x", 0).attr("y", -tickLength);
  369. text.style("text-anchor", "middle");
  370. tspan.attr('x', 0).attr("dy", "0em");
  371. pathUpdate.attr("d", "M" + range[0] + "," + -outerTickSize + "V0H" + range[1] + "V" + -outerTickSize);
  372. break;
  373. }
  374. case "left":
  375. {
  376. tickTransform = axisY;
  377. lineEnter.attr("x2", -innerTickSize);
  378. textEnter.attr("x", -tickLength);
  379. lineUpdate.attr("x2", -innerTickSize).attr("y1", tickY).attr("y2", tickY);
  380. textUpdate.attr("x", -tickLength).attr("y", tickOffset);
  381. text.style("text-anchor", "end");
  382. tspan.attr('x', -tickLength).attr("dy", tspanDy);
  383. pathUpdate.attr("d", "M" + -outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + -outerTickSize);
  384. break;
  385. }
  386. case "right":
  387. {
  388. tickTransform = axisY;
  389. lineEnter.attr("x2", innerTickSize);
  390. textEnter.attr("x", tickLength);
  391. lineUpdate.attr("x2", innerTickSize).attr("y2", 0);
  392. textUpdate.attr("x", tickLength).attr("y", 0);
  393. text.style("text-anchor", "start");
  394. tspan.attr('x', tickLength).attr("dy", tspanDy);
  395. pathUpdate.attr("d", "M" + outerTickSize + "," + range[0] + "H0V" + range[1] + "H" + outerTickSize);
  396. break;
  397. }
  398. }
  399. if (scale1.rangeBand) {
  400. var x = scale1,
  401. dx = x.rangeBand() / 2;
  402. scale0 = scale1 = function scale1(d) {
  403. return x(d) + dx;
  404. };
  405. } else if (scale0.rangeBand) {
  406. scale0 = scale1;
  407. } else {
  408. tickExit.call(tickTransform, scale1);
  409. }
  410. tickEnter.call(tickTransform, scale0);
  411. tickUpdate.call(tickTransform, scale1);
  412. });
  413. }
  414. axis.scale = function (x) {
  415. if (!arguments.length) {
  416. return scale;
  417. }
  418. scale = x;
  419. return axis;
  420. };
  421. axis.orient = function (x) {
  422. if (!arguments.length) {
  423. return orient;
  424. }
  425. orient = x in { top: 1, right: 1, bottom: 1, left: 1 } ? x + "" : "bottom";
  426. return axis;
  427. };
  428. axis.tickFormat = function (format) {
  429. if (!arguments.length) {
  430. return tickFormat;
  431. }
  432. tickFormat = format;
  433. return axis;
  434. };
  435. axis.tickCentered = function (isCentered) {
  436. if (!arguments.length) {
  437. return tickCentered;
  438. }
  439. tickCentered = isCentered;
  440. return axis;
  441. };
  442. axis.tickOffset = function () {
  443. return tickOffset;
  444. };
  445. axis.tickInterval = function () {
  446. var interval, length;
  447. if (params.isCategory) {
  448. interval = tickOffset * 2;
  449. } else {
  450. length = axis.g.select('path.domain').node().getTotalLength() - outerTickSize * 2;
  451. interval = length / axis.g.selectAll('line').size();
  452. }
  453. return interval === Infinity ? 0 : interval;
  454. };
  455. axis.ticks = function () {
  456. if (!arguments.length) {
  457. return tickArguments;
  458. }
  459. tickArguments = arguments;
  460. return axis;
  461. };
  462. axis.tickCulling = function (culling) {
  463. if (!arguments.length) {
  464. return tickCulling;
  465. }
  466. tickCulling = culling;
  467. return axis;
  468. };
  469. axis.tickValues = function (x) {
  470. if (typeof x === 'function') {
  471. tickValues = function tickValues() {
  472. return x(scale.domain());
  473. };
  474. } else {
  475. if (!arguments.length) {
  476. return tickValues;
  477. }
  478. tickValues = x;
  479. }
  480. return axis;
  481. };
  482. return axis;
  483. }
  484. function Axis(owner) {
  485. API.call(this, owner);
  486. }
  487. inherit(API, Axis);
  488. Axis.prototype.init = function init() {
  489. var $$ = this.owner,
  490. config = $$.config,
  491. main = $$.main;
  492. $$.axes.x = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisX).attr("clip-path", $$.clipPathForXAxis).attr("transform", $$.getTranslate('x')).style("visibility", config.axis_x_show ? 'visible' : 'hidden');
  493. $$.axes.x.append("text").attr("class", CLASS.axisXLabel).attr("transform", config.axis_rotated ? "rotate(-90)" : "").style("text-anchor", this.textAnchorForXAxisLabel.bind(this));
  494. $$.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');
  495. $$.axes.y.append("text").attr("class", CLASS.axisYLabel).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForYAxisLabel.bind(this));
  496. $$.axes.y2 = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY2
  497. // clip-path?
  498. ).attr("transform", $$.getTranslate('y2')).style("visibility", config.axis_y2_show ? 'visible' : 'hidden');
  499. $$.axes.y2.append("text").attr("class", CLASS.axisY2Label).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForY2AxisLabel.bind(this));
  500. };
  501. Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  502. var $$ = this.owner,
  503. config = $$.config,
  504. axisParams = {
  505. isCategory: $$.isCategorized(),
  506. withOuterTick: withOuterTick,
  507. tickMultiline: config.axis_x_tick_multiline,
  508. tickWidth: config.axis_x_tick_width,
  509. tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,
  510. withoutTransition: withoutTransition
  511. },
  512. axis = c3_axis($$.d3, axisParams).scale(scale).orient(orient);
  513. if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") {
  514. tickValues = tickValues.map(function (v) {
  515. return $$.parseDate(v);
  516. });
  517. }
  518. // Set tick
  519. axis.tickFormat(tickFormat).tickValues(tickValues);
  520. if ($$.isCategorized()) {
  521. axis.tickCentered(config.axis_x_tick_centered);
  522. if (isEmpty(config.axis_x_tick_culling)) {
  523. config.axis_x_tick_culling = false;
  524. }
  525. }
  526. return axis;
  527. };
  528. Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) {
  529. var $$ = this.owner,
  530. config = $$.config,
  531. tickValues;
  532. if (config.axis_x_tick_fit || config.axis_x_tick_count) {
  533. tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries());
  534. }
  535. if (axis) {
  536. axis.tickValues(tickValues);
  537. } else {
  538. $$.xAxis.tickValues(tickValues);
  539. $$.subXAxis.tickValues(tickValues);
  540. }
  541. return tickValues;
  542. };
  543. Axis.prototype.getYAxis = function getYAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  544. var $$ = this.owner,
  545. config = $$.config,
  546. axisParams = {
  547. withOuterTick: withOuterTick,
  548. withoutTransition: withoutTransition,
  549. tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate
  550. },
  551. axis = c3_axis($$.d3, axisParams).scale(scale).orient(orient).tickFormat(tickFormat);
  552. if ($$.isTimeSeriesY()) {
  553. axis.ticks($$.d3.time[config.axis_y_tick_time_value], config.axis_y_tick_time_interval);
  554. } else {
  555. axis.tickValues(tickValues);
  556. }
  557. return axis;
  558. };
  559. Axis.prototype.getId = function getId(id) {
  560. var config = this.owner.config;
  561. return id in config.data_axes ? config.data_axes[id] : 'y';
  562. };
  563. Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {
  564. var $$ = this.owner,
  565. config = $$.config,
  566. format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) {
  567. return v < 0 ? v.toFixed(0) : v;
  568. };
  569. if (config.axis_x_tick_format) {
  570. if (isFunction(config.axis_x_tick_format)) {
  571. format = config.axis_x_tick_format;
  572. } else if ($$.isTimeSeries()) {
  573. format = function format(date) {
  574. return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : "";
  575. };
  576. }
  577. }
  578. return isFunction(format) ? function (v) {
  579. return format.call($$, v);
  580. } : format;
  581. };
  582. Axis.prototype.getTickValues = function getTickValues(tickValues, axis) {
  583. return tickValues ? tickValues : axis ? axis.tickValues() : undefined;
  584. };
  585. Axis.prototype.getXAxisTickValues = function getXAxisTickValues() {
  586. return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis);
  587. };
  588. Axis.prototype.getYAxisTickValues = function getYAxisTickValues() {
  589. return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis);
  590. };
  591. Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {
  592. return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis);
  593. };
  594. Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) {
  595. var $$ = this.owner,
  596. config = $$.config,
  597. option;
  598. if (axisId === 'y') {
  599. option = config.axis_y_label;
  600. } else if (axisId === 'y2') {
  601. option = config.axis_y2_label;
  602. } else if (axisId === 'x') {
  603. option = config.axis_x_label;
  604. }
  605. return option;
  606. };
  607. Axis.prototype.getLabelText = function getLabelText(axisId) {
  608. var option = this.getLabelOptionByAxisId(axisId);
  609. return isString(option) ? option : option ? option.text : null;
  610. };
  611. Axis.prototype.setLabelText = function setLabelText(axisId, text) {
  612. var $$ = this.owner,
  613. config = $$.config,
  614. option = this.getLabelOptionByAxisId(axisId);
  615. if (isString(option)) {
  616. if (axisId === 'y') {
  617. config.axis_y_label = text;
  618. } else if (axisId === 'y2') {
  619. config.axis_y2_label = text;
  620. } else if (axisId === 'x') {
  621. config.axis_x_label = text;
  622. }
  623. } else if (option) {
  624. option.text = text;
  625. }
  626. };
  627. Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) {
  628. var option = this.getLabelOptionByAxisId(axisId),
  629. position = option && (typeof option === 'undefined' ? 'undefined' : _typeof(option)) === 'object' && option.position ? option.position : defaultPosition;
  630. return {
  631. isInner: position.indexOf('inner') >= 0,
  632. isOuter: position.indexOf('outer') >= 0,
  633. isLeft: position.indexOf('left') >= 0,
  634. isCenter: position.indexOf('center') >= 0,
  635. isRight: position.indexOf('right') >= 0,
  636. isTop: position.indexOf('top') >= 0,
  637. isMiddle: position.indexOf('middle') >= 0,
  638. isBottom: position.indexOf('bottom') >= 0
  639. };
  640. };
  641. Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {
  642. return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right');
  643. };
  644. Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {
  645. return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  646. };
  647. Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {
  648. return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  649. };
  650. Axis.prototype.getLabelPositionById = function getLabelPositionById(id) {
  651. return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition();
  652. };
  653. Axis.prototype.textForXAxisLabel = function textForXAxisLabel() {
  654. return this.getLabelText('x');
  655. };
  656. Axis.prototype.textForYAxisLabel = function textForYAxisLabel() {
  657. return this.getLabelText('y');
  658. };
  659. Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {
  660. return this.getLabelText('y2');
  661. };
  662. Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {
  663. var $$ = this.owner;
  664. if (forHorizontal) {
  665. return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;
  666. } else {
  667. return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0;
  668. }
  669. };
  670. Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) {
  671. if (forHorizontal) {
  672. return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0";
  673. } else {
  674. return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0";
  675. }
  676. };
  677. Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) {
  678. if (forHorizontal) {
  679. return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';
  680. } else {
  681. return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';
  682. }
  683. };
  684. Axis.prototype.xForXAxisLabel = function xForXAxisLabel() {
  685. return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  686. };
  687. Axis.prototype.xForYAxisLabel = function xForYAxisLabel() {
  688. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  689. };
  690. Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {
  691. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  692. };
  693. Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {
  694. return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  695. };
  696. Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {
  697. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  698. };
  699. Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {
  700. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  701. };
  702. Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {
  703. var $$ = this.owner,
  704. config = $$.config,
  705. position = this.getXAxisLabelPosition();
  706. if (config.axis_rotated) {
  707. return position.isInner ? "1.2em" : -25 - this.getMaxTickWidth('x');
  708. } else {
  709. return position.isInner ? "-0.5em" : config.axis_x_height ? config.axis_x_height - 10 : "3em";
  710. }
  711. };
  712. Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {
  713. var $$ = this.owner,
  714. position = this.getYAxisLabelPosition();
  715. if ($$.config.axis_rotated) {
  716. return position.isInner ? "-0.5em" : "3em";
  717. } else {
  718. return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10);
  719. }
  720. };
  721. Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {
  722. var $$ = this.owner,
  723. position = this.getY2AxisLabelPosition();
  724. if ($$.config.axis_rotated) {
  725. return position.isInner ? "1.2em" : "-2.2em";
  726. } else {
  727. return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15);
  728. }
  729. };
  730. Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {
  731. var $$ = this.owner;
  732. return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition());
  733. };
  734. Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {
  735. var $$ = this.owner;
  736. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition());
  737. };
  738. Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {
  739. var $$ = this.owner;
  740. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition());
  741. };
  742. Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) {
  743. var $$ = this.owner,
  744. config = $$.config,
  745. maxWidth = 0,
  746. targetsToShow,
  747. scale,
  748. axis,
  749. dummy,
  750. svg;
  751. if (withoutRecompute && $$.currentMaxTickWidths[id]) {
  752. return $$.currentMaxTickWidths[id];
  753. }
  754. if ($$.svg) {
  755. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  756. if (id === 'y') {
  757. scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
  758. axis = this.getYAxis(scale, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, false, true, true);
  759. } else if (id === 'y2') {
  760. scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
  761. axis = this.getYAxis(scale, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, false, true, true);
  762. } else {
  763. scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
  764. axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);
  765. this.updateXAxisTickValues(targetsToShow, axis);
  766. }
  767. dummy = $$.d3.select('body').append('div').classed('c3', true);
  768. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () {
  769. $$.d3.select(this).selectAll('text').each(function () {
  770. var box = this.getBoundingClientRect();
  771. if (maxWidth < box.width) {
  772. maxWidth = box.width;
  773. }
  774. });
  775. dummy.remove();
  776. });
  777. }
  778. $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;
  779. return $$.currentMaxTickWidths[id];
  780. };
  781. Axis.prototype.updateLabels = function updateLabels(withTransition) {
  782. var $$ = this.owner;
  783. var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),
  784. axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),
  785. axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label);
  786. (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));
  787. (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));
  788. (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));
  789. };
  790. Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) {
  791. var p = typeof padding === 'number' ? padding : padding[key];
  792. if (!isValue(p)) {
  793. return defaultValue;
  794. }
  795. if (padding.unit === 'ratio') {
  796. return padding[key] * domainLength;
  797. }
  798. // assume padding is pixels if unit is not specified
  799. return this.convertPixelsToAxisPadding(p, domainLength);
  800. };
  801. Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) {
  802. var $$ = this.owner,
  803. length = $$.config.axis_rotated ? $$.width : $$.height;
  804. return domainLength * (pixels / length);
  805. };
  806. Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) {
  807. var tickValues = values,
  808. targetCount,
  809. start,
  810. end,
  811. count,
  812. interval,
  813. i,
  814. tickValue;
  815. if (tickCount) {
  816. targetCount = isFunction(tickCount) ? tickCount() : tickCount;
  817. // compute ticks according to tickCount
  818. if (targetCount === 1) {
  819. tickValues = [values[0]];
  820. } else if (targetCount === 2) {
  821. tickValues = [values[0], values[values.length - 1]];
  822. } else if (targetCount > 2) {
  823. count = targetCount - 2;
  824. start = values[0];
  825. end = values[values.length - 1];
  826. interval = (end - start) / (count + 1);
  827. // re-construct unique values
  828. tickValues = [start];
  829. for (i = 0; i < count; i++) {
  830. tickValue = +start + interval * (i + 1);
  831. tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);
  832. }
  833. tickValues.push(end);
  834. }
  835. }
  836. if (!forTimeSeries) {
  837. tickValues = tickValues.sort(function (a, b) {
  838. return a - b;
  839. });
  840. }
  841. return tickValues;
  842. };
  843. Axis.prototype.generateTransitions = function generateTransitions(duration) {
  844. var $$ = this.owner,
  845. axes = $$.axes;
  846. return {
  847. axisX: duration ? axes.x.transition().duration(duration) : axes.x,
  848. axisY: duration ? axes.y.transition().duration(duration) : axes.y,
  849. axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,
  850. axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx
  851. };
  852. };
  853. Axis.prototype.redraw = function redraw(transitions, isHidden) {
  854. var $$ = this.owner;
  855. $$.axes.x.style("opacity", isHidden ? 0 : 1);
  856. $$.axes.y.style("opacity", isHidden ? 0 : 1);
  857. $$.axes.y2.style("opacity", isHidden ? 0 : 1);
  858. $$.axes.subx.style("opacity", isHidden ? 0 : 1);
  859. transitions.axisX.call($$.xAxis);
  860. transitions.axisY.call($$.yAxis);
  861. transitions.axisY2.call($$.y2Axis);
  862. transitions.axisSubX.call($$.subXAxis);
  863. };
  864. var c3$1 = { version: "0.4.15" };
  865. var c3_chart_fn;
  866. var c3_chart_internal_fn;
  867. var c3_chart_internal_axis_fn;
  868. function API(owner) {
  869. this.owner = owner;
  870. }
  871. function inherit(base, derived) {
  872. if (Object.create) {
  873. derived.prototype = Object.create(base.prototype);
  874. } else {
  875. var f = function f() {};
  876. f.prototype = base.prototype;
  877. derived.prototype = new f();
  878. }
  879. derived.prototype.constructor = derived;
  880. return derived;
  881. }
  882. function Chart(config) {
  883. var $$ = this.internal = new ChartInternal(this);
  884. $$.loadConfig(config);
  885. $$.beforeInit(config);
  886. $$.init();
  887. $$.afterInit(config);
  888. // bind "this" to nested API
  889. (function bindThis(fn, target, argThis) {
  890. Object.keys(fn).forEach(function (key) {
  891. target[key] = fn[key].bind(argThis);
  892. if (Object.keys(fn[key]).length > 0) {
  893. bindThis(fn[key], target[key], argThis);
  894. }
  895. });
  896. })(c3_chart_fn, this, this);
  897. }
  898. function ChartInternal(api) {
  899. var $$ = this;
  900. $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
  901. $$.api = api;
  902. $$.config = $$.getDefaultConfig();
  903. $$.data = {};
  904. $$.cache = {};
  905. $$.axes = {};
  906. }
  907. c3$1.generate = function (config) {
  908. return new Chart(config);
  909. };
  910. c3$1.chart = {
  911. fn: Chart.prototype,
  912. internal: {
  913. fn: ChartInternal.prototype,
  914. axis: {
  915. fn: Axis.prototype
  916. }
  917. }
  918. };
  919. c3_chart_fn = c3$1.chart.fn;
  920. c3_chart_internal_fn = c3$1.chart.internal.fn;
  921. c3_chart_internal_axis_fn = c3$1.chart.internal.axis.fn;
  922. c3_chart_internal_fn.beforeInit = function () {
  923. // can do something
  924. };
  925. c3_chart_internal_fn.afterInit = function () {
  926. // can do something
  927. };
  928. c3_chart_internal_fn.init = function () {
  929. var $$ = this,
  930. config = $$.config;
  931. $$.initParams();
  932. if (config.data_url) {
  933. $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);
  934. } else if (config.data_json) {
  935. $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
  936. } else if (config.data_rows) {
  937. $$.initWithData($$.convertRowsToData(config.data_rows));
  938. } else if (config.data_columns) {
  939. $$.initWithData($$.convertColumnsToData(config.data_columns));
  940. } else {
  941. throw Error('url or json or rows or columns is required.');
  942. }
  943. };
  944. c3_chart_internal_fn.initParams = function () {
  945. var $$ = this,
  946. d3 = $$.d3,
  947. config = $$.config;
  948. // MEMO: clipId needs to be unique because it conflicts when multiple charts exist
  949. $$.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);
  950. $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid), $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart), $$.dragStart = null;
  951. $$.dragging = false;
  952. $$.flowing = false;
  953. $$.cancelClick = false;
  954. $$.mouseover = false;
  955. $$.transiting = false;
  956. $$.color = $$.generateColor();
  957. $$.levelColor = $$.generateLevelColor();
  958. $$.dataTimeFormat = config.data_xLocaltime ? d3.time.format : d3.time.format.utc;
  959. $$.axisTimeFormat = config.axis_x_localtime ? d3.time.format : d3.time.format.utc;
  960. $$.defaultAxisTimeFormat = $$.axisTimeFormat.multi([[".%L", function (d) {
  961. return d.getMilliseconds();
  962. }], [":%S", function (d) {
  963. return d.getSeconds();
  964. }], ["%I:%M", function (d) {
  965. return d.getMinutes();
  966. }], ["%I %p", function (d) {
  967. return d.getHours();
  968. }], ["%-m/%-d", function (d) {
  969. return d.getDay() && d.getDate() !== 1;
  970. }], ["%-m/%-d", function (d) {
  971. return d.getDate() !== 1;
  972. }], ["%-m/%-d", function (d) {
  973. return d.getMonth();
  974. }], ["%Y/%-m/%-d", function () {
  975. return true;
  976. }]]);
  977. $$.hiddenTargetIds = [];
  978. $$.hiddenLegendIds = [];
  979. $$.focusedTargetIds = [];
  980. $$.defocusedTargetIds = [];
  981. $$.xOrient = config.axis_rotated ? "left" : "bottom";
  982. $$.yOrient = config.axis_rotated ? config.axis_y_inner ? "top" : "bottom" : config.axis_y_inner ? "right" : "left";
  983. $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? "bottom" : "top" : config.axis_y2_inner ? "left" : "right";
  984. $$.subXOrient = config.axis_rotated ? "left" : "bottom";
  985. $$.isLegendRight = config.legend_position === 'right';
  986. $$.isLegendInset = config.legend_position === 'inset';
  987. $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right';
  988. $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left';
  989. $$.legendStep = 0;
  990. $$.legendItemWidth = 0;
  991. $$.legendItemHeight = 0;
  992. $$.currentMaxTickWidths = {
  993. x: 0,
  994. y: 0,
  995. y2: 0
  996. };
  997. $$.rotated_padding_left = 30;
  998. $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;
  999. $$.rotated_padding_top = 5;
  1000. $$.withoutFadeIn = {};
  1001. $$.intervalForObserveInserted = undefined;
  1002. $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
  1003. };
  1004. c3_chart_internal_fn.initChartElements = function () {
  1005. if (this.initBar) {
  1006. this.initBar();
  1007. }
  1008. if (this.initLine) {
  1009. this.initLine();
  1010. }
  1011. if (this.initArc) {
  1012. this.initArc();
  1013. }
  1014. if (this.initGauge) {
  1015. this.initGauge();
  1016. }
  1017. if (this.initText) {
  1018. this.initText();
  1019. }
  1020. };
  1021. c3_chart_internal_fn.initWithData = function (data) {
  1022. var $$ = this,
  1023. d3 = $$.d3,
  1024. config = $$.config;
  1025. var defs,
  1026. main,
  1027. binding = true;
  1028. $$.axis = new Axis($$);
  1029. if ($$.initPie) {
  1030. $$.initPie();
  1031. }
  1032. if ($$.initBrush) {
  1033. $$.initBrush();
  1034. }
  1035. if ($$.initZoom) {
  1036. $$.initZoom();
  1037. }
  1038. if (!config.bindto) {
  1039. $$.selectChart = d3.selectAll([]);
  1040. } else if (typeof config.bindto.node === 'function') {
  1041. $$.selectChart = config.bindto;
  1042. } else {
  1043. $$.selectChart = d3.select(config.bindto);
  1044. }
  1045. if ($$.selectChart.empty()) {
  1046. $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0);
  1047. $$.observeInserted($$.selectChart);
  1048. binding = false;
  1049. }
  1050. $$.selectChart.html("").classed("c3", true);
  1051. // Init data as targets
  1052. $$.data.xs = {};
  1053. $$.data.targets = $$.convertDataToTargets(data);
  1054. if (config.data_filter) {
  1055. $$.data.targets = $$.data.targets.filter(config.data_filter);
  1056. }
  1057. // Set targets to hide if needed
  1058. if (config.data_hide) {
  1059. $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide);
  1060. }
  1061. if (config.legend_hide) {
  1062. $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide);
  1063. }
  1064. // when gauge, hide legend // TODO: fix
  1065. if ($$.hasType('gauge')) {
  1066. config.legend_show = false;
  1067. }
  1068. // Init sizes and scales
  1069. $$.updateSizes();
  1070. $$.updateScales();
  1071. // Set domains for each scale
  1072. $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));
  1073. $$.y.domain($$.getYDomain($$.data.targets, 'y'));
  1074. $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));
  1075. $$.subX.domain($$.x.domain());
  1076. $$.subY.domain($$.y.domain());
  1077. $$.subY2.domain($$.y2.domain());
  1078. // Save original x domain for zoom update
  1079. $$.orgXDomain = $$.x.domain();
  1080. // Set initialized scales to brush and zoom
  1081. if ($$.brush) {
  1082. $$.brush.scale($$.subX);
  1083. }
  1084. if (config.zoom_enabled) {
  1085. $$.zoom.scale($$.x);
  1086. }
  1087. /*-- Basic Elements --*/
  1088. // Define svgs
  1089. $$.svg = $$.selectChart.append("svg").style("overflow", "hidden").on('mouseenter', function () {
  1090. return config.onmouseover.call($$);
  1091. }).on('mouseleave', function () {
  1092. return config.onmouseout.call($$);
  1093. });
  1094. if ($$.config.svg_classname) {
  1095. $$.svg.attr('class', $$.config.svg_classname);
  1096. }
  1097. // Define defs
  1098. defs = $$.svg.append("defs");
  1099. $$.clipChart = $$.appendClip(defs, $$.clipId);
  1100. $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);
  1101. $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);
  1102. $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);
  1103. $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);
  1104. $$.updateSvgSize();
  1105. // Define regions
  1106. main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main'));
  1107. if ($$.initSubchart) {
  1108. $$.initSubchart();
  1109. }
  1110. if ($$.initTooltip) {
  1111. $$.initTooltip();
  1112. }
  1113. if ($$.initLegend) {
  1114. $$.initLegend();
  1115. }
  1116. if ($$.initTitle) {
  1117. $$.initTitle();
  1118. }
  1119. /*-- Main Region --*/
  1120. // text when empty
  1121. main.append("text").attr("class", CLASS.text + ' ' + CLASS.empty).attr("text-anchor", "middle" // horizontal centering of text at x position in all browsers.
  1122. ).attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE.
  1123. // Regions
  1124. $$.initRegion();
  1125. // Grids
  1126. $$.initGrid();
  1127. // Define g for chart area
  1128. main.append('g').attr("clip-path", $$.clipPath).attr('class', CLASS.chart);
  1129. // Grid lines
  1130. if (config.grid_lines_front) {
  1131. $$.initGridLines();
  1132. }
  1133. // Cover whole with rects for events
  1134. $$.initEventRect();
  1135. // Define g for chart
  1136. $$.initChartElements();
  1137. // if zoom privileged, insert rect to forefront
  1138. // TODO: is this needed?
  1139. main.insert('rect', config.zoom_privileged ? null : 'g.' + CLASS.regions).attr('class', CLASS.zoomRect).attr('width', $$.width).attr('height', $$.height).style('opacity', 0).on("dblclick.zoom", null);
  1140. // Set default extent if defined
  1141. if (config.axis_x_extent) {
  1142. $$.brush.extent($$.getDefaultExtent());
  1143. }
  1144. // Add Axis
  1145. $$.axis.init();
  1146. // Set targets
  1147. $$.updateTargets($$.data.targets);
  1148. // Draw with targets
  1149. if (binding) {
  1150. $$.updateDimension();
  1151. $$.config.oninit.call($$);
  1152. $$.redraw({
  1153. withTransition: false,
  1154. withTransform: true,
  1155. withUpdateXDomain: true,
  1156. withUpdateOrgXDomain: true,
  1157. withTransitionForAxis: false
  1158. });
  1159. }
  1160. // Bind resize event
  1161. $$.bindResize();
  1162. // export element of the chart
  1163. $$.api.element = $$.selectChart.node();
  1164. };
  1165. c3_chart_internal_fn.smoothLines = function (el, type) {
  1166. var $$ = this;
  1167. if (type === 'grid') {
  1168. el.each(function () {
  1169. var g = $$.d3.select(this),
  1170. x1 = g.attr('x1'),
  1171. x2 = g.attr('x2'),
  1172. y1 = g.attr('y1'),
  1173. y2 = g.attr('y2');
  1174. g.attr({
  1175. 'x1': Math.ceil(x1),
  1176. 'x2': Math.ceil(x2),
  1177. 'y1': Math.ceil(y1),
  1178. 'y2': Math.ceil(y2)
  1179. });
  1180. });
  1181. }
  1182. };
  1183. c3_chart_internal_fn.updateSizes = function () {
  1184. var $$ = this,
  1185. config = $$.config;
  1186. var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
  1187. legendWidth = $$.legend ? $$.getLegendWidth() : 0,
  1188. legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
  1189. hasArc = $$.hasArcType(),
  1190. xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),
  1191. subchartHeight = config.subchart_show && !hasArc ? config.subchart_size_height + xAxisHeight : 0;
  1192. $$.currentWidth = $$.getCurrentWidth();
  1193. $$.currentHeight = $$.getCurrentHeight();
  1194. // for main
  1195. $$.margin = config.axis_rotated ? {
  1196. top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),
  1197. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1198. bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1199. left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())
  1200. } : {
  1201. top: 4 + $$.getCurrentPaddingTop(), // for top tick text
  1202. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1203. bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1204. left: hasArc ? 0 : $$.getCurrentPaddingLeft()
  1205. };
  1206. // for subchart
  1207. $$.margin2 = config.axis_rotated ? {
  1208. top: $$.margin.top,
  1209. right: NaN,
  1210. bottom: 20 + legendHeightForBottom,
  1211. left: $$.rotated_padding_left
  1212. } : {
  1213. top: $$.currentHeight - subchartHeight - legendHeightForBottom,
  1214. right: NaN,
  1215. bottom: xAxisHeight + legendHeightForBottom,
  1216. left: $$.margin.left
  1217. };
  1218. // for legend
  1219. $$.margin3 = {
  1220. top: 0,
  1221. right: NaN,
  1222. bottom: 0,
  1223. left: 0
  1224. };
  1225. if ($$.updateSizeForLegend) {
  1226. $$.updateSizeForLegend(legendHeight, legendWidth);
  1227. }
  1228. $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;
  1229. $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;
  1230. if ($$.width < 0) {
  1231. $$.width = 0;
  1232. }
  1233. if ($$.height < 0) {
  1234. $$.height = 0;
  1235. }
  1236. $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width;
  1237. $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;
  1238. if ($$.width2 < 0) {
  1239. $$.width2 = 0;
  1240. }
  1241. if ($$.height2 < 0) {
  1242. $$.height2 = 0;
  1243. }
  1244. // for arc
  1245. $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
  1246. $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
  1247. if ($$.hasType('gauge') && !config.gauge_fullCircle) {
  1248. $$.arcHeight += $$.height - $$.getGaugeLabelHeight();
  1249. }
  1250. if ($$.updateRadius) {
  1251. $$.updateRadius();
  1252. }
  1253. if ($$.isLegendRight && hasArc) {
  1254. $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;
  1255. }
  1256. };
  1257. c3_chart_internal_fn.updateTargets = function (targets) {
  1258. var $$ = this;
  1259. /*-- Main --*/
  1260. //-- Text --//
  1261. $$.updateTargetsForText(targets);
  1262. //-- Bar --//
  1263. $$.updateTargetsForBar(targets);
  1264. //-- Line --//
  1265. $$.updateTargetsForLine(targets);
  1266. //-- Arc --//
  1267. if ($$.hasArcType() && $$.updateTargetsForArc) {
  1268. $$.updateTargetsForArc(targets);
  1269. }
  1270. /*-- Sub --*/
  1271. if ($$.updateTargetsForSubchart) {
  1272. $$.updateTargetsForSubchart(targets);
  1273. }
  1274. // Fade-in each chart
  1275. $$.showTargets();
  1276. };
  1277. c3_chart_internal_fn.showTargets = function () {
  1278. var $$ = this;
  1279. $$.svg.selectAll('.' + CLASS.target).filter(function (d) {
  1280. return $$.isTargetToShow(d.id);
  1281. }).transition().duration($$.config.transition_duration).style("opacity", 1);
  1282. };
  1283. c3_chart_internal_fn.redraw = function (options, transitions) {
  1284. var $$ = this,
  1285. main = $$.main,
  1286. d3 = $$.d3,
  1287. config = $$.config;
  1288. var areaIndices = $$.getShapeIndices($$.isAreaType),
  1289. barIndices = $$.getShapeIndices($$.isBarType),
  1290. lineIndices = $$.getShapeIndices($$.isLineType);
  1291. var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, withEventRect, withDimension, withUpdateXAxis;
  1292. var hideAxis = $$.hasArcType();
  1293. var drawArea, drawBar, drawLine, xForText, yForText;
  1294. var duration, durationForExit, durationForAxis;
  1295. var waitForDraw, flow;
  1296. var targetsToShow = $$.filterTargetsToShow($$.data.targets),
  1297. tickValues,
  1298. i,
  1299. intervalForCulling,
  1300. xDomainForZoom;
  1301. var xv = $$.xv.bind($$),
  1302. cx,
  1303. cy;
  1304. options = options || {};
  1305. withY = getOption(options, "withY", true);
  1306. withSubchart = getOption(options, "withSubchart", true);
  1307. withTransition = getOption(options, "withTransition", true);
  1308. withTransform = getOption(options, "withTransform", false);
  1309. withUpdateXDomain = getOption(options, "withUpdateXDomain", false);
  1310. withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false);
  1311. withTrimXDomain = getOption(options, "withTrimXDomain", true);
  1312. withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain);
  1313. withLegend = getOption(options, "withLegend", false);
  1314. withEventRect = getOption(options, "withEventRect", true);
  1315. withDimension = getOption(options, "withDimension", true);
  1316. withTransitionForExit = getOption(options, "withTransitionForExit", withTransition);
  1317. withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition);
  1318. duration = withTransition ? config.transition_duration : 0;
  1319. durationForExit = withTransitionForExit ? duration : 0;
  1320. durationForAxis = withTransitionForAxis ? duration : 0;
  1321. transitions = transitions || $$.axis.generateTransitions(durationForAxis);
  1322. // update legend and transform each g
  1323. if (withLegend && config.legend_show) {
  1324. $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
  1325. } else if (withDimension) {
  1326. // need to update dimension (e.g. axis.y.tick.values) because y tick values should change
  1327. // no need to update axis in it because they will be updated in redraw()
  1328. $$.updateDimension(true);
  1329. }
  1330. // MEMO: needed for grids calculation
  1331. if ($$.isCategorized() && targetsToShow.length === 0) {
  1332. $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);
  1333. }
  1334. if (targetsToShow.length) {
  1335. $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);
  1336. if (!config.axis_x_tick_values) {
  1337. tickValues = $$.axis.updateXAxisTickValues(targetsToShow);
  1338. }
  1339. } else {
  1340. $$.xAxis.tickValues([]);
  1341. $$.subXAxis.tickValues([]);
  1342. }
  1343. if (config.zoom_rescale && !options.flow) {
  1344. xDomainForZoom = $$.x.orgDomain();
  1345. }
  1346. $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));
  1347. $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));
  1348. if (!config.axis_y_tick_values && config.axis_y_tick_count) {
  1349. $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count));
  1350. }
  1351. if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {
  1352. $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count));
  1353. }
  1354. // axes
  1355. $$.axis.redraw(transitions, hideAxis);
  1356. // Update axis label
  1357. $$.axis.updateLabels(withTransition);
  1358. // show/hide if manual culling needed
  1359. if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {
  1360. if (config.axis_x_tick_culling && tickValues) {
  1361. for (i = 1; i < tickValues.length; i++) {
  1362. if (tickValues.length / i < config.axis_x_tick_culling_max) {
  1363. intervalForCulling = i;
  1364. break;
  1365. }
  1366. }
  1367. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {
  1368. var index = tickValues.indexOf(e);
  1369. if (index >= 0) {
  1370. d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');
  1371. }
  1372. });
  1373. } else {
  1374. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block');
  1375. }
  1376. }
  1377. // setup drawer - MEMO: these must be called after axis updated
  1378. drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined;
  1379. drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;
  1380. drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined;
  1381. xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
  1382. yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false);
  1383. // Update sub domain
  1384. if (withY) {
  1385. $$.subY.domain($$.getYDomain(targetsToShow, 'y'));
  1386. $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));
  1387. }
  1388. // xgrid focus
  1389. $$.updateXgridFocus();
  1390. // Data empty label positioning and text.
  1391. 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);
  1392. // grid
  1393. $$.updateGrid(duration);
  1394. // rect for regions
  1395. $$.updateRegion(duration);
  1396. // bars
  1397. $$.updateBar(durationForExit);
  1398. // lines, areas and cricles
  1399. $$.updateLine(durationForExit);
  1400. $$.updateArea(durationForExit);
  1401. $$.updateCircle();
  1402. // text
  1403. if ($$.hasDataLabel()) {
  1404. $$.updateText(durationForExit);
  1405. }
  1406. // title
  1407. if ($$.redrawTitle) {
  1408. $$.redrawTitle();
  1409. }
  1410. // arc
  1411. if ($$.redrawArc) {
  1412. $$.redrawArc(duration, durationForExit, withTransform);
  1413. }
  1414. // subchart
  1415. if ($$.redrawSubchart) {
  1416. $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);
  1417. }
  1418. // circles for select
  1419. main.selectAll('.' + CLASS.selectedCircles).filter($$.isBarType.bind($$)).selectAll('circle').remove();
  1420. // event rects will redrawn when flow called
  1421. if (config.interaction_enabled && !options.flow && withEventRect) {
  1422. $$.redrawEventRect();
  1423. if ($$.updateZoom) {
  1424. $$.updateZoom();
  1425. }
  1426. }
  1427. // update circleY based on updated parameters
  1428. $$.updateCircleY();
  1429. // generate circle x/y functions depending on updated params
  1430. cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
  1431. cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$);
  1432. if (options.flow) {
  1433. flow = $$.generateFlow({
  1434. targets: targetsToShow,
  1435. flow: options.flow,
  1436. duration: options.flow.duration,
  1437. drawBar: drawBar,
  1438. drawLine: drawLine,
  1439. drawArea: drawArea,
  1440. cx: cx,
  1441. cy: cy,
  1442. xv: xv,
  1443. xForText: xForText,
  1444. yForText: yForText
  1445. });
  1446. }
  1447. if ((duration || flow) && $$.isTabVisible()) {
  1448. // Only use transition if tab visible. See #938.
  1449. // transition should be derived from one transition
  1450. d3.transition().duration(duration).each(function () {
  1451. var transitionsToWait = [];
  1452. // redraw and gather transitions
  1453. [$$.redrawBar(drawBar, true), $$.redrawLine(drawLine, true), $$.redrawArea(drawArea, true), $$.redrawCircle(cx, cy, true), $$.redrawText(xForText, yForText, options.flow, true), $$.redrawRegion(true), $$.redrawGrid(true)].forEach(function (transitions) {
  1454. transitions.forEach(function (transition) {
  1455. transitionsToWait.push(transition);
  1456. });
  1457. });
  1458. // Wait for end of transitions to call flow and onrendered callback
  1459. waitForDraw = $$.generateWait();
  1460. transitionsToWait.forEach(function (t) {
  1461. waitForDraw.add(t);
  1462. });
  1463. }).call(waitForDraw, function () {
  1464. if (flow) {
  1465. flow();
  1466. }
  1467. if (config.onrendered) {
  1468. config.onrendered.call($$);
  1469. }
  1470. });
  1471. } else {
  1472. $$.redrawBar(drawBar);
  1473. $$.redrawLine(drawLine);
  1474. $$.redrawArea(drawArea);
  1475. $$.redrawCircle(cx, cy);
  1476. $$.redrawText(xForText, yForText, options.flow);
  1477. $$.redrawRegion();
  1478. $$.redrawGrid();
  1479. if (config.onrendered) {
  1480. config.onrendered.call($$);
  1481. }
  1482. }
  1483. // update fadein condition
  1484. $$.mapToIds($$.data.targets).forEach(function (id) {
  1485. $$.withoutFadeIn[id] = true;
  1486. });
  1487. };
  1488. c3_chart_internal_fn.updateAndRedraw = function (options) {
  1489. var $$ = this,
  1490. config = $$.config,
  1491. transitions;
  1492. options = options || {};
  1493. // same with redraw
  1494. options.withTransition = getOption(options, "withTransition", true);
  1495. options.withTransform = getOption(options, "withTransform", false);
  1496. options.withLegend = getOption(options, "withLegend", false);
  1497. // NOT same with redraw
  1498. options.withUpdateXDomain = true;
  1499. options.withUpdateOrgXDomain = true;
  1500. options.withTransitionForExit = false;
  1501. options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition);
  1502. // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)
  1503. $$.updateSizes();
  1504. // MEMO: called in updateLegend in redraw if withLegend
  1505. if (!(options.withLegend && config.legend_show)) {
  1506. transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0);
  1507. // Update scales
  1508. $$.updateScales();
  1509. $$.updateSvgSize();
  1510. // Update g positions
  1511. $$.transformAll(options.withTransitionForTransform, transitions);
  1512. }
  1513. // Draw with new sizes & scales
  1514. $$.redraw(options, transitions);
  1515. };
  1516. c3_chart_internal_fn.redrawWithoutRescale = function () {
  1517. this.redraw({
  1518. withY: false,
  1519. withSubchart: false,
  1520. withEventRect: false,
  1521. withTransitionForAxis: false
  1522. });
  1523. };
  1524. c3_chart_internal_fn.isTimeSeries = function () {
  1525. return this.config.axis_x_type === 'timeseries';
  1526. };
  1527. c3_chart_internal_fn.isCategorized = function () {
  1528. return this.config.axis_x_type.indexOf('categor') >= 0;
  1529. };
  1530. c3_chart_internal_fn.isCustomX = function () {
  1531. var $$ = this,
  1532. config = $$.config;
  1533. return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));
  1534. };
  1535. c3_chart_internal_fn.isTimeSeriesY = function () {
  1536. return this.config.axis_y_type === 'timeseries';
  1537. };
  1538. c3_chart_internal_fn.getTranslate = function (target) {
  1539. var $$ = this,
  1540. config = $$.config,
  1541. x,
  1542. y;
  1543. if (target === 'main') {
  1544. x = asHalfPixel($$.margin.left);
  1545. y = asHalfPixel($$.margin.top);
  1546. } else if (target === 'context') {
  1547. x = asHalfPixel($$.margin2.left);
  1548. y = asHalfPixel($$.margin2.top);
  1549. } else if (target === 'legend') {
  1550. x = $$.margin3.left;
  1551. y = $$.margin3.top;
  1552. } else if (target === 'x') {
  1553. x = 0;
  1554. y = config.axis_rotated ? 0 : $$.height;
  1555. } else if (target === 'y') {
  1556. x = 0;
  1557. y = config.axis_rotated ? $$.height : 0;
  1558. } else if (target === 'y2') {
  1559. x = config.axis_rotated ? 0 : $$.width;
  1560. y = config.axis_rotated ? 1 : 0;
  1561. } else if (target === 'subx') {
  1562. x = 0;
  1563. y = config.axis_rotated ? 0 : $$.height2;
  1564. } else if (target === 'arc') {
  1565. x = $$.arcWidth / 2;
  1566. y = $$.arcHeight / 2;
  1567. }
  1568. return "translate(" + x + "," + y + ")";
  1569. };
  1570. c3_chart_internal_fn.initialOpacity = function (d) {
  1571. return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;
  1572. };
  1573. c3_chart_internal_fn.initialOpacityForCircle = function (d) {
  1574. return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0;
  1575. };
  1576. c3_chart_internal_fn.opacityForCircle = function (d) {
  1577. var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show;
  1578. var opacity = isPointShouldBeShown ? 1 : 0;
  1579. return isValue(d.value) ? this.isScatterType(d) ? 0.5 : opacity : 0;
  1580. };
  1581. c3_chart_internal_fn.opacityForText = function () {
  1582. return this.hasDataLabel() ? 1 : 0;
  1583. };
  1584. c3_chart_internal_fn.xx = function (d) {
  1585. return d ? this.x(d.x) : null;
  1586. };
  1587. c3_chart_internal_fn.xv = function (d) {
  1588. var $$ = this,
  1589. value = d.value;
  1590. if ($$.isTimeSeries()) {
  1591. value = $$.parseDate(d.value);
  1592. } else if ($$.isCategorized() && typeof d.value === 'string') {
  1593. value = $$.config.axis_x_categories.indexOf(d.value);
  1594. }
  1595. return Math.ceil($$.x(value));
  1596. };
  1597. c3_chart_internal_fn.yv = function (d) {
  1598. var $$ = this,
  1599. yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;
  1600. return Math.ceil(yScale(d.value));
  1601. };
  1602. c3_chart_internal_fn.subxx = function (d) {
  1603. return d ? this.subX(d.x) : null;
  1604. };
  1605. c3_chart_internal_fn.transformMain = function (withTransition, transitions) {
  1606. var $$ = this,
  1607. xAxis,
  1608. yAxis,
  1609. y2Axis;
  1610. if (transitions && transitions.axisX) {
  1611. xAxis = transitions.axisX;
  1612. } else {
  1613. xAxis = $$.main.select('.' + CLASS.axisX);
  1614. if (withTransition) {
  1615. xAxis = xAxis.transition();
  1616. }
  1617. }
  1618. if (transitions && transitions.axisY) {
  1619. yAxis = transitions.axisY;
  1620. } else {
  1621. yAxis = $$.main.select('.' + CLASS.axisY);
  1622. if (withTransition) {
  1623. yAxis = yAxis.transition();
  1624. }
  1625. }
  1626. if (transitions && transitions.axisY2) {
  1627. y2Axis = transitions.axisY2;
  1628. } else {
  1629. y2Axis = $$.main.select('.' + CLASS.axisY2);
  1630. if (withTransition) {
  1631. y2Axis = y2Axis.transition();
  1632. }
  1633. }
  1634. (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main'));
  1635. xAxis.attr("transform", $$.getTranslate('x'));
  1636. yAxis.attr("transform", $$.getTranslate('y'));
  1637. y2Axis.attr("transform", $$.getTranslate('y2'));
  1638. $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  1639. };
  1640. c3_chart_internal_fn.transformAll = function (withTransition, transitions) {
  1641. var $$ = this;
  1642. $$.transformMain(withTransition, transitions);
  1643. if ($$.config.subchart_show) {
  1644. $$.transformContext(withTransition, transitions);
  1645. }
  1646. if ($$.legend) {
  1647. $$.transformLegend(withTransition);
  1648. }
  1649. };
  1650. c3_chart_internal_fn.updateSvgSize = function () {
  1651. var $$ = this,
  1652. brush = $$.svg.select(".c3-brush .background");
  1653. $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
  1654. $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect').attr('width', $$.width).attr('height', $$.height);
  1655. $$.svg.select('#' + $$.clipIdForXAxis).select('rect').attr('x', $$.getXAxisClipX.bind($$)).attr('y', $$.getXAxisClipY.bind($$)).attr('width', $$.getXAxisClipWidth.bind($$)).attr('height', $$.getXAxisClipHeight.bind($$));
  1656. $$.svg.select('#' + $$.clipIdForYAxis).select('rect').attr('x', $$.getYAxisClipX.bind($$)).attr('y', $$.getYAxisClipY.bind($$)).attr('width', $$.getYAxisClipWidth.bind($$)).attr('height', $$.getYAxisClipHeight.bind($$));
  1657. $$.svg.select('#' + $$.clipIdForSubchart).select('rect').attr('width', $$.width).attr('height', brush.size() ? brush.attr('height') : 0);
  1658. $$.svg.select('.' + CLASS.zoomRect).attr('width', $$.width).attr('height', $$.height);
  1659. // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
  1660. $$.selectChart.style('max-height', $$.currentHeight + "px");
  1661. };
  1662. c3_chart_internal_fn.updateDimension = function (withoutAxis) {
  1663. var $$ = this;
  1664. if (!withoutAxis) {
  1665. if ($$.config.axis_rotated) {
  1666. $$.axes.x.call($$.xAxis);
  1667. $$.axes.subx.call($$.subXAxis);
  1668. } else {
  1669. $$.axes.y.call($$.yAxis);
  1670. $$.axes.y2.call($$.y2Axis);
  1671. }
  1672. }
  1673. $$.updateSizes();
  1674. $$.updateScales();
  1675. $$.updateSvgSize();
  1676. $$.transformAll(false);
  1677. };
  1678. c3_chart_internal_fn.observeInserted = function (selection) {
  1679. var $$ = this,
  1680. observer;
  1681. if (typeof MutationObserver === 'undefined') {
  1682. window.console.error("MutationObserver not defined.");
  1683. return;
  1684. }
  1685. observer = new MutationObserver(function (mutations) {
  1686. mutations.forEach(function (mutation) {
  1687. if (mutation.type === 'childList' && mutation.previousSibling) {
  1688. observer.disconnect();
  1689. // need to wait for completion of load because size calculation requires the actual sizes determined after that completion
  1690. $$.intervalForObserveInserted = window.setInterval(function () {
  1691. // parentNode will NOT be null when completed
  1692. if (selection.node().parentNode) {
  1693. window.clearInterval($$.intervalForObserveInserted);
  1694. $$.updateDimension();
  1695. if ($$.brush) {
  1696. $$.brush.update();
  1697. }
  1698. $$.config.oninit.call($$);
  1699. $$.redraw({
  1700. withTransform: true,
  1701. withUpdateXDomain: true,
  1702. withUpdateOrgXDomain: true,
  1703. withTransition: false,
  1704. withTransitionForTransform: false,
  1705. withLegend: true
  1706. });
  1707. selection.transition().style('opacity', 1);
  1708. }
  1709. }, 10);
  1710. }
  1711. });
  1712. });
  1713. observer.observe(selection.node(), { attributes: true, childList: true, characterData: true });
  1714. };
  1715. c3_chart_internal_fn.bindResize = function () {
  1716. var $$ = this,
  1717. config = $$.config;
  1718. $$.resizeFunction = $$.generateResize();
  1719. $$.resizeFunction.add(function () {
  1720. config.onresize.call($$);
  1721. });
  1722. if (config.resize_auto) {
  1723. $$.resizeFunction.add(function () {
  1724. if ($$.resizeTimeout !== undefined) {
  1725. window.clearTimeout($$.resizeTimeout);
  1726. }
  1727. $$.resizeTimeout = window.setTimeout(function () {
  1728. delete $$.resizeTimeout;
  1729. $$.api.flush();
  1730. }, 100);
  1731. });
  1732. }
  1733. $$.resizeFunction.add(function () {
  1734. config.onresized.call($$);
  1735. });
  1736. if (window.attachEvent) {
  1737. window.attachEvent('onresize', $$.resizeFunction);
  1738. } else if (window.addEventListener) {
  1739. window.addEventListener('resize', $$.resizeFunction, false);
  1740. } else {
  1741. // fallback to this, if this is a very old browser
  1742. var wrapper = window.onresize;
  1743. if (!wrapper) {
  1744. // create a wrapper that will call all charts
  1745. wrapper = $$.generateResize();
  1746. } else if (!wrapper.add || !wrapper.remove) {
  1747. // there is already a handler registered, make sure we call it too
  1748. wrapper = $$.generateResize();
  1749. wrapper.add(window.onresize);
  1750. }
  1751. // add this graph to the wrapper, we will be removed if the user calls destroy
  1752. wrapper.add($$.resizeFunction);
  1753. window.onresize = wrapper;
  1754. }
  1755. };
  1756. c3_chart_internal_fn.generateResize = function () {
  1757. var resizeFunctions = [];
  1758. function callResizeFunctions() {
  1759. resizeFunctions.forEach(function (f) {
  1760. f();
  1761. });
  1762. }
  1763. callResizeFunctions.add = function (f) {
  1764. resizeFunctions.push(f);
  1765. };
  1766. callResizeFunctions.remove = function (f) {
  1767. for (var i = 0; i < resizeFunctions.length; i++) {
  1768. if (resizeFunctions[i] === f) {
  1769. resizeFunctions.splice(i, 1);
  1770. break;
  1771. }
  1772. }
  1773. };
  1774. return callResizeFunctions;
  1775. };
  1776. c3_chart_internal_fn.endall = function (transition, callback) {
  1777. var n = 0;
  1778. transition.each(function () {
  1779. ++n;
  1780. }).each("end", function () {
  1781. if (! --n) {
  1782. callback.apply(this, arguments);
  1783. }
  1784. });
  1785. };
  1786. c3_chart_internal_fn.generateWait = function () {
  1787. var transitionsToWait = [],
  1788. f = function f(transition, callback) {
  1789. var timer = setInterval(function () {
  1790. var done = 0;
  1791. transitionsToWait.forEach(function (t) {
  1792. if (t.empty()) {
  1793. done += 1;
  1794. return;
  1795. }
  1796. try {
  1797. t.transition();
  1798. } catch (e) {
  1799. done += 1;
  1800. }
  1801. });
  1802. if (done === transitionsToWait.length) {
  1803. clearInterval(timer);
  1804. if (callback) {
  1805. callback();
  1806. }
  1807. }
  1808. }, 10);
  1809. };
  1810. f.add = function (transition) {
  1811. transitionsToWait.push(transition);
  1812. };
  1813. return f;
  1814. };
  1815. c3_chart_internal_fn.parseDate = function (date) {
  1816. var $$ = this,
  1817. parsedDate;
  1818. if (date instanceof Date) {
  1819. parsedDate = date;
  1820. } else if (typeof date === 'string') {
  1821. parsedDate = $$.dataTimeFormat($$.config.data_xFormat).parse(date);
  1822. } else if ((typeof date === 'undefined' ? 'undefined' : _typeof(date)) === 'object') {
  1823. parsedDate = new Date(+date);
  1824. } else if (typeof date === 'number' && !isNaN(date)) {
  1825. parsedDate = new Date(+date);
  1826. }
  1827. if (!parsedDate || isNaN(+parsedDate)) {
  1828. window.console.error("Failed to parse x '" + date + "' to Date object");
  1829. }
  1830. return parsedDate;
  1831. };
  1832. c3_chart_internal_fn.isTabVisible = function () {
  1833. var hidden;
  1834. if (typeof document.hidden !== "undefined") {
  1835. // Opera 12.10 and Firefox 18 and later support
  1836. hidden = "hidden";
  1837. } else if (typeof document.mozHidden !== "undefined") {
  1838. hidden = "mozHidden";
  1839. } else if (typeof document.msHidden !== "undefined") {
  1840. hidden = "msHidden";
  1841. } else if (typeof document.webkitHidden !== "undefined") {
  1842. hidden = "webkitHidden";
  1843. }
  1844. return document[hidden] ? false : true;
  1845. };
  1846. c3_chart_internal_fn.isValue = isValue;
  1847. c3_chart_internal_fn.isFunction = isFunction;
  1848. c3_chart_internal_fn.isString = isString;
  1849. c3_chart_internal_fn.isUndefined = isUndefined;
  1850. c3_chart_internal_fn.isDefined = isDefined;
  1851. c3_chart_internal_fn.ceil10 = ceil10;
  1852. c3_chart_internal_fn.asHalfPixel = asHalfPixel;
  1853. c3_chart_internal_fn.diffDomain = diffDomain;
  1854. c3_chart_internal_fn.isEmpty = isEmpty;
  1855. c3_chart_internal_fn.notEmpty = notEmpty;
  1856. c3_chart_internal_fn.notEmpty = notEmpty;
  1857. c3_chart_internal_fn.getOption = getOption;
  1858. c3_chart_internal_fn.hasValue = hasValue;
  1859. c3_chart_internal_fn.sanitise = sanitise;
  1860. c3_chart_internal_fn.getPathBox = getPathBox;
  1861. c3_chart_internal_fn.CLASS = CLASS;
  1862. /* jshint ignore:start */
  1863. // PhantomJS doesn't have support for Function.prototype.bind, which has caused confusion. Use
  1864. // this polyfill to avoid the confusion.
  1865. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Polyfill
  1866. if (!Function.prototype.bind) {
  1867. Function.prototype.bind = function (oThis) {
  1868. if (typeof this !== 'function') {
  1869. // closest thing possible to the ECMAScript 5
  1870. // internal IsCallable function
  1871. throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
  1872. }
  1873. var aArgs = Array.prototype.slice.call(arguments, 1),
  1874. fToBind = this,
  1875. fNOP = function fNOP() {},
  1876. fBound = function fBound() {
  1877. return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
  1878. };
  1879. fNOP.prototype = this.prototype;
  1880. fBound.prototype = new fNOP();
  1881. return fBound;
  1882. };
  1883. }
  1884. // SVGPathSeg API polyfill
  1885. // https://github.com/progers/pathseg
  1886. //
  1887. // This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from
  1888. // SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec
  1889. // changes which were implemented in Firefox 43 and Chrome 46.
  1890. (function () {
  1891. "use strict";
  1892. if (!("SVGPathSeg" in window)) {
  1893. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
  1894. window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {
  1895. this.pathSegType = type;
  1896. this.pathSegTypeAsLetter = typeAsLetter;
  1897. this._owningPathSegList = owningPathSegList;
  1898. };
  1899. window.SVGPathSeg.prototype.classname = "SVGPathSeg";
  1900. window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
  1901. window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
  1902. window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
  1903. window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
  1904. window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
  1905. window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
  1906. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
  1907. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
  1908. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
  1909. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
  1910. window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
  1911. window.SVGPathSeg.PATHSEG_ARC_REL = 11;
  1912. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
  1913. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
  1914. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
  1915. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
  1916. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
  1917. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
  1918. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
  1919. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19;
  1920. // Notify owning PathSegList on any changes so they can be synchronized back to the path element.
  1921. window.SVGPathSeg.prototype._segmentChanged = function () {
  1922. if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);
  1923. };
  1924. window.SVGPathSegClosePath = function (owningPathSegList) {
  1925. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
  1926. };
  1927. window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
  1928. window.SVGPathSegClosePath.prototype.toString = function () {
  1929. return "[object SVGPathSegClosePath]";
  1930. };
  1931. window.SVGPathSegClosePath.prototype._asPathString = function () {
  1932. return this.pathSegTypeAsLetter;
  1933. };
  1934. window.SVGPathSegClosePath.prototype.clone = function () {
  1935. return new window.SVGPathSegClosePath(undefined);
  1936. };
  1937. window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {
  1938. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
  1939. this._x = x;
  1940. this._y = y;
  1941. };
  1942. window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  1943. window.SVGPathSegMovetoAbs.prototype.toString = function () {
  1944. return "[object SVGPathSegMovetoAbs]";
  1945. };
  1946. window.SVGPathSegMovetoAbs.prototype._asPathString = function () {
  1947. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  1948. };
  1949. window.SVGPathSegMovetoAbs.prototype.clone = function () {
  1950. return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y);
  1951. };
  1952. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", { get: function get() {
  1953. return this._x;
  1954. }, set: function set(x) {
  1955. this._x = x;this._segmentChanged();
  1956. }, enumerable: true });
  1957. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", { get: function get() {
  1958. return this._y;
  1959. }, set: function set(y) {
  1960. this._y = y;this._segmentChanged();
  1961. }, enumerable: true });
  1962. window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {
  1963. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
  1964. this._x = x;
  1965. this._y = y;
  1966. };
  1967. window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  1968. window.SVGPathSegMovetoRel.prototype.toString = function () {
  1969. return "[object SVGPathSegMovetoRel]";
  1970. };
  1971. window.SVGPathSegMovetoRel.prototype._asPathString = function () {
  1972. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  1973. };
  1974. window.SVGPathSegMovetoRel.prototype.clone = function () {
  1975. return new window.SVGPathSegMovetoRel(undefined, this._x, this._y);
  1976. };
  1977. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", { get: function get() {
  1978. return this._x;
  1979. }, set: function set(x) {
  1980. this._x = x;this._segmentChanged();
  1981. }, enumerable: true });
  1982. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", { get: function get() {
  1983. return this._y;
  1984. }, set: function set(y) {
  1985. this._y = y;this._segmentChanged();
  1986. }, enumerable: true });
  1987. window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {
  1988. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
  1989. this._x = x;
  1990. this._y = y;
  1991. };
  1992. window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  1993. window.SVGPathSegLinetoAbs.prototype.toString = function () {
  1994. return "[object SVGPathSegLinetoAbs]";
  1995. };
  1996. window.SVGPathSegLinetoAbs.prototype._asPathString = function () {
  1997. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  1998. };
  1999. window.SVGPathSegLinetoAbs.prototype.clone = function () {
  2000. return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y);
  2001. };
  2002. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", { get: function get() {
  2003. return this._x;
  2004. }, set: function set(x) {
  2005. this._x = x;this._segmentChanged();
  2006. }, enumerable: true });
  2007. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", { get: function get() {
  2008. return this._y;
  2009. }, set: function set(y) {
  2010. this._y = y;this._segmentChanged();
  2011. }, enumerable: true });
  2012. window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {
  2013. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
  2014. this._x = x;
  2015. this._y = y;
  2016. };
  2017. window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2018. window.SVGPathSegLinetoRel.prototype.toString = function () {
  2019. return "[object SVGPathSegLinetoRel]";
  2020. };
  2021. window.SVGPathSegLinetoRel.prototype._asPathString = function () {
  2022. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2023. };
  2024. window.SVGPathSegLinetoRel.prototype.clone = function () {
  2025. return new window.SVGPathSegLinetoRel(undefined, this._x, this._y);
  2026. };
  2027. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", { get: function get() {
  2028. return this._x;
  2029. }, set: function set(x) {
  2030. this._x = x;this._segmentChanged();
  2031. }, enumerable: true });
  2032. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", { get: function get() {
  2033. return this._y;
  2034. }, set: function set(y) {
  2035. this._y = y;this._segmentChanged();
  2036. }, enumerable: true });
  2037. window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2038. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
  2039. this._x = x;
  2040. this._y = y;
  2041. this._x1 = x1;
  2042. this._y1 = y1;
  2043. this._x2 = x2;
  2044. this._y2 = y2;
  2045. };
  2046. window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2047. window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () {
  2048. return "[object SVGPathSegCurvetoCubicAbs]";
  2049. };
  2050. window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () {
  2051. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2052. };
  2053. window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () {
  2054. return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2055. };
  2056. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", { get: function get() {
  2057. return this._x;
  2058. }, set: function set(x) {
  2059. this._x = x;this._segmentChanged();
  2060. }, enumerable: true });
  2061. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", { get: function get() {
  2062. return this._y;
  2063. }, set: function set(y) {
  2064. this._y = y;this._segmentChanged();
  2065. }, enumerable: true });
  2066. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", { get: function get() {
  2067. return this._x1;
  2068. }, set: function set(x1) {
  2069. this._x1 = x1;this._segmentChanged();
  2070. }, enumerable: true });
  2071. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", { get: function get() {
  2072. return this._y1;
  2073. }, set: function set(y1) {
  2074. this._y1 = y1;this._segmentChanged();
  2075. }, enumerable: true });
  2076. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", { get: function get() {
  2077. return this._x2;
  2078. }, set: function set(x2) {
  2079. this._x2 = x2;this._segmentChanged();
  2080. }, enumerable: true });
  2081. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", { get: function get() {
  2082. return this._y2;
  2083. }, set: function set(y2) {
  2084. this._y2 = y2;this._segmentChanged();
  2085. }, enumerable: true });
  2086. window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2087. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
  2088. this._x = x;
  2089. this._y = y;
  2090. this._x1 = x1;
  2091. this._y1 = y1;
  2092. this._x2 = x2;
  2093. this._y2 = y2;
  2094. };
  2095. window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2096. window.SVGPathSegCurvetoCubicRel.prototype.toString = function () {
  2097. return "[object SVGPathSegCurvetoCubicRel]";
  2098. };
  2099. window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () {
  2100. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2101. };
  2102. window.SVGPathSegCurvetoCubicRel.prototype.clone = function () {
  2103. return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2104. };
  2105. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", { get: function get() {
  2106. return this._x;
  2107. }, set: function set(x) {
  2108. this._x = x;this._segmentChanged();
  2109. }, enumerable: true });
  2110. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", { get: function get() {
  2111. return this._y;
  2112. }, set: function set(y) {
  2113. this._y = y;this._segmentChanged();
  2114. }, enumerable: true });
  2115. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", { get: function get() {
  2116. return this._x1;
  2117. }, set: function set(x1) {
  2118. this._x1 = x1;this._segmentChanged();
  2119. }, enumerable: true });
  2120. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", { get: function get() {
  2121. return this._y1;
  2122. }, set: function set(y1) {
  2123. this._y1 = y1;this._segmentChanged();
  2124. }, enumerable: true });
  2125. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", { get: function get() {
  2126. return this._x2;
  2127. }, set: function set(x2) {
  2128. this._x2 = x2;this._segmentChanged();
  2129. }, enumerable: true });
  2130. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", { get: function get() {
  2131. return this._y2;
  2132. }, set: function set(y2) {
  2133. this._y2 = y2;this._segmentChanged();
  2134. }, enumerable: true });
  2135. window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {
  2136. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
  2137. this._x = x;
  2138. this._y = y;
  2139. this._x1 = x1;
  2140. this._y1 = y1;
  2141. };
  2142. window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2143. window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () {
  2144. return "[object SVGPathSegCurvetoQuadraticAbs]";
  2145. };
  2146. window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () {
  2147. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2148. };
  2149. window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () {
  2150. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1);
  2151. };
  2152. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", { get: function get() {
  2153. return this._x;
  2154. }, set: function set(x) {
  2155. this._x = x;this._segmentChanged();
  2156. }, enumerable: true });
  2157. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", { get: function get() {
  2158. return this._y;
  2159. }, set: function set(y) {
  2160. this._y = y;this._segmentChanged();
  2161. }, enumerable: true });
  2162. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", { get: function get() {
  2163. return this._x1;
  2164. }, set: function set(x1) {
  2165. this._x1 = x1;this._segmentChanged();
  2166. }, enumerable: true });
  2167. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", { get: function get() {
  2168. return this._y1;
  2169. }, set: function set(y1) {
  2170. this._y1 = y1;this._segmentChanged();
  2171. }, enumerable: true });
  2172. window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {
  2173. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
  2174. this._x = x;
  2175. this._y = y;
  2176. this._x1 = x1;
  2177. this._y1 = y1;
  2178. };
  2179. window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2180. window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () {
  2181. return "[object SVGPathSegCurvetoQuadraticRel]";
  2182. };
  2183. window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () {
  2184. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2185. };
  2186. window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () {
  2187. return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1);
  2188. };
  2189. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", { get: function get() {
  2190. return this._x;
  2191. }, set: function set(x) {
  2192. this._x = x;this._segmentChanged();
  2193. }, enumerable: true });
  2194. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", { get: function get() {
  2195. return this._y;
  2196. }, set: function set(y) {
  2197. this._y = y;this._segmentChanged();
  2198. }, enumerable: true });
  2199. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", { get: function get() {
  2200. return this._x1;
  2201. }, set: function set(x1) {
  2202. this._x1 = x1;this._segmentChanged();
  2203. }, enumerable: true });
  2204. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", { get: function get() {
  2205. return this._y1;
  2206. }, set: function set(y1) {
  2207. this._y1 = y1;this._segmentChanged();
  2208. }, enumerable: true });
  2209. window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2210. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
  2211. this._x = x;
  2212. this._y = y;
  2213. this._r1 = r1;
  2214. this._r2 = r2;
  2215. this._angle = angle;
  2216. this._largeArcFlag = largeArcFlag;
  2217. this._sweepFlag = sweepFlag;
  2218. };
  2219. window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2220. window.SVGPathSegArcAbs.prototype.toString = function () {
  2221. return "[object SVGPathSegArcAbs]";
  2222. };
  2223. window.SVGPathSegArcAbs.prototype._asPathString = function () {
  2224. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2225. };
  2226. window.SVGPathSegArcAbs.prototype.clone = function () {
  2227. return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2228. };
  2229. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", { get: function get() {
  2230. return this._x;
  2231. }, set: function set(x) {
  2232. this._x = x;this._segmentChanged();
  2233. }, enumerable: true });
  2234. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", { get: function get() {
  2235. return this._y;
  2236. }, set: function set(y) {
  2237. this._y = y;this._segmentChanged();
  2238. }, enumerable: true });
  2239. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", { get: function get() {
  2240. return this._r1;
  2241. }, set: function set(r1) {
  2242. this._r1 = r1;this._segmentChanged();
  2243. }, enumerable: true });
  2244. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", { get: function get() {
  2245. return this._r2;
  2246. }, set: function set(r2) {
  2247. this._r2 = r2;this._segmentChanged();
  2248. }, enumerable: true });
  2249. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", { get: function get() {
  2250. return this._angle;
  2251. }, set: function set(angle) {
  2252. this._angle = angle;this._segmentChanged();
  2253. }, enumerable: true });
  2254. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", { get: function get() {
  2255. return this._largeArcFlag;
  2256. }, set: function set(largeArcFlag) {
  2257. this._largeArcFlag = largeArcFlag;this._segmentChanged();
  2258. }, enumerable: true });
  2259. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", { get: function get() {
  2260. return this._sweepFlag;
  2261. }, set: function set(sweepFlag) {
  2262. this._sweepFlag = sweepFlag;this._segmentChanged();
  2263. }, enumerable: true });
  2264. window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2265. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
  2266. this._x = x;
  2267. this._y = y;
  2268. this._r1 = r1;
  2269. this._r2 = r2;
  2270. this._angle = angle;
  2271. this._largeArcFlag = largeArcFlag;
  2272. this._sweepFlag = sweepFlag;
  2273. };
  2274. window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2275. window.SVGPathSegArcRel.prototype.toString = function () {
  2276. return "[object SVGPathSegArcRel]";
  2277. };
  2278. window.SVGPathSegArcRel.prototype._asPathString = function () {
  2279. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2280. };
  2281. window.SVGPathSegArcRel.prototype.clone = function () {
  2282. return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2283. };
  2284. Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", { get: function get() {
  2285. return this._x;
  2286. }, set: function set(x) {
  2287. this._x = x;this._segmentChanged();
  2288. }, enumerable: true });
  2289. Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", { get: function get() {
  2290. return this._y;
  2291. }, set: function set(y) {
  2292. this._y = y;this._segmentChanged();
  2293. }, enumerable: true });
  2294. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", { get: function get() {
  2295. return this._r1;
  2296. }, set: function set(r1) {
  2297. this._r1 = r1;this._segmentChanged();
  2298. }, enumerable: true });
  2299. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", { get: function get() {
  2300. return this._r2;
  2301. }, set: function set(r2) {
  2302. this._r2 = r2;this._segmentChanged();
  2303. }, enumerable: true });
  2304. Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", { get: function get() {
  2305. return this._angle;
  2306. }, set: function set(angle) {
  2307. this._angle = angle;this._segmentChanged();
  2308. }, enumerable: true });
  2309. Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", { get: function get() {
  2310. return this._largeArcFlag;
  2311. }, set: function set(largeArcFlag) {
  2312. this._largeArcFlag = largeArcFlag;this._segmentChanged();
  2313. }, enumerable: true });
  2314. Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", { get: function get() {
  2315. return this._sweepFlag;
  2316. }, set: function set(sweepFlag) {
  2317. this._sweepFlag = sweepFlag;this._segmentChanged();
  2318. }, enumerable: true });
  2319. window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {
  2320. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
  2321. this._x = x;
  2322. };
  2323. window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2324. window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () {
  2325. return "[object SVGPathSegLinetoHorizontalAbs]";
  2326. };
  2327. window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () {
  2328. return this.pathSegTypeAsLetter + " " + this._x;
  2329. };
  2330. window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () {
  2331. return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x);
  2332. };
  2333. Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", { get: function get() {
  2334. return this._x;
  2335. }, set: function set(x) {
  2336. this._x = x;this._segmentChanged();
  2337. }, enumerable: true });
  2338. window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {
  2339. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
  2340. this._x = x;
  2341. };
  2342. window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2343. window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () {
  2344. return "[object SVGPathSegLinetoHorizontalRel]";
  2345. };
  2346. window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () {
  2347. return this.pathSegTypeAsLetter + " " + this._x;
  2348. };
  2349. window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () {
  2350. return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x);
  2351. };
  2352. Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", { get: function get() {
  2353. return this._x;
  2354. }, set: function set(x) {
  2355. this._x = x;this._segmentChanged();
  2356. }, enumerable: true });
  2357. window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {
  2358. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
  2359. this._y = y;
  2360. };
  2361. window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2362. window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () {
  2363. return "[object SVGPathSegLinetoVerticalAbs]";
  2364. };
  2365. window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () {
  2366. return this.pathSegTypeAsLetter + " " + this._y;
  2367. };
  2368. window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () {
  2369. return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y);
  2370. };
  2371. Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", { get: function get() {
  2372. return this._y;
  2373. }, set: function set(y) {
  2374. this._y = y;this._segmentChanged();
  2375. }, enumerable: true });
  2376. window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {
  2377. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
  2378. this._y = y;
  2379. };
  2380. window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2381. window.SVGPathSegLinetoVerticalRel.prototype.toString = function () {
  2382. return "[object SVGPathSegLinetoVerticalRel]";
  2383. };
  2384. window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () {
  2385. return this.pathSegTypeAsLetter + " " + this._y;
  2386. };
  2387. window.SVGPathSegLinetoVerticalRel.prototype.clone = function () {
  2388. return new window.SVGPathSegLinetoVerticalRel(undefined, this._y);
  2389. };
  2390. Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", { get: function get() {
  2391. return this._y;
  2392. }, set: function set(y) {
  2393. this._y = y;this._segmentChanged();
  2394. }, enumerable: true });
  2395. window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {
  2396. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
  2397. this._x = x;
  2398. this._y = y;
  2399. this._x2 = x2;
  2400. this._y2 = y2;
  2401. };
  2402. window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2403. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () {
  2404. return "[object SVGPathSegCurvetoCubicSmoothAbs]";
  2405. };
  2406. window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () {
  2407. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2408. };
  2409. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () {
  2410. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2);
  2411. };
  2412. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", { get: function get() {
  2413. return this._x;
  2414. }, set: function set(x) {
  2415. this._x = x;this._segmentChanged();
  2416. }, enumerable: true });
  2417. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", { get: function get() {
  2418. return this._y;
  2419. }, set: function set(y) {
  2420. this._y = y;this._segmentChanged();
  2421. }, enumerable: true });
  2422. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", { get: function get() {
  2423. return this._x2;
  2424. }, set: function set(x2) {
  2425. this._x2 = x2;this._segmentChanged();
  2426. }, enumerable: true });
  2427. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", { get: function get() {
  2428. return this._y2;
  2429. }, set: function set(y2) {
  2430. this._y2 = y2;this._segmentChanged();
  2431. }, enumerable: true });
  2432. window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {
  2433. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
  2434. this._x = x;
  2435. this._y = y;
  2436. this._x2 = x2;
  2437. this._y2 = y2;
  2438. };
  2439. window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2440. window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () {
  2441. return "[object SVGPathSegCurvetoCubicSmoothRel]";
  2442. };
  2443. window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () {
  2444. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2445. };
  2446. window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () {
  2447. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2);
  2448. };
  2449. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", { get: function get() {
  2450. return this._x;
  2451. }, set: function set(x) {
  2452. this._x = x;this._segmentChanged();
  2453. }, enumerable: true });
  2454. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", { get: function get() {
  2455. return this._y;
  2456. }, set: function set(y) {
  2457. this._y = y;this._segmentChanged();
  2458. }, enumerable: true });
  2459. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", { get: function get() {
  2460. return this._x2;
  2461. }, set: function set(x2) {
  2462. this._x2 = x2;this._segmentChanged();
  2463. }, enumerable: true });
  2464. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", { get: function get() {
  2465. return this._y2;
  2466. }, set: function set(y2) {
  2467. this._y2 = y2;this._segmentChanged();
  2468. }, enumerable: true });
  2469. window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {
  2470. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
  2471. this._x = x;
  2472. this._y = y;
  2473. };
  2474. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2475. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () {
  2476. return "[object SVGPathSegCurvetoQuadraticSmoothAbs]";
  2477. };
  2478. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () {
  2479. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2480. };
  2481. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () {
  2482. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y);
  2483. };
  2484. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", { get: function get() {
  2485. return this._x;
  2486. }, set: function set(x) {
  2487. this._x = x;this._segmentChanged();
  2488. }, enumerable: true });
  2489. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", { get: function get() {
  2490. return this._y;
  2491. }, set: function set(y) {
  2492. this._y = y;this._segmentChanged();
  2493. }, enumerable: true });
  2494. window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {
  2495. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
  2496. this._x = x;
  2497. this._y = y;
  2498. };
  2499. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2500. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () {
  2501. return "[object SVGPathSegCurvetoQuadraticSmoothRel]";
  2502. };
  2503. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () {
  2504. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2505. };
  2506. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () {
  2507. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y);
  2508. };
  2509. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", { get: function get() {
  2510. return this._x;
  2511. }, set: function set(x) {
  2512. this._x = x;this._segmentChanged();
  2513. }, enumerable: true });
  2514. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", { get: function get() {
  2515. return this._y;
  2516. }, set: function set(y) {
  2517. this._y = y;this._segmentChanged();
  2518. }, enumerable: true });
  2519. // Add createSVGPathSeg* functions to window.SVGPathElement.
  2520. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
  2521. window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {
  2522. return new window.SVGPathSegClosePath(undefined);
  2523. };
  2524. window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) {
  2525. return new window.SVGPathSegMovetoAbs(undefined, x, y);
  2526. };
  2527. window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) {
  2528. return new window.SVGPathSegMovetoRel(undefined, x, y);
  2529. };
  2530. window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) {
  2531. return new window.SVGPathSegLinetoAbs(undefined, x, y);
  2532. };
  2533. window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) {
  2534. return new window.SVGPathSegLinetoRel(undefined, x, y);
  2535. };
  2536. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) {
  2537. return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2);
  2538. };
  2539. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) {
  2540. return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2);
  2541. };
  2542. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) {
  2543. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1);
  2544. };
  2545. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) {
  2546. return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1);
  2547. };
  2548. window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2549. return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  2550. };
  2551. window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2552. return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  2553. };
  2554. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) {
  2555. return new window.SVGPathSegLinetoHorizontalAbs(undefined, x);
  2556. };
  2557. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) {
  2558. return new window.SVGPathSegLinetoHorizontalRel(undefined, x);
  2559. };
  2560. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) {
  2561. return new window.SVGPathSegLinetoVerticalAbs(undefined, y);
  2562. };
  2563. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) {
  2564. return new window.SVGPathSegLinetoVerticalRel(undefined, y);
  2565. };
  2566. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) {
  2567. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2);
  2568. };
  2569. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) {
  2570. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2);
  2571. };
  2572. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) {
  2573. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y);
  2574. };
  2575. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) {
  2576. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y);
  2577. };
  2578. if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) {
  2579. // Add getPathSegAtLength to SVGPathElement.
  2580. // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
  2581. // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
  2582. window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {
  2583. if (distance === undefined || !isFinite(distance)) throw "Invalid arguments.";
  2584. var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  2585. measurementElement.setAttribute("d", this.getAttribute("d"));
  2586. var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1;
  2587. // If the path is empty, return 0.
  2588. if (lastPathSegment <= 0) return 0;
  2589. do {
  2590. measurementElement.pathSegList.removeItem(lastPathSegment);
  2591. if (distance > measurementElement.getTotalLength()) break;
  2592. lastPathSegment--;
  2593. } while (lastPathSegment > 0);
  2594. return lastPathSegment;
  2595. };
  2596. }
  2597. }
  2598. if (!("SVGPathSegList" in window)) {
  2599. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
  2600. window.SVGPathSegList = function (pathElement) {
  2601. this._pathElement = pathElement;
  2602. this._list = this._parsePath(this._pathElement.getAttribute("d"));
  2603. // Use a MutationObserver to catch changes to the path's "d" attribute.
  2604. this._mutationObserverConfig = { "attributes": true, "attributeFilter": ["d"] };
  2605. this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
  2606. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  2607. };
  2608. window.SVGPathSegList.prototype.classname = "SVGPathSegList";
  2609. Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
  2610. get: function get() {
  2611. this._checkPathSynchronizedToList();
  2612. return this._list.length;
  2613. },
  2614. enumerable: true
  2615. });
  2616. // Add the pathSegList accessors to window.SVGPathElement.
  2617. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
  2618. Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
  2619. get: function get() {
  2620. if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this);
  2621. return this._pathSegList;
  2622. },
  2623. enumerable: true
  2624. });
  2625. // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
  2626. Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", { get: function get() {
  2627. return this.pathSegList;
  2628. }, enumerable: true });
  2629. Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", { get: function get() {
  2630. return this.pathSegList;
  2631. }, enumerable: true });
  2632. Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", { get: function get() {
  2633. return this.pathSegList;
  2634. }, enumerable: true });
  2635. // Process any pending mutations to the path element and update the list as needed.
  2636. // This should be the first call of all public functions and is needed because
  2637. // MutationObservers are not synchronous so we can have pending asynchronous mutations.
  2638. window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {
  2639. this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
  2640. };
  2641. window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {
  2642. if (!this._pathElement) return;
  2643. var hasPathMutations = false;
  2644. mutationRecords.forEach(function (record) {
  2645. if (record.attributeName == "d") hasPathMutations = true;
  2646. });
  2647. if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d"));
  2648. };
  2649. // Serialize the list and update the path's 'd' attribute.
  2650. window.SVGPathSegList.prototype._writeListToPath = function () {
  2651. this._pathElementMutationObserver.disconnect();
  2652. this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
  2653. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  2654. };
  2655. // When a path segment changes the list needs to be synchronized back to the path element.
  2656. window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {
  2657. this._writeListToPath();
  2658. };
  2659. window.SVGPathSegList.prototype.clear = function () {
  2660. this._checkPathSynchronizedToList();
  2661. this._list.forEach(function (pathSeg) {
  2662. pathSeg._owningPathSegList = null;
  2663. });
  2664. this._list = [];
  2665. this._writeListToPath();
  2666. };
  2667. window.SVGPathSegList.prototype.initialize = function (newItem) {
  2668. this._checkPathSynchronizedToList();
  2669. this._list = [newItem];
  2670. newItem._owningPathSegList = this;
  2671. this._writeListToPath();
  2672. return newItem;
  2673. };
  2674. window.SVGPathSegList.prototype._checkValidIndex = function (index) {
  2675. if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR";
  2676. };
  2677. window.SVGPathSegList.prototype.getItem = function (index) {
  2678. this._checkPathSynchronizedToList();
  2679. this._checkValidIndex(index);
  2680. return this._list[index];
  2681. };
  2682. window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {
  2683. this._checkPathSynchronizedToList();
  2684. // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
  2685. if (index > this.numberOfItems) index = this.numberOfItems;
  2686. if (newItem._owningPathSegList) {
  2687. // SVG2 spec says to make a copy.
  2688. newItem = newItem.clone();
  2689. }
  2690. this._list.splice(index, 0, newItem);
  2691. newItem._owningPathSegList = this;
  2692. this._writeListToPath();
  2693. return newItem;
  2694. };
  2695. window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {
  2696. this._checkPathSynchronizedToList();
  2697. if (newItem._owningPathSegList) {
  2698. // SVG2 spec says to make a copy.
  2699. newItem = newItem.clone();
  2700. }
  2701. this._checkValidIndex(index);
  2702. this._list[index] = newItem;
  2703. newItem._owningPathSegList = this;
  2704. this._writeListToPath();
  2705. return newItem;
  2706. };
  2707. window.SVGPathSegList.prototype.removeItem = function (index) {
  2708. this._checkPathSynchronizedToList();
  2709. this._checkValidIndex(index);
  2710. var item = this._list[index];
  2711. this._list.splice(index, 1);
  2712. this._writeListToPath();
  2713. return item;
  2714. };
  2715. window.SVGPathSegList.prototype.appendItem = function (newItem) {
  2716. this._checkPathSynchronizedToList();
  2717. if (newItem._owningPathSegList) {
  2718. // SVG2 spec says to make a copy.
  2719. newItem = newItem.clone();
  2720. }
  2721. this._list.push(newItem);
  2722. newItem._owningPathSegList = this;
  2723. // TODO: Optimize this to just append to the existing attribute.
  2724. this._writeListToPath();
  2725. return newItem;
  2726. };
  2727. window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {
  2728. var string = "";
  2729. var first = true;
  2730. pathSegArray.forEach(function (pathSeg) {
  2731. if (first) {
  2732. first = false;
  2733. string += pathSeg._asPathString();
  2734. } else {
  2735. string += " " + pathSeg._asPathString();
  2736. }
  2737. });
  2738. return string;
  2739. };
  2740. // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
  2741. window.SVGPathSegList.prototype._parsePath = function (string) {
  2742. if (!string || string.length == 0) return [];
  2743. var owningPathSegList = this;
  2744. var Builder = function Builder() {
  2745. this.pathSegList = [];
  2746. };
  2747. Builder.prototype.appendSegment = function (pathSeg) {
  2748. this.pathSegList.push(pathSeg);
  2749. };
  2750. var Source = function Source(string) {
  2751. this._string = string;
  2752. this._currentIndex = 0;
  2753. this._endIndex = this._string.length;
  2754. this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
  2755. this._skipOptionalSpaces();
  2756. };
  2757. Source.prototype._isCurrentSpace = function () {
  2758. var character = this._string[this._currentIndex];
  2759. return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
  2760. };
  2761. Source.prototype._skipOptionalSpaces = function () {
  2762. while (this._currentIndex < this._endIndex && this._isCurrentSpace()) {
  2763. this._currentIndex++;
  2764. }return this._currentIndex < this._endIndex;
  2765. };
  2766. Source.prototype._skipOptionalSpacesOrDelimiter = function () {
  2767. if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false;
  2768. if (this._skipOptionalSpaces()) {
  2769. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
  2770. this._currentIndex++;
  2771. this._skipOptionalSpaces();
  2772. }
  2773. }
  2774. return this._currentIndex < this._endIndex;
  2775. };
  2776. Source.prototype.hasMoreData = function () {
  2777. return this._currentIndex < this._endIndex;
  2778. };
  2779. Source.prototype.peekSegmentType = function () {
  2780. var lookahead = this._string[this._currentIndex];
  2781. return this._pathSegTypeFromChar(lookahead);
  2782. };
  2783. Source.prototype._pathSegTypeFromChar = function (lookahead) {
  2784. switch (lookahead) {
  2785. case "Z":
  2786. case "z":
  2787. return window.SVGPathSeg.PATHSEG_CLOSEPATH;
  2788. case "M":
  2789. return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
  2790. case "m":
  2791. return window.SVGPathSeg.PATHSEG_MOVETO_REL;
  2792. case "L":
  2793. return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  2794. case "l":
  2795. return window.SVGPathSeg.PATHSEG_LINETO_REL;
  2796. case "C":
  2797. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
  2798. case "c":
  2799. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
  2800. case "Q":
  2801. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
  2802. case "q":
  2803. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
  2804. case "A":
  2805. return window.SVGPathSeg.PATHSEG_ARC_ABS;
  2806. case "a":
  2807. return window.SVGPathSeg.PATHSEG_ARC_REL;
  2808. case "H":
  2809. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
  2810. case "h":
  2811. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
  2812. case "V":
  2813. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
  2814. case "v":
  2815. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
  2816. case "S":
  2817. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
  2818. case "s":
  2819. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
  2820. case "T":
  2821. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
  2822. case "t":
  2823. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
  2824. default:
  2825. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  2826. }
  2827. };
  2828. Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {
  2829. // Check for remaining coordinates in the current command.
  2830. if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
  2831. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  2832. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL;
  2833. return previousCommand;
  2834. }
  2835. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  2836. };
  2837. Source.prototype.initialCommandIsMoveTo = function () {
  2838. // If the path is empty it is still valid, so return true.
  2839. if (!this.hasMoreData()) return true;
  2840. var command = this.peekSegmentType();
  2841. // Path must start with moveTo.
  2842. return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
  2843. };
  2844. // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
  2845. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
  2846. Source.prototype._parseNumber = function () {
  2847. var exponent = 0;
  2848. var integer = 0;
  2849. var frac = 1;
  2850. var decimal = 0;
  2851. var sign = 1;
  2852. var expsign = 1;
  2853. var startIndex = this._currentIndex;
  2854. this._skipOptionalSpaces();
  2855. // Read the sign.
  2856. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
  2857. this._currentIndex++;
  2858. sign = -1;
  2859. }
  2860. if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".")
  2861. // The first character of a number must be one of [0-9+-.].
  2862. return undefined;
  2863. // Read the integer part, build right-to-left.
  2864. var startIntPartIndex = this._currentIndex;
  2865. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  2866. this._currentIndex++;
  2867. } // Advance to first non-digit.
  2868. if (this._currentIndex != startIntPartIndex) {
  2869. var scanIntPartIndex = this._currentIndex - 1;
  2870. var multiplier = 1;
  2871. while (scanIntPartIndex >= startIntPartIndex) {
  2872. integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
  2873. multiplier *= 10;
  2874. }
  2875. }
  2876. // Read the decimals.
  2877. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
  2878. this._currentIndex++;
  2879. // There must be a least one digit following the .
  2880. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  2881. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  2882. frac *= 10;
  2883. decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
  2884. this._currentIndex += 1;
  2885. }
  2886. }
  2887. // Read the exponent part.
  2888. 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") {
  2889. this._currentIndex++;
  2890. // Read the sign of the exponent.
  2891. if (this._string.charAt(this._currentIndex) == "+") {
  2892. this._currentIndex++;
  2893. } else if (this._string.charAt(this._currentIndex) == "-") {
  2894. this._currentIndex++;
  2895. expsign = -1;
  2896. }
  2897. // There must be an exponent.
  2898. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  2899. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  2900. exponent *= 10;
  2901. exponent += this._string.charAt(this._currentIndex) - "0";
  2902. this._currentIndex++;
  2903. }
  2904. }
  2905. var number = integer + decimal;
  2906. number *= sign;
  2907. if (exponent) number *= Math.pow(10, expsign * exponent);
  2908. if (startIndex == this._currentIndex) return undefined;
  2909. this._skipOptionalSpacesOrDelimiter();
  2910. return number;
  2911. };
  2912. Source.prototype._parseArcFlag = function () {
  2913. if (this._currentIndex >= this._endIndex) return undefined;
  2914. var flag = false;
  2915. var flagChar = this._string.charAt(this._currentIndex++);
  2916. if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined;
  2917. this._skipOptionalSpacesOrDelimiter();
  2918. return flag;
  2919. };
  2920. Source.prototype.parseSegment = function () {
  2921. var lookahead = this._string[this._currentIndex];
  2922. var command = this._pathSegTypeFromChar(lookahead);
  2923. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
  2924. // Possibly an implicit command. Not allowed if this is the first command.
  2925. if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  2926. command = this._nextCommandHelper(lookahead, this._previousCommand);
  2927. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  2928. } else {
  2929. this._currentIndex++;
  2930. }
  2931. this._previousCommand = command;
  2932. switch (command) {
  2933. case window.SVGPathSeg.PATHSEG_MOVETO_REL:
  2934. return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  2935. case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
  2936. return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  2937. case window.SVGPathSeg.PATHSEG_LINETO_REL:
  2938. return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  2939. case window.SVGPathSeg.PATHSEG_LINETO_ABS:
  2940. return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  2941. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
  2942. return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
  2943. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
  2944. return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
  2945. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
  2946. return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
  2947. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
  2948. return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
  2949. case window.SVGPathSeg.PATHSEG_CLOSEPATH:
  2950. this._skipOptionalSpaces();
  2951. return new window.SVGPathSegClosePath(owningPathSegList);
  2952. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
  2953. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  2954. return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  2955. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
  2956. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  2957. return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  2958. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
  2959. var points = { x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  2960. return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
  2961. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
  2962. var points = { x2: this._parseNumber(), y2: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  2963. return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
  2964. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
  2965. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  2966. return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
  2967. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
  2968. var points = { x1: this._parseNumber(), y1: this._parseNumber(), x: this._parseNumber(), y: this._parseNumber() };
  2969. return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
  2970. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
  2971. return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  2972. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
  2973. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  2974. case window.SVGPathSeg.PATHSEG_ARC_REL:
  2975. var points = { x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber() };
  2976. return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  2977. case window.SVGPathSeg.PATHSEG_ARC_ABS:
  2978. var points = { x1: this._parseNumber(), y1: this._parseNumber(), arcAngle: this._parseNumber(), arcLarge: this._parseArcFlag(), arcSweep: this._parseArcFlag(), x: this._parseNumber(), y: this._parseNumber() };
  2979. return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  2980. default:
  2981. throw "Unknown path seg type.";
  2982. }
  2983. };
  2984. var builder = new Builder();
  2985. var source = new Source(string);
  2986. if (!source.initialCommandIsMoveTo()) return [];
  2987. while (source.hasMoreData()) {
  2988. var pathSeg = source.parseSegment();
  2989. if (!pathSeg) return [];
  2990. builder.appendSegment(pathSeg);
  2991. }
  2992. return builder.pathSegList;
  2993. };
  2994. }
  2995. })();
  2996. /* jshint ignore:end */
  2997. c3_chart_fn.axis = function () {};
  2998. c3_chart_fn.axis.labels = function (labels) {
  2999. var $$ = this.internal;
  3000. if (arguments.length) {
  3001. Object.keys(labels).forEach(function (axisId) {
  3002. $$.axis.setLabelText(axisId, labels[axisId]);
  3003. });
  3004. $$.axis.updateLabels();
  3005. }
  3006. // TODO: return some values?
  3007. };
  3008. c3_chart_fn.axis.max = function (max) {
  3009. var $$ = this.internal,
  3010. config = $$.config;
  3011. if (arguments.length) {
  3012. if ((typeof max === 'undefined' ? 'undefined' : _typeof(max)) === 'object') {
  3013. if (isValue(max.x)) {
  3014. config.axis_x_max = max.x;
  3015. }
  3016. if (isValue(max.y)) {
  3017. config.axis_y_max = max.y;
  3018. }
  3019. if (isValue(max.y2)) {
  3020. config.axis_y2_max = max.y2;
  3021. }
  3022. } else {
  3023. config.axis_y_max = config.axis_y2_max = max;
  3024. }
  3025. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3026. } else {
  3027. return {
  3028. x: config.axis_x_max,
  3029. y: config.axis_y_max,
  3030. y2: config.axis_y2_max
  3031. };
  3032. }
  3033. };
  3034. c3_chart_fn.axis.min = function (min) {
  3035. var $$ = this.internal,
  3036. config = $$.config;
  3037. if (arguments.length) {
  3038. if ((typeof min === 'undefined' ? 'undefined' : _typeof(min)) === 'object') {
  3039. if (isValue(min.x)) {
  3040. config.axis_x_min = min.x;
  3041. }
  3042. if (isValue(min.y)) {
  3043. config.axis_y_min = min.y;
  3044. }
  3045. if (isValue(min.y2)) {
  3046. config.axis_y2_min = min.y2;
  3047. }
  3048. } else {
  3049. config.axis_y_min = config.axis_y2_min = min;
  3050. }
  3051. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3052. } else {
  3053. return {
  3054. x: config.axis_x_min,
  3055. y: config.axis_y_min,
  3056. y2: config.axis_y2_min
  3057. };
  3058. }
  3059. };
  3060. c3_chart_fn.axis.range = function (range) {
  3061. if (arguments.length) {
  3062. if (isDefined(range.max)) {
  3063. this.axis.max(range.max);
  3064. }
  3065. if (isDefined(range.min)) {
  3066. this.axis.min(range.min);
  3067. }
  3068. } else {
  3069. return {
  3070. max: this.axis.max(),
  3071. min: this.axis.min()
  3072. };
  3073. }
  3074. };
  3075. c3_chart_fn.category = function (i, category) {
  3076. var $$ = this.internal,
  3077. config = $$.config;
  3078. if (arguments.length > 1) {
  3079. config.axis_x_categories[i] = category;
  3080. $$.redraw();
  3081. }
  3082. return config.axis_x_categories[i];
  3083. };
  3084. c3_chart_fn.categories = function (categories) {
  3085. var $$ = this.internal,
  3086. config = $$.config;
  3087. if (!arguments.length) {
  3088. return config.axis_x_categories;
  3089. }
  3090. config.axis_x_categories = categories;
  3091. $$.redraw();
  3092. return config.axis_x_categories;
  3093. };
  3094. c3_chart_fn.resize = function (size) {
  3095. var $$ = this.internal,
  3096. config = $$.config;
  3097. config.size_width = size ? size.width : null;
  3098. config.size_height = size ? size.height : null;
  3099. this.flush();
  3100. };
  3101. c3_chart_fn.flush = function () {
  3102. var $$ = this.internal;
  3103. $$.updateAndRedraw({ withLegend: true, withTransition: false, withTransitionForTransform: false });
  3104. };
  3105. c3_chart_fn.destroy = function () {
  3106. var $$ = this.internal;
  3107. window.clearInterval($$.intervalForObserveInserted);
  3108. if ($$.resizeTimeout !== undefined) {
  3109. window.clearTimeout($$.resizeTimeout);
  3110. }
  3111. if (window.detachEvent) {
  3112. window.detachEvent('onresize', $$.resizeFunction);
  3113. } else if (window.removeEventListener) {
  3114. window.removeEventListener('resize', $$.resizeFunction);
  3115. } else {
  3116. var wrapper = window.onresize;
  3117. // check if no one else removed our wrapper and remove our resizeFunction from it
  3118. if (wrapper && wrapper.add && wrapper.remove) {
  3119. wrapper.remove($$.resizeFunction);
  3120. }
  3121. }
  3122. $$.selectChart.classed('c3', false).html("");
  3123. // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.
  3124. Object.keys($$).forEach(function (key) {
  3125. $$[key] = null;
  3126. });
  3127. return null;
  3128. };
  3129. // TODO: fix
  3130. c3_chart_fn.color = function (id) {
  3131. var $$ = this.internal;
  3132. return $$.color(id); // more patterns
  3133. };
  3134. c3_chart_fn.data = function (targetIds) {
  3135. var targets = this.internal.data.targets;
  3136. return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) {
  3137. return [].concat(targetIds).indexOf(t.id) >= 0;
  3138. });
  3139. };
  3140. c3_chart_fn.data.shown = function (targetIds) {
  3141. return this.internal.filterTargetsToShow(this.data(targetIds));
  3142. };
  3143. c3_chart_fn.data.values = function (targetId) {
  3144. var targets,
  3145. values = null;
  3146. if (targetId) {
  3147. targets = this.data(targetId);
  3148. values = targets[0] ? targets[0].values.map(function (d) {
  3149. return d.value;
  3150. }) : null;
  3151. }
  3152. return values;
  3153. };
  3154. c3_chart_fn.data.names = function (names) {
  3155. this.internal.clearLegendItemTextBoxCache();
  3156. return this.internal.updateDataAttributes('names', names);
  3157. };
  3158. c3_chart_fn.data.colors = function (colors) {
  3159. return this.internal.updateDataAttributes('colors', colors);
  3160. };
  3161. c3_chart_fn.data.axes = function (axes) {
  3162. return this.internal.updateDataAttributes('axes', axes);
  3163. };
  3164. c3_chart_fn.flow = function (args) {
  3165. var $$ = this.internal,
  3166. targets,
  3167. data,
  3168. notfoundIds = [],
  3169. orgDataCount = $$.getMaxDataCount(),
  3170. dataCount,
  3171. domain,
  3172. baseTarget,
  3173. baseValue,
  3174. length = 0,
  3175. tail = 0,
  3176. diff,
  3177. to;
  3178. if (args.json) {
  3179. data = $$.convertJsonToData(args.json, args.keys);
  3180. } else if (args.rows) {
  3181. data = $$.convertRowsToData(args.rows);
  3182. } else if (args.columns) {
  3183. data = $$.convertColumnsToData(args.columns);
  3184. } else {
  3185. return;
  3186. }
  3187. targets = $$.convertDataToTargets(data, true);
  3188. // Update/Add data
  3189. $$.data.targets.forEach(function (t) {
  3190. var found = false,
  3191. i,
  3192. j;
  3193. for (i = 0; i < targets.length; i++) {
  3194. if (t.id === targets[i].id) {
  3195. found = true;
  3196. if (t.values[t.values.length - 1]) {
  3197. tail = t.values[t.values.length - 1].index + 1;
  3198. }
  3199. length = targets[i].values.length;
  3200. for (j = 0; j < length; j++) {
  3201. targets[i].values[j].index = tail + j;
  3202. if (!$$.isTimeSeries()) {
  3203. targets[i].values[j].x = tail + j;
  3204. }
  3205. }
  3206. t.values = t.values.concat(targets[i].values);
  3207. targets.splice(i, 1);
  3208. break;
  3209. }
  3210. }
  3211. if (!found) {
  3212. notfoundIds.push(t.id);
  3213. }
  3214. });
  3215. // Append null for not found targets
  3216. $$.data.targets.forEach(function (t) {
  3217. var i, j;
  3218. for (i = 0; i < notfoundIds.length; i++) {
  3219. if (t.id === notfoundIds[i]) {
  3220. tail = t.values[t.values.length - 1].index + 1;
  3221. for (j = 0; j < length; j++) {
  3222. t.values.push({
  3223. id: t.id,
  3224. index: tail + j,
  3225. x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
  3226. value: null
  3227. });
  3228. }
  3229. }
  3230. }
  3231. });
  3232. // Generate null values for new target
  3233. if ($$.data.targets.length) {
  3234. targets.forEach(function (t) {
  3235. var i,
  3236. missing = [];
  3237. for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
  3238. missing.push({
  3239. id: t.id,
  3240. index: i,
  3241. x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
  3242. value: null
  3243. });
  3244. }
  3245. t.values.forEach(function (v) {
  3246. v.index += tail;
  3247. if (!$$.isTimeSeries()) {
  3248. v.x += tail;
  3249. }
  3250. });
  3251. t.values = missing.concat(t.values);
  3252. });
  3253. }
  3254. $$.data.targets = $$.data.targets.concat(targets); // add remained
  3255. // check data count because behavior needs to change when it's only one
  3256. dataCount = $$.getMaxDataCount();
  3257. baseTarget = $$.data.targets[0];
  3258. baseValue = baseTarget.values[0];
  3259. // Update length to flow if needed
  3260. if (isDefined(args.to)) {
  3261. length = 0;
  3262. to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
  3263. baseTarget.values.forEach(function (v) {
  3264. if (v.x < to) {
  3265. length++;
  3266. }
  3267. });
  3268. } else if (isDefined(args.length)) {
  3269. length = args.length;
  3270. }
  3271. // If only one data, update the domain to flow from left edge of the chart
  3272. if (!orgDataCount) {
  3273. if ($$.isTimeSeries()) {
  3274. if (baseTarget.values.length > 1) {
  3275. diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
  3276. } else {
  3277. diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
  3278. }
  3279. } else {
  3280. diff = 1;
  3281. }
  3282. domain = [baseValue.x - diff, baseValue.x];
  3283. $$.updateXDomain(null, true, true, false, domain);
  3284. } else if (orgDataCount === 1) {
  3285. if ($$.isTimeSeries()) {
  3286. diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
  3287. domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
  3288. $$.updateXDomain(null, true, true, false, domain);
  3289. }
  3290. }
  3291. // Set targets
  3292. $$.updateTargets($$.data.targets);
  3293. // Redraw with new targets
  3294. $$.redraw({
  3295. flow: {
  3296. index: baseValue.index,
  3297. length: length,
  3298. duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
  3299. done: args.done,
  3300. orgDataCount: orgDataCount
  3301. },
  3302. withLegend: true,
  3303. withTransition: orgDataCount > 1,
  3304. withTrimXDomain: false,
  3305. withUpdateXAxis: true
  3306. });
  3307. };
  3308. c3_chart_internal_fn.generateFlow = function (args) {
  3309. var $$ = this,
  3310. config = $$.config,
  3311. d3 = $$.d3;
  3312. return function () {
  3313. var targets = args.targets,
  3314. flow = args.flow,
  3315. drawBar = args.drawBar,
  3316. drawLine = args.drawLine,
  3317. drawArea = args.drawArea,
  3318. cx = args.cx,
  3319. cy = args.cy,
  3320. xv = args.xv,
  3321. xForText = args.xForText,
  3322. yForText = args.yForText,
  3323. duration = args.duration;
  3324. var translateX,
  3325. scaleX = 1,
  3326. transform,
  3327. flowIndex = flow.index,
  3328. flowLength = flow.length,
  3329. flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),
  3330. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength),
  3331. orgDomain = $$.x.domain(),
  3332. domain,
  3333. durationForFlow = flow.duration || duration,
  3334. done = flow.done || function () {},
  3335. wait = $$.generateWait();
  3336. var xgrid = $$.xgrid || d3.selectAll([]),
  3337. xgridLines = $$.xgridLines || d3.selectAll([]),
  3338. mainRegion = $$.mainRegion || d3.selectAll([]),
  3339. mainText = $$.mainText || d3.selectAll([]),
  3340. mainBar = $$.mainBar || d3.selectAll([]),
  3341. mainLine = $$.mainLine || d3.selectAll([]),
  3342. mainArea = $$.mainArea || d3.selectAll([]),
  3343. mainCircle = $$.mainCircle || d3.selectAll([]);
  3344. // set flag
  3345. $$.flowing = true;
  3346. // remove head data after rendered
  3347. $$.data.targets.forEach(function (d) {
  3348. d.values.splice(0, flowLength);
  3349. });
  3350. // update x domain to generate axis elements for flow
  3351. domain = $$.updateXDomain(targets, true, true);
  3352. // update elements related to x scale
  3353. if ($$.updateXGrid) {
  3354. $$.updateXGrid(true);
  3355. }
  3356. // generate transform to flow
  3357. if (!flow.orgDataCount) {
  3358. // if empty
  3359. if ($$.data.targets[0].values.length !== 1) {
  3360. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3361. } else {
  3362. if ($$.isTimeSeries()) {
  3363. flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);
  3364. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);
  3365. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3366. } else {
  3367. translateX = diffDomain(domain) / 2;
  3368. }
  3369. }
  3370. } else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {
  3371. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3372. } else {
  3373. if ($$.isTimeSeries()) {
  3374. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3375. } else {
  3376. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3377. }
  3378. }
  3379. scaleX = diffDomain(orgDomain) / diffDomain(domain);
  3380. transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';
  3381. $$.hideXGridFocus();
  3382. d3.transition().ease('linear').duration(durationForFlow).each(function () {
  3383. wait.add($$.axes.x.transition().call($$.xAxis));
  3384. wait.add(mainBar.transition().attr('transform', transform));
  3385. wait.add(mainLine.transition().attr('transform', transform));
  3386. wait.add(mainArea.transition().attr('transform', transform));
  3387. wait.add(mainCircle.transition().attr('transform', transform));
  3388. wait.add(mainText.transition().attr('transform', transform));
  3389. wait.add(mainRegion.filter($$.isRegionOnX).transition().attr('transform', transform));
  3390. wait.add(xgrid.transition().attr('transform', transform));
  3391. wait.add(xgridLines.transition().attr('transform', transform));
  3392. }).call(wait, function () {
  3393. var i,
  3394. shapes = [],
  3395. texts = [],
  3396. eventRects = [];
  3397. // remove flowed elements
  3398. if (flowLength) {
  3399. for (i = 0; i < flowLength; i++) {
  3400. shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));
  3401. texts.push('.' + CLASS.text + '-' + (flowIndex + i));
  3402. eventRects.push('.' + CLASS.eventRect + '-' + (flowIndex + i));
  3403. }
  3404. $$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove();
  3405. $$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove();
  3406. $$.svg.selectAll('.' + CLASS.eventRects).selectAll(eventRects).remove();
  3407. $$.svg.select('.' + CLASS.xgrid).remove();
  3408. }
  3409. // draw again for removing flowed elements and reverting attr
  3410. xgrid.attr('transform', null).attr($$.xgridAttr);
  3411. xgridLines.attr('transform', null);
  3412. xgridLines.select('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv);
  3413. xgridLines.select('text').attr("x", config.axis_rotated ? $$.width : 0).attr("y", xv);
  3414. mainBar.attr('transform', null).attr("d", drawBar);
  3415. mainLine.attr('transform', null).attr("d", drawLine);
  3416. mainArea.attr('transform', null).attr("d", drawArea);
  3417. mainCircle.attr('transform', null).attr("cx", cx).attr("cy", cy);
  3418. mainText.attr('transform', null).attr('x', xForText).attr('y', yForText).style('fill-opacity', $$.opacityForText.bind($$));
  3419. mainRegion.attr('transform', null);
  3420. mainRegion.select('rect').filter($$.isRegionOnX).attr("x", $$.regionX.bind($$)).attr("width", $$.regionWidth.bind($$));
  3421. if (config.interaction_enabled) {
  3422. $$.redrawEventRect();
  3423. }
  3424. // callback for end of flow
  3425. done();
  3426. $$.flowing = false;
  3427. });
  3428. };
  3429. };
  3430. c3_chart_fn.focus = function (targetIds) {
  3431. var $$ = this.internal,
  3432. candidates;
  3433. targetIds = $$.mapToTargetIds(targetIds);
  3434. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), this.revert();
  3435. this.defocus();
  3436. candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);
  3437. if ($$.hasArcType()) {
  3438. $$.expandArc(targetIds);
  3439. }
  3440. $$.toggleFocusLegend(targetIds, true);
  3441. $$.focusedTargetIds = targetIds;
  3442. $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) {
  3443. return targetIds.indexOf(id) < 0;
  3444. });
  3445. };
  3446. c3_chart_fn.defocus = function (targetIds) {
  3447. var $$ = this.internal,
  3448. candidates;
  3449. targetIds = $$.mapToTargetIds(targetIds);
  3450. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);
  3451. if ($$.hasArcType()) {
  3452. $$.unexpandArc(targetIds);
  3453. }
  3454. $$.toggleFocusLegend(targetIds, false);
  3455. $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) {
  3456. return targetIds.indexOf(id) < 0;
  3457. });
  3458. $$.defocusedTargetIds = targetIds;
  3459. };
  3460. c3_chart_fn.revert = function (targetIds) {
  3461. var $$ = this.internal,
  3462. candidates;
  3463. targetIds = $$.mapToTargetIds(targetIds);
  3464. candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets
  3465. candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);
  3466. if ($$.hasArcType()) {
  3467. $$.unexpandArc(targetIds);
  3468. }
  3469. if ($$.config.legend_show) {
  3470. $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));
  3471. $$.legend.selectAll($$.selectorLegends(targetIds)).filter(function () {
  3472. return $$.d3.select(this).classed(CLASS.legendItemFocused);
  3473. }).classed(CLASS.legendItemFocused, false);
  3474. }
  3475. $$.focusedTargetIds = [];
  3476. $$.defocusedTargetIds = [];
  3477. };
  3478. c3_chart_fn.xgrids = function (grids) {
  3479. var $$ = this.internal,
  3480. config = $$.config;
  3481. if (!grids) {
  3482. return config.grid_x_lines;
  3483. }
  3484. config.grid_x_lines = grids;
  3485. $$.redrawWithoutRescale();
  3486. return config.grid_x_lines;
  3487. };
  3488. c3_chart_fn.xgrids.add = function (grids) {
  3489. var $$ = this.internal;
  3490. return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []));
  3491. };
  3492. c3_chart_fn.xgrids.remove = function (params) {
  3493. // TODO: multiple
  3494. var $$ = this.internal;
  3495. $$.removeGridLines(params, true);
  3496. };
  3497. c3_chart_fn.ygrids = function (grids) {
  3498. var $$ = this.internal,
  3499. config = $$.config;
  3500. if (!grids) {
  3501. return config.grid_y_lines;
  3502. }
  3503. config.grid_y_lines = grids;
  3504. $$.redrawWithoutRescale();
  3505. return config.grid_y_lines;
  3506. };
  3507. c3_chart_fn.ygrids.add = function (grids) {
  3508. var $$ = this.internal;
  3509. return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []));
  3510. };
  3511. c3_chart_fn.ygrids.remove = function (params) {
  3512. // TODO: multiple
  3513. var $$ = this.internal;
  3514. $$.removeGridLines(params, false);
  3515. };
  3516. c3_chart_fn.groups = function (groups) {
  3517. var $$ = this.internal,
  3518. config = $$.config;
  3519. if (isUndefined(groups)) {
  3520. return config.data_groups;
  3521. }
  3522. config.data_groups = groups;
  3523. $$.redraw();
  3524. return config.data_groups;
  3525. };
  3526. c3_chart_fn.legend = function () {};
  3527. c3_chart_fn.legend.show = function (targetIds) {
  3528. var $$ = this.internal;
  3529. $$.showLegend($$.mapToTargetIds(targetIds));
  3530. $$.updateAndRedraw({ withLegend: true });
  3531. };
  3532. c3_chart_fn.legend.hide = function (targetIds) {
  3533. var $$ = this.internal;
  3534. $$.hideLegend($$.mapToTargetIds(targetIds));
  3535. $$.updateAndRedraw({ withLegend: true });
  3536. };
  3537. c3_chart_fn.load = function (args) {
  3538. var $$ = this.internal,
  3539. config = $$.config;
  3540. // update xs if specified
  3541. if (args.xs) {
  3542. $$.addXs(args.xs);
  3543. }
  3544. // update names if exists
  3545. if ('names' in args) {
  3546. c3_chart_fn.data.names.bind(this)(args.names);
  3547. }
  3548. // update classes if exists
  3549. if ('classes' in args) {
  3550. Object.keys(args.classes).forEach(function (id) {
  3551. config.data_classes[id] = args.classes[id];
  3552. });
  3553. }
  3554. // update categories if exists
  3555. if ('categories' in args && $$.isCategorized()) {
  3556. config.axis_x_categories = args.categories;
  3557. }
  3558. // update axes if exists
  3559. if ('axes' in args) {
  3560. Object.keys(args.axes).forEach(function (id) {
  3561. config.data_axes[id] = args.axes[id];
  3562. });
  3563. }
  3564. // update colors if exists
  3565. if ('colors' in args) {
  3566. Object.keys(args.colors).forEach(function (id) {
  3567. config.data_colors[id] = args.colors[id];
  3568. });
  3569. }
  3570. // use cache if exists
  3571. if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {
  3572. $$.load($$.getCaches(args.cacheIds), args.done);
  3573. return;
  3574. }
  3575. // unload if needed
  3576. if ('unload' in args) {
  3577. // TODO: do not unload if target will load (included in url/rows/columns)
  3578. $$.unload($$.mapToTargetIds(typeof args.unload === 'boolean' && args.unload ? null : args.unload), function () {
  3579. $$.loadFromArgs(args);
  3580. });
  3581. } else {
  3582. $$.loadFromArgs(args);
  3583. }
  3584. };
  3585. c3_chart_fn.unload = function (args) {
  3586. var $$ = this.internal;
  3587. args = args || {};
  3588. if (args instanceof Array) {
  3589. args = { ids: args };
  3590. } else if (typeof args === 'string') {
  3591. args = { ids: [args] };
  3592. }
  3593. $$.unload($$.mapToTargetIds(args.ids), function () {
  3594. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  3595. if (args.done) {
  3596. args.done();
  3597. }
  3598. });
  3599. };
  3600. c3_chart_fn.regions = function (regions) {
  3601. var $$ = this.internal,
  3602. config = $$.config;
  3603. if (!regions) {
  3604. return config.regions;
  3605. }
  3606. config.regions = regions;
  3607. $$.redrawWithoutRescale();
  3608. return config.regions;
  3609. };
  3610. c3_chart_fn.regions.add = function (regions) {
  3611. var $$ = this.internal,
  3612. config = $$.config;
  3613. if (!regions) {
  3614. return config.regions;
  3615. }
  3616. config.regions = config.regions.concat(regions);
  3617. $$.redrawWithoutRescale();
  3618. return config.regions;
  3619. };
  3620. c3_chart_fn.regions.remove = function (options) {
  3621. var $$ = this.internal,
  3622. config = $$.config,
  3623. duration,
  3624. classes,
  3625. regions;
  3626. options = options || {};
  3627. duration = $$.getOption(options, "duration", config.transition_duration);
  3628. classes = $$.getOption(options, "classes", [CLASS.region]);
  3629. regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) {
  3630. return '.' + c;
  3631. }));
  3632. (duration ? regions.transition().duration(duration) : regions).style('opacity', 0).remove();
  3633. config.regions = config.regions.filter(function (region) {
  3634. var found = false;
  3635. if (!region['class']) {
  3636. return true;
  3637. }
  3638. region['class'].split(' ').forEach(function (c) {
  3639. if (classes.indexOf(c) >= 0) {
  3640. found = true;
  3641. }
  3642. });
  3643. return !found;
  3644. });
  3645. return config.regions;
  3646. };
  3647. c3_chart_fn.selected = function (targetId) {
  3648. var $$ = this.internal,
  3649. d3 = $$.d3;
  3650. return d3.merge($$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape).filter(function () {
  3651. return d3.select(this).classed(CLASS.SELECTED);
  3652. }).map(function (d) {
  3653. return d.map(function (d) {
  3654. var data = d.__data__;return data.data ? data.data : data;
  3655. });
  3656. }));
  3657. };
  3658. c3_chart_fn.select = function (ids, indices, resetOther) {
  3659. var $$ = this.internal,
  3660. d3 = $$.d3,
  3661. config = $$.config;
  3662. if (!config.data_selection_enabled) {
  3663. return;
  3664. }
  3665. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  3666. var shape = d3.select(this),
  3667. id = d.data ? d.data.id : d.id,
  3668. toggle = $$.getToggle(this, d).bind($$),
  3669. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  3670. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  3671. isSelected = shape.classed(CLASS.SELECTED);
  3672. // line/area selection not supported yet
  3673. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  3674. return;
  3675. }
  3676. if (isTargetId && isTargetIndex) {
  3677. if (config.data_selection_isselectable(d) && !isSelected) {
  3678. toggle(true, shape.classed(CLASS.SELECTED, true), d, i);
  3679. }
  3680. } else if (isDefined(resetOther) && resetOther) {
  3681. if (isSelected) {
  3682. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  3683. }
  3684. }
  3685. });
  3686. };
  3687. c3_chart_fn.unselect = function (ids, indices) {
  3688. var $$ = this.internal,
  3689. d3 = $$.d3,
  3690. config = $$.config;
  3691. if (!config.data_selection_enabled) {
  3692. return;
  3693. }
  3694. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  3695. var shape = d3.select(this),
  3696. id = d.data ? d.data.id : d.id,
  3697. toggle = $$.getToggle(this, d).bind($$),
  3698. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  3699. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  3700. isSelected = shape.classed(CLASS.SELECTED);
  3701. // line/area selection not supported yet
  3702. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  3703. return;
  3704. }
  3705. if (isTargetId && isTargetIndex) {
  3706. if (config.data_selection_isselectable(d)) {
  3707. if (isSelected) {
  3708. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  3709. }
  3710. }
  3711. }
  3712. });
  3713. };
  3714. c3_chart_fn.show = function (targetIds, options) {
  3715. var $$ = this.internal,
  3716. targets;
  3717. targetIds = $$.mapToTargetIds(targetIds);
  3718. options = options || {};
  3719. $$.removeHiddenTargetIds(targetIds);
  3720. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  3721. targets.transition().style('opacity', 1, 'important').call($$.endall, function () {
  3722. targets.style('opacity', null).style('opacity', 1);
  3723. });
  3724. if (options.withLegend) {
  3725. $$.showLegend(targetIds);
  3726. }
  3727. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  3728. };
  3729. c3_chart_fn.hide = function (targetIds, options) {
  3730. var $$ = this.internal,
  3731. targets;
  3732. targetIds = $$.mapToTargetIds(targetIds);
  3733. options = options || {};
  3734. $$.addHiddenTargetIds(targetIds);
  3735. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  3736. targets.transition().style('opacity', 0, 'important').call($$.endall, function () {
  3737. targets.style('opacity', null).style('opacity', 0);
  3738. });
  3739. if (options.withLegend) {
  3740. $$.hideLegend(targetIds);
  3741. }
  3742. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  3743. };
  3744. c3_chart_fn.toggle = function (targetIds, options) {
  3745. var that = this,
  3746. $$ = this.internal;
  3747. $$.mapToTargetIds(targetIds).forEach(function (targetId) {
  3748. $$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options);
  3749. });
  3750. };
  3751. c3_chart_fn.tooltip = function () {};
  3752. c3_chart_fn.tooltip.show = function (args) {
  3753. var $$ = this.internal,
  3754. index,
  3755. mouse;
  3756. // determine mouse position on the chart
  3757. if (args.mouse) {
  3758. mouse = args.mouse;
  3759. }
  3760. // determine focus data
  3761. if (args.data) {
  3762. if ($$.isMultipleX()) {
  3763. // if multiple xs, target point will be determined by mouse
  3764. mouse = [$$.x(args.data.x), $$.getYScale(args.data.id)(args.data.value)];
  3765. index = null;
  3766. } else {
  3767. // TODO: when tooltip_grouped = false
  3768. index = isValue(args.data.index) ? args.data.index : $$.getIndexByX(args.data.x);
  3769. }
  3770. } else if (typeof args.x !== 'undefined') {
  3771. index = $$.getIndexByX(args.x);
  3772. } else if (typeof args.index !== 'undefined') {
  3773. index = args.index;
  3774. }
  3775. // emulate mouse events to show
  3776. $$.dispatchEvent('mouseover', index, mouse);
  3777. $$.dispatchEvent('mousemove', index, mouse);
  3778. $$.config.tooltip_onshow.call($$, args.data);
  3779. };
  3780. c3_chart_fn.tooltip.hide = function () {
  3781. // TODO: get target data by checking the state of focus
  3782. this.internal.dispatchEvent('mouseout', 0);
  3783. this.internal.config.tooltip_onhide.call(this);
  3784. };
  3785. c3_chart_fn.transform = function (type, targetIds) {
  3786. var $$ = this.internal,
  3787. options = ['pie', 'donut'].indexOf(type) >= 0 ? { withTransform: true } : null;
  3788. $$.transformTo(targetIds, type, options);
  3789. };
  3790. c3_chart_internal_fn.transformTo = function (targetIds, type, optionsForRedraw) {
  3791. var $$ = this,
  3792. withTransitionForAxis = !$$.hasArcType(),
  3793. options = optionsForRedraw || { withTransitionForAxis: withTransitionForAxis };
  3794. options.withTransitionForTransform = false;
  3795. $$.transiting = false;
  3796. $$.setTargetType(targetIds, type);
  3797. $$.updateTargets($$.data.targets); // this is needed when transforming to arc
  3798. $$.updateAndRedraw(options);
  3799. };
  3800. c3_chart_fn.x = function (x) {
  3801. var $$ = this.internal;
  3802. if (arguments.length) {
  3803. $$.updateTargetX($$.data.targets, x);
  3804. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3805. }
  3806. return $$.data.xs;
  3807. };
  3808. c3_chart_fn.xs = function (xs) {
  3809. var $$ = this.internal;
  3810. if (arguments.length) {
  3811. $$.updateTargetXs($$.data.targets, xs);
  3812. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true });
  3813. }
  3814. return $$.data.xs;
  3815. };
  3816. c3_chart_fn.zoom = function (domain) {
  3817. var $$ = this.internal;
  3818. if (domain) {
  3819. if ($$.isTimeSeries()) {
  3820. domain = domain.map(function (x) {
  3821. return $$.parseDate(x);
  3822. });
  3823. }
  3824. $$.brush.extent(domain);
  3825. $$.redraw({ withUpdateXDomain: true, withY: $$.config.zoom_rescale });
  3826. $$.config.zoom_onzoom.call(this, $$.x.orgDomain());
  3827. }
  3828. return $$.brush.extent();
  3829. };
  3830. c3_chart_fn.zoom.enable = function (enabled) {
  3831. var $$ = this.internal;
  3832. $$.config.zoom_enabled = enabled;
  3833. $$.updateAndRedraw();
  3834. };
  3835. c3_chart_fn.unzoom = function () {
  3836. var $$ = this.internal;
  3837. $$.brush.clear().update();
  3838. $$.redraw({ withUpdateXDomain: true });
  3839. };
  3840. c3_chart_fn.zoom.max = function (max) {
  3841. var $$ = this.internal,
  3842. config = $$.config,
  3843. d3 = $$.d3;
  3844. if (max === 0 || max) {
  3845. config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);
  3846. } else {
  3847. return config.zoom_x_max;
  3848. }
  3849. };
  3850. c3_chart_fn.zoom.min = function (min) {
  3851. var $$ = this.internal,
  3852. config = $$.config,
  3853. d3 = $$.d3;
  3854. if (min === 0 || min) {
  3855. config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);
  3856. } else {
  3857. return config.zoom_x_min;
  3858. }
  3859. };
  3860. c3_chart_fn.zoom.range = function (range) {
  3861. if (arguments.length) {
  3862. if (isDefined(range.max)) {
  3863. this.domain.max(range.max);
  3864. }
  3865. if (isDefined(range.min)) {
  3866. this.domain.min(range.min);
  3867. }
  3868. } else {
  3869. return {
  3870. max: this.domain.max(),
  3871. min: this.domain.min()
  3872. };
  3873. }
  3874. };
  3875. c3_chart_internal_fn.initPie = function () {
  3876. var $$ = this,
  3877. d3 = $$.d3,
  3878. config = $$.config;
  3879. $$.pie = d3.layout.pie().value(function (d) {
  3880. return d.values.reduce(function (a, b) {
  3881. return a + b.value;
  3882. }, 0);
  3883. });
  3884. if (!config.data_order) {
  3885. $$.pie.sort(null);
  3886. }
  3887. };
  3888. c3_chart_internal_fn.updateRadius = function () {
  3889. var $$ = this,
  3890. config = $$.config,
  3891. w = config.gauge_width || config.donut_width;
  3892. $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2;
  3893. $$.radius = $$.radiusExpanded * 0.95;
  3894. $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;
  3895. $$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0;
  3896. };
  3897. c3_chart_internal_fn.updateArc = function () {
  3898. var $$ = this;
  3899. $$.svgArc = $$.getSvgArc();
  3900. $$.svgArcExpanded = $$.getSvgArcExpanded();
  3901. $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);
  3902. };
  3903. c3_chart_internal_fn.updateAngle = function (d) {
  3904. var $$ = this,
  3905. config = $$.config,
  3906. found = false,
  3907. index = 0,
  3908. gMin,
  3909. gMax,
  3910. gTic,
  3911. gValue;
  3912. if (!config) {
  3913. return null;
  3914. }
  3915. $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) {
  3916. if (!found && t.data.id === d.data.id) {
  3917. found = true;
  3918. d = t;
  3919. d.index = index;
  3920. }
  3921. index++;
  3922. });
  3923. if (isNaN(d.startAngle)) {
  3924. d.startAngle = 0;
  3925. }
  3926. if (isNaN(d.endAngle)) {
  3927. d.endAngle = d.startAngle;
  3928. }
  3929. if ($$.isGaugeType(d.data)) {
  3930. gMin = config.gauge_min;
  3931. gMax = config.gauge_max;
  3932. gTic = Math.PI * (config.gauge_fullCircle ? 2 : 1) / (gMax - gMin);
  3933. gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;
  3934. d.startAngle = config.gauge_startingAngle;
  3935. d.endAngle = d.startAngle + gTic * gValue;
  3936. }
  3937. return found ? d : null;
  3938. };
  3939. c3_chart_internal_fn.getSvgArc = function () {
  3940. var $$ = this,
  3941. arc = $$.d3.svg.arc().outerRadius($$.radius).innerRadius($$.innerRadius),
  3942. newArc = function newArc(d, withoutUpdate) {
  3943. var updated;
  3944. if (withoutUpdate) {
  3945. return arc(d);
  3946. } // for interpolate
  3947. updated = $$.updateAngle(d);
  3948. return updated ? arc(updated) : "M 0 0";
  3949. };
  3950. // TODO: extends all function
  3951. newArc.centroid = arc.centroid;
  3952. return newArc;
  3953. };
  3954. c3_chart_internal_fn.getSvgArcExpanded = function (rate) {
  3955. var $$ = this,
  3956. arc = $$.d3.svg.arc().outerRadius($$.radiusExpanded * (rate ? rate : 1)).innerRadius($$.innerRadius);
  3957. return function (d) {
  3958. var updated = $$.updateAngle(d);
  3959. return updated ? arc(updated) : "M 0 0";
  3960. };
  3961. };
  3962. c3_chart_internal_fn.getArc = function (d, withoutUpdate, force) {
  3963. return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0";
  3964. };
  3965. c3_chart_internal_fn.transformForArcLabel = function (d) {
  3966. var $$ = this,
  3967. config = $$.config,
  3968. updated = $$.updateAngle(d),
  3969. c,
  3970. x,
  3971. y,
  3972. h,
  3973. ratio,
  3974. translate = "";
  3975. if (updated && !$$.hasType('gauge')) {
  3976. c = this.svgArc.centroid(updated);
  3977. x = isNaN(c[0]) ? 0 : c[0];
  3978. y = isNaN(c[1]) ? 0 : c[1];
  3979. h = Math.sqrt(x * x + y * y);
  3980. if ($$.hasType('donut') && config.donut_label_ratio) {
  3981. ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio;
  3982. } else if ($$.hasType('pie') && config.pie_label_ratio) {
  3983. ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio;
  3984. } else {
  3985. ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0;
  3986. }
  3987. translate = "translate(" + x * ratio + ',' + y * ratio + ")";
  3988. }
  3989. return translate;
  3990. };
  3991. c3_chart_internal_fn.getArcRatio = function (d) {
  3992. var $$ = this,
  3993. config = $$.config,
  3994. whole = Math.PI * ($$.hasType('gauge') && !config.gauge_fullCircle ? 1 : 2);
  3995. return d ? (d.endAngle - d.startAngle) / whole : null;
  3996. };
  3997. c3_chart_internal_fn.convertToArcData = function (d) {
  3998. return this.addName({
  3999. id: d.data.id,
  4000. value: d.value,
  4001. ratio: this.getArcRatio(d),
  4002. index: d.index
  4003. });
  4004. };
  4005. c3_chart_internal_fn.textForArcLabel = function (d) {
  4006. var $$ = this,
  4007. updated,
  4008. value,
  4009. ratio,
  4010. id,
  4011. format;
  4012. if (!$$.shouldShowArcLabel()) {
  4013. return "";
  4014. }
  4015. updated = $$.updateAngle(d);
  4016. value = updated ? updated.value : null;
  4017. ratio = $$.getArcRatio(updated);
  4018. id = d.data.id;
  4019. if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {
  4020. return "";
  4021. }
  4022. format = $$.getArcLabelFormat();
  4023. return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio);
  4024. };
  4025. c3_chart_internal_fn.textForGaugeMinMax = function (value, isMax) {
  4026. var $$ = this,
  4027. format = $$.getGaugeLabelExtents();
  4028. return format ? format(value, isMax) : value;
  4029. };
  4030. c3_chart_internal_fn.expandArc = function (targetIds) {
  4031. var $$ = this,
  4032. interval;
  4033. // MEMO: avoid to cancel transition
  4034. if ($$.transiting) {
  4035. interval = window.setInterval(function () {
  4036. if (!$$.transiting) {
  4037. window.clearInterval(interval);
  4038. if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {
  4039. $$.expandArc(targetIds);
  4040. }
  4041. }
  4042. }, 10);
  4043. return;
  4044. }
  4045. targetIds = $$.mapToTargetIds(targetIds);
  4046. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).each(function (d) {
  4047. if (!$$.shouldExpand(d.data.id)) {
  4048. return;
  4049. }
  4050. $$.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) {
  4051. if ($$.isDonutType(d.data)) {
  4052. // callback here
  4053. }
  4054. });
  4055. });
  4056. };
  4057. c3_chart_internal_fn.unexpandArc = function (targetIds) {
  4058. var $$ = this;
  4059. if ($$.transiting) {
  4060. return;
  4061. }
  4062. targetIds = $$.mapToTargetIds(targetIds);
  4063. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path').transition().duration(function (d) {
  4064. return $$.expandDuration(d.data.id);
  4065. }).attr("d", $$.svgArc);
  4066. $$.svg.selectAll('.' + CLASS.arc);
  4067. };
  4068. c3_chart_internal_fn.expandDuration = function (id) {
  4069. var $$ = this,
  4070. config = $$.config;
  4071. if ($$.isDonutType(id)) {
  4072. return config.donut_expand_duration;
  4073. } else if ($$.isGaugeType(id)) {
  4074. return config.gauge_expand_duration;
  4075. } else if ($$.isPieType(id)) {
  4076. return config.pie_expand_duration;
  4077. } else {
  4078. return 50;
  4079. }
  4080. };
  4081. c3_chart_internal_fn.shouldExpand = function (id) {
  4082. var $$ = this,
  4083. config = $$.config;
  4084. return $$.isDonutType(id) && config.donut_expand || $$.isGaugeType(id) && config.gauge_expand || $$.isPieType(id) && config.pie_expand;
  4085. };
  4086. c3_chart_internal_fn.shouldShowArcLabel = function () {
  4087. var $$ = this,
  4088. config = $$.config,
  4089. shouldShow = true;
  4090. if ($$.hasType('donut')) {
  4091. shouldShow = config.donut_label_show;
  4092. } else if ($$.hasType('pie')) {
  4093. shouldShow = config.pie_label_show;
  4094. }
  4095. // when gauge, always true
  4096. return shouldShow;
  4097. };
  4098. c3_chart_internal_fn.meetsArcLabelThreshold = function (ratio) {
  4099. var $$ = this,
  4100. config = $$.config,
  4101. threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold;
  4102. return ratio >= threshold;
  4103. };
  4104. c3_chart_internal_fn.getArcLabelFormat = function () {
  4105. var $$ = this,
  4106. config = $$.config,
  4107. format = config.pie_label_format;
  4108. if ($$.hasType('gauge')) {
  4109. format = config.gauge_label_format;
  4110. } else if ($$.hasType('donut')) {
  4111. format = config.donut_label_format;
  4112. }
  4113. return format;
  4114. };
  4115. c3_chart_internal_fn.getGaugeLabelExtents = function () {
  4116. var $$ = this,
  4117. config = $$.config;
  4118. return config.gauge_label_extents;
  4119. };
  4120. c3_chart_internal_fn.getArcTitle = function () {
  4121. var $$ = this;
  4122. return $$.hasType('donut') ? $$.config.donut_title : "";
  4123. };
  4124. c3_chart_internal_fn.updateTargetsForArc = function (targets) {
  4125. var $$ = this,
  4126. main = $$.main,
  4127. mainPieUpdate,
  4128. mainPieEnter,
  4129. classChartArc = $$.classChartArc.bind($$),
  4130. classArcs = $$.classArcs.bind($$),
  4131. classFocus = $$.classFocus.bind($$);
  4132. mainPieUpdate = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr("class", function (d) {
  4133. return classChartArc(d) + classFocus(d.data);
  4134. });
  4135. mainPieEnter = mainPieUpdate.enter().append("g").attr("class", classChartArc);
  4136. mainPieEnter.append('g').attr('class', classArcs);
  4137. mainPieEnter.append("text").attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em").style("opacity", 0).style("text-anchor", "middle").style("pointer-events", "none");
  4138. // MEMO: can not keep same color..., but not bad to update color in redraw
  4139. //mainPieUpdate.exit().remove();
  4140. };
  4141. c3_chart_internal_fn.initArc = function () {
  4142. var $$ = this;
  4143. $$.arcs = $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  4144. $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style("text-anchor", "middle").text($$.getArcTitle());
  4145. };
  4146. c3_chart_internal_fn.redrawArc = function (duration, durationForExit, withTransform) {
  4147. var $$ = this,
  4148. d3 = $$.d3,
  4149. config = $$.config,
  4150. main = $$.main,
  4151. mainArc;
  4152. mainArc = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc).data($$.arcData.bind($$));
  4153. mainArc.enter().append('path').attr("class", $$.classArc.bind($$)).style("fill", function (d) {
  4154. return $$.color(d.data);
  4155. }).style("cursor", function (d) {
  4156. return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null;
  4157. }).each(function (d) {
  4158. if ($$.isGaugeType(d.data)) {
  4159. d.startAngle = d.endAngle = config.gauge_startingAngle;
  4160. }
  4161. this._current = d;
  4162. });
  4163. mainArc.attr("transform", function (d) {
  4164. return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : "";
  4165. }).on('mouseover', config.interaction_enabled ? function (d) {
  4166. var updated, arcData;
  4167. if ($$.transiting) {
  4168. // skip while transiting
  4169. return;
  4170. }
  4171. updated = $$.updateAngle(d);
  4172. if (updated) {
  4173. arcData = $$.convertToArcData(updated);
  4174. // transitions
  4175. $$.expandArc(updated.data.id);
  4176. $$.api.focus(updated.data.id);
  4177. $$.toggleFocusLegend(updated.data.id, true);
  4178. $$.config.data_onmouseover(arcData, this);
  4179. }
  4180. } : null).on('mousemove', config.interaction_enabled ? function (d) {
  4181. var updated = $$.updateAngle(d),
  4182. arcData,
  4183. selectedData;
  4184. if (updated) {
  4185. arcData = $$.convertToArcData(updated), selectedData = [arcData];
  4186. $$.showTooltip(selectedData, this);
  4187. }
  4188. } : null).on('mouseout', config.interaction_enabled ? function (d) {
  4189. var updated, arcData;
  4190. if ($$.transiting) {
  4191. // skip while transiting
  4192. return;
  4193. }
  4194. updated = $$.updateAngle(d);
  4195. if (updated) {
  4196. arcData = $$.convertToArcData(updated);
  4197. // transitions
  4198. $$.unexpandArc(updated.data.id);
  4199. $$.api.revert();
  4200. $$.revertLegend();
  4201. $$.hideTooltip();
  4202. $$.config.data_onmouseout(arcData, this);
  4203. }
  4204. } : null).on('click', config.interaction_enabled ? function (d, i) {
  4205. var updated = $$.updateAngle(d),
  4206. arcData;
  4207. if (updated) {
  4208. arcData = $$.convertToArcData(updated);
  4209. if ($$.toggleShape) {
  4210. $$.toggleShape(this, arcData, i);
  4211. }
  4212. $$.config.data_onclick.call($$.api, arcData, this);
  4213. }
  4214. } : null).each(function () {
  4215. $$.transiting = true;
  4216. }).transition().duration(duration).attrTween("d", function (d) {
  4217. var updated = $$.updateAngle(d),
  4218. interpolate;
  4219. if (!updated) {
  4220. return function () {
  4221. return "M 0 0";
  4222. };
  4223. }
  4224. // if (this._current === d) {
  4225. // this._current = {
  4226. // startAngle: Math.PI*2,
  4227. // endAngle: Math.PI*2,
  4228. // };
  4229. // }
  4230. if (isNaN(this._current.startAngle)) {
  4231. this._current.startAngle = 0;
  4232. }
  4233. if (isNaN(this._current.endAngle)) {
  4234. this._current.endAngle = this._current.startAngle;
  4235. }
  4236. interpolate = d3.interpolate(this._current, updated);
  4237. this._current = interpolate(0);
  4238. return function (t) {
  4239. var interpolated = interpolate(t);
  4240. interpolated.data = d.data; // data.id will be updated by interporator
  4241. return $$.getArc(interpolated, true);
  4242. };
  4243. }).attr("transform", withTransform ? "scale(1)" : "").style("fill", function (d) {
  4244. return $$.levelColor ? $$.levelColor(d.data.values[0].value) : $$.color(d.data.id);
  4245. } // Where gauge reading color would receive customization.
  4246. ).call($$.endall, function () {
  4247. $$.transiting = false;
  4248. });
  4249. mainArc.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  4250. main.selectAll('.' + CLASS.chartArc).select('text').style("opacity", 0).attr('class', function (d) {
  4251. return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '';
  4252. }).text($$.textForArcLabel.bind($$)).attr("transform", $$.transformForArcLabel.bind($$)).style('font-size', function (d) {
  4253. return $$.isGaugeType(d.data) ? Math.round($$.radius / 5) + 'px' : '';
  4254. }).transition().duration(duration).style("opacity", function (d) {
  4255. return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0;
  4256. });
  4257. main.select('.' + CLASS.chartArcsTitle).style("opacity", $$.hasType('donut') || $$.hasType('gauge') ? 1 : 0);
  4258. if ($$.hasType('gauge')) {
  4259. $$.arcs.select('.' + CLASS.chartArcsBackground).attr("d", function () {
  4260. var d = {
  4261. data: [{ value: config.gauge_max }],
  4262. startAngle: config.gauge_startingAngle,
  4263. endAngle: -1 * config.gauge_startingAngle
  4264. };
  4265. return $$.getArc(d, true, true);
  4266. });
  4267. $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr("dy", ".75em").text(config.gauge_label_show ? config.gauge_units : '');
  4268. $$.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) : '');
  4269. $$.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) : '');
  4270. }
  4271. };
  4272. c3_chart_internal_fn.initGauge = function () {
  4273. var arcs = this.arcs;
  4274. if (this.hasType('gauge')) {
  4275. arcs.append('path').attr("class", CLASS.chartArcsBackground);
  4276. arcs.append("text").attr("class", CLASS.chartArcsGaugeUnit).style("text-anchor", "middle").style("pointer-events", "none");
  4277. arcs.append("text").attr("class", CLASS.chartArcsGaugeMin).style("text-anchor", "middle").style("pointer-events", "none");
  4278. arcs.append("text").attr("class", CLASS.chartArcsGaugeMax).style("text-anchor", "middle").style("pointer-events", "none");
  4279. }
  4280. };
  4281. c3_chart_internal_fn.getGaugeLabelHeight = function () {
  4282. return this.config.gauge_label_show ? 20 : 0;
  4283. };
  4284. c3_chart_internal_fn.hasCaches = function (ids) {
  4285. for (var i = 0; i < ids.length; i++) {
  4286. if (!(ids[i] in this.cache)) {
  4287. return false;
  4288. }
  4289. }
  4290. return true;
  4291. };
  4292. c3_chart_internal_fn.addCache = function (id, target) {
  4293. this.cache[id] = this.cloneTarget(target);
  4294. };
  4295. c3_chart_internal_fn.getCaches = function (ids) {
  4296. var targets = [],
  4297. i;
  4298. for (i = 0; i < ids.length; i++) {
  4299. if (ids[i] in this.cache) {
  4300. targets.push(this.cloneTarget(this.cache[ids[i]]));
  4301. }
  4302. }
  4303. return targets;
  4304. };
  4305. c3_chart_internal_fn.categoryName = function (i) {
  4306. var config = this.config;
  4307. return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;
  4308. };
  4309. c3_chart_internal_fn.generateClass = function (prefix, targetId) {
  4310. return " " + prefix + " " + prefix + this.getTargetSelectorSuffix(targetId);
  4311. };
  4312. c3_chart_internal_fn.classText = function (d) {
  4313. return this.generateClass(CLASS.text, d.index);
  4314. };
  4315. c3_chart_internal_fn.classTexts = function (d) {
  4316. return this.generateClass(CLASS.texts, d.id);
  4317. };
  4318. c3_chart_internal_fn.classShape = function (d) {
  4319. return this.generateClass(CLASS.shape, d.index);
  4320. };
  4321. c3_chart_internal_fn.classShapes = function (d) {
  4322. return this.generateClass(CLASS.shapes, d.id);
  4323. };
  4324. c3_chart_internal_fn.classLine = function (d) {
  4325. return this.classShape(d) + this.generateClass(CLASS.line, d.id);
  4326. };
  4327. c3_chart_internal_fn.classLines = function (d) {
  4328. return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);
  4329. };
  4330. c3_chart_internal_fn.classCircle = function (d) {
  4331. return this.classShape(d) + this.generateClass(CLASS.circle, d.index);
  4332. };
  4333. c3_chart_internal_fn.classCircles = function (d) {
  4334. return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);
  4335. };
  4336. c3_chart_internal_fn.classBar = function (d) {
  4337. return this.classShape(d) + this.generateClass(CLASS.bar, d.index);
  4338. };
  4339. c3_chart_internal_fn.classBars = function (d) {
  4340. return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);
  4341. };
  4342. c3_chart_internal_fn.classArc = function (d) {
  4343. return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);
  4344. };
  4345. c3_chart_internal_fn.classArcs = function (d) {
  4346. return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);
  4347. };
  4348. c3_chart_internal_fn.classArea = function (d) {
  4349. return this.classShape(d) + this.generateClass(CLASS.area, d.id);
  4350. };
  4351. c3_chart_internal_fn.classAreas = function (d) {
  4352. return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);
  4353. };
  4354. c3_chart_internal_fn.classRegion = function (d, i) {
  4355. return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '');
  4356. };
  4357. c3_chart_internal_fn.classEvent = function (d) {
  4358. return this.generateClass(CLASS.eventRect, d.index);
  4359. };
  4360. c3_chart_internal_fn.classTarget = function (id) {
  4361. var $$ = this;
  4362. var additionalClassSuffix = $$.config.data_classes[id],
  4363. additionalClass = '';
  4364. if (additionalClassSuffix) {
  4365. additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;
  4366. }
  4367. return $$.generateClass(CLASS.target, id) + additionalClass;
  4368. };
  4369. c3_chart_internal_fn.classFocus = function (d) {
  4370. return this.classFocused(d) + this.classDefocused(d);
  4371. };
  4372. c3_chart_internal_fn.classFocused = function (d) {
  4373. return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');
  4374. };
  4375. c3_chart_internal_fn.classDefocused = function (d) {
  4376. return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '');
  4377. };
  4378. c3_chart_internal_fn.classChartText = function (d) {
  4379. return CLASS.chartText + this.classTarget(d.id);
  4380. };
  4381. c3_chart_internal_fn.classChartLine = function (d) {
  4382. return CLASS.chartLine + this.classTarget(d.id);
  4383. };
  4384. c3_chart_internal_fn.classChartBar = function (d) {
  4385. return CLASS.chartBar + this.classTarget(d.id);
  4386. };
  4387. c3_chart_internal_fn.classChartArc = function (d) {
  4388. return CLASS.chartArc + this.classTarget(d.data.id);
  4389. };
  4390. c3_chart_internal_fn.getTargetSelectorSuffix = function (targetId) {
  4391. return targetId || targetId === 0 ? ('-' + targetId).replace(/[\s?!@#$%^&*()_=+,.<>'":;\[\]\/|~`{}\\]/g, '-') : '';
  4392. };
  4393. c3_chart_internal_fn.selectorTarget = function (id, prefix) {
  4394. return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);
  4395. };
  4396. c3_chart_internal_fn.selectorTargets = function (ids, prefix) {
  4397. var $$ = this;
  4398. ids = ids || [];
  4399. return ids.length ? ids.map(function (id) {
  4400. return $$.selectorTarget(id, prefix);
  4401. }) : null;
  4402. };
  4403. c3_chart_internal_fn.selectorLegend = function (id) {
  4404. return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);
  4405. };
  4406. c3_chart_internal_fn.selectorLegends = function (ids) {
  4407. var $$ = this;
  4408. return ids && ids.length ? ids.map(function (id) {
  4409. return $$.selectorLegend(id);
  4410. }) : null;
  4411. };
  4412. c3_chart_internal_fn.getClipPath = function (id) {
  4413. var isIE9 = window.navigator.appVersion.toLowerCase().indexOf("msie 9.") >= 0;
  4414. return "url(" + (isIE9 ? "" : document.URL.split('#')[0]) + "#" + id + ")";
  4415. };
  4416. c3_chart_internal_fn.appendClip = function (parent, id) {
  4417. return parent.append("clipPath").attr("id", id).append("rect");
  4418. };
  4419. c3_chart_internal_fn.getAxisClipX = function (forHorizontal) {
  4420. // axis line width + padding for left
  4421. var left = Math.max(30, this.margin.left);
  4422. return forHorizontal ? -(1 + left) : -(left - 1);
  4423. };
  4424. c3_chart_internal_fn.getAxisClipY = function (forHorizontal) {
  4425. return forHorizontal ? -20 : -this.margin.top;
  4426. };
  4427. c3_chart_internal_fn.getXAxisClipX = function () {
  4428. var $$ = this;
  4429. return $$.getAxisClipX(!$$.config.axis_rotated);
  4430. };
  4431. c3_chart_internal_fn.getXAxisClipY = function () {
  4432. var $$ = this;
  4433. return $$.getAxisClipY(!$$.config.axis_rotated);
  4434. };
  4435. c3_chart_internal_fn.getYAxisClipX = function () {
  4436. var $$ = this;
  4437. return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated);
  4438. };
  4439. c3_chart_internal_fn.getYAxisClipY = function () {
  4440. var $$ = this;
  4441. return $$.getAxisClipY($$.config.axis_rotated);
  4442. };
  4443. c3_chart_internal_fn.getAxisClipWidth = function (forHorizontal) {
  4444. var $$ = this,
  4445. left = Math.max(30, $$.margin.left),
  4446. right = Math.max(30, $$.margin.right);
  4447. // width + axis line width + padding for left/right
  4448. return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20;
  4449. };
  4450. c3_chart_internal_fn.getAxisClipHeight = function (forHorizontal) {
  4451. // less than 20 is not enough to show the axis label 'outer' without legend
  4452. return (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20;
  4453. };
  4454. c3_chart_internal_fn.getXAxisClipWidth = function () {
  4455. var $$ = this;
  4456. return $$.getAxisClipWidth(!$$.config.axis_rotated);
  4457. };
  4458. c3_chart_internal_fn.getXAxisClipHeight = function () {
  4459. var $$ = this;
  4460. return $$.getAxisClipHeight(!$$.config.axis_rotated);
  4461. };
  4462. c3_chart_internal_fn.getYAxisClipWidth = function () {
  4463. var $$ = this;
  4464. return $$.getAxisClipWidth($$.config.axis_rotated) + ($$.config.axis_y_inner ? 20 : 0);
  4465. };
  4466. c3_chart_internal_fn.getYAxisClipHeight = function () {
  4467. var $$ = this;
  4468. return $$.getAxisClipHeight($$.config.axis_rotated);
  4469. };
  4470. c3_chart_internal_fn.generateColor = function () {
  4471. var $$ = this,
  4472. config = $$.config,
  4473. d3 = $$.d3,
  4474. colors = config.data_colors,
  4475. pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.scale.category10().range(),
  4476. callback = config.data_color,
  4477. ids = [];
  4478. return function (d) {
  4479. var id = d.id || d.data && d.data.id || d,
  4480. color;
  4481. // if callback function is provided
  4482. if (colors[id] instanceof Function) {
  4483. color = colors[id](d);
  4484. }
  4485. // if specified, choose that color
  4486. else if (colors[id]) {
  4487. color = colors[id];
  4488. }
  4489. // if not specified, choose from pattern
  4490. else {
  4491. if (ids.indexOf(id) < 0) {
  4492. ids.push(id);
  4493. }
  4494. color = pattern[ids.indexOf(id) % pattern.length];
  4495. colors[id] = color;
  4496. }
  4497. return callback instanceof Function ? callback(color, d) : color;
  4498. };
  4499. };
  4500. c3_chart_internal_fn.generateLevelColor = function () {
  4501. var $$ = this,
  4502. config = $$.config,
  4503. colors = config.color_pattern,
  4504. threshold = config.color_threshold,
  4505. asValue = threshold.unit === 'value',
  4506. values = threshold.values && threshold.values.length ? threshold.values : [],
  4507. max = threshold.max || 100;
  4508. return notEmpty(config.color_threshold) ? function (value) {
  4509. var i,
  4510. v,
  4511. color = colors[colors.length - 1];
  4512. for (i = 0; i < values.length; i++) {
  4513. v = asValue ? value : value * 100 / max;
  4514. if (v < values[i]) {
  4515. color = colors[i];
  4516. break;
  4517. }
  4518. }
  4519. return color;
  4520. } : null;
  4521. };
  4522. c3_chart_internal_fn.getDefaultConfig = function () {
  4523. var config = {
  4524. bindto: '#chart',
  4525. svg_classname: undefined,
  4526. size_width: undefined,
  4527. size_height: undefined,
  4528. padding_left: undefined,
  4529. padding_right: undefined,
  4530. padding_top: undefined,
  4531. padding_bottom: undefined,
  4532. resize_auto: true,
  4533. zoom_enabled: false,
  4534. zoom_extent: undefined,
  4535. zoom_privileged: false,
  4536. zoom_rescale: false,
  4537. zoom_onzoom: function zoom_onzoom() {},
  4538. zoom_onzoomstart: function zoom_onzoomstart() {},
  4539. zoom_onzoomend: function zoom_onzoomend() {},
  4540. zoom_x_min: undefined,
  4541. zoom_x_max: undefined,
  4542. interaction_brighten: true,
  4543. interaction_enabled: true,
  4544. onmouseover: function onmouseover() {},
  4545. onmouseout: function onmouseout() {},
  4546. onresize: function onresize() {},
  4547. onresized: function onresized() {},
  4548. oninit: function oninit() {},
  4549. onrendered: function onrendered() {},
  4550. transition_duration: 350,
  4551. data_x: undefined,
  4552. data_xs: {},
  4553. data_xFormat: '%Y-%m-%d',
  4554. data_xLocaltime: true,
  4555. data_xSort: true,
  4556. data_idConverter: function data_idConverter(id) {
  4557. return id;
  4558. },
  4559. data_names: {},
  4560. data_classes: {},
  4561. data_groups: [],
  4562. data_axes: {},
  4563. data_type: undefined,
  4564. data_types: {},
  4565. data_labels: {},
  4566. data_order: 'desc',
  4567. data_regions: {},
  4568. data_color: undefined,
  4569. data_colors: {},
  4570. data_hide: false,
  4571. data_filter: undefined,
  4572. data_selection_enabled: false,
  4573. data_selection_grouped: false,
  4574. data_selection_isselectable: function data_selection_isselectable() {
  4575. return true;
  4576. },
  4577. data_selection_multiple: true,
  4578. data_selection_draggable: false,
  4579. data_onclick: function data_onclick() {},
  4580. data_onmouseover: function data_onmouseover() {},
  4581. data_onmouseout: function data_onmouseout() {},
  4582. data_onselected: function data_onselected() {},
  4583. data_onunselected: function data_onunselected() {},
  4584. data_url: undefined,
  4585. data_headers: undefined,
  4586. data_json: undefined,
  4587. data_rows: undefined,
  4588. data_columns: undefined,
  4589. data_mimeType: undefined,
  4590. data_keys: undefined,
  4591. // configuration for no plot-able data supplied.
  4592. data_empty_label_text: "",
  4593. // subchart
  4594. subchart_show: false,
  4595. subchart_size_height: 60,
  4596. subchart_axis_x_show: true,
  4597. subchart_onbrush: function subchart_onbrush() {},
  4598. // color
  4599. color_pattern: [],
  4600. color_threshold: {},
  4601. // legend
  4602. legend_show: true,
  4603. legend_hide: false,
  4604. legend_position: 'bottom',
  4605. legend_inset_anchor: 'top-left',
  4606. legend_inset_x: 10,
  4607. legend_inset_y: 0,
  4608. legend_inset_step: undefined,
  4609. legend_item_onclick: undefined,
  4610. legend_item_onmouseover: undefined,
  4611. legend_item_onmouseout: undefined,
  4612. legend_equally: false,
  4613. legend_padding: 0,
  4614. legend_item_tile_width: 10,
  4615. legend_item_tile_height: 10,
  4616. // axis
  4617. axis_rotated: false,
  4618. axis_x_show: true,
  4619. axis_x_type: 'indexed',
  4620. axis_x_localtime: true,
  4621. axis_x_categories: [],
  4622. axis_x_tick_centered: false,
  4623. axis_x_tick_format: undefined,
  4624. axis_x_tick_culling: {},
  4625. axis_x_tick_culling_max: 10,
  4626. axis_x_tick_count: undefined,
  4627. axis_x_tick_fit: true,
  4628. axis_x_tick_values: null,
  4629. axis_x_tick_rotate: 0,
  4630. axis_x_tick_outer: true,
  4631. axis_x_tick_multiline: true,
  4632. axis_x_tick_width: null,
  4633. axis_x_max: undefined,
  4634. axis_x_min: undefined,
  4635. axis_x_padding: {},
  4636. axis_x_height: undefined,
  4637. axis_x_extent: undefined,
  4638. axis_x_label: {},
  4639. axis_y_show: true,
  4640. axis_y_type: undefined,
  4641. axis_y_max: undefined,
  4642. axis_y_min: undefined,
  4643. axis_y_inverted: false,
  4644. axis_y_center: undefined,
  4645. axis_y_inner: undefined,
  4646. axis_y_label: {},
  4647. axis_y_tick_format: undefined,
  4648. axis_y_tick_outer: true,
  4649. axis_y_tick_values: null,
  4650. axis_y_tick_rotate: 0,
  4651. axis_y_tick_count: undefined,
  4652. axis_y_tick_time_value: undefined,
  4653. axis_y_tick_time_interval: undefined,
  4654. axis_y_padding: {},
  4655. axis_y_default: undefined,
  4656. axis_y2_show: false,
  4657. axis_y2_max: undefined,
  4658. axis_y2_min: undefined,
  4659. axis_y2_inverted: false,
  4660. axis_y2_center: undefined,
  4661. axis_y2_inner: undefined,
  4662. axis_y2_label: {},
  4663. axis_y2_tick_format: undefined,
  4664. axis_y2_tick_outer: true,
  4665. axis_y2_tick_values: null,
  4666. axis_y2_tick_count: undefined,
  4667. axis_y2_padding: {},
  4668. axis_y2_default: undefined,
  4669. // grid
  4670. grid_x_show: false,
  4671. grid_x_type: 'tick',
  4672. grid_x_lines: [],
  4673. grid_y_show: false,
  4674. // not used
  4675. // grid_y_type: 'tick',
  4676. grid_y_lines: [],
  4677. grid_y_ticks: 10,
  4678. grid_focus_show: true,
  4679. grid_lines_front: true,
  4680. // point - point of each data
  4681. point_show: true,
  4682. point_r: 2.5,
  4683. point_sensitivity: 10,
  4684. point_focus_expand_enabled: true,
  4685. point_focus_expand_r: undefined,
  4686. point_select_r: undefined,
  4687. // line
  4688. line_connectNull: false,
  4689. line_step_type: 'step',
  4690. // bar
  4691. bar_width: undefined,
  4692. bar_width_ratio: 0.6,
  4693. bar_width_max: undefined,
  4694. bar_zerobased: true,
  4695. // area
  4696. area_zerobased: true,
  4697. area_above: false,
  4698. // pie
  4699. pie_label_show: true,
  4700. pie_label_format: undefined,
  4701. pie_label_threshold: 0.05,
  4702. pie_label_ratio: undefined,
  4703. pie_expand: {},
  4704. pie_expand_duration: 50,
  4705. // gauge
  4706. gauge_fullCircle: false,
  4707. gauge_label_show: true,
  4708. gauge_label_format: undefined,
  4709. gauge_min: 0,
  4710. gauge_max: 100,
  4711. gauge_startingAngle: -1 * Math.PI / 2,
  4712. gauge_label_extents: undefined,
  4713. gauge_units: undefined,
  4714. gauge_width: undefined,
  4715. gauge_expand: {},
  4716. gauge_expand_duration: 50,
  4717. // donut
  4718. donut_label_show: true,
  4719. donut_label_format: undefined,
  4720. donut_label_threshold: 0.05,
  4721. donut_label_ratio: undefined,
  4722. donut_width: undefined,
  4723. donut_title: "",
  4724. donut_expand: {},
  4725. donut_expand_duration: 50,
  4726. // spline
  4727. spline_interpolation_type: 'cardinal',
  4728. // region - region to change style
  4729. regions: [],
  4730. // tooltip - show when mouseover on each data
  4731. tooltip_show: true,
  4732. tooltip_grouped: true,
  4733. tooltip_order: undefined,
  4734. tooltip_format_title: undefined,
  4735. tooltip_format_name: undefined,
  4736. tooltip_format_value: undefined,
  4737. tooltip_position: undefined,
  4738. tooltip_contents: function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) {
  4739. return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
  4740. },
  4741. tooltip_init_show: false,
  4742. tooltip_init_x: 0,
  4743. tooltip_init_position: { top: '0px', left: '50px' },
  4744. tooltip_onshow: function tooltip_onshow() {},
  4745. tooltip_onhide: function tooltip_onhide() {},
  4746. // title
  4747. title_text: undefined,
  4748. title_padding: {
  4749. top: 0,
  4750. right: 0,
  4751. bottom: 0,
  4752. left: 0
  4753. },
  4754. title_position: 'top-center'
  4755. };
  4756. Object.keys(this.additionalConfig).forEach(function (key) {
  4757. config[key] = this.additionalConfig[key];
  4758. }, this);
  4759. return config;
  4760. };
  4761. c3_chart_internal_fn.additionalConfig = {};
  4762. c3_chart_internal_fn.loadConfig = function (config) {
  4763. var this_config = this.config,
  4764. target,
  4765. keys,
  4766. read;
  4767. function find() {
  4768. var key = keys.shift();
  4769. // console.log("key =>", key, ", target =>", target);
  4770. if (key && target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && key in target) {
  4771. target = target[key];
  4772. return find();
  4773. } else if (!key) {
  4774. return target;
  4775. } else {
  4776. return undefined;
  4777. }
  4778. }
  4779. Object.keys(this_config).forEach(function (key) {
  4780. target = config;
  4781. keys = key.split('_');
  4782. read = find();
  4783. // console.log("CONFIG : ", key, read);
  4784. if (isDefined(read)) {
  4785. this_config[key] = read;
  4786. }
  4787. });
  4788. };
  4789. c3_chart_internal_fn.convertUrlToData = function (url, mimeType, headers, keys, done) {
  4790. var $$ = this,
  4791. type = mimeType ? mimeType : 'csv';
  4792. var req = $$.d3.xhr(url);
  4793. if (headers) {
  4794. Object.keys(headers).forEach(function (header) {
  4795. req.header(header, headers[header]);
  4796. });
  4797. }
  4798. req.get(function (error, data) {
  4799. var d;
  4800. var dataResponse = data.response || data.responseText; // Fixes IE9 XHR issue; see #1345
  4801. if (!data) {
  4802. throw new Error(error.responseURL + ' ' + error.status + ' (' + error.statusText + ')');
  4803. }
  4804. if (type === 'json') {
  4805. d = $$.convertJsonToData(JSON.parse(dataResponse), keys);
  4806. } else if (type === 'tsv') {
  4807. d = $$.convertTsvToData(dataResponse);
  4808. } else {
  4809. d = $$.convertCsvToData(dataResponse);
  4810. }
  4811. done.call($$, d);
  4812. });
  4813. };
  4814. c3_chart_internal_fn.convertXsvToData = function (xsv, parser) {
  4815. var rows = parser.parseRows(xsv),
  4816. d;
  4817. if (rows.length === 1) {
  4818. d = [{}];
  4819. rows[0].forEach(function (id) {
  4820. d[0][id] = null;
  4821. });
  4822. } else {
  4823. d = parser.parse(xsv);
  4824. }
  4825. return d;
  4826. };
  4827. c3_chart_internal_fn.convertCsvToData = function (csv) {
  4828. return this.convertXsvToData(csv, this.d3.csv);
  4829. };
  4830. c3_chart_internal_fn.convertTsvToData = function (tsv) {
  4831. return this.convertXsvToData(tsv, this.d3.tsv);
  4832. };
  4833. c3_chart_internal_fn.convertJsonToData = function (json, keys) {
  4834. var $$ = this,
  4835. new_rows = [],
  4836. targetKeys,
  4837. data;
  4838. if (keys) {
  4839. // when keys specified, json would be an array that includes objects
  4840. if (keys.x) {
  4841. targetKeys = keys.value.concat(keys.x);
  4842. $$.config.data_x = keys.x;
  4843. } else {
  4844. targetKeys = keys.value;
  4845. }
  4846. new_rows.push(targetKeys);
  4847. json.forEach(function (o) {
  4848. var new_row = [];
  4849. targetKeys.forEach(function (key) {
  4850. // convert undefined to null because undefined data will be removed in convertDataToTargets()
  4851. var v = $$.findValueInJson(o, key);
  4852. if (isUndefined(v)) {
  4853. v = null;
  4854. }
  4855. new_row.push(v);
  4856. });
  4857. new_rows.push(new_row);
  4858. });
  4859. data = $$.convertRowsToData(new_rows);
  4860. } else {
  4861. Object.keys(json).forEach(function (key) {
  4862. new_rows.push([key].concat(json[key]));
  4863. });
  4864. data = $$.convertColumnsToData(new_rows);
  4865. }
  4866. return data;
  4867. };
  4868. c3_chart_internal_fn.findValueInJson = function (object, path) {
  4869. path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
  4870. path = path.replace(/^\./, ''); // strip a leading dot
  4871. var pathArray = path.split('.');
  4872. for (var i = 0; i < pathArray.length; ++i) {
  4873. var k = pathArray[i];
  4874. if (k in object) {
  4875. object = object[k];
  4876. } else {
  4877. return;
  4878. }
  4879. }
  4880. return object;
  4881. };
  4882. /**
  4883. * Converts the rows to normalized data.
  4884. * @param {any[][]} rows The row data
  4885. * @return {Object[]}
  4886. */
  4887. c3_chart_internal_fn.convertRowsToData = function (rows) {
  4888. var newRows = [];
  4889. var keys = rows[0];
  4890. for (var i = 1; i < rows.length; i++) {
  4891. var newRow = {};
  4892. for (var j = 0; j < rows[i].length; j++) {
  4893. if (isUndefined(rows[i][j])) {
  4894. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  4895. }
  4896. newRow[keys[j]] = rows[i][j];
  4897. }
  4898. newRows.push(newRow);
  4899. }
  4900. return newRows;
  4901. };
  4902. /**
  4903. * Converts the columns to normalized data.
  4904. * @param {any[][]} columns The column data
  4905. * @return {Object[]}
  4906. */
  4907. c3_chart_internal_fn.convertColumnsToData = function (columns) {
  4908. var newRows = [];
  4909. for (var i = 0; i < columns.length; i++) {
  4910. var key = columns[i][0];
  4911. for (var j = 1; j < columns[i].length; j++) {
  4912. if (isUndefined(newRows[j - 1])) {
  4913. newRows[j - 1] = {};
  4914. }
  4915. if (isUndefined(columns[i][j])) {
  4916. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  4917. }
  4918. newRows[j - 1][key] = columns[i][j];
  4919. }
  4920. }
  4921. return newRows;
  4922. };
  4923. c3_chart_internal_fn.convertDataToTargets = function (data, appendXs) {
  4924. var $$ = this,
  4925. config = $$.config,
  4926. ids = $$.d3.keys(data[0]).filter($$.isNotX, $$),
  4927. xs = $$.d3.keys(data[0]).filter($$.isX, $$),
  4928. targets;
  4929. // save x for update data by load when custom x and c3.x API
  4930. ids.forEach(function (id) {
  4931. var xKey = $$.getXKey(id);
  4932. if ($$.isCustomX() || $$.isTimeSeries()) {
  4933. // if included in input data
  4934. if (xs.indexOf(xKey) >= 0) {
  4935. $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat(data.map(function (d) {
  4936. return d[xKey];
  4937. }).filter(isValue).map(function (rawX, i) {
  4938. return $$.generateTargetX(rawX, id, i);
  4939. }));
  4940. }
  4941. // if not included in input data, find from preloaded data of other id's x
  4942. else if (config.data_x) {
  4943. $$.data.xs[id] = $$.getOtherTargetXs();
  4944. }
  4945. // if not included in input data, find from preloaded data
  4946. else if (notEmpty(config.data_xs)) {
  4947. $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);
  4948. }
  4949. // MEMO: if no x included, use same x of current will be used
  4950. } else {
  4951. $$.data.xs[id] = data.map(function (d, i) {
  4952. return i;
  4953. });
  4954. }
  4955. });
  4956. // check x is defined
  4957. ids.forEach(function (id) {
  4958. if (!$$.data.xs[id]) {
  4959. throw new Error('x is not defined for id = "' + id + '".');
  4960. }
  4961. });
  4962. // convert to target
  4963. targets = ids.map(function (id, index) {
  4964. var convertedId = config.data_idConverter(id);
  4965. return {
  4966. id: convertedId,
  4967. id_org: id,
  4968. values: data.map(function (d, i) {
  4969. var xKey = $$.getXKey(id),
  4970. rawX = d[xKey],
  4971. value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null,
  4972. x;
  4973. // use x as categories if custom x and categorized
  4974. if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {
  4975. if (index === 0 && i === 0) {
  4976. config.axis_x_categories = [];
  4977. }
  4978. x = config.axis_x_categories.indexOf(rawX);
  4979. if (x === -1) {
  4980. x = config.axis_x_categories.length;
  4981. config.axis_x_categories.push(rawX);
  4982. }
  4983. } else {
  4984. x = $$.generateTargetX(rawX, id, i);
  4985. }
  4986. // mark as x = undefined if value is undefined and filter to remove after mapped
  4987. if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {
  4988. x = undefined;
  4989. }
  4990. return { x: x, value: value, id: convertedId };
  4991. }).filter(function (v) {
  4992. return isDefined(v.x);
  4993. })
  4994. };
  4995. });
  4996. // finish targets
  4997. targets.forEach(function (t) {
  4998. var i;
  4999. // sort values by its x
  5000. if (config.data_xSort) {
  5001. t.values = t.values.sort(function (v1, v2) {
  5002. var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,
  5003. x2 = v2.x || v2.x === 0 ? v2.x : Infinity;
  5004. return x1 - x2;
  5005. });
  5006. }
  5007. // indexing each value
  5008. i = 0;
  5009. t.values.forEach(function (v) {
  5010. v.index = i++;
  5011. });
  5012. // this needs to be sorted because its index and value.index is identical
  5013. $$.data.xs[t.id].sort(function (v1, v2) {
  5014. return v1 - v2;
  5015. });
  5016. });
  5017. // cache information about values
  5018. $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  5019. $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets);
  5020. // set target types
  5021. if (config.data_type) {
  5022. $$.setTargetType($$.mapToIds(targets).filter(function (id) {
  5023. return !(id in config.data_types);
  5024. }), config.data_type);
  5025. }
  5026. // cache as original id keyed
  5027. targets.forEach(function (d) {
  5028. $$.addCache(d.id_org, d);
  5029. });
  5030. return targets;
  5031. };
  5032. c3_chart_internal_fn.isX = function (key) {
  5033. var $$ = this,
  5034. config = $$.config;
  5035. return config.data_x && key === config.data_x || notEmpty(config.data_xs) && hasValue(config.data_xs, key);
  5036. };
  5037. c3_chart_internal_fn.isNotX = function (key) {
  5038. return !this.isX(key);
  5039. };
  5040. c3_chart_internal_fn.getXKey = function (id) {
  5041. var $$ = this,
  5042. config = $$.config;
  5043. return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null;
  5044. };
  5045. c3_chart_internal_fn.getXValuesOfXKey = function (key, targets) {
  5046. var $$ = this,
  5047. xValues,
  5048. ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];
  5049. ids.forEach(function (id) {
  5050. if ($$.getXKey(id) === key) {
  5051. xValues = $$.data.xs[id];
  5052. }
  5053. });
  5054. return xValues;
  5055. };
  5056. c3_chart_internal_fn.getIndexByX = function (x) {
  5057. var $$ = this,
  5058. data = $$.filterByX($$.data.targets, x);
  5059. return data.length ? data[0].index : null;
  5060. };
  5061. c3_chart_internal_fn.getXValue = function (id, i) {
  5062. var $$ = this;
  5063. return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
  5064. };
  5065. c3_chart_internal_fn.getOtherTargetXs = function () {
  5066. var $$ = this,
  5067. idsForX = Object.keys($$.data.xs);
  5068. return idsForX.length ? $$.data.xs[idsForX[0]] : null;
  5069. };
  5070. c3_chart_internal_fn.getOtherTargetX = function (index) {
  5071. var xs = this.getOtherTargetXs();
  5072. return xs && index < xs.length ? xs[index] : null;
  5073. };
  5074. c3_chart_internal_fn.addXs = function (xs) {
  5075. var $$ = this;
  5076. Object.keys(xs).forEach(function (id) {
  5077. $$.config.data_xs[id] = xs[id];
  5078. });
  5079. };
  5080. c3_chart_internal_fn.hasMultipleX = function (xs) {
  5081. return this.d3.set(Object.keys(xs).map(function (id) {
  5082. return xs[id];
  5083. })).size() > 1;
  5084. };
  5085. c3_chart_internal_fn.isMultipleX = function () {
  5086. return notEmpty(this.config.data_xs) || !this.config.data_xSort || this.hasType('scatter');
  5087. };
  5088. c3_chart_internal_fn.addName = function (data) {
  5089. var $$ = this,
  5090. name;
  5091. if (data) {
  5092. name = $$.config.data_names[data.id];
  5093. data.name = name !== undefined ? name : data.id;
  5094. }
  5095. return data;
  5096. };
  5097. c3_chart_internal_fn.getValueOnIndex = function (values, index) {
  5098. var valueOnIndex = values.filter(function (v) {
  5099. return v.index === index;
  5100. });
  5101. return valueOnIndex.length ? valueOnIndex[0] : null;
  5102. };
  5103. c3_chart_internal_fn.updateTargetX = function (targets, x) {
  5104. var $$ = this;
  5105. targets.forEach(function (t) {
  5106. t.values.forEach(function (v, i) {
  5107. v.x = $$.generateTargetX(x[i], t.id, i);
  5108. });
  5109. $$.data.xs[t.id] = x;
  5110. });
  5111. };
  5112. c3_chart_internal_fn.updateTargetXs = function (targets, xs) {
  5113. var $$ = this;
  5114. targets.forEach(function (t) {
  5115. if (xs[t.id]) {
  5116. $$.updateTargetX([t], xs[t.id]);
  5117. }
  5118. });
  5119. };
  5120. c3_chart_internal_fn.generateTargetX = function (rawX, id, index) {
  5121. var $$ = this,
  5122. x;
  5123. if ($$.isTimeSeries()) {
  5124. x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));
  5125. } else if ($$.isCustomX() && !$$.isCategorized()) {
  5126. x = isValue(rawX) ? +rawX : $$.getXValue(id, index);
  5127. } else {
  5128. x = index;
  5129. }
  5130. return x;
  5131. };
  5132. c3_chart_internal_fn.cloneTarget = function (target) {
  5133. return {
  5134. id: target.id,
  5135. id_org: target.id_org,
  5136. values: target.values.map(function (d) {
  5137. return { x: d.x, value: d.value, id: d.id };
  5138. })
  5139. };
  5140. };
  5141. c3_chart_internal_fn.updateXs = function () {
  5142. var $$ = this;
  5143. if ($$.data.targets.length) {
  5144. $$.xs = [];
  5145. $$.data.targets[0].values.forEach(function (v) {
  5146. $$.xs[v.index] = v.x;
  5147. });
  5148. }
  5149. };
  5150. c3_chart_internal_fn.getPrevX = function (i) {
  5151. var x = this.xs[i - 1];
  5152. return typeof x !== 'undefined' ? x : null;
  5153. };
  5154. c3_chart_internal_fn.getNextX = function (i) {
  5155. var x = this.xs[i + 1];
  5156. return typeof x !== 'undefined' ? x : null;
  5157. };
  5158. c3_chart_internal_fn.getMaxDataCount = function () {
  5159. var $$ = this;
  5160. return $$.d3.max($$.data.targets, function (t) {
  5161. return t.values.length;
  5162. });
  5163. };
  5164. c3_chart_internal_fn.getMaxDataCountTarget = function (targets) {
  5165. var length = targets.length,
  5166. max = 0,
  5167. maxTarget;
  5168. if (length > 1) {
  5169. targets.forEach(function (t) {
  5170. if (t.values.length > max) {
  5171. maxTarget = t;
  5172. max = t.values.length;
  5173. }
  5174. });
  5175. } else {
  5176. maxTarget = length ? targets[0] : null;
  5177. }
  5178. return maxTarget;
  5179. };
  5180. c3_chart_internal_fn.getEdgeX = function (targets) {
  5181. var $$ = this;
  5182. return !targets.length ? [0, 0] : [$$.d3.min(targets, function (t) {
  5183. return t.values[0].x;
  5184. }), $$.d3.max(targets, function (t) {
  5185. return t.values[t.values.length - 1].x;
  5186. })];
  5187. };
  5188. c3_chart_internal_fn.mapToIds = function (targets) {
  5189. return targets.map(function (d) {
  5190. return d.id;
  5191. });
  5192. };
  5193. c3_chart_internal_fn.mapToTargetIds = function (ids) {
  5194. var $$ = this;
  5195. return ids ? [].concat(ids) : $$.mapToIds($$.data.targets);
  5196. };
  5197. c3_chart_internal_fn.hasTarget = function (targets, id) {
  5198. var ids = this.mapToIds(targets),
  5199. i;
  5200. for (i = 0; i < ids.length; i++) {
  5201. if (ids[i] === id) {
  5202. return true;
  5203. }
  5204. }
  5205. return false;
  5206. };
  5207. c3_chart_internal_fn.isTargetToShow = function (targetId) {
  5208. return this.hiddenTargetIds.indexOf(targetId) < 0;
  5209. };
  5210. c3_chart_internal_fn.isLegendToShow = function (targetId) {
  5211. return this.hiddenLegendIds.indexOf(targetId) < 0;
  5212. };
  5213. c3_chart_internal_fn.filterTargetsToShow = function (targets) {
  5214. var $$ = this;
  5215. return targets.filter(function (t) {
  5216. return $$.isTargetToShow(t.id);
  5217. });
  5218. };
  5219. c3_chart_internal_fn.mapTargetsToUniqueXs = function (targets) {
  5220. var $$ = this;
  5221. var xs = $$.d3.set($$.d3.merge(targets.map(function (t) {
  5222. return t.values.map(function (v) {
  5223. return +v.x;
  5224. });
  5225. }))).values();
  5226. xs = $$.isTimeSeries() ? xs.map(function (x) {
  5227. return new Date(+x);
  5228. }) : xs.map(function (x) {
  5229. return +x;
  5230. });
  5231. return xs.sort(function (a, b) {
  5232. return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
  5233. });
  5234. };
  5235. c3_chart_internal_fn.addHiddenTargetIds = function (targetIds) {
  5236. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  5237. for (var i = 0; i < targetIds.length; i++) {
  5238. if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {
  5239. this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);
  5240. }
  5241. }
  5242. };
  5243. c3_chart_internal_fn.removeHiddenTargetIds = function (targetIds) {
  5244. this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) {
  5245. return targetIds.indexOf(id) < 0;
  5246. });
  5247. };
  5248. c3_chart_internal_fn.addHiddenLegendIds = function (targetIds) {
  5249. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  5250. for (var i = 0; i < targetIds.length; i++) {
  5251. if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {
  5252. this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);
  5253. }
  5254. }
  5255. };
  5256. c3_chart_internal_fn.removeHiddenLegendIds = function (targetIds) {
  5257. this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) {
  5258. return targetIds.indexOf(id) < 0;
  5259. });
  5260. };
  5261. c3_chart_internal_fn.getValuesAsIdKeyed = function (targets) {
  5262. var ys = {};
  5263. targets.forEach(function (t) {
  5264. ys[t.id] = [];
  5265. t.values.forEach(function (v) {
  5266. ys[t.id].push(v.value);
  5267. });
  5268. });
  5269. return ys;
  5270. };
  5271. c3_chart_internal_fn.checkValueInTargets = function (targets, checker) {
  5272. var ids = Object.keys(targets),
  5273. i,
  5274. j,
  5275. values;
  5276. for (i = 0; i < ids.length; i++) {
  5277. values = targets[ids[i]].values;
  5278. for (j = 0; j < values.length; j++) {
  5279. if (checker(values[j].value)) {
  5280. return true;
  5281. }
  5282. }
  5283. }
  5284. return false;
  5285. };
  5286. c3_chart_internal_fn.hasNegativeValueInTargets = function (targets) {
  5287. return this.checkValueInTargets(targets, function (v) {
  5288. return v < 0;
  5289. });
  5290. };
  5291. c3_chart_internal_fn.hasPositiveValueInTargets = function (targets) {
  5292. return this.checkValueInTargets(targets, function (v) {
  5293. return v > 0;
  5294. });
  5295. };
  5296. c3_chart_internal_fn.isOrderDesc = function () {
  5297. var config = this.config;
  5298. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'desc';
  5299. };
  5300. c3_chart_internal_fn.isOrderAsc = function () {
  5301. var config = this.config;
  5302. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'asc';
  5303. };
  5304. c3_chart_internal_fn.orderTargets = function (targets) {
  5305. var $$ = this,
  5306. config = $$.config,
  5307. orderAsc = $$.isOrderAsc(),
  5308. orderDesc = $$.isOrderDesc();
  5309. if (orderAsc || orderDesc) {
  5310. targets.sort(function (t1, t2) {
  5311. var reducer = function reducer(p, c) {
  5312. return p + Math.abs(c.value);
  5313. };
  5314. var t1Sum = t1.values.reduce(reducer, 0),
  5315. t2Sum = t2.values.reduce(reducer, 0);
  5316. return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;
  5317. });
  5318. } else if (isFunction(config.data_order)) {
  5319. targets.sort(config.data_order);
  5320. } else if (isArray(config.data_order)) {
  5321. targets.sort(function (t1, t2) {
  5322. return config.data_order.indexOf(t1.id) - config.data_order.indexOf(t2.id);
  5323. });
  5324. }
  5325. return targets;
  5326. };
  5327. c3_chart_internal_fn.filterByX = function (targets, x) {
  5328. return this.d3.merge(targets.map(function (t) {
  5329. return t.values;
  5330. })).filter(function (v) {
  5331. return v.x - x === 0;
  5332. });
  5333. };
  5334. c3_chart_internal_fn.filterRemoveNull = function (data) {
  5335. return data.filter(function (d) {
  5336. return isValue(d.value);
  5337. });
  5338. };
  5339. c3_chart_internal_fn.filterByXDomain = function (targets, xDomain) {
  5340. return targets.map(function (t) {
  5341. return {
  5342. id: t.id,
  5343. id_org: t.id_org,
  5344. values: t.values.filter(function (v) {
  5345. return xDomain[0] <= v.x && v.x <= xDomain[1];
  5346. })
  5347. };
  5348. });
  5349. };
  5350. c3_chart_internal_fn.hasDataLabel = function () {
  5351. var config = this.config;
  5352. if (typeof config.data_labels === 'boolean' && config.data_labels) {
  5353. return true;
  5354. } else if (_typeof(config.data_labels) === 'object' && notEmpty(config.data_labels)) {
  5355. return true;
  5356. }
  5357. return false;
  5358. };
  5359. c3_chart_internal_fn.getDataLabelLength = function (min, max, key) {
  5360. var $$ = this,
  5361. lengths = [0, 0],
  5362. paddingCoef = 1.3;
  5363. $$.selectChart.select('svg').selectAll('.dummy').data([min, max]).enter().append('text').text(function (d) {
  5364. return $$.dataLabelFormat(d.id)(d);
  5365. }).each(function (d, i) {
  5366. lengths[i] = this.getBoundingClientRect()[key] * paddingCoef;
  5367. }).remove();
  5368. return lengths;
  5369. };
  5370. c3_chart_internal_fn.isNoneArc = function (d) {
  5371. return this.hasTarget(this.data.targets, d.id);
  5372. }, c3_chart_internal_fn.isArc = function (d) {
  5373. return 'data' in d && this.hasTarget(this.data.targets, d.data.id);
  5374. };
  5375. c3_chart_internal_fn.findSameXOfValues = function (values, index) {
  5376. var i,
  5377. targetX = values[index].x,
  5378. sames = [];
  5379. for (i = index - 1; i >= 0; i--) {
  5380. if (targetX !== values[i].x) {
  5381. break;
  5382. }
  5383. sames.push(values[i]);
  5384. }
  5385. for (i = index; i < values.length; i++) {
  5386. if (targetX !== values[i].x) {
  5387. break;
  5388. }
  5389. sames.push(values[i]);
  5390. }
  5391. return sames;
  5392. };
  5393. c3_chart_internal_fn.findClosestFromTargets = function (targets, pos) {
  5394. var $$ = this,
  5395. candidates;
  5396. // map to array of closest points of each target
  5397. candidates = targets.map(function (target) {
  5398. return $$.findClosest(target.values, pos);
  5399. });
  5400. // decide closest point and return
  5401. return $$.findClosest(candidates, pos);
  5402. };
  5403. c3_chart_internal_fn.findClosest = function (values, pos) {
  5404. var $$ = this,
  5405. minDist = $$.config.point_sensitivity,
  5406. closest;
  5407. // find mouseovering bar
  5408. values.filter(function (v) {
  5409. return v && $$.isBarType(v.id);
  5410. }).forEach(function (v) {
  5411. var shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node();
  5412. if (!closest && $$.isWithinBar(shape)) {
  5413. closest = v;
  5414. }
  5415. });
  5416. // find closest point from non-bar
  5417. values.filter(function (v) {
  5418. return v && !$$.isBarType(v.id);
  5419. }).forEach(function (v) {
  5420. var d = $$.dist(v, pos);
  5421. if (d < minDist) {
  5422. minDist = d;
  5423. closest = v;
  5424. }
  5425. });
  5426. return closest;
  5427. };
  5428. c3_chart_internal_fn.dist = function (data, pos) {
  5429. var $$ = this,
  5430. config = $$.config,
  5431. xIndex = config.axis_rotated ? 1 : 0,
  5432. yIndex = config.axis_rotated ? 0 : 1,
  5433. y = $$.circleY(data, data.index),
  5434. x = $$.x(data.x);
  5435. return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));
  5436. };
  5437. c3_chart_internal_fn.convertValuesToStep = function (values) {
  5438. var converted = [].concat(values),
  5439. i;
  5440. if (!this.isCategorized()) {
  5441. return values;
  5442. }
  5443. for (i = values.length + 1; 0 < i; i--) {
  5444. converted[i] = converted[i - 1];
  5445. }
  5446. converted[0] = {
  5447. x: converted[0].x - 1,
  5448. value: converted[0].value,
  5449. id: converted[0].id
  5450. };
  5451. converted[values.length + 1] = {
  5452. x: converted[values.length].x + 1,
  5453. value: converted[values.length].value,
  5454. id: converted[values.length].id
  5455. };
  5456. return converted;
  5457. };
  5458. c3_chart_internal_fn.updateDataAttributes = function (name, attrs) {
  5459. var $$ = this,
  5460. config = $$.config,
  5461. current = config['data_' + name];
  5462. if (typeof attrs === 'undefined') {
  5463. return current;
  5464. }
  5465. Object.keys(attrs).forEach(function (id) {
  5466. current[id] = attrs[id];
  5467. });
  5468. $$.redraw({ withLegend: true });
  5469. return current;
  5470. };
  5471. c3_chart_internal_fn.load = function (targets, args) {
  5472. var $$ = this;
  5473. if (targets) {
  5474. // filter loading targets if needed
  5475. if (args.filter) {
  5476. targets = targets.filter(args.filter);
  5477. }
  5478. // set type if args.types || args.type specified
  5479. if (args.type || args.types) {
  5480. targets.forEach(function (t) {
  5481. var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;
  5482. $$.setTargetType(t.id, type);
  5483. });
  5484. }
  5485. // Update/Add data
  5486. $$.data.targets.forEach(function (d) {
  5487. for (var i = 0; i < targets.length; i++) {
  5488. if (d.id === targets[i].id) {
  5489. d.values = targets[i].values;
  5490. targets.splice(i, 1);
  5491. break;
  5492. }
  5493. }
  5494. });
  5495. $$.data.targets = $$.data.targets.concat(targets); // add remained
  5496. }
  5497. // Set targets
  5498. $$.updateTargets($$.data.targets);
  5499. // Redraw with new targets
  5500. $$.redraw({ withUpdateOrgXDomain: true, withUpdateXDomain: true, withLegend: true });
  5501. if (args.done) {
  5502. args.done();
  5503. }
  5504. };
  5505. c3_chart_internal_fn.loadFromArgs = function (args) {
  5506. var $$ = this;
  5507. if (args.data) {
  5508. $$.load($$.convertDataToTargets(args.data), args);
  5509. } else if (args.url) {
  5510. $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {
  5511. $$.load($$.convertDataToTargets(data), args);
  5512. });
  5513. } else if (args.json) {
  5514. $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);
  5515. } else if (args.rows) {
  5516. $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);
  5517. } else if (args.columns) {
  5518. $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);
  5519. } else {
  5520. $$.load(null, args);
  5521. }
  5522. };
  5523. c3_chart_internal_fn.unload = function (targetIds, done) {
  5524. var $$ = this;
  5525. if (!done) {
  5526. done = function done() {};
  5527. }
  5528. // filter existing target
  5529. targetIds = targetIds.filter(function (id) {
  5530. return $$.hasTarget($$.data.targets, id);
  5531. });
  5532. // If no target, call done and return
  5533. if (!targetIds || targetIds.length === 0) {
  5534. done();
  5535. return;
  5536. }
  5537. $$.svg.selectAll(targetIds.map(function (id) {
  5538. return $$.selectorTarget(id);
  5539. })).transition().style('opacity', 0).remove().call($$.endall, done);
  5540. targetIds.forEach(function (id) {
  5541. // Reset fadein for future load
  5542. $$.withoutFadeIn[id] = false;
  5543. // Remove target's elements
  5544. if ($$.legend) {
  5545. $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove();
  5546. }
  5547. // Remove target
  5548. $$.data.targets = $$.data.targets.filter(function (t) {
  5549. return t.id !== id;
  5550. });
  5551. });
  5552. };
  5553. c3_chart_internal_fn.getYDomainMin = function (targets) {
  5554. var $$ = this,
  5555. config = $$.config,
  5556. ids = $$.mapToIds(targets),
  5557. ys = $$.getValuesAsIdKeyed(targets),
  5558. j,
  5559. k,
  5560. baseId,
  5561. idsInGroup,
  5562. id,
  5563. hasNegativeValue;
  5564. if (config.data_groups.length > 0) {
  5565. hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  5566. for (j = 0; j < config.data_groups.length; j++) {
  5567. // Determine baseId
  5568. idsInGroup = config.data_groups[j].filter(function (id) {
  5569. return ids.indexOf(id) >= 0;
  5570. });
  5571. if (idsInGroup.length === 0) {
  5572. continue;
  5573. }
  5574. baseId = idsInGroup[0];
  5575. // Consider negative values
  5576. if (hasNegativeValue && ys[baseId]) {
  5577. ys[baseId].forEach(function (v, i) {
  5578. ys[baseId][i] = v < 0 ? v : 0;
  5579. });
  5580. }
  5581. // Compute min
  5582. for (k = 1; k < idsInGroup.length; k++) {
  5583. id = idsInGroup[k];
  5584. if (!ys[id]) {
  5585. continue;
  5586. }
  5587. ys[id].forEach(function (v, i) {
  5588. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) {
  5589. ys[baseId][i] += +v;
  5590. }
  5591. });
  5592. }
  5593. }
  5594. }
  5595. return $$.d3.min(Object.keys(ys).map(function (key) {
  5596. return $$.d3.min(ys[key]);
  5597. }));
  5598. };
  5599. c3_chart_internal_fn.getYDomainMax = function (targets) {
  5600. var $$ = this,
  5601. config = $$.config,
  5602. ids = $$.mapToIds(targets),
  5603. ys = $$.getValuesAsIdKeyed(targets),
  5604. j,
  5605. k,
  5606. baseId,
  5607. idsInGroup,
  5608. id,
  5609. hasPositiveValue;
  5610. if (config.data_groups.length > 0) {
  5611. hasPositiveValue = $$.hasPositiveValueInTargets(targets);
  5612. for (j = 0; j < config.data_groups.length; j++) {
  5613. // Determine baseId
  5614. idsInGroup = config.data_groups[j].filter(function (id) {
  5615. return ids.indexOf(id) >= 0;
  5616. });
  5617. if (idsInGroup.length === 0) {
  5618. continue;
  5619. }
  5620. baseId = idsInGroup[0];
  5621. // Consider positive values
  5622. if (hasPositiveValue && ys[baseId]) {
  5623. ys[baseId].forEach(function (v, i) {
  5624. ys[baseId][i] = v > 0 ? v : 0;
  5625. });
  5626. }
  5627. // Compute max
  5628. for (k = 1; k < idsInGroup.length; k++) {
  5629. id = idsInGroup[k];
  5630. if (!ys[id]) {
  5631. continue;
  5632. }
  5633. ys[id].forEach(function (v, i) {
  5634. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) {
  5635. ys[baseId][i] += +v;
  5636. }
  5637. });
  5638. }
  5639. }
  5640. }
  5641. return $$.d3.max(Object.keys(ys).map(function (key) {
  5642. return $$.d3.max(ys[key]);
  5643. }));
  5644. };
  5645. c3_chart_internal_fn.getYDomain = function (targets, axisId, xDomain) {
  5646. var $$ = this,
  5647. config = $$.config,
  5648. targetsByAxisId = targets.filter(function (t) {
  5649. return $$.axis.getId(t.id) === axisId;
  5650. }),
  5651. yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId,
  5652. yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,
  5653. yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,
  5654. yDomainMin = $$.getYDomainMin(yTargets),
  5655. yDomainMax = $$.getYDomainMax(yTargets),
  5656. domain,
  5657. domainLength,
  5658. padding,
  5659. padding_top,
  5660. padding_bottom,
  5661. center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,
  5662. yDomainAbs,
  5663. lengths,
  5664. diff,
  5665. ratio,
  5666. isAllPositive,
  5667. isAllNegative,
  5668. isZeroBased = $$.hasType('bar', yTargets) && config.bar_zerobased || $$.hasType('area', yTargets) && config.area_zerobased,
  5669. isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,
  5670. showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,
  5671. showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated;
  5672. // MEMO: avoid inverting domain unexpectedly
  5673. yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? yDomainMin < yMax ? yDomainMin : yMax - 10 : yDomainMin;
  5674. yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? yMin < yDomainMax ? yDomainMax : yMin + 10 : yDomainMax;
  5675. if (yTargets.length === 0) {
  5676. // use current domain if target of axisId is none
  5677. return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();
  5678. }
  5679. if (isNaN(yDomainMin)) {
  5680. // set minimum to zero when not number
  5681. yDomainMin = 0;
  5682. }
  5683. if (isNaN(yDomainMax)) {
  5684. // set maximum to have same value as yDomainMin
  5685. yDomainMax = yDomainMin;
  5686. }
  5687. if (yDomainMin === yDomainMax) {
  5688. yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0;
  5689. }
  5690. isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;
  5691. isAllNegative = yDomainMin <= 0 && yDomainMax <= 0;
  5692. // Cancel zerobased if axis_*_min / axis_*_max specified
  5693. if (isValue(yMin) && isAllPositive || isValue(yMax) && isAllNegative) {
  5694. isZeroBased = false;
  5695. }
  5696. // Bar/Area chart should be 0-based if all positive|negative
  5697. if (isZeroBased) {
  5698. if (isAllPositive) {
  5699. yDomainMin = 0;
  5700. }
  5701. if (isAllNegative) {
  5702. yDomainMax = 0;
  5703. }
  5704. }
  5705. domainLength = Math.abs(yDomainMax - yDomainMin);
  5706. padding = padding_top = padding_bottom = domainLength * 0.1;
  5707. if (typeof center !== 'undefined') {
  5708. yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));
  5709. yDomainMax = center + yDomainAbs;
  5710. yDomainMin = center - yDomainAbs;
  5711. }
  5712. // add padding for data label
  5713. if (showHorizontalDataLabel) {
  5714. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');
  5715. diff = diffDomain($$.y.range());
  5716. ratio = [lengths[0] / diff, lengths[1] / diff];
  5717. padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));
  5718. padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));
  5719. } else if (showVerticalDataLabel) {
  5720. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');
  5721. padding_top += $$.axis.convertPixelsToAxisPadding(lengths[1], domainLength);
  5722. padding_bottom += $$.axis.convertPixelsToAxisPadding(lengths[0], domainLength);
  5723. }
  5724. if (axisId === 'y' && notEmpty(config.axis_y_padding)) {
  5725. padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength);
  5726. padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength);
  5727. }
  5728. if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {
  5729. padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength);
  5730. padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength);
  5731. }
  5732. // Bar/Area chart should be 0-based if all positive|negative
  5733. if (isZeroBased) {
  5734. if (isAllPositive) {
  5735. padding_bottom = yDomainMin;
  5736. }
  5737. if (isAllNegative) {
  5738. padding_top = -yDomainMax;
  5739. }
  5740. }
  5741. domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];
  5742. return isInverted ? domain.reverse() : domain;
  5743. };
  5744. c3_chart_internal_fn.getXDomainMin = function (targets) {
  5745. var $$ = this,
  5746. config = $$.config;
  5747. return isDefined(config.axis_x_min) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min : $$.d3.min(targets, function (t) {
  5748. return $$.d3.min(t.values, function (v) {
  5749. return v.x;
  5750. });
  5751. });
  5752. };
  5753. c3_chart_internal_fn.getXDomainMax = function (targets) {
  5754. var $$ = this,
  5755. config = $$.config;
  5756. return isDefined(config.axis_x_max) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max : $$.d3.max(targets, function (t) {
  5757. return $$.d3.max(t.values, function (v) {
  5758. return v.x;
  5759. });
  5760. });
  5761. };
  5762. c3_chart_internal_fn.getXDomainPadding = function (domain) {
  5763. var $$ = this,
  5764. config = $$.config,
  5765. diff = domain[1] - domain[0],
  5766. maxDataCount,
  5767. padding,
  5768. paddingLeft,
  5769. paddingRight;
  5770. if ($$.isCategorized()) {
  5771. padding = 0;
  5772. } else if ($$.hasType('bar')) {
  5773. maxDataCount = $$.getMaxDataCount();
  5774. padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;
  5775. } else {
  5776. padding = diff * 0.01;
  5777. }
  5778. if (_typeof(config.axis_x_padding) === 'object' && notEmpty(config.axis_x_padding)) {
  5779. paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding;
  5780. paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding;
  5781. } else if (typeof config.axis_x_padding === 'number') {
  5782. paddingLeft = paddingRight = config.axis_x_padding;
  5783. } else {
  5784. paddingLeft = paddingRight = padding;
  5785. }
  5786. return { left: paddingLeft, right: paddingRight };
  5787. };
  5788. c3_chart_internal_fn.getXDomain = function (targets) {
  5789. var $$ = this,
  5790. xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],
  5791. firstX = xDomain[0],
  5792. lastX = xDomain[1],
  5793. padding = $$.getXDomainPadding(xDomain),
  5794. min = 0,
  5795. max = 0;
  5796. // show center of x domain if min and max are the same
  5797. if (firstX - lastX === 0 && !$$.isCategorized()) {
  5798. if ($$.isTimeSeries()) {
  5799. firstX = new Date(firstX.getTime() * 0.5);
  5800. lastX = new Date(lastX.getTime() * 1.5);
  5801. } else {
  5802. firstX = firstX === 0 ? 1 : firstX * 0.5;
  5803. lastX = lastX === 0 ? -1 : lastX * 1.5;
  5804. }
  5805. }
  5806. if (firstX || firstX === 0) {
  5807. min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;
  5808. }
  5809. if (lastX || lastX === 0) {
  5810. max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right;
  5811. }
  5812. return [min, max];
  5813. };
  5814. c3_chart_internal_fn.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {
  5815. var $$ = this,
  5816. config = $$.config;
  5817. if (withUpdateOrgXDomain) {
  5818. $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));
  5819. $$.orgXDomain = $$.x.domain();
  5820. if (config.zoom_enabled) {
  5821. $$.zoom.scale($$.x).updateScaleExtent();
  5822. }
  5823. $$.subX.domain($$.x.domain());
  5824. if ($$.brush) {
  5825. $$.brush.scale($$.subX);
  5826. }
  5827. }
  5828. if (withUpdateXDomain) {
  5829. $$.x.domain(domain ? domain : !$$.brush || $$.brush.empty() ? $$.orgXDomain : $$.brush.extent());
  5830. if (config.zoom_enabled) {
  5831. $$.zoom.scale($$.x).updateScaleExtent();
  5832. }
  5833. }
  5834. // Trim domain when too big by zoom mousemove event
  5835. if (withTrim) {
  5836. $$.x.domain($$.trimXDomain($$.x.orgDomain()));
  5837. }
  5838. return $$.x.domain();
  5839. };
  5840. c3_chart_internal_fn.trimXDomain = function (domain) {
  5841. var zoomDomain = this.getZoomDomain(),
  5842. min = zoomDomain[0],
  5843. max = zoomDomain[1];
  5844. if (domain[0] <= min) {
  5845. domain[1] = +domain[1] + (min - domain[0]);
  5846. domain[0] = min;
  5847. }
  5848. if (max <= domain[1]) {
  5849. domain[0] = +domain[0] - (domain[1] - max);
  5850. domain[1] = max;
  5851. }
  5852. return domain;
  5853. };
  5854. c3_chart_internal_fn.drag = function (mouse) {
  5855. var $$ = this,
  5856. config = $$.config,
  5857. main = $$.main,
  5858. d3 = $$.d3;
  5859. var sx, sy, mx, my, minX, maxX, minY, maxY;
  5860. if ($$.hasArcType()) {
  5861. return;
  5862. }
  5863. if (!config.data_selection_enabled) {
  5864. return;
  5865. } // do nothing if not selectable
  5866. if (config.zoom_enabled && !$$.zoom.altDomain) {
  5867. return;
  5868. } // skip if zoomable because of conflict drag dehavior
  5869. if (!config.data_selection_multiple) {
  5870. return;
  5871. } // skip when single selection because drag is used for multiple selection
  5872. sx = $$.dragStart[0];
  5873. sy = $$.dragStart[1];
  5874. mx = mouse[0];
  5875. my = mouse[1];
  5876. minX = Math.min(sx, mx);
  5877. maxX = Math.max(sx, mx);
  5878. minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);
  5879. maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);
  5880. main.select('.' + CLASS.dragarea).attr('x', minX).attr('y', minY).attr('width', maxX - minX).attr('height', maxY - minY);
  5881. // TODO: binary search when multiple xs
  5882. main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).filter(function (d) {
  5883. return config.data_selection_isselectable(d);
  5884. }).each(function (d, i) {
  5885. var shape = d3.select(this),
  5886. isSelected = shape.classed(CLASS.SELECTED),
  5887. isIncluded = shape.classed(CLASS.INCLUDED),
  5888. _x,
  5889. _y,
  5890. _w,
  5891. _h,
  5892. toggle,
  5893. isWithin = false,
  5894. box;
  5895. if (shape.classed(CLASS.circle)) {
  5896. _x = shape.attr("cx") * 1;
  5897. _y = shape.attr("cy") * 1;
  5898. toggle = $$.togglePoint;
  5899. isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;
  5900. } else if (shape.classed(CLASS.bar)) {
  5901. box = getPathBox(this);
  5902. _x = box.x;
  5903. _y = box.y;
  5904. _w = box.width;
  5905. _h = box.height;
  5906. toggle = $$.togglePath;
  5907. isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);
  5908. } else {
  5909. // line/area selection not supported yet
  5910. return;
  5911. }
  5912. if (isWithin ^ isIncluded) {
  5913. shape.classed(CLASS.INCLUDED, !isIncluded);
  5914. // TODO: included/unincluded callback here
  5915. shape.classed(CLASS.SELECTED, !isSelected);
  5916. toggle.call($$, !isSelected, shape, d, i);
  5917. }
  5918. });
  5919. };
  5920. c3_chart_internal_fn.dragstart = function (mouse) {
  5921. var $$ = this,
  5922. config = $$.config;
  5923. if ($$.hasArcType()) {
  5924. return;
  5925. }
  5926. if (!config.data_selection_enabled) {
  5927. return;
  5928. } // do nothing if not selectable
  5929. $$.dragStart = mouse;
  5930. $$.main.select('.' + CLASS.chart).append('rect').attr('class', CLASS.dragarea).style('opacity', 0.1);
  5931. $$.dragging = true;
  5932. };
  5933. c3_chart_internal_fn.dragend = function () {
  5934. var $$ = this,
  5935. config = $$.config;
  5936. if ($$.hasArcType()) {
  5937. return;
  5938. }
  5939. if (!config.data_selection_enabled) {
  5940. return;
  5941. } // do nothing if not selectable
  5942. $$.main.select('.' + CLASS.dragarea).transition().duration(100).style('opacity', 0).remove();
  5943. $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);
  5944. $$.dragging = false;
  5945. };
  5946. c3_chart_internal_fn.getYFormat = function (forArc) {
  5947. var $$ = this,
  5948. formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,
  5949. formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;
  5950. return function (v, ratio, id) {
  5951. var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;
  5952. return format.call($$, v, ratio);
  5953. };
  5954. };
  5955. c3_chart_internal_fn.yFormat = function (v) {
  5956. var $$ = this,
  5957. config = $$.config,
  5958. format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat;
  5959. return format(v);
  5960. };
  5961. c3_chart_internal_fn.y2Format = function (v) {
  5962. var $$ = this,
  5963. config = $$.config,
  5964. format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat;
  5965. return format(v);
  5966. };
  5967. c3_chart_internal_fn.defaultValueFormat = function (v) {
  5968. return isValue(v) ? +v : "";
  5969. };
  5970. c3_chart_internal_fn.defaultArcValueFormat = function (v, ratio) {
  5971. return (ratio * 100).toFixed(1) + '%';
  5972. };
  5973. c3_chart_internal_fn.dataLabelFormat = function (targetId) {
  5974. var $$ = this,
  5975. data_labels = $$.config.data_labels,
  5976. format,
  5977. defaultFormat = function defaultFormat(v) {
  5978. return isValue(v) ? +v : "";
  5979. };
  5980. // find format according to axis id
  5981. if (typeof data_labels.format === 'function') {
  5982. format = data_labels.format;
  5983. } else if (_typeof(data_labels.format) === 'object') {
  5984. if (data_labels.format[targetId]) {
  5985. format = data_labels.format[targetId] === true ? defaultFormat : data_labels.format[targetId];
  5986. } else {
  5987. format = function format() {
  5988. return '';
  5989. };
  5990. }
  5991. } else {
  5992. format = defaultFormat;
  5993. }
  5994. return format;
  5995. };
  5996. c3_chart_internal_fn.initGrid = function () {
  5997. var $$ = this,
  5998. config = $$.config,
  5999. d3 = $$.d3;
  6000. $$.grid = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid);
  6001. if (config.grid_x_show) {
  6002. $$.grid.append("g").attr("class", CLASS.xgrids);
  6003. }
  6004. if (config.grid_y_show) {
  6005. $$.grid.append('g').attr('class', CLASS.ygrids);
  6006. }
  6007. if (config.grid_focus_show) {
  6008. $$.grid.append('g').attr("class", CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus);
  6009. }
  6010. $$.xgrid = d3.selectAll([]);
  6011. if (!config.grid_lines_front) {
  6012. $$.initGridLines();
  6013. }
  6014. };
  6015. c3_chart_internal_fn.initGridLines = function () {
  6016. var $$ = this,
  6017. d3 = $$.d3;
  6018. $$.gridLines = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines);
  6019. $$.gridLines.append('g').attr("class", CLASS.xgridLines);
  6020. $$.gridLines.append('g').attr('class', CLASS.ygridLines);
  6021. $$.xgridLines = d3.selectAll([]);
  6022. };
  6023. c3_chart_internal_fn.updateXGrid = function (withoutUpdate) {
  6024. var $$ = this,
  6025. config = $$.config,
  6026. d3 = $$.d3,
  6027. xgridData = $$.generateGridData(config.grid_x_type, $$.x),
  6028. tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;
  6029. $$.xgridAttr = config.axis_rotated ? {
  6030. 'x1': 0,
  6031. 'x2': $$.width,
  6032. 'y1': function y1(d) {
  6033. return $$.x(d) - tickOffset;
  6034. },
  6035. 'y2': function y2(d) {
  6036. return $$.x(d) - tickOffset;
  6037. }
  6038. } : {
  6039. 'x1': function x1(d) {
  6040. return $$.x(d) + tickOffset;
  6041. },
  6042. 'x2': function x2(d) {
  6043. return $$.x(d) + tickOffset;
  6044. },
  6045. 'y1': 0,
  6046. 'y2': $$.height
  6047. };
  6048. $$.xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid).data(xgridData);
  6049. $$.xgrid.enter().append('line').attr("class", CLASS.xgrid);
  6050. if (!withoutUpdate) {
  6051. $$.xgrid.attr($$.xgridAttr).style("opacity", function () {
  6052. return +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1') === (config.axis_rotated ? $$.height : 0) ? 0 : 1;
  6053. });
  6054. }
  6055. $$.xgrid.exit().remove();
  6056. };
  6057. c3_chart_internal_fn.updateYGrid = function () {
  6058. var $$ = this,
  6059. config = $$.config,
  6060. gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);
  6061. $$.ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid).data(gridValues);
  6062. $$.ygrid.enter().append('line').attr('class', CLASS.ygrid);
  6063. $$.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);
  6064. $$.ygrid.exit().remove();
  6065. $$.smoothLines($$.ygrid, 'grid');
  6066. };
  6067. c3_chart_internal_fn.gridTextAnchor = function (d) {
  6068. return d.position ? d.position : "end";
  6069. };
  6070. c3_chart_internal_fn.gridTextDx = function (d) {
  6071. return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4;
  6072. };
  6073. c3_chart_internal_fn.xGridTextX = function (d) {
  6074. return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0;
  6075. };
  6076. c3_chart_internal_fn.yGridTextX = function (d) {
  6077. return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width;
  6078. };
  6079. c3_chart_internal_fn.updateGrid = function (duration) {
  6080. var $$ = this,
  6081. main = $$.main,
  6082. config = $$.config,
  6083. xgridLine,
  6084. ygridLine,
  6085. yv;
  6086. // hide if arc type
  6087. $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  6088. main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  6089. if (config.grid_x_show) {
  6090. $$.updateXGrid();
  6091. }
  6092. $$.xgridLines = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine).data(config.grid_x_lines);
  6093. // enter
  6094. xgridLine = $$.xgridLines.enter().append('g').attr("class", function (d) {
  6095. return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '');
  6096. });
  6097. xgridLine.append('line').style("opacity", 0);
  6098. xgridLine.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "" : "rotate(-90)").attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0);
  6099. // udpate
  6100. // done in d3.transition() of the end of this function
  6101. // exit
  6102. $$.xgridLines.exit().transition().duration(duration).style("opacity", 0).remove();
  6103. // Y-Grid
  6104. if (config.grid_y_show) {
  6105. $$.updateYGrid();
  6106. }
  6107. $$.ygridLines = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine).data(config.grid_y_lines);
  6108. // enter
  6109. ygridLine = $$.ygridLines.enter().append('g').attr("class", function (d) {
  6110. return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '');
  6111. });
  6112. ygridLine.append('line').style("opacity", 0);
  6113. ygridLine.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "rotate(-90)" : "").attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0);
  6114. // update
  6115. yv = $$.yv.bind($$);
  6116. $$.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);
  6117. $$.ygridLines.select('text').transition().duration(duration).attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr("y", yv).text(function (d) {
  6118. return d.text;
  6119. }).style("opacity", 1);
  6120. // exit
  6121. $$.ygridLines.exit().transition().duration(duration).style("opacity", 0).remove();
  6122. };
  6123. c3_chart_internal_fn.redrawGrid = function (withTransition) {
  6124. var $$ = this,
  6125. config = $$.config,
  6126. xv = $$.xv.bind($$),
  6127. lines = $$.xgridLines.select('line'),
  6128. texts = $$.xgridLines.select('text');
  6129. return [(withTransition ? lines.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() : texts).attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr("y", xv).text(function (d) {
  6130. return d.text;
  6131. }).style("opacity", 1)];
  6132. };
  6133. c3_chart_internal_fn.showXGridFocus = function (selectedData) {
  6134. var $$ = this,
  6135. config = $$.config,
  6136. dataToShow = selectedData.filter(function (d) {
  6137. return d && isValue(d.value);
  6138. }),
  6139. focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),
  6140. xx = $$.xx.bind($$);
  6141. if (!config.tooltip_show) {
  6142. return;
  6143. }
  6144. // Hide when scatter plot exists
  6145. if ($$.hasType('scatter') || $$.hasArcType()) {
  6146. return;
  6147. }
  6148. focusEl.style("visibility", "visible").data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx);
  6149. $$.smoothLines(focusEl, 'grid');
  6150. };
  6151. c3_chart_internal_fn.hideXGridFocus = function () {
  6152. this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  6153. };
  6154. c3_chart_internal_fn.updateXgridFocus = function () {
  6155. var $$ = this,
  6156. config = $$.config;
  6157. $$.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);
  6158. };
  6159. c3_chart_internal_fn.generateGridData = function (type, scale) {
  6160. var $$ = this,
  6161. gridData = [],
  6162. xDomain,
  6163. firstYear,
  6164. lastYear,
  6165. i,
  6166. tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size();
  6167. if (type === 'year') {
  6168. xDomain = $$.getXDomain();
  6169. firstYear = xDomain[0].getFullYear();
  6170. lastYear = xDomain[1].getFullYear();
  6171. for (i = firstYear; i <= lastYear; i++) {
  6172. gridData.push(new Date(i + '-01-01 00:00:00'));
  6173. }
  6174. } else {
  6175. gridData = scale.ticks(10);
  6176. if (gridData.length > tickNum) {
  6177. // use only int
  6178. gridData = gridData.filter(function (d) {
  6179. return ("" + d).indexOf('.') < 0;
  6180. });
  6181. }
  6182. }
  6183. return gridData;
  6184. };
  6185. c3_chart_internal_fn.getGridFilterToRemove = function (params) {
  6186. return params ? function (line) {
  6187. var found = false;
  6188. [].concat(params).forEach(function (param) {
  6189. if ('value' in param && line.value === param.value || 'class' in param && line['class'] === param['class']) {
  6190. found = true;
  6191. }
  6192. });
  6193. return found;
  6194. } : function () {
  6195. return true;
  6196. };
  6197. };
  6198. c3_chart_internal_fn.removeGridLines = function (params, forX) {
  6199. var $$ = this,
  6200. config = $$.config,
  6201. toRemove = $$.getGridFilterToRemove(params),
  6202. toShow = function toShow(line) {
  6203. return !toRemove(line);
  6204. },
  6205. classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,
  6206. classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;
  6207. $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove).transition().duration(config.transition_duration).style('opacity', 0).remove();
  6208. if (forX) {
  6209. config.grid_x_lines = config.grid_x_lines.filter(toShow);
  6210. } else {
  6211. config.grid_y_lines = config.grid_y_lines.filter(toShow);
  6212. }
  6213. };
  6214. c3_chart_internal_fn.initEventRect = function () {
  6215. var $$ = this;
  6216. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.eventRects).style('fill-opacity', 0);
  6217. };
  6218. c3_chart_internal_fn.redrawEventRect = function () {
  6219. var $$ = this,
  6220. config = $$.config,
  6221. eventRectUpdate,
  6222. maxDataCountTarget,
  6223. isMultipleX = $$.isMultipleX();
  6224. // rects for mouseover
  6225. var eventRects = $$.main.select('.' + CLASS.eventRects).style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null).classed(CLASS.eventRectsMultiple, isMultipleX).classed(CLASS.eventRectsSingle, !isMultipleX);
  6226. // clear old rects
  6227. eventRects.selectAll('.' + CLASS.eventRect).remove();
  6228. // open as public variable
  6229. $$.eventRect = eventRects.selectAll('.' + CLASS.eventRect);
  6230. if (isMultipleX) {
  6231. eventRectUpdate = $$.eventRect.data([0]);
  6232. // enter : only one rect will be added
  6233. $$.generateEventRectsForMultipleXs(eventRectUpdate.enter());
  6234. // update
  6235. $$.updateEventRect(eventRectUpdate);
  6236. // exit : not needed because always only one rect exists
  6237. } else {
  6238. // Set data and update $$.eventRect
  6239. maxDataCountTarget = $$.getMaxDataCountTarget($$.data.targets);
  6240. eventRects.datum(maxDataCountTarget ? maxDataCountTarget.values : []);
  6241. $$.eventRect = eventRects.selectAll('.' + CLASS.eventRect);
  6242. eventRectUpdate = $$.eventRect.data(function (d) {
  6243. return d;
  6244. });
  6245. // enter
  6246. $$.generateEventRectsForSingleX(eventRectUpdate.enter());
  6247. // update
  6248. $$.updateEventRect(eventRectUpdate);
  6249. // exit
  6250. eventRectUpdate.exit().remove();
  6251. }
  6252. };
  6253. c3_chart_internal_fn.updateEventRect = function (eventRectUpdate) {
  6254. var $$ = this,
  6255. config = $$.config,
  6256. x,
  6257. y,
  6258. w,
  6259. h,
  6260. rectW,
  6261. rectX;
  6262. // set update selection if null
  6263. eventRectUpdate = eventRectUpdate || $$.eventRect.data(function (d) {
  6264. return d;
  6265. });
  6266. if ($$.isMultipleX()) {
  6267. // TODO: rotated not supported yet
  6268. x = 0;
  6269. y = 0;
  6270. w = $$.width;
  6271. h = $$.height;
  6272. } else {
  6273. if (($$.isCustomX() || $$.isTimeSeries()) && !$$.isCategorized()) {
  6274. // update index for x that is used by prevX and nextX
  6275. $$.updateXs();
  6276. rectW = function rectW(d) {
  6277. var prevX = $$.getPrevX(d.index),
  6278. nextX = $$.getNextX(d.index);
  6279. // if there this is a single data point make the eventRect full width (or height)
  6280. if (prevX === null && nextX === null) {
  6281. return config.axis_rotated ? $$.height : $$.width;
  6282. }
  6283. if (prevX === null) {
  6284. prevX = $$.x.domain()[0];
  6285. }
  6286. if (nextX === null) {
  6287. nextX = $$.x.domain()[1];
  6288. }
  6289. return Math.max(0, ($$.x(nextX) - $$.x(prevX)) / 2);
  6290. };
  6291. rectX = function rectX(d) {
  6292. var prevX = $$.getPrevX(d.index),
  6293. nextX = $$.getNextX(d.index),
  6294. thisX = $$.data.xs[d.id][d.index];
  6295. // if there this is a single data point position the eventRect at 0
  6296. if (prevX === null && nextX === null) {
  6297. return 0;
  6298. }
  6299. if (prevX === null) {
  6300. prevX = $$.x.domain()[0];
  6301. }
  6302. return ($$.x(thisX) + $$.x(prevX)) / 2;
  6303. };
  6304. } else {
  6305. rectW = $$.getEventRectWidth();
  6306. rectX = function rectX(d) {
  6307. return $$.x(d.x) - rectW / 2;
  6308. };
  6309. }
  6310. x = config.axis_rotated ? 0 : rectX;
  6311. y = config.axis_rotated ? rectX : 0;
  6312. w = config.axis_rotated ? $$.width : rectW;
  6313. h = config.axis_rotated ? rectW : $$.height;
  6314. }
  6315. eventRectUpdate.attr('class', $$.classEvent.bind($$)).attr("x", x).attr("y", y).attr("width", w).attr("height", h);
  6316. };
  6317. c3_chart_internal_fn.generateEventRectsForSingleX = function (eventRectEnter) {
  6318. var $$ = this,
  6319. d3 = $$.d3,
  6320. config = $$.config;
  6321. eventRectEnter.append("rect").attr("class", $$.classEvent.bind($$)).style("cursor", config.data_selection_enabled && config.data_selection_grouped ? "pointer" : null).on('mouseover', function (d) {
  6322. var index = d.index;
  6323. if ($$.dragging || $$.flowing) {
  6324. return;
  6325. } // do nothing while dragging/flowing
  6326. if ($$.hasArcType()) {
  6327. return;
  6328. }
  6329. // Expand shapes for selection
  6330. if (config.point_focus_expand_enabled) {
  6331. $$.expandCircles(index, null, true);
  6332. }
  6333. $$.expandBars(index, null, true);
  6334. // Call event handler
  6335. $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
  6336. config.data_onmouseover.call($$.api, d);
  6337. });
  6338. }).on('mouseout', function (d) {
  6339. var index = d.index;
  6340. if (!$$.config) {
  6341. return;
  6342. } // chart is destroyed
  6343. if ($$.hasArcType()) {
  6344. return;
  6345. }
  6346. $$.hideXGridFocus();
  6347. $$.hideTooltip();
  6348. // Undo expanded shapes
  6349. $$.unexpandCircles();
  6350. $$.unexpandBars();
  6351. // Call event handler
  6352. $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
  6353. config.data_onmouseout.call($$.api, d);
  6354. });
  6355. }).on('mousemove', function (d) {
  6356. var selectedData,
  6357. index = d.index,
  6358. eventRect = $$.svg.select('.' + CLASS.eventRect + '-' + index);
  6359. if ($$.dragging || $$.flowing) {
  6360. return;
  6361. } // do nothing while dragging/flowing
  6362. if ($$.hasArcType()) {
  6363. return;
  6364. }
  6365. if ($$.isStepType(d) && $$.config.line_step_type === 'step-after' && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
  6366. index -= 1;
  6367. }
  6368. // Show tooltip
  6369. selectedData = $$.filterTargetsToShow($$.data.targets).map(function (t) {
  6370. return $$.addName($$.getValueOnIndex(t.values, index));
  6371. });
  6372. if (config.tooltip_grouped) {
  6373. $$.showTooltip(selectedData, this);
  6374. $$.showXGridFocus(selectedData);
  6375. }
  6376. if (config.tooltip_grouped && (!config.data_selection_enabled || config.data_selection_grouped)) {
  6377. return;
  6378. }
  6379. $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function () {
  6380. d3.select(this).classed(CLASS.EXPANDED, true);
  6381. if (config.data_selection_enabled) {
  6382. eventRect.style('cursor', config.data_selection_grouped ? 'pointer' : null);
  6383. }
  6384. if (!config.tooltip_grouped) {
  6385. $$.hideXGridFocus();
  6386. $$.hideTooltip();
  6387. if (!config.data_selection_grouped) {
  6388. $$.unexpandCircles(index);
  6389. $$.unexpandBars(index);
  6390. }
  6391. }
  6392. }).filter(function (d) {
  6393. return $$.isWithinShape(this, d);
  6394. }).each(function (d) {
  6395. if (config.data_selection_enabled && (config.data_selection_grouped || config.data_selection_isselectable(d))) {
  6396. eventRect.style('cursor', 'pointer');
  6397. }
  6398. if (!config.tooltip_grouped) {
  6399. $$.showTooltip([d], this);
  6400. $$.showXGridFocus([d]);
  6401. if (config.point_focus_expand_enabled) {
  6402. $$.expandCircles(index, d.id, true);
  6403. }
  6404. $$.expandBars(index, d.id, true);
  6405. }
  6406. });
  6407. }).on('click', function (d) {
  6408. var index = d.index;
  6409. if ($$.hasArcType() || !$$.toggleShape) {
  6410. return;
  6411. }
  6412. if ($$.cancelClick) {
  6413. $$.cancelClick = false;
  6414. return;
  6415. }
  6416. if ($$.isStepType(d) && config.line_step_type === 'step-after' && d3.mouse(this)[0] < $$.x($$.getXValue(d.id, index))) {
  6417. index -= 1;
  6418. }
  6419. $$.main.selectAll('.' + CLASS.shape + '-' + index).each(function (d) {
  6420. if (config.data_selection_grouped || $$.isWithinShape(this, d)) {
  6421. $$.toggleShape(this, d, index);
  6422. $$.config.data_onclick.call($$.api, d, this);
  6423. }
  6424. });
  6425. }).call(config.data_selection_draggable && $$.drag ? d3.behavior.drag().origin(Object).on('drag', function () {
  6426. $$.drag(d3.mouse(this));
  6427. }).on('dragstart', function () {
  6428. $$.dragstart(d3.mouse(this));
  6429. }).on('dragend', function () {
  6430. $$.dragend();
  6431. }) : function () {});
  6432. };
  6433. c3_chart_internal_fn.generateEventRectsForMultipleXs = function (eventRectEnter) {
  6434. var $$ = this,
  6435. d3 = $$.d3,
  6436. config = $$.config;
  6437. function mouseout() {
  6438. $$.svg.select('.' + CLASS.eventRect).style('cursor', null);
  6439. $$.hideXGridFocus();
  6440. $$.hideTooltip();
  6441. $$.unexpandCircles();
  6442. $$.unexpandBars();
  6443. }
  6444. eventRectEnter.append('rect').attr('x', 0).attr('y', 0).attr('width', $$.width).attr('height', $$.height).attr('class', CLASS.eventRect).on('mouseout', function () {
  6445. if (!$$.config) {
  6446. return;
  6447. } // chart is destroyed
  6448. if ($$.hasArcType()) {
  6449. return;
  6450. }
  6451. mouseout();
  6452. }).on('mousemove', function () {
  6453. var targetsToShow = $$.filterTargetsToShow($$.data.targets);
  6454. var mouse, closest, sameXData, selectedData;
  6455. if ($$.dragging) {
  6456. return;
  6457. } // do nothing when dragging
  6458. if ($$.hasArcType(targetsToShow)) {
  6459. return;
  6460. }
  6461. mouse = d3.mouse(this);
  6462. closest = $$.findClosestFromTargets(targetsToShow, mouse);
  6463. if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id)) {
  6464. config.data_onmouseout.call($$.api, $$.mouseover);
  6465. $$.mouseover = undefined;
  6466. }
  6467. if (!closest) {
  6468. mouseout();
  6469. return;
  6470. }
  6471. if ($$.isScatterType(closest) || !config.tooltip_grouped) {
  6472. sameXData = [closest];
  6473. } else {
  6474. sameXData = $$.filterByX(targetsToShow, closest.x);
  6475. }
  6476. // show tooltip when cursor is close to some point
  6477. selectedData = sameXData.map(function (d) {
  6478. return $$.addName(d);
  6479. });
  6480. $$.showTooltip(selectedData, this);
  6481. // expand points
  6482. if (config.point_focus_expand_enabled) {
  6483. $$.expandCircles(closest.index, closest.id, true);
  6484. }
  6485. $$.expandBars(closest.index, closest.id, true);
  6486. // Show xgrid focus line
  6487. $$.showXGridFocus(selectedData);
  6488. // Show cursor as pointer if point is close to mouse position
  6489. if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
  6490. $$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer');
  6491. if (!$$.mouseover) {
  6492. config.data_onmouseover.call($$.api, closest);
  6493. $$.mouseover = closest;
  6494. }
  6495. }
  6496. }).on('click', function () {
  6497. var targetsToShow = $$.filterTargetsToShow($$.data.targets);
  6498. var mouse, closest;
  6499. if ($$.hasArcType(targetsToShow)) {
  6500. return;
  6501. }
  6502. mouse = d3.mouse(this);
  6503. closest = $$.findClosestFromTargets(targetsToShow, mouse);
  6504. if (!closest) {
  6505. return;
  6506. }
  6507. // select if selection enabled
  6508. if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
  6509. $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(closest.id)).selectAll('.' + CLASS.shape + '-' + closest.index).each(function () {
  6510. if (config.data_selection_grouped || $$.isWithinShape(this, closest)) {
  6511. $$.toggleShape(this, closest, closest.index);
  6512. $$.config.data_onclick.call($$.api, closest, this);
  6513. }
  6514. });
  6515. }
  6516. }).call(config.data_selection_draggable && $$.drag ? d3.behavior.drag().origin(Object).on('drag', function () {
  6517. $$.drag(d3.mouse(this));
  6518. }).on('dragstart', function () {
  6519. $$.dragstart(d3.mouse(this));
  6520. }).on('dragend', function () {
  6521. $$.dragend();
  6522. }) : function () {});
  6523. };
  6524. c3_chart_internal_fn.dispatchEvent = function (type, index, mouse) {
  6525. var $$ = this,
  6526. selector = '.' + CLASS.eventRect + (!$$.isMultipleX() ? '-' + index : ''),
  6527. eventRect = $$.main.select(selector).node(),
  6528. box = eventRect.getBoundingClientRect(),
  6529. x = box.left + (mouse ? mouse[0] : 0),
  6530. y = box.top + (mouse ? mouse[1] : 0),
  6531. event = document.createEvent("MouseEvents");
  6532. event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null);
  6533. eventRect.dispatchEvent(event);
  6534. };
  6535. c3_chart_internal_fn.initLegend = function () {
  6536. var $$ = this;
  6537. $$.legendItemTextBox = {};
  6538. $$.legendHasRendered = false;
  6539. $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend'));
  6540. if (!$$.config.legend_show) {
  6541. $$.legend.style('visibility', 'hidden');
  6542. $$.hiddenLegendIds = $$.mapToIds($$.data.targets);
  6543. return;
  6544. }
  6545. // MEMO: call here to update legend box and tranlate for all
  6546. // MEMO: translate will be upated by this, so transform not needed in updateLegend()
  6547. $$.updateLegendWithDefaults();
  6548. };
  6549. c3_chart_internal_fn.updateLegendWithDefaults = function () {
  6550. var $$ = this;
  6551. $$.updateLegend($$.mapToIds($$.data.targets), { withTransform: false, withTransitionForTransform: false, withTransition: false });
  6552. };
  6553. c3_chart_internal_fn.updateSizeForLegend = function (legendHeight, legendWidth) {
  6554. var $$ = this,
  6555. config = $$.config,
  6556. insetLegendPosition = {
  6557. top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y,
  6558. left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5
  6559. };
  6560. $$.margin3 = {
  6561. top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight,
  6562. right: NaN,
  6563. bottom: 0,
  6564. left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0
  6565. };
  6566. };
  6567. c3_chart_internal_fn.transformLegend = function (withTransition) {
  6568. var $$ = this;
  6569. (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend'));
  6570. };
  6571. c3_chart_internal_fn.updateLegendStep = function (step) {
  6572. this.legendStep = step;
  6573. };
  6574. c3_chart_internal_fn.updateLegendItemWidth = function (w) {
  6575. this.legendItemWidth = w;
  6576. };
  6577. c3_chart_internal_fn.updateLegendItemHeight = function (h) {
  6578. this.legendItemHeight = h;
  6579. };
  6580. c3_chart_internal_fn.getLegendWidth = function () {
  6581. var $$ = this;
  6582. return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0;
  6583. };
  6584. c3_chart_internal_fn.getLegendHeight = function () {
  6585. var $$ = this,
  6586. h = 0;
  6587. if ($$.config.legend_show) {
  6588. if ($$.isLegendRight) {
  6589. h = $$.currentHeight;
  6590. } else {
  6591. h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);
  6592. }
  6593. }
  6594. return h;
  6595. };
  6596. c3_chart_internal_fn.opacityForLegend = function (legendItem) {
  6597. return legendItem.classed(CLASS.legendItemHidden) ? null : 1;
  6598. };
  6599. c3_chart_internal_fn.opacityForUnfocusedLegend = function (legendItem) {
  6600. return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3;
  6601. };
  6602. c3_chart_internal_fn.toggleFocusLegend = function (targetIds, focus) {
  6603. var $$ = this;
  6604. targetIds = $$.mapToTargetIds(targetIds);
  6605. $$.legend.selectAll('.' + CLASS.legendItem).filter(function (id) {
  6606. return targetIds.indexOf(id) >= 0;
  6607. }).classed(CLASS.legendItemFocused, focus).transition().duration(100).style('opacity', function () {
  6608. var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;
  6609. return opacity.call($$, $$.d3.select(this));
  6610. });
  6611. };
  6612. c3_chart_internal_fn.revertLegend = function () {
  6613. var $$ = this,
  6614. d3 = $$.d3;
  6615. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemFocused, false).transition().duration(100).style('opacity', function () {
  6616. return $$.opacityForLegend(d3.select(this));
  6617. });
  6618. };
  6619. c3_chart_internal_fn.showLegend = function (targetIds) {
  6620. var $$ = this,
  6621. config = $$.config;
  6622. if (!config.legend_show) {
  6623. config.legend_show = true;
  6624. $$.legend.style('visibility', 'visible');
  6625. if (!$$.legendHasRendered) {
  6626. $$.updateLegendWithDefaults();
  6627. }
  6628. }
  6629. $$.removeHiddenLegendIds(targetIds);
  6630. $$.legend.selectAll($$.selectorLegends(targetIds)).style('visibility', 'visible').transition().style('opacity', function () {
  6631. return $$.opacityForLegend($$.d3.select(this));
  6632. });
  6633. };
  6634. c3_chart_internal_fn.hideLegend = function (targetIds) {
  6635. var $$ = this,
  6636. config = $$.config;
  6637. if (config.legend_show && isEmpty(targetIds)) {
  6638. config.legend_show = false;
  6639. $$.legend.style('visibility', 'hidden');
  6640. }
  6641. $$.addHiddenLegendIds(targetIds);
  6642. $$.legend.selectAll($$.selectorLegends(targetIds)).style('opacity', 0).style('visibility', 'hidden');
  6643. };
  6644. c3_chart_internal_fn.clearLegendItemTextBoxCache = function () {
  6645. this.legendItemTextBox = {};
  6646. };
  6647. c3_chart_internal_fn.updateLegend = function (targetIds, options, transitions) {
  6648. var $$ = this,
  6649. config = $$.config;
  6650. var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile;
  6651. var paddingTop = 4,
  6652. paddingRight = 10,
  6653. maxWidth = 0,
  6654. maxHeight = 0,
  6655. posMin = 10,
  6656. tileWidth = config.legend_item_tile_width + 5;
  6657. var l,
  6658. totalLength = 0,
  6659. offsets = {},
  6660. widths = {},
  6661. heights = {},
  6662. margins = [0],
  6663. steps = {},
  6664. step = 0;
  6665. var withTransition, withTransitionForTransform;
  6666. var texts, rects, tiles, background;
  6667. // Skip elements when their name is set to null
  6668. targetIds = targetIds.filter(function (id) {
  6669. return !isDefined(config.data_names[id]) || config.data_names[id] !== null;
  6670. });
  6671. options = options || {};
  6672. withTransition = getOption(options, "withTransition", true);
  6673. withTransitionForTransform = getOption(options, "withTransitionForTransform", true);
  6674. function getTextBox(textElement, id) {
  6675. if (!$$.legendItemTextBox[id]) {
  6676. $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement);
  6677. }
  6678. return $$.legendItemTextBox[id];
  6679. }
  6680. function updatePositions(textElement, id, index) {
  6681. var reset = index === 0,
  6682. isLast = index === targetIds.length - 1,
  6683. box = getTextBox(textElement, id),
  6684. itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + config.legend_padding,
  6685. itemHeight = box.height + paddingTop,
  6686. itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,
  6687. areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(),
  6688. margin,
  6689. maxLength;
  6690. // MEMO: care about condifion of step, totalLength
  6691. function updateValues(id, withoutStep) {
  6692. if (!withoutStep) {
  6693. margin = (areaLength - totalLength - itemLength) / 2;
  6694. if (margin < posMin) {
  6695. margin = (areaLength - itemLength) / 2;
  6696. totalLength = 0;
  6697. step++;
  6698. }
  6699. }
  6700. steps[id] = step;
  6701. margins[step] = $$.isLegendInset ? 10 : margin;
  6702. offsets[id] = totalLength;
  6703. totalLength += itemLength;
  6704. }
  6705. if (reset) {
  6706. totalLength = 0;
  6707. step = 0;
  6708. maxWidth = 0;
  6709. maxHeight = 0;
  6710. }
  6711. if (config.legend_show && !$$.isLegendToShow(id)) {
  6712. widths[id] = heights[id] = steps[id] = offsets[id] = 0;
  6713. return;
  6714. }
  6715. widths[id] = itemWidth;
  6716. heights[id] = itemHeight;
  6717. if (!maxWidth || itemWidth >= maxWidth) {
  6718. maxWidth = itemWidth;
  6719. }
  6720. if (!maxHeight || itemHeight >= maxHeight) {
  6721. maxHeight = itemHeight;
  6722. }
  6723. maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;
  6724. if (config.legend_equally) {
  6725. Object.keys(widths).forEach(function (id) {
  6726. widths[id] = maxWidth;
  6727. });
  6728. Object.keys(heights).forEach(function (id) {
  6729. heights[id] = maxHeight;
  6730. });
  6731. margin = (areaLength - maxLength * targetIds.length) / 2;
  6732. if (margin < posMin) {
  6733. totalLength = 0;
  6734. step = 0;
  6735. targetIds.forEach(function (id) {
  6736. updateValues(id);
  6737. });
  6738. } else {
  6739. updateValues(id, true);
  6740. }
  6741. } else {
  6742. updateValues(id);
  6743. }
  6744. }
  6745. if ($$.isLegendInset) {
  6746. step = config.legend_inset_step ? config.legend_inset_step : targetIds.length;
  6747. $$.updateLegendStep(step);
  6748. }
  6749. if ($$.isLegendRight) {
  6750. xForLegend = function xForLegend(id) {
  6751. return maxWidth * steps[id];
  6752. };
  6753. yForLegend = function yForLegend(id) {
  6754. return margins[steps[id]] + offsets[id];
  6755. };
  6756. } else if ($$.isLegendInset) {
  6757. xForLegend = function xForLegend(id) {
  6758. return maxWidth * steps[id] + 10;
  6759. };
  6760. yForLegend = function yForLegend(id) {
  6761. return margins[steps[id]] + offsets[id];
  6762. };
  6763. } else {
  6764. xForLegend = function xForLegend(id) {
  6765. return margins[steps[id]] + offsets[id];
  6766. };
  6767. yForLegend = function yForLegend(id) {
  6768. return maxHeight * steps[id];
  6769. };
  6770. }
  6771. xForLegendText = function xForLegendText(id, i) {
  6772. return xForLegend(id, i) + 4 + config.legend_item_tile_width;
  6773. };
  6774. yForLegendText = function yForLegendText(id, i) {
  6775. return yForLegend(id, i) + 9;
  6776. };
  6777. xForLegendRect = function xForLegendRect(id, i) {
  6778. return xForLegend(id, i);
  6779. };
  6780. yForLegendRect = function yForLegendRect(id, i) {
  6781. return yForLegend(id, i) - 5;
  6782. };
  6783. x1ForLegendTile = function x1ForLegendTile(id, i) {
  6784. return xForLegend(id, i) - 2;
  6785. };
  6786. x2ForLegendTile = function x2ForLegendTile(id, i) {
  6787. return xForLegend(id, i) - 2 + config.legend_item_tile_width;
  6788. };
  6789. yForLegendTile = function yForLegendTile(id, i) {
  6790. return yForLegend(id, i) + 4;
  6791. };
  6792. // Define g for legend area
  6793. l = $$.legend.selectAll('.' + CLASS.legendItem).data(targetIds).enter().append('g').attr('class', function (id) {
  6794. return $$.generateClass(CLASS.legendItem, id);
  6795. }).style('visibility', function (id) {
  6796. return $$.isLegendToShow(id) ? 'visible' : 'hidden';
  6797. }).style('cursor', 'pointer').on('click', function (id) {
  6798. if (config.legend_item_onclick) {
  6799. config.legend_item_onclick.call($$, id);
  6800. } else {
  6801. if ($$.d3.event.altKey) {
  6802. $$.api.hide();
  6803. $$.api.show(id);
  6804. } else {
  6805. $$.api.toggle(id);
  6806. $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();
  6807. }
  6808. }
  6809. }).on('mouseover', function (id) {
  6810. if (config.legend_item_onmouseover) {
  6811. config.legend_item_onmouseover.call($$, id);
  6812. } else {
  6813. $$.d3.select(this).classed(CLASS.legendItemFocused, true);
  6814. if (!$$.transiting && $$.isTargetToShow(id)) {
  6815. $$.api.focus(id);
  6816. }
  6817. }
  6818. }).on('mouseout', function (id) {
  6819. if (config.legend_item_onmouseout) {
  6820. config.legend_item_onmouseout.call($$, id);
  6821. } else {
  6822. $$.d3.select(this).classed(CLASS.legendItemFocused, false);
  6823. $$.api.revert();
  6824. }
  6825. });
  6826. l.append('text').text(function (id) {
  6827. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  6828. }).each(function (id, i) {
  6829. updatePositions(this, id, i);
  6830. }).style("pointer-events", "none").attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);
  6831. l.append('rect').attr("class", CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);
  6832. 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);
  6833. // Set background for inset legend
  6834. background = $$.legend.select('.' + CLASS.legendBackground + ' rect');
  6835. if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {
  6836. background = $$.legend.insert('g', '.' + CLASS.legendItem).attr("class", CLASS.legendBackground).append('rect');
  6837. }
  6838. texts = $$.legend.selectAll('text').data(targetIds).text(function (id) {
  6839. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  6840. } // MEMO: needed for update
  6841. ).each(function (id, i) {
  6842. updatePositions(this, id, i);
  6843. });
  6844. (withTransition ? texts.transition() : texts).attr('x', xForLegendText).attr('y', yForLegendText);
  6845. rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds);
  6846. (withTransition ? rects.transition() : rects).attr('width', function (id) {
  6847. return widths[id];
  6848. }).attr('height', function (id) {
  6849. return heights[id];
  6850. }).attr('x', xForLegendRect).attr('y', yForLegendRect);
  6851. tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds);
  6852. (withTransition ? tiles.transition() : tiles).style('stroke', $$.color).attr('x1', x1ForLegendTile).attr('y1', yForLegendTile).attr('x2', x2ForLegendTile).attr('y2', yForLegendTile);
  6853. if (background) {
  6854. (withTransition ? background.transition() : background).attr('height', $$.getLegendHeight() - 12).attr('width', maxWidth * (step + 1) + 10);
  6855. }
  6856. // toggle legend state
  6857. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemHidden, function (id) {
  6858. return !$$.isTargetToShow(id);
  6859. });
  6860. // Update all to reflect change of legend
  6861. $$.updateLegendItemWidth(maxWidth);
  6862. $$.updateLegendItemHeight(maxHeight);
  6863. $$.updateLegendStep(step);
  6864. // Update size and scale
  6865. $$.updateSizes();
  6866. $$.updateScales();
  6867. $$.updateSvgSize();
  6868. // Update g positions
  6869. $$.transformAll(withTransitionForTransform, transitions);
  6870. $$.legendHasRendered = true;
  6871. };
  6872. c3_chart_internal_fn.initRegion = function () {
  6873. var $$ = this;
  6874. $$.region = $$.main.append('g').attr("clip-path", $$.clipPath).attr("class", CLASS.regions);
  6875. };
  6876. c3_chart_internal_fn.updateRegion = function (duration) {
  6877. var $$ = this,
  6878. config = $$.config;
  6879. // hide if arc type
  6880. $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  6881. $$.mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region).data(config.regions);
  6882. $$.mainRegion.enter().append('g').append('rect').style("fill-opacity", 0);
  6883. $$.mainRegion.attr('class', $$.classRegion.bind($$));
  6884. $$.mainRegion.exit().transition().duration(duration).style("opacity", 0).remove();
  6885. };
  6886. c3_chart_internal_fn.redrawRegion = function (withTransition) {
  6887. var $$ = this,
  6888. regions = $$.mainRegion.selectAll('rect').each(function () {
  6889. // data is binded to g and it's not transferred to rect (child node) automatically,
  6890. // then data of each rect has to be updated manually.
  6891. // TODO: there should be more efficient way to solve this?
  6892. var parentData = $$.d3.select(this.parentNode).datum();
  6893. $$.d3.select(this).datum(parentData);
  6894. }),
  6895. x = $$.regionX.bind($$),
  6896. y = $$.regionY.bind($$),
  6897. w = $$.regionWidth.bind($$),
  6898. h = $$.regionHeight.bind($$);
  6899. return [(withTransition ? regions.transition() : regions).attr("x", x).attr("y", y).attr("width", w).attr("height", h).style("fill-opacity", function (d) {
  6900. return isValue(d.opacity) ? d.opacity : 0.1;
  6901. })];
  6902. };
  6903. c3_chart_internal_fn.regionX = function (d) {
  6904. var $$ = this,
  6905. config = $$.config,
  6906. xPos,
  6907. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6908. if (d.axis === 'y' || d.axis === 'y2') {
  6909. xPos = config.axis_rotated ? 'start' in d ? yScale(d.start) : 0 : 0;
  6910. } else {
  6911. xPos = config.axis_rotated ? 0 : 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0;
  6912. }
  6913. return xPos;
  6914. };
  6915. c3_chart_internal_fn.regionY = function (d) {
  6916. var $$ = this,
  6917. config = $$.config,
  6918. yPos,
  6919. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6920. if (d.axis === 'y' || d.axis === 'y2') {
  6921. yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;
  6922. } else {
  6923. yPos = config.axis_rotated ? 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0 : 0;
  6924. }
  6925. return yPos;
  6926. };
  6927. c3_chart_internal_fn.regionWidth = function (d) {
  6928. var $$ = this,
  6929. config = $$.config,
  6930. start = $$.regionX(d),
  6931. end,
  6932. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6933. if (d.axis === 'y' || d.axis === 'y2') {
  6934. end = config.axis_rotated ? 'end' in d ? yScale(d.end) : $$.width : $$.width;
  6935. } else {
  6936. end = config.axis_rotated ? $$.width : 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width;
  6937. }
  6938. return end < start ? 0 : end - start;
  6939. };
  6940. c3_chart_internal_fn.regionHeight = function (d) {
  6941. var $$ = this,
  6942. config = $$.config,
  6943. start = this.regionY(d),
  6944. end,
  6945. yScale = d.axis === 'y' ? $$.y : $$.y2;
  6946. if (d.axis === 'y' || d.axis === 'y2') {
  6947. end = config.axis_rotated ? $$.height : 'start' in d ? yScale(d.start) : $$.height;
  6948. } else {
  6949. end = config.axis_rotated ? 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height : $$.height;
  6950. }
  6951. return end < start ? 0 : end - start;
  6952. };
  6953. c3_chart_internal_fn.isRegionOnX = function (d) {
  6954. return !d.axis || d.axis === 'x';
  6955. };
  6956. c3_chart_internal_fn.getScale = function (min, max, forTimeseries) {
  6957. return (forTimeseries ? this.d3.time.scale() : this.d3.scale.linear()).range([min, max]);
  6958. };
  6959. c3_chart_internal_fn.getX = function (min, max, domain, offset) {
  6960. var $$ = this,
  6961. scale = $$.getScale(min, max, $$.isTimeSeries()),
  6962. _scale = domain ? scale.domain(domain) : scale,
  6963. key;
  6964. // Define customized scale if categorized axis
  6965. if ($$.isCategorized()) {
  6966. offset = offset || function () {
  6967. return 0;
  6968. };
  6969. scale = function scale(d, raw) {
  6970. var v = _scale(d) + offset(d);
  6971. return raw ? v : Math.ceil(v);
  6972. };
  6973. } else {
  6974. scale = function scale(d, raw) {
  6975. var v = _scale(d);
  6976. return raw ? v : Math.ceil(v);
  6977. };
  6978. }
  6979. // define functions
  6980. for (key in _scale) {
  6981. scale[key] = _scale[key];
  6982. }
  6983. scale.orgDomain = function () {
  6984. return _scale.domain();
  6985. };
  6986. // define custom domain() for categorized axis
  6987. if ($$.isCategorized()) {
  6988. scale.domain = function (domain) {
  6989. if (!arguments.length) {
  6990. domain = this.orgDomain();
  6991. return [domain[0], domain[1] + 1];
  6992. }
  6993. _scale.domain(domain);
  6994. return scale;
  6995. };
  6996. }
  6997. return scale;
  6998. };
  6999. c3_chart_internal_fn.getY = function (min, max, domain) {
  7000. var scale = this.getScale(min, max, this.isTimeSeriesY());
  7001. if (domain) {
  7002. scale.domain(domain);
  7003. }
  7004. return scale;
  7005. };
  7006. c3_chart_internal_fn.getYScale = function (id) {
  7007. return this.axis.getId(id) === 'y2' ? this.y2 : this.y;
  7008. };
  7009. c3_chart_internal_fn.getSubYScale = function (id) {
  7010. return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY;
  7011. };
  7012. c3_chart_internal_fn.updateScales = function () {
  7013. var $$ = this,
  7014. config = $$.config,
  7015. forInit = !$$.x;
  7016. // update edges
  7017. $$.xMin = config.axis_rotated ? 1 : 0;
  7018. $$.xMax = config.axis_rotated ? $$.height : $$.width;
  7019. $$.yMin = config.axis_rotated ? 0 : $$.height;
  7020. $$.yMax = config.axis_rotated ? $$.width : 1;
  7021. $$.subXMin = $$.xMin;
  7022. $$.subXMax = $$.xMax;
  7023. $$.subYMin = config.axis_rotated ? 0 : $$.height2;
  7024. $$.subYMax = config.axis_rotated ? $$.width2 : 1;
  7025. // update scales
  7026. $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () {
  7027. return $$.xAxis.tickOffset();
  7028. });
  7029. $$.y = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y_default : $$.y.domain());
  7030. $$.y2 = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y2_default : $$.y2.domain());
  7031. $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) {
  7032. return d % 1 ? 0 : $$.subXAxis.tickOffset();
  7033. });
  7034. $$.subY = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y_default : $$.subY.domain());
  7035. $$.subY2 = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y2_default : $$.subY2.domain());
  7036. // update axes
  7037. $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();
  7038. $$.xAxisTickValues = $$.axis.getXAxisTickValues();
  7039. $$.yAxisTickValues = $$.axis.getYAxisTickValues();
  7040. $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();
  7041. $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  7042. $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  7043. $$.yAxis = $$.axis.getYAxis($$.y, $$.yOrient, config.axis_y_tick_format, $$.yAxisTickValues, config.axis_y_tick_outer);
  7044. $$.y2Axis = $$.axis.getYAxis($$.y2, $$.y2Orient, config.axis_y2_tick_format, $$.y2AxisTickValues, config.axis_y2_tick_outer);
  7045. // Set initialized scales to brush and zoom
  7046. if (!forInit) {
  7047. if ($$.brush) {
  7048. $$.brush.scale($$.subX);
  7049. }
  7050. if (config.zoom_enabled) {
  7051. $$.zoom.scale($$.x);
  7052. }
  7053. }
  7054. // update for arc
  7055. if ($$.updateArc) {
  7056. $$.updateArc();
  7057. }
  7058. };
  7059. c3_chart_internal_fn.selectPoint = function (target, d, i) {
  7060. var $$ = this,
  7061. config = $$.config,
  7062. cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),
  7063. cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),
  7064. r = $$.pointSelectR.bind($$);
  7065. config.data_onselected.call($$.api, d, target.node());
  7066. // add selected-circle on low layer g
  7067. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr("class", function () {
  7068. return $$.generateClass(CLASS.selectedCircle, i);
  7069. }).attr("cx", cx).attr("cy", cy).attr("stroke", function () {
  7070. return $$.color(d);
  7071. }).attr("r", function (d) {
  7072. return $$.pointSelectR(d) * 1.4;
  7073. }).transition().duration(100).attr("r", r);
  7074. };
  7075. c3_chart_internal_fn.unselectPoint = function (target, d, i) {
  7076. var $$ = this;
  7077. $$.config.data_onunselected.call($$.api, d, target.node());
  7078. // remove selected-circle from low layer g
  7079. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).transition().duration(100).attr('r', 0).remove();
  7080. };
  7081. c3_chart_internal_fn.togglePoint = function (selected, target, d, i) {
  7082. selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);
  7083. };
  7084. c3_chart_internal_fn.selectPath = function (target, d) {
  7085. var $$ = this;
  7086. $$.config.data_onselected.call($$, d, target.node());
  7087. if ($$.config.interaction_brighten) {
  7088. target.transition().duration(100).style("fill", function () {
  7089. return $$.d3.rgb($$.color(d)).brighter(0.75);
  7090. });
  7091. }
  7092. };
  7093. c3_chart_internal_fn.unselectPath = function (target, d) {
  7094. var $$ = this;
  7095. $$.config.data_onunselected.call($$, d, target.node());
  7096. if ($$.config.interaction_brighten) {
  7097. target.transition().duration(100).style("fill", function () {
  7098. return $$.color(d);
  7099. });
  7100. }
  7101. };
  7102. c3_chart_internal_fn.togglePath = function (selected, target, d, i) {
  7103. selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);
  7104. };
  7105. c3_chart_internal_fn.getToggle = function (that, d) {
  7106. var $$ = this,
  7107. toggle;
  7108. if (that.nodeName === 'circle') {
  7109. if ($$.isStepType(d)) {
  7110. // circle is hidden in step chart, so treat as within the click area
  7111. toggle = function toggle() {}; // TODO: how to select step chart?
  7112. } else {
  7113. toggle = $$.togglePoint;
  7114. }
  7115. } else if (that.nodeName === 'path') {
  7116. toggle = $$.togglePath;
  7117. }
  7118. return toggle;
  7119. };
  7120. c3_chart_internal_fn.toggleShape = function (that, d, i) {
  7121. var $$ = this,
  7122. d3 = $$.d3,
  7123. config = $$.config,
  7124. shape = d3.select(that),
  7125. isSelected = shape.classed(CLASS.SELECTED),
  7126. toggle = $$.getToggle(that, d).bind($$);
  7127. if (config.data_selection_enabled && config.data_selection_isselectable(d)) {
  7128. if (!config.data_selection_multiple) {
  7129. $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) {
  7130. var shape = d3.select(this);
  7131. if (shape.classed(CLASS.SELECTED)) {
  7132. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  7133. }
  7134. });
  7135. }
  7136. shape.classed(CLASS.SELECTED, !isSelected);
  7137. toggle(!isSelected, shape, d, i);
  7138. }
  7139. };
  7140. c3_chart_internal_fn.initBar = function () {
  7141. var $$ = this;
  7142. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars);
  7143. };
  7144. c3_chart_internal_fn.updateTargetsForBar = function (targets) {
  7145. var $$ = this,
  7146. config = $$.config,
  7147. mainBarUpdate,
  7148. mainBarEnter,
  7149. classChartBar = $$.classChartBar.bind($$),
  7150. classBars = $$.classBars.bind($$),
  7151. classFocus = $$.classFocus.bind($$);
  7152. mainBarUpdate = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', function (d) {
  7153. return classChartBar(d) + classFocus(d);
  7154. });
  7155. mainBarEnter = mainBarUpdate.enter().append('g').attr('class', classChartBar).style("pointer-events", "none");
  7156. // Bars for each data
  7157. mainBarEnter.append('g').attr("class", classBars).style("cursor", function (d) {
  7158. return config.data_selection_isselectable(d) ? "pointer" : null;
  7159. });
  7160. };
  7161. c3_chart_internal_fn.updateBar = function (durationForExit) {
  7162. var $$ = this,
  7163. barData = $$.barData.bind($$),
  7164. classBar = $$.classBar.bind($$),
  7165. initialOpacity = $$.initialOpacity.bind($$),
  7166. color = function color(d) {
  7167. return $$.color(d.id);
  7168. };
  7169. $$.mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data(barData);
  7170. $$.mainBar.enter().append('path').attr("class", classBar).style("stroke", color).style("fill", color);
  7171. $$.mainBar.style("opacity", initialOpacity);
  7172. $$.mainBar.exit().transition().duration(durationForExit).remove();
  7173. };
  7174. c3_chart_internal_fn.redrawBar = function (drawBar, withTransition) {
  7175. return [(withTransition ? this.mainBar.transition(Math.random().toString()) : this.mainBar).attr('d', drawBar).style("fill", this.color).style("opacity", 1)];
  7176. };
  7177. c3_chart_internal_fn.getBarW = function (axis, barTargetsNum) {
  7178. var $$ = this,
  7179. config = $$.config,
  7180. w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? axis.tickInterval() * config.bar_width_ratio / barTargetsNum : 0;
  7181. return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w;
  7182. };
  7183. c3_chart_internal_fn.getBars = function (i, id) {
  7184. var $$ = this;
  7185. return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
  7186. };
  7187. c3_chart_internal_fn.expandBars = function (i, id, reset) {
  7188. var $$ = this;
  7189. if (reset) {
  7190. $$.unexpandBars();
  7191. }
  7192. $$.getBars(i, id).classed(CLASS.EXPANDED, true);
  7193. };
  7194. c3_chart_internal_fn.unexpandBars = function (i) {
  7195. var $$ = this;
  7196. $$.getBars(i).classed(CLASS.EXPANDED, false);
  7197. };
  7198. c3_chart_internal_fn.generateDrawBar = function (barIndices, isSub) {
  7199. var $$ = this,
  7200. config = $$.config,
  7201. getPoints = $$.generateGetBarPoints(barIndices, isSub);
  7202. return function (d, i) {
  7203. // 4 points that make a bar
  7204. var points = getPoints(d, i);
  7205. // switch points if axis is rotated, not applicable for sub chart
  7206. var indexX = config.axis_rotated ? 1 : 0;
  7207. var indexY = config.axis_rotated ? 0 : 1;
  7208. 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';
  7209. return path;
  7210. };
  7211. };
  7212. c3_chart_internal_fn.generateGetBarPoints = function (barIndices, isSub) {
  7213. var $$ = this,
  7214. axis = isSub ? $$.subXAxis : $$.xAxis,
  7215. barTargetsNum = barIndices.__max__ + 1,
  7216. barW = $$.getBarW(axis, barTargetsNum),
  7217. barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),
  7218. barY = $$.getShapeY(!!isSub),
  7219. barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),
  7220. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  7221. return function (d, i) {
  7222. var y0 = yScale.call($$, d.id)(0),
  7223. offset = barOffset(d, i) || y0,
  7224. // offset is for stacked bar chart
  7225. posX = barX(d),
  7226. posY = barY(d);
  7227. // fix posY not to overflow opposite quadrant
  7228. if ($$.config.axis_rotated) {
  7229. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  7230. posY = y0;
  7231. }
  7232. }
  7233. // 4 points that make a bar
  7234. return [[posX, offset], [posX, posY - (y0 - offset)], [posX + barW, posY - (y0 - offset)], [posX + barW, offset]];
  7235. };
  7236. };
  7237. c3_chart_internal_fn.isWithinBar = function (that) {
  7238. var mouse = this.d3.mouse(that),
  7239. box = that.getBoundingClientRect(),
  7240. seg0 = that.pathSegList.getItem(0),
  7241. seg1 = that.pathSegList.getItem(1),
  7242. x = Math.min(seg0.x, seg1.x),
  7243. y = Math.min(seg0.y, seg1.y),
  7244. w = box.width,
  7245. h = box.height,
  7246. offset = 2,
  7247. sx = x - offset,
  7248. ex = x + w + offset,
  7249. sy = y + h + offset,
  7250. ey = y - offset;
  7251. return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy;
  7252. };
  7253. c3_chart_internal_fn.getShapeIndices = function (typeFilter) {
  7254. var $$ = this,
  7255. config = $$.config,
  7256. indices = {},
  7257. i = 0,
  7258. j,
  7259. k;
  7260. $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {
  7261. for (j = 0; j < config.data_groups.length; j++) {
  7262. if (config.data_groups[j].indexOf(d.id) < 0) {
  7263. continue;
  7264. }
  7265. for (k = 0; k < config.data_groups[j].length; k++) {
  7266. if (config.data_groups[j][k] in indices) {
  7267. indices[d.id] = indices[config.data_groups[j][k]];
  7268. break;
  7269. }
  7270. }
  7271. }
  7272. if (isUndefined(indices[d.id])) {
  7273. indices[d.id] = i++;
  7274. }
  7275. });
  7276. indices.__max__ = i - 1;
  7277. return indices;
  7278. };
  7279. c3_chart_internal_fn.getShapeX = function (offset, targetsNum, indices, isSub) {
  7280. var $$ = this,
  7281. scale = isSub ? $$.subX : $$.x;
  7282. return function (d) {
  7283. var index = d.id in indices ? indices[d.id] : 0;
  7284. return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;
  7285. };
  7286. };
  7287. c3_chart_internal_fn.getShapeY = function (isSub) {
  7288. var $$ = this;
  7289. return function (d) {
  7290. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);
  7291. return scale(d.value);
  7292. };
  7293. };
  7294. c3_chart_internal_fn.getShapeOffset = function (typeFilter, indices, isSub) {
  7295. var $$ = this,
  7296. targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))),
  7297. targetIds = targets.map(function (t) {
  7298. return t.id;
  7299. });
  7300. return function (d, i) {
  7301. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),
  7302. y0 = scale(0),
  7303. offset = y0;
  7304. targets.forEach(function (t) {
  7305. var values = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values;
  7306. if (t.id === d.id || indices[t.id] !== indices[d.id]) {
  7307. return;
  7308. }
  7309. if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {
  7310. // check if the x values line up
  7311. if (typeof values[i] === 'undefined' || +values[i].x !== +d.x) {
  7312. // "+" for timeseries
  7313. // if not, try to find the value that does line up
  7314. i = -1;
  7315. values.forEach(function (v, j) {
  7316. if (v.x === d.x) {
  7317. i = j;
  7318. }
  7319. });
  7320. }
  7321. if (i in values && values[i].value * d.value >= 0) {
  7322. offset += scale(values[i].value) - y0;
  7323. }
  7324. }
  7325. });
  7326. return offset;
  7327. };
  7328. };
  7329. c3_chart_internal_fn.isWithinShape = function (that, d) {
  7330. var $$ = this,
  7331. shape = $$.d3.select(that),
  7332. isWithin;
  7333. if (!$$.isTargetToShow(d.id)) {
  7334. isWithin = false;
  7335. } else if (that.nodeName === 'circle') {
  7336. isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);
  7337. } else if (that.nodeName === 'path') {
  7338. isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar(that) : true;
  7339. }
  7340. return isWithin;
  7341. };
  7342. c3_chart_internal_fn.getInterpolate = function (d) {
  7343. var $$ = this,
  7344. interpolation = $$.isInterpolationType($$.config.spline_interpolation_type) ? $$.config.spline_interpolation_type : 'cardinal';
  7345. return $$.isSplineType(d) ? interpolation : $$.isStepType(d) ? $$.config.line_step_type : "linear";
  7346. };
  7347. c3_chart_internal_fn.initLine = function () {
  7348. var $$ = this;
  7349. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines);
  7350. };
  7351. c3_chart_internal_fn.updateTargetsForLine = function (targets) {
  7352. var $$ = this,
  7353. config = $$.config,
  7354. mainLineUpdate,
  7355. mainLineEnter,
  7356. classChartLine = $$.classChartLine.bind($$),
  7357. classLines = $$.classLines.bind($$),
  7358. classAreas = $$.classAreas.bind($$),
  7359. classCircles = $$.classCircles.bind($$),
  7360. classFocus = $$.classFocus.bind($$);
  7361. mainLineUpdate = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', function (d) {
  7362. return classChartLine(d) + classFocus(d);
  7363. });
  7364. mainLineEnter = mainLineUpdate.enter().append('g').attr('class', classChartLine).style('opacity', 0).style("pointer-events", "none");
  7365. // Lines for each data
  7366. mainLineEnter.append('g').attr("class", classLines);
  7367. // Areas
  7368. mainLineEnter.append('g').attr('class', classAreas);
  7369. // Circles for each data point on lines
  7370. mainLineEnter.append('g').attr("class", function (d) {
  7371. return $$.generateClass(CLASS.selectedCircles, d.id);
  7372. });
  7373. mainLineEnter.append('g').attr("class", classCircles).style("cursor", function (d) {
  7374. return config.data_selection_isselectable(d) ? "pointer" : null;
  7375. });
  7376. // Update date for selected circles
  7377. targets.forEach(function (t) {
  7378. $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) {
  7379. d.value = t.values[d.index].value;
  7380. });
  7381. });
  7382. // MEMO: can not keep same color...
  7383. //mainLineUpdate.exit().remove();
  7384. };
  7385. c3_chart_internal_fn.updateLine = function (durationForExit) {
  7386. var $$ = this;
  7387. $$.mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  7388. $$.mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style("stroke", $$.color);
  7389. $$.mainLine.style("opacity", $$.initialOpacity.bind($$)).style('shape-rendering', function (d) {
  7390. return $$.isStepType(d) ? 'crispEdges' : '';
  7391. }).attr('transform', null);
  7392. $$.mainLine.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7393. };
  7394. c3_chart_internal_fn.redrawLine = function (drawLine, withTransition) {
  7395. return [(withTransition ? this.mainLine.transition(Math.random().toString()) : this.mainLine).attr("d", drawLine).style("stroke", this.color).style("opacity", 1)];
  7396. };
  7397. c3_chart_internal_fn.generateDrawLine = function (lineIndices, isSub) {
  7398. var $$ = this,
  7399. config = $$.config,
  7400. line = $$.d3.svg.line(),
  7401. getPoints = $$.generateGetLinePoints(lineIndices, isSub),
  7402. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  7403. xValue = function xValue(d) {
  7404. return (isSub ? $$.subxx : $$.xx).call($$, d);
  7405. },
  7406. yValue = function yValue(d, i) {
  7407. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value);
  7408. };
  7409. line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue);
  7410. if (!config.line_connectNull) {
  7411. line = line.defined(function (d) {
  7412. return d.value != null;
  7413. });
  7414. }
  7415. return function (d) {
  7416. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  7417. x = isSub ? $$.x : $$.subX,
  7418. y = yScaleGetter.call($$, d.id),
  7419. x0 = 0,
  7420. y0 = 0,
  7421. path;
  7422. if ($$.isLineType(d)) {
  7423. if (config.data_regions[d.id]) {
  7424. path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);
  7425. } else {
  7426. if ($$.isStepType(d)) {
  7427. values = $$.convertValuesToStep(values);
  7428. }
  7429. path = line.interpolate($$.getInterpolate(d))(values);
  7430. }
  7431. } else {
  7432. if (values[0]) {
  7433. x0 = x(values[0].x);
  7434. y0 = y(values[0].value);
  7435. }
  7436. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  7437. }
  7438. return path ? path : "M 0 0";
  7439. };
  7440. };
  7441. c3_chart_internal_fn.generateGetLinePoints = function (lineIndices, isSub) {
  7442. // partial duplication of generateGetBarPoints
  7443. var $$ = this,
  7444. config = $$.config,
  7445. lineTargetsNum = lineIndices.__max__ + 1,
  7446. x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),
  7447. y = $$.getShapeY(!!isSub),
  7448. lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),
  7449. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  7450. return function (d, i) {
  7451. var y0 = yScale.call($$, d.id)(0),
  7452. offset = lineOffset(d, i) || y0,
  7453. // offset is for stacked area chart
  7454. posX = x(d),
  7455. posY = y(d);
  7456. // fix posY not to overflow opposite quadrant
  7457. if (config.axis_rotated) {
  7458. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  7459. posY = y0;
  7460. }
  7461. }
  7462. // 1 point that marks the line position
  7463. return [[posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  7464. [posX, posY - (y0 - offset)], // needed for compatibility
  7465. [posX, posY - (y0 - offset)] // needed for compatibility
  7466. ];
  7467. };
  7468. };
  7469. c3_chart_internal_fn.lineWithRegions = function (d, x, y, _regions) {
  7470. var $$ = this,
  7471. config = $$.config,
  7472. prev = -1,
  7473. i,
  7474. j,
  7475. s = "M",
  7476. sWithRegion,
  7477. xp,
  7478. yp,
  7479. dx,
  7480. dy,
  7481. dd,
  7482. diff,
  7483. diffx2,
  7484. xOffset = $$.isCategorized() ? 0.5 : 0,
  7485. xValue,
  7486. yValue,
  7487. regions = [];
  7488. function isWithinRegions(x, regions) {
  7489. var i;
  7490. for (i = 0; i < regions.length; i++) {
  7491. if (regions[i].start < x && x <= regions[i].end) {
  7492. return true;
  7493. }
  7494. }
  7495. return false;
  7496. }
  7497. // Check start/end of regions
  7498. if (isDefined(_regions)) {
  7499. for (i = 0; i < _regions.length; i++) {
  7500. regions[i] = {};
  7501. if (isUndefined(_regions[i].start)) {
  7502. regions[i].start = d[0].x;
  7503. } else {
  7504. regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start;
  7505. }
  7506. if (isUndefined(_regions[i].end)) {
  7507. regions[i].end = d[d.length - 1].x;
  7508. } else {
  7509. regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end;
  7510. }
  7511. }
  7512. }
  7513. // Set scales
  7514. xValue = config.axis_rotated ? function (d) {
  7515. return y(d.value);
  7516. } : function (d) {
  7517. return x(d.x);
  7518. };
  7519. yValue = config.axis_rotated ? function (d) {
  7520. return x(d.x);
  7521. } : function (d) {
  7522. return y(d.value);
  7523. };
  7524. // Define svg generator function for region
  7525. function generateM(points) {
  7526. return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1];
  7527. }
  7528. if ($$.isTimeSeries()) {
  7529. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  7530. var x0 = d0.x.getTime(),
  7531. x_diff = d1.x - d0.x,
  7532. xv0 = new Date(x0 + x_diff * j),
  7533. xv1 = new Date(x0 + x_diff * (j + diff)),
  7534. points;
  7535. if (config.axis_rotated) {
  7536. points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]];
  7537. } else {
  7538. points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]];
  7539. }
  7540. return generateM(points);
  7541. };
  7542. } else {
  7543. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  7544. var points;
  7545. if (config.axis_rotated) {
  7546. points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]];
  7547. } else {
  7548. points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]];
  7549. }
  7550. return generateM(points);
  7551. };
  7552. }
  7553. // Generate
  7554. for (i = 0; i < d.length; i++) {
  7555. // Draw as normal
  7556. if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {
  7557. s += " " + xValue(d[i]) + " " + yValue(d[i]);
  7558. }
  7559. // Draw with region // TODO: Fix for horizotal charts
  7560. else {
  7561. xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries());
  7562. yp = $$.getScale(d[i - 1].value, d[i].value);
  7563. dx = x(d[i].x) - x(d[i - 1].x);
  7564. dy = y(d[i].value) - y(d[i - 1].value);
  7565. dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
  7566. diff = 2 / dd;
  7567. diffx2 = diff * 2;
  7568. for (j = diff; j <= 1; j += diffx2) {
  7569. s += sWithRegion(d[i - 1], d[i], j, diff);
  7570. }
  7571. }
  7572. prev = d[i].x;
  7573. }
  7574. return s;
  7575. };
  7576. c3_chart_internal_fn.updateArea = function (durationForExit) {
  7577. var $$ = this,
  7578. d3 = $$.d3;
  7579. $$.mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  7580. $$.mainArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  7581. $$.orgAreaOpacity = +d3.select(this).style('opacity');return 0;
  7582. });
  7583. $$.mainArea.style("opacity", $$.orgAreaOpacity);
  7584. $$.mainArea.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7585. };
  7586. c3_chart_internal_fn.redrawArea = function (drawArea, withTransition) {
  7587. return [(withTransition ? this.mainArea.transition(Math.random().toString()) : this.mainArea).attr("d", drawArea).style("fill", this.color).style("opacity", this.orgAreaOpacity)];
  7588. };
  7589. c3_chart_internal_fn.generateDrawArea = function (areaIndices, isSub) {
  7590. var $$ = this,
  7591. config = $$.config,
  7592. area = $$.d3.svg.area(),
  7593. getPoints = $$.generateGetAreaPoints(areaIndices, isSub),
  7594. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  7595. xValue = function xValue(d) {
  7596. return (isSub ? $$.subxx : $$.xx).call($$, d);
  7597. },
  7598. value0 = function value0(d, i) {
  7599. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id));
  7600. },
  7601. value1 = function value1(d, i) {
  7602. return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value);
  7603. };
  7604. area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1);
  7605. if (!config.line_connectNull) {
  7606. area = area.defined(function (d) {
  7607. return d.value !== null;
  7608. });
  7609. }
  7610. return function (d) {
  7611. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  7612. x0 = 0,
  7613. y0 = 0,
  7614. path;
  7615. if ($$.isAreaType(d)) {
  7616. if ($$.isStepType(d)) {
  7617. values = $$.convertValuesToStep(values);
  7618. }
  7619. path = area.interpolate($$.getInterpolate(d))(values);
  7620. } else {
  7621. if (values[0]) {
  7622. x0 = $$.x(values[0].x);
  7623. y0 = $$.getYScale(d.id)(values[0].value);
  7624. }
  7625. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  7626. }
  7627. return path ? path : "M 0 0";
  7628. };
  7629. };
  7630. c3_chart_internal_fn.getAreaBaseValue = function () {
  7631. return 0;
  7632. };
  7633. c3_chart_internal_fn.generateGetAreaPoints = function (areaIndices, isSub) {
  7634. // partial duplication of generateGetBarPoints
  7635. var $$ = this,
  7636. config = $$.config,
  7637. areaTargetsNum = areaIndices.__max__ + 1,
  7638. x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),
  7639. y = $$.getShapeY(!!isSub),
  7640. areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),
  7641. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  7642. return function (d, i) {
  7643. var y0 = yScale.call($$, d.id)(0),
  7644. offset = areaOffset(d, i) || y0,
  7645. // offset is for stacked area chart
  7646. posX = x(d),
  7647. posY = y(d);
  7648. // fix posY not to overflow opposite quadrant
  7649. if (config.axis_rotated) {
  7650. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  7651. posY = y0;
  7652. }
  7653. }
  7654. // 1 point that marks the area position
  7655. return [[posX, offset], [posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  7656. [posX, offset] // needed for compatibility
  7657. ];
  7658. };
  7659. };
  7660. c3_chart_internal_fn.updateCircle = function () {
  7661. var $$ = this;
  7662. $$.mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle).data($$.lineOrScatterData.bind($$));
  7663. $$.mainCircle.enter().append("circle").attr("class", $$.classCircle.bind($$)).attr("r", $$.pointR.bind($$)).style("fill", $$.color);
  7664. $$.mainCircle.style("opacity", $$.initialOpacityForCircle.bind($$));
  7665. $$.mainCircle.exit().remove();
  7666. };
  7667. c3_chart_internal_fn.redrawCircle = function (cx, cy, withTransition) {
  7668. var selectedCircles = this.main.selectAll('.' + CLASS.selectedCircle);
  7669. return [(withTransition ? this.mainCircle.transition(Math.random().toString()) : this.mainCircle).style('opacity', this.opacityForCircle.bind(this)).style("fill", this.color).attr("cx", cx).attr("cy", cy), (withTransition ? selectedCircles.transition(Math.random().toString()) : selectedCircles).attr("cx", cx).attr("cy", cy)];
  7670. };
  7671. c3_chart_internal_fn.circleX = function (d) {
  7672. return d.x || d.x === 0 ? this.x(d.x) : null;
  7673. };
  7674. c3_chart_internal_fn.updateCircleY = function () {
  7675. var $$ = this,
  7676. lineIndices,
  7677. getPoints;
  7678. if ($$.config.data_groups.length > 0) {
  7679. lineIndices = $$.getShapeIndices($$.isLineType), getPoints = $$.generateGetLinePoints(lineIndices);
  7680. $$.circleY = function (d, i) {
  7681. return getPoints(d, i)[0][1];
  7682. };
  7683. } else {
  7684. $$.circleY = function (d) {
  7685. return $$.getYScale(d.id)(d.value);
  7686. };
  7687. }
  7688. };
  7689. c3_chart_internal_fn.getCircles = function (i, id) {
  7690. var $$ = this;
  7691. return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
  7692. };
  7693. c3_chart_internal_fn.expandCircles = function (i, id, reset) {
  7694. var $$ = this,
  7695. r = $$.pointExpandedR.bind($$);
  7696. if (reset) {
  7697. $$.unexpandCircles();
  7698. }
  7699. $$.getCircles(i, id).classed(CLASS.EXPANDED, true).attr('r', r);
  7700. };
  7701. c3_chart_internal_fn.unexpandCircles = function (i) {
  7702. var $$ = this,
  7703. r = $$.pointR.bind($$);
  7704. $$.getCircles(i).filter(function () {
  7705. return $$.d3.select(this).classed(CLASS.EXPANDED);
  7706. }).classed(CLASS.EXPANDED, false).attr('r', r);
  7707. };
  7708. c3_chart_internal_fn.pointR = function (d) {
  7709. var $$ = this,
  7710. config = $$.config;
  7711. return $$.isStepType(d) ? 0 : isFunction(config.point_r) ? config.point_r(d) : config.point_r;
  7712. };
  7713. c3_chart_internal_fn.pointExpandedR = function (d) {
  7714. var $$ = this,
  7715. config = $$.config;
  7716. return config.point_focus_expand_enabled ? config.point_focus_expand_r ? config.point_focus_expand_r : $$.pointR(d) * 1.75 : $$.pointR(d);
  7717. };
  7718. c3_chart_internal_fn.pointSelectR = function (d) {
  7719. var $$ = this,
  7720. config = $$.config;
  7721. return isFunction(config.point_select_r) ? config.point_select_r(d) : config.point_select_r ? config.point_select_r : $$.pointR(d) * 4;
  7722. };
  7723. c3_chart_internal_fn.isWithinCircle = function (that, r) {
  7724. var d3 = this.d3,
  7725. mouse = d3.mouse(that),
  7726. d3_this = d3.select(that),
  7727. cx = +d3_this.attr("cx"),
  7728. cy = +d3_this.attr("cy");
  7729. return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r;
  7730. };
  7731. c3_chart_internal_fn.isWithinStep = function (that, y) {
  7732. return Math.abs(y - this.d3.mouse(that)[1]) < 30;
  7733. };
  7734. c3_chart_internal_fn.getCurrentWidth = function () {
  7735. var $$ = this,
  7736. config = $$.config;
  7737. return config.size_width ? config.size_width : $$.getParentWidth();
  7738. };
  7739. c3_chart_internal_fn.getCurrentHeight = function () {
  7740. var $$ = this,
  7741. config = $$.config,
  7742. h = config.size_height ? config.size_height : $$.getParentHeight();
  7743. return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);
  7744. };
  7745. c3_chart_internal_fn.getCurrentPaddingTop = function () {
  7746. var $$ = this,
  7747. config = $$.config,
  7748. padding = isValue(config.padding_top) ? config.padding_top : 0;
  7749. if ($$.title && $$.title.node()) {
  7750. padding += $$.getTitlePadding();
  7751. }
  7752. return padding;
  7753. };
  7754. c3_chart_internal_fn.getCurrentPaddingBottom = function () {
  7755. var config = this.config;
  7756. return isValue(config.padding_bottom) ? config.padding_bottom : 0;
  7757. };
  7758. c3_chart_internal_fn.getCurrentPaddingLeft = function (withoutRecompute) {
  7759. var $$ = this,
  7760. config = $$.config;
  7761. if (isValue(config.padding_left)) {
  7762. return config.padding_left;
  7763. } else if (config.axis_rotated) {
  7764. return !config.axis_x_show ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);
  7765. } else if (!config.axis_y_show || config.axis_y_inner) {
  7766. // && !config.axis_rotated
  7767. return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1;
  7768. } else {
  7769. return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));
  7770. }
  7771. };
  7772. c3_chart_internal_fn.getCurrentPaddingRight = function () {
  7773. var $$ = this,
  7774. config = $$.config,
  7775. defaultPadding = 10,
  7776. legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;
  7777. if (isValue(config.padding_right)) {
  7778. return config.padding_right + 1; // 1 is needed not to hide tick line
  7779. } else if (config.axis_rotated) {
  7780. return defaultPadding + legendWidthOnRight;
  7781. } else if (!config.axis_y2_show || config.axis_y2_inner) {
  7782. // && !config.axis_rotated
  7783. return 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);
  7784. } else {
  7785. return ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;
  7786. }
  7787. };
  7788. c3_chart_internal_fn.getParentRectValue = function (key) {
  7789. var parent = this.selectChart.node(),
  7790. v;
  7791. while (parent && parent.tagName !== 'BODY') {
  7792. try {
  7793. v = parent.getBoundingClientRect()[key];
  7794. } catch (e) {
  7795. if (key === 'width') {
  7796. // In IE in certain cases getBoundingClientRect
  7797. // will cause an "unspecified error"
  7798. v = parent.offsetWidth;
  7799. }
  7800. }
  7801. if (v) {
  7802. break;
  7803. }
  7804. parent = parent.parentNode;
  7805. }
  7806. return v;
  7807. };
  7808. c3_chart_internal_fn.getParentWidth = function () {
  7809. return this.getParentRectValue('width');
  7810. };
  7811. c3_chart_internal_fn.getParentHeight = function () {
  7812. var h = this.selectChart.style('height');
  7813. return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;
  7814. };
  7815. c3_chart_internal_fn.getSvgLeft = function (withoutRecompute) {
  7816. var $$ = this,
  7817. config = $$.config,
  7818. hasLeftAxisRect = config.axis_rotated || !config.axis_rotated && !config.axis_y_inner,
  7819. leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,
  7820. leftAxis = $$.main.select('.' + leftAxisClass).node(),
  7821. svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : { right: 0 },
  7822. chartRect = $$.selectChart.node().getBoundingClientRect(),
  7823. hasArc = $$.hasArcType(),
  7824. svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));
  7825. return svgLeft > 0 ? svgLeft : 0;
  7826. };
  7827. c3_chart_internal_fn.getAxisWidthByAxisId = function (id, withoutRecompute) {
  7828. var $$ = this,
  7829. position = $$.axis.getLabelPositionById(id);
  7830. return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40);
  7831. };
  7832. c3_chart_internal_fn.getHorizontalAxisHeight = function (axisId) {
  7833. var $$ = this,
  7834. config = $$.config,
  7835. h = 30;
  7836. if (axisId === 'x' && !config.axis_x_show) {
  7837. return 8;
  7838. }
  7839. if (axisId === 'x' && config.axis_x_height) {
  7840. return config.axis_x_height;
  7841. }
  7842. if (axisId === 'y' && !config.axis_y_show) {
  7843. return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;
  7844. }
  7845. if (axisId === 'y2' && !config.axis_y2_show) {
  7846. return $$.rotated_padding_top;
  7847. }
  7848. // Calculate x axis height when tick rotated
  7849. if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
  7850. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - config.axis_x_tick_rotate) / 180);
  7851. }
  7852. // Calculate y axis height when tick rotated
  7853. if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {
  7854. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - config.axis_y_tick_rotate) / 180);
  7855. }
  7856. return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0);
  7857. };
  7858. c3_chart_internal_fn.getEventRectWidth = function () {
  7859. return Math.max(0, this.xAxis.tickInterval());
  7860. };
  7861. c3_chart_internal_fn.initBrush = function () {
  7862. var $$ = this,
  7863. d3 = $$.d3;
  7864. $$.brush = d3.svg.brush().on("brush", function () {
  7865. $$.redrawForBrush();
  7866. });
  7867. $$.brush.update = function () {
  7868. if ($$.context) {
  7869. $$.context.select('.' + CLASS.brush).call(this);
  7870. }
  7871. return this;
  7872. };
  7873. $$.brush.scale = function (scale) {
  7874. return $$.config.axis_rotated ? this.y(scale) : this.x(scale);
  7875. };
  7876. };
  7877. c3_chart_internal_fn.initSubchart = function () {
  7878. var $$ = this,
  7879. config = $$.config,
  7880. context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')),
  7881. visibility = config.subchart_show ? 'visible' : 'hidden';
  7882. context.style('visibility', visibility);
  7883. // Define g for chart area
  7884. context.append('g').attr("clip-path", $$.clipPathForSubchart).attr('class', CLASS.chart);
  7885. // Define g for bar chart area
  7886. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars);
  7887. // Define g for line chart area
  7888. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines);
  7889. // Add extent rect for Brush
  7890. context.append("g").attr("clip-path", $$.clipPath).attr("class", CLASS.brush).call($$.brush);
  7891. // ATTENTION: This must be called AFTER chart added
  7892. // Add Axis
  7893. $$.axes.subx = context.append("g").attr("class", CLASS.axisX).attr("transform", $$.getTranslate('subx')).attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis).style("visibility", config.subchart_axis_x_show ? visibility : 'hidden');
  7894. };
  7895. c3_chart_internal_fn.updateTargetsForSubchart = function (targets) {
  7896. var $$ = this,
  7897. context = $$.context,
  7898. config = $$.config,
  7899. contextLineEnter,
  7900. contextLineUpdate,
  7901. contextBarEnter,
  7902. contextBarUpdate,
  7903. classChartBar = $$.classChartBar.bind($$),
  7904. classBars = $$.classBars.bind($$),
  7905. classChartLine = $$.classChartLine.bind($$),
  7906. classLines = $$.classLines.bind($$),
  7907. classAreas = $$.classAreas.bind($$);
  7908. if (config.subchart_show) {
  7909. //-- Bar --//
  7910. contextBarUpdate = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', classChartBar);
  7911. contextBarEnter = contextBarUpdate.enter().append('g').style('opacity', 0).attr('class', classChartBar);
  7912. // Bars for each data
  7913. contextBarEnter.append('g').attr("class", classBars);
  7914. //-- Line --//
  7915. contextLineUpdate = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', classChartLine);
  7916. contextLineEnter = contextLineUpdate.enter().append('g').style('opacity', 0).attr('class', classChartLine);
  7917. // Lines for each data
  7918. contextLineEnter.append("g").attr("class", classLines);
  7919. // Area
  7920. contextLineEnter.append("g").attr("class", classAreas);
  7921. //-- Brush --//
  7922. context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2);
  7923. }
  7924. };
  7925. c3_chart_internal_fn.updateBarForSubchart = function (durationForExit) {
  7926. var $$ = this;
  7927. $$.contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data($$.barData.bind($$));
  7928. $$.contextBar.enter().append('path').attr("class", $$.classBar.bind($$)).style("stroke", 'none').style("fill", $$.color);
  7929. $$.contextBar.style("opacity", $$.initialOpacity.bind($$));
  7930. $$.contextBar.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7931. };
  7932. c3_chart_internal_fn.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) {
  7933. (withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar).attr('d', drawBarOnSub).style('opacity', 1);
  7934. };
  7935. c3_chart_internal_fn.updateLineForSubchart = function (durationForExit) {
  7936. var $$ = this;
  7937. $$.contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  7938. $$.contextLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color);
  7939. $$.contextLine.style("opacity", $$.initialOpacity.bind($$));
  7940. $$.contextLine.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7941. };
  7942. c3_chart_internal_fn.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) {
  7943. (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr("d", drawLineOnSub).style('opacity', 1);
  7944. };
  7945. c3_chart_internal_fn.updateAreaForSubchart = function (durationForExit) {
  7946. var $$ = this,
  7947. d3 = $$.d3;
  7948. $$.contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  7949. $$.contextArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  7950. $$.orgAreaOpacity = +d3.select(this).style('opacity');return 0;
  7951. });
  7952. $$.contextArea.style("opacity", 0);
  7953. $$.contextArea.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  7954. };
  7955. c3_chart_internal_fn.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) {
  7956. (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr("d", drawAreaOnSub).style("fill", this.color).style("opacity", this.orgAreaOpacity);
  7957. };
  7958. c3_chart_internal_fn.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) {
  7959. var $$ = this,
  7960. d3 = $$.d3,
  7961. config = $$.config,
  7962. drawAreaOnSub,
  7963. drawBarOnSub,
  7964. drawLineOnSub;
  7965. $$.context.style('visibility', config.subchart_show ? 'visible' : 'hidden');
  7966. // subchart
  7967. if (config.subchart_show) {
  7968. // reflect main chart to extent on subchart if zoomed
  7969. if (d3.event && d3.event.type === 'zoom') {
  7970. $$.brush.extent($$.x.orgDomain()).update();
  7971. }
  7972. // update subchart elements if needed
  7973. if (withSubchart) {
  7974. // extent rect
  7975. if (!$$.brush.empty()) {
  7976. $$.brush.extent($$.x.orgDomain()).update();
  7977. }
  7978. // setup drawer - MEMO: this must be called after axis updated
  7979. drawAreaOnSub = $$.generateDrawArea(areaIndices, true);
  7980. drawBarOnSub = $$.generateDrawBar(barIndices, true);
  7981. drawLineOnSub = $$.generateDrawLine(lineIndices, true);
  7982. $$.updateBarForSubchart(duration);
  7983. $$.updateLineForSubchart(duration);
  7984. $$.updateAreaForSubchart(duration);
  7985. $$.redrawBarForSubchart(drawBarOnSub, duration, duration);
  7986. $$.redrawLineForSubchart(drawLineOnSub, duration, duration);
  7987. $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);
  7988. }
  7989. }
  7990. };
  7991. c3_chart_internal_fn.redrawForBrush = function () {
  7992. var $$ = this,
  7993. x = $$.x;
  7994. $$.redraw({
  7995. withTransition: false,
  7996. withY: $$.config.zoom_rescale,
  7997. withSubchart: false,
  7998. withUpdateXDomain: true,
  7999. withDimension: false
  8000. });
  8001. $$.config.subchart_onbrush.call($$.api, x.orgDomain());
  8002. };
  8003. c3_chart_internal_fn.transformContext = function (withTransition, transitions) {
  8004. var $$ = this,
  8005. subXAxis;
  8006. if (transitions && transitions.axisSubX) {
  8007. subXAxis = transitions.axisSubX;
  8008. } else {
  8009. subXAxis = $$.context.select('.' + CLASS.axisX);
  8010. if (withTransition) {
  8011. subXAxis = subXAxis.transition();
  8012. }
  8013. }
  8014. $$.context.attr("transform", $$.getTranslate('context'));
  8015. subXAxis.attr("transform", $$.getTranslate('subx'));
  8016. };
  8017. c3_chart_internal_fn.getDefaultExtent = function () {
  8018. var $$ = this,
  8019. config = $$.config,
  8020. extent = isFunction(config.axis_x_extent) ? config.axis_x_extent($$.getXDomain($$.data.targets)) : config.axis_x_extent;
  8021. if ($$.isTimeSeries()) {
  8022. extent = [$$.parseDate(extent[0]), $$.parseDate(extent[1])];
  8023. }
  8024. return extent;
  8025. };
  8026. c3_chart_internal_fn.initText = function () {
  8027. var $$ = this;
  8028. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartTexts);
  8029. $$.mainText = $$.d3.selectAll([]);
  8030. };
  8031. c3_chart_internal_fn.updateTargetsForText = function (targets) {
  8032. var $$ = this,
  8033. mainTextUpdate,
  8034. mainTextEnter,
  8035. classChartText = $$.classChartText.bind($$),
  8036. classTexts = $$.classTexts.bind($$),
  8037. classFocus = $$.classFocus.bind($$);
  8038. mainTextUpdate = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText).data(targets).attr('class', function (d) {
  8039. return classChartText(d) + classFocus(d);
  8040. });
  8041. mainTextEnter = mainTextUpdate.enter().append('g').attr('class', classChartText).style('opacity', 0).style("pointer-events", "none");
  8042. mainTextEnter.append('g').attr('class', classTexts);
  8043. };
  8044. c3_chart_internal_fn.updateText = function (durationForExit) {
  8045. var $$ = this,
  8046. config = $$.config,
  8047. barOrLineData = $$.barOrLineData.bind($$),
  8048. classText = $$.classText.bind($$);
  8049. $$.mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text).data(barOrLineData);
  8050. $$.mainText.enter().append('text').attr("class", classText).attr('text-anchor', function (d) {
  8051. return config.axis_rotated ? d.value < 0 ? 'end' : 'start' : 'middle';
  8052. }).style("stroke", 'none').style("fill", function (d) {
  8053. return $$.color(d);
  8054. }).style("fill-opacity", 0);
  8055. $$.mainText.text(function (d, i, j) {
  8056. return $$.dataLabelFormat(d.id)(d.value, d.id, i, j);
  8057. });
  8058. $$.mainText.exit().transition().duration(durationForExit).style('fill-opacity', 0).remove();
  8059. };
  8060. c3_chart_internal_fn.redrawText = function (xForText, yForText, forFlow, withTransition) {
  8061. return [(withTransition ? this.mainText.transition() : this.mainText).attr('x', xForText).attr('y', yForText).style("fill", this.color).style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this))];
  8062. };
  8063. c3_chart_internal_fn.getTextRect = function (text, cls, element) {
  8064. var dummy = this.d3.select('body').append('div').classed('c3', true),
  8065. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0),
  8066. font = this.d3.select(element).style('font'),
  8067. rect;
  8068. svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : "", true).style('font', font).text(text).each(function () {
  8069. rect = this.getBoundingClientRect();
  8070. });
  8071. dummy.remove();
  8072. return rect;
  8073. };
  8074. c3_chart_internal_fn.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {
  8075. var $$ = this,
  8076. getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),
  8077. getBarPoints = $$.generateGetBarPoints(barIndices, false),
  8078. getLinePoints = $$.generateGetLinePoints(lineIndices, false),
  8079. getter = forX ? $$.getXForText : $$.getYForText;
  8080. return function (d, i) {
  8081. var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints;
  8082. return getter.call($$, getPoints(d, i), d, this);
  8083. };
  8084. };
  8085. c3_chart_internal_fn.getXForText = function (points, d, textElement) {
  8086. var $$ = this,
  8087. box = textElement.getBoundingClientRect(),
  8088. xPos,
  8089. padding;
  8090. if ($$.config.axis_rotated) {
  8091. padding = $$.isBarType(d) ? 4 : 6;
  8092. xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);
  8093. } else {
  8094. xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];
  8095. }
  8096. // show labels regardless of the domain if value is null
  8097. if (d.value === null) {
  8098. if (xPos > $$.width) {
  8099. xPos = $$.width - box.width;
  8100. } else if (xPos < 0) {
  8101. xPos = 4;
  8102. }
  8103. }
  8104. return xPos;
  8105. };
  8106. c3_chart_internal_fn.getYForText = function (points, d, textElement) {
  8107. var $$ = this,
  8108. box = textElement.getBoundingClientRect(),
  8109. yPos;
  8110. if ($$.config.axis_rotated) {
  8111. yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;
  8112. } else {
  8113. yPos = points[2][1];
  8114. if (d.value < 0 || d.value === 0 && !$$.hasPositiveValue) {
  8115. yPos += box.height;
  8116. if ($$.isBarType(d) && $$.isSafari()) {
  8117. yPos -= 3;
  8118. } else if (!$$.isBarType(d) && $$.isChrome()) {
  8119. yPos += 3;
  8120. }
  8121. } else {
  8122. yPos += $$.isBarType(d) ? -3 : -6;
  8123. }
  8124. }
  8125. // show labels regardless of the domain if value is null
  8126. if (d.value === null && !$$.config.axis_rotated) {
  8127. if (yPos < box.height) {
  8128. yPos = box.height;
  8129. } else if (yPos > this.height) {
  8130. yPos = this.height - 4;
  8131. }
  8132. }
  8133. return yPos;
  8134. };
  8135. c3_chart_internal_fn.initTitle = function () {
  8136. var $$ = this;
  8137. $$.title = $$.svg.append("text").text($$.config.title_text).attr("class", $$.CLASS.title);
  8138. };
  8139. c3_chart_internal_fn.redrawTitle = function () {
  8140. var $$ = this;
  8141. $$.title.attr("x", $$.xForTitle.bind($$)).attr("y", $$.yForTitle.bind($$));
  8142. };
  8143. c3_chart_internal_fn.xForTitle = function () {
  8144. var $$ = this,
  8145. config = $$.config,
  8146. position = config.title_position || 'left',
  8147. x;
  8148. if (position.indexOf('right') >= 0) {
  8149. x = $$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width - config.title_padding.right;
  8150. } else if (position.indexOf('center') >= 0) {
  8151. x = ($$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) / 2;
  8152. } else {
  8153. // left
  8154. x = config.title_padding.left;
  8155. }
  8156. return x;
  8157. };
  8158. c3_chart_internal_fn.yForTitle = function () {
  8159. var $$ = this;
  8160. return $$.config.title_padding.top + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).height;
  8161. };
  8162. c3_chart_internal_fn.getTitlePadding = function () {
  8163. var $$ = this;
  8164. return $$.yForTitle() + $$.config.title_padding.bottom;
  8165. };
  8166. c3_chart_internal_fn.initTooltip = function () {
  8167. var $$ = this,
  8168. config = $$.config,
  8169. i;
  8170. $$.tooltip = $$.selectChart.style("position", "relative").append("div").attr('class', CLASS.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none");
  8171. // Show tooltip if needed
  8172. if (config.tooltip_init_show) {
  8173. if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {
  8174. config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);
  8175. for (i = 0; i < $$.data.targets[0].values.length; i++) {
  8176. if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {
  8177. break;
  8178. }
  8179. }
  8180. config.tooltip_init_x = i;
  8181. }
  8182. $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {
  8183. return $$.addName(d.values[config.tooltip_init_x]);
  8184. }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));
  8185. $$.tooltip.style("top", config.tooltip_init_position.top).style("left", config.tooltip_init_position.left).style("display", "block");
  8186. }
  8187. };
  8188. c3_chart_internal_fn.getTooltipSortFunction = function () {
  8189. var $$ = this,
  8190. config = $$.config;
  8191. if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {
  8192. // if data are not grouped or if an order is specified
  8193. // for the tooltip values we sort them by their values
  8194. var order = config.tooltip_order;
  8195. if (order === undefined) {
  8196. order = config.data_order;
  8197. }
  8198. var valueOf = function valueOf(obj) {
  8199. return obj ? obj.value : null;
  8200. };
  8201. // if data are not grouped, we sort them by their value
  8202. if (isString(order) && order.toLowerCase() === 'asc') {
  8203. return function (a, b) {
  8204. return valueOf(a) - valueOf(b);
  8205. };
  8206. } else if (isString(order) && order.toLowerCase() === 'desc') {
  8207. return function (a, b) {
  8208. return valueOf(b) - valueOf(a);
  8209. };
  8210. } else if (isFunction(order)) {
  8211. // if the function is from data_order we need
  8212. // to wrap the returned function in order to format
  8213. // the sorted value to the expected format
  8214. var sortFunction = order;
  8215. if (config.tooltip_order === undefined) {
  8216. sortFunction = function sortFunction(a, b) {
  8217. return order(a ? {
  8218. id: a.id,
  8219. values: [a]
  8220. } : null, b ? {
  8221. id: b.id,
  8222. values: [b]
  8223. } : null);
  8224. };
  8225. }
  8226. return sortFunction;
  8227. } else if (isArray(order)) {
  8228. return function (a, b) {
  8229. return order.indexOf(a.id) - order.indexOf(b.id);
  8230. };
  8231. }
  8232. } else {
  8233. // if data are grouped, we follow the order of grouped targets
  8234. var ids = $$.orderTargets($$.data.targets).map(function (i) {
  8235. return i.id;
  8236. });
  8237. // if it was either asc or desc we need to invert the order
  8238. // returned by orderTargets
  8239. if ($$.isOrderAsc() || $$.isOrderDesc()) {
  8240. ids = ids.reverse();
  8241. }
  8242. return function (a, b) {
  8243. return ids.indexOf(a.id) - ids.indexOf(b.id);
  8244. };
  8245. }
  8246. };
  8247. c3_chart_internal_fn.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {
  8248. var $$ = this,
  8249. config = $$.config,
  8250. titleFormat = config.tooltip_format_title || defaultTitleFormat,
  8251. nameFormat = config.tooltip_format_name || function (name) {
  8252. return name;
  8253. },
  8254. valueFormat = config.tooltip_format_value || defaultValueFormat,
  8255. text,
  8256. i,
  8257. title,
  8258. value,
  8259. name,
  8260. bgcolor;
  8261. var tooltipSortFunction = this.getTooltipSortFunction();
  8262. if (tooltipSortFunction) {
  8263. d.sort(tooltipSortFunction);
  8264. }
  8265. for (i = 0; i < d.length; i++) {
  8266. if (!(d[i] && (d[i].value || d[i].value === 0))) {
  8267. continue;
  8268. }
  8269. if (!text) {
  8270. title = sanitise(titleFormat ? titleFormat(d[i].x) : d[i].x);
  8271. text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
  8272. }
  8273. value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));
  8274. if (value !== undefined) {
  8275. // Skip elements when their name is set to null
  8276. if (d[i].name === null) {
  8277. continue;
  8278. }
  8279. name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));
  8280. bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
  8281. text += "<tr class='" + $$.CLASS.tooltipName + "-" + $$.getTargetSelectorSuffix(d[i].id) + "'>";
  8282. text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
  8283. text += "<td class='value'>" + value + "</td>";
  8284. text += "</tr>";
  8285. }
  8286. }
  8287. return text + "</table>";
  8288. };
  8289. c3_chart_internal_fn.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {
  8290. var $$ = this,
  8291. config = $$.config,
  8292. d3 = $$.d3;
  8293. var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
  8294. var forArc = $$.hasArcType(),
  8295. mouse = d3.mouse(element);
  8296. // Determin tooltip position
  8297. if (forArc) {
  8298. tooltipLeft = ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];
  8299. tooltipTop = $$.height / 2 + mouse[1] + 20;
  8300. } else {
  8301. svgLeft = $$.getSvgLeft(true);
  8302. if (config.axis_rotated) {
  8303. tooltipLeft = svgLeft + mouse[0] + 100;
  8304. tooltipRight = tooltipLeft + tWidth;
  8305. chartRight = $$.currentWidth - $$.getCurrentPaddingRight();
  8306. tooltipTop = $$.x(dataToShow[0].x) + 20;
  8307. } else {
  8308. tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;
  8309. tooltipRight = tooltipLeft + tWidth;
  8310. chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();
  8311. tooltipTop = mouse[1] + 15;
  8312. }
  8313. if (tooltipRight > chartRight) {
  8314. // 20 is needed for Firefox to keep tooltip width
  8315. tooltipLeft -= tooltipRight - chartRight + 20;
  8316. }
  8317. if (tooltipTop + tHeight > $$.currentHeight) {
  8318. tooltipTop -= tHeight + 30;
  8319. }
  8320. }
  8321. if (tooltipTop < 0) {
  8322. tooltipTop = 0;
  8323. }
  8324. return { top: tooltipTop, left: tooltipLeft };
  8325. };
  8326. c3_chart_internal_fn.showTooltip = function (selectedData, element) {
  8327. var $$ = this,
  8328. config = $$.config;
  8329. var tWidth, tHeight, position;
  8330. var forArc = $$.hasArcType(),
  8331. dataToShow = selectedData.filter(function (d) {
  8332. return d && isValue(d.value);
  8333. }),
  8334. positionFunction = config.tooltip_position || c3_chart_internal_fn.tooltipPosition;
  8335. if (dataToShow.length === 0 || !config.tooltip_show) {
  8336. return;
  8337. }
  8338. $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block");
  8339. // Get tooltip dimensions
  8340. tWidth = $$.tooltip.property('offsetWidth');
  8341. tHeight = $$.tooltip.property('offsetHeight');
  8342. position = positionFunction.call(this, dataToShow, tWidth, tHeight, element);
  8343. // Set tooltip
  8344. $$.tooltip.style("top", position.top + "px").style("left", position.left + 'px');
  8345. };
  8346. c3_chart_internal_fn.hideTooltip = function () {
  8347. this.tooltip.style("display", "none");
  8348. };
  8349. c3_chart_internal_fn.setTargetType = function (targetIds, type) {
  8350. var $$ = this,
  8351. config = $$.config;
  8352. $$.mapToTargetIds(targetIds).forEach(function (id) {
  8353. $$.withoutFadeIn[id] = type === config.data_types[id];
  8354. config.data_types[id] = type;
  8355. });
  8356. if (!targetIds) {
  8357. config.data_type = type;
  8358. }
  8359. };
  8360. c3_chart_internal_fn.hasType = function (type, targets) {
  8361. var $$ = this,
  8362. types = $$.config.data_types,
  8363. has = false;
  8364. targets = targets || $$.data.targets;
  8365. if (targets && targets.length) {
  8366. targets.forEach(function (target) {
  8367. var t = types[target.id];
  8368. if (t && t.indexOf(type) >= 0 || !t && type === 'line') {
  8369. has = true;
  8370. }
  8371. });
  8372. } else if (Object.keys(types).length) {
  8373. Object.keys(types).forEach(function (id) {
  8374. if (types[id] === type) {
  8375. has = true;
  8376. }
  8377. });
  8378. } else {
  8379. has = $$.config.data_type === type;
  8380. }
  8381. return has;
  8382. };
  8383. c3_chart_internal_fn.hasArcType = function (targets) {
  8384. return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets);
  8385. };
  8386. c3_chart_internal_fn.isLineType = function (d) {
  8387. var config = this.config,
  8388. id = isString(d) ? d : d.id;
  8389. return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0;
  8390. };
  8391. c3_chart_internal_fn.isStepType = function (d) {
  8392. var id = isString(d) ? d : d.id;
  8393. return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  8394. };
  8395. c3_chart_internal_fn.isSplineType = function (d) {
  8396. var id = isString(d) ? d : d.id;
  8397. return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;
  8398. };
  8399. c3_chart_internal_fn.isAreaType = function (d) {
  8400. var id = isString(d) ? d : d.id;
  8401. return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  8402. };
  8403. c3_chart_internal_fn.isBarType = function (d) {
  8404. var id = isString(d) ? d : d.id;
  8405. return this.config.data_types[id] === 'bar';
  8406. };
  8407. c3_chart_internal_fn.isScatterType = function (d) {
  8408. var id = isString(d) ? d : d.id;
  8409. return this.config.data_types[id] === 'scatter';
  8410. };
  8411. c3_chart_internal_fn.isPieType = function (d) {
  8412. var id = isString(d) ? d : d.id;
  8413. return this.config.data_types[id] === 'pie';
  8414. };
  8415. c3_chart_internal_fn.isGaugeType = function (d) {
  8416. var id = isString(d) ? d : d.id;
  8417. return this.config.data_types[id] === 'gauge';
  8418. };
  8419. c3_chart_internal_fn.isDonutType = function (d) {
  8420. var id = isString(d) ? d : d.id;
  8421. return this.config.data_types[id] === 'donut';
  8422. };
  8423. c3_chart_internal_fn.isArcType = function (d) {
  8424. return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);
  8425. };
  8426. c3_chart_internal_fn.lineData = function (d) {
  8427. return this.isLineType(d) ? [d] : [];
  8428. };
  8429. c3_chart_internal_fn.arcData = function (d) {
  8430. return this.isArcType(d.data) ? [d] : [];
  8431. };
  8432. /* not used
  8433. function scatterData(d) {
  8434. return isScatterType(d) ? d.values : [];
  8435. }
  8436. */
  8437. c3_chart_internal_fn.barData = function (d) {
  8438. return this.isBarType(d) ? d.values : [];
  8439. };
  8440. c3_chart_internal_fn.lineOrScatterData = function (d) {
  8441. return this.isLineType(d) || this.isScatterType(d) ? d.values : [];
  8442. };
  8443. c3_chart_internal_fn.barOrLineData = function (d) {
  8444. return this.isBarType(d) || this.isLineType(d) ? d.values : [];
  8445. };
  8446. c3_chart_internal_fn.isInterpolationType = function (type) {
  8447. return ['linear', 'linear-closed', 'basis', 'basis-open', 'basis-closed', 'bundle', 'cardinal', 'cardinal-open', 'cardinal-closed', 'monotone'].indexOf(type) >= 0;
  8448. };
  8449. c3_chart_internal_fn.isSafari = function () {
  8450. var ua = window.navigator.userAgent;
  8451. return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0;
  8452. };
  8453. c3_chart_internal_fn.isChrome = function () {
  8454. var ua = window.navigator.userAgent;
  8455. return ua.indexOf('Chrome') >= 0;
  8456. };
  8457. c3_chart_internal_fn.initZoom = function () {
  8458. var $$ = this,
  8459. d3 = $$.d3,
  8460. config = $$.config,
  8461. startEvent;
  8462. $$.zoom = d3.behavior.zoom().on("zoomstart", function () {
  8463. startEvent = d3.event.sourceEvent;
  8464. $$.zoom.altDomain = d3.event.sourceEvent.altKey ? $$.x.orgDomain() : null;
  8465. config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);
  8466. }).on("zoom", function () {
  8467. $$.redrawForZoom.call($$);
  8468. }).on('zoomend', function () {
  8469. var event = d3.event.sourceEvent;
  8470. // if click, do nothing. otherwise, click interaction will be canceled.
  8471. if (event && startEvent.clientX === event.clientX && startEvent.clientY === event.clientY) {
  8472. return;
  8473. }
  8474. $$.redrawEventRect();
  8475. $$.updateZoom();
  8476. config.zoom_onzoomend.call($$.api, $$.x.orgDomain());
  8477. });
  8478. $$.zoom.scale = function (scale) {
  8479. return config.axis_rotated ? this.y(scale) : this.x(scale);
  8480. };
  8481. $$.zoom.orgScaleExtent = function () {
  8482. var extent = config.zoom_extent ? config.zoom_extent : [1, 10];
  8483. return [extent[0], Math.max($$.getMaxDataCount() / extent[1], extent[1])];
  8484. };
  8485. $$.zoom.updateScaleExtent = function () {
  8486. var ratio = diffDomain($$.x.orgDomain()) / diffDomain($$.getZoomDomain()),
  8487. extent = this.orgScaleExtent();
  8488. this.scaleExtent([extent[0] * ratio, extent[1] * ratio]);
  8489. return this;
  8490. };
  8491. };
  8492. c3_chart_internal_fn.getZoomDomain = function () {
  8493. var $$ = this,
  8494. config = $$.config,
  8495. d3 = $$.d3,
  8496. min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),
  8497. max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);
  8498. return [min, max];
  8499. };
  8500. c3_chart_internal_fn.updateZoom = function () {
  8501. var $$ = this,
  8502. z = $$.config.zoom_enabled ? $$.zoom : function () {};
  8503. $$.main.select('.' + CLASS.zoomRect).call(z).on("dblclick.zoom", null);
  8504. $$.main.selectAll('.' + CLASS.eventRect).call(z).on("dblclick.zoom", null);
  8505. };
  8506. c3_chart_internal_fn.redrawForZoom = function () {
  8507. var $$ = this,
  8508. d3 = $$.d3,
  8509. config = $$.config,
  8510. zoom = $$.zoom,
  8511. x = $$.x;
  8512. if (!config.zoom_enabled) {
  8513. return;
  8514. }
  8515. if ($$.filterTargetsToShow($$.data.targets).length === 0) {
  8516. return;
  8517. }
  8518. if (d3.event.sourceEvent.type === 'mousemove' && zoom.altDomain) {
  8519. x.domain(zoom.altDomain);
  8520. zoom.scale(x).updateScaleExtent();
  8521. return;
  8522. }
  8523. if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {
  8524. x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);
  8525. }
  8526. $$.redraw({
  8527. withTransition: false,
  8528. withY: config.zoom_rescale,
  8529. withSubchart: false,
  8530. withEventRect: false,
  8531. withDimension: false
  8532. });
  8533. if (d3.event.sourceEvent.type === 'mousemove') {
  8534. $$.cancelClick = true;
  8535. }
  8536. config.zoom_onzoom.call($$.api, x.orgDomain());
  8537. };
  8538. return c3$1;
  8539. })));