c3.js 370 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551
  1. /* @license C3.js v0.7.8 | (c) C3 Team and other contributors | http://c3js.org/ */
  2. (function (global, factory) {
  3. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  4. typeof define === 'function' && define.amd ? define(factory) :
  5. (global = global || self, global.c3 = factory());
  6. }(this, function () { 'use strict';
  7. function _typeof(obj) {
  8. if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
  9. _typeof = function (obj) {
  10. return typeof obj;
  11. };
  12. } else {
  13. _typeof = function (obj) {
  14. return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
  15. };
  16. }
  17. return _typeof(obj);
  18. }
  19. function _classCallCheck(instance, Constructor) {
  20. if (!(instance instanceof Constructor)) {
  21. throw new TypeError("Cannot call a class as a function");
  22. }
  23. }
  24. function _defineProperty(obj, key, value) {
  25. if (key in obj) {
  26. Object.defineProperty(obj, key, {
  27. value: value,
  28. enumerable: true,
  29. configurable: true,
  30. writable: true
  31. });
  32. } else {
  33. obj[key] = value;
  34. }
  35. return obj;
  36. }
  37. function _toConsumableArray(arr) {
  38. return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread();
  39. }
  40. function _arrayWithoutHoles(arr) {
  41. if (Array.isArray(arr)) {
  42. for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
  43. return arr2;
  44. }
  45. }
  46. function _iterableToArray(iter) {
  47. if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter);
  48. }
  49. function _nonIterableSpread() {
  50. throw new TypeError("Invalid attempt to spread non-iterable instance");
  51. }
  52. function ChartInternal(api) {
  53. var $$ = this;
  54. $$.d3 = window.d3 ? window.d3 : typeof require !== 'undefined' ? require("d3") : undefined;
  55. $$.api = api;
  56. $$.config = $$.getDefaultConfig();
  57. $$.data = {};
  58. $$.cache = {};
  59. $$.axes = {};
  60. }
  61. /**
  62. * The Chart class
  63. *
  64. * The methods of this class is the public APIs of the chart object.
  65. */
  66. function Chart(config) {
  67. this.internal = new ChartInternal(this);
  68. this.internal.loadConfig(config);
  69. this.internal.beforeInit(config);
  70. this.internal.init();
  71. this.internal.afterInit(config); // bind "this" to nested API
  72. (function bindThis(fn, target, argThis) {
  73. Object.keys(fn).forEach(function (key) {
  74. target[key] = fn[key].bind(argThis);
  75. if (Object.keys(fn[key]).length > 0) {
  76. bindThis(fn[key], target[key], argThis);
  77. }
  78. });
  79. })(Chart.prototype, this, this);
  80. }
  81. var asHalfPixel = function asHalfPixel(n) {
  82. return Math.ceil(n) + 0.5;
  83. };
  84. var ceil10 = function ceil10(v) {
  85. return Math.ceil(v / 10) * 10;
  86. };
  87. var diffDomain = function diffDomain(d) {
  88. return d[1] - d[0];
  89. };
  90. var getOption = function getOption(options, key, defaultValue) {
  91. return isDefined(options[key]) ? options[key] : defaultValue;
  92. };
  93. var getPathBox = function getPathBox(path) {
  94. var box = getBBox(path),
  95. items = [path.pathSegList.getItem(0), path.pathSegList.getItem(1)],
  96. minX = items[0].x,
  97. minY = Math.min(items[0].y, items[1].y);
  98. return {
  99. x: minX,
  100. y: minY,
  101. width: box.width,
  102. height: box.height
  103. };
  104. };
  105. var getBBox = function getBBox(element) {
  106. try {
  107. return element.getBBox();
  108. } catch (ignore) {
  109. // Firefox will throw an exception if getBBox() is called whereas the
  110. // element is rendered with display:none
  111. // See https://github.com/c3js/c3/issues/2692
  112. // The previous code was using `getBoundingClientRect` which was returning
  113. // everything at 0 in this case so let's reproduce this behavior here.
  114. return {
  115. x: 0,
  116. y: 0,
  117. width: 0,
  118. height: 0
  119. };
  120. }
  121. };
  122. var hasValue = function hasValue(dict, value) {
  123. var found = false;
  124. Object.keys(dict).forEach(function (key) {
  125. if (dict[key] === value) {
  126. found = true;
  127. }
  128. });
  129. return found;
  130. };
  131. var isArray = function isArray(o) {
  132. return Array.isArray(o);
  133. };
  134. var isDefined = function isDefined(v) {
  135. return typeof v !== 'undefined';
  136. };
  137. var isEmpty = function isEmpty(o) {
  138. return typeof o === 'undefined' || o === null || isString(o) && o.length === 0 || _typeof(o) === 'object' && Object.keys(o).length === 0;
  139. };
  140. var isFunction = function isFunction(o) {
  141. return typeof o === 'function';
  142. };
  143. var isNumber = function isNumber(o) {
  144. return typeof o === 'number';
  145. };
  146. var isString = function isString(o) {
  147. return typeof o === 'string';
  148. };
  149. var isUndefined = function isUndefined(v) {
  150. return typeof v === 'undefined';
  151. };
  152. var isValue = function isValue(v) {
  153. return v || v === 0;
  154. };
  155. var notEmpty = function notEmpty(o) {
  156. return !isEmpty(o);
  157. };
  158. var sanitise = function sanitise(str) {
  159. return typeof str === 'string' ? str.replace(/</g, '&lt;').replace(/>/g, '&gt;') : str;
  160. };
  161. var flattenArray = function flattenArray(arr) {
  162. var _ref;
  163. return Array.isArray(arr) ? (_ref = []).concat.apply(_ref, _toConsumableArray(arr)) : [];
  164. };
  165. function AxisInternal(component, params) {
  166. var internal = this;
  167. internal.component = component;
  168. internal.params = params || {};
  169. internal.d3 = component.d3;
  170. internal.scale = internal.d3.scaleLinear();
  171. internal.range;
  172. internal.orient = "bottom";
  173. internal.innerTickSize = 6;
  174. internal.outerTickSize = this.params.withOuterTick ? 6 : 0;
  175. internal.tickPadding = 3;
  176. internal.tickValues = null;
  177. internal.tickFormat;
  178. internal.tickArguments;
  179. internal.tickOffset = 0;
  180. internal.tickCulling = true;
  181. internal.tickCentered;
  182. internal.tickTextCharSize;
  183. internal.tickTextRotate = internal.params.tickTextRotate;
  184. internal.tickLength;
  185. internal.axis = internal.generateAxis();
  186. }
  187. AxisInternal.prototype.axisX = function (selection, x, tickOffset) {
  188. selection.attr("transform", function (d) {
  189. return "translate(" + Math.ceil(x(d) + tickOffset) + ", 0)";
  190. });
  191. };
  192. AxisInternal.prototype.axisY = function (selection, y) {
  193. selection.attr("transform", function (d) {
  194. return "translate(0," + Math.ceil(y(d)) + ")";
  195. });
  196. };
  197. AxisInternal.prototype.scaleExtent = function (domain) {
  198. var start = domain[0],
  199. stop = domain[domain.length - 1];
  200. return start < stop ? [start, stop] : [stop, start];
  201. };
  202. AxisInternal.prototype.generateTicks = function (scale) {
  203. var internal = this;
  204. var i,
  205. domain,
  206. ticks = [];
  207. if (scale.ticks) {
  208. return scale.ticks.apply(scale, internal.tickArguments);
  209. }
  210. domain = scale.domain();
  211. for (i = Math.ceil(domain[0]); i < domain[1]; i++) {
  212. ticks.push(i);
  213. }
  214. if (ticks.length > 0 && ticks[0] > 0) {
  215. ticks.unshift(ticks[0] - (ticks[1] - ticks[0]));
  216. }
  217. return ticks;
  218. };
  219. AxisInternal.prototype.copyScale = function () {
  220. var internal = this;
  221. var newScale = internal.scale.copy(),
  222. domain;
  223. if (internal.params.isCategory) {
  224. domain = internal.scale.domain();
  225. newScale.domain([domain[0], domain[1] - 1]);
  226. }
  227. return newScale;
  228. };
  229. AxisInternal.prototype.textFormatted = function (v) {
  230. var internal = this,
  231. formatted = internal.tickFormat ? internal.tickFormat(v) : v;
  232. return typeof formatted !== 'undefined' ? formatted : '';
  233. };
  234. AxisInternal.prototype.updateRange = function () {
  235. var internal = this;
  236. internal.range = internal.scale.rangeExtent ? internal.scale.rangeExtent() : internal.scaleExtent(internal.scale.range());
  237. return internal.range;
  238. };
  239. AxisInternal.prototype.updateTickTextCharSize = function (tick) {
  240. var internal = this;
  241. if (internal.tickTextCharSize) {
  242. return internal.tickTextCharSize;
  243. }
  244. var size = {
  245. h: 11.5,
  246. w: 5.5
  247. };
  248. tick.select('text').text(function (d) {
  249. return internal.textFormatted(d);
  250. }).each(function (d) {
  251. var box = getBBox(this),
  252. text = internal.textFormatted(d),
  253. h = box.height,
  254. w = text ? box.width / text.length : undefined;
  255. if (h && w) {
  256. size.h = h;
  257. size.w = w;
  258. }
  259. }).text('');
  260. internal.tickTextCharSize = size;
  261. return size;
  262. };
  263. AxisInternal.prototype.isVertical = function () {
  264. return this.orient === 'left' || this.orient === 'right';
  265. };
  266. AxisInternal.prototype.tspanData = function (d, i, scale) {
  267. var internal = this;
  268. var splitted = internal.params.tickMultiline ? internal.splitTickText(d, scale) : [].concat(internal.textFormatted(d));
  269. if (internal.params.tickMultiline && internal.params.tickMultilineMax > 0) {
  270. splitted = internal.ellipsify(splitted, internal.params.tickMultilineMax);
  271. }
  272. return splitted.map(function (s) {
  273. return {
  274. index: i,
  275. splitted: s,
  276. length: splitted.length
  277. };
  278. });
  279. };
  280. AxisInternal.prototype.splitTickText = function (d, scale) {
  281. var internal = this,
  282. tickText = internal.textFormatted(d),
  283. maxWidth = internal.params.tickWidth,
  284. subtext,
  285. spaceIndex,
  286. textWidth,
  287. splitted = [];
  288. if (Object.prototype.toString.call(tickText) === "[object Array]") {
  289. return tickText;
  290. }
  291. if (!maxWidth || maxWidth <= 0) {
  292. maxWidth = internal.isVertical() ? 95 : internal.params.isCategory ? Math.ceil(scale(1) - scale(0)) - 12 : 110;
  293. }
  294. function split(splitted, text) {
  295. spaceIndex = undefined;
  296. for (var i = 1; i < text.length; i++) {
  297. if (text.charAt(i) === ' ') {
  298. spaceIndex = i;
  299. }
  300. subtext = text.substr(0, i + 1);
  301. textWidth = internal.tickTextCharSize.w * subtext.length; // if text width gets over tick width, split by space index or crrent index
  302. if (maxWidth < textWidth) {
  303. return split(splitted.concat(text.substr(0, spaceIndex ? spaceIndex : i)), text.slice(spaceIndex ? spaceIndex + 1 : i));
  304. }
  305. }
  306. return splitted.concat(text);
  307. }
  308. return split(splitted, tickText + "");
  309. };
  310. AxisInternal.prototype.ellipsify = function (splitted, max) {
  311. if (splitted.length <= max) {
  312. return splitted;
  313. }
  314. var ellipsified = splitted.slice(0, max);
  315. var remaining = 3;
  316. for (var i = max - 1; i >= 0; i--) {
  317. var available = ellipsified[i].length;
  318. ellipsified[i] = ellipsified[i].substr(0, available - remaining).padEnd(available, '.');
  319. remaining -= available;
  320. if (remaining <= 0) {
  321. break;
  322. }
  323. }
  324. return ellipsified;
  325. };
  326. AxisInternal.prototype.updateTickLength = function () {
  327. var internal = this;
  328. internal.tickLength = Math.max(internal.innerTickSize, 0) + internal.tickPadding;
  329. };
  330. AxisInternal.prototype.lineY2 = function (d) {
  331. var internal = this,
  332. tickPosition = internal.scale(d) + (internal.tickCentered ? 0 : internal.tickOffset);
  333. return internal.range[0] < tickPosition && tickPosition < internal.range[1] ? internal.innerTickSize : 0;
  334. };
  335. AxisInternal.prototype.textY = function () {
  336. var internal = this,
  337. rotate = internal.tickTextRotate;
  338. return rotate ? 11.5 - 2.5 * (rotate / 15) * (rotate > 0 ? 1 : -1) : internal.tickLength;
  339. };
  340. AxisInternal.prototype.textTransform = function () {
  341. var internal = this,
  342. rotate = internal.tickTextRotate;
  343. return rotate ? "rotate(" + rotate + ")" : "";
  344. };
  345. AxisInternal.prototype.textTextAnchor = function () {
  346. var internal = this,
  347. rotate = internal.tickTextRotate;
  348. return rotate ? rotate > 0 ? "start" : "end" : "middle";
  349. };
  350. AxisInternal.prototype.tspanDx = function () {
  351. var internal = this,
  352. rotate = internal.tickTextRotate;
  353. return rotate ? 8 * Math.sin(Math.PI * (rotate / 180)) : 0;
  354. };
  355. AxisInternal.prototype.tspanDy = function (d, i) {
  356. var internal = this,
  357. dy = internal.tickTextCharSize.h;
  358. if (i === 0) {
  359. if (internal.isVertical()) {
  360. dy = -((d.length - 1) * (internal.tickTextCharSize.h / 2) - 3);
  361. } else {
  362. dy = ".71em";
  363. }
  364. }
  365. return dy;
  366. };
  367. AxisInternal.prototype.generateAxis = function () {
  368. var internal = this,
  369. d3 = internal.d3,
  370. params = internal.params;
  371. function axis(g, transition) {
  372. var self;
  373. g.each(function () {
  374. var g = axis.g = d3.select(this);
  375. var scale0 = this.__chart__ || internal.scale,
  376. scale1 = this.__chart__ = internal.copyScale();
  377. var ticksValues = internal.tickValues ? internal.tickValues : internal.generateTicks(scale1),
  378. ticks = g.selectAll(".tick").data(ticksValues, scale1),
  379. tickEnter = ticks.enter().insert("g", ".domain").attr("class", "tick").style("opacity", 1e-6),
  380. // MEMO: No exit transition. The reason is this transition affects max tick width calculation because old tick will be included in the ticks.
  381. tickExit = ticks.exit().remove(),
  382. tickUpdate = ticks.merge(tickEnter),
  383. tickTransform,
  384. tickX,
  385. tickY;
  386. if (params.isCategory) {
  387. internal.tickOffset = Math.ceil((scale1(1) - scale1(0)) / 2);
  388. tickX = internal.tickCentered ? 0 : internal.tickOffset;
  389. tickY = internal.tickCentered ? internal.tickOffset : 0;
  390. } else {
  391. internal.tickOffset = tickX = 0;
  392. }
  393. internal.updateRange();
  394. internal.updateTickLength();
  395. internal.updateTickTextCharSize(g.select('.tick'));
  396. var lineUpdate = tickUpdate.select("line").merge(tickEnter.append("line")),
  397. textUpdate = tickUpdate.select("text").merge(tickEnter.append("text"));
  398. var tspans = tickUpdate.selectAll('text').selectAll('tspan').data(function (d, i) {
  399. return internal.tspanData(d, i, scale1);
  400. }),
  401. tspanEnter = tspans.enter().append('tspan'),
  402. tspanUpdate = tspanEnter.merge(tspans).text(function (d) {
  403. return d.splitted;
  404. });
  405. tspans.exit().remove();
  406. var path = g.selectAll(".domain").data([0]),
  407. pathUpdate = path.enter().append("path").merge(path).attr("class", "domain"); // TODO: each attr should be one function and change its behavior by internal.orient, probably
  408. switch (internal.orient) {
  409. case "bottom":
  410. {
  411. tickTransform = internal.axisX;
  412. lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) {
  413. return internal.lineY2(d, i);
  414. });
  415. textUpdate.attr("x", 0).attr("y", function (d, i) {
  416. return internal.textY(d, i);
  417. }).attr("transform", function (d, i) {
  418. return internal.textTransform(d, i);
  419. }).style("text-anchor", function (d, i) {
  420. return internal.textTextAnchor(d, i);
  421. });
  422. tspanUpdate.attr('x', 0).attr("dy", function (d, i) {
  423. return internal.tspanDy(d, i);
  424. }).attr('dx', function (d, i) {
  425. return internal.tspanDx(d, i);
  426. });
  427. pathUpdate.attr("d", "M" + internal.range[0] + "," + internal.outerTickSize + "V0H" + internal.range[1] + "V" + internal.outerTickSize);
  428. break;
  429. }
  430. case "top":
  431. {
  432. // TODO: rotated tick text
  433. tickTransform = internal.axisX;
  434. lineUpdate.attr("x1", tickX).attr("x2", tickX).attr("y2", function (d, i) {
  435. return -1 * internal.lineY2(d, i);
  436. });
  437. textUpdate.attr("x", 0).attr("y", function (d, i) {
  438. return -1 * internal.textY(d, i) - (params.isCategory ? 2 : internal.tickLength - 2);
  439. }).attr("transform", function (d, i) {
  440. return internal.textTransform(d, i);
  441. }).style("text-anchor", function (d, i) {
  442. return internal.textTextAnchor(d, i);
  443. });
  444. tspanUpdate.attr('x', 0).attr("dy", function (d, i) {
  445. return internal.tspanDy(d, i);
  446. }).attr('dx', function (d, i) {
  447. return internal.tspanDx(d, i);
  448. });
  449. pathUpdate.attr("d", "M" + internal.range[0] + "," + -internal.outerTickSize + "V0H" + internal.range[1] + "V" + -internal.outerTickSize);
  450. break;
  451. }
  452. case "left":
  453. {
  454. tickTransform = internal.axisY;
  455. lineUpdate.attr("x2", -internal.innerTickSize).attr("y1", tickY).attr("y2", tickY);
  456. textUpdate.attr("x", -internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "end");
  457. tspanUpdate.attr('x', -internal.tickLength).attr("dy", function (d, i) {
  458. return internal.tspanDy(d, i);
  459. });
  460. pathUpdate.attr("d", "M" + -internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + -internal.outerTickSize);
  461. break;
  462. }
  463. case "right":
  464. {
  465. tickTransform = internal.axisY;
  466. lineUpdate.attr("x2", internal.innerTickSize).attr("y1", tickY).attr("y2", tickY);
  467. textUpdate.attr("x", internal.tickLength).attr("y", internal.tickOffset).style("text-anchor", "start");
  468. tspanUpdate.attr('x', internal.tickLength).attr("dy", function (d, i) {
  469. return internal.tspanDy(d, i);
  470. });
  471. pathUpdate.attr("d", "M" + internal.outerTickSize + "," + internal.range[0] + "H0V" + internal.range[1] + "H" + internal.outerTickSize);
  472. break;
  473. }
  474. }
  475. if (scale1.rangeBand) {
  476. var x = scale1,
  477. dx = x.rangeBand() / 2;
  478. scale0 = scale1 = function scale1(d) {
  479. return x(d) + dx;
  480. };
  481. } else if (scale0.rangeBand) {
  482. scale0 = scale1;
  483. } else {
  484. tickExit.call(tickTransform, scale1, internal.tickOffset);
  485. }
  486. tickEnter.call(tickTransform, scale0, internal.tickOffset);
  487. self = (transition ? tickUpdate.transition(transition) : tickUpdate).style('opacity', 1).call(tickTransform, scale1, internal.tickOffset);
  488. });
  489. return self;
  490. }
  491. axis.scale = function (x) {
  492. if (!arguments.length) {
  493. return internal.scale;
  494. }
  495. internal.scale = x;
  496. return axis;
  497. };
  498. axis.orient = function (x) {
  499. if (!arguments.length) {
  500. return internal.orient;
  501. }
  502. internal.orient = x in {
  503. top: 1,
  504. right: 1,
  505. bottom: 1,
  506. left: 1
  507. } ? x + "" : "bottom";
  508. return axis;
  509. };
  510. axis.tickFormat = function (format) {
  511. if (!arguments.length) {
  512. return internal.tickFormat;
  513. }
  514. internal.tickFormat = format;
  515. return axis;
  516. };
  517. axis.tickCentered = function (isCentered) {
  518. if (!arguments.length) {
  519. return internal.tickCentered;
  520. }
  521. internal.tickCentered = isCentered;
  522. return axis;
  523. };
  524. axis.tickOffset = function () {
  525. return internal.tickOffset;
  526. };
  527. axis.tickInterval = function () {
  528. var interval, length;
  529. if (params.isCategory) {
  530. interval = internal.tickOffset * 2;
  531. } else {
  532. length = axis.g.select('path.domain').node().getTotalLength() - internal.outerTickSize * 2;
  533. interval = length / axis.g.selectAll('line').size();
  534. }
  535. return interval === Infinity ? 0 : interval;
  536. };
  537. axis.ticks = function () {
  538. if (!arguments.length) {
  539. return internal.tickArguments;
  540. }
  541. internal.tickArguments = arguments;
  542. return axis;
  543. };
  544. axis.tickCulling = function (culling) {
  545. if (!arguments.length) {
  546. return internal.tickCulling;
  547. }
  548. internal.tickCulling = culling;
  549. return axis;
  550. };
  551. axis.tickValues = function (x) {
  552. if (typeof x === 'function') {
  553. internal.tickValues = function () {
  554. return x(internal.scale.domain());
  555. };
  556. } else {
  557. if (!arguments.length) {
  558. return internal.tickValues;
  559. }
  560. internal.tickValues = x;
  561. }
  562. return axis;
  563. };
  564. return axis;
  565. };
  566. var CLASS = {
  567. target: 'c3-target',
  568. chart: 'c3-chart',
  569. chartLine: 'c3-chart-line',
  570. chartLines: 'c3-chart-lines',
  571. chartBar: 'c3-chart-bar',
  572. chartBars: 'c3-chart-bars',
  573. chartText: 'c3-chart-text',
  574. chartTexts: 'c3-chart-texts',
  575. chartArc: 'c3-chart-arc',
  576. chartArcs: 'c3-chart-arcs',
  577. chartArcsTitle: 'c3-chart-arcs-title',
  578. chartArcsBackground: 'c3-chart-arcs-background',
  579. chartArcsGaugeUnit: 'c3-chart-arcs-gauge-unit',
  580. chartArcsGaugeMax: 'c3-chart-arcs-gauge-max',
  581. chartArcsGaugeMin: 'c3-chart-arcs-gauge-min',
  582. selectedCircle: 'c3-selected-circle',
  583. selectedCircles: 'c3-selected-circles',
  584. eventRect: 'c3-event-rect',
  585. eventRects: 'c3-event-rects',
  586. eventRectsSingle: 'c3-event-rects-single',
  587. eventRectsMultiple: 'c3-event-rects-multiple',
  588. zoomRect: 'c3-zoom-rect',
  589. brush: 'c3-brush',
  590. dragZoom: 'c3-drag-zoom',
  591. focused: 'c3-focused',
  592. defocused: 'c3-defocused',
  593. region: 'c3-region',
  594. regions: 'c3-regions',
  595. title: 'c3-title',
  596. tooltipContainer: 'c3-tooltip-container',
  597. tooltip: 'c3-tooltip',
  598. tooltipName: 'c3-tooltip-name',
  599. shape: 'c3-shape',
  600. shapes: 'c3-shapes',
  601. line: 'c3-line',
  602. lines: 'c3-lines',
  603. bar: 'c3-bar',
  604. bars: 'c3-bars',
  605. circle: 'c3-circle',
  606. circles: 'c3-circles',
  607. arc: 'c3-arc',
  608. arcLabelLine: 'c3-arc-label-line',
  609. arcs: 'c3-arcs',
  610. area: 'c3-area',
  611. areas: 'c3-areas',
  612. empty: 'c3-empty',
  613. text: 'c3-text',
  614. texts: 'c3-texts',
  615. gaugeValue: 'c3-gauge-value',
  616. grid: 'c3-grid',
  617. gridLines: 'c3-grid-lines',
  618. xgrid: 'c3-xgrid',
  619. xgrids: 'c3-xgrids',
  620. xgridLine: 'c3-xgrid-line',
  621. xgridLines: 'c3-xgrid-lines',
  622. xgridFocus: 'c3-xgrid-focus',
  623. ygrid: 'c3-ygrid',
  624. ygrids: 'c3-ygrids',
  625. ygridLine: 'c3-ygrid-line',
  626. ygridLines: 'c3-ygrid-lines',
  627. colorScale: 'c3-colorscale',
  628. stanfordElements: 'c3-stanford-elements',
  629. stanfordLine: 'c3-stanford-line',
  630. stanfordLines: 'c3-stanford-lines',
  631. stanfordRegion: 'c3-stanford-region',
  632. stanfordRegions: 'c3-stanford-regions',
  633. stanfordText: 'c3-stanford-text',
  634. stanfordTexts: 'c3-stanford-texts',
  635. axis: 'c3-axis',
  636. axisX: 'c3-axis-x',
  637. axisXLabel: 'c3-axis-x-label',
  638. axisY: 'c3-axis-y',
  639. axisYLabel: 'c3-axis-y-label',
  640. axisY2: 'c3-axis-y2',
  641. axisY2Label: 'c3-axis-y2-label',
  642. legendBackground: 'c3-legend-background',
  643. legendItem: 'c3-legend-item',
  644. legendItemEvent: 'c3-legend-item-event',
  645. legendItemTile: 'c3-legend-item-tile',
  646. legendItemHidden: 'c3-legend-item-hidden',
  647. legendItemFocused: 'c3-legend-item-focused',
  648. dragarea: 'c3-dragarea',
  649. EXPANDED: '_expanded_',
  650. SELECTED: '_selected_',
  651. INCLUDED: '_included_'
  652. };
  653. var Axis = function Axis(owner) {
  654. _classCallCheck(this, Axis);
  655. this.owner = owner;
  656. this.d3 = owner.d3;
  657. this.internal = AxisInternal;
  658. };
  659. Axis.prototype.init = function init() {
  660. var $$ = this.owner,
  661. config = $$.config,
  662. main = $$.main;
  663. $$.axes.x = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisX).attr("clip-path", config.axis_x_inner ? "" : $$.clipPathForXAxis).attr("transform", $$.getTranslate('x')).style("visibility", config.axis_x_show ? 'visible' : 'hidden');
  664. $$.axes.x.append("text").attr("class", CLASS.axisXLabel).attr("transform", config.axis_rotated ? "rotate(-90)" : "").style("text-anchor", this.textAnchorForXAxisLabel.bind(this));
  665. $$.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');
  666. $$.axes.y.append("text").attr("class", CLASS.axisYLabel).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForYAxisLabel.bind(this));
  667. $$.axes.y2 = main.append("g").attr("class", CLASS.axis + ' ' + CLASS.axisY2) // clip-path?
  668. .attr("transform", $$.getTranslate('y2')).style("visibility", config.axis_y2_show ? 'visible' : 'hidden');
  669. $$.axes.y2.append("text").attr("class", CLASS.axisY2Label).attr("transform", config.axis_rotated ? "" : "rotate(-90)").style("text-anchor", this.textAnchorForY2AxisLabel.bind(this));
  670. };
  671. Axis.prototype.getXAxis = function getXAxis(scale, orient, tickFormat, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  672. var $$ = this.owner,
  673. config = $$.config,
  674. axisParams = {
  675. isCategory: $$.isCategorized(),
  676. withOuterTick: withOuterTick,
  677. tickMultiline: config.axis_x_tick_multiline,
  678. tickMultilineMax: config.axis_x_tick_multiline ? Number(config.axis_x_tick_multilineMax) : 0,
  679. tickWidth: config.axis_x_tick_width,
  680. tickTextRotate: withoutRotateTickText ? 0 : config.axis_x_tick_rotate,
  681. withoutTransition: withoutTransition
  682. },
  683. axis = new this.internal(this, axisParams).axis.scale(scale).orient(orient);
  684. if ($$.isTimeSeries() && tickValues && typeof tickValues !== "function") {
  685. tickValues = tickValues.map(function (v) {
  686. return $$.parseDate(v);
  687. });
  688. } // Set tick
  689. axis.tickFormat(tickFormat).tickValues(tickValues);
  690. if ($$.isCategorized()) {
  691. axis.tickCentered(config.axis_x_tick_centered);
  692. if (isEmpty(config.axis_x_tick_culling)) {
  693. config.axis_x_tick_culling = false;
  694. }
  695. }
  696. return axis;
  697. };
  698. Axis.prototype.updateXAxisTickValues = function updateXAxisTickValues(targets, axis) {
  699. var $$ = this.owner,
  700. config = $$.config,
  701. tickValues;
  702. if (config.axis_x_tick_fit || config.axis_x_tick_count) {
  703. tickValues = this.generateTickValues($$.mapTargetsToUniqueXs(targets), config.axis_x_tick_count, $$.isTimeSeries());
  704. }
  705. if (axis) {
  706. axis.tickValues(tickValues);
  707. } else {
  708. $$.xAxis.tickValues(tickValues);
  709. $$.subXAxis.tickValues(tickValues);
  710. }
  711. return tickValues;
  712. };
  713. Axis.prototype.getYAxis = function getYAxis(axisId, scale, orient, tickValues, withOuterTick, withoutTransition, withoutRotateTickText) {
  714. var $$ = this.owner;
  715. var config = $$.config;
  716. var tickFormat = config["axis_".concat(axisId, "_tick_format")];
  717. if (!tickFormat && $$.isAxisNormalized(axisId)) {
  718. tickFormat = function tickFormat(x) {
  719. return "".concat(x, "%");
  720. };
  721. }
  722. var axis = new this.internal(this, {
  723. withOuterTick: withOuterTick,
  724. withoutTransition: withoutTransition,
  725. tickTextRotate: withoutRotateTickText ? 0 : config.axis_y_tick_rotate
  726. }).axis.scale(scale).orient(orient);
  727. if (tickFormat) {
  728. axis.tickFormat(tickFormat);
  729. }
  730. if ($$.isTimeSeriesY()) {
  731. axis.ticks(config.axis_y_tick_time_type, config.axis_y_tick_time_interval);
  732. } else {
  733. axis.tickValues(tickValues);
  734. }
  735. return axis;
  736. };
  737. Axis.prototype.getId = function getId(id) {
  738. var config = this.owner.config;
  739. return id in config.data_axes ? config.data_axes[id] : 'y';
  740. };
  741. Axis.prototype.getXAxisTickFormat = function getXAxisTickFormat() {
  742. // #2251 previously set any negative values to a whole number,
  743. // however both should be truncated according to the users format specification
  744. var $$ = this.owner,
  745. config = $$.config;
  746. var format = $$.isTimeSeries() ? $$.defaultAxisTimeFormat : $$.isCategorized() ? $$.categoryName : function (v) {
  747. return v;
  748. };
  749. if (config.axis_x_tick_format) {
  750. if (isFunction(config.axis_x_tick_format)) {
  751. format = config.axis_x_tick_format;
  752. } else if ($$.isTimeSeries()) {
  753. format = function format(date) {
  754. return date ? $$.axisTimeFormat(config.axis_x_tick_format)(date) : "";
  755. };
  756. }
  757. }
  758. return isFunction(format) ? function (v) {
  759. return format.call($$, v);
  760. } : format;
  761. };
  762. Axis.prototype.getTickValues = function getTickValues(tickValues, axis) {
  763. return tickValues ? tickValues : axis ? axis.tickValues() : undefined;
  764. };
  765. Axis.prototype.getXAxisTickValues = function getXAxisTickValues() {
  766. return this.getTickValues(this.owner.config.axis_x_tick_values, this.owner.xAxis);
  767. };
  768. Axis.prototype.getYAxisTickValues = function getYAxisTickValues() {
  769. return this.getTickValues(this.owner.config.axis_y_tick_values, this.owner.yAxis);
  770. };
  771. Axis.prototype.getY2AxisTickValues = function getY2AxisTickValues() {
  772. return this.getTickValues(this.owner.config.axis_y2_tick_values, this.owner.y2Axis);
  773. };
  774. Axis.prototype.getLabelOptionByAxisId = function getLabelOptionByAxisId(axisId) {
  775. var $$ = this.owner,
  776. config = $$.config,
  777. option;
  778. if (axisId === 'y') {
  779. option = config.axis_y_label;
  780. } else if (axisId === 'y2') {
  781. option = config.axis_y2_label;
  782. } else if (axisId === 'x') {
  783. option = config.axis_x_label;
  784. }
  785. return option;
  786. };
  787. Axis.prototype.getLabelText = function getLabelText(axisId) {
  788. var option = this.getLabelOptionByAxisId(axisId);
  789. return isString(option) ? option : option ? option.text : null;
  790. };
  791. Axis.prototype.setLabelText = function setLabelText(axisId, text) {
  792. var $$ = this.owner,
  793. config = $$.config,
  794. option = this.getLabelOptionByAxisId(axisId);
  795. if (isString(option)) {
  796. if (axisId === 'y') {
  797. config.axis_y_label = text;
  798. } else if (axisId === 'y2') {
  799. config.axis_y2_label = text;
  800. } else if (axisId === 'x') {
  801. config.axis_x_label = text;
  802. }
  803. } else if (option) {
  804. option.text = text;
  805. }
  806. };
  807. Axis.prototype.getLabelPosition = function getLabelPosition(axisId, defaultPosition) {
  808. var option = this.getLabelOptionByAxisId(axisId),
  809. position = option && _typeof(option) === 'object' && option.position ? option.position : defaultPosition;
  810. return {
  811. isInner: position.indexOf('inner') >= 0,
  812. isOuter: position.indexOf('outer') >= 0,
  813. isLeft: position.indexOf('left') >= 0,
  814. isCenter: position.indexOf('center') >= 0,
  815. isRight: position.indexOf('right') >= 0,
  816. isTop: position.indexOf('top') >= 0,
  817. isMiddle: position.indexOf('middle') >= 0,
  818. isBottom: position.indexOf('bottom') >= 0
  819. };
  820. };
  821. Axis.prototype.getXAxisLabelPosition = function getXAxisLabelPosition() {
  822. return this.getLabelPosition('x', this.owner.config.axis_rotated ? 'inner-top' : 'inner-right');
  823. };
  824. Axis.prototype.getYAxisLabelPosition = function getYAxisLabelPosition() {
  825. return this.getLabelPosition('y', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  826. };
  827. Axis.prototype.getY2AxisLabelPosition = function getY2AxisLabelPosition() {
  828. return this.getLabelPosition('y2', this.owner.config.axis_rotated ? 'inner-right' : 'inner-top');
  829. };
  830. Axis.prototype.getLabelPositionById = function getLabelPositionById(id) {
  831. return id === 'y2' ? this.getY2AxisLabelPosition() : id === 'y' ? this.getYAxisLabelPosition() : this.getXAxisLabelPosition();
  832. };
  833. Axis.prototype.textForXAxisLabel = function textForXAxisLabel() {
  834. return this.getLabelText('x');
  835. };
  836. Axis.prototype.textForYAxisLabel = function textForYAxisLabel() {
  837. return this.getLabelText('y');
  838. };
  839. Axis.prototype.textForY2AxisLabel = function textForY2AxisLabel() {
  840. return this.getLabelText('y2');
  841. };
  842. Axis.prototype.xForAxisLabel = function xForAxisLabel(forHorizontal, position) {
  843. var $$ = this.owner;
  844. if (forHorizontal) {
  845. return position.isLeft ? 0 : position.isCenter ? $$.width / 2 : $$.width;
  846. } else {
  847. return position.isBottom ? -$$.height : position.isMiddle ? -$$.height / 2 : 0;
  848. }
  849. };
  850. Axis.prototype.dxForAxisLabel = function dxForAxisLabel(forHorizontal, position) {
  851. if (forHorizontal) {
  852. return position.isLeft ? "0.5em" : position.isRight ? "-0.5em" : "0";
  853. } else {
  854. return position.isTop ? "-0.5em" : position.isBottom ? "0.5em" : "0";
  855. }
  856. };
  857. Axis.prototype.textAnchorForAxisLabel = function textAnchorForAxisLabel(forHorizontal, position) {
  858. if (forHorizontal) {
  859. return position.isLeft ? 'start' : position.isCenter ? 'middle' : 'end';
  860. } else {
  861. return position.isBottom ? 'start' : position.isMiddle ? 'middle' : 'end';
  862. }
  863. };
  864. Axis.prototype.xForXAxisLabel = function xForXAxisLabel() {
  865. return this.xForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  866. };
  867. Axis.prototype.xForYAxisLabel = function xForYAxisLabel() {
  868. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  869. };
  870. Axis.prototype.xForY2AxisLabel = function xForY2AxisLabel() {
  871. return this.xForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  872. };
  873. Axis.prototype.dxForXAxisLabel = function dxForXAxisLabel() {
  874. return this.dxForAxisLabel(!this.owner.config.axis_rotated, this.getXAxisLabelPosition());
  875. };
  876. Axis.prototype.dxForYAxisLabel = function dxForYAxisLabel() {
  877. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getYAxisLabelPosition());
  878. };
  879. Axis.prototype.dxForY2AxisLabel = function dxForY2AxisLabel() {
  880. return this.dxForAxisLabel(this.owner.config.axis_rotated, this.getY2AxisLabelPosition());
  881. };
  882. Axis.prototype.dyForXAxisLabel = function dyForXAxisLabel() {
  883. var $$ = this.owner,
  884. config = $$.config,
  885. position = this.getXAxisLabelPosition();
  886. if (config.axis_rotated) {
  887. return position.isInner ? "1.2em" : -25 - ($$.config.axis_x_inner ? 0 : this.getMaxTickWidth('x'));
  888. } else {
  889. return position.isInner ? "-0.5em" : $$.getHorizontalAxisHeight('x') - 10;
  890. }
  891. };
  892. Axis.prototype.dyForYAxisLabel = function dyForYAxisLabel() {
  893. var $$ = this.owner,
  894. position = this.getYAxisLabelPosition();
  895. if ($$.config.axis_rotated) {
  896. return position.isInner ? "-0.5em" : "3em";
  897. } else {
  898. return position.isInner ? "1.2em" : -10 - ($$.config.axis_y_inner ? 0 : this.getMaxTickWidth('y') + 10);
  899. }
  900. };
  901. Axis.prototype.dyForY2AxisLabel = function dyForY2AxisLabel() {
  902. var $$ = this.owner,
  903. position = this.getY2AxisLabelPosition();
  904. if ($$.config.axis_rotated) {
  905. return position.isInner ? "1.2em" : "-2.2em";
  906. } else {
  907. return position.isInner ? "-0.5em" : 15 + ($$.config.axis_y2_inner ? 0 : this.getMaxTickWidth('y2') + 15);
  908. }
  909. };
  910. Axis.prototype.textAnchorForXAxisLabel = function textAnchorForXAxisLabel() {
  911. var $$ = this.owner;
  912. return this.textAnchorForAxisLabel(!$$.config.axis_rotated, this.getXAxisLabelPosition());
  913. };
  914. Axis.prototype.textAnchorForYAxisLabel = function textAnchorForYAxisLabel() {
  915. var $$ = this.owner;
  916. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getYAxisLabelPosition());
  917. };
  918. Axis.prototype.textAnchorForY2AxisLabel = function textAnchorForY2AxisLabel() {
  919. var $$ = this.owner;
  920. return this.textAnchorForAxisLabel($$.config.axis_rotated, this.getY2AxisLabelPosition());
  921. };
  922. Axis.prototype.getMaxTickWidth = function getMaxTickWidth(id, withoutRecompute) {
  923. var $$ = this.owner,
  924. maxWidth = 0,
  925. targetsToShow,
  926. scale,
  927. axis,
  928. dummy,
  929. svg;
  930. if (withoutRecompute && $$.currentMaxTickWidths[id]) {
  931. return $$.currentMaxTickWidths[id];
  932. }
  933. if ($$.svg) {
  934. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  935. if (id === 'y') {
  936. scale = $$.y.copy().domain($$.getYDomain(targetsToShow, 'y'));
  937. axis = this.getYAxis(id, scale, $$.yOrient, $$.yAxisTickValues, false, true, true);
  938. } else if (id === 'y2') {
  939. scale = $$.y2.copy().domain($$.getYDomain(targetsToShow, 'y2'));
  940. axis = this.getYAxis(id, scale, $$.y2Orient, $$.y2AxisTickValues, false, true, true);
  941. } else {
  942. scale = $$.x.copy().domain($$.getXDomain(targetsToShow));
  943. axis = this.getXAxis(scale, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, false, true, true);
  944. this.updateXAxisTickValues(targetsToShow, axis);
  945. }
  946. dummy = $$.d3.select('body').append('div').classed('c3', true);
  947. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0), svg.append('g').call(axis).each(function () {
  948. $$.d3.select(this).selectAll('text').each(function () {
  949. var box = getBBox(this);
  950. if (maxWidth < box.width) {
  951. maxWidth = box.width;
  952. }
  953. });
  954. dummy.remove();
  955. });
  956. }
  957. $$.currentMaxTickWidths[id] = maxWidth <= 0 ? $$.currentMaxTickWidths[id] : maxWidth;
  958. return $$.currentMaxTickWidths[id];
  959. };
  960. Axis.prototype.updateLabels = function updateLabels(withTransition) {
  961. var $$ = this.owner;
  962. var axisXLabel = $$.main.select('.' + CLASS.axisX + ' .' + CLASS.axisXLabel),
  963. axisYLabel = $$.main.select('.' + CLASS.axisY + ' .' + CLASS.axisYLabel),
  964. axisY2Label = $$.main.select('.' + CLASS.axisY2 + ' .' + CLASS.axisY2Label);
  965. (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));
  966. (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));
  967. (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));
  968. };
  969. Axis.prototype.getPadding = function getPadding(padding, key, defaultValue, domainLength) {
  970. var p = typeof padding === 'number' ? padding : padding[key];
  971. if (!isValue(p)) {
  972. return defaultValue;
  973. }
  974. if (padding.unit === 'ratio') {
  975. return padding[key] * domainLength;
  976. } // assume padding is pixels if unit is not specified
  977. return this.convertPixelsToAxisPadding(p, domainLength);
  978. };
  979. Axis.prototype.convertPixelsToAxisPadding = function convertPixelsToAxisPadding(pixels, domainLength) {
  980. var $$ = this.owner,
  981. length = $$.config.axis_rotated ? $$.width : $$.height;
  982. return domainLength * (pixels / length);
  983. };
  984. Axis.prototype.generateTickValues = function generateTickValues(values, tickCount, forTimeSeries) {
  985. var tickValues = values,
  986. targetCount,
  987. start,
  988. end,
  989. count,
  990. interval,
  991. i,
  992. tickValue;
  993. if (tickCount) {
  994. targetCount = isFunction(tickCount) ? tickCount() : tickCount; // compute ticks according to tickCount
  995. if (targetCount === 1) {
  996. tickValues = [values[0]];
  997. } else if (targetCount === 2) {
  998. tickValues = [values[0], values[values.length - 1]];
  999. } else if (targetCount > 2) {
  1000. count = targetCount - 2;
  1001. start = values[0];
  1002. end = values[values.length - 1];
  1003. interval = (end - start) / (count + 1); // re-construct unique values
  1004. tickValues = [start];
  1005. for (i = 0; i < count; i++) {
  1006. tickValue = +start + interval * (i + 1);
  1007. tickValues.push(forTimeSeries ? new Date(tickValue) : tickValue);
  1008. }
  1009. tickValues.push(end);
  1010. }
  1011. }
  1012. if (!forTimeSeries) {
  1013. tickValues = tickValues.sort(function (a, b) {
  1014. return a - b;
  1015. });
  1016. }
  1017. return tickValues;
  1018. };
  1019. Axis.prototype.generateTransitions = function generateTransitions(duration) {
  1020. var $$ = this.owner,
  1021. axes = $$.axes;
  1022. return {
  1023. axisX: duration ? axes.x.transition().duration(duration) : axes.x,
  1024. axisY: duration ? axes.y.transition().duration(duration) : axes.y,
  1025. axisY2: duration ? axes.y2.transition().duration(duration) : axes.y2,
  1026. axisSubX: duration ? axes.subx.transition().duration(duration) : axes.subx
  1027. };
  1028. };
  1029. Axis.prototype.redraw = function redraw(duration, isHidden) {
  1030. var $$ = this.owner,
  1031. transition = duration ? $$.d3.transition().duration(duration) : null;
  1032. $$.axes.x.style("opacity", isHidden ? 0 : 1).call($$.xAxis, transition);
  1033. $$.axes.y.style("opacity", isHidden ? 0 : 1).call($$.yAxis, transition);
  1034. $$.axes.y2.style("opacity", isHidden ? 0 : 1).call($$.y2Axis, transition);
  1035. $$.axes.subx.style("opacity", isHidden ? 0 : 1).call($$.subXAxis, transition);
  1036. };
  1037. var c3 = {
  1038. version: "0.7.8",
  1039. chart: {
  1040. fn: Chart.prototype,
  1041. internal: {
  1042. fn: ChartInternal.prototype,
  1043. axis: {
  1044. fn: Axis.prototype,
  1045. internal: {
  1046. fn: AxisInternal.prototype
  1047. }
  1048. }
  1049. }
  1050. },
  1051. generate: function generate(config) {
  1052. return new Chart(config);
  1053. }
  1054. };
  1055. ChartInternal.prototype.beforeInit = function () {// can do something
  1056. };
  1057. ChartInternal.prototype.afterInit = function () {// can do something
  1058. };
  1059. ChartInternal.prototype.init = function () {
  1060. var $$ = this,
  1061. config = $$.config;
  1062. $$.initParams();
  1063. if (config.data_url) {
  1064. $$.convertUrlToData(config.data_url, config.data_mimeType, config.data_headers, config.data_keys, $$.initWithData);
  1065. } else if (config.data_json) {
  1066. $$.initWithData($$.convertJsonToData(config.data_json, config.data_keys));
  1067. } else if (config.data_rows) {
  1068. $$.initWithData($$.convertRowsToData(config.data_rows));
  1069. } else if (config.data_columns) {
  1070. $$.initWithData($$.convertColumnsToData(config.data_columns));
  1071. } else {
  1072. throw Error('url or json or rows or columns is required.');
  1073. }
  1074. };
  1075. ChartInternal.prototype.initParams = function () {
  1076. var $$ = this,
  1077. d3 = $$.d3,
  1078. config = $$.config; // MEMO: clipId needs to be unique because it conflicts when multiple charts exist
  1079. $$.clipId = "c3-" + +new Date() + '-clip';
  1080. $$.clipIdForXAxis = $$.clipId + '-xaxis';
  1081. $$.clipIdForYAxis = $$.clipId + '-yaxis';
  1082. $$.clipIdForGrid = $$.clipId + '-grid';
  1083. $$.clipIdForSubchart = $$.clipId + '-subchart';
  1084. $$.clipPath = $$.getClipPath($$.clipId);
  1085. $$.clipPathForXAxis = $$.getClipPath($$.clipIdForXAxis);
  1086. $$.clipPathForYAxis = $$.getClipPath($$.clipIdForYAxis);
  1087. $$.clipPathForGrid = $$.getClipPath($$.clipIdForGrid);
  1088. $$.clipPathForSubchart = $$.getClipPath($$.clipIdForSubchart);
  1089. $$.dragStart = null;
  1090. $$.dragging = false;
  1091. $$.flowing = false;
  1092. $$.cancelClick = false;
  1093. $$.mouseover = false;
  1094. $$.transiting = false;
  1095. $$.color = $$.generateColor();
  1096. $$.levelColor = $$.generateLevelColor();
  1097. $$.dataTimeParse = (config.data_xLocaltime ? d3.timeParse : d3.utcParse)($$.config.data_xFormat);
  1098. $$.axisTimeFormat = config.axis_x_localtime ? d3.timeFormat : d3.utcFormat;
  1099. $$.defaultAxisTimeFormat = function (date) {
  1100. if (date.getMilliseconds()) {
  1101. return d3.timeFormat(".%L")(date);
  1102. }
  1103. if (date.getSeconds()) {
  1104. return d3.timeFormat(":%S")(date);
  1105. }
  1106. if (date.getMinutes()) {
  1107. return d3.timeFormat("%I:%M")(date);
  1108. }
  1109. if (date.getHours()) {
  1110. return d3.timeFormat("%I %p")(date);
  1111. }
  1112. if (date.getDay() && date.getDate() !== 1) {
  1113. return d3.timeFormat("%-m/%-d")(date);
  1114. }
  1115. if (date.getDate() !== 1) {
  1116. return d3.timeFormat("%-m/%-d")(date);
  1117. }
  1118. if (date.getMonth()) {
  1119. return d3.timeFormat("%-m/%-d")(date);
  1120. }
  1121. return d3.timeFormat("%Y/%-m/%-d")(date);
  1122. };
  1123. $$.hiddenTargetIds = [];
  1124. $$.hiddenLegendIds = [];
  1125. $$.focusedTargetIds = [];
  1126. $$.defocusedTargetIds = [];
  1127. $$.xOrient = config.axis_rotated ? config.axis_x_inner ? "right" : "left" : config.axis_x_inner ? "top" : "bottom";
  1128. $$.yOrient = config.axis_rotated ? config.axis_y_inner ? "top" : "bottom" : config.axis_y_inner ? "right" : "left";
  1129. $$.y2Orient = config.axis_rotated ? config.axis_y2_inner ? "bottom" : "top" : config.axis_y2_inner ? "left" : "right";
  1130. $$.subXOrient = config.axis_rotated ? "left" : "bottom";
  1131. $$.isLegendRight = config.legend_position === 'right';
  1132. $$.isLegendInset = config.legend_position === 'inset';
  1133. $$.isLegendTop = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'top-right';
  1134. $$.isLegendLeft = config.legend_inset_anchor === 'top-left' || config.legend_inset_anchor === 'bottom-left';
  1135. $$.legendStep = 0;
  1136. $$.legendItemWidth = 0;
  1137. $$.legendItemHeight = 0;
  1138. $$.currentMaxTickWidths = {
  1139. x: 0,
  1140. y: 0,
  1141. y2: 0
  1142. };
  1143. $$.rotated_padding_left = 30;
  1144. $$.rotated_padding_right = config.axis_rotated && !config.axis_x_show ? 0 : 30;
  1145. $$.rotated_padding_top = 5;
  1146. $$.withoutFadeIn = {};
  1147. $$.intervalForObserveInserted = undefined;
  1148. $$.axes.subx = d3.selectAll([]); // needs when excluding subchart.js
  1149. };
  1150. ChartInternal.prototype.initChartElements = function () {
  1151. if (this.initBar) {
  1152. this.initBar();
  1153. }
  1154. if (this.initLine) {
  1155. this.initLine();
  1156. }
  1157. if (this.initArc) {
  1158. this.initArc();
  1159. }
  1160. if (this.initGauge) {
  1161. this.initGauge();
  1162. }
  1163. if (this.initText) {
  1164. this.initText();
  1165. }
  1166. };
  1167. ChartInternal.prototype.initWithData = function (data) {
  1168. var $$ = this,
  1169. d3 = $$.d3,
  1170. config = $$.config;
  1171. var defs,
  1172. main,
  1173. binding = true;
  1174. $$.axis = new Axis($$);
  1175. if (!config.bindto) {
  1176. $$.selectChart = d3.selectAll([]);
  1177. } else if (typeof config.bindto.node === 'function') {
  1178. $$.selectChart = config.bindto;
  1179. } else {
  1180. $$.selectChart = d3.select(config.bindto);
  1181. }
  1182. if ($$.selectChart.empty()) {
  1183. $$.selectChart = d3.select(document.createElement('div')).style('opacity', 0);
  1184. $$.observeInserted($$.selectChart);
  1185. binding = false;
  1186. }
  1187. $$.selectChart.html("").classed("c3", true); // Init data as targets
  1188. $$.data.xs = {};
  1189. $$.data.targets = $$.convertDataToTargets(data);
  1190. if (config.data_filter) {
  1191. $$.data.targets = $$.data.targets.filter(config.data_filter);
  1192. } // Set targets to hide if needed
  1193. if (config.data_hide) {
  1194. $$.addHiddenTargetIds(config.data_hide === true ? $$.mapToIds($$.data.targets) : config.data_hide);
  1195. }
  1196. if (config.legend_hide) {
  1197. $$.addHiddenLegendIds(config.legend_hide === true ? $$.mapToIds($$.data.targets) : config.legend_hide);
  1198. }
  1199. if ($$.isStanfordGraphType()) {
  1200. $$.initStanfordData();
  1201. } // Init sizes and scales
  1202. $$.updateSizes();
  1203. $$.updateScales(); // Set domains for each scale
  1204. $$.x.domain(d3.extent($$.getXDomain($$.data.targets)));
  1205. $$.y.domain($$.getYDomain($$.data.targets, 'y'));
  1206. $$.y2.domain($$.getYDomain($$.data.targets, 'y2'));
  1207. $$.subX.domain($$.x.domain());
  1208. $$.subY.domain($$.y.domain());
  1209. $$.subY2.domain($$.y2.domain()); // Save original x domain for zoom update
  1210. $$.orgXDomain = $$.x.domain();
  1211. /*-- Basic Elements --*/
  1212. // Define svgs
  1213. $$.svg = $$.selectChart.append("svg").style("overflow", "hidden").on('mouseenter', function () {
  1214. return config.onmouseover.call($$);
  1215. }).on('mouseleave', function () {
  1216. return config.onmouseout.call($$);
  1217. });
  1218. if ($$.config.svg_classname) {
  1219. $$.svg.attr('class', $$.config.svg_classname);
  1220. } // Define defs
  1221. defs = $$.svg.append("defs");
  1222. $$.clipChart = $$.appendClip(defs, $$.clipId);
  1223. $$.clipXAxis = $$.appendClip(defs, $$.clipIdForXAxis);
  1224. $$.clipYAxis = $$.appendClip(defs, $$.clipIdForYAxis);
  1225. $$.clipGrid = $$.appendClip(defs, $$.clipIdForGrid);
  1226. $$.clipSubchart = $$.appendClip(defs, $$.clipIdForSubchart);
  1227. $$.updateSvgSize(); // Define regions
  1228. main = $$.main = $$.svg.append("g").attr("transform", $$.getTranslate('main'));
  1229. if ($$.initPie) {
  1230. $$.initPie();
  1231. }
  1232. if ($$.initDragZoom) {
  1233. $$.initDragZoom();
  1234. }
  1235. if ($$.initSubchart) {
  1236. $$.initSubchart();
  1237. }
  1238. if ($$.initTooltip) {
  1239. $$.initTooltip();
  1240. }
  1241. if ($$.initLegend) {
  1242. $$.initLegend();
  1243. }
  1244. if ($$.initTitle) {
  1245. $$.initTitle();
  1246. }
  1247. if ($$.initZoom) {
  1248. $$.initZoom();
  1249. }
  1250. if ($$.isStanfordGraphType()) {
  1251. $$.drawColorScale();
  1252. } // Update selection based on size and scale
  1253. // TODO: currently this must be called after initLegend because of update of sizes, but it should be done in initSubchart.
  1254. if ($$.initSubchartBrush) {
  1255. $$.initSubchartBrush();
  1256. }
  1257. /*-- Main Region --*/
  1258. // text when empty
  1259. main.append("text").attr("class", CLASS.text + ' ' + CLASS.empty).attr("text-anchor", "middle") // horizontal centering of text at x position in all browsers.
  1260. .attr("dominant-baseline", "middle"); // vertical centering of text at y position in all browsers, except IE.
  1261. // Regions
  1262. $$.initRegion(); // Grids
  1263. $$.initGrid(); // Define g for chart area
  1264. main.append('g').attr("clip-path", $$.clipPath).attr('class', CLASS.chart); // Grid lines
  1265. if (config.grid_lines_front) {
  1266. $$.initGridLines();
  1267. }
  1268. $$.initStanfordElements(); // Cover whole with rects for events
  1269. $$.initEventRect(); // Define g for chart
  1270. $$.initChartElements(); // Add Axis
  1271. $$.axis.init(); // Set targets
  1272. $$.updateTargets($$.data.targets); // Set default extent if defined
  1273. if (config.axis_x_selection) {
  1274. $$.brush.selectionAsValue($$.getDefaultSelection());
  1275. } // Draw with targets
  1276. if (binding) {
  1277. $$.updateDimension();
  1278. $$.config.oninit.call($$);
  1279. $$.redraw({
  1280. withTransition: false,
  1281. withTransform: true,
  1282. withUpdateXDomain: true,
  1283. withUpdateOrgXDomain: true,
  1284. withTransitionForAxis: false
  1285. });
  1286. } // Bind to resize event
  1287. $$.bindResize(); // Bind to window focus event
  1288. $$.bindWindowFocus(); // export element of the chart
  1289. $$.api.element = $$.selectChart.node();
  1290. };
  1291. ChartInternal.prototype.smoothLines = function (el, type) {
  1292. var $$ = this;
  1293. if (type === 'grid') {
  1294. el.each(function () {
  1295. var g = $$.d3.select(this),
  1296. x1 = g.attr('x1'),
  1297. x2 = g.attr('x2'),
  1298. y1 = g.attr('y1'),
  1299. y2 = g.attr('y2');
  1300. g.attr({
  1301. 'x1': Math.ceil(x1),
  1302. 'x2': Math.ceil(x2),
  1303. 'y1': Math.ceil(y1),
  1304. 'y2': Math.ceil(y2)
  1305. });
  1306. });
  1307. }
  1308. };
  1309. ChartInternal.prototype.updateSizes = function () {
  1310. var $$ = this,
  1311. config = $$.config;
  1312. var legendHeight = $$.legend ? $$.getLegendHeight() : 0,
  1313. legendWidth = $$.legend ? $$.getLegendWidth() : 0,
  1314. legendHeightForBottom = $$.isLegendRight || $$.isLegendInset ? 0 : legendHeight,
  1315. hasArc = $$.hasArcType(),
  1316. xAxisHeight = config.axis_rotated || hasArc ? 0 : $$.getHorizontalAxisHeight('x'),
  1317. subchartHeight = config.subchart_show && !hasArc ? config.subchart_size_height + xAxisHeight : 0;
  1318. $$.currentWidth = $$.getCurrentWidth();
  1319. $$.currentHeight = $$.getCurrentHeight(); // for main
  1320. $$.margin = config.axis_rotated ? {
  1321. top: $$.getHorizontalAxisHeight('y2') + $$.getCurrentPaddingTop(),
  1322. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1323. bottom: $$.getHorizontalAxisHeight('y') + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1324. left: subchartHeight + (hasArc ? 0 : $$.getCurrentPaddingLeft())
  1325. } : {
  1326. top: 4 + $$.getCurrentPaddingTop(),
  1327. // for top tick text
  1328. right: hasArc ? 0 : $$.getCurrentPaddingRight(),
  1329. bottom: xAxisHeight + subchartHeight + legendHeightForBottom + $$.getCurrentPaddingBottom(),
  1330. left: hasArc ? 0 : $$.getCurrentPaddingLeft()
  1331. }; // for subchart
  1332. $$.margin2 = config.axis_rotated ? {
  1333. top: $$.margin.top,
  1334. right: NaN,
  1335. bottom: 20 + legendHeightForBottom,
  1336. left: $$.rotated_padding_left
  1337. } : {
  1338. top: $$.currentHeight - subchartHeight - legendHeightForBottom,
  1339. right: NaN,
  1340. bottom: xAxisHeight + legendHeightForBottom,
  1341. left: $$.margin.left
  1342. }; // for legend
  1343. $$.margin3 = {
  1344. top: 0,
  1345. right: NaN,
  1346. bottom: 0,
  1347. left: 0
  1348. };
  1349. if ($$.updateSizeForLegend) {
  1350. $$.updateSizeForLegend(legendHeight, legendWidth);
  1351. }
  1352. $$.width = $$.currentWidth - $$.margin.left - $$.margin.right;
  1353. $$.height = $$.currentHeight - $$.margin.top - $$.margin.bottom;
  1354. if ($$.width < 0) {
  1355. $$.width = 0;
  1356. }
  1357. if ($$.height < 0) {
  1358. $$.height = 0;
  1359. }
  1360. $$.width2 = config.axis_rotated ? $$.margin.left - $$.rotated_padding_left - $$.rotated_padding_right : $$.width;
  1361. $$.height2 = config.axis_rotated ? $$.height : $$.currentHeight - $$.margin2.top - $$.margin2.bottom;
  1362. if ($$.width2 < 0) {
  1363. $$.width2 = 0;
  1364. }
  1365. if ($$.height2 < 0) {
  1366. $$.height2 = 0;
  1367. } // for arc
  1368. $$.arcWidth = $$.width - ($$.isLegendRight ? legendWidth + 10 : 0);
  1369. $$.arcHeight = $$.height - ($$.isLegendRight ? 0 : 10);
  1370. if ($$.hasType('gauge') && !config.gauge_fullCircle) {
  1371. $$.arcHeight += $$.height - $$.getGaugeLabelHeight();
  1372. }
  1373. if ($$.updateRadius) {
  1374. $$.updateRadius();
  1375. }
  1376. if ($$.isLegendRight && hasArc) {
  1377. $$.margin3.left = $$.arcWidth / 2 + $$.radiusExpanded * 1.1;
  1378. }
  1379. };
  1380. ChartInternal.prototype.updateTargets = function (targets) {
  1381. var $$ = this;
  1382. /*-- Main --*/
  1383. //-- Text --//
  1384. $$.updateTargetsForText(targets); //-- Bar --//
  1385. $$.updateTargetsForBar(targets); //-- Line --//
  1386. $$.updateTargetsForLine(targets); //-- Arc --//
  1387. if ($$.hasArcType() && $$.updateTargetsForArc) {
  1388. $$.updateTargetsForArc(targets);
  1389. }
  1390. /*-- Sub --*/
  1391. if ($$.updateTargetsForSubchart) {
  1392. $$.updateTargetsForSubchart(targets);
  1393. } // Fade-in each chart
  1394. $$.showTargets();
  1395. };
  1396. ChartInternal.prototype.showTargets = function () {
  1397. var $$ = this;
  1398. $$.svg.selectAll('.' + CLASS.target).filter(function (d) {
  1399. return $$.isTargetToShow(d.id);
  1400. }).transition().duration($$.config.transition_duration).style("opacity", 1);
  1401. };
  1402. ChartInternal.prototype.redraw = function (options, transitions) {
  1403. var $$ = this,
  1404. main = $$.main,
  1405. d3 = $$.d3,
  1406. config = $$.config;
  1407. var areaIndices = $$.getShapeIndices($$.isAreaType),
  1408. barIndices = $$.getShapeIndices($$.isBarType),
  1409. lineIndices = $$.getShapeIndices($$.isLineType);
  1410. var withY, withSubchart, withTransition, withTransitionForExit, withTransitionForAxis, withTransform, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain, withLegend, withEventRect, withDimension, withUpdateXAxis;
  1411. var hideAxis = $$.hasArcType();
  1412. var drawArea, drawBar, drawLine, xForText, yForText;
  1413. var duration, durationForExit, durationForAxis;
  1414. var transitionsToWait, waitForDraw, flow, transition;
  1415. var targetsToShow = $$.filterTargetsToShow($$.data.targets),
  1416. tickValues,
  1417. i,
  1418. intervalForCulling,
  1419. xDomainForZoom;
  1420. var xv = $$.xv.bind($$),
  1421. cx,
  1422. cy;
  1423. options = options || {};
  1424. withY = getOption(options, "withY", true);
  1425. withSubchart = getOption(options, "withSubchart", true);
  1426. withTransition = getOption(options, "withTransition", true);
  1427. withTransform = getOption(options, "withTransform", false);
  1428. withUpdateXDomain = getOption(options, "withUpdateXDomain", false);
  1429. withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", false);
  1430. withTrimXDomain = getOption(options, "withTrimXDomain", true);
  1431. withUpdateXAxis = getOption(options, "withUpdateXAxis", withUpdateXDomain);
  1432. withLegend = getOption(options, "withLegend", false);
  1433. withEventRect = getOption(options, "withEventRect", true);
  1434. withDimension = getOption(options, "withDimension", true);
  1435. withTransitionForExit = getOption(options, "withTransitionForExit", withTransition);
  1436. withTransitionForAxis = getOption(options, "withTransitionForAxis", withTransition);
  1437. duration = withTransition ? config.transition_duration : 0;
  1438. durationForExit = withTransitionForExit ? duration : 0;
  1439. durationForAxis = withTransitionForAxis ? duration : 0;
  1440. transitions = transitions || $$.axis.generateTransitions(durationForAxis); // update legend and transform each g
  1441. if (withLegend && config.legend_show) {
  1442. $$.updateLegend($$.mapToIds($$.data.targets), options, transitions);
  1443. } else if (withDimension) {
  1444. // need to update dimension (e.g. axis.y.tick.values) because y tick values should change
  1445. // no need to update axis in it because they will be updated in redraw()
  1446. $$.updateDimension(true);
  1447. } // MEMO: needed for grids calculation
  1448. if ($$.isCategorized() && targetsToShow.length === 0) {
  1449. $$.x.domain([0, $$.axes.x.selectAll('.tick').size()]);
  1450. }
  1451. if (targetsToShow.length) {
  1452. $$.updateXDomain(targetsToShow, withUpdateXDomain, withUpdateOrgXDomain, withTrimXDomain);
  1453. if (!config.axis_x_tick_values) {
  1454. tickValues = $$.axis.updateXAxisTickValues(targetsToShow);
  1455. }
  1456. } else {
  1457. $$.xAxis.tickValues([]);
  1458. $$.subXAxis.tickValues([]);
  1459. }
  1460. if (config.zoom_rescale && !options.flow) {
  1461. xDomainForZoom = $$.x.orgDomain();
  1462. }
  1463. $$.y.domain($$.getYDomain(targetsToShow, 'y', xDomainForZoom));
  1464. $$.y2.domain($$.getYDomain(targetsToShow, 'y2', xDomainForZoom));
  1465. if (!config.axis_y_tick_values && config.axis_y_tick_count) {
  1466. $$.yAxis.tickValues($$.axis.generateTickValues($$.y.domain(), config.axis_y_tick_count));
  1467. }
  1468. if (!config.axis_y2_tick_values && config.axis_y2_tick_count) {
  1469. $$.y2Axis.tickValues($$.axis.generateTickValues($$.y2.domain(), config.axis_y2_tick_count));
  1470. } // axes
  1471. $$.axis.redraw(durationForAxis, hideAxis); // Update axis label
  1472. $$.axis.updateLabels(withTransition); // show/hide if manual culling needed
  1473. if ((withUpdateXDomain || withUpdateXAxis) && targetsToShow.length) {
  1474. if (config.axis_x_tick_culling && tickValues) {
  1475. for (i = 1; i < tickValues.length; i++) {
  1476. if (tickValues.length / i < config.axis_x_tick_culling_max) {
  1477. intervalForCulling = i;
  1478. break;
  1479. }
  1480. }
  1481. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').each(function (e) {
  1482. var index = tickValues.indexOf(e);
  1483. if (index >= 0) {
  1484. d3.select(this).style('display', index % intervalForCulling ? 'none' : 'block');
  1485. }
  1486. });
  1487. } else {
  1488. $$.svg.selectAll('.' + CLASS.axisX + ' .tick text').style('display', 'block');
  1489. }
  1490. } // setup drawer - MEMO: these must be called after axis updated
  1491. drawArea = $$.generateDrawArea ? $$.generateDrawArea(areaIndices, false) : undefined;
  1492. drawBar = $$.generateDrawBar ? $$.generateDrawBar(barIndices) : undefined;
  1493. drawLine = $$.generateDrawLine ? $$.generateDrawLine(lineIndices, false) : undefined;
  1494. xForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, true);
  1495. yForText = $$.generateXYForText(areaIndices, barIndices, lineIndices, false); // update circleY based on updated parameters
  1496. $$.updateCircleY(); // generate circle x/y functions depending on updated params
  1497. cx = ($$.config.axis_rotated ? $$.circleY : $$.circleX).bind($$);
  1498. cy = ($$.config.axis_rotated ? $$.circleX : $$.circleY).bind($$); // Update sub domain
  1499. if (withY) {
  1500. $$.subY.domain($$.getYDomain(targetsToShow, 'y'));
  1501. $$.subY2.domain($$.getYDomain(targetsToShow, 'y2'));
  1502. } // xgrid focus
  1503. $$.updateXgridFocus(); // Data empty label positioning and text.
  1504. main.select("text." + CLASS.text + '.' + CLASS.empty).attr("x", $$.width / 2).attr("y", $$.height / 2).text(config.data_empty_label_text).transition().style('opacity', targetsToShow.length ? 0 : 1); // event rect
  1505. if (withEventRect) {
  1506. $$.redrawEventRect();
  1507. } // grid
  1508. $$.updateGrid(duration);
  1509. $$.updateStanfordElements(duration); // rect for regions
  1510. $$.updateRegion(duration); // bars
  1511. $$.updateBar(durationForExit); // lines, areas and circles
  1512. $$.updateLine(durationForExit);
  1513. $$.updateArea(durationForExit);
  1514. $$.updateCircle(cx, cy); // text
  1515. if ($$.hasDataLabel()) {
  1516. $$.updateText(xForText, yForText, durationForExit);
  1517. } // title
  1518. if ($$.redrawTitle) {
  1519. $$.redrawTitle();
  1520. } // arc
  1521. if ($$.redrawArc) {
  1522. $$.redrawArc(duration, durationForExit, withTransform);
  1523. } // subchart
  1524. if ($$.redrawSubchart) {
  1525. $$.redrawSubchart(withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices);
  1526. }
  1527. if ($$.isStanfordGraphType()) {
  1528. $$.drawColorScale();
  1529. } // circles for select
  1530. main.selectAll('.' + CLASS.selectedCircles).filter($$.isBarType.bind($$)).selectAll('circle').remove();
  1531. if (options.flow) {
  1532. flow = $$.generateFlow({
  1533. targets: targetsToShow,
  1534. flow: options.flow,
  1535. duration: options.flow.duration,
  1536. drawBar: drawBar,
  1537. drawLine: drawLine,
  1538. drawArea: drawArea,
  1539. cx: cx,
  1540. cy: cy,
  1541. xv: xv,
  1542. xForText: xForText,
  1543. yForText: yForText
  1544. });
  1545. }
  1546. if (duration && $$.isTabVisible()) {
  1547. // Only use transition if tab visible. See #938.
  1548. // transition should be derived from one transition
  1549. transition = d3.transition().duration(duration);
  1550. transitionsToWait = [];
  1551. [$$.redrawBar(drawBar, true, transition), $$.redrawLine(drawLine, true, transition), $$.redrawArea(drawArea, true, transition), $$.redrawCircle(cx, cy, true, transition), $$.redrawText(xForText, yForText, options.flow, true, transition), $$.redrawRegion(true, transition), $$.redrawGrid(true, transition)].forEach(function (transitions) {
  1552. transitions.forEach(function (transition) {
  1553. transitionsToWait.push(transition);
  1554. });
  1555. }); // Wait for end of transitions to call flow and onrendered callback
  1556. waitForDraw = $$.generateWait();
  1557. transitionsToWait.forEach(function (t) {
  1558. waitForDraw.add(t);
  1559. });
  1560. waitForDraw(function () {
  1561. if (flow) {
  1562. flow();
  1563. }
  1564. if (config.onrendered) {
  1565. config.onrendered.call($$);
  1566. }
  1567. });
  1568. } else {
  1569. $$.redrawBar(drawBar);
  1570. $$.redrawLine(drawLine);
  1571. $$.redrawArea(drawArea);
  1572. $$.redrawCircle(cx, cy);
  1573. $$.redrawText(xForText, yForText, options.flow);
  1574. $$.redrawRegion();
  1575. $$.redrawGrid();
  1576. if (flow) {
  1577. flow();
  1578. }
  1579. if (config.onrendered) {
  1580. config.onrendered.call($$);
  1581. }
  1582. } // update fadein condition
  1583. $$.mapToIds($$.data.targets).forEach(function (id) {
  1584. $$.withoutFadeIn[id] = true;
  1585. });
  1586. };
  1587. ChartInternal.prototype.updateAndRedraw = function (options) {
  1588. var $$ = this,
  1589. config = $$.config,
  1590. transitions;
  1591. options = options || {}; // same with redraw
  1592. options.withTransition = getOption(options, "withTransition", true);
  1593. options.withTransform = getOption(options, "withTransform", false);
  1594. options.withLegend = getOption(options, "withLegend", false); // NOT same with redraw
  1595. options.withUpdateXDomain = getOption(options, "withUpdateXDomain", true);
  1596. options.withUpdateOrgXDomain = getOption(options, "withUpdateOrgXDomain", true);
  1597. options.withTransitionForExit = false;
  1598. options.withTransitionForTransform = getOption(options, "withTransitionForTransform", options.withTransition); // MEMO: this needs to be called before updateLegend and it means this ALWAYS needs to be called)
  1599. $$.updateSizes(); // MEMO: called in updateLegend in redraw if withLegend
  1600. if (!(options.withLegend && config.legend_show)) {
  1601. transitions = $$.axis.generateTransitions(options.withTransitionForAxis ? config.transition_duration : 0); // Update scales
  1602. $$.updateScales();
  1603. $$.updateSvgSize(); // Update g positions
  1604. $$.transformAll(options.withTransitionForTransform, transitions);
  1605. } // Draw with new sizes & scales
  1606. $$.redraw(options, transitions);
  1607. };
  1608. ChartInternal.prototype.redrawWithoutRescale = function () {
  1609. this.redraw({
  1610. withY: false,
  1611. withSubchart: false,
  1612. withEventRect: false,
  1613. withTransitionForAxis: false
  1614. });
  1615. };
  1616. ChartInternal.prototype.isTimeSeries = function () {
  1617. return this.config.axis_x_type === 'timeseries';
  1618. };
  1619. ChartInternal.prototype.isCategorized = function () {
  1620. return this.config.axis_x_type.indexOf('categor') >= 0;
  1621. };
  1622. ChartInternal.prototype.isCustomX = function () {
  1623. var $$ = this,
  1624. config = $$.config;
  1625. return !$$.isTimeSeries() && (config.data_x || notEmpty(config.data_xs));
  1626. };
  1627. ChartInternal.prototype.isTimeSeriesY = function () {
  1628. return this.config.axis_y_type === 'timeseries';
  1629. };
  1630. ChartInternal.prototype.getTranslate = function (target) {
  1631. var $$ = this,
  1632. config = $$.config,
  1633. x,
  1634. y;
  1635. if (target === 'main') {
  1636. x = asHalfPixel($$.margin.left);
  1637. y = asHalfPixel($$.margin.top);
  1638. } else if (target === 'context') {
  1639. x = asHalfPixel($$.margin2.left);
  1640. y = asHalfPixel($$.margin2.top);
  1641. } else if (target === 'legend') {
  1642. x = $$.margin3.left;
  1643. y = $$.margin3.top;
  1644. } else if (target === 'x') {
  1645. x = 0;
  1646. y = config.axis_rotated ? 0 : $$.height;
  1647. } else if (target === 'y') {
  1648. x = 0;
  1649. y = config.axis_rotated ? $$.height : 0;
  1650. } else if (target === 'y2') {
  1651. x = config.axis_rotated ? 0 : $$.width;
  1652. y = config.axis_rotated ? 1 : 0;
  1653. } else if (target === 'subx') {
  1654. x = 0;
  1655. y = config.axis_rotated ? 0 : $$.height2;
  1656. } else if (target === 'arc') {
  1657. x = $$.arcWidth / 2;
  1658. y = $$.arcHeight / 2 - ($$.hasType('gauge') ? 6 : 0); // to prevent wrong display of min and max label
  1659. }
  1660. return "translate(" + x + "," + y + ")";
  1661. };
  1662. ChartInternal.prototype.initialOpacity = function (d) {
  1663. return d.value !== null && this.withoutFadeIn[d.id] ? 1 : 0;
  1664. };
  1665. ChartInternal.prototype.initialOpacityForCircle = function (d) {
  1666. return d.value !== null && this.withoutFadeIn[d.id] ? this.opacityForCircle(d) : 0;
  1667. };
  1668. ChartInternal.prototype.opacityForCircle = function (d) {
  1669. var isPointShouldBeShown = isFunction(this.config.point_show) ? this.config.point_show(d) : this.config.point_show;
  1670. var opacity = isPointShouldBeShown || this.isStanfordType(d) ? 1 : 0;
  1671. return isValue(d.value) ? this.isScatterType(d) ? 0.5 : opacity : 0;
  1672. };
  1673. ChartInternal.prototype.opacityForText = function () {
  1674. return this.hasDataLabel() ? 1 : 0;
  1675. };
  1676. ChartInternal.prototype.xx = function (d) {
  1677. return d ? this.x(d.x) : null;
  1678. };
  1679. ChartInternal.prototype.xvCustom = function (d, xyValue) {
  1680. var $$ = this,
  1681. value = xyValue ? d[xyValue] : d.value;
  1682. if ($$.isTimeSeries()) {
  1683. value = $$.parseDate(d.value);
  1684. } else if ($$.isCategorized() && typeof d.value === 'string') {
  1685. value = $$.config.axis_x_categories.indexOf(d.value);
  1686. }
  1687. return Math.ceil($$.x(value));
  1688. };
  1689. ChartInternal.prototype.yvCustom = function (d, xyValue) {
  1690. var $$ = this,
  1691. yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y,
  1692. value = xyValue ? d[xyValue] : d.value;
  1693. return Math.ceil(yScale(value));
  1694. };
  1695. ChartInternal.prototype.xv = function (d) {
  1696. var $$ = this,
  1697. value = d.value;
  1698. if ($$.isTimeSeries()) {
  1699. value = $$.parseDate(d.value);
  1700. } else if ($$.isCategorized() && typeof d.value === 'string') {
  1701. value = $$.config.axis_x_categories.indexOf(d.value);
  1702. }
  1703. return Math.ceil($$.x(value));
  1704. };
  1705. ChartInternal.prototype.yv = function (d) {
  1706. var $$ = this,
  1707. yScale = d.axis && d.axis === 'y2' ? $$.y2 : $$.y;
  1708. return Math.ceil(yScale(d.value));
  1709. };
  1710. ChartInternal.prototype.subxx = function (d) {
  1711. return d ? this.subX(d.x) : null;
  1712. };
  1713. ChartInternal.prototype.transformMain = function (withTransition, transitions) {
  1714. var $$ = this,
  1715. xAxis,
  1716. yAxis,
  1717. y2Axis;
  1718. if (transitions && transitions.axisX) {
  1719. xAxis = transitions.axisX;
  1720. } else {
  1721. xAxis = $$.main.select('.' + CLASS.axisX);
  1722. if (withTransition) {
  1723. xAxis = xAxis.transition();
  1724. }
  1725. }
  1726. if (transitions && transitions.axisY) {
  1727. yAxis = transitions.axisY;
  1728. } else {
  1729. yAxis = $$.main.select('.' + CLASS.axisY);
  1730. if (withTransition) {
  1731. yAxis = yAxis.transition();
  1732. }
  1733. }
  1734. if (transitions && transitions.axisY2) {
  1735. y2Axis = transitions.axisY2;
  1736. } else {
  1737. y2Axis = $$.main.select('.' + CLASS.axisY2);
  1738. if (withTransition) {
  1739. y2Axis = y2Axis.transition();
  1740. }
  1741. }
  1742. (withTransition ? $$.main.transition() : $$.main).attr("transform", $$.getTranslate('main'));
  1743. xAxis.attr("transform", $$.getTranslate('x'));
  1744. yAxis.attr("transform", $$.getTranslate('y'));
  1745. y2Axis.attr("transform", $$.getTranslate('y2'));
  1746. $$.main.select('.' + CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  1747. };
  1748. ChartInternal.prototype.transformAll = function (withTransition, transitions) {
  1749. var $$ = this;
  1750. $$.transformMain(withTransition, transitions);
  1751. if ($$.config.subchart_show) {
  1752. $$.transformContext(withTransition, transitions);
  1753. }
  1754. if ($$.legend) {
  1755. $$.transformLegend(withTransition);
  1756. }
  1757. };
  1758. ChartInternal.prototype.updateSvgSize = function () {
  1759. var $$ = this,
  1760. brush = $$.svg.select(".c3-brush .overlay");
  1761. $$.svg.attr('width', $$.currentWidth).attr('height', $$.currentHeight);
  1762. $$.svg.selectAll(['#' + $$.clipId, '#' + $$.clipIdForGrid]).select('rect').attr('width', $$.width).attr('height', $$.height);
  1763. $$.svg.select('#' + $$.clipIdForXAxis).select('rect').attr('x', $$.getXAxisClipX.bind($$)).attr('y', $$.getXAxisClipY.bind($$)).attr('width', $$.getXAxisClipWidth.bind($$)).attr('height', $$.getXAxisClipHeight.bind($$));
  1764. $$.svg.select('#' + $$.clipIdForYAxis).select('rect').attr('x', $$.getYAxisClipX.bind($$)).attr('y', $$.getYAxisClipY.bind($$)).attr('width', $$.getYAxisClipWidth.bind($$)).attr('height', $$.getYAxisClipHeight.bind($$));
  1765. $$.svg.select('#' + $$.clipIdForSubchart).select('rect').attr('width', $$.width).attr('height', brush.size() ? brush.attr('height') : 0); // MEMO: parent div's height will be bigger than svg when <!DOCTYPE html>
  1766. $$.selectChart.style('max-height', $$.currentHeight + "px");
  1767. };
  1768. ChartInternal.prototype.updateDimension = function (withoutAxis) {
  1769. var $$ = this;
  1770. if (!withoutAxis) {
  1771. if ($$.config.axis_rotated) {
  1772. $$.axes.x.call($$.xAxis);
  1773. $$.axes.subx.call($$.subXAxis);
  1774. } else {
  1775. $$.axes.y.call($$.yAxis);
  1776. $$.axes.y2.call($$.y2Axis);
  1777. }
  1778. }
  1779. $$.updateSizes();
  1780. $$.updateScales();
  1781. $$.updateSvgSize();
  1782. $$.transformAll(false);
  1783. };
  1784. ChartInternal.prototype.observeInserted = function (selection) {
  1785. var $$ = this,
  1786. observer;
  1787. if (typeof MutationObserver === 'undefined') {
  1788. window.console.error("MutationObserver not defined.");
  1789. return;
  1790. }
  1791. observer = new MutationObserver(function (mutations) {
  1792. mutations.forEach(function (mutation) {
  1793. if (mutation.type === 'childList' && mutation.previousSibling) {
  1794. observer.disconnect(); // need to wait for completion of load because size calculation requires the actual sizes determined after that completion
  1795. $$.intervalForObserveInserted = window.setInterval(function () {
  1796. // parentNode will NOT be null when completed
  1797. if (selection.node().parentNode) {
  1798. window.clearInterval($$.intervalForObserveInserted);
  1799. $$.updateDimension();
  1800. if ($$.brush) {
  1801. $$.brush.update();
  1802. }
  1803. $$.config.oninit.call($$);
  1804. $$.redraw({
  1805. withTransform: true,
  1806. withUpdateXDomain: true,
  1807. withUpdateOrgXDomain: true,
  1808. withTransition: false,
  1809. withTransitionForTransform: false,
  1810. withLegend: true
  1811. });
  1812. selection.transition().style('opacity', 1);
  1813. }
  1814. }, 10);
  1815. }
  1816. });
  1817. });
  1818. observer.observe(selection.node(), {
  1819. attributes: true,
  1820. childList: true,
  1821. characterData: true
  1822. });
  1823. };
  1824. /**
  1825. * Binds handlers to the window resize event.
  1826. */
  1827. ChartInternal.prototype.bindResize = function () {
  1828. var $$ = this,
  1829. config = $$.config;
  1830. $$.resizeFunction = $$.generateResize(); // need to call .remove
  1831. $$.resizeFunction.add(function () {
  1832. config.onresize.call($$);
  1833. });
  1834. if (config.resize_auto) {
  1835. $$.resizeFunction.add(function () {
  1836. if ($$.resizeTimeout !== undefined) {
  1837. window.clearTimeout($$.resizeTimeout);
  1838. }
  1839. $$.resizeTimeout = window.setTimeout(function () {
  1840. delete $$.resizeTimeout;
  1841. $$.updateAndRedraw({
  1842. withUpdateXDomain: false,
  1843. withUpdateOrgXDomain: false,
  1844. withTransition: false,
  1845. withTransitionForTransform: false,
  1846. withLegend: true
  1847. });
  1848. if ($$.brush) {
  1849. $$.brush.update();
  1850. }
  1851. }, 100);
  1852. });
  1853. }
  1854. $$.resizeFunction.add(function () {
  1855. config.onresized.call($$);
  1856. });
  1857. $$.resizeIfElementDisplayed = function () {
  1858. // if element not displayed skip it
  1859. if ($$.api == null || !$$.api.element.offsetParent) {
  1860. return;
  1861. }
  1862. $$.resizeFunction();
  1863. };
  1864. if (window.attachEvent) {
  1865. window.attachEvent('onresize', $$.resizeIfElementDisplayed);
  1866. } else if (window.addEventListener) {
  1867. window.addEventListener('resize', $$.resizeIfElementDisplayed, false);
  1868. } else {
  1869. // fallback to this, if this is a very old browser
  1870. var wrapper = window.onresize;
  1871. if (!wrapper) {
  1872. // create a wrapper that will call all charts
  1873. wrapper = $$.generateResize();
  1874. } else if (!wrapper.add || !wrapper.remove) {
  1875. // there is already a handler registered, make sure we call it too
  1876. wrapper = $$.generateResize();
  1877. wrapper.add(window.onresize);
  1878. } // add this graph to the wrapper, we will be removed if the user calls destroy
  1879. wrapper.add($$.resizeFunction);
  1880. window.onresize = function () {
  1881. // if element not displayed skip it
  1882. if (!$$.api.element.offsetParent) {
  1883. return;
  1884. }
  1885. wrapper();
  1886. };
  1887. }
  1888. };
  1889. /**
  1890. * Binds handlers to the window focus event.
  1891. */
  1892. ChartInternal.prototype.bindWindowFocus = function () {
  1893. var _this = this;
  1894. if (this.windowFocusHandler) {
  1895. // The handler is already set
  1896. return;
  1897. }
  1898. this.windowFocusHandler = function () {
  1899. _this.redraw();
  1900. };
  1901. window.addEventListener('focus', this.windowFocusHandler);
  1902. };
  1903. /**
  1904. * Unbinds from the window focus event.
  1905. */
  1906. ChartInternal.prototype.unbindWindowFocus = function () {
  1907. window.removeEventListener('focus', this.windowFocusHandler);
  1908. delete this.windowFocusHandler;
  1909. };
  1910. ChartInternal.prototype.generateResize = function () {
  1911. var resizeFunctions = [];
  1912. function callResizeFunctions() {
  1913. resizeFunctions.forEach(function (f) {
  1914. f();
  1915. });
  1916. }
  1917. callResizeFunctions.add = function (f) {
  1918. resizeFunctions.push(f);
  1919. };
  1920. callResizeFunctions.remove = function (f) {
  1921. for (var i = 0; i < resizeFunctions.length; i++) {
  1922. if (resizeFunctions[i] === f) {
  1923. resizeFunctions.splice(i, 1);
  1924. break;
  1925. }
  1926. }
  1927. };
  1928. return callResizeFunctions;
  1929. };
  1930. ChartInternal.prototype.endall = function (transition, callback) {
  1931. var n = 0;
  1932. transition.each(function () {
  1933. ++n;
  1934. }).on("end", function () {
  1935. if (! --n) {
  1936. callback.apply(this, arguments);
  1937. }
  1938. });
  1939. };
  1940. ChartInternal.prototype.generateWait = function () {
  1941. var $$ = this;
  1942. var transitionsToWait = [],
  1943. f = function f(callback) {
  1944. var timer = setInterval(function () {
  1945. if (!$$.isTabVisible()) {
  1946. return;
  1947. }
  1948. var done = 0;
  1949. transitionsToWait.forEach(function (t) {
  1950. if (t.empty()) {
  1951. done += 1;
  1952. return;
  1953. }
  1954. try {
  1955. t.transition();
  1956. } catch (e) {
  1957. done += 1;
  1958. }
  1959. });
  1960. if (done === transitionsToWait.length) {
  1961. clearInterval(timer);
  1962. if (callback) {
  1963. callback();
  1964. }
  1965. }
  1966. }, 50);
  1967. };
  1968. f.add = function (transition) {
  1969. transitionsToWait.push(transition);
  1970. };
  1971. return f;
  1972. };
  1973. ChartInternal.prototype.parseDate = function (date) {
  1974. var $$ = this,
  1975. parsedDate;
  1976. if (date instanceof Date) {
  1977. parsedDate = date;
  1978. } else if (typeof date === 'string') {
  1979. parsedDate = $$.dataTimeParse(date);
  1980. } else if (_typeof(date) === 'object') {
  1981. parsedDate = new Date(+date);
  1982. } else if (typeof date === 'number' && !isNaN(date)) {
  1983. parsedDate = new Date(+date);
  1984. }
  1985. if (!parsedDate || isNaN(+parsedDate)) {
  1986. window.console.error("Failed to parse x '" + date + "' to Date object");
  1987. }
  1988. return parsedDate;
  1989. };
  1990. ChartInternal.prototype.isTabVisible = function () {
  1991. return !document.hidden;
  1992. };
  1993. ChartInternal.prototype.getPathBox = getPathBox;
  1994. ChartInternal.prototype.CLASS = CLASS;
  1995. /* jshint ignore:start */
  1996. // SVGPathSeg API polyfill
  1997. // https://github.com/progers/pathseg
  1998. //
  1999. // This is a drop-in replacement for the SVGPathSeg and SVGPathSegList APIs that were removed from
  2000. // SVG2 (https://lists.w3.org/Archives/Public/www-svg/2015Jun/0044.html), including the latest spec
  2001. // changes which were implemented in Firefox 43 and Chrome 46.
  2002. (function () {
  2003. if (!("SVGPathSeg" in window)) {
  2004. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSeg
  2005. window.SVGPathSeg = function (type, typeAsLetter, owningPathSegList) {
  2006. this.pathSegType = type;
  2007. this.pathSegTypeAsLetter = typeAsLetter;
  2008. this._owningPathSegList = owningPathSegList;
  2009. };
  2010. window.SVGPathSeg.prototype.classname = "SVGPathSeg";
  2011. window.SVGPathSeg.PATHSEG_UNKNOWN = 0;
  2012. window.SVGPathSeg.PATHSEG_CLOSEPATH = 1;
  2013. window.SVGPathSeg.PATHSEG_MOVETO_ABS = 2;
  2014. window.SVGPathSeg.PATHSEG_MOVETO_REL = 3;
  2015. window.SVGPathSeg.PATHSEG_LINETO_ABS = 4;
  2016. window.SVGPathSeg.PATHSEG_LINETO_REL = 5;
  2017. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS = 6;
  2018. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL = 7;
  2019. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS = 8;
  2020. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL = 9;
  2021. window.SVGPathSeg.PATHSEG_ARC_ABS = 10;
  2022. window.SVGPathSeg.PATHSEG_ARC_REL = 11;
  2023. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS = 12;
  2024. window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL = 13;
  2025. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS = 14;
  2026. window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL = 15;
  2027. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS = 16;
  2028. window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL = 17;
  2029. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS = 18;
  2030. window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL = 19; // Notify owning PathSegList on any changes so they can be synchronized back to the path element.
  2031. window.SVGPathSeg.prototype._segmentChanged = function () {
  2032. if (this._owningPathSegList) this._owningPathSegList.segmentChanged(this);
  2033. };
  2034. window.SVGPathSegClosePath = function (owningPathSegList) {
  2035. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CLOSEPATH, "z", owningPathSegList);
  2036. };
  2037. window.SVGPathSegClosePath.prototype = Object.create(window.SVGPathSeg.prototype);
  2038. window.SVGPathSegClosePath.prototype.toString = function () {
  2039. return "[object SVGPathSegClosePath]";
  2040. };
  2041. window.SVGPathSegClosePath.prototype._asPathString = function () {
  2042. return this.pathSegTypeAsLetter;
  2043. };
  2044. window.SVGPathSegClosePath.prototype.clone = function () {
  2045. return new window.SVGPathSegClosePath(undefined);
  2046. };
  2047. window.SVGPathSegMovetoAbs = function (owningPathSegList, x, y) {
  2048. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_ABS, "M", owningPathSegList);
  2049. this._x = x;
  2050. this._y = y;
  2051. };
  2052. window.SVGPathSegMovetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2053. window.SVGPathSegMovetoAbs.prototype.toString = function () {
  2054. return "[object SVGPathSegMovetoAbs]";
  2055. };
  2056. window.SVGPathSegMovetoAbs.prototype._asPathString = function () {
  2057. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2058. };
  2059. window.SVGPathSegMovetoAbs.prototype.clone = function () {
  2060. return new window.SVGPathSegMovetoAbs(undefined, this._x, this._y);
  2061. };
  2062. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "x", {
  2063. get: function get() {
  2064. return this._x;
  2065. },
  2066. set: function set(x) {
  2067. this._x = x;
  2068. this._segmentChanged();
  2069. },
  2070. enumerable: true
  2071. });
  2072. Object.defineProperty(window.SVGPathSegMovetoAbs.prototype, "y", {
  2073. get: function get() {
  2074. return this._y;
  2075. },
  2076. set: function set(y) {
  2077. this._y = y;
  2078. this._segmentChanged();
  2079. },
  2080. enumerable: true
  2081. });
  2082. window.SVGPathSegMovetoRel = function (owningPathSegList, x, y) {
  2083. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_MOVETO_REL, "m", owningPathSegList);
  2084. this._x = x;
  2085. this._y = y;
  2086. };
  2087. window.SVGPathSegMovetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2088. window.SVGPathSegMovetoRel.prototype.toString = function () {
  2089. return "[object SVGPathSegMovetoRel]";
  2090. };
  2091. window.SVGPathSegMovetoRel.prototype._asPathString = function () {
  2092. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2093. };
  2094. window.SVGPathSegMovetoRel.prototype.clone = function () {
  2095. return new window.SVGPathSegMovetoRel(undefined, this._x, this._y);
  2096. };
  2097. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "x", {
  2098. get: function get() {
  2099. return this._x;
  2100. },
  2101. set: function set(x) {
  2102. this._x = x;
  2103. this._segmentChanged();
  2104. },
  2105. enumerable: true
  2106. });
  2107. Object.defineProperty(window.SVGPathSegMovetoRel.prototype, "y", {
  2108. get: function get() {
  2109. return this._y;
  2110. },
  2111. set: function set(y) {
  2112. this._y = y;
  2113. this._segmentChanged();
  2114. },
  2115. enumerable: true
  2116. });
  2117. window.SVGPathSegLinetoAbs = function (owningPathSegList, x, y) {
  2118. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_ABS, "L", owningPathSegList);
  2119. this._x = x;
  2120. this._y = y;
  2121. };
  2122. window.SVGPathSegLinetoAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2123. window.SVGPathSegLinetoAbs.prototype.toString = function () {
  2124. return "[object SVGPathSegLinetoAbs]";
  2125. };
  2126. window.SVGPathSegLinetoAbs.prototype._asPathString = function () {
  2127. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2128. };
  2129. window.SVGPathSegLinetoAbs.prototype.clone = function () {
  2130. return new window.SVGPathSegLinetoAbs(undefined, this._x, this._y);
  2131. };
  2132. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "x", {
  2133. get: function get() {
  2134. return this._x;
  2135. },
  2136. set: function set(x) {
  2137. this._x = x;
  2138. this._segmentChanged();
  2139. },
  2140. enumerable: true
  2141. });
  2142. Object.defineProperty(window.SVGPathSegLinetoAbs.prototype, "y", {
  2143. get: function get() {
  2144. return this._y;
  2145. },
  2146. set: function set(y) {
  2147. this._y = y;
  2148. this._segmentChanged();
  2149. },
  2150. enumerable: true
  2151. });
  2152. window.SVGPathSegLinetoRel = function (owningPathSegList, x, y) {
  2153. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_REL, "l", owningPathSegList);
  2154. this._x = x;
  2155. this._y = y;
  2156. };
  2157. window.SVGPathSegLinetoRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2158. window.SVGPathSegLinetoRel.prototype.toString = function () {
  2159. return "[object SVGPathSegLinetoRel]";
  2160. };
  2161. window.SVGPathSegLinetoRel.prototype._asPathString = function () {
  2162. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2163. };
  2164. window.SVGPathSegLinetoRel.prototype.clone = function () {
  2165. return new window.SVGPathSegLinetoRel(undefined, this._x, this._y);
  2166. };
  2167. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "x", {
  2168. get: function get() {
  2169. return this._x;
  2170. },
  2171. set: function set(x) {
  2172. this._x = x;
  2173. this._segmentChanged();
  2174. },
  2175. enumerable: true
  2176. });
  2177. Object.defineProperty(window.SVGPathSegLinetoRel.prototype, "y", {
  2178. get: function get() {
  2179. return this._y;
  2180. },
  2181. set: function set(y) {
  2182. this._y = y;
  2183. this._segmentChanged();
  2184. },
  2185. enumerable: true
  2186. });
  2187. window.SVGPathSegCurvetoCubicAbs = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2188. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS, "C", owningPathSegList);
  2189. this._x = x;
  2190. this._y = y;
  2191. this._x1 = x1;
  2192. this._y1 = y1;
  2193. this._x2 = x2;
  2194. this._y2 = y2;
  2195. };
  2196. window.SVGPathSegCurvetoCubicAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2197. window.SVGPathSegCurvetoCubicAbs.prototype.toString = function () {
  2198. return "[object SVGPathSegCurvetoCubicAbs]";
  2199. };
  2200. window.SVGPathSegCurvetoCubicAbs.prototype._asPathString = function () {
  2201. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2202. };
  2203. window.SVGPathSegCurvetoCubicAbs.prototype.clone = function () {
  2204. return new window.SVGPathSegCurvetoCubicAbs(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2205. };
  2206. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x", {
  2207. get: function get() {
  2208. return this._x;
  2209. },
  2210. set: function set(x) {
  2211. this._x = x;
  2212. this._segmentChanged();
  2213. },
  2214. enumerable: true
  2215. });
  2216. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y", {
  2217. get: function get() {
  2218. return this._y;
  2219. },
  2220. set: function set(y) {
  2221. this._y = y;
  2222. this._segmentChanged();
  2223. },
  2224. enumerable: true
  2225. });
  2226. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x1", {
  2227. get: function get() {
  2228. return this._x1;
  2229. },
  2230. set: function set(x1) {
  2231. this._x1 = x1;
  2232. this._segmentChanged();
  2233. },
  2234. enumerable: true
  2235. });
  2236. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y1", {
  2237. get: function get() {
  2238. return this._y1;
  2239. },
  2240. set: function set(y1) {
  2241. this._y1 = y1;
  2242. this._segmentChanged();
  2243. },
  2244. enumerable: true
  2245. });
  2246. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "x2", {
  2247. get: function get() {
  2248. return this._x2;
  2249. },
  2250. set: function set(x2) {
  2251. this._x2 = x2;
  2252. this._segmentChanged();
  2253. },
  2254. enumerable: true
  2255. });
  2256. Object.defineProperty(window.SVGPathSegCurvetoCubicAbs.prototype, "y2", {
  2257. get: function get() {
  2258. return this._y2;
  2259. },
  2260. set: function set(y2) {
  2261. this._y2 = y2;
  2262. this._segmentChanged();
  2263. },
  2264. enumerable: true
  2265. });
  2266. window.SVGPathSegCurvetoCubicRel = function (owningPathSegList, x, y, x1, y1, x2, y2) {
  2267. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL, "c", owningPathSegList);
  2268. this._x = x;
  2269. this._y = y;
  2270. this._x1 = x1;
  2271. this._y1 = y1;
  2272. this._x2 = x2;
  2273. this._y2 = y2;
  2274. };
  2275. window.SVGPathSegCurvetoCubicRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2276. window.SVGPathSegCurvetoCubicRel.prototype.toString = function () {
  2277. return "[object SVGPathSegCurvetoCubicRel]";
  2278. };
  2279. window.SVGPathSegCurvetoCubicRel.prototype._asPathString = function () {
  2280. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2281. };
  2282. window.SVGPathSegCurvetoCubicRel.prototype.clone = function () {
  2283. return new window.SVGPathSegCurvetoCubicRel(undefined, this._x, this._y, this._x1, this._y1, this._x2, this._y2);
  2284. };
  2285. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x", {
  2286. get: function get() {
  2287. return this._x;
  2288. },
  2289. set: function set(x) {
  2290. this._x = x;
  2291. this._segmentChanged();
  2292. },
  2293. enumerable: true
  2294. });
  2295. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y", {
  2296. get: function get() {
  2297. return this._y;
  2298. },
  2299. set: function set(y) {
  2300. this._y = y;
  2301. this._segmentChanged();
  2302. },
  2303. enumerable: true
  2304. });
  2305. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x1", {
  2306. get: function get() {
  2307. return this._x1;
  2308. },
  2309. set: function set(x1) {
  2310. this._x1 = x1;
  2311. this._segmentChanged();
  2312. },
  2313. enumerable: true
  2314. });
  2315. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y1", {
  2316. get: function get() {
  2317. return this._y1;
  2318. },
  2319. set: function set(y1) {
  2320. this._y1 = y1;
  2321. this._segmentChanged();
  2322. },
  2323. enumerable: true
  2324. });
  2325. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "x2", {
  2326. get: function get() {
  2327. return this._x2;
  2328. },
  2329. set: function set(x2) {
  2330. this._x2 = x2;
  2331. this._segmentChanged();
  2332. },
  2333. enumerable: true
  2334. });
  2335. Object.defineProperty(window.SVGPathSegCurvetoCubicRel.prototype, "y2", {
  2336. get: function get() {
  2337. return this._y2;
  2338. },
  2339. set: function set(y2) {
  2340. this._y2 = y2;
  2341. this._segmentChanged();
  2342. },
  2343. enumerable: true
  2344. });
  2345. window.SVGPathSegCurvetoQuadraticAbs = function (owningPathSegList, x, y, x1, y1) {
  2346. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS, "Q", owningPathSegList);
  2347. this._x = x;
  2348. this._y = y;
  2349. this._x1 = x1;
  2350. this._y1 = y1;
  2351. };
  2352. window.SVGPathSegCurvetoQuadraticAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2353. window.SVGPathSegCurvetoQuadraticAbs.prototype.toString = function () {
  2354. return "[object SVGPathSegCurvetoQuadraticAbs]";
  2355. };
  2356. window.SVGPathSegCurvetoQuadraticAbs.prototype._asPathString = function () {
  2357. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2358. };
  2359. window.SVGPathSegCurvetoQuadraticAbs.prototype.clone = function () {
  2360. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, this._x, this._y, this._x1, this._y1);
  2361. };
  2362. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x", {
  2363. get: function get() {
  2364. return this._x;
  2365. },
  2366. set: function set(x) {
  2367. this._x = x;
  2368. this._segmentChanged();
  2369. },
  2370. enumerable: true
  2371. });
  2372. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y", {
  2373. get: function get() {
  2374. return this._y;
  2375. },
  2376. set: function set(y) {
  2377. this._y = y;
  2378. this._segmentChanged();
  2379. },
  2380. enumerable: true
  2381. });
  2382. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "x1", {
  2383. get: function get() {
  2384. return this._x1;
  2385. },
  2386. set: function set(x1) {
  2387. this._x1 = x1;
  2388. this._segmentChanged();
  2389. },
  2390. enumerable: true
  2391. });
  2392. Object.defineProperty(window.SVGPathSegCurvetoQuadraticAbs.prototype, "y1", {
  2393. get: function get() {
  2394. return this._y1;
  2395. },
  2396. set: function set(y1) {
  2397. this._y1 = y1;
  2398. this._segmentChanged();
  2399. },
  2400. enumerable: true
  2401. });
  2402. window.SVGPathSegCurvetoQuadraticRel = function (owningPathSegList, x, y, x1, y1) {
  2403. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL, "q", owningPathSegList);
  2404. this._x = x;
  2405. this._y = y;
  2406. this._x1 = x1;
  2407. this._y1 = y1;
  2408. };
  2409. window.SVGPathSegCurvetoQuadraticRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2410. window.SVGPathSegCurvetoQuadraticRel.prototype.toString = function () {
  2411. return "[object SVGPathSegCurvetoQuadraticRel]";
  2412. };
  2413. window.SVGPathSegCurvetoQuadraticRel.prototype._asPathString = function () {
  2414. return this.pathSegTypeAsLetter + " " + this._x1 + " " + this._y1 + " " + this._x + " " + this._y;
  2415. };
  2416. window.SVGPathSegCurvetoQuadraticRel.prototype.clone = function () {
  2417. return new window.SVGPathSegCurvetoQuadraticRel(undefined, this._x, this._y, this._x1, this._y1);
  2418. };
  2419. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x", {
  2420. get: function get() {
  2421. return this._x;
  2422. },
  2423. set: function set(x) {
  2424. this._x = x;
  2425. this._segmentChanged();
  2426. },
  2427. enumerable: true
  2428. });
  2429. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y", {
  2430. get: function get() {
  2431. return this._y;
  2432. },
  2433. set: function set(y) {
  2434. this._y = y;
  2435. this._segmentChanged();
  2436. },
  2437. enumerable: true
  2438. });
  2439. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "x1", {
  2440. get: function get() {
  2441. return this._x1;
  2442. },
  2443. set: function set(x1) {
  2444. this._x1 = x1;
  2445. this._segmentChanged();
  2446. },
  2447. enumerable: true
  2448. });
  2449. Object.defineProperty(window.SVGPathSegCurvetoQuadraticRel.prototype, "y1", {
  2450. get: function get() {
  2451. return this._y1;
  2452. },
  2453. set: function set(y1) {
  2454. this._y1 = y1;
  2455. this._segmentChanged();
  2456. },
  2457. enumerable: true
  2458. });
  2459. window.SVGPathSegArcAbs = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2460. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_ABS, "A", owningPathSegList);
  2461. this._x = x;
  2462. this._y = y;
  2463. this._r1 = r1;
  2464. this._r2 = r2;
  2465. this._angle = angle;
  2466. this._largeArcFlag = largeArcFlag;
  2467. this._sweepFlag = sweepFlag;
  2468. };
  2469. window.SVGPathSegArcAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2470. window.SVGPathSegArcAbs.prototype.toString = function () {
  2471. return "[object SVGPathSegArcAbs]";
  2472. };
  2473. window.SVGPathSegArcAbs.prototype._asPathString = function () {
  2474. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2475. };
  2476. window.SVGPathSegArcAbs.prototype.clone = function () {
  2477. return new window.SVGPathSegArcAbs(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2478. };
  2479. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "x", {
  2480. get: function get() {
  2481. return this._x;
  2482. },
  2483. set: function set(x) {
  2484. this._x = x;
  2485. this._segmentChanged();
  2486. },
  2487. enumerable: true
  2488. });
  2489. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "y", {
  2490. get: function get() {
  2491. return this._y;
  2492. },
  2493. set: function set(y) {
  2494. this._y = y;
  2495. this._segmentChanged();
  2496. },
  2497. enumerable: true
  2498. });
  2499. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r1", {
  2500. get: function get() {
  2501. return this._r1;
  2502. },
  2503. set: function set(r1) {
  2504. this._r1 = r1;
  2505. this._segmentChanged();
  2506. },
  2507. enumerable: true
  2508. });
  2509. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "r2", {
  2510. get: function get() {
  2511. return this._r2;
  2512. },
  2513. set: function set(r2) {
  2514. this._r2 = r2;
  2515. this._segmentChanged();
  2516. },
  2517. enumerable: true
  2518. });
  2519. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "angle", {
  2520. get: function get() {
  2521. return this._angle;
  2522. },
  2523. set: function set(angle) {
  2524. this._angle = angle;
  2525. this._segmentChanged();
  2526. },
  2527. enumerable: true
  2528. });
  2529. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "largeArcFlag", {
  2530. get: function get() {
  2531. return this._largeArcFlag;
  2532. },
  2533. set: function set(largeArcFlag) {
  2534. this._largeArcFlag = largeArcFlag;
  2535. this._segmentChanged();
  2536. },
  2537. enumerable: true
  2538. });
  2539. Object.defineProperty(window.SVGPathSegArcAbs.prototype, "sweepFlag", {
  2540. get: function get() {
  2541. return this._sweepFlag;
  2542. },
  2543. set: function set(sweepFlag) {
  2544. this._sweepFlag = sweepFlag;
  2545. this._segmentChanged();
  2546. },
  2547. enumerable: true
  2548. });
  2549. window.SVGPathSegArcRel = function (owningPathSegList, x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2550. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_ARC_REL, "a", owningPathSegList);
  2551. this._x = x;
  2552. this._y = y;
  2553. this._r1 = r1;
  2554. this._r2 = r2;
  2555. this._angle = angle;
  2556. this._largeArcFlag = largeArcFlag;
  2557. this._sweepFlag = sweepFlag;
  2558. };
  2559. window.SVGPathSegArcRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2560. window.SVGPathSegArcRel.prototype.toString = function () {
  2561. return "[object SVGPathSegArcRel]";
  2562. };
  2563. window.SVGPathSegArcRel.prototype._asPathString = function () {
  2564. return this.pathSegTypeAsLetter + " " + this._r1 + " " + this._r2 + " " + this._angle + " " + (this._largeArcFlag ? "1" : "0") + " " + (this._sweepFlag ? "1" : "0") + " " + this._x + " " + this._y;
  2565. };
  2566. window.SVGPathSegArcRel.prototype.clone = function () {
  2567. return new window.SVGPathSegArcRel(undefined, this._x, this._y, this._r1, this._r2, this._angle, this._largeArcFlag, this._sweepFlag);
  2568. };
  2569. Object.defineProperty(window.SVGPathSegArcRel.prototype, "x", {
  2570. get: function get() {
  2571. return this._x;
  2572. },
  2573. set: function set(x) {
  2574. this._x = x;
  2575. this._segmentChanged();
  2576. },
  2577. enumerable: true
  2578. });
  2579. Object.defineProperty(window.SVGPathSegArcRel.prototype, "y", {
  2580. get: function get() {
  2581. return this._y;
  2582. },
  2583. set: function set(y) {
  2584. this._y = y;
  2585. this._segmentChanged();
  2586. },
  2587. enumerable: true
  2588. });
  2589. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r1", {
  2590. get: function get() {
  2591. return this._r1;
  2592. },
  2593. set: function set(r1) {
  2594. this._r1 = r1;
  2595. this._segmentChanged();
  2596. },
  2597. enumerable: true
  2598. });
  2599. Object.defineProperty(window.SVGPathSegArcRel.prototype, "r2", {
  2600. get: function get() {
  2601. return this._r2;
  2602. },
  2603. set: function set(r2) {
  2604. this._r2 = r2;
  2605. this._segmentChanged();
  2606. },
  2607. enumerable: true
  2608. });
  2609. Object.defineProperty(window.SVGPathSegArcRel.prototype, "angle", {
  2610. get: function get() {
  2611. return this._angle;
  2612. },
  2613. set: function set(angle) {
  2614. this._angle = angle;
  2615. this._segmentChanged();
  2616. },
  2617. enumerable: true
  2618. });
  2619. Object.defineProperty(window.SVGPathSegArcRel.prototype, "largeArcFlag", {
  2620. get: function get() {
  2621. return this._largeArcFlag;
  2622. },
  2623. set: function set(largeArcFlag) {
  2624. this._largeArcFlag = largeArcFlag;
  2625. this._segmentChanged();
  2626. },
  2627. enumerable: true
  2628. });
  2629. Object.defineProperty(window.SVGPathSegArcRel.prototype, "sweepFlag", {
  2630. get: function get() {
  2631. return this._sweepFlag;
  2632. },
  2633. set: function set(sweepFlag) {
  2634. this._sweepFlag = sweepFlag;
  2635. this._segmentChanged();
  2636. },
  2637. enumerable: true
  2638. });
  2639. window.SVGPathSegLinetoHorizontalAbs = function (owningPathSegList, x) {
  2640. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS, "H", owningPathSegList);
  2641. this._x = x;
  2642. };
  2643. window.SVGPathSegLinetoHorizontalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2644. window.SVGPathSegLinetoHorizontalAbs.prototype.toString = function () {
  2645. return "[object SVGPathSegLinetoHorizontalAbs]";
  2646. };
  2647. window.SVGPathSegLinetoHorizontalAbs.prototype._asPathString = function () {
  2648. return this.pathSegTypeAsLetter + " " + this._x;
  2649. };
  2650. window.SVGPathSegLinetoHorizontalAbs.prototype.clone = function () {
  2651. return new window.SVGPathSegLinetoHorizontalAbs(undefined, this._x);
  2652. };
  2653. Object.defineProperty(window.SVGPathSegLinetoHorizontalAbs.prototype, "x", {
  2654. get: function get() {
  2655. return this._x;
  2656. },
  2657. set: function set(x) {
  2658. this._x = x;
  2659. this._segmentChanged();
  2660. },
  2661. enumerable: true
  2662. });
  2663. window.SVGPathSegLinetoHorizontalRel = function (owningPathSegList, x) {
  2664. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL, "h", owningPathSegList);
  2665. this._x = x;
  2666. };
  2667. window.SVGPathSegLinetoHorizontalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2668. window.SVGPathSegLinetoHorizontalRel.prototype.toString = function () {
  2669. return "[object SVGPathSegLinetoHorizontalRel]";
  2670. };
  2671. window.SVGPathSegLinetoHorizontalRel.prototype._asPathString = function () {
  2672. return this.pathSegTypeAsLetter + " " + this._x;
  2673. };
  2674. window.SVGPathSegLinetoHorizontalRel.prototype.clone = function () {
  2675. return new window.SVGPathSegLinetoHorizontalRel(undefined, this._x);
  2676. };
  2677. Object.defineProperty(window.SVGPathSegLinetoHorizontalRel.prototype, "x", {
  2678. get: function get() {
  2679. return this._x;
  2680. },
  2681. set: function set(x) {
  2682. this._x = x;
  2683. this._segmentChanged();
  2684. },
  2685. enumerable: true
  2686. });
  2687. window.SVGPathSegLinetoVerticalAbs = function (owningPathSegList, y) {
  2688. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS, "V", owningPathSegList);
  2689. this._y = y;
  2690. };
  2691. window.SVGPathSegLinetoVerticalAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2692. window.SVGPathSegLinetoVerticalAbs.prototype.toString = function () {
  2693. return "[object SVGPathSegLinetoVerticalAbs]";
  2694. };
  2695. window.SVGPathSegLinetoVerticalAbs.prototype._asPathString = function () {
  2696. return this.pathSegTypeAsLetter + " " + this._y;
  2697. };
  2698. window.SVGPathSegLinetoVerticalAbs.prototype.clone = function () {
  2699. return new window.SVGPathSegLinetoVerticalAbs(undefined, this._y);
  2700. };
  2701. Object.defineProperty(window.SVGPathSegLinetoVerticalAbs.prototype, "y", {
  2702. get: function get() {
  2703. return this._y;
  2704. },
  2705. set: function set(y) {
  2706. this._y = y;
  2707. this._segmentChanged();
  2708. },
  2709. enumerable: true
  2710. });
  2711. window.SVGPathSegLinetoVerticalRel = function (owningPathSegList, y) {
  2712. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL, "v", owningPathSegList);
  2713. this._y = y;
  2714. };
  2715. window.SVGPathSegLinetoVerticalRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2716. window.SVGPathSegLinetoVerticalRel.prototype.toString = function () {
  2717. return "[object SVGPathSegLinetoVerticalRel]";
  2718. };
  2719. window.SVGPathSegLinetoVerticalRel.prototype._asPathString = function () {
  2720. return this.pathSegTypeAsLetter + " " + this._y;
  2721. };
  2722. window.SVGPathSegLinetoVerticalRel.prototype.clone = function () {
  2723. return new window.SVGPathSegLinetoVerticalRel(undefined, this._y);
  2724. };
  2725. Object.defineProperty(window.SVGPathSegLinetoVerticalRel.prototype, "y", {
  2726. get: function get() {
  2727. return this._y;
  2728. },
  2729. set: function set(y) {
  2730. this._y = y;
  2731. this._segmentChanged();
  2732. },
  2733. enumerable: true
  2734. });
  2735. window.SVGPathSegCurvetoCubicSmoothAbs = function (owningPathSegList, x, y, x2, y2) {
  2736. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS, "S", owningPathSegList);
  2737. this._x = x;
  2738. this._y = y;
  2739. this._x2 = x2;
  2740. this._y2 = y2;
  2741. };
  2742. window.SVGPathSegCurvetoCubicSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2743. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.toString = function () {
  2744. return "[object SVGPathSegCurvetoCubicSmoothAbs]";
  2745. };
  2746. window.SVGPathSegCurvetoCubicSmoothAbs.prototype._asPathString = function () {
  2747. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2748. };
  2749. window.SVGPathSegCurvetoCubicSmoothAbs.prototype.clone = function () {
  2750. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, this._x, this._y, this._x2, this._y2);
  2751. };
  2752. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x", {
  2753. get: function get() {
  2754. return this._x;
  2755. },
  2756. set: function set(x) {
  2757. this._x = x;
  2758. this._segmentChanged();
  2759. },
  2760. enumerable: true
  2761. });
  2762. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y", {
  2763. get: function get() {
  2764. return this._y;
  2765. },
  2766. set: function set(y) {
  2767. this._y = y;
  2768. this._segmentChanged();
  2769. },
  2770. enumerable: true
  2771. });
  2772. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "x2", {
  2773. get: function get() {
  2774. return this._x2;
  2775. },
  2776. set: function set(x2) {
  2777. this._x2 = x2;
  2778. this._segmentChanged();
  2779. },
  2780. enumerable: true
  2781. });
  2782. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothAbs.prototype, "y2", {
  2783. get: function get() {
  2784. return this._y2;
  2785. },
  2786. set: function set(y2) {
  2787. this._y2 = y2;
  2788. this._segmentChanged();
  2789. },
  2790. enumerable: true
  2791. });
  2792. window.SVGPathSegCurvetoCubicSmoothRel = function (owningPathSegList, x, y, x2, y2) {
  2793. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL, "s", owningPathSegList);
  2794. this._x = x;
  2795. this._y = y;
  2796. this._x2 = x2;
  2797. this._y2 = y2;
  2798. };
  2799. window.SVGPathSegCurvetoCubicSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2800. window.SVGPathSegCurvetoCubicSmoothRel.prototype.toString = function () {
  2801. return "[object SVGPathSegCurvetoCubicSmoothRel]";
  2802. };
  2803. window.SVGPathSegCurvetoCubicSmoothRel.prototype._asPathString = function () {
  2804. return this.pathSegTypeAsLetter + " " + this._x2 + " " + this._y2 + " " + this._x + " " + this._y;
  2805. };
  2806. window.SVGPathSegCurvetoCubicSmoothRel.prototype.clone = function () {
  2807. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, this._x, this._y, this._x2, this._y2);
  2808. };
  2809. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x", {
  2810. get: function get() {
  2811. return this._x;
  2812. },
  2813. set: function set(x) {
  2814. this._x = x;
  2815. this._segmentChanged();
  2816. },
  2817. enumerable: true
  2818. });
  2819. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y", {
  2820. get: function get() {
  2821. return this._y;
  2822. },
  2823. set: function set(y) {
  2824. this._y = y;
  2825. this._segmentChanged();
  2826. },
  2827. enumerable: true
  2828. });
  2829. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "x2", {
  2830. get: function get() {
  2831. return this._x2;
  2832. },
  2833. set: function set(x2) {
  2834. this._x2 = x2;
  2835. this._segmentChanged();
  2836. },
  2837. enumerable: true
  2838. });
  2839. Object.defineProperty(window.SVGPathSegCurvetoCubicSmoothRel.prototype, "y2", {
  2840. get: function get() {
  2841. return this._y2;
  2842. },
  2843. set: function set(y2) {
  2844. this._y2 = y2;
  2845. this._segmentChanged();
  2846. },
  2847. enumerable: true
  2848. });
  2849. window.SVGPathSegCurvetoQuadraticSmoothAbs = function (owningPathSegList, x, y) {
  2850. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS, "T", owningPathSegList);
  2851. this._x = x;
  2852. this._y = y;
  2853. };
  2854. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype = Object.create(window.SVGPathSeg.prototype);
  2855. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.toString = function () {
  2856. return "[object SVGPathSegCurvetoQuadraticSmoothAbs]";
  2857. };
  2858. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype._asPathString = function () {
  2859. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2860. };
  2861. window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype.clone = function () {
  2862. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, this._x, this._y);
  2863. };
  2864. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "x", {
  2865. get: function get() {
  2866. return this._x;
  2867. },
  2868. set: function set(x) {
  2869. this._x = x;
  2870. this._segmentChanged();
  2871. },
  2872. enumerable: true
  2873. });
  2874. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothAbs.prototype, "y", {
  2875. get: function get() {
  2876. return this._y;
  2877. },
  2878. set: function set(y) {
  2879. this._y = y;
  2880. this._segmentChanged();
  2881. },
  2882. enumerable: true
  2883. });
  2884. window.SVGPathSegCurvetoQuadraticSmoothRel = function (owningPathSegList, x, y) {
  2885. window.SVGPathSeg.call(this, window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL, "t", owningPathSegList);
  2886. this._x = x;
  2887. this._y = y;
  2888. };
  2889. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype = Object.create(window.SVGPathSeg.prototype);
  2890. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.toString = function () {
  2891. return "[object SVGPathSegCurvetoQuadraticSmoothRel]";
  2892. };
  2893. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype._asPathString = function () {
  2894. return this.pathSegTypeAsLetter + " " + this._x + " " + this._y;
  2895. };
  2896. window.SVGPathSegCurvetoQuadraticSmoothRel.prototype.clone = function () {
  2897. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, this._x, this._y);
  2898. };
  2899. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "x", {
  2900. get: function get() {
  2901. return this._x;
  2902. },
  2903. set: function set(x) {
  2904. this._x = x;
  2905. this._segmentChanged();
  2906. },
  2907. enumerable: true
  2908. });
  2909. Object.defineProperty(window.SVGPathSegCurvetoQuadraticSmoothRel.prototype, "y", {
  2910. get: function get() {
  2911. return this._y;
  2912. },
  2913. set: function set(y) {
  2914. this._y = y;
  2915. this._segmentChanged();
  2916. },
  2917. enumerable: true
  2918. }); // Add createSVGPathSeg* functions to window.SVGPathElement.
  2919. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-Interfacewindow.SVGPathElement.
  2920. window.SVGPathElement.prototype.createSVGPathSegClosePath = function () {
  2921. return new window.SVGPathSegClosePath(undefined);
  2922. };
  2923. window.SVGPathElement.prototype.createSVGPathSegMovetoAbs = function (x, y) {
  2924. return new window.SVGPathSegMovetoAbs(undefined, x, y);
  2925. };
  2926. window.SVGPathElement.prototype.createSVGPathSegMovetoRel = function (x, y) {
  2927. return new window.SVGPathSegMovetoRel(undefined, x, y);
  2928. };
  2929. window.SVGPathElement.prototype.createSVGPathSegLinetoAbs = function (x, y) {
  2930. return new window.SVGPathSegLinetoAbs(undefined, x, y);
  2931. };
  2932. window.SVGPathElement.prototype.createSVGPathSegLinetoRel = function (x, y) {
  2933. return new window.SVGPathSegLinetoRel(undefined, x, y);
  2934. };
  2935. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicAbs = function (x, y, x1, y1, x2, y2) {
  2936. return new window.SVGPathSegCurvetoCubicAbs(undefined, x, y, x1, y1, x2, y2);
  2937. };
  2938. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicRel = function (x, y, x1, y1, x2, y2) {
  2939. return new window.SVGPathSegCurvetoCubicRel(undefined, x, y, x1, y1, x2, y2);
  2940. };
  2941. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticAbs = function (x, y, x1, y1) {
  2942. return new window.SVGPathSegCurvetoQuadraticAbs(undefined, x, y, x1, y1);
  2943. };
  2944. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticRel = function (x, y, x1, y1) {
  2945. return new window.SVGPathSegCurvetoQuadraticRel(undefined, x, y, x1, y1);
  2946. };
  2947. window.SVGPathElement.prototype.createSVGPathSegArcAbs = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2948. return new window.SVGPathSegArcAbs(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  2949. };
  2950. window.SVGPathElement.prototype.createSVGPathSegArcRel = function (x, y, r1, r2, angle, largeArcFlag, sweepFlag) {
  2951. return new window.SVGPathSegArcRel(undefined, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
  2952. };
  2953. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalAbs = function (x) {
  2954. return new window.SVGPathSegLinetoHorizontalAbs(undefined, x);
  2955. };
  2956. window.SVGPathElement.prototype.createSVGPathSegLinetoHorizontalRel = function (x) {
  2957. return new window.SVGPathSegLinetoHorizontalRel(undefined, x);
  2958. };
  2959. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalAbs = function (y) {
  2960. return new window.SVGPathSegLinetoVerticalAbs(undefined, y);
  2961. };
  2962. window.SVGPathElement.prototype.createSVGPathSegLinetoVerticalRel = function (y) {
  2963. return new window.SVGPathSegLinetoVerticalRel(undefined, y);
  2964. };
  2965. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothAbs = function (x, y, x2, y2) {
  2966. return new window.SVGPathSegCurvetoCubicSmoothAbs(undefined, x, y, x2, y2);
  2967. };
  2968. window.SVGPathElement.prototype.createSVGPathSegCurvetoCubicSmoothRel = function (x, y, x2, y2) {
  2969. return new window.SVGPathSegCurvetoCubicSmoothRel(undefined, x, y, x2, y2);
  2970. };
  2971. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothAbs = function (x, y) {
  2972. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(undefined, x, y);
  2973. };
  2974. window.SVGPathElement.prototype.createSVGPathSegCurvetoQuadraticSmoothRel = function (x, y) {
  2975. return new window.SVGPathSegCurvetoQuadraticSmoothRel(undefined, x, y);
  2976. };
  2977. if (!("getPathSegAtLength" in window.SVGPathElement.prototype)) {
  2978. // Add getPathSegAtLength to SVGPathElement.
  2979. // Spec: https://www.w3.org/TR/SVG11/single-page.html#paths-__svg__SVGPathElement__getPathSegAtLength
  2980. // This polyfill requires SVGPathElement.getTotalLength to implement the distance-along-a-path algorithm.
  2981. window.SVGPathElement.prototype.getPathSegAtLength = function (distance) {
  2982. if (distance === undefined || !isFinite(distance)) throw "Invalid arguments.";
  2983. var measurementElement = document.createElementNS("http://www.w3.org/2000/svg", "path");
  2984. measurementElement.setAttribute("d", this.getAttribute("d"));
  2985. var lastPathSegment = measurementElement.pathSegList.numberOfItems - 1; // If the path is empty, return 0.
  2986. if (lastPathSegment <= 0) return 0;
  2987. do {
  2988. measurementElement.pathSegList.removeItem(lastPathSegment);
  2989. if (distance > measurementElement.getTotalLength()) break;
  2990. lastPathSegment--;
  2991. } while (lastPathSegment > 0);
  2992. return lastPathSegment;
  2993. };
  2994. }
  2995. }
  2996. if (!("SVGPathSegList" in window)) {
  2997. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGPathSegList
  2998. window.SVGPathSegList = function (pathElement) {
  2999. this._pathElement = pathElement;
  3000. this._list = this._parsePath(this._pathElement.getAttribute("d")); // Use a MutationObserver to catch changes to the path's "d" attribute.
  3001. this._mutationObserverConfig = {
  3002. "attributes": true,
  3003. "attributeFilter": ["d"]
  3004. };
  3005. this._pathElementMutationObserver = new MutationObserver(this._updateListFromPathMutations.bind(this));
  3006. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  3007. };
  3008. window.SVGPathSegList.prototype.classname = "SVGPathSegList";
  3009. Object.defineProperty(window.SVGPathSegList.prototype, "numberOfItems", {
  3010. get: function get() {
  3011. this._checkPathSynchronizedToList();
  3012. return this._list.length;
  3013. },
  3014. enumerable: true
  3015. }); // Add the pathSegList accessors to window.SVGPathElement.
  3016. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-InterfaceSVGAnimatedPathData
  3017. Object.defineProperty(window.SVGPathElement.prototype, "pathSegList", {
  3018. get: function get() {
  3019. if (!this._pathSegList) this._pathSegList = new window.SVGPathSegList(this);
  3020. return this._pathSegList;
  3021. },
  3022. enumerable: true
  3023. }); // FIXME: The following are not implemented and simply return window.SVGPathElement.pathSegList.
  3024. Object.defineProperty(window.SVGPathElement.prototype, "normalizedPathSegList", {
  3025. get: function get() {
  3026. return this.pathSegList;
  3027. },
  3028. enumerable: true
  3029. });
  3030. Object.defineProperty(window.SVGPathElement.prototype, "animatedPathSegList", {
  3031. get: function get() {
  3032. return this.pathSegList;
  3033. },
  3034. enumerable: true
  3035. });
  3036. Object.defineProperty(window.SVGPathElement.prototype, "animatedNormalizedPathSegList", {
  3037. get: function get() {
  3038. return this.pathSegList;
  3039. },
  3040. enumerable: true
  3041. }); // Process any pending mutations to the path element and update the list as needed.
  3042. // This should be the first call of all public functions and is needed because
  3043. // MutationObservers are not synchronous so we can have pending asynchronous mutations.
  3044. window.SVGPathSegList.prototype._checkPathSynchronizedToList = function () {
  3045. this._updateListFromPathMutations(this._pathElementMutationObserver.takeRecords());
  3046. };
  3047. window.SVGPathSegList.prototype._updateListFromPathMutations = function (mutationRecords) {
  3048. if (!this._pathElement) return;
  3049. var hasPathMutations = false;
  3050. mutationRecords.forEach(function (record) {
  3051. if (record.attributeName == "d") hasPathMutations = true;
  3052. });
  3053. if (hasPathMutations) this._list = this._parsePath(this._pathElement.getAttribute("d"));
  3054. }; // Serialize the list and update the path's 'd' attribute.
  3055. window.SVGPathSegList.prototype._writeListToPath = function () {
  3056. this._pathElementMutationObserver.disconnect();
  3057. this._pathElement.setAttribute("d", window.SVGPathSegList._pathSegArrayAsString(this._list));
  3058. this._pathElementMutationObserver.observe(this._pathElement, this._mutationObserverConfig);
  3059. }; // When a path segment changes the list needs to be synchronized back to the path element.
  3060. window.SVGPathSegList.prototype.segmentChanged = function (pathSeg) {
  3061. this._writeListToPath();
  3062. };
  3063. window.SVGPathSegList.prototype.clear = function () {
  3064. this._checkPathSynchronizedToList();
  3065. this._list.forEach(function (pathSeg) {
  3066. pathSeg._owningPathSegList = null;
  3067. });
  3068. this._list = [];
  3069. this._writeListToPath();
  3070. };
  3071. window.SVGPathSegList.prototype.initialize = function (newItem) {
  3072. this._checkPathSynchronizedToList();
  3073. this._list = [newItem];
  3074. newItem._owningPathSegList = this;
  3075. this._writeListToPath();
  3076. return newItem;
  3077. };
  3078. window.SVGPathSegList.prototype._checkValidIndex = function (index) {
  3079. if (isNaN(index) || index < 0 || index >= this.numberOfItems) throw "INDEX_SIZE_ERR";
  3080. };
  3081. window.SVGPathSegList.prototype.getItem = function (index) {
  3082. this._checkPathSynchronizedToList();
  3083. this._checkValidIndex(index);
  3084. return this._list[index];
  3085. };
  3086. window.SVGPathSegList.prototype.insertItemBefore = function (newItem, index) {
  3087. this._checkPathSynchronizedToList(); // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
  3088. if (index > this.numberOfItems) index = this.numberOfItems;
  3089. if (newItem._owningPathSegList) {
  3090. // SVG2 spec says to make a copy.
  3091. newItem = newItem.clone();
  3092. }
  3093. this._list.splice(index, 0, newItem);
  3094. newItem._owningPathSegList = this;
  3095. this._writeListToPath();
  3096. return newItem;
  3097. };
  3098. window.SVGPathSegList.prototype.replaceItem = function (newItem, index) {
  3099. this._checkPathSynchronizedToList();
  3100. if (newItem._owningPathSegList) {
  3101. // SVG2 spec says to make a copy.
  3102. newItem = newItem.clone();
  3103. }
  3104. this._checkValidIndex(index);
  3105. this._list[index] = newItem;
  3106. newItem._owningPathSegList = this;
  3107. this._writeListToPath();
  3108. return newItem;
  3109. };
  3110. window.SVGPathSegList.prototype.removeItem = function (index) {
  3111. this._checkPathSynchronizedToList();
  3112. this._checkValidIndex(index);
  3113. var item = this._list[index];
  3114. this._list.splice(index, 1);
  3115. this._writeListToPath();
  3116. return item;
  3117. };
  3118. window.SVGPathSegList.prototype.appendItem = function (newItem) {
  3119. this._checkPathSynchronizedToList();
  3120. if (newItem._owningPathSegList) {
  3121. // SVG2 spec says to make a copy.
  3122. newItem = newItem.clone();
  3123. }
  3124. this._list.push(newItem);
  3125. newItem._owningPathSegList = this; // TODO: Optimize this to just append to the existing attribute.
  3126. this._writeListToPath();
  3127. return newItem;
  3128. };
  3129. window.SVGPathSegList._pathSegArrayAsString = function (pathSegArray) {
  3130. var string = "";
  3131. var first = true;
  3132. pathSegArray.forEach(function (pathSeg) {
  3133. if (first) {
  3134. first = false;
  3135. string += pathSeg._asPathString();
  3136. } else {
  3137. string += " " + pathSeg._asPathString();
  3138. }
  3139. });
  3140. return string;
  3141. }; // This closely follows SVGPathParser::parsePath from Source/core/svg/SVGPathParser.cpp.
  3142. window.SVGPathSegList.prototype._parsePath = function (string) {
  3143. if (!string || string.length == 0) return [];
  3144. var owningPathSegList = this;
  3145. var Builder = function Builder() {
  3146. this.pathSegList = [];
  3147. };
  3148. Builder.prototype.appendSegment = function (pathSeg) {
  3149. this.pathSegList.push(pathSeg);
  3150. };
  3151. var Source = function Source(string) {
  3152. this._string = string;
  3153. this._currentIndex = 0;
  3154. this._endIndex = this._string.length;
  3155. this._previousCommand = window.SVGPathSeg.PATHSEG_UNKNOWN;
  3156. this._skipOptionalSpaces();
  3157. };
  3158. Source.prototype._isCurrentSpace = function () {
  3159. var character = this._string[this._currentIndex];
  3160. return character <= " " && (character == " " || character == "\n" || character == "\t" || character == "\r" || character == "\f");
  3161. };
  3162. Source.prototype._skipOptionalSpaces = function () {
  3163. while (this._currentIndex < this._endIndex && this._isCurrentSpace()) {
  3164. this._currentIndex++;
  3165. }
  3166. return this._currentIndex < this._endIndex;
  3167. };
  3168. Source.prototype._skipOptionalSpacesOrDelimiter = function () {
  3169. if (this._currentIndex < this._endIndex && !this._isCurrentSpace() && this._string.charAt(this._currentIndex) != ",") return false;
  3170. if (this._skipOptionalSpaces()) {
  3171. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ",") {
  3172. this._currentIndex++;
  3173. this._skipOptionalSpaces();
  3174. }
  3175. }
  3176. return this._currentIndex < this._endIndex;
  3177. };
  3178. Source.prototype.hasMoreData = function () {
  3179. return this._currentIndex < this._endIndex;
  3180. };
  3181. Source.prototype.peekSegmentType = function () {
  3182. var lookahead = this._string[this._currentIndex];
  3183. return this._pathSegTypeFromChar(lookahead);
  3184. };
  3185. Source.prototype._pathSegTypeFromChar = function (lookahead) {
  3186. switch (lookahead) {
  3187. case "Z":
  3188. case "z":
  3189. return window.SVGPathSeg.PATHSEG_CLOSEPATH;
  3190. case "M":
  3191. return window.SVGPathSeg.PATHSEG_MOVETO_ABS;
  3192. case "m":
  3193. return window.SVGPathSeg.PATHSEG_MOVETO_REL;
  3194. case "L":
  3195. return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  3196. case "l":
  3197. return window.SVGPathSeg.PATHSEG_LINETO_REL;
  3198. case "C":
  3199. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS;
  3200. case "c":
  3201. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL;
  3202. case "Q":
  3203. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS;
  3204. case "q":
  3205. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL;
  3206. case "A":
  3207. return window.SVGPathSeg.PATHSEG_ARC_ABS;
  3208. case "a":
  3209. return window.SVGPathSeg.PATHSEG_ARC_REL;
  3210. case "H":
  3211. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS;
  3212. case "h":
  3213. return window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL;
  3214. case "V":
  3215. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS;
  3216. case "v":
  3217. return window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL;
  3218. case "S":
  3219. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS;
  3220. case "s":
  3221. return window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL;
  3222. case "T":
  3223. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS;
  3224. case "t":
  3225. return window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL;
  3226. default:
  3227. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  3228. }
  3229. };
  3230. Source.prototype._nextCommandHelper = function (lookahead, previousCommand) {
  3231. // Check for remaining coordinates in the current command.
  3232. if ((lookahead == "+" || lookahead == "-" || lookahead == "." || lookahead >= "0" && lookahead <= "9") && previousCommand != window.SVGPathSeg.PATHSEG_CLOSEPATH) {
  3233. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_ABS) return window.SVGPathSeg.PATHSEG_LINETO_ABS;
  3234. if (previousCommand == window.SVGPathSeg.PATHSEG_MOVETO_REL) return window.SVGPathSeg.PATHSEG_LINETO_REL;
  3235. return previousCommand;
  3236. }
  3237. return window.SVGPathSeg.PATHSEG_UNKNOWN;
  3238. };
  3239. Source.prototype.initialCommandIsMoveTo = function () {
  3240. // If the path is empty it is still valid, so return true.
  3241. if (!this.hasMoreData()) return true;
  3242. var command = this.peekSegmentType(); // Path must start with moveTo.
  3243. return command == window.SVGPathSeg.PATHSEG_MOVETO_ABS || command == window.SVGPathSeg.PATHSEG_MOVETO_REL;
  3244. }; // Parse a number from an SVG path. This very closely follows genericParseNumber(...) from Source/core/svg/SVGParserUtilities.cpp.
  3245. // Spec: http://www.w3.org/TR/SVG11/single-page.html#paths-PathDataBNF
  3246. Source.prototype._parseNumber = function () {
  3247. var exponent = 0;
  3248. var integer = 0;
  3249. var frac = 1;
  3250. var decimal = 0;
  3251. var sign = 1;
  3252. var expsign = 1;
  3253. var startIndex = this._currentIndex;
  3254. this._skipOptionalSpaces(); // Read the sign.
  3255. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "+") this._currentIndex++;else if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == "-") {
  3256. this._currentIndex++;
  3257. sign = -1;
  3258. }
  3259. if (this._currentIndex == this._endIndex || (this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") && this._string.charAt(this._currentIndex) != ".") // The first character of a number must be one of [0-9+-.].
  3260. return undefined; // Read the integer part, cloud right-to-left.
  3261. var startIntPartIndex = this._currentIndex;
  3262. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  3263. this._currentIndex++;
  3264. } // Advance to first non-digit.
  3265. if (this._currentIndex != startIntPartIndex) {
  3266. var scanIntPartIndex = this._currentIndex - 1;
  3267. var multiplier = 1;
  3268. while (scanIntPartIndex >= startIntPartIndex) {
  3269. integer += multiplier * (this._string.charAt(scanIntPartIndex--) - "0");
  3270. multiplier *= 10;
  3271. }
  3272. } // Read the decimals.
  3273. if (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) == ".") {
  3274. this._currentIndex++; // There must be a least one digit following the .
  3275. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  3276. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  3277. frac *= 10;
  3278. decimal += (this._string.charAt(this._currentIndex) - "0") / frac;
  3279. this._currentIndex += 1;
  3280. }
  3281. } // Read the exponent part.
  3282. 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") {
  3283. this._currentIndex++; // Read the sign of the exponent.
  3284. if (this._string.charAt(this._currentIndex) == "+") {
  3285. this._currentIndex++;
  3286. } else if (this._string.charAt(this._currentIndex) == "-") {
  3287. this._currentIndex++;
  3288. expsign = -1;
  3289. } // There must be an exponent.
  3290. if (this._currentIndex >= this._endIndex || this._string.charAt(this._currentIndex) < "0" || this._string.charAt(this._currentIndex) > "9") return undefined;
  3291. while (this._currentIndex < this._endIndex && this._string.charAt(this._currentIndex) >= "0" && this._string.charAt(this._currentIndex) <= "9") {
  3292. exponent *= 10;
  3293. exponent += this._string.charAt(this._currentIndex) - "0";
  3294. this._currentIndex++;
  3295. }
  3296. }
  3297. var number = integer + decimal;
  3298. number *= sign;
  3299. if (exponent) number *= Math.pow(10, expsign * exponent);
  3300. if (startIndex == this._currentIndex) return undefined;
  3301. this._skipOptionalSpacesOrDelimiter();
  3302. return number;
  3303. };
  3304. Source.prototype._parseArcFlag = function () {
  3305. if (this._currentIndex >= this._endIndex) return undefined;
  3306. var flag = false;
  3307. var flagChar = this._string.charAt(this._currentIndex++);
  3308. if (flagChar == "0") flag = false;else if (flagChar == "1") flag = true;else return undefined;
  3309. this._skipOptionalSpacesOrDelimiter();
  3310. return flag;
  3311. };
  3312. Source.prototype.parseSegment = function () {
  3313. var lookahead = this._string[this._currentIndex];
  3314. var command = this._pathSegTypeFromChar(lookahead);
  3315. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) {
  3316. // Possibly an implicit command. Not allowed if this is the first command.
  3317. if (this._previousCommand == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  3318. command = this._nextCommandHelper(lookahead, this._previousCommand);
  3319. if (command == window.SVGPathSeg.PATHSEG_UNKNOWN) return null;
  3320. } else {
  3321. this._currentIndex++;
  3322. }
  3323. this._previousCommand = command;
  3324. switch (command) {
  3325. case window.SVGPathSeg.PATHSEG_MOVETO_REL:
  3326. return new window.SVGPathSegMovetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3327. case window.SVGPathSeg.PATHSEG_MOVETO_ABS:
  3328. return new window.SVGPathSegMovetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3329. case window.SVGPathSeg.PATHSEG_LINETO_REL:
  3330. return new window.SVGPathSegLinetoRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3331. case window.SVGPathSeg.PATHSEG_LINETO_ABS:
  3332. return new window.SVGPathSegLinetoAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3333. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
  3334. return new window.SVGPathSegLinetoHorizontalRel(owningPathSegList, this._parseNumber());
  3335. case window.SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
  3336. return new window.SVGPathSegLinetoHorizontalAbs(owningPathSegList, this._parseNumber());
  3337. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
  3338. return new window.SVGPathSegLinetoVerticalRel(owningPathSegList, this._parseNumber());
  3339. case window.SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
  3340. return new window.SVGPathSegLinetoVerticalAbs(owningPathSegList, this._parseNumber());
  3341. case window.SVGPathSeg.PATHSEG_CLOSEPATH:
  3342. this._skipOptionalSpaces();
  3343. return new window.SVGPathSegClosePath(owningPathSegList);
  3344. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
  3345. var points = {
  3346. x1: this._parseNumber(),
  3347. y1: this._parseNumber(),
  3348. x2: this._parseNumber(),
  3349. y2: this._parseNumber(),
  3350. x: this._parseNumber(),
  3351. y: this._parseNumber()
  3352. };
  3353. return new window.SVGPathSegCurvetoCubicRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  3354. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
  3355. var points = {
  3356. x1: this._parseNumber(),
  3357. y1: this._parseNumber(),
  3358. x2: this._parseNumber(),
  3359. y2: this._parseNumber(),
  3360. x: this._parseNumber(),
  3361. y: this._parseNumber()
  3362. };
  3363. return new window.SVGPathSegCurvetoCubicAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.x2, points.y2);
  3364. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
  3365. var points = {
  3366. x2: this._parseNumber(),
  3367. y2: this._parseNumber(),
  3368. x: this._parseNumber(),
  3369. y: this._parseNumber()
  3370. };
  3371. return new window.SVGPathSegCurvetoCubicSmoothRel(owningPathSegList, points.x, points.y, points.x2, points.y2);
  3372. case window.SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
  3373. var points = {
  3374. x2: this._parseNumber(),
  3375. y2: this._parseNumber(),
  3376. x: this._parseNumber(),
  3377. y: this._parseNumber()
  3378. };
  3379. return new window.SVGPathSegCurvetoCubicSmoothAbs(owningPathSegList, points.x, points.y, points.x2, points.y2);
  3380. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
  3381. var points = {
  3382. x1: this._parseNumber(),
  3383. y1: this._parseNumber(),
  3384. x: this._parseNumber(),
  3385. y: this._parseNumber()
  3386. };
  3387. return new window.SVGPathSegCurvetoQuadraticRel(owningPathSegList, points.x, points.y, points.x1, points.y1);
  3388. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
  3389. var points = {
  3390. x1: this._parseNumber(),
  3391. y1: this._parseNumber(),
  3392. x: this._parseNumber(),
  3393. y: this._parseNumber()
  3394. };
  3395. return new window.SVGPathSegCurvetoQuadraticAbs(owningPathSegList, points.x, points.y, points.x1, points.y1);
  3396. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
  3397. return new window.SVGPathSegCurvetoQuadraticSmoothRel(owningPathSegList, this._parseNumber(), this._parseNumber());
  3398. case window.SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
  3399. return new window.SVGPathSegCurvetoQuadraticSmoothAbs(owningPathSegList, this._parseNumber(), this._parseNumber());
  3400. case window.SVGPathSeg.PATHSEG_ARC_REL:
  3401. var points = {
  3402. x1: this._parseNumber(),
  3403. y1: this._parseNumber(),
  3404. arcAngle: this._parseNumber(),
  3405. arcLarge: this._parseArcFlag(),
  3406. arcSweep: this._parseArcFlag(),
  3407. x: this._parseNumber(),
  3408. y: this._parseNumber()
  3409. };
  3410. return new window.SVGPathSegArcRel(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  3411. case window.SVGPathSeg.PATHSEG_ARC_ABS:
  3412. var points = {
  3413. x1: this._parseNumber(),
  3414. y1: this._parseNumber(),
  3415. arcAngle: this._parseNumber(),
  3416. arcLarge: this._parseArcFlag(),
  3417. arcSweep: this._parseArcFlag(),
  3418. x: this._parseNumber(),
  3419. y: this._parseNumber()
  3420. };
  3421. return new window.SVGPathSegArcAbs(owningPathSegList, points.x, points.y, points.x1, points.y1, points.arcAngle, points.arcLarge, points.arcSweep);
  3422. default:
  3423. throw "Unknown path seg type.";
  3424. }
  3425. };
  3426. var builder = new Builder();
  3427. var source = new Source(string);
  3428. if (!source.initialCommandIsMoveTo()) return [];
  3429. while (source.hasMoreData()) {
  3430. var pathSeg = source.parseSegment();
  3431. if (!pathSeg) return [];
  3432. builder.appendSegment(pathSeg);
  3433. }
  3434. return builder.pathSegList;
  3435. };
  3436. }
  3437. })(); // String.padEnd polyfill for IE11
  3438. //
  3439. // https://github.com/uxitten/polyfill/blob/master/string.polyfill.js
  3440. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
  3441. if (!String.prototype.padEnd) {
  3442. String.prototype.padEnd = function padEnd(targetLength, padString) {
  3443. targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
  3444. padString = String(typeof padString !== 'undefined' ? padString : ' ');
  3445. if (this.length > targetLength) {
  3446. return String(this);
  3447. } else {
  3448. targetLength = targetLength - this.length;
  3449. if (targetLength > padString.length) {
  3450. padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
  3451. }
  3452. return String(this) + padString.slice(0, targetLength);
  3453. }
  3454. };
  3455. }
  3456. /* jshint ignore:end */
  3457. Chart.prototype.axis = function () {};
  3458. Chart.prototype.axis.labels = function (labels) {
  3459. var $$ = this.internal;
  3460. if (arguments.length) {
  3461. Object.keys(labels).forEach(function (axisId) {
  3462. $$.axis.setLabelText(axisId, labels[axisId]);
  3463. });
  3464. $$.axis.updateLabels();
  3465. } // TODO: return some values?
  3466. };
  3467. Chart.prototype.axis.max = function (max) {
  3468. var $$ = this.internal,
  3469. config = $$.config;
  3470. if (arguments.length) {
  3471. if (_typeof(max) === 'object') {
  3472. if (isValue(max.x)) {
  3473. config.axis_x_max = max.x;
  3474. }
  3475. if (isValue(max.y)) {
  3476. config.axis_y_max = max.y;
  3477. }
  3478. if (isValue(max.y2)) {
  3479. config.axis_y2_max = max.y2;
  3480. }
  3481. } else {
  3482. config.axis_y_max = config.axis_y2_max = max;
  3483. }
  3484. $$.redraw({
  3485. withUpdateOrgXDomain: true,
  3486. withUpdateXDomain: true
  3487. });
  3488. } else {
  3489. return {
  3490. x: config.axis_x_max,
  3491. y: config.axis_y_max,
  3492. y2: config.axis_y2_max
  3493. };
  3494. }
  3495. };
  3496. Chart.prototype.axis.min = function (min) {
  3497. var $$ = this.internal,
  3498. config = $$.config;
  3499. if (arguments.length) {
  3500. if (_typeof(min) === 'object') {
  3501. if (isValue(min.x)) {
  3502. config.axis_x_min = min.x;
  3503. }
  3504. if (isValue(min.y)) {
  3505. config.axis_y_min = min.y;
  3506. }
  3507. if (isValue(min.y2)) {
  3508. config.axis_y2_min = min.y2;
  3509. }
  3510. } else {
  3511. config.axis_y_min = config.axis_y2_min = min;
  3512. }
  3513. $$.redraw({
  3514. withUpdateOrgXDomain: true,
  3515. withUpdateXDomain: true
  3516. });
  3517. } else {
  3518. return {
  3519. x: config.axis_x_min,
  3520. y: config.axis_y_min,
  3521. y2: config.axis_y2_min
  3522. };
  3523. }
  3524. };
  3525. Chart.prototype.axis.range = function (range) {
  3526. if (arguments.length) {
  3527. if (isDefined(range.max)) {
  3528. this.axis.max(range.max);
  3529. }
  3530. if (isDefined(range.min)) {
  3531. this.axis.min(range.min);
  3532. }
  3533. } else {
  3534. return {
  3535. max: this.axis.max(),
  3536. min: this.axis.min()
  3537. };
  3538. }
  3539. };
  3540. Chart.prototype.category = function (i, category) {
  3541. var $$ = this.internal,
  3542. config = $$.config;
  3543. if (arguments.length > 1) {
  3544. config.axis_x_categories[i] = category;
  3545. $$.redraw();
  3546. }
  3547. return config.axis_x_categories[i];
  3548. };
  3549. Chart.prototype.categories = function (categories) {
  3550. var $$ = this.internal,
  3551. config = $$.config;
  3552. if (!arguments.length) {
  3553. return config.axis_x_categories;
  3554. }
  3555. config.axis_x_categories = categories;
  3556. $$.redraw();
  3557. return config.axis_x_categories;
  3558. };
  3559. Chart.prototype.resize = function (size) {
  3560. var $$ = this.internal,
  3561. config = $$.config;
  3562. config.size_width = size ? size.width : null;
  3563. config.size_height = size ? size.height : null;
  3564. this.flush();
  3565. };
  3566. Chart.prototype.flush = function () {
  3567. var $$ = this.internal;
  3568. $$.updateAndRedraw({
  3569. withLegend: true,
  3570. withTransition: false,
  3571. withTransitionForTransform: false
  3572. });
  3573. };
  3574. Chart.prototype.destroy = function () {
  3575. var $$ = this.internal;
  3576. window.clearInterval($$.intervalForObserveInserted);
  3577. if ($$.resizeTimeout !== undefined) {
  3578. window.clearTimeout($$.resizeTimeout);
  3579. }
  3580. if (window.detachEvent) {
  3581. window.detachEvent('onresize', $$.resizeIfElementDisplayed);
  3582. } else if (window.removeEventListener) {
  3583. window.removeEventListener('resize', $$.resizeIfElementDisplayed);
  3584. } else {
  3585. var wrapper = window.onresize; // check if no one else removed our wrapper and remove our resizeFunction from it
  3586. if (wrapper && wrapper.add && wrapper.remove) {
  3587. wrapper.remove($$.resizeFunction);
  3588. }
  3589. } // Removes the inner resize functions
  3590. $$.resizeFunction.remove(); // Unbinds from the window focus event
  3591. $$.unbindWindowFocus();
  3592. $$.selectChart.classed('c3', false).html(""); // MEMO: this is needed because the reference of some elements will not be released, then memory leak will happen.
  3593. Object.keys($$).forEach(function (key) {
  3594. $$[key] = null;
  3595. });
  3596. return null;
  3597. };
  3598. Chart.prototype.color = function (id) {
  3599. var $$ = this.internal;
  3600. return $$.color(id); // more patterns
  3601. };
  3602. Chart.prototype.data = function (targetIds) {
  3603. var targets = this.internal.data.targets;
  3604. return typeof targetIds === 'undefined' ? targets : targets.filter(function (t) {
  3605. return [].concat(targetIds).indexOf(t.id) >= 0;
  3606. });
  3607. };
  3608. Chart.prototype.data.shown = function (targetIds) {
  3609. return this.internal.filterTargetsToShow(this.data(targetIds));
  3610. };
  3611. /**
  3612. * Get values of the data loaded in the chart.
  3613. *
  3614. * @param {String|Array} targetId This API returns the value of specified target.
  3615. * @param flat
  3616. * @return {Array} Data values
  3617. */
  3618. Chart.prototype.data.values = function (targetId) {
  3619. var flat = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
  3620. var values = null;
  3621. if (targetId) {
  3622. var targets = this.data(targetId);
  3623. if (targets && isArray(targets)) {
  3624. values = targets.reduce(function (ret, v) {
  3625. var dataValue = v.values.map(function (d) {
  3626. return d.value;
  3627. });
  3628. if (flat) {
  3629. ret = ret.concat(dataValue);
  3630. } else {
  3631. ret.push(dataValue);
  3632. }
  3633. return ret;
  3634. }, []);
  3635. }
  3636. }
  3637. return values;
  3638. };
  3639. Chart.prototype.data.names = function (names) {
  3640. this.internal.clearLegendItemTextBoxCache();
  3641. return this.internal.updateDataAttributes('names', names);
  3642. };
  3643. Chart.prototype.data.colors = function (colors) {
  3644. return this.internal.updateDataAttributes('colors', colors);
  3645. };
  3646. Chart.prototype.data.axes = function (axes) {
  3647. return this.internal.updateDataAttributes('axes', axes);
  3648. };
  3649. Chart.prototype.data.stackNormalized = function (normalized) {
  3650. if (normalized === undefined) {
  3651. return this.internal.isStackNormalized();
  3652. }
  3653. this.internal.config.data_stack_normalize = !!normalized;
  3654. this.internal.redraw();
  3655. };
  3656. Chart.prototype.donut = function () {};
  3657. Chart.prototype.donut.padAngle = function (padAngle) {
  3658. if (padAngle === undefined) {
  3659. return this.internal.config.donut_padAngle;
  3660. }
  3661. this.internal.config.donut_padAngle = padAngle;
  3662. this.flush();
  3663. };
  3664. Chart.prototype.flow = function (args) {
  3665. var $$ = this.internal,
  3666. targets,
  3667. data,
  3668. notfoundIds = [],
  3669. orgDataCount = $$.getMaxDataCount(),
  3670. dataCount,
  3671. domain,
  3672. baseTarget,
  3673. baseValue,
  3674. length = 0,
  3675. tail = 0,
  3676. diff,
  3677. to;
  3678. if (args.json) {
  3679. data = $$.convertJsonToData(args.json, args.keys);
  3680. } else if (args.rows) {
  3681. data = $$.convertRowsToData(args.rows);
  3682. } else if (args.columns) {
  3683. data = $$.convertColumnsToData(args.columns);
  3684. } else {
  3685. return;
  3686. }
  3687. targets = $$.convertDataToTargets(data, true); // Update/Add data
  3688. $$.data.targets.forEach(function (t) {
  3689. var found = false,
  3690. i,
  3691. j;
  3692. for (i = 0; i < targets.length; i++) {
  3693. if (t.id === targets[i].id) {
  3694. found = true;
  3695. if (t.values[t.values.length - 1]) {
  3696. tail = t.values[t.values.length - 1].index + 1;
  3697. }
  3698. length = targets[i].values.length;
  3699. for (j = 0; j < length; j++) {
  3700. targets[i].values[j].index = tail + j;
  3701. if (!$$.isTimeSeries()) {
  3702. targets[i].values[j].x = tail + j;
  3703. }
  3704. }
  3705. t.values = t.values.concat(targets[i].values);
  3706. targets.splice(i, 1);
  3707. break;
  3708. }
  3709. }
  3710. if (!found) {
  3711. notfoundIds.push(t.id);
  3712. }
  3713. }); // Append null for not found targets
  3714. $$.data.targets.forEach(function (t) {
  3715. var i, j;
  3716. for (i = 0; i < notfoundIds.length; i++) {
  3717. if (t.id === notfoundIds[i]) {
  3718. tail = t.values[t.values.length - 1].index + 1;
  3719. for (j = 0; j < length; j++) {
  3720. t.values.push({
  3721. id: t.id,
  3722. index: tail + j,
  3723. x: $$.isTimeSeries() ? $$.getOtherTargetX(tail + j) : tail + j,
  3724. value: null
  3725. });
  3726. }
  3727. }
  3728. }
  3729. }); // Generate null values for new target
  3730. if ($$.data.targets.length) {
  3731. targets.forEach(function (t) {
  3732. var i,
  3733. missing = [];
  3734. for (i = $$.data.targets[0].values[0].index; i < tail; i++) {
  3735. missing.push({
  3736. id: t.id,
  3737. index: i,
  3738. x: $$.isTimeSeries() ? $$.getOtherTargetX(i) : i,
  3739. value: null
  3740. });
  3741. }
  3742. t.values.forEach(function (v) {
  3743. v.index += tail;
  3744. if (!$$.isTimeSeries()) {
  3745. v.x += tail;
  3746. }
  3747. });
  3748. t.values = missing.concat(t.values);
  3749. });
  3750. }
  3751. $$.data.targets = $$.data.targets.concat(targets); // add remained
  3752. // check data count because behavior needs to change when it's only one
  3753. dataCount = $$.getMaxDataCount();
  3754. baseTarget = $$.data.targets[0];
  3755. baseValue = baseTarget.values[0]; // Update length to flow if needed
  3756. if (isDefined(args.to)) {
  3757. length = 0;
  3758. to = $$.isTimeSeries() ? $$.parseDate(args.to) : args.to;
  3759. baseTarget.values.forEach(function (v) {
  3760. if (v.x < to) {
  3761. length++;
  3762. }
  3763. });
  3764. } else if (isDefined(args.length)) {
  3765. length = args.length;
  3766. } // If only one data, update the domain to flow from left edge of the chart
  3767. if (!orgDataCount) {
  3768. if ($$.isTimeSeries()) {
  3769. if (baseTarget.values.length > 1) {
  3770. diff = baseTarget.values[baseTarget.values.length - 1].x - baseValue.x;
  3771. } else {
  3772. diff = baseValue.x - $$.getXDomain($$.data.targets)[0];
  3773. }
  3774. } else {
  3775. diff = 1;
  3776. }
  3777. domain = [baseValue.x - diff, baseValue.x];
  3778. $$.updateXDomain(null, true, true, false, domain);
  3779. } else if (orgDataCount === 1) {
  3780. if ($$.isTimeSeries()) {
  3781. diff = (baseTarget.values[baseTarget.values.length - 1].x - baseValue.x) / 2;
  3782. domain = [new Date(+baseValue.x - diff), new Date(+baseValue.x + diff)];
  3783. $$.updateXDomain(null, true, true, false, domain);
  3784. }
  3785. } // Set targets
  3786. $$.updateTargets($$.data.targets); // Redraw with new targets
  3787. $$.redraw({
  3788. flow: {
  3789. index: baseValue.index,
  3790. length: length,
  3791. duration: isValue(args.duration) ? args.duration : $$.config.transition_duration,
  3792. done: args.done,
  3793. orgDataCount: orgDataCount
  3794. },
  3795. withLegend: true,
  3796. withTransition: orgDataCount > 1,
  3797. withTrimXDomain: false,
  3798. withUpdateXAxis: true
  3799. });
  3800. };
  3801. ChartInternal.prototype.generateFlow = function (args) {
  3802. var $$ = this,
  3803. config = $$.config,
  3804. d3 = $$.d3;
  3805. return function () {
  3806. var targets = args.targets,
  3807. flow = args.flow,
  3808. drawBar = args.drawBar,
  3809. drawLine = args.drawLine,
  3810. drawArea = args.drawArea,
  3811. cx = args.cx,
  3812. cy = args.cy,
  3813. xv = args.xv,
  3814. xForText = args.xForText,
  3815. yForText = args.yForText,
  3816. duration = args.duration;
  3817. var translateX,
  3818. scaleX = 1,
  3819. transform,
  3820. flowIndex = flow.index,
  3821. flowLength = flow.length,
  3822. flowStart = $$.getValueOnIndex($$.data.targets[0].values, flowIndex),
  3823. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, flowIndex + flowLength),
  3824. orgDomain = $$.x.domain(),
  3825. domain,
  3826. durationForFlow = flow.duration || duration,
  3827. done = flow.done || function () {},
  3828. wait = $$.generateWait();
  3829. var xgrid, xgridLines, mainRegion, mainText, mainBar, mainLine, mainArea, mainCircle; // set flag
  3830. $$.flowing = true; // remove head data after rendered
  3831. $$.data.targets.forEach(function (d) {
  3832. d.values.splice(0, flowLength);
  3833. }); // update x domain to generate axis elements for flow
  3834. domain = $$.updateXDomain(targets, true, true); // update elements related to x scale
  3835. if ($$.updateXGrid) {
  3836. $$.updateXGrid(true);
  3837. }
  3838. xgrid = $$.xgrid || d3.selectAll([]); // xgrid needs to be obtained after updateXGrid
  3839. xgridLines = $$.xgridLines || d3.selectAll([]);
  3840. mainRegion = $$.mainRegion || d3.selectAll([]);
  3841. mainText = $$.mainText || d3.selectAll([]);
  3842. mainBar = $$.mainBar || d3.selectAll([]);
  3843. mainLine = $$.mainLine || d3.selectAll([]);
  3844. mainArea = $$.mainArea || d3.selectAll([]);
  3845. mainCircle = $$.mainCircle || d3.selectAll([]); // generate transform to flow
  3846. if (!flow.orgDataCount) {
  3847. // if empty
  3848. if ($$.data.targets[0].values.length !== 1) {
  3849. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3850. } else {
  3851. if ($$.isTimeSeries()) {
  3852. flowStart = $$.getValueOnIndex($$.data.targets[0].values, 0);
  3853. flowEnd = $$.getValueOnIndex($$.data.targets[0].values, $$.data.targets[0].values.length - 1);
  3854. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3855. } else {
  3856. translateX = diffDomain(domain) / 2;
  3857. }
  3858. }
  3859. } else if (flow.orgDataCount === 1 || (flowStart && flowStart.x) === (flowEnd && flowEnd.x)) {
  3860. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3861. } else {
  3862. if ($$.isTimeSeries()) {
  3863. translateX = $$.x(orgDomain[0]) - $$.x(domain[0]);
  3864. } else {
  3865. translateX = $$.x(flowStart.x) - $$.x(flowEnd.x);
  3866. }
  3867. }
  3868. scaleX = diffDomain(orgDomain) / diffDomain(domain);
  3869. transform = 'translate(' + translateX + ',0) scale(' + scaleX + ',1)';
  3870. $$.hideXGridFocus();
  3871. var flowTransition = d3.transition().ease(d3.easeLinear).duration(durationForFlow);
  3872. wait.add($$.xAxis($$.axes.x, flowTransition));
  3873. wait.add(mainBar.transition(flowTransition).attr('transform', transform));
  3874. wait.add(mainLine.transition(flowTransition).attr('transform', transform));
  3875. wait.add(mainArea.transition(flowTransition).attr('transform', transform));
  3876. wait.add(mainCircle.transition(flowTransition).attr('transform', transform));
  3877. wait.add(mainText.transition(flowTransition).attr('transform', transform));
  3878. wait.add(mainRegion.filter($$.isRegionOnX).transition(flowTransition).attr('transform', transform));
  3879. wait.add(xgrid.transition(flowTransition).attr('transform', transform));
  3880. wait.add(xgridLines.transition(flowTransition).attr('transform', transform));
  3881. wait(function () {
  3882. var i,
  3883. shapes = [],
  3884. texts = []; // remove flowed elements
  3885. if (flowLength) {
  3886. for (i = 0; i < flowLength; i++) {
  3887. shapes.push('.' + CLASS.shape + '-' + (flowIndex + i));
  3888. texts.push('.' + CLASS.text + '-' + (flowIndex + i));
  3889. }
  3890. $$.svg.selectAll('.' + CLASS.shapes).selectAll(shapes).remove();
  3891. $$.svg.selectAll('.' + CLASS.texts).selectAll(texts).remove();
  3892. $$.svg.select('.' + CLASS.xgrid).remove();
  3893. } // draw again for removing flowed elements and reverting attr
  3894. xgrid.attr('transform', null).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity);
  3895. xgridLines.attr('transform', null);
  3896. xgridLines.select('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv);
  3897. xgridLines.select('text').attr("x", config.axis_rotated ? $$.width : 0).attr("y", xv);
  3898. mainBar.attr('transform', null).attr("d", drawBar);
  3899. mainLine.attr('transform', null).attr("d", drawLine);
  3900. mainArea.attr('transform', null).attr("d", drawArea);
  3901. mainCircle.attr('transform', null).attr("cx", cx).attr("cy", cy);
  3902. mainText.attr('transform', null).attr('x', xForText).attr('y', yForText).style('fill-opacity', $$.opacityForText.bind($$));
  3903. mainRegion.attr('transform', null);
  3904. mainRegion.filter($$.isRegionOnX).attr("x", $$.regionX.bind($$)).attr("width", $$.regionWidth.bind($$)); // callback for end of flow
  3905. done();
  3906. $$.flowing = false;
  3907. });
  3908. };
  3909. };
  3910. Chart.prototype.focus = function (targetIds) {
  3911. var $$ = this.internal,
  3912. candidates;
  3913. targetIds = $$.mapToTargetIds(targetIds);
  3914. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), this.revert();
  3915. this.defocus();
  3916. candidates.classed(CLASS.focused, true).classed(CLASS.defocused, false);
  3917. if ($$.hasArcType()) {
  3918. $$.expandArc(targetIds);
  3919. }
  3920. $$.toggleFocusLegend(targetIds, true);
  3921. $$.focusedTargetIds = targetIds;
  3922. $$.defocusedTargetIds = $$.defocusedTargetIds.filter(function (id) {
  3923. return targetIds.indexOf(id) < 0;
  3924. });
  3925. };
  3926. Chart.prototype.defocus = function (targetIds) {
  3927. var $$ = this.internal,
  3928. candidates;
  3929. targetIds = $$.mapToTargetIds(targetIds);
  3930. candidates = $$.svg.selectAll($$.selectorTargets(targetIds.filter($$.isTargetToShow, $$))), candidates.classed(CLASS.focused, false).classed(CLASS.defocused, true);
  3931. if ($$.hasArcType()) {
  3932. $$.unexpandArc(targetIds);
  3933. }
  3934. $$.toggleFocusLegend(targetIds, false);
  3935. $$.focusedTargetIds = $$.focusedTargetIds.filter(function (id) {
  3936. return targetIds.indexOf(id) < 0;
  3937. });
  3938. $$.defocusedTargetIds = targetIds;
  3939. };
  3940. Chart.prototype.revert = function (targetIds) {
  3941. var $$ = this.internal,
  3942. candidates;
  3943. targetIds = $$.mapToTargetIds(targetIds);
  3944. candidates = $$.svg.selectAll($$.selectorTargets(targetIds)); // should be for all targets
  3945. candidates.classed(CLASS.focused, false).classed(CLASS.defocused, false);
  3946. if ($$.hasArcType()) {
  3947. $$.unexpandArc(targetIds);
  3948. }
  3949. if ($$.config.legend_show) {
  3950. $$.showLegend(targetIds.filter($$.isLegendToShow.bind($$)));
  3951. $$.legend.selectAll($$.selectorLegends(targetIds)).filter(function () {
  3952. return $$.d3.select(this).classed(CLASS.legendItemFocused);
  3953. }).classed(CLASS.legendItemFocused, false);
  3954. }
  3955. $$.focusedTargetIds = [];
  3956. $$.defocusedTargetIds = [];
  3957. };
  3958. Chart.prototype.xgrids = function (grids) {
  3959. var $$ = this.internal,
  3960. config = $$.config;
  3961. if (!grids) {
  3962. return config.grid_x_lines;
  3963. }
  3964. config.grid_x_lines = grids;
  3965. $$.redrawWithoutRescale();
  3966. return config.grid_x_lines;
  3967. };
  3968. Chart.prototype.xgrids.add = function (grids) {
  3969. var $$ = this.internal;
  3970. return this.xgrids($$.config.grid_x_lines.concat(grids ? grids : []));
  3971. };
  3972. Chart.prototype.xgrids.remove = function (params) {
  3973. // TODO: multiple
  3974. var $$ = this.internal;
  3975. $$.removeGridLines(params, true);
  3976. };
  3977. Chart.prototype.ygrids = function (grids) {
  3978. var $$ = this.internal,
  3979. config = $$.config;
  3980. if (!grids) {
  3981. return config.grid_y_lines;
  3982. }
  3983. config.grid_y_lines = grids;
  3984. $$.redrawWithoutRescale();
  3985. return config.grid_y_lines;
  3986. };
  3987. Chart.prototype.ygrids.add = function (grids) {
  3988. var $$ = this.internal;
  3989. return this.ygrids($$.config.grid_y_lines.concat(grids ? grids : []));
  3990. };
  3991. Chart.prototype.ygrids.remove = function (params) {
  3992. // TODO: multiple
  3993. var $$ = this.internal;
  3994. $$.removeGridLines(params, false);
  3995. };
  3996. Chart.prototype.groups = function (groups) {
  3997. var $$ = this.internal,
  3998. config = $$.config;
  3999. if (isUndefined(groups)) {
  4000. return config.data_groups;
  4001. }
  4002. config.data_groups = groups;
  4003. $$.redraw();
  4004. return config.data_groups;
  4005. };
  4006. Chart.prototype.legend = function () {};
  4007. Chart.prototype.legend.show = function (targetIds) {
  4008. var $$ = this.internal;
  4009. $$.showLegend($$.mapToTargetIds(targetIds));
  4010. $$.updateAndRedraw({
  4011. withLegend: true
  4012. });
  4013. };
  4014. Chart.prototype.legend.hide = function (targetIds) {
  4015. var $$ = this.internal;
  4016. $$.hideLegend($$.mapToTargetIds(targetIds));
  4017. $$.updateAndRedraw({
  4018. withLegend: false
  4019. });
  4020. };
  4021. Chart.prototype.load = function (args) {
  4022. var $$ = this.internal,
  4023. config = $$.config; // update xs if specified
  4024. if (args.xs) {
  4025. $$.addXs(args.xs);
  4026. } // update names if exists
  4027. if ('names' in args) {
  4028. Chart.prototype.data.names.bind(this)(args.names);
  4029. } // update classes if exists
  4030. if ('classes' in args) {
  4031. Object.keys(args.classes).forEach(function (id) {
  4032. config.data_classes[id] = args.classes[id];
  4033. });
  4034. } // update categories if exists
  4035. if ('categories' in args && $$.isCategorized()) {
  4036. config.axis_x_categories = args.categories;
  4037. } // update axes if exists
  4038. if ('axes' in args) {
  4039. Object.keys(args.axes).forEach(function (id) {
  4040. config.data_axes[id] = args.axes[id];
  4041. });
  4042. } // update colors if exists
  4043. if ('colors' in args) {
  4044. Object.keys(args.colors).forEach(function (id) {
  4045. config.data_colors[id] = args.colors[id];
  4046. });
  4047. } // use cache if exists
  4048. if ('cacheIds' in args && $$.hasCaches(args.cacheIds)) {
  4049. $$.load($$.getCaches(args.cacheIds), args.done);
  4050. return;
  4051. } // unload if needed
  4052. if (args.unload) {
  4053. // TODO: do not unload if target will load (included in url/rows/columns)
  4054. $$.unload($$.mapToTargetIds(args.unload === true ? null : args.unload), function () {
  4055. $$.loadFromArgs(args);
  4056. });
  4057. } else {
  4058. $$.loadFromArgs(args);
  4059. }
  4060. };
  4061. Chart.prototype.unload = function (args) {
  4062. var $$ = this.internal;
  4063. args = args || {};
  4064. if (args instanceof Array) {
  4065. args = {
  4066. ids: args
  4067. };
  4068. } else if (typeof args === 'string') {
  4069. args = {
  4070. ids: [args]
  4071. };
  4072. }
  4073. $$.unload($$.mapToTargetIds(args.ids), function () {
  4074. $$.redraw({
  4075. withUpdateOrgXDomain: true,
  4076. withUpdateXDomain: true,
  4077. withLegend: true
  4078. });
  4079. if (args.done) {
  4080. args.done();
  4081. }
  4082. });
  4083. };
  4084. Chart.prototype.pie = function () {};
  4085. Chart.prototype.pie.padAngle = function (padAngle) {
  4086. if (padAngle === undefined) {
  4087. return this.internal.config.pie_padAngle;
  4088. }
  4089. this.internal.config.pie_padAngle = padAngle;
  4090. this.flush();
  4091. };
  4092. Chart.prototype.regions = function (regions) {
  4093. var $$ = this.internal,
  4094. config = $$.config;
  4095. if (!regions) {
  4096. return config.regions;
  4097. }
  4098. config.regions = regions;
  4099. $$.redrawWithoutRescale();
  4100. return config.regions;
  4101. };
  4102. Chart.prototype.regions.add = function (regions) {
  4103. var $$ = this.internal,
  4104. config = $$.config;
  4105. if (!regions) {
  4106. return config.regions;
  4107. }
  4108. config.regions = config.regions.concat(regions);
  4109. $$.redrawWithoutRescale();
  4110. return config.regions;
  4111. };
  4112. Chart.prototype.regions.remove = function (options) {
  4113. var $$ = this.internal,
  4114. config = $$.config,
  4115. duration,
  4116. classes,
  4117. regions;
  4118. options = options || {};
  4119. duration = getOption(options, "duration", config.transition_duration);
  4120. classes = getOption(options, "classes", [CLASS.region]);
  4121. regions = $$.main.select('.' + CLASS.regions).selectAll(classes.map(function (c) {
  4122. return '.' + c;
  4123. }));
  4124. (duration ? regions.transition().duration(duration) : regions).style('opacity', 0).remove();
  4125. config.regions = config.regions.filter(function (region) {
  4126. var found = false;
  4127. if (!region['class']) {
  4128. return true;
  4129. }
  4130. region['class'].split(' ').forEach(function (c) {
  4131. if (classes.indexOf(c) >= 0) {
  4132. found = true;
  4133. }
  4134. });
  4135. return !found;
  4136. });
  4137. return config.regions;
  4138. };
  4139. Chart.prototype.selected = function (targetId) {
  4140. var $$ = this.internal,
  4141. d3 = $$.d3;
  4142. return $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(targetId)).selectAll('.' + CLASS.shape).filter(function () {
  4143. return d3.select(this).classed(CLASS.SELECTED);
  4144. }).nodes().map(function (d) {
  4145. var data = d.__data__;
  4146. return data.data ? data.data : data;
  4147. });
  4148. };
  4149. Chart.prototype.select = function (ids, indices, resetOther) {
  4150. var $$ = this.internal,
  4151. d3 = $$.d3,
  4152. config = $$.config;
  4153. if (!config.data_selection_enabled) {
  4154. return;
  4155. }
  4156. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  4157. var shape = d3.select(this),
  4158. id = d.data ? d.data.id : d.id,
  4159. toggle = $$.getToggle(this, d).bind($$),
  4160. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  4161. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  4162. isSelected = shape.classed(CLASS.SELECTED); // line/area selection not supported yet
  4163. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  4164. return;
  4165. }
  4166. if (isTargetId && isTargetIndex) {
  4167. if (config.data_selection_isselectable(d) && !isSelected) {
  4168. toggle(true, shape.classed(CLASS.SELECTED, true), d, i);
  4169. }
  4170. } else if (isDefined(resetOther) && resetOther) {
  4171. if (isSelected) {
  4172. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  4173. }
  4174. }
  4175. });
  4176. };
  4177. Chart.prototype.unselect = function (ids, indices) {
  4178. var $$ = this.internal,
  4179. d3 = $$.d3,
  4180. config = $$.config;
  4181. if (!config.data_selection_enabled) {
  4182. return;
  4183. }
  4184. $$.main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).each(function (d, i) {
  4185. var shape = d3.select(this),
  4186. id = d.data ? d.data.id : d.id,
  4187. toggle = $$.getToggle(this, d).bind($$),
  4188. isTargetId = config.data_selection_grouped || !ids || ids.indexOf(id) >= 0,
  4189. isTargetIndex = !indices || indices.indexOf(i) >= 0,
  4190. isSelected = shape.classed(CLASS.SELECTED); // line/area selection not supported yet
  4191. if (shape.classed(CLASS.line) || shape.classed(CLASS.area)) {
  4192. return;
  4193. }
  4194. if (isTargetId && isTargetIndex) {
  4195. if (config.data_selection_isselectable(d)) {
  4196. if (isSelected) {
  4197. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  4198. }
  4199. }
  4200. }
  4201. });
  4202. };
  4203. Chart.prototype.show = function (targetIds, options) {
  4204. var $$ = this.internal,
  4205. targets;
  4206. targetIds = $$.mapToTargetIds(targetIds);
  4207. options = options || {};
  4208. $$.removeHiddenTargetIds(targetIds);
  4209. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  4210. targets.transition().style('display', 'initial', 'important').style('opacity', 1, 'important').call($$.endall, function () {
  4211. targets.style('opacity', null).style('opacity', 1);
  4212. });
  4213. if (options.withLegend) {
  4214. $$.showLegend(targetIds);
  4215. }
  4216. $$.redraw({
  4217. withUpdateOrgXDomain: true,
  4218. withUpdateXDomain: true,
  4219. withLegend: true
  4220. });
  4221. };
  4222. Chart.prototype.hide = function (targetIds, options) {
  4223. var $$ = this.internal,
  4224. targets;
  4225. targetIds = $$.mapToTargetIds(targetIds);
  4226. options = options || {};
  4227. $$.addHiddenTargetIds(targetIds);
  4228. targets = $$.svg.selectAll($$.selectorTargets(targetIds));
  4229. targets.transition().style('opacity', 0, 'important').call($$.endall, function () {
  4230. targets.style('opacity', null).style('opacity', 0);
  4231. targets.style('display', 'none');
  4232. });
  4233. if (options.withLegend) {
  4234. $$.hideLegend(targetIds);
  4235. }
  4236. $$.redraw({
  4237. withUpdateOrgXDomain: true,
  4238. withUpdateXDomain: true,
  4239. withLegend: true
  4240. });
  4241. };
  4242. Chart.prototype.toggle = function (targetIds, options) {
  4243. var that = this,
  4244. $$ = this.internal;
  4245. $$.mapToTargetIds(targetIds).forEach(function (targetId) {
  4246. $$.isTargetToShow(targetId) ? that.hide(targetId, options) : that.show(targetId, options);
  4247. });
  4248. };
  4249. Chart.prototype.tooltip = function () {};
  4250. Chart.prototype.tooltip.show = function (args) {
  4251. var $$ = this.internal,
  4252. targets,
  4253. data,
  4254. mouse = {}; // determine mouse position on the chart
  4255. if (args.mouse) {
  4256. mouse = args.mouse;
  4257. } else {
  4258. // determine focus data
  4259. if (args.data) {
  4260. data = args.data;
  4261. } else if (typeof args.x !== 'undefined') {
  4262. if (args.id) {
  4263. targets = $$.data.targets.filter(function (t) {
  4264. return t.id === args.id;
  4265. });
  4266. } else {
  4267. targets = $$.data.targets;
  4268. }
  4269. data = $$.filterByX(targets, args.x).slice(0, 1)[0];
  4270. }
  4271. mouse = data ? $$.getMousePosition(data) : null;
  4272. } // emulate mouse events to show
  4273. $$.dispatchEvent('mousemove', mouse);
  4274. $$.config.tooltip_onshow.call($$, data);
  4275. };
  4276. Chart.prototype.tooltip.hide = function () {
  4277. // TODO: get target data by checking the state of focus
  4278. this.internal.dispatchEvent('mouseout', 0);
  4279. this.internal.config.tooltip_onhide.call(this);
  4280. };
  4281. Chart.prototype.transform = function (type, targetIds) {
  4282. var $$ = this.internal,
  4283. options = ['pie', 'donut'].indexOf(type) >= 0 ? {
  4284. withTransform: true
  4285. } : null;
  4286. $$.transformTo(targetIds, type, options);
  4287. };
  4288. ChartInternal.prototype.transformTo = function (targetIds, type, optionsForRedraw) {
  4289. var $$ = this,
  4290. withTransitionForAxis = !$$.hasArcType(),
  4291. options = optionsForRedraw || {
  4292. withTransitionForAxis: withTransitionForAxis
  4293. };
  4294. options.withTransitionForTransform = false;
  4295. $$.transiting = false;
  4296. $$.setTargetType(targetIds, type);
  4297. $$.updateTargets($$.data.targets); // this is needed when transforming to arc
  4298. $$.updateAndRedraw(options);
  4299. };
  4300. Chart.prototype.x = function (x) {
  4301. var $$ = this.internal;
  4302. if (arguments.length) {
  4303. $$.updateTargetX($$.data.targets, x);
  4304. $$.redraw({
  4305. withUpdateOrgXDomain: true,
  4306. withUpdateXDomain: true
  4307. });
  4308. }
  4309. return $$.data.xs;
  4310. };
  4311. Chart.prototype.xs = function (xs) {
  4312. var $$ = this.internal;
  4313. if (arguments.length) {
  4314. $$.updateTargetXs($$.data.targets, xs);
  4315. $$.redraw({
  4316. withUpdateOrgXDomain: true,
  4317. withUpdateXDomain: true
  4318. });
  4319. }
  4320. return $$.data.xs;
  4321. };
  4322. Chart.prototype.zoom = function (domain) {
  4323. var $$ = this.internal;
  4324. if (domain) {
  4325. if ($$.isTimeSeries()) {
  4326. domain = domain.map(function (x) {
  4327. return $$.parseDate(x);
  4328. });
  4329. }
  4330. if ($$.config.subchart_show) {
  4331. $$.brush.selectionAsValue(domain, true);
  4332. } else {
  4333. $$.updateXDomain(null, true, false, false, domain);
  4334. $$.redraw({
  4335. withY: $$.config.zoom_rescale,
  4336. withSubchart: false
  4337. });
  4338. }
  4339. $$.config.zoom_onzoom.call(this, $$.x.orgDomain());
  4340. return domain;
  4341. } else {
  4342. return $$.x.domain();
  4343. }
  4344. };
  4345. Chart.prototype.zoom.enable = function (enabled) {
  4346. var $$ = this.internal;
  4347. $$.config.zoom_enabled = enabled;
  4348. $$.updateAndRedraw();
  4349. };
  4350. Chart.prototype.unzoom = function () {
  4351. var $$ = this.internal;
  4352. if ($$.config.subchart_show) {
  4353. $$.brush.clear();
  4354. } else {
  4355. $$.updateXDomain(null, true, false, false, $$.subX.domain());
  4356. $$.redraw({
  4357. withY: $$.config.zoom_rescale,
  4358. withSubchart: false
  4359. });
  4360. }
  4361. };
  4362. Chart.prototype.zoom.max = function (max) {
  4363. var $$ = this.internal,
  4364. config = $$.config,
  4365. d3 = $$.d3;
  4366. if (max === 0 || max) {
  4367. config.zoom_x_max = d3.max([$$.orgXDomain[1], max]);
  4368. } else {
  4369. return config.zoom_x_max;
  4370. }
  4371. };
  4372. Chart.prototype.zoom.min = function (min) {
  4373. var $$ = this.internal,
  4374. config = $$.config,
  4375. d3 = $$.d3;
  4376. if (min === 0 || min) {
  4377. config.zoom_x_min = d3.min([$$.orgXDomain[0], min]);
  4378. } else {
  4379. return config.zoom_x_min;
  4380. }
  4381. };
  4382. Chart.prototype.zoom.range = function (range) {
  4383. if (arguments.length) {
  4384. if (isDefined(range.max)) {
  4385. this.domain.max(range.max);
  4386. }
  4387. if (isDefined(range.min)) {
  4388. this.domain.min(range.min);
  4389. }
  4390. } else {
  4391. return {
  4392. max: this.domain.max(),
  4393. min: this.domain.min()
  4394. };
  4395. }
  4396. };
  4397. ChartInternal.prototype.initPie = function () {
  4398. var $$ = this,
  4399. d3 = $$.d3;
  4400. $$.pie = d3.pie().padAngle(this.getPadAngle.bind(this)).value(function (d) {
  4401. return d.values.reduce(function (a, b) {
  4402. return a + b.value;
  4403. }, 0);
  4404. });
  4405. var orderFct = $$.getOrderFunction(); // we need to reverse the returned order if asc or desc to have the slice in expected order.
  4406. if (orderFct && ($$.isOrderAsc() || $$.isOrderDesc())) {
  4407. var defaultSort = orderFct;
  4408. orderFct = function orderFct(t1, t2) {
  4409. return defaultSort(t1, t2) * -1;
  4410. };
  4411. }
  4412. $$.pie.sort(orderFct || null);
  4413. };
  4414. ChartInternal.prototype.updateRadius = function () {
  4415. var $$ = this,
  4416. config = $$.config,
  4417. w = config.gauge_width || config.donut_width,
  4418. gaugeArcWidth = $$.filterTargetsToShow($$.data.targets).length * $$.config.gauge_arcs_minWidth;
  4419. $$.radiusExpanded = Math.min($$.arcWidth, $$.arcHeight) / 2 * ($$.hasType('gauge') ? 0.85 : 1);
  4420. $$.radius = $$.radiusExpanded * 0.95;
  4421. $$.innerRadiusRatio = w ? ($$.radius - w) / $$.radius : 0.6;
  4422. $$.innerRadius = $$.hasType('donut') || $$.hasType('gauge') ? $$.radius * $$.innerRadiusRatio : 0;
  4423. $$.gaugeArcWidth = w ? w : gaugeArcWidth <= $$.radius - $$.innerRadius ? $$.radius - $$.innerRadius : gaugeArcWidth <= $$.radius ? gaugeArcWidth : $$.radius;
  4424. };
  4425. ChartInternal.prototype.getPadAngle = function () {
  4426. if (this.hasType('pie')) {
  4427. return this.config.pie_padAngle || 0;
  4428. } else if (this.hasType('donut')) {
  4429. return this.config.donut_padAngle || 0;
  4430. } else {
  4431. return 0;
  4432. }
  4433. };
  4434. ChartInternal.prototype.updateArc = function () {
  4435. var $$ = this;
  4436. $$.svgArc = $$.getSvgArc();
  4437. $$.svgArcExpanded = $$.getSvgArcExpanded();
  4438. $$.svgArcExpandedSub = $$.getSvgArcExpanded(0.98);
  4439. };
  4440. ChartInternal.prototype.updateAngle = function (d) {
  4441. var $$ = this,
  4442. config = $$.config,
  4443. found = false,
  4444. index = 0,
  4445. gMin,
  4446. gMax,
  4447. gTic,
  4448. gValue;
  4449. if (!config) {
  4450. return null;
  4451. }
  4452. $$.pie($$.filterTargetsToShow($$.data.targets)).forEach(function (t) {
  4453. if (!found && t.data.id === d.data.id) {
  4454. found = true;
  4455. d = t;
  4456. d.index = index;
  4457. }
  4458. index++;
  4459. });
  4460. if (isNaN(d.startAngle)) {
  4461. d.startAngle = 0;
  4462. }
  4463. if (isNaN(d.endAngle)) {
  4464. d.endAngle = d.startAngle;
  4465. }
  4466. if ($$.isGaugeType(d.data)) {
  4467. gMin = config.gauge_min;
  4468. gMax = config.gauge_max;
  4469. gTic = Math.PI * (config.gauge_fullCircle ? 2 : 1) / (gMax - gMin);
  4470. gValue = d.value < gMin ? 0 : d.value < gMax ? d.value - gMin : gMax - gMin;
  4471. d.startAngle = config.gauge_startingAngle;
  4472. d.endAngle = d.startAngle + gTic * gValue;
  4473. }
  4474. return found ? d : null;
  4475. };
  4476. ChartInternal.prototype.getSvgArc = function () {
  4477. var $$ = this,
  4478. hasGaugeType = $$.hasType('gauge'),
  4479. singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,
  4480. arc = $$.d3.arc().outerRadius(function (d) {
  4481. return hasGaugeType ? $$.radius - singleArcWidth * d.index : $$.radius;
  4482. }).innerRadius(function (d) {
  4483. return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius;
  4484. }),
  4485. newArc = function newArc(d, withoutUpdate) {
  4486. var updated;
  4487. if (withoutUpdate) {
  4488. return arc(d);
  4489. } // for interpolate
  4490. updated = $$.updateAngle(d);
  4491. return updated ? arc(updated) : "M 0 0";
  4492. }; // TODO: extends all function
  4493. newArc.centroid = arc.centroid;
  4494. return newArc;
  4495. };
  4496. ChartInternal.prototype.getSvgArcExpanded = function (rate) {
  4497. rate = rate || 1;
  4498. var $$ = this,
  4499. hasGaugeType = $$.hasType('gauge'),
  4500. singleArcWidth = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length,
  4501. expandWidth = Math.min($$.radiusExpanded * rate - $$.radius, singleArcWidth * 0.8 - (1 - rate) * 100),
  4502. arc = $$.d3.arc().outerRadius(function (d) {
  4503. return hasGaugeType ? $$.radius - singleArcWidth * d.index + expandWidth : $$.radiusExpanded * rate;
  4504. }).innerRadius(function (d) {
  4505. return hasGaugeType ? $$.radius - singleArcWidth * (d.index + 1) : $$.innerRadius;
  4506. });
  4507. return function (d) {
  4508. var updated = $$.updateAngle(d);
  4509. return updated ? arc(updated) : "M 0 0";
  4510. };
  4511. };
  4512. ChartInternal.prototype.getArc = function (d, withoutUpdate, force) {
  4513. return force || this.isArcType(d.data) ? this.svgArc(d, withoutUpdate) : "M 0 0";
  4514. };
  4515. ChartInternal.prototype.transformForArcLabel = function (d) {
  4516. var $$ = this,
  4517. config = $$.config,
  4518. updated = $$.updateAngle(d),
  4519. c,
  4520. x,
  4521. y,
  4522. h,
  4523. ratio,
  4524. translate = "",
  4525. hasGauge = $$.hasType('gauge');
  4526. if (updated && !hasGauge) {
  4527. c = this.svgArc.centroid(updated);
  4528. x = isNaN(c[0]) ? 0 : c[0];
  4529. y = isNaN(c[1]) ? 0 : c[1];
  4530. h = Math.sqrt(x * x + y * y);
  4531. if ($$.hasType('donut') && config.donut_label_ratio) {
  4532. ratio = isFunction(config.donut_label_ratio) ? config.donut_label_ratio(d, $$.radius, h) : config.donut_label_ratio;
  4533. } else if ($$.hasType('pie') && config.pie_label_ratio) {
  4534. ratio = isFunction(config.pie_label_ratio) ? config.pie_label_ratio(d, $$.radius, h) : config.pie_label_ratio;
  4535. } else {
  4536. ratio = $$.radius && h ? (36 / $$.radius > 0.375 ? 1.175 - 36 / $$.radius : 0.8) * $$.radius / h : 0;
  4537. }
  4538. translate = "translate(" + x * ratio + ',' + y * ratio + ")";
  4539. } else if (updated && hasGauge && $$.filterTargetsToShow($$.data.targets).length > 1) {
  4540. var y1 = Math.sin(updated.endAngle - Math.PI / 2);
  4541. x = Math.cos(updated.endAngle - Math.PI / 2) * ($$.radiusExpanded + 25);
  4542. y = y1 * ($$.radiusExpanded + 15 - Math.abs(y1 * 10)) + 3;
  4543. translate = "translate(" + x + ',' + y + ")";
  4544. }
  4545. return translate;
  4546. };
  4547. /**
  4548. * @deprecated Use `getRatio('arc', d)` instead.
  4549. */
  4550. ChartInternal.prototype.getArcRatio = function (d) {
  4551. return this.getRatio('arc', d);
  4552. };
  4553. ChartInternal.prototype.convertToArcData = function (d) {
  4554. return this.addName({
  4555. id: d.data.id,
  4556. value: d.value,
  4557. ratio: this.getRatio('arc', d),
  4558. index: d.index
  4559. });
  4560. };
  4561. ChartInternal.prototype.textForArcLabel = function (d) {
  4562. var $$ = this,
  4563. updated,
  4564. value,
  4565. ratio,
  4566. id,
  4567. format;
  4568. if (!$$.shouldShowArcLabel()) {
  4569. return "";
  4570. }
  4571. updated = $$.updateAngle(d);
  4572. value = updated ? updated.value : null;
  4573. ratio = $$.getRatio('arc', updated);
  4574. id = d.data.id;
  4575. if (!$$.hasType('gauge') && !$$.meetsArcLabelThreshold(ratio)) {
  4576. return "";
  4577. }
  4578. format = $$.getArcLabelFormat();
  4579. return format ? format(value, ratio, id) : $$.defaultArcValueFormat(value, ratio);
  4580. };
  4581. ChartInternal.prototype.textForGaugeMinMax = function (value, isMax) {
  4582. var $$ = this,
  4583. format = $$.getGaugeLabelExtents();
  4584. return format ? format(value, isMax) : value;
  4585. };
  4586. ChartInternal.prototype.expandArc = function (targetIds) {
  4587. var $$ = this,
  4588. interval; // MEMO: avoid to cancel transition
  4589. if ($$.transiting) {
  4590. interval = window.setInterval(function () {
  4591. if (!$$.transiting) {
  4592. window.clearInterval(interval);
  4593. if ($$.legend.selectAll('.c3-legend-item-focused').size() > 0) {
  4594. $$.expandArc(targetIds);
  4595. }
  4596. }
  4597. }, 10);
  4598. return;
  4599. }
  4600. targetIds = $$.mapToTargetIds(targetIds);
  4601. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).each(function (d) {
  4602. if (!$$.shouldExpand(d.data.id)) {
  4603. return;
  4604. }
  4605. $$.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) {
  4606. if ($$.isDonutType(d.data)) ;
  4607. });
  4608. });
  4609. };
  4610. ChartInternal.prototype.unexpandArc = function (targetIds) {
  4611. var $$ = this;
  4612. if ($$.transiting) {
  4613. return;
  4614. }
  4615. targetIds = $$.mapToTargetIds(targetIds);
  4616. $$.svg.selectAll($$.selectorTargets(targetIds, '.' + CLASS.chartArc)).selectAll('path').transition().duration(function (d) {
  4617. return $$.expandDuration(d.data.id);
  4618. }).attr("d", $$.svgArc);
  4619. $$.svg.selectAll('.' + CLASS.arc);
  4620. };
  4621. ChartInternal.prototype.expandDuration = function (id) {
  4622. var $$ = this,
  4623. config = $$.config;
  4624. if ($$.isDonutType(id)) {
  4625. return config.donut_expand_duration;
  4626. } else if ($$.isGaugeType(id)) {
  4627. return config.gauge_expand_duration;
  4628. } else if ($$.isPieType(id)) {
  4629. return config.pie_expand_duration;
  4630. } else {
  4631. return 50;
  4632. }
  4633. };
  4634. ChartInternal.prototype.shouldExpand = function (id) {
  4635. var $$ = this,
  4636. config = $$.config;
  4637. return $$.isDonutType(id) && config.donut_expand || $$.isGaugeType(id) && config.gauge_expand || $$.isPieType(id) && config.pie_expand;
  4638. };
  4639. ChartInternal.prototype.shouldShowArcLabel = function () {
  4640. var $$ = this,
  4641. config = $$.config,
  4642. shouldShow = true;
  4643. if ($$.hasType('donut')) {
  4644. shouldShow = config.donut_label_show;
  4645. } else if ($$.hasType('pie')) {
  4646. shouldShow = config.pie_label_show;
  4647. } // when gauge, always true
  4648. return shouldShow;
  4649. };
  4650. ChartInternal.prototype.meetsArcLabelThreshold = function (ratio) {
  4651. var $$ = this,
  4652. config = $$.config,
  4653. threshold = $$.hasType('donut') ? config.donut_label_threshold : config.pie_label_threshold;
  4654. return ratio >= threshold;
  4655. };
  4656. ChartInternal.prototype.getArcLabelFormat = function () {
  4657. var $$ = this,
  4658. config = $$.config,
  4659. format = config.pie_label_format;
  4660. if ($$.hasType('gauge')) {
  4661. format = config.gauge_label_format;
  4662. } else if ($$.hasType('donut')) {
  4663. format = config.donut_label_format;
  4664. }
  4665. return format;
  4666. };
  4667. ChartInternal.prototype.getGaugeLabelExtents = function () {
  4668. var $$ = this,
  4669. config = $$.config;
  4670. return config.gauge_label_extents;
  4671. };
  4672. ChartInternal.prototype.getArcTitle = function () {
  4673. var $$ = this;
  4674. return $$.hasType('donut') ? $$.config.donut_title : "";
  4675. };
  4676. ChartInternal.prototype.updateTargetsForArc = function (targets) {
  4677. var $$ = this,
  4678. main = $$.main,
  4679. mainPies,
  4680. mainPieEnter,
  4681. classChartArc = $$.classChartArc.bind($$),
  4682. classArcs = $$.classArcs.bind($$),
  4683. classFocus = $$.classFocus.bind($$);
  4684. mainPies = main.select('.' + CLASS.chartArcs).selectAll('.' + CLASS.chartArc).data($$.pie(targets)).attr("class", function (d) {
  4685. return classChartArc(d) + classFocus(d.data);
  4686. });
  4687. mainPieEnter = mainPies.enter().append("g").attr("class", classChartArc);
  4688. mainPieEnter.append('g').attr('class', classArcs);
  4689. mainPieEnter.append("text").attr("dy", $$.hasType('gauge') ? "-.1em" : ".35em").style("opacity", 0).style("text-anchor", "middle").style("pointer-events", "none"); // MEMO: can not keep same color..., but not bad to update color in redraw
  4690. //mainPieUpdate.exit().remove();
  4691. };
  4692. ChartInternal.prototype.initArc = function () {
  4693. var $$ = this;
  4694. $$.arcs = $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartArcs).attr("transform", $$.getTranslate('arc'));
  4695. $$.arcs.append('text').attr('class', CLASS.chartArcsTitle).style("text-anchor", "middle").text($$.getArcTitle());
  4696. };
  4697. ChartInternal.prototype.redrawArc = function (duration, durationForExit, withTransform) {
  4698. var $$ = this,
  4699. d3 = $$.d3,
  4700. config = $$.config,
  4701. main = $$.main,
  4702. arcs,
  4703. mainArc,
  4704. arcLabelLines,
  4705. mainArcLabelLine,
  4706. hasGaugeType = $$.hasType('gauge');
  4707. arcs = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arc).data($$.arcData.bind($$));
  4708. mainArc = arcs.enter().append('path').attr("class", $$.classArc.bind($$)).style("fill", function (d) {
  4709. return $$.color(d.data);
  4710. }).style("cursor", function (d) {
  4711. return config.interaction_enabled && config.data_selection_isselectable(d) ? "pointer" : null;
  4712. }).each(function (d) {
  4713. if ($$.isGaugeType(d.data)) {
  4714. d.startAngle = d.endAngle = config.gauge_startingAngle;
  4715. }
  4716. this._current = d;
  4717. }).merge(arcs);
  4718. if (hasGaugeType) {
  4719. arcLabelLines = main.selectAll('.' + CLASS.arcs).selectAll('.' + CLASS.arcLabelLine).data($$.arcData.bind($$));
  4720. mainArcLabelLine = arcLabelLines.enter().append('rect').attr("class", function (d) {
  4721. return CLASS.arcLabelLine + ' ' + CLASS.target + ' ' + CLASS.target + '-' + d.data.id;
  4722. }).merge(arcLabelLines);
  4723. if ($$.filterTargetsToShow($$.data.targets).length === 1) {
  4724. mainArcLabelLine.style("display", "none");
  4725. } else {
  4726. mainArcLabelLine.style("fill", function (d) {
  4727. return $$.levelColor ? $$.levelColor(d.data.values[0].value) : $$.color(d.data);
  4728. }).style("display", config.gauge_labelLine_show ? "" : "none").each(function (d) {
  4729. var lineLength = 0,
  4730. lineThickness = 2,
  4731. x = 0,
  4732. y = 0,
  4733. transform = "";
  4734. if ($$.hiddenTargetIds.indexOf(d.data.id) < 0) {
  4735. var updated = $$.updateAngle(d),
  4736. innerLineLength = $$.gaugeArcWidth / $$.filterTargetsToShow($$.data.targets).length * (updated.index + 1),
  4737. lineAngle = updated.endAngle - Math.PI / 2,
  4738. arcInnerRadius = $$.radius - innerLineLength,
  4739. linePositioningAngle = lineAngle - (arcInnerRadius === 0 ? 0 : 1 / arcInnerRadius);
  4740. lineLength = $$.radiusExpanded - $$.radius + innerLineLength;
  4741. x = Math.cos(linePositioningAngle) * arcInnerRadius;
  4742. y = Math.sin(linePositioningAngle) * arcInnerRadius;
  4743. transform = "rotate(" + lineAngle * 180 / Math.PI + ", " + x + ", " + y + ")";
  4744. }
  4745. d3.select(this).attr('x', x).attr('y', y).attr('width', lineLength).attr('height', lineThickness).attr('transform', transform).style("stroke-dasharray", "0, " + (lineLength + lineThickness) + ", 0");
  4746. });
  4747. }
  4748. }
  4749. mainArc.attr("transform", function (d) {
  4750. return !$$.isGaugeType(d.data) && withTransform ? "scale(0)" : "";
  4751. }).on('mouseover', config.interaction_enabled ? function (d) {
  4752. var updated, arcData;
  4753. if ($$.transiting) {
  4754. // skip while transiting
  4755. return;
  4756. }
  4757. updated = $$.updateAngle(d);
  4758. if (updated) {
  4759. arcData = $$.convertToArcData(updated); // transitions
  4760. $$.expandArc(updated.data.id);
  4761. $$.api.focus(updated.data.id);
  4762. $$.toggleFocusLegend(updated.data.id, true);
  4763. $$.config.data_onmouseover(arcData, this);
  4764. }
  4765. } : null).on('mousemove', config.interaction_enabled ? function (d) {
  4766. var updated = $$.updateAngle(d),
  4767. arcData,
  4768. selectedData;
  4769. if (updated) {
  4770. arcData = $$.convertToArcData(updated), selectedData = [arcData];
  4771. $$.showTooltip(selectedData, this);
  4772. }
  4773. } : null).on('mouseout', config.interaction_enabled ? function (d) {
  4774. var updated, arcData;
  4775. if ($$.transiting) {
  4776. // skip while transiting
  4777. return;
  4778. }
  4779. updated = $$.updateAngle(d);
  4780. if (updated) {
  4781. arcData = $$.convertToArcData(updated); // transitions
  4782. $$.unexpandArc(updated.data.id);
  4783. $$.api.revert();
  4784. $$.revertLegend();
  4785. $$.hideTooltip();
  4786. $$.config.data_onmouseout(arcData, this);
  4787. }
  4788. } : null).on('click', config.interaction_enabled ? function (d, i) {
  4789. var updated = $$.updateAngle(d),
  4790. arcData;
  4791. if (updated) {
  4792. arcData = $$.convertToArcData(updated);
  4793. if ($$.toggleShape) {
  4794. $$.toggleShape(this, arcData, i);
  4795. }
  4796. $$.config.data_onclick.call($$.api, arcData, this);
  4797. }
  4798. } : null).each(function () {
  4799. $$.transiting = true;
  4800. }).transition().duration(duration).attrTween("d", function (d) {
  4801. var updated = $$.updateAngle(d),
  4802. interpolate;
  4803. if (!updated) {
  4804. return function () {
  4805. return "M 0 0";
  4806. };
  4807. } // if (this._current === d) {
  4808. // this._current = {
  4809. // startAngle: Math.PI*2,
  4810. // endAngle: Math.PI*2,
  4811. // };
  4812. // }
  4813. if (isNaN(this._current.startAngle)) {
  4814. this._current.startAngle = 0;
  4815. }
  4816. if (isNaN(this._current.endAngle)) {
  4817. this._current.endAngle = this._current.startAngle;
  4818. }
  4819. interpolate = d3.interpolate(this._current, updated);
  4820. this._current = interpolate(0);
  4821. return function (t) {
  4822. // prevents crashing the charts once in transition and chart.destroy() has been called
  4823. if ($$.config === null) {
  4824. return "M 0 0";
  4825. }
  4826. var interpolated = interpolate(t);
  4827. interpolated.data = d.data; // data.id will be updated by interporator
  4828. return $$.getArc(interpolated, true);
  4829. };
  4830. }).attr("transform", withTransform ? "scale(1)" : "").style("fill", function (d) {
  4831. return $$.levelColor ? $$.levelColor(d.data.values[0].value) : $$.color(d.data.id);
  4832. }) // Where gauge reading color would receive customization.
  4833. .call($$.endall, function () {
  4834. $$.transiting = false;
  4835. });
  4836. arcs.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  4837. main.selectAll('.' + CLASS.chartArc).select('text').style("opacity", 0).attr('class', function (d) {
  4838. return $$.isGaugeType(d.data) ? CLASS.gaugeValue : '';
  4839. }).text($$.textForArcLabel.bind($$)).attr("transform", $$.transformForArcLabel.bind($$)).style('font-size', function (d) {
  4840. return $$.isGaugeType(d.data) && $$.filterTargetsToShow($$.data.targets).length === 1 ? Math.round($$.radius / 5) + 'px' : '';
  4841. }).transition().duration(duration).style("opacity", function (d) {
  4842. return $$.isTargetToShow(d.data.id) && $$.isArcType(d.data) ? 1 : 0;
  4843. });
  4844. main.select('.' + CLASS.chartArcsTitle).style("opacity", $$.hasType('donut') || hasGaugeType ? 1 : 0);
  4845. if (hasGaugeType) {
  4846. var index = 0;
  4847. var backgroundArc = $$.arcs.select('g.' + CLASS.chartArcsBackground).selectAll('path.' + CLASS.chartArcsBackground).data($$.data.targets);
  4848. backgroundArc.enter().append("path").attr("class", function (d, i) {
  4849. return CLASS.chartArcsBackground + ' ' + CLASS.chartArcsBackground + '-' + i;
  4850. }).merge(backgroundArc).attr("d", function (d1) {
  4851. if ($$.hiddenTargetIds.indexOf(d1.id) >= 0) {
  4852. return "M 0 0";
  4853. }
  4854. var d = {
  4855. data: [{
  4856. value: config.gauge_max
  4857. }],
  4858. startAngle: config.gauge_startingAngle,
  4859. endAngle: -1 * config.gauge_startingAngle * (config.gauge_fullCircle ? Math.PI : 1),
  4860. index: index++
  4861. };
  4862. return $$.getArc(d, true, true);
  4863. });
  4864. backgroundArc.exit().remove();
  4865. $$.arcs.select('.' + CLASS.chartArcsGaugeUnit).attr("dy", ".75em").text(config.gauge_label_show ? config.gauge_units : '');
  4866. $$.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) : '');
  4867. $$.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) : '');
  4868. }
  4869. };
  4870. ChartInternal.prototype.initGauge = function () {
  4871. var arcs = this.arcs;
  4872. if (this.hasType('gauge')) {
  4873. arcs.append('g').attr("class", CLASS.chartArcsBackground);
  4874. arcs.append("text").attr("class", CLASS.chartArcsGaugeUnit).style("text-anchor", "middle").style("pointer-events", "none");
  4875. arcs.append("text").attr("class", CLASS.chartArcsGaugeMin).style("text-anchor", "middle").style("pointer-events", "none");
  4876. arcs.append("text").attr("class", CLASS.chartArcsGaugeMax).style("text-anchor", "middle").style("pointer-events", "none");
  4877. }
  4878. };
  4879. ChartInternal.prototype.getGaugeLabelHeight = function () {
  4880. return this.config.gauge_label_show ? 20 : 0;
  4881. };
  4882. /**
  4883. * Store value into cache
  4884. *
  4885. * @param key
  4886. * @param value
  4887. */
  4888. ChartInternal.prototype.addToCache = function (key, value) {
  4889. this.cache["$".concat(key)] = value;
  4890. };
  4891. /**
  4892. * Returns a cached value or undefined
  4893. *
  4894. * @param key
  4895. * @return {*}
  4896. */
  4897. ChartInternal.prototype.getFromCache = function (key) {
  4898. return this.cache["$".concat(key)];
  4899. };
  4900. /**
  4901. * Reset cached data
  4902. */
  4903. ChartInternal.prototype.resetCache = function () {
  4904. var _this = this;
  4905. Object.keys(this.cache).filter(function (key) {
  4906. return /^\$/.test(key);
  4907. }).forEach(function (key) {
  4908. delete _this.cache[key];
  4909. });
  4910. }; // Old API that stores Targets
  4911. ChartInternal.prototype.hasCaches = function (ids) {
  4912. for (var i = 0; i < ids.length; i++) {
  4913. if (!(ids[i] in this.cache)) {
  4914. return false;
  4915. }
  4916. }
  4917. return true;
  4918. };
  4919. ChartInternal.prototype.addCache = function (id, target) {
  4920. this.cache[id] = this.cloneTarget(target);
  4921. };
  4922. ChartInternal.prototype.getCaches = function (ids) {
  4923. var targets = [],
  4924. i;
  4925. for (i = 0; i < ids.length; i++) {
  4926. if (ids[i] in this.cache) {
  4927. targets.push(this.cloneTarget(this.cache[ids[i]]));
  4928. }
  4929. }
  4930. return targets;
  4931. };
  4932. ChartInternal.prototype.categoryName = function (i) {
  4933. var config = this.config;
  4934. return i < config.axis_x_categories.length ? config.axis_x_categories[i] : i;
  4935. };
  4936. ChartInternal.prototype.generateTargetClass = function (targetId) {
  4937. return targetId || targetId === 0 ? ('-' + targetId).replace(/\s/g, '-') : '';
  4938. };
  4939. ChartInternal.prototype.generateClass = function (prefix, targetId) {
  4940. return " " + prefix + " " + prefix + this.generateTargetClass(targetId);
  4941. };
  4942. ChartInternal.prototype.classText = function (d) {
  4943. return this.generateClass(CLASS.text, d.index);
  4944. };
  4945. ChartInternal.prototype.classTexts = function (d) {
  4946. return this.generateClass(CLASS.texts, d.id);
  4947. };
  4948. ChartInternal.prototype.classShape = function (d) {
  4949. return this.generateClass(CLASS.shape, d.index);
  4950. };
  4951. ChartInternal.prototype.classShapes = function (d) {
  4952. return this.generateClass(CLASS.shapes, d.id);
  4953. };
  4954. ChartInternal.prototype.classLine = function (d) {
  4955. return this.classShape(d) + this.generateClass(CLASS.line, d.id);
  4956. };
  4957. ChartInternal.prototype.classLines = function (d) {
  4958. return this.classShapes(d) + this.generateClass(CLASS.lines, d.id);
  4959. };
  4960. ChartInternal.prototype.classCircle = function (d) {
  4961. return this.classShape(d) + this.generateClass(CLASS.circle, d.index);
  4962. };
  4963. ChartInternal.prototype.classCircles = function (d) {
  4964. return this.classShapes(d) + this.generateClass(CLASS.circles, d.id);
  4965. };
  4966. ChartInternal.prototype.classBar = function (d) {
  4967. return this.classShape(d) + this.generateClass(CLASS.bar, d.index);
  4968. };
  4969. ChartInternal.prototype.classBars = function (d) {
  4970. return this.classShapes(d) + this.generateClass(CLASS.bars, d.id);
  4971. };
  4972. ChartInternal.prototype.classArc = function (d) {
  4973. return this.classShape(d.data) + this.generateClass(CLASS.arc, d.data.id);
  4974. };
  4975. ChartInternal.prototype.classArcs = function (d) {
  4976. return this.classShapes(d.data) + this.generateClass(CLASS.arcs, d.data.id);
  4977. };
  4978. ChartInternal.prototype.classArea = function (d) {
  4979. return this.classShape(d) + this.generateClass(CLASS.area, d.id);
  4980. };
  4981. ChartInternal.prototype.classAreas = function (d) {
  4982. return this.classShapes(d) + this.generateClass(CLASS.areas, d.id);
  4983. };
  4984. ChartInternal.prototype.classRegion = function (d, i) {
  4985. return this.generateClass(CLASS.region, i) + ' ' + ('class' in d ? d['class'] : '');
  4986. };
  4987. ChartInternal.prototype.classEvent = function (d) {
  4988. return this.generateClass(CLASS.eventRect, d.index);
  4989. };
  4990. ChartInternal.prototype.classTarget = function (id) {
  4991. var $$ = this;
  4992. var additionalClassSuffix = $$.config.data_classes[id],
  4993. additionalClass = '';
  4994. if (additionalClassSuffix) {
  4995. additionalClass = ' ' + CLASS.target + '-' + additionalClassSuffix;
  4996. }
  4997. return $$.generateClass(CLASS.target, id) + additionalClass;
  4998. };
  4999. ChartInternal.prototype.classFocus = function (d) {
  5000. return this.classFocused(d) + this.classDefocused(d);
  5001. };
  5002. ChartInternal.prototype.classFocused = function (d) {
  5003. return ' ' + (this.focusedTargetIds.indexOf(d.id) >= 0 ? CLASS.focused : '');
  5004. };
  5005. ChartInternal.prototype.classDefocused = function (d) {
  5006. return ' ' + (this.defocusedTargetIds.indexOf(d.id) >= 0 ? CLASS.defocused : '');
  5007. };
  5008. ChartInternal.prototype.classChartText = function (d) {
  5009. return CLASS.chartText + this.classTarget(d.id);
  5010. };
  5011. ChartInternal.prototype.classChartLine = function (d) {
  5012. return CLASS.chartLine + this.classTarget(d.id);
  5013. };
  5014. ChartInternal.prototype.classChartBar = function (d) {
  5015. return CLASS.chartBar + this.classTarget(d.id);
  5016. };
  5017. ChartInternal.prototype.classChartArc = function (d) {
  5018. return CLASS.chartArc + this.classTarget(d.data.id);
  5019. };
  5020. ChartInternal.prototype.getTargetSelectorSuffix = function (targetId) {
  5021. var targetClass = this.generateTargetClass(targetId);
  5022. if (window.CSS && window.CSS.escape) {
  5023. return window.CSS.escape(targetClass);
  5024. } // fallback on imperfect method for old browsers (does not handles unicode)
  5025. return targetClass.replace(/([?!@#$%^&*()=+,.<>'":;\[\]\/|~`{}\\])/g, '\\$1');
  5026. };
  5027. ChartInternal.prototype.selectorTarget = function (id, prefix) {
  5028. return (prefix || '') + '.' + CLASS.target + this.getTargetSelectorSuffix(id);
  5029. };
  5030. ChartInternal.prototype.selectorTargets = function (ids, prefix) {
  5031. var $$ = this;
  5032. ids = ids || [];
  5033. return ids.length ? ids.map(function (id) {
  5034. return $$.selectorTarget(id, prefix);
  5035. }) : null;
  5036. };
  5037. ChartInternal.prototype.selectorLegend = function (id) {
  5038. return '.' + CLASS.legendItem + this.getTargetSelectorSuffix(id);
  5039. };
  5040. ChartInternal.prototype.selectorLegends = function (ids) {
  5041. var $$ = this;
  5042. return ids && ids.length ? ids.map(function (id) {
  5043. return $$.selectorLegend(id);
  5044. }) : null;
  5045. };
  5046. ChartInternal.prototype.getClipPath = function (id) {
  5047. var isIE9 = window.navigator.appVersion.toLowerCase().indexOf("msie 9.") >= 0;
  5048. return "url(" + (isIE9 ? "" : document.URL.split('#')[0]) + "#" + id + ")";
  5049. };
  5050. ChartInternal.prototype.appendClip = function (parent, id) {
  5051. return parent.append("clipPath").attr("id", id).append("rect");
  5052. };
  5053. ChartInternal.prototype.getAxisClipX = function (forHorizontal) {
  5054. // axis line width + padding for left
  5055. var left = Math.max(30, this.margin.left);
  5056. return forHorizontal ? -(1 + left) : -(left - 1);
  5057. };
  5058. ChartInternal.prototype.getAxisClipY = function (forHorizontal) {
  5059. return forHorizontal ? -20 : -this.margin.top;
  5060. };
  5061. ChartInternal.prototype.getXAxisClipX = function () {
  5062. var $$ = this;
  5063. return $$.getAxisClipX(!$$.config.axis_rotated);
  5064. };
  5065. ChartInternal.prototype.getXAxisClipY = function () {
  5066. var $$ = this;
  5067. return $$.getAxisClipY(!$$.config.axis_rotated);
  5068. };
  5069. ChartInternal.prototype.getYAxisClipX = function () {
  5070. var $$ = this;
  5071. return $$.config.axis_y_inner ? -1 : $$.getAxisClipX($$.config.axis_rotated);
  5072. };
  5073. ChartInternal.prototype.getYAxisClipY = function () {
  5074. var $$ = this;
  5075. return $$.getAxisClipY($$.config.axis_rotated);
  5076. };
  5077. ChartInternal.prototype.getAxisClipWidth = function (forHorizontal) {
  5078. var $$ = this,
  5079. left = Math.max(30, $$.margin.left),
  5080. right = Math.max(30, $$.margin.right); // width + axis line width + padding for left/right
  5081. return forHorizontal ? $$.width + 2 + left + right : $$.margin.left + 20;
  5082. };
  5083. ChartInternal.prototype.getAxisClipHeight = function (forHorizontal) {
  5084. // less than 20 is not enough to show the axis label 'outer' without legend
  5085. return (forHorizontal ? this.margin.bottom : this.margin.top + this.height) + 20;
  5086. };
  5087. ChartInternal.prototype.getXAxisClipWidth = function () {
  5088. var $$ = this;
  5089. return $$.getAxisClipWidth(!$$.config.axis_rotated);
  5090. };
  5091. ChartInternal.prototype.getXAxisClipHeight = function () {
  5092. var $$ = this;
  5093. return $$.getAxisClipHeight(!$$.config.axis_rotated);
  5094. };
  5095. ChartInternal.prototype.getYAxisClipWidth = function () {
  5096. var $$ = this;
  5097. return $$.getAxisClipWidth($$.config.axis_rotated) + ($$.config.axis_y_inner ? 20 : 0);
  5098. };
  5099. ChartInternal.prototype.getYAxisClipHeight = function () {
  5100. var $$ = this;
  5101. return $$.getAxisClipHeight($$.config.axis_rotated);
  5102. };
  5103. ChartInternal.prototype.generateColor = function () {
  5104. var $$ = this,
  5105. config = $$.config,
  5106. d3 = $$.d3,
  5107. colors = config.data_colors,
  5108. pattern = notEmpty(config.color_pattern) ? config.color_pattern : d3.schemeCategory10,
  5109. callback = config.data_color,
  5110. ids = [];
  5111. return function (d) {
  5112. var id = d.id || d.data && d.data.id || d,
  5113. color; // if callback function is provided
  5114. if (colors[id] instanceof Function) {
  5115. color = colors[id](d);
  5116. } // if specified, choose that color
  5117. else if (colors[id]) {
  5118. color = colors[id];
  5119. } // if not specified, choose from pattern
  5120. else {
  5121. if (ids.indexOf(id) < 0) {
  5122. ids.push(id);
  5123. }
  5124. color = pattern[ids.indexOf(id) % pattern.length];
  5125. colors[id] = color;
  5126. }
  5127. return callback instanceof Function ? callback(color, d) : color;
  5128. };
  5129. };
  5130. ChartInternal.prototype.generateLevelColor = function () {
  5131. var $$ = this,
  5132. config = $$.config,
  5133. colors = config.color_pattern,
  5134. threshold = config.color_threshold,
  5135. asValue = threshold.unit === 'value',
  5136. values = threshold.values && threshold.values.length ? threshold.values : [],
  5137. max = threshold.max || 100;
  5138. return notEmpty(threshold) && notEmpty(colors) ? function (value) {
  5139. var i,
  5140. v,
  5141. color = colors[colors.length - 1];
  5142. for (i = 0; i < values.length; i++) {
  5143. v = asValue ? value : value * 100 / max;
  5144. if (v < values[i]) {
  5145. color = colors[i];
  5146. break;
  5147. }
  5148. }
  5149. return color;
  5150. } : null;
  5151. };
  5152. ChartInternal.prototype.getDefaultConfig = function () {
  5153. var config = {
  5154. bindto: '#chart',
  5155. svg_classname: undefined,
  5156. size_width: undefined,
  5157. size_height: undefined,
  5158. padding_left: undefined,
  5159. padding_right: undefined,
  5160. padding_top: undefined,
  5161. padding_bottom: undefined,
  5162. resize_auto: true,
  5163. zoom_enabled: false,
  5164. zoom_initialRange: undefined,
  5165. zoom_type: 'scroll',
  5166. zoom_disableDefaultBehavior: false,
  5167. zoom_privileged: false,
  5168. zoom_rescale: false,
  5169. zoom_onzoom: function zoom_onzoom() {},
  5170. zoom_onzoomstart: function zoom_onzoomstart() {},
  5171. zoom_onzoomend: function zoom_onzoomend() {},
  5172. zoom_x_min: undefined,
  5173. zoom_x_max: undefined,
  5174. interaction_brighten: true,
  5175. interaction_enabled: true,
  5176. onmouseover: function onmouseover() {},
  5177. onmouseout: function onmouseout() {},
  5178. onresize: function onresize() {},
  5179. onresized: function onresized() {},
  5180. oninit: function oninit() {},
  5181. onrendered: function onrendered() {},
  5182. transition_duration: 350,
  5183. data_epochs: 'epochs',
  5184. data_x: undefined,
  5185. data_xs: {},
  5186. data_xFormat: '%Y-%m-%d',
  5187. data_xLocaltime: true,
  5188. data_xSort: true,
  5189. data_idConverter: function data_idConverter(id) {
  5190. return id;
  5191. },
  5192. data_names: {},
  5193. data_classes: {},
  5194. data_groups: [],
  5195. data_axes: {},
  5196. data_type: undefined,
  5197. data_types: {},
  5198. data_labels: {},
  5199. data_order: 'desc',
  5200. data_regions: {},
  5201. data_color: undefined,
  5202. data_colors: {},
  5203. data_hide: false,
  5204. data_filter: undefined,
  5205. data_selection_enabled: false,
  5206. data_selection_grouped: false,
  5207. data_selection_isselectable: function data_selection_isselectable() {
  5208. return true;
  5209. },
  5210. data_selection_multiple: true,
  5211. data_selection_draggable: false,
  5212. data_stack_normalize: false,
  5213. data_onclick: function data_onclick() {},
  5214. data_onmouseover: function data_onmouseover() {},
  5215. data_onmouseout: function data_onmouseout() {},
  5216. data_onselected: function data_onselected() {},
  5217. data_onunselected: function data_onunselected() {},
  5218. data_url: undefined,
  5219. data_headers: undefined,
  5220. data_json: undefined,
  5221. data_rows: undefined,
  5222. data_columns: undefined,
  5223. data_mimeType: undefined,
  5224. data_keys: undefined,
  5225. // configuration for no plot-able data supplied.
  5226. data_empty_label_text: "",
  5227. // subchart
  5228. subchart_show: false,
  5229. subchart_size_height: 60,
  5230. subchart_axis_x_show: true,
  5231. subchart_onbrush: function subchart_onbrush() {},
  5232. // color
  5233. color_pattern: [],
  5234. color_threshold: {},
  5235. // legend
  5236. legend_show: true,
  5237. legend_hide: false,
  5238. legend_position: 'bottom',
  5239. legend_inset_anchor: 'top-left',
  5240. legend_inset_x: 10,
  5241. legend_inset_y: 0,
  5242. legend_inset_step: undefined,
  5243. legend_item_onclick: undefined,
  5244. legend_item_onmouseover: undefined,
  5245. legend_item_onmouseout: undefined,
  5246. legend_equally: false,
  5247. legend_padding: 0,
  5248. legend_item_tile_width: 10,
  5249. legend_item_tile_height: 10,
  5250. // axis
  5251. axis_rotated: false,
  5252. axis_x_show: true,
  5253. axis_x_type: 'indexed',
  5254. axis_x_localtime: true,
  5255. axis_x_categories: [],
  5256. axis_x_tick_centered: false,
  5257. axis_x_tick_format: undefined,
  5258. axis_x_tick_culling: {},
  5259. axis_x_tick_culling_max: 10,
  5260. axis_x_tick_count: undefined,
  5261. axis_x_tick_fit: true,
  5262. axis_x_tick_values: null,
  5263. axis_x_tick_rotate: 0,
  5264. axis_x_tick_outer: true,
  5265. axis_x_tick_multiline: true,
  5266. axis_x_tick_multilineMax: 0,
  5267. axis_x_tick_width: null,
  5268. axis_x_max: undefined,
  5269. axis_x_min: undefined,
  5270. axis_x_padding: {},
  5271. axis_x_height: undefined,
  5272. axis_x_selection: undefined,
  5273. axis_x_label: {},
  5274. axis_x_inner: undefined,
  5275. axis_y_show: true,
  5276. axis_y_type: undefined,
  5277. axis_y_max: undefined,
  5278. axis_y_min: undefined,
  5279. axis_y_inverted: false,
  5280. axis_y_center: undefined,
  5281. axis_y_inner: undefined,
  5282. axis_y_label: {},
  5283. axis_y_tick_format: undefined,
  5284. axis_y_tick_outer: true,
  5285. axis_y_tick_values: null,
  5286. axis_y_tick_rotate: 0,
  5287. axis_y_tick_count: undefined,
  5288. axis_y_tick_time_type: undefined,
  5289. axis_y_tick_time_interval: undefined,
  5290. axis_y_padding: {},
  5291. axis_y_default: undefined,
  5292. axis_y2_show: false,
  5293. axis_y2_max: undefined,
  5294. axis_y2_min: undefined,
  5295. axis_y2_inverted: false,
  5296. axis_y2_center: undefined,
  5297. axis_y2_inner: undefined,
  5298. axis_y2_label: {},
  5299. axis_y2_tick_format: undefined,
  5300. axis_y2_tick_outer: true,
  5301. axis_y2_tick_values: null,
  5302. axis_y2_tick_count: undefined,
  5303. axis_y2_padding: {},
  5304. axis_y2_default: undefined,
  5305. // grid
  5306. grid_x_show: false,
  5307. grid_x_type: 'tick',
  5308. grid_x_lines: [],
  5309. grid_y_show: false,
  5310. // not used
  5311. // grid_y_type: 'tick',
  5312. grid_y_lines: [],
  5313. grid_y_ticks: 10,
  5314. grid_focus_show: true,
  5315. grid_lines_front: true,
  5316. // point - point of each data
  5317. point_show: true,
  5318. point_r: 2.5,
  5319. point_sensitivity: 10,
  5320. point_focus_expand_enabled: true,
  5321. point_focus_expand_r: undefined,
  5322. point_select_r: undefined,
  5323. // line
  5324. line_connectNull: false,
  5325. line_step_type: 'step',
  5326. // bar
  5327. bar_width: undefined,
  5328. bar_width_ratio: 0.6,
  5329. bar_width_max: undefined,
  5330. bar_zerobased: true,
  5331. bar_space: 0,
  5332. // area
  5333. area_zerobased: true,
  5334. area_above: false,
  5335. // pie
  5336. pie_label_show: true,
  5337. pie_label_format: undefined,
  5338. pie_label_threshold: 0.05,
  5339. pie_label_ratio: undefined,
  5340. pie_expand: {},
  5341. pie_expand_duration: 50,
  5342. pie_padAngle: 0,
  5343. // gauge
  5344. gauge_fullCircle: false,
  5345. gauge_label_show: true,
  5346. gauge_labelLine_show: true,
  5347. gauge_label_format: undefined,
  5348. gauge_min: 0,
  5349. gauge_max: 100,
  5350. gauge_startingAngle: -1 * Math.PI / 2,
  5351. gauge_label_extents: undefined,
  5352. gauge_units: undefined,
  5353. gauge_width: undefined,
  5354. gauge_arcs_minWidth: 5,
  5355. gauge_expand: {},
  5356. gauge_expand_duration: 50,
  5357. // donut
  5358. donut_label_show: true,
  5359. donut_label_format: undefined,
  5360. donut_label_threshold: 0.05,
  5361. donut_label_ratio: undefined,
  5362. donut_width: undefined,
  5363. donut_title: "",
  5364. donut_expand: {},
  5365. donut_expand_duration: 50,
  5366. donut_padAngle: 0,
  5367. // spline
  5368. spline_interpolation_type: 'cardinal',
  5369. // stanford
  5370. stanford_lines: [],
  5371. stanford_regions: [],
  5372. stanford_texts: [],
  5373. stanford_scaleMin: undefined,
  5374. stanford_scaleMax: undefined,
  5375. stanford_scaleWidth: undefined,
  5376. stanford_scaleFormat: undefined,
  5377. stanford_scaleValues: undefined,
  5378. stanford_colors: undefined,
  5379. stanford_padding: {
  5380. top: 0,
  5381. right: 0,
  5382. bottom: 0,
  5383. left: 0
  5384. },
  5385. // region - region to change style
  5386. regions: [],
  5387. // tooltip - show when mouseover on each data
  5388. tooltip_show: true,
  5389. tooltip_grouped: true,
  5390. tooltip_order: undefined,
  5391. tooltip_format_title: undefined,
  5392. tooltip_format_name: undefined,
  5393. tooltip_format_value: undefined,
  5394. tooltip_horizontal: undefined,
  5395. tooltip_position: undefined,
  5396. tooltip_contents: function tooltip_contents(d, defaultTitleFormat, defaultValueFormat, color) {
  5397. return this.getTooltipContent ? this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color) : '';
  5398. },
  5399. tooltip_init_show: false,
  5400. tooltip_init_x: 0,
  5401. tooltip_init_position: {
  5402. top: '0px',
  5403. left: '50px'
  5404. },
  5405. tooltip_onshow: function tooltip_onshow() {},
  5406. tooltip_onhide: function tooltip_onhide() {},
  5407. // title
  5408. title_text: undefined,
  5409. title_padding: {
  5410. top: 0,
  5411. right: 0,
  5412. bottom: 0,
  5413. left: 0
  5414. },
  5415. title_position: 'top-center'
  5416. };
  5417. Object.keys(this.additionalConfig).forEach(function (key) {
  5418. config[key] = this.additionalConfig[key];
  5419. }, this);
  5420. return config;
  5421. };
  5422. ChartInternal.prototype.additionalConfig = {};
  5423. ChartInternal.prototype.loadConfig = function (config) {
  5424. var this_config = this.config,
  5425. target,
  5426. keys,
  5427. read;
  5428. function find() {
  5429. var key = keys.shift(); // console.log("key =>", key, ", target =>", target);
  5430. if (key && target && _typeof(target) === 'object' && key in target) {
  5431. target = target[key];
  5432. return find();
  5433. } else if (!key) {
  5434. return target;
  5435. } else {
  5436. return undefined;
  5437. }
  5438. }
  5439. Object.keys(this_config).forEach(function (key) {
  5440. target = config;
  5441. keys = key.split('_');
  5442. read = find(); // console.log("CONFIG : ", key, read);
  5443. if (isDefined(read)) {
  5444. this_config[key] = read;
  5445. }
  5446. });
  5447. };
  5448. ChartInternal.prototype.convertUrlToData = function (url, mimeType, headers, keys, done) {
  5449. var $$ = this,
  5450. type = mimeType ? mimeType : 'csv',
  5451. f,
  5452. converter;
  5453. if (type === 'json') {
  5454. f = $$.d3.json;
  5455. converter = $$.convertJsonToData;
  5456. } else if (type === 'tsv') {
  5457. f = $$.d3.tsv;
  5458. converter = $$.convertXsvToData;
  5459. } else {
  5460. f = $$.d3.csv;
  5461. converter = $$.convertXsvToData;
  5462. }
  5463. f(url, headers).then(function (data) {
  5464. done.call($$, converter.call($$, data, keys));
  5465. })["catch"](function (error) {
  5466. throw error;
  5467. });
  5468. };
  5469. ChartInternal.prototype.convertXsvToData = function (xsv) {
  5470. var keys = xsv.columns,
  5471. rows = xsv;
  5472. if (rows.length === 0) {
  5473. return {
  5474. keys: keys,
  5475. rows: [keys.reduce(function (row, key) {
  5476. return Object.assign(row, _defineProperty({}, key, null));
  5477. }, {})]
  5478. };
  5479. } else {
  5480. // [].concat() is to convert result into a plain array otherwise
  5481. // test is not happy because rows have properties.
  5482. return {
  5483. keys: keys,
  5484. rows: [].concat(xsv)
  5485. };
  5486. }
  5487. };
  5488. ChartInternal.prototype.convertJsonToData = function (json, keys) {
  5489. var $$ = this,
  5490. new_rows = [],
  5491. targetKeys,
  5492. data;
  5493. if (keys) {
  5494. // when keys specified, json would be an array that includes objects
  5495. if (keys.x) {
  5496. targetKeys = keys.value.concat(keys.x);
  5497. $$.config.data_x = keys.x;
  5498. } else {
  5499. targetKeys = keys.value;
  5500. }
  5501. new_rows.push(targetKeys);
  5502. json.forEach(function (o) {
  5503. var new_row = [];
  5504. targetKeys.forEach(function (key) {
  5505. // convert undefined to null because undefined data will be removed in convertDataToTargets()
  5506. var v = $$.findValueInJson(o, key);
  5507. if (isUndefined(v)) {
  5508. v = null;
  5509. }
  5510. new_row.push(v);
  5511. });
  5512. new_rows.push(new_row);
  5513. });
  5514. data = $$.convertRowsToData(new_rows);
  5515. } else {
  5516. Object.keys(json).forEach(function (key) {
  5517. new_rows.push([key].concat(json[key]));
  5518. });
  5519. data = $$.convertColumnsToData(new_rows);
  5520. }
  5521. return data;
  5522. };
  5523. ChartInternal.prototype.findValueInJson = function (object, path) {
  5524. path = path.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties (replace [] with .)
  5525. path = path.replace(/^\./, ''); // strip a leading dot
  5526. var pathArray = path.split('.');
  5527. for (var i = 0; i < pathArray.length; ++i) {
  5528. var k = pathArray[i];
  5529. if (k in object) {
  5530. object = object[k];
  5531. } else {
  5532. return;
  5533. }
  5534. }
  5535. return object;
  5536. };
  5537. /**
  5538. * Converts the rows to normalized data.
  5539. * @param {any[][]} rows The row data
  5540. * @return {Object}
  5541. */
  5542. ChartInternal.prototype.convertRowsToData = function (rows) {
  5543. var newRows = [];
  5544. var keys = rows[0];
  5545. for (var i = 1; i < rows.length; i++) {
  5546. var newRow = {};
  5547. for (var j = 0; j < rows[i].length; j++) {
  5548. if (isUndefined(rows[i][j])) {
  5549. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  5550. }
  5551. newRow[keys[j]] = rows[i][j];
  5552. }
  5553. newRows.push(newRow);
  5554. }
  5555. return {
  5556. keys: keys,
  5557. rows: newRows
  5558. };
  5559. };
  5560. /**
  5561. * Converts the columns to normalized data.
  5562. * @param {any[][]} columns The column data
  5563. * @return {Object}
  5564. */
  5565. ChartInternal.prototype.convertColumnsToData = function (columns) {
  5566. var newRows = [];
  5567. var keys = [];
  5568. for (var i = 0; i < columns.length; i++) {
  5569. var key = columns[i][0];
  5570. for (var j = 1; j < columns[i].length; j++) {
  5571. if (isUndefined(newRows[j - 1])) {
  5572. newRows[j - 1] = {};
  5573. }
  5574. if (isUndefined(columns[i][j])) {
  5575. throw new Error("Source data is missing a component at (" + i + "," + j + ")!");
  5576. }
  5577. newRows[j - 1][key] = columns[i][j];
  5578. }
  5579. keys.push(key);
  5580. }
  5581. return {
  5582. keys: keys,
  5583. rows: newRows
  5584. };
  5585. };
  5586. /**
  5587. * Converts the data format into the target format.
  5588. * @param {!Object} data
  5589. * @param {!Array} data.keys Ordered list of target IDs.
  5590. * @param {!Array} data.rows Rows of data to convert.
  5591. * @param {boolean} appendXs True to append to $$.data.xs, False to replace.
  5592. * @return {!Array}
  5593. */
  5594. ChartInternal.prototype.convertDataToTargets = function (data, appendXs) {
  5595. var $$ = this,
  5596. config = $$.config,
  5597. targets,
  5598. ids,
  5599. xs,
  5600. keys,
  5601. epochs; // handles format where keys are not orderly provided
  5602. if (isArray(data)) {
  5603. keys = Object.keys(data[0]);
  5604. } else {
  5605. keys = data.keys;
  5606. data = data.rows;
  5607. }
  5608. xs = keys.filter($$.isX, $$);
  5609. if (!$$.isStanfordGraphType()) {
  5610. ids = keys.filter($$.isNotX, $$);
  5611. } else {
  5612. epochs = keys.filter($$.isEpochs, $$);
  5613. ids = keys.filter($$.isNotXAndNotEpochs, $$);
  5614. if (xs.length !== 1 || epochs.length !== 1 || ids.length !== 1) {
  5615. throw new Error('You must define the \'x\' key name and the \'epochs\' for Stanford Diagrams');
  5616. }
  5617. } // save x for update data by load when custom x and c3.x API
  5618. ids.forEach(function (id) {
  5619. var xKey = $$.getXKey(id);
  5620. if ($$.isCustomX() || $$.isTimeSeries()) {
  5621. // if included in input data
  5622. if (xs.indexOf(xKey) >= 0) {
  5623. $$.data.xs[id] = (appendXs && $$.data.xs[id] ? $$.data.xs[id] : []).concat(data.map(function (d) {
  5624. return d[xKey];
  5625. }).filter(isValue).map(function (rawX, i) {
  5626. return $$.generateTargetX(rawX, id, i);
  5627. }));
  5628. } // if not included in input data, find from preloaded data of other id's x
  5629. else if (config.data_x) {
  5630. $$.data.xs[id] = $$.getOtherTargetXs();
  5631. } // if not included in input data, find from preloaded data
  5632. else if (notEmpty(config.data_xs)) {
  5633. $$.data.xs[id] = $$.getXValuesOfXKey(xKey, $$.data.targets);
  5634. } // MEMO: if no x included, use same x of current will be used
  5635. } else {
  5636. $$.data.xs[id] = data.map(function (d, i) {
  5637. return i;
  5638. });
  5639. }
  5640. }); // check x is defined
  5641. ids.forEach(function (id) {
  5642. if (!$$.data.xs[id]) {
  5643. throw new Error('x is not defined for id = "' + id + '".');
  5644. }
  5645. }); // convert to target
  5646. targets = ids.map(function (id, index) {
  5647. var convertedId = config.data_idConverter(id);
  5648. return {
  5649. id: convertedId,
  5650. id_org: id,
  5651. values: data.map(function (d, i) {
  5652. var xKey = $$.getXKey(id),
  5653. rawX = d[xKey],
  5654. value = d[id] !== null && !isNaN(d[id]) ? +d[id] : null,
  5655. x,
  5656. returnData; // use x as categories if custom x and categorized
  5657. if ($$.isCustomX() && $$.isCategorized() && !isUndefined(rawX)) {
  5658. if (index === 0 && i === 0) {
  5659. config.axis_x_categories = [];
  5660. }
  5661. x = config.axis_x_categories.indexOf(rawX);
  5662. if (x === -1) {
  5663. x = config.axis_x_categories.length;
  5664. config.axis_x_categories.push(rawX);
  5665. }
  5666. } else {
  5667. x = $$.generateTargetX(rawX, id, i);
  5668. } // mark as x = undefined if value is undefined and filter to remove after mapped
  5669. if (isUndefined(d[id]) || $$.data.xs[id].length <= i) {
  5670. x = undefined;
  5671. }
  5672. returnData = {
  5673. x: x,
  5674. value: value,
  5675. id: convertedId
  5676. };
  5677. if ($$.isStanfordGraphType()) {
  5678. returnData.epochs = d[epochs];
  5679. }
  5680. return returnData;
  5681. }).filter(function (v) {
  5682. return isDefined(v.x);
  5683. })
  5684. };
  5685. }); // finish targets
  5686. targets.forEach(function (t) {
  5687. var i; // sort values by its x
  5688. if (config.data_xSort) {
  5689. t.values = t.values.sort(function (v1, v2) {
  5690. var x1 = v1.x || v1.x === 0 ? v1.x : Infinity,
  5691. x2 = v2.x || v2.x === 0 ? v2.x : Infinity;
  5692. return x1 - x2;
  5693. });
  5694. } // indexing each value
  5695. i = 0;
  5696. t.values.forEach(function (v) {
  5697. v.index = i++;
  5698. }); // this needs to be sorted because its index and value.index is identical
  5699. $$.data.xs[t.id].sort(function (v1, v2) {
  5700. return v1 - v2;
  5701. });
  5702. }); // cache information about values
  5703. $$.hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  5704. $$.hasPositiveValue = $$.hasPositiveValueInTargets(targets); // set target types
  5705. if (config.data_type) {
  5706. $$.setTargetType($$.mapToIds(targets).filter(function (id) {
  5707. return !(id in config.data_types);
  5708. }), config.data_type);
  5709. } // cache as original id keyed
  5710. targets.forEach(function (d) {
  5711. $$.addCache(d.id_org, d);
  5712. });
  5713. return targets;
  5714. };
  5715. ChartInternal.prototype.isEpochs = function (key) {
  5716. var $$ = this,
  5717. config = $$.config;
  5718. return config.data_epochs && key === config.data_epochs;
  5719. };
  5720. ChartInternal.prototype.isX = function (key) {
  5721. var $$ = this,
  5722. config = $$.config;
  5723. return config.data_x && key === config.data_x || notEmpty(config.data_xs) && hasValue(config.data_xs, key);
  5724. };
  5725. ChartInternal.prototype.isNotX = function (key) {
  5726. return !this.isX(key);
  5727. };
  5728. ChartInternal.prototype.isNotXAndNotEpochs = function (key) {
  5729. return !this.isX(key) && !this.isEpochs(key);
  5730. };
  5731. /**
  5732. * Returns whether the normalized stack option is enabled or not.
  5733. *
  5734. * To be enabled it must also have data.groups defined.
  5735. *
  5736. * @return {boolean}
  5737. */
  5738. ChartInternal.prototype.isStackNormalized = function () {
  5739. return this.config.data_stack_normalize && this.config.data_groups.length > 0;
  5740. };
  5741. /**
  5742. * Returns whether the axis is normalized or not.
  5743. *
  5744. * An axis is normalized as long as one of its associated target
  5745. * is normalized.
  5746. *
  5747. * @param axisId Axis ID (y or y2)
  5748. * @return {Boolean}
  5749. */
  5750. ChartInternal.prototype.isAxisNormalized = function (axisId) {
  5751. var $$ = this;
  5752. if (!$$.isStackNormalized()) {
  5753. // shortcut
  5754. return false;
  5755. }
  5756. return $$.data.targets.filter(function (target) {
  5757. return $$.axis.getId(target.id) === axisId;
  5758. }).some(function (target) {
  5759. return $$.isTargetNormalized(target.id);
  5760. });
  5761. };
  5762. /**
  5763. * Returns whether the values for this target ID is normalized or not.
  5764. *
  5765. * To be normalized the option needs to be enabled and target needs
  5766. * to be defined in `data.groups`.
  5767. *
  5768. * @param targetId ID of the target
  5769. * @return {Boolean} True if the target is normalized, false otherwise.
  5770. */
  5771. ChartInternal.prototype.isTargetNormalized = function (targetId) {
  5772. var $$ = this;
  5773. return $$.isStackNormalized() && $$.config.data_groups.some(function (group) {
  5774. return group.includes(targetId);
  5775. });
  5776. };
  5777. ChartInternal.prototype.getXKey = function (id) {
  5778. var $$ = this,
  5779. config = $$.config;
  5780. return config.data_x ? config.data_x : notEmpty(config.data_xs) ? config.data_xs[id] : null;
  5781. };
  5782. /**
  5783. * Get sum of visible data per index for given axis.
  5784. *
  5785. * Expect axisId to be either 'y' or 'y2'.
  5786. *
  5787. * @private
  5788. * @param axisId Compute sum for data associated to given axis.
  5789. * @return {Array}
  5790. */
  5791. ChartInternal.prototype.getTotalPerIndex = function (axisId) {
  5792. var $$ = this;
  5793. if (!$$.isStackNormalized()) {
  5794. return null;
  5795. }
  5796. var cached = $$.getFromCache('getTotalPerIndex');
  5797. if (cached !== undefined) {
  5798. return cached[axisId];
  5799. }
  5800. var sum = {
  5801. y: [],
  5802. y2: []
  5803. };
  5804. $$.data.targets // keep only target that are normalized
  5805. .filter(function (target) {
  5806. return $$.isTargetNormalized(target.id);
  5807. }) // keep only target that are visible
  5808. .filter(function (target) {
  5809. return $$.isTargetToShow(target.id);
  5810. }) // compute sum per axis
  5811. .forEach(function (target) {
  5812. var sumByAxis = sum[$$.axis.getId(target.id)];
  5813. target.values.forEach(function (v, i) {
  5814. if (!sumByAxis[i]) {
  5815. sumByAxis[i] = 0;
  5816. }
  5817. sumByAxis[i] += isNumber(v.value) ? v.value : 0;
  5818. });
  5819. });
  5820. $$.addToCache('getTotalPerIndex', sum);
  5821. return sum[axisId];
  5822. };
  5823. /**
  5824. * Get sum of visible data.
  5825. *
  5826. * Should be used for normalised data only since all values
  5827. * are expected to be positive.
  5828. *
  5829. * @private
  5830. * @return {Number}
  5831. */
  5832. ChartInternal.prototype.getTotalDataSum = function () {
  5833. var $$ = this;
  5834. var cached = $$.getFromCache('getTotalDataSum');
  5835. if (cached !== undefined) {
  5836. return cached;
  5837. }
  5838. var totalDataSum = flattenArray($$.data.targets.filter(function (target) {
  5839. return $$.isTargetToShow(target.id);
  5840. }).map(function (target) {
  5841. return target.values;
  5842. })).map(function (d) {
  5843. return d.value;
  5844. }).reduce(function (p, c) {
  5845. return p + c;
  5846. }, 0);
  5847. $$.addToCache('getTotalDataSum', totalDataSum);
  5848. return totalDataSum;
  5849. };
  5850. ChartInternal.prototype.getXValuesOfXKey = function (key, targets) {
  5851. var $$ = this,
  5852. xValues,
  5853. ids = targets && notEmpty(targets) ? $$.mapToIds(targets) : [];
  5854. ids.forEach(function (id) {
  5855. if ($$.getXKey(id) === key) {
  5856. xValues = $$.data.xs[id];
  5857. }
  5858. });
  5859. return xValues;
  5860. };
  5861. ChartInternal.prototype.getXValue = function (id, i) {
  5862. var $$ = this;
  5863. return id in $$.data.xs && $$.data.xs[id] && isValue($$.data.xs[id][i]) ? $$.data.xs[id][i] : i;
  5864. };
  5865. ChartInternal.prototype.getOtherTargetXs = function () {
  5866. var $$ = this,
  5867. idsForX = Object.keys($$.data.xs);
  5868. return idsForX.length ? $$.data.xs[idsForX[0]] : null;
  5869. };
  5870. ChartInternal.prototype.getOtherTargetX = function (index) {
  5871. var xs = this.getOtherTargetXs();
  5872. return xs && index < xs.length ? xs[index] : null;
  5873. };
  5874. ChartInternal.prototype.addXs = function (xs) {
  5875. var $$ = this;
  5876. Object.keys(xs).forEach(function (id) {
  5877. $$.config.data_xs[id] = xs[id];
  5878. });
  5879. };
  5880. ChartInternal.prototype.addName = function (data) {
  5881. var $$ = this,
  5882. name;
  5883. if (data) {
  5884. name = $$.config.data_names[data.id];
  5885. data.name = name !== undefined ? name : data.id;
  5886. }
  5887. return data;
  5888. };
  5889. ChartInternal.prototype.getValueOnIndex = function (values, index) {
  5890. var valueOnIndex = values.filter(function (v) {
  5891. return v.index === index;
  5892. });
  5893. return valueOnIndex.length ? valueOnIndex[0] : null;
  5894. };
  5895. ChartInternal.prototype.updateTargetX = function (targets, x) {
  5896. var $$ = this;
  5897. targets.forEach(function (t) {
  5898. t.values.forEach(function (v, i) {
  5899. v.x = $$.generateTargetX(x[i], t.id, i);
  5900. });
  5901. $$.data.xs[t.id] = x;
  5902. });
  5903. };
  5904. ChartInternal.prototype.updateTargetXs = function (targets, xs) {
  5905. var $$ = this;
  5906. targets.forEach(function (t) {
  5907. if (xs[t.id]) {
  5908. $$.updateTargetX([t], xs[t.id]);
  5909. }
  5910. });
  5911. };
  5912. ChartInternal.prototype.generateTargetX = function (rawX, id, index) {
  5913. var $$ = this,
  5914. x;
  5915. if ($$.isTimeSeries()) {
  5916. x = rawX ? $$.parseDate(rawX) : $$.parseDate($$.getXValue(id, index));
  5917. } else if ($$.isCustomX() && !$$.isCategorized()) {
  5918. x = isValue(rawX) ? +rawX : $$.getXValue(id, index);
  5919. } else {
  5920. x = index;
  5921. }
  5922. return x;
  5923. };
  5924. ChartInternal.prototype.cloneTarget = function (target) {
  5925. return {
  5926. id: target.id,
  5927. id_org: target.id_org,
  5928. values: target.values.map(function (d) {
  5929. return {
  5930. x: d.x,
  5931. value: d.value,
  5932. id: d.id
  5933. };
  5934. })
  5935. };
  5936. };
  5937. ChartInternal.prototype.getMaxDataCount = function () {
  5938. var $$ = this;
  5939. return $$.d3.max($$.data.targets, function (t) {
  5940. return t.values.length;
  5941. });
  5942. };
  5943. ChartInternal.prototype.mapToIds = function (targets) {
  5944. return targets.map(function (d) {
  5945. return d.id;
  5946. });
  5947. };
  5948. ChartInternal.prototype.mapToTargetIds = function (ids) {
  5949. var $$ = this;
  5950. return ids ? [].concat(ids) : $$.mapToIds($$.data.targets);
  5951. };
  5952. ChartInternal.prototype.hasTarget = function (targets, id) {
  5953. var ids = this.mapToIds(targets),
  5954. i;
  5955. for (i = 0; i < ids.length; i++) {
  5956. if (ids[i] === id) {
  5957. return true;
  5958. }
  5959. }
  5960. return false;
  5961. };
  5962. ChartInternal.prototype.isTargetToShow = function (targetId) {
  5963. return this.hiddenTargetIds.indexOf(targetId) < 0;
  5964. };
  5965. ChartInternal.prototype.isLegendToShow = function (targetId) {
  5966. return this.hiddenLegendIds.indexOf(targetId) < 0;
  5967. };
  5968. ChartInternal.prototype.filterTargetsToShow = function (targets) {
  5969. var $$ = this;
  5970. return targets.filter(function (t) {
  5971. return $$.isTargetToShow(t.id);
  5972. });
  5973. };
  5974. ChartInternal.prototype.mapTargetsToUniqueXs = function (targets) {
  5975. var $$ = this;
  5976. var xs = $$.d3.set($$.d3.merge(targets.map(function (t) {
  5977. return t.values.map(function (v) {
  5978. return +v.x;
  5979. });
  5980. }))).values();
  5981. xs = $$.isTimeSeries() ? xs.map(function (x) {
  5982. return new Date(+x);
  5983. }) : xs.map(function (x) {
  5984. return +x;
  5985. });
  5986. return xs.sort(function (a, b) {
  5987. return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
  5988. });
  5989. };
  5990. ChartInternal.prototype.addHiddenTargetIds = function (targetIds) {
  5991. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  5992. for (var i = 0; i < targetIds.length; i++) {
  5993. if (this.hiddenTargetIds.indexOf(targetIds[i]) < 0) {
  5994. this.hiddenTargetIds = this.hiddenTargetIds.concat(targetIds[i]);
  5995. }
  5996. }
  5997. this.resetCache();
  5998. };
  5999. ChartInternal.prototype.removeHiddenTargetIds = function (targetIds) {
  6000. this.hiddenTargetIds = this.hiddenTargetIds.filter(function (id) {
  6001. return targetIds.indexOf(id) < 0;
  6002. });
  6003. this.resetCache();
  6004. };
  6005. ChartInternal.prototype.addHiddenLegendIds = function (targetIds) {
  6006. targetIds = targetIds instanceof Array ? targetIds : new Array(targetIds);
  6007. for (var i = 0; i < targetIds.length; i++) {
  6008. if (this.hiddenLegendIds.indexOf(targetIds[i]) < 0) {
  6009. this.hiddenLegendIds = this.hiddenLegendIds.concat(targetIds[i]);
  6010. }
  6011. }
  6012. };
  6013. ChartInternal.prototype.removeHiddenLegendIds = function (targetIds) {
  6014. this.hiddenLegendIds = this.hiddenLegendIds.filter(function (id) {
  6015. return targetIds.indexOf(id) < 0;
  6016. });
  6017. };
  6018. ChartInternal.prototype.getValuesAsIdKeyed = function (targets) {
  6019. var ys = {};
  6020. targets.forEach(function (t) {
  6021. ys[t.id] = [];
  6022. t.values.forEach(function (v) {
  6023. ys[t.id].push(v.value);
  6024. });
  6025. });
  6026. return ys;
  6027. };
  6028. ChartInternal.prototype.checkValueInTargets = function (targets, checker) {
  6029. var ids = Object.keys(targets),
  6030. i,
  6031. j,
  6032. values;
  6033. for (i = 0; i < ids.length; i++) {
  6034. values = targets[ids[i]].values;
  6035. for (j = 0; j < values.length; j++) {
  6036. if (checker(values[j].value)) {
  6037. return true;
  6038. }
  6039. }
  6040. }
  6041. return false;
  6042. };
  6043. ChartInternal.prototype.hasNegativeValueInTargets = function (targets) {
  6044. return this.checkValueInTargets(targets, function (v) {
  6045. return v < 0;
  6046. });
  6047. };
  6048. ChartInternal.prototype.hasPositiveValueInTargets = function (targets) {
  6049. return this.checkValueInTargets(targets, function (v) {
  6050. return v > 0;
  6051. });
  6052. };
  6053. ChartInternal.prototype.isOrderDesc = function () {
  6054. var config = this.config;
  6055. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'desc';
  6056. };
  6057. ChartInternal.prototype.isOrderAsc = function () {
  6058. var config = this.config;
  6059. return typeof config.data_order === 'string' && config.data_order.toLowerCase() === 'asc';
  6060. };
  6061. ChartInternal.prototype.getOrderFunction = function () {
  6062. var $$ = this,
  6063. config = $$.config,
  6064. orderAsc = $$.isOrderAsc(),
  6065. orderDesc = $$.isOrderDesc();
  6066. if (orderAsc || orderDesc) {
  6067. var reducer = function reducer(p, c) {
  6068. return p + Math.abs(c.value);
  6069. };
  6070. return function (t1, t2) {
  6071. var t1Sum = t1.values.reduce(reducer, 0),
  6072. t2Sum = t2.values.reduce(reducer, 0);
  6073. return orderAsc ? t2Sum - t1Sum : t1Sum - t2Sum;
  6074. };
  6075. } else if (isFunction(config.data_order)) {
  6076. return config.data_order;
  6077. } else if (isArray(config.data_order)) {
  6078. var order = config.data_order;
  6079. return function (t1, t2) {
  6080. return order.indexOf(t1.id) - order.indexOf(t2.id);
  6081. };
  6082. }
  6083. };
  6084. ChartInternal.prototype.orderTargets = function (targets) {
  6085. var fct = this.getOrderFunction();
  6086. if (fct) {
  6087. targets.sort(fct);
  6088. }
  6089. return targets;
  6090. };
  6091. ChartInternal.prototype.filterByX = function (targets, x) {
  6092. return this.d3.merge(targets.map(function (t) {
  6093. return t.values;
  6094. })).filter(function (v) {
  6095. return v.x - x === 0;
  6096. });
  6097. };
  6098. ChartInternal.prototype.filterRemoveNull = function (data) {
  6099. return data.filter(function (d) {
  6100. return isValue(d.value);
  6101. });
  6102. };
  6103. ChartInternal.prototype.filterByXDomain = function (targets, xDomain) {
  6104. return targets.map(function (t) {
  6105. return {
  6106. id: t.id,
  6107. id_org: t.id_org,
  6108. values: t.values.filter(function (v) {
  6109. return xDomain[0] <= v.x && v.x <= xDomain[1];
  6110. })
  6111. };
  6112. });
  6113. };
  6114. ChartInternal.prototype.hasDataLabel = function () {
  6115. var config = this.config;
  6116. if (typeof config.data_labels === 'boolean' && config.data_labels) {
  6117. return true;
  6118. } else if (_typeof(config.data_labels) === 'object' && notEmpty(config.data_labels)) {
  6119. return true;
  6120. }
  6121. return false;
  6122. };
  6123. ChartInternal.prototype.getDataLabelLength = function (min, max, key) {
  6124. var $$ = this,
  6125. lengths = [0, 0],
  6126. paddingCoef = 1.3;
  6127. $$.selectChart.select('svg').selectAll('.dummy').data([min, max]).enter().append('text').text(function (d) {
  6128. return $$.dataLabelFormat(d.id)(d);
  6129. }).each(function (d, i) {
  6130. lengths[i] = getBBox(this)[key] * paddingCoef;
  6131. }).remove();
  6132. return lengths;
  6133. };
  6134. /**
  6135. * Returns true if the given data point is not arc type, otherwise false.
  6136. * @param {Object} d The data point
  6137. * @return {boolean}
  6138. */
  6139. ChartInternal.prototype.isNoneArc = function (d) {
  6140. return this.hasTarget(this.data.targets, d.id);
  6141. };
  6142. /**
  6143. * Returns true if the given data point is arc type, otherwise false.
  6144. * @param {Object} d The data point
  6145. * @return {boolean}
  6146. */
  6147. ChartInternal.prototype.isArc = function (d) {
  6148. return 'data' in d && this.hasTarget(this.data.targets, d.data.id);
  6149. };
  6150. ChartInternal.prototype.findClosestFromTargets = function (targets, pos) {
  6151. var $$ = this,
  6152. candidates; // map to array of closest points of each target
  6153. candidates = targets.map(function (target) {
  6154. return $$.findClosest(target.values, pos);
  6155. }); // decide closest point and return
  6156. return $$.findClosest(candidates, pos);
  6157. };
  6158. ChartInternal.prototype.findClosest = function (values, pos) {
  6159. var $$ = this,
  6160. minDist = $$.config.point_sensitivity,
  6161. closest; // find mouseovering bar
  6162. values.filter(function (v) {
  6163. return v && $$.isBarType(v.id);
  6164. }).forEach(function (v) {
  6165. var shape = $$.main.select('.' + CLASS.bars + $$.getTargetSelectorSuffix(v.id) + ' .' + CLASS.bar + '-' + v.index).node();
  6166. if (!closest && $$.isWithinBar($$.d3.mouse(shape), shape)) {
  6167. closest = v;
  6168. }
  6169. }); // find closest point from non-bar
  6170. values.filter(function (v) {
  6171. return v && !$$.isBarType(v.id);
  6172. }).forEach(function (v) {
  6173. var d = $$.config.tooltip_horizontal ? $$.horizontalDistance(v, pos) : $$.dist(v, pos);
  6174. if (d < minDist) {
  6175. minDist = d;
  6176. closest = v;
  6177. }
  6178. });
  6179. return closest;
  6180. };
  6181. ChartInternal.prototype.dist = function (data, pos) {
  6182. var $$ = this,
  6183. config = $$.config,
  6184. xIndex = config.axis_rotated ? 1 : 0,
  6185. yIndex = config.axis_rotated ? 0 : 1,
  6186. y = $$.circleY(data, data.index),
  6187. x = $$.x(data.x);
  6188. return Math.sqrt(Math.pow(x - pos[xIndex], 2) + Math.pow(y - pos[yIndex], 2));
  6189. };
  6190. ChartInternal.prototype.horizontalDistance = function (data, pos) {
  6191. var $$ = this,
  6192. config = $$.config,
  6193. xIndex = config.axis_rotated ? 1 : 0,
  6194. x = $$.x(data.x);
  6195. return Math.abs(x - pos[xIndex]);
  6196. };
  6197. ChartInternal.prototype.convertValuesToStep = function (values) {
  6198. var converted = [].concat(values),
  6199. i;
  6200. if (!this.isCategorized()) {
  6201. return values;
  6202. }
  6203. for (i = values.length + 1; 0 < i; i--) {
  6204. converted[i] = converted[i - 1];
  6205. }
  6206. converted[0] = {
  6207. x: converted[0].x - 1,
  6208. value: converted[0].value,
  6209. id: converted[0].id
  6210. };
  6211. converted[values.length + 1] = {
  6212. x: converted[values.length].x + 1,
  6213. value: converted[values.length].value,
  6214. id: converted[values.length].id
  6215. };
  6216. return converted;
  6217. };
  6218. /**
  6219. * Get ratio value
  6220. *
  6221. * @param {String} type Ratio for given type
  6222. * @param {Object} d Data value object
  6223. * @param {Boolean} asPercent Convert the return as percent or not
  6224. * @return {Number} Ratio value
  6225. * @private
  6226. */
  6227. ChartInternal.prototype.getRatio = function (type, d) {
  6228. var asPercent = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
  6229. var $$ = this;
  6230. var api = $$.api;
  6231. var ratio = 0;
  6232. if (d && api.data.shown.call(api).length) {
  6233. ratio = d.ratio || d.value;
  6234. if (type === "arc") {
  6235. if ($$.hasType('gauge')) {
  6236. ratio = (d.endAngle - d.startAngle) / (Math.PI * ($$.config.gauge_fullCircle ? 2 : 1));
  6237. } else {
  6238. var total = $$.getTotalDataSum();
  6239. ratio = d.value / total;
  6240. }
  6241. } else if (type === "index") {
  6242. var _total = $$.getTotalPerIndex($$.axis.getId(d.id));
  6243. d.ratio = isNumber(d.value) && _total && _total[d.index] > 0 ? d.value / _total[d.index] : 0;
  6244. ratio = d.ratio;
  6245. }
  6246. }
  6247. return asPercent && ratio ? ratio * 100 : ratio;
  6248. };
  6249. ChartInternal.prototype.updateDataAttributes = function (name, attrs) {
  6250. var $$ = this,
  6251. config = $$.config,
  6252. current = config['data_' + name];
  6253. if (typeof attrs === 'undefined') {
  6254. return current;
  6255. }
  6256. Object.keys(attrs).forEach(function (id) {
  6257. current[id] = attrs[id];
  6258. });
  6259. $$.redraw({
  6260. withLegend: true
  6261. });
  6262. return current;
  6263. };
  6264. ChartInternal.prototype.load = function (targets, args) {
  6265. var $$ = this;
  6266. if (targets) {
  6267. // filter loading targets if needed
  6268. if (args.filter) {
  6269. targets = targets.filter(args.filter);
  6270. } // set type if args.types || args.type specified
  6271. if (args.type || args.types) {
  6272. targets.forEach(function (t) {
  6273. var type = args.types && args.types[t.id] ? args.types[t.id] : args.type;
  6274. $$.setTargetType(t.id, type);
  6275. });
  6276. } // Update/Add data
  6277. $$.data.targets.forEach(function (d) {
  6278. for (var i = 0; i < targets.length; i++) {
  6279. if (d.id === targets[i].id) {
  6280. d.values = targets[i].values;
  6281. targets.splice(i, 1);
  6282. break;
  6283. }
  6284. }
  6285. });
  6286. $$.data.targets = $$.data.targets.concat(targets); // add remained
  6287. } // Set targets
  6288. $$.updateTargets($$.data.targets); // Redraw with new targets
  6289. $$.redraw({
  6290. withUpdateOrgXDomain: true,
  6291. withUpdateXDomain: true,
  6292. withLegend: true
  6293. });
  6294. if (args.done) {
  6295. args.done();
  6296. }
  6297. };
  6298. ChartInternal.prototype.loadFromArgs = function (args) {
  6299. var $$ = this;
  6300. $$.resetCache();
  6301. if (args.data) {
  6302. $$.load($$.convertDataToTargets(args.data), args);
  6303. } else if (args.url) {
  6304. $$.convertUrlToData(args.url, args.mimeType, args.headers, args.keys, function (data) {
  6305. $$.load($$.convertDataToTargets(data), args);
  6306. });
  6307. } else if (args.json) {
  6308. $$.load($$.convertDataToTargets($$.convertJsonToData(args.json, args.keys)), args);
  6309. } else if (args.rows) {
  6310. $$.load($$.convertDataToTargets($$.convertRowsToData(args.rows)), args);
  6311. } else if (args.columns) {
  6312. $$.load($$.convertDataToTargets($$.convertColumnsToData(args.columns)), args);
  6313. } else {
  6314. $$.load(null, args);
  6315. }
  6316. };
  6317. ChartInternal.prototype.unload = function (targetIds, done) {
  6318. var $$ = this;
  6319. $$.resetCache();
  6320. if (!done) {
  6321. done = function done() {};
  6322. } // filter existing target
  6323. targetIds = targetIds.filter(function (id) {
  6324. return $$.hasTarget($$.data.targets, id);
  6325. }); // If no target, call done and return
  6326. if (!targetIds || targetIds.length === 0) {
  6327. done();
  6328. return;
  6329. }
  6330. $$.svg.selectAll(targetIds.map(function (id) {
  6331. return $$.selectorTarget(id);
  6332. })).transition().style('opacity', 0).remove().call($$.endall, done);
  6333. targetIds.forEach(function (id) {
  6334. // Reset fadein for future load
  6335. $$.withoutFadeIn[id] = false; // Remove target's elements
  6336. if ($$.legend) {
  6337. $$.legend.selectAll('.' + CLASS.legendItem + $$.getTargetSelectorSuffix(id)).remove();
  6338. } // Remove target
  6339. $$.data.targets = $$.data.targets.filter(function (t) {
  6340. return t.id !== id;
  6341. });
  6342. });
  6343. };
  6344. ChartInternal.prototype.getYDomainMin = function (targets) {
  6345. var $$ = this,
  6346. config = $$.config,
  6347. ids = $$.mapToIds(targets),
  6348. ys = $$.getValuesAsIdKeyed(targets),
  6349. j,
  6350. k,
  6351. baseId,
  6352. idsInGroup,
  6353. id,
  6354. hasNegativeValue;
  6355. if (config.data_groups.length > 0) {
  6356. hasNegativeValue = $$.hasNegativeValueInTargets(targets);
  6357. for (j = 0; j < config.data_groups.length; j++) {
  6358. // Determine baseId
  6359. idsInGroup = config.data_groups[j].filter(function (id) {
  6360. return ids.indexOf(id) >= 0;
  6361. });
  6362. if (idsInGroup.length === 0) {
  6363. continue;
  6364. }
  6365. baseId = idsInGroup[0]; // Consider negative values
  6366. if (hasNegativeValue && ys[baseId]) {
  6367. ys[baseId].forEach(function (v, i) {
  6368. ys[baseId][i] = v < 0 ? v : 0;
  6369. });
  6370. } // Compute min
  6371. for (k = 1; k < idsInGroup.length; k++) {
  6372. id = idsInGroup[k];
  6373. if (!ys[id]) {
  6374. continue;
  6375. }
  6376. ys[id].forEach(function (v, i) {
  6377. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasNegativeValue && +v > 0)) {
  6378. ys[baseId][i] += +v;
  6379. }
  6380. });
  6381. }
  6382. }
  6383. }
  6384. return $$.d3.min(Object.keys(ys).map(function (key) {
  6385. return $$.d3.min(ys[key]);
  6386. }));
  6387. };
  6388. ChartInternal.prototype.getYDomainMax = function (targets) {
  6389. var $$ = this,
  6390. config = $$.config,
  6391. ids = $$.mapToIds(targets),
  6392. ys = $$.getValuesAsIdKeyed(targets),
  6393. j,
  6394. k,
  6395. baseId,
  6396. idsInGroup,
  6397. id,
  6398. hasPositiveValue;
  6399. if (config.data_groups.length > 0) {
  6400. hasPositiveValue = $$.hasPositiveValueInTargets(targets);
  6401. for (j = 0; j < config.data_groups.length; j++) {
  6402. // Determine baseId
  6403. idsInGroup = config.data_groups[j].filter(function (id) {
  6404. return ids.indexOf(id) >= 0;
  6405. });
  6406. if (idsInGroup.length === 0) {
  6407. continue;
  6408. }
  6409. baseId = idsInGroup[0]; // Consider positive values
  6410. if (hasPositiveValue && ys[baseId]) {
  6411. ys[baseId].forEach(function (v, i) {
  6412. ys[baseId][i] = v > 0 ? v : 0;
  6413. });
  6414. } // Compute max
  6415. for (k = 1; k < idsInGroup.length; k++) {
  6416. id = idsInGroup[k];
  6417. if (!ys[id]) {
  6418. continue;
  6419. }
  6420. ys[id].forEach(function (v, i) {
  6421. if ($$.axis.getId(id) === $$.axis.getId(baseId) && ys[baseId] && !(hasPositiveValue && +v < 0)) {
  6422. ys[baseId][i] += +v;
  6423. }
  6424. });
  6425. }
  6426. }
  6427. }
  6428. return $$.d3.max(Object.keys(ys).map(function (key) {
  6429. return $$.d3.max(ys[key]);
  6430. }));
  6431. };
  6432. ChartInternal.prototype.getYDomain = function (targets, axisId, xDomain) {
  6433. var $$ = this,
  6434. config = $$.config;
  6435. if ($$.isAxisNormalized(axisId)) {
  6436. return [0, 100];
  6437. }
  6438. var targetsByAxisId = targets.filter(function (t) {
  6439. return $$.axis.getId(t.id) === axisId;
  6440. }),
  6441. yTargets = xDomain ? $$.filterByXDomain(targetsByAxisId, xDomain) : targetsByAxisId,
  6442. yMin = axisId === 'y2' ? config.axis_y2_min : config.axis_y_min,
  6443. yMax = axisId === 'y2' ? config.axis_y2_max : config.axis_y_max,
  6444. yDomainMin = $$.getYDomainMin(yTargets),
  6445. yDomainMax = $$.getYDomainMax(yTargets),
  6446. domain,
  6447. domainLength,
  6448. padding,
  6449. padding_top,
  6450. padding_bottom,
  6451. center = axisId === 'y2' ? config.axis_y2_center : config.axis_y_center,
  6452. yDomainAbs,
  6453. lengths,
  6454. diff,
  6455. ratio,
  6456. isAllPositive,
  6457. isAllNegative,
  6458. isZeroBased = $$.hasType('bar', yTargets) && config.bar_zerobased || $$.hasType('area', yTargets) && config.area_zerobased,
  6459. isInverted = axisId === 'y2' ? config.axis_y2_inverted : config.axis_y_inverted,
  6460. showHorizontalDataLabel = $$.hasDataLabel() && config.axis_rotated,
  6461. showVerticalDataLabel = $$.hasDataLabel() && !config.axis_rotated; // MEMO: avoid inverting domain unexpectedly
  6462. yDomainMin = isValue(yMin) ? yMin : isValue(yMax) ? yDomainMin < yMax ? yDomainMin : yMax - 10 : yDomainMin;
  6463. yDomainMax = isValue(yMax) ? yMax : isValue(yMin) ? yMin < yDomainMax ? yDomainMax : yMin + 10 : yDomainMax;
  6464. if (yTargets.length === 0) {
  6465. // use current domain if target of axisId is none
  6466. return axisId === 'y2' ? $$.y2.domain() : $$.y.domain();
  6467. }
  6468. if (isNaN(yDomainMin)) {
  6469. // set minimum to zero when not number
  6470. yDomainMin = 0;
  6471. }
  6472. if (isNaN(yDomainMax)) {
  6473. // set maximum to have same value as yDomainMin
  6474. yDomainMax = yDomainMin;
  6475. }
  6476. if (yDomainMin === yDomainMax) {
  6477. yDomainMin < 0 ? yDomainMax = 0 : yDomainMin = 0;
  6478. }
  6479. isAllPositive = yDomainMin >= 0 && yDomainMax >= 0;
  6480. isAllNegative = yDomainMin <= 0 && yDomainMax <= 0; // Cancel zerobased if axis_*_min / axis_*_max specified
  6481. if (isValue(yMin) && isAllPositive || isValue(yMax) && isAllNegative) {
  6482. isZeroBased = false;
  6483. } // Bar/Area chart should be 0-based if all positive|negative
  6484. if (isZeroBased) {
  6485. if (isAllPositive) {
  6486. yDomainMin = 0;
  6487. }
  6488. if (isAllNegative) {
  6489. yDomainMax = 0;
  6490. }
  6491. }
  6492. domainLength = Math.abs(yDomainMax - yDomainMin);
  6493. padding = padding_top = padding_bottom = domainLength * 0.1;
  6494. if (typeof center !== 'undefined') {
  6495. yDomainAbs = Math.max(Math.abs(yDomainMin), Math.abs(yDomainMax));
  6496. yDomainMax = center + yDomainAbs;
  6497. yDomainMin = center - yDomainAbs;
  6498. } // add padding for data label
  6499. if (showHorizontalDataLabel) {
  6500. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'width');
  6501. diff = diffDomain($$.y.range());
  6502. ratio = [lengths[0] / diff, lengths[1] / diff];
  6503. padding_top += domainLength * (ratio[1] / (1 - ratio[0] - ratio[1]));
  6504. padding_bottom += domainLength * (ratio[0] / (1 - ratio[0] - ratio[1]));
  6505. } else if (showVerticalDataLabel) {
  6506. lengths = $$.getDataLabelLength(yDomainMin, yDomainMax, 'height');
  6507. padding_top += $$.axis.convertPixelsToAxisPadding(lengths[1], domainLength);
  6508. padding_bottom += $$.axis.convertPixelsToAxisPadding(lengths[0], domainLength);
  6509. }
  6510. if (axisId === 'y' && notEmpty(config.axis_y_padding)) {
  6511. padding_top = $$.axis.getPadding(config.axis_y_padding, 'top', padding_top, domainLength);
  6512. padding_bottom = $$.axis.getPadding(config.axis_y_padding, 'bottom', padding_bottom, domainLength);
  6513. }
  6514. if (axisId === 'y2' && notEmpty(config.axis_y2_padding)) {
  6515. padding_top = $$.axis.getPadding(config.axis_y2_padding, 'top', padding_top, domainLength);
  6516. padding_bottom = $$.axis.getPadding(config.axis_y2_padding, 'bottom', padding_bottom, domainLength);
  6517. } // Bar/Area chart should be 0-based if all positive|negative
  6518. if (isZeroBased) {
  6519. if (isAllPositive) {
  6520. padding_bottom = yDomainMin;
  6521. }
  6522. if (isAllNegative) {
  6523. padding_top = -yDomainMax;
  6524. }
  6525. }
  6526. domain = [yDomainMin - padding_bottom, yDomainMax + padding_top];
  6527. return isInverted ? domain.reverse() : domain;
  6528. };
  6529. ChartInternal.prototype.getXDomainMin = function (targets) {
  6530. var $$ = this,
  6531. config = $$.config;
  6532. return isDefined(config.axis_x_min) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_min) : config.axis_x_min : $$.d3.min(targets, function (t) {
  6533. return $$.d3.min(t.values, function (v) {
  6534. return v.x;
  6535. });
  6536. });
  6537. };
  6538. ChartInternal.prototype.getXDomainMax = function (targets) {
  6539. var $$ = this,
  6540. config = $$.config;
  6541. return isDefined(config.axis_x_max) ? $$.isTimeSeries() ? this.parseDate(config.axis_x_max) : config.axis_x_max : $$.d3.max(targets, function (t) {
  6542. return $$.d3.max(t.values, function (v) {
  6543. return v.x;
  6544. });
  6545. });
  6546. };
  6547. ChartInternal.prototype.getXDomainPadding = function (domain) {
  6548. var $$ = this,
  6549. config = $$.config,
  6550. diff = domain[1] - domain[0],
  6551. maxDataCount,
  6552. padding,
  6553. paddingLeft,
  6554. paddingRight;
  6555. if ($$.isCategorized()) {
  6556. padding = 0;
  6557. } else if ($$.hasType('bar')) {
  6558. maxDataCount = $$.getMaxDataCount();
  6559. padding = maxDataCount > 1 ? diff / (maxDataCount - 1) / 2 : 0.5;
  6560. } else {
  6561. padding = diff * 0.01;
  6562. }
  6563. if (_typeof(config.axis_x_padding) === 'object' && notEmpty(config.axis_x_padding)) {
  6564. paddingLeft = isValue(config.axis_x_padding.left) ? config.axis_x_padding.left : padding;
  6565. paddingRight = isValue(config.axis_x_padding.right) ? config.axis_x_padding.right : padding;
  6566. } else if (typeof config.axis_x_padding === 'number') {
  6567. paddingLeft = paddingRight = config.axis_x_padding;
  6568. } else {
  6569. paddingLeft = paddingRight = padding;
  6570. }
  6571. return {
  6572. left: paddingLeft,
  6573. right: paddingRight
  6574. };
  6575. };
  6576. ChartInternal.prototype.getXDomain = function (targets) {
  6577. var $$ = this,
  6578. xDomain = [$$.getXDomainMin(targets), $$.getXDomainMax(targets)],
  6579. firstX = xDomain[0],
  6580. lastX = xDomain[1],
  6581. padding = $$.getXDomainPadding(xDomain),
  6582. min = 0,
  6583. max = 0; // show center of x domain if min and max are the same
  6584. if (firstX - lastX === 0 && !$$.isCategorized()) {
  6585. if ($$.isTimeSeries()) {
  6586. firstX = new Date(firstX.getTime() * 0.5);
  6587. lastX = new Date(lastX.getTime() * 1.5);
  6588. } else {
  6589. firstX = firstX === 0 ? 1 : firstX * 0.5;
  6590. lastX = lastX === 0 ? -1 : lastX * 1.5;
  6591. }
  6592. }
  6593. if (firstX || firstX === 0) {
  6594. min = $$.isTimeSeries() ? new Date(firstX.getTime() - padding.left) : firstX - padding.left;
  6595. }
  6596. if (lastX || lastX === 0) {
  6597. max = $$.isTimeSeries() ? new Date(lastX.getTime() + padding.right) : lastX + padding.right;
  6598. }
  6599. return [min, max];
  6600. };
  6601. ChartInternal.prototype.updateXDomain = function (targets, withUpdateXDomain, withUpdateOrgXDomain, withTrim, domain) {
  6602. var $$ = this,
  6603. config = $$.config;
  6604. if (withUpdateOrgXDomain) {
  6605. $$.x.domain(domain ? domain : $$.d3.extent($$.getXDomain(targets)));
  6606. $$.orgXDomain = $$.x.domain();
  6607. if (config.zoom_enabled) {
  6608. $$.zoom.update();
  6609. }
  6610. $$.subX.domain($$.x.domain());
  6611. if ($$.brush) {
  6612. $$.brush.updateScale($$.subX);
  6613. }
  6614. }
  6615. if (withUpdateXDomain) {
  6616. $$.x.domain(domain ? domain : !$$.brush || $$.brush.empty() ? $$.orgXDomain : $$.brush.selectionAsValue());
  6617. } // Trim domain when too big by zoom mousemove event
  6618. if (withTrim) {
  6619. $$.x.domain($$.trimXDomain($$.x.orgDomain()));
  6620. }
  6621. return $$.x.domain();
  6622. };
  6623. ChartInternal.prototype.trimXDomain = function (domain) {
  6624. var zoomDomain = this.getZoomDomain(),
  6625. min = zoomDomain[0],
  6626. max = zoomDomain[1];
  6627. if (domain[0] <= min) {
  6628. domain[1] = +domain[1] + (min - domain[0]);
  6629. domain[0] = min;
  6630. }
  6631. if (max <= domain[1]) {
  6632. domain[0] = +domain[0] - (domain[1] - max);
  6633. domain[1] = max;
  6634. }
  6635. return domain;
  6636. };
  6637. ChartInternal.prototype.drag = function (mouse) {
  6638. var $$ = this,
  6639. config = $$.config,
  6640. main = $$.main,
  6641. d3 = $$.d3;
  6642. var sx, sy, mx, my, minX, maxX, minY, maxY;
  6643. if ($$.hasArcType()) {
  6644. return;
  6645. }
  6646. if (!config.data_selection_enabled) {
  6647. return;
  6648. } // do nothing if not selectable
  6649. if (!config.data_selection_multiple) {
  6650. return;
  6651. } // skip when single selection because drag is used for multiple selection
  6652. sx = $$.dragStart[0];
  6653. sy = $$.dragStart[1];
  6654. mx = mouse[0];
  6655. my = mouse[1];
  6656. minX = Math.min(sx, mx);
  6657. maxX = Math.max(sx, mx);
  6658. minY = config.data_selection_grouped ? $$.margin.top : Math.min(sy, my);
  6659. maxY = config.data_selection_grouped ? $$.height : Math.max(sy, my);
  6660. main.select('.' + CLASS.dragarea).attr('x', minX).attr('y', minY).attr('width', maxX - minX).attr('height', maxY - minY); // TODO: binary search when multiple xs
  6661. main.selectAll('.' + CLASS.shapes).selectAll('.' + CLASS.shape).filter(function (d) {
  6662. return config.data_selection_isselectable(d);
  6663. }).each(function (d, i) {
  6664. var shape = d3.select(this),
  6665. isSelected = shape.classed(CLASS.SELECTED),
  6666. isIncluded = shape.classed(CLASS.INCLUDED),
  6667. _x,
  6668. _y,
  6669. _w,
  6670. _h,
  6671. toggle,
  6672. isWithin = false,
  6673. box;
  6674. if (shape.classed(CLASS.circle)) {
  6675. _x = shape.attr("cx") * 1;
  6676. _y = shape.attr("cy") * 1;
  6677. toggle = $$.togglePoint;
  6678. isWithin = minX < _x && _x < maxX && minY < _y && _y < maxY;
  6679. } else if (shape.classed(CLASS.bar)) {
  6680. box = getPathBox(this);
  6681. _x = box.x;
  6682. _y = box.y;
  6683. _w = box.width;
  6684. _h = box.height;
  6685. toggle = $$.togglePath;
  6686. isWithin = !(maxX < _x || _x + _w < minX) && !(maxY < _y || _y + _h < minY);
  6687. } else {
  6688. // line/area selection not supported yet
  6689. return;
  6690. }
  6691. if (isWithin ^ isIncluded) {
  6692. shape.classed(CLASS.INCLUDED, !isIncluded); // TODO: included/unincluded callback here
  6693. shape.classed(CLASS.SELECTED, !isSelected);
  6694. toggle.call($$, !isSelected, shape, d, i);
  6695. }
  6696. });
  6697. };
  6698. ChartInternal.prototype.dragstart = function (mouse) {
  6699. var $$ = this,
  6700. config = $$.config;
  6701. if ($$.hasArcType()) {
  6702. return;
  6703. }
  6704. if (!config.data_selection_enabled) {
  6705. return;
  6706. } // do nothing if not selectable
  6707. $$.dragStart = mouse;
  6708. $$.main.select('.' + CLASS.chart).append('rect').attr('class', CLASS.dragarea).style('opacity', 0.1);
  6709. $$.dragging = true;
  6710. };
  6711. ChartInternal.prototype.dragend = function () {
  6712. var $$ = this,
  6713. config = $$.config;
  6714. if ($$.hasArcType()) {
  6715. return;
  6716. }
  6717. if (!config.data_selection_enabled) {
  6718. return;
  6719. } // do nothing if not selectable
  6720. $$.main.select('.' + CLASS.dragarea).transition().duration(100).style('opacity', 0).remove();
  6721. $$.main.selectAll('.' + CLASS.shape).classed(CLASS.INCLUDED, false);
  6722. $$.dragging = false;
  6723. };
  6724. ChartInternal.prototype.getYFormat = function (forArc) {
  6725. var $$ = this,
  6726. formatForY = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.yFormat,
  6727. formatForY2 = forArc && !$$.hasType('gauge') ? $$.defaultArcValueFormat : $$.y2Format;
  6728. return function (v, ratio, id) {
  6729. var format = $$.axis.getId(id) === 'y2' ? formatForY2 : formatForY;
  6730. return format.call($$, v, ratio);
  6731. };
  6732. };
  6733. ChartInternal.prototype.yFormat = function (v) {
  6734. var $$ = this,
  6735. config = $$.config,
  6736. format = config.axis_y_tick_format ? config.axis_y_tick_format : $$.defaultValueFormat;
  6737. return format(v);
  6738. };
  6739. ChartInternal.prototype.y2Format = function (v) {
  6740. var $$ = this,
  6741. config = $$.config,
  6742. format = config.axis_y2_tick_format ? config.axis_y2_tick_format : $$.defaultValueFormat;
  6743. return format(v);
  6744. };
  6745. ChartInternal.prototype.defaultValueFormat = function (v) {
  6746. return isValue(v) ? +v : "";
  6747. };
  6748. ChartInternal.prototype.defaultArcValueFormat = function (v, ratio) {
  6749. return (ratio * 100).toFixed(1) + '%';
  6750. };
  6751. ChartInternal.prototype.dataLabelFormat = function (targetId) {
  6752. var $$ = this,
  6753. data_labels = $$.config.data_labels,
  6754. format,
  6755. defaultFormat = function defaultFormat(v) {
  6756. return isValue(v) ? +v : "";
  6757. }; // find format according to axis id
  6758. if (typeof data_labels.format === 'function') {
  6759. format = data_labels.format;
  6760. } else if (_typeof(data_labels.format) === 'object') {
  6761. if (data_labels.format[targetId]) {
  6762. format = data_labels.format[targetId] === true ? defaultFormat : data_labels.format[targetId];
  6763. } else {
  6764. format = function format() {
  6765. return '';
  6766. };
  6767. }
  6768. } else {
  6769. format = defaultFormat;
  6770. }
  6771. return format;
  6772. };
  6773. ChartInternal.prototype.initGrid = function () {
  6774. var $$ = this,
  6775. config = $$.config,
  6776. d3 = $$.d3;
  6777. $$.grid = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid);
  6778. if (config.grid_x_show) {
  6779. $$.grid.append("g").attr("class", CLASS.xgrids);
  6780. }
  6781. if (config.grid_y_show) {
  6782. $$.grid.append('g').attr('class', CLASS.ygrids);
  6783. }
  6784. if (config.grid_focus_show) {
  6785. $$.grid.append('g').attr("class", CLASS.xgridFocus).append('line').attr('class', CLASS.xgridFocus);
  6786. }
  6787. $$.xgrid = d3.selectAll([]);
  6788. if (!config.grid_lines_front) {
  6789. $$.initGridLines();
  6790. }
  6791. };
  6792. ChartInternal.prototype.initGridLines = function () {
  6793. var $$ = this,
  6794. d3 = $$.d3;
  6795. $$.gridLines = $$.main.append('g').attr("clip-path", $$.clipPathForGrid).attr('class', CLASS.grid + ' ' + CLASS.gridLines);
  6796. $$.gridLines.append('g').attr("class", CLASS.xgridLines);
  6797. $$.gridLines.append('g').attr('class', CLASS.ygridLines);
  6798. $$.xgridLines = d3.selectAll([]);
  6799. };
  6800. ChartInternal.prototype.updateXGrid = function (withoutUpdate) {
  6801. var $$ = this,
  6802. config = $$.config,
  6803. d3 = $$.d3,
  6804. xgridData = $$.generateGridData(config.grid_x_type, $$.x),
  6805. tickOffset = $$.isCategorized() ? $$.xAxis.tickOffset() : 0;
  6806. $$.xgridAttr = config.axis_rotated ? {
  6807. 'x1': 0,
  6808. 'x2': $$.width,
  6809. 'y1': function y1(d) {
  6810. return $$.x(d) - tickOffset;
  6811. },
  6812. 'y2': function y2(d) {
  6813. return $$.x(d) - tickOffset;
  6814. }
  6815. } : {
  6816. 'x1': function x1(d) {
  6817. return $$.x(d) + tickOffset;
  6818. },
  6819. 'x2': function x2(d) {
  6820. return $$.x(d) + tickOffset;
  6821. },
  6822. 'y1': 0,
  6823. 'y2': $$.height
  6824. };
  6825. $$.xgridAttr.opacity = function () {
  6826. var pos = +d3.select(this).attr(config.axis_rotated ? 'y1' : 'x1');
  6827. return pos === (config.axis_rotated ? $$.height : 0) ? 0 : 1;
  6828. };
  6829. var xgrid = $$.main.select('.' + CLASS.xgrids).selectAll('.' + CLASS.xgrid).data(xgridData);
  6830. var xgridEnter = xgrid.enter().append('line').attr("class", CLASS.xgrid).attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", 0);
  6831. $$.xgrid = xgridEnter.merge(xgrid);
  6832. if (!withoutUpdate) {
  6833. $$.xgrid.attr('x1', $$.xgridAttr.x1).attr('x2', $$.xgridAttr.x2).attr('y1', $$.xgridAttr.y1).attr('y2', $$.xgridAttr.y2).style("opacity", $$.xgridAttr.opacity);
  6834. }
  6835. xgrid.exit().remove();
  6836. };
  6837. ChartInternal.prototype.updateYGrid = function () {
  6838. var $$ = this,
  6839. config = $$.config,
  6840. gridValues = $$.yAxis.tickValues() || $$.y.ticks(config.grid_y_ticks);
  6841. var ygrid = $$.main.select('.' + CLASS.ygrids).selectAll('.' + CLASS.ygrid).data(gridValues);
  6842. var ygridEnter = ygrid.enter().append('line') // TODO: x1, x2, y1, y2, opacity need to be set here maybe
  6843. .attr('class', CLASS.ygrid);
  6844. $$.ygrid = ygridEnter.merge(ygrid);
  6845. $$.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);
  6846. ygrid.exit().remove();
  6847. $$.smoothLines($$.ygrid, 'grid');
  6848. };
  6849. ChartInternal.prototype.gridTextAnchor = function (d) {
  6850. return d.position ? d.position : "end";
  6851. };
  6852. ChartInternal.prototype.gridTextDx = function (d) {
  6853. return d.position === 'start' ? 4 : d.position === 'middle' ? 0 : -4;
  6854. };
  6855. ChartInternal.prototype.xGridTextX = function (d) {
  6856. return d.position === 'start' ? -this.height : d.position === 'middle' ? -this.height / 2 : 0;
  6857. };
  6858. ChartInternal.prototype.yGridTextX = function (d) {
  6859. return d.position === 'start' ? 0 : d.position === 'middle' ? this.width / 2 : this.width;
  6860. };
  6861. ChartInternal.prototype.updateGrid = function (duration) {
  6862. var $$ = this,
  6863. main = $$.main,
  6864. config = $$.config,
  6865. xgridLine,
  6866. xgridLineEnter,
  6867. ygridLine,
  6868. ygridLineEnter,
  6869. xv = $$.xv.bind($$),
  6870. yv = $$.yv.bind($$),
  6871. xGridTextX = $$.xGridTextX.bind($$),
  6872. yGridTextX = $$.yGridTextX.bind($$); // hide if arc type
  6873. $$.grid.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  6874. main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  6875. if (config.grid_x_show) {
  6876. $$.updateXGrid();
  6877. }
  6878. xgridLine = main.select('.' + CLASS.xgridLines).selectAll('.' + CLASS.xgridLine).data(config.grid_x_lines); // enter
  6879. xgridLineEnter = xgridLine.enter().append('g').attr("class", function (d) {
  6880. return CLASS.xgridLine + (d['class'] ? ' ' + d['class'] : '');
  6881. });
  6882. xgridLineEnter.append('line').attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 0);
  6883. xgridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "" : "rotate(-90)").attr("x", config.axis_rotated ? yGridTextX : xGridTextX).attr("y", xv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // udpate
  6884. $$.xgridLines = xgridLineEnter.merge(xgridLine); // done in d3.transition() of the end of this function
  6885. // exit
  6886. xgridLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Y-Grid
  6887. if (config.grid_y_show) {
  6888. $$.updateYGrid();
  6889. }
  6890. ygridLine = main.select('.' + CLASS.ygridLines).selectAll('.' + CLASS.ygridLine).data(config.grid_y_lines); // enter
  6891. ygridLineEnter = ygridLine.enter().append('g').attr("class", function (d) {
  6892. return CLASS.ygridLine + (d['class'] ? ' ' + d['class'] : '');
  6893. });
  6894. ygridLineEnter.append('line').attr("x1", config.axis_rotated ? yv : 0).attr("x2", config.axis_rotated ? yv : $$.width).attr("y1", config.axis_rotated ? 0 : yv).attr("y2", config.axis_rotated ? $$.height : yv).style("opacity", 0);
  6895. ygridLineEnter.append('text').attr("text-anchor", $$.gridTextAnchor).attr("transform", config.axis_rotated ? "rotate(-90)" : "").attr("x", config.axis_rotated ? xGridTextX : yGridTextX).attr("y", yv).attr('dx', $$.gridTextDx).attr('dy', -5).style("opacity", 0); // update
  6896. $$.ygridLines = ygridLineEnter.merge(ygridLine);
  6897. $$.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);
  6898. $$.ygridLines.select('text').transition().duration(duration).attr("x", config.axis_rotated ? $$.xGridTextX.bind($$) : $$.yGridTextX.bind($$)).attr("y", yv).text(function (d) {
  6899. return d.text;
  6900. }).style("opacity", 1); // exit
  6901. ygridLine.exit().transition().duration(duration).style("opacity", 0).remove();
  6902. };
  6903. ChartInternal.prototype.redrawGrid = function (withTransition, transition) {
  6904. var $$ = this,
  6905. config = $$.config,
  6906. xv = $$.xv.bind($$),
  6907. lines = $$.xgridLines.select('line'),
  6908. texts = $$.xgridLines.select('text');
  6909. return [(withTransition ? lines.transition(transition) : lines).attr("x1", config.axis_rotated ? 0 : xv).attr("x2", config.axis_rotated ? $$.width : xv).attr("y1", config.axis_rotated ? xv : 0).attr("y2", config.axis_rotated ? xv : $$.height).style("opacity", 1), (withTransition ? texts.transition(transition) : texts).attr("x", config.axis_rotated ? $$.yGridTextX.bind($$) : $$.xGridTextX.bind($$)).attr("y", xv).text(function (d) {
  6910. return d.text;
  6911. }).style("opacity", 1)];
  6912. };
  6913. ChartInternal.prototype.showXGridFocus = function (selectedData) {
  6914. var $$ = this,
  6915. config = $$.config,
  6916. dataToShow = selectedData.filter(function (d) {
  6917. return d && isValue(d.value);
  6918. }),
  6919. focusEl = $$.main.selectAll('line.' + CLASS.xgridFocus),
  6920. xx = $$.xx.bind($$);
  6921. if (!config.tooltip_show) {
  6922. return;
  6923. } // Hide when scatter plot exists
  6924. if ($$.hasType('scatter') || $$.hasType('stanford') || $$.hasArcType()) {
  6925. return;
  6926. }
  6927. focusEl.style("visibility", "visible").data([dataToShow[0]]).attr(config.axis_rotated ? 'y1' : 'x1', xx).attr(config.axis_rotated ? 'y2' : 'x2', xx);
  6928. $$.smoothLines(focusEl, 'grid');
  6929. };
  6930. ChartInternal.prototype.hideXGridFocus = function () {
  6931. this.main.select('line.' + CLASS.xgridFocus).style("visibility", "hidden");
  6932. };
  6933. ChartInternal.prototype.updateXgridFocus = function () {
  6934. var $$ = this,
  6935. config = $$.config;
  6936. $$.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);
  6937. };
  6938. ChartInternal.prototype.generateGridData = function (type, scale) {
  6939. var $$ = this,
  6940. gridData = [],
  6941. xDomain,
  6942. firstYear,
  6943. lastYear,
  6944. i,
  6945. tickNum = $$.main.select("." + CLASS.axisX).selectAll('.tick').size();
  6946. if (type === 'year') {
  6947. xDomain = $$.getXDomain();
  6948. firstYear = xDomain[0].getFullYear();
  6949. lastYear = xDomain[1].getFullYear();
  6950. for (i = firstYear; i <= lastYear; i++) {
  6951. gridData.push(new Date(i + '-01-01 00:00:00'));
  6952. }
  6953. } else {
  6954. gridData = scale.ticks(10);
  6955. if (gridData.length > tickNum) {
  6956. // use only int
  6957. gridData = gridData.filter(function (d) {
  6958. return ("" + d).indexOf('.') < 0;
  6959. });
  6960. }
  6961. }
  6962. return gridData;
  6963. };
  6964. ChartInternal.prototype.getGridFilterToRemove = function (params) {
  6965. return params ? function (line) {
  6966. var found = false;
  6967. [].concat(params).forEach(function (param) {
  6968. if ('value' in param && line.value === param.value || 'class' in param && line['class'] === param['class']) {
  6969. found = true;
  6970. }
  6971. });
  6972. return found;
  6973. } : function () {
  6974. return true;
  6975. };
  6976. };
  6977. ChartInternal.prototype.removeGridLines = function (params, forX) {
  6978. var $$ = this,
  6979. config = $$.config,
  6980. toRemove = $$.getGridFilterToRemove(params),
  6981. toShow = function toShow(line) {
  6982. return !toRemove(line);
  6983. },
  6984. classLines = forX ? CLASS.xgridLines : CLASS.ygridLines,
  6985. classLine = forX ? CLASS.xgridLine : CLASS.ygridLine;
  6986. $$.main.select('.' + classLines).selectAll('.' + classLine).filter(toRemove).transition().duration(config.transition_duration).style('opacity', 0).remove();
  6987. if (forX) {
  6988. config.grid_x_lines = config.grid_x_lines.filter(toShow);
  6989. } else {
  6990. config.grid_y_lines = config.grid_y_lines.filter(toShow);
  6991. }
  6992. };
  6993. ChartInternal.prototype.initEventRect = function () {
  6994. var $$ = this,
  6995. config = $$.config;
  6996. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.eventRects).style('fill-opacity', 0);
  6997. $$.eventRect = $$.main.select('.' + CLASS.eventRects).append('rect').attr('class', CLASS.eventRect); // event rect handle zoom event as well
  6998. if (config.zoom_enabled && $$.zoom) {
  6999. $$.eventRect.call($$.zoom).on("dblclick.zoom", null);
  7000. if (config.zoom_initialRange) {
  7001. // WORKAROUND: Add transition to apply transform immediately when no subchart
  7002. $$.eventRect.transition().duration(0).call($$.zoom.transform, $$.zoomTransform(config.zoom_initialRange));
  7003. }
  7004. }
  7005. };
  7006. ChartInternal.prototype.redrawEventRect = function () {
  7007. var $$ = this,
  7008. d3 = $$.d3,
  7009. config = $$.config,
  7010. x,
  7011. y,
  7012. w,
  7013. h; // TODO: rotated not supported yet
  7014. x = 0;
  7015. y = 0;
  7016. w = $$.width;
  7017. h = $$.height;
  7018. function mouseout() {
  7019. $$.svg.select('.' + CLASS.eventRect).style('cursor', null);
  7020. $$.hideXGridFocus();
  7021. $$.hideTooltip();
  7022. $$.unexpandCircles();
  7023. $$.unexpandBars();
  7024. } // rects for mouseover
  7025. $$.main.select('.' + CLASS.eventRects).style('cursor', config.zoom_enabled ? config.axis_rotated ? 'ns-resize' : 'ew-resize' : null);
  7026. $$.eventRect.attr('x', x).attr('y', y).attr('width', w).attr('height', h).on('mouseout', config.interaction_enabled ? function () {
  7027. if (!config) {
  7028. return;
  7029. } // chart is destroyed
  7030. if ($$.hasArcType()) {
  7031. return;
  7032. }
  7033. mouseout();
  7034. } : null).on('mousemove', config.interaction_enabled ? function () {
  7035. var targetsToShow, mouse, closest, sameXData, selectedData;
  7036. if ($$.dragging) {
  7037. return;
  7038. } // do nothing when dragging
  7039. if ($$.hasArcType(targetsToShow)) {
  7040. return;
  7041. }
  7042. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  7043. mouse = d3.mouse(this);
  7044. closest = $$.findClosestFromTargets(targetsToShow, mouse);
  7045. if ($$.mouseover && (!closest || closest.id !== $$.mouseover.id)) {
  7046. config.data_onmouseout.call($$.api, $$.mouseover);
  7047. $$.mouseover = undefined;
  7048. }
  7049. if (!closest) {
  7050. mouseout();
  7051. return;
  7052. }
  7053. if ($$.isScatterOrStanfordType(closest) || !config.tooltip_grouped) {
  7054. sameXData = [closest];
  7055. } else {
  7056. sameXData = $$.filterByX(targetsToShow, closest.x);
  7057. } // show tooltip when cursor is close to some point
  7058. selectedData = sameXData.map(function (d) {
  7059. return $$.addName(d);
  7060. });
  7061. $$.showTooltip(selectedData, this); // expand points
  7062. if (config.point_focus_expand_enabled) {
  7063. $$.unexpandCircles();
  7064. selectedData.forEach(function (d) {
  7065. $$.expandCircles(d.index, d.id, false);
  7066. });
  7067. }
  7068. $$.expandBars(closest.index, closest.id, true); // Show xgrid focus line
  7069. $$.showXGridFocus(selectedData); // Show cursor as pointer if point is close to mouse position
  7070. if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
  7071. $$.svg.select('.' + CLASS.eventRect).style('cursor', 'pointer');
  7072. if (!$$.mouseover) {
  7073. config.data_onmouseover.call($$.api, closest);
  7074. $$.mouseover = closest;
  7075. }
  7076. }
  7077. } : null).on('click', config.interaction_enabled ? function () {
  7078. var targetsToShow, mouse, closest, sameXData;
  7079. if ($$.hasArcType(targetsToShow)) {
  7080. return;
  7081. }
  7082. targetsToShow = $$.filterTargetsToShow($$.data.targets);
  7083. mouse = d3.mouse(this);
  7084. closest = $$.findClosestFromTargets(targetsToShow, mouse);
  7085. if (!closest) {
  7086. return;
  7087. } // select if selection enabled
  7088. if ($$.isBarType(closest.id) || $$.dist(closest, mouse) < config.point_sensitivity) {
  7089. if ($$.isScatterOrStanfordType(closest) || !config.data_selection_grouped) {
  7090. sameXData = [closest];
  7091. } else {
  7092. sameXData = $$.filterByX(targetsToShow, closest.x);
  7093. }
  7094. sameXData.forEach(function (d) {
  7095. $$.main.selectAll('.' + CLASS.shapes + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.shape + '-' + d.index).each(function () {
  7096. if (config.data_selection_grouped || $$.isWithinShape(this, d)) {
  7097. $$.toggleShape(this, d, d.index);
  7098. config.data_onclick.call($$.api, d, this);
  7099. }
  7100. });
  7101. });
  7102. }
  7103. } : null).call(config.interaction_enabled && config.data_selection_draggable && $$.drag ? d3.drag().on('drag', function () {
  7104. $$.drag(d3.mouse(this));
  7105. }).on('start', function () {
  7106. $$.dragstart(d3.mouse(this));
  7107. }).on('end', function () {
  7108. $$.dragend();
  7109. }) : function () {});
  7110. };
  7111. ChartInternal.prototype.getMousePosition = function (data) {
  7112. var $$ = this;
  7113. return [$$.x(data.x), $$.getYScale(data.id)(data.value)];
  7114. };
  7115. ChartInternal.prototype.dispatchEvent = function (type, mouse) {
  7116. var $$ = this,
  7117. selector = '.' + CLASS.eventRect,
  7118. eventRect = $$.main.select(selector).node(),
  7119. box = eventRect.getBoundingClientRect(),
  7120. x = box.left + (mouse ? mouse[0] : 0),
  7121. y = box.top + (mouse ? mouse[1] : 0),
  7122. event = document.createEvent("MouseEvents");
  7123. event.initMouseEvent(type, true, true, window, 0, x, y, x, y, false, false, false, false, 0, null);
  7124. eventRect.dispatchEvent(event);
  7125. };
  7126. ChartInternal.prototype.initLegend = function () {
  7127. var $$ = this;
  7128. $$.legendItemTextBox = {};
  7129. $$.legendHasRendered = false;
  7130. $$.legend = $$.svg.append("g").attr("transform", $$.getTranslate('legend'));
  7131. if (!$$.config.legend_show) {
  7132. $$.legend.style('visibility', 'hidden');
  7133. $$.hiddenLegendIds = $$.mapToIds($$.data.targets);
  7134. return;
  7135. } // MEMO: call here to update legend box and tranlate for all
  7136. // MEMO: translate will be upated by this, so transform not needed in updateLegend()
  7137. $$.updateLegendWithDefaults();
  7138. };
  7139. ChartInternal.prototype.updateLegendWithDefaults = function () {
  7140. var $$ = this;
  7141. $$.updateLegend($$.mapToIds($$.data.targets), {
  7142. withTransform: false,
  7143. withTransitionForTransform: false,
  7144. withTransition: false
  7145. });
  7146. };
  7147. ChartInternal.prototype.updateSizeForLegend = function (legendHeight, legendWidth) {
  7148. var $$ = this,
  7149. config = $$.config,
  7150. insetLegendPosition = {
  7151. top: $$.isLegendTop ? $$.getCurrentPaddingTop() + config.legend_inset_y + 5.5 : $$.currentHeight - legendHeight - $$.getCurrentPaddingBottom() - config.legend_inset_y,
  7152. left: $$.isLegendLeft ? $$.getCurrentPaddingLeft() + config.legend_inset_x + 0.5 : $$.currentWidth - legendWidth - $$.getCurrentPaddingRight() - config.legend_inset_x + 0.5
  7153. };
  7154. $$.margin3 = {
  7155. top: $$.isLegendRight ? 0 : $$.isLegendInset ? insetLegendPosition.top : $$.currentHeight - legendHeight,
  7156. right: NaN,
  7157. bottom: 0,
  7158. left: $$.isLegendRight ? $$.currentWidth - legendWidth : $$.isLegendInset ? insetLegendPosition.left : 0
  7159. };
  7160. };
  7161. ChartInternal.prototype.transformLegend = function (withTransition) {
  7162. var $$ = this;
  7163. (withTransition ? $$.legend.transition() : $$.legend).attr("transform", $$.getTranslate('legend'));
  7164. };
  7165. ChartInternal.prototype.updateLegendStep = function (step) {
  7166. this.legendStep = step;
  7167. };
  7168. ChartInternal.prototype.updateLegendItemWidth = function (w) {
  7169. this.legendItemWidth = w;
  7170. };
  7171. ChartInternal.prototype.updateLegendItemHeight = function (h) {
  7172. this.legendItemHeight = h;
  7173. };
  7174. ChartInternal.prototype.getLegendWidth = function () {
  7175. var $$ = this;
  7176. return $$.config.legend_show ? $$.isLegendRight || $$.isLegendInset ? $$.legendItemWidth * ($$.legendStep + 1) : $$.currentWidth : 0;
  7177. };
  7178. ChartInternal.prototype.getLegendHeight = function () {
  7179. var $$ = this,
  7180. h = 0;
  7181. if ($$.config.legend_show) {
  7182. if ($$.isLegendRight) {
  7183. h = $$.currentHeight;
  7184. } else {
  7185. h = Math.max(20, $$.legendItemHeight) * ($$.legendStep + 1);
  7186. }
  7187. }
  7188. return h;
  7189. };
  7190. ChartInternal.prototype.opacityForLegend = function (legendItem) {
  7191. return legendItem.classed(CLASS.legendItemHidden) ? null : 1;
  7192. };
  7193. ChartInternal.prototype.opacityForUnfocusedLegend = function (legendItem) {
  7194. return legendItem.classed(CLASS.legendItemHidden) ? null : 0.3;
  7195. };
  7196. ChartInternal.prototype.toggleFocusLegend = function (targetIds, focus) {
  7197. var $$ = this;
  7198. targetIds = $$.mapToTargetIds(targetIds);
  7199. $$.legend.selectAll('.' + CLASS.legendItem).filter(function (id) {
  7200. return targetIds.indexOf(id) >= 0;
  7201. }).classed(CLASS.legendItemFocused, focus).transition().duration(100).style('opacity', function () {
  7202. var opacity = focus ? $$.opacityForLegend : $$.opacityForUnfocusedLegend;
  7203. return opacity.call($$, $$.d3.select(this));
  7204. });
  7205. };
  7206. ChartInternal.prototype.revertLegend = function () {
  7207. var $$ = this,
  7208. d3 = $$.d3;
  7209. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemFocused, false).transition().duration(100).style('opacity', function () {
  7210. return $$.opacityForLegend(d3.select(this));
  7211. });
  7212. };
  7213. ChartInternal.prototype.showLegend = function (targetIds) {
  7214. var $$ = this,
  7215. config = $$.config;
  7216. if (!config.legend_show) {
  7217. config.legend_show = true;
  7218. $$.legend.style('visibility', 'visible');
  7219. if (!$$.legendHasRendered) {
  7220. $$.updateLegendWithDefaults();
  7221. }
  7222. }
  7223. $$.removeHiddenLegendIds(targetIds);
  7224. $$.legend.selectAll($$.selectorLegends(targetIds)).style('visibility', 'visible').transition().style('opacity', function () {
  7225. return $$.opacityForLegend($$.d3.select(this));
  7226. });
  7227. };
  7228. ChartInternal.prototype.hideLegend = function (targetIds) {
  7229. var $$ = this,
  7230. config = $$.config;
  7231. if (config.legend_show && isEmpty(targetIds)) {
  7232. config.legend_show = false;
  7233. $$.legend.style('visibility', 'hidden');
  7234. }
  7235. $$.addHiddenLegendIds(targetIds);
  7236. $$.legend.selectAll($$.selectorLegends(targetIds)).style('opacity', 0).style('visibility', 'hidden');
  7237. };
  7238. ChartInternal.prototype.clearLegendItemTextBoxCache = function () {
  7239. this.legendItemTextBox = {};
  7240. };
  7241. ChartInternal.prototype.updateLegend = function (targetIds, options, transitions) {
  7242. var $$ = this,
  7243. config = $$.config;
  7244. var xForLegend, xForLegendText, xForLegendRect, yForLegend, yForLegendText, yForLegendRect, x1ForLegendTile, x2ForLegendTile, yForLegendTile;
  7245. var paddingTop = 4,
  7246. paddingRight = 10,
  7247. maxWidth = 0,
  7248. maxHeight = 0,
  7249. posMin = 10,
  7250. tileWidth = config.legend_item_tile_width + 5;
  7251. var l,
  7252. totalLength = 0,
  7253. offsets = {},
  7254. widths = {},
  7255. heights = {},
  7256. margins = [0],
  7257. steps = {},
  7258. step = 0;
  7259. var withTransition, withTransitionForTransform;
  7260. var texts, rects, tiles, background; // Skip elements when their name is set to null
  7261. targetIds = targetIds.filter(function (id) {
  7262. return !isDefined(config.data_names[id]) || config.data_names[id] !== null;
  7263. });
  7264. options = options || {};
  7265. withTransition = getOption(options, "withTransition", true);
  7266. withTransitionForTransform = getOption(options, "withTransitionForTransform", true);
  7267. function getTextBox(textElement, id) {
  7268. if (!$$.legendItemTextBox[id]) {
  7269. $$.legendItemTextBox[id] = $$.getTextRect(textElement.textContent, CLASS.legendItem, textElement);
  7270. }
  7271. return $$.legendItemTextBox[id];
  7272. }
  7273. function updatePositions(textElement, id, index) {
  7274. var reset = index === 0,
  7275. isLast = index === targetIds.length - 1,
  7276. box = getTextBox(textElement, id),
  7277. itemWidth = box.width + tileWidth + (isLast && !($$.isLegendRight || $$.isLegendInset) ? 0 : paddingRight) + config.legend_padding,
  7278. itemHeight = box.height + paddingTop,
  7279. itemLength = $$.isLegendRight || $$.isLegendInset ? itemHeight : itemWidth,
  7280. areaLength = $$.isLegendRight || $$.isLegendInset ? $$.getLegendHeight() : $$.getLegendWidth(),
  7281. margin,
  7282. maxLength; // MEMO: care about condifion of step, totalLength
  7283. function updateValues(id, withoutStep) {
  7284. if (!withoutStep) {
  7285. margin = (areaLength - totalLength - itemLength) / 2;
  7286. if (margin < posMin) {
  7287. margin = (areaLength - itemLength) / 2;
  7288. totalLength = 0;
  7289. step++;
  7290. }
  7291. }
  7292. steps[id] = step;
  7293. margins[step] = $$.isLegendInset ? 10 : margin;
  7294. offsets[id] = totalLength;
  7295. totalLength += itemLength;
  7296. }
  7297. if (reset) {
  7298. totalLength = 0;
  7299. step = 0;
  7300. maxWidth = 0;
  7301. maxHeight = 0;
  7302. }
  7303. if (config.legend_show && !$$.isLegendToShow(id)) {
  7304. widths[id] = heights[id] = steps[id] = offsets[id] = 0;
  7305. return;
  7306. }
  7307. widths[id] = itemWidth;
  7308. heights[id] = itemHeight;
  7309. if (!maxWidth || itemWidth >= maxWidth) {
  7310. maxWidth = itemWidth;
  7311. }
  7312. if (!maxHeight || itemHeight >= maxHeight) {
  7313. maxHeight = itemHeight;
  7314. }
  7315. maxLength = $$.isLegendRight || $$.isLegendInset ? maxHeight : maxWidth;
  7316. if (config.legend_equally) {
  7317. Object.keys(widths).forEach(function (id) {
  7318. widths[id] = maxWidth;
  7319. });
  7320. Object.keys(heights).forEach(function (id) {
  7321. heights[id] = maxHeight;
  7322. });
  7323. margin = (areaLength - maxLength * targetIds.length) / 2;
  7324. if (margin < posMin) {
  7325. totalLength = 0;
  7326. step = 0;
  7327. targetIds.forEach(function (id) {
  7328. updateValues(id);
  7329. });
  7330. } else {
  7331. updateValues(id, true);
  7332. }
  7333. } else {
  7334. updateValues(id);
  7335. }
  7336. }
  7337. if ($$.isLegendInset) {
  7338. step = config.legend_inset_step ? config.legend_inset_step : targetIds.length;
  7339. $$.updateLegendStep(step);
  7340. }
  7341. if ($$.isLegendRight) {
  7342. xForLegend = function xForLegend(id) {
  7343. return maxWidth * steps[id];
  7344. };
  7345. yForLegend = function yForLegend(id) {
  7346. return margins[steps[id]] + offsets[id];
  7347. };
  7348. } else if ($$.isLegendInset) {
  7349. xForLegend = function xForLegend(id) {
  7350. return maxWidth * steps[id] + 10;
  7351. };
  7352. yForLegend = function yForLegend(id) {
  7353. return margins[steps[id]] + offsets[id];
  7354. };
  7355. } else {
  7356. xForLegend = function xForLegend(id) {
  7357. return margins[steps[id]] + offsets[id];
  7358. };
  7359. yForLegend = function yForLegend(id) {
  7360. return maxHeight * steps[id];
  7361. };
  7362. }
  7363. xForLegendText = function xForLegendText(id, i) {
  7364. return xForLegend(id, i) + 4 + config.legend_item_tile_width;
  7365. };
  7366. yForLegendText = function yForLegendText(id, i) {
  7367. return yForLegend(id, i) + 9;
  7368. };
  7369. xForLegendRect = function xForLegendRect(id, i) {
  7370. return xForLegend(id, i);
  7371. };
  7372. yForLegendRect = function yForLegendRect(id, i) {
  7373. return yForLegend(id, i) - 5;
  7374. };
  7375. x1ForLegendTile = function x1ForLegendTile(id, i) {
  7376. return xForLegend(id, i) - 2;
  7377. };
  7378. x2ForLegendTile = function x2ForLegendTile(id, i) {
  7379. return xForLegend(id, i) - 2 + config.legend_item_tile_width;
  7380. };
  7381. yForLegendTile = function yForLegendTile(id, i) {
  7382. return yForLegend(id, i) + 4;
  7383. }; // Define g for legend area
  7384. l = $$.legend.selectAll('.' + CLASS.legendItem).data(targetIds).enter().append('g').attr('class', function (id) {
  7385. return $$.generateClass(CLASS.legendItem, id);
  7386. }).style('visibility', function (id) {
  7387. return $$.isLegendToShow(id) ? 'visible' : 'hidden';
  7388. }).style('cursor', 'pointer').on('click', function (id) {
  7389. if (config.legend_item_onclick) {
  7390. config.legend_item_onclick.call($$, id);
  7391. } else {
  7392. if ($$.d3.event.altKey) {
  7393. $$.api.hide();
  7394. $$.api.show(id);
  7395. } else {
  7396. $$.api.toggle(id);
  7397. $$.isTargetToShow(id) ? $$.api.focus(id) : $$.api.revert();
  7398. }
  7399. }
  7400. }).on('mouseover', function (id) {
  7401. if (config.legend_item_onmouseover) {
  7402. config.legend_item_onmouseover.call($$, id);
  7403. } else {
  7404. $$.d3.select(this).classed(CLASS.legendItemFocused, true);
  7405. if (!$$.transiting && $$.isTargetToShow(id)) {
  7406. $$.api.focus(id);
  7407. }
  7408. }
  7409. }).on('mouseout', function (id) {
  7410. if (config.legend_item_onmouseout) {
  7411. config.legend_item_onmouseout.call($$, id);
  7412. } else {
  7413. $$.d3.select(this).classed(CLASS.legendItemFocused, false);
  7414. $$.api.revert();
  7415. }
  7416. });
  7417. l.append('text').text(function (id) {
  7418. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  7419. }).each(function (id, i) {
  7420. updatePositions(this, id, i);
  7421. }).style("pointer-events", "none").attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendText : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendText);
  7422. l.append('rect').attr("class", CLASS.legendItemEvent).style('fill-opacity', 0).attr('x', $$.isLegendRight || $$.isLegendInset ? xForLegendRect : -200).attr('y', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendRect);
  7423. l.append('line').attr('class', CLASS.legendItemTile).style('stroke', $$.color).style("pointer-events", "none").attr('x1', $$.isLegendRight || $$.isLegendInset ? x1ForLegendTile : -200).attr('y1', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('x2', $$.isLegendRight || $$.isLegendInset ? x2ForLegendTile : -200).attr('y2', $$.isLegendRight || $$.isLegendInset ? -200 : yForLegendTile).attr('stroke-width', config.legend_item_tile_height); // Set background for inset legend
  7424. background = $$.legend.select('.' + CLASS.legendBackground + ' rect');
  7425. if ($$.isLegendInset && maxWidth > 0 && background.size() === 0) {
  7426. background = $$.legend.insert('g', '.' + CLASS.legendItem).attr("class", CLASS.legendBackground).append('rect');
  7427. }
  7428. texts = $$.legend.selectAll('text').data(targetIds).text(function (id) {
  7429. return isDefined(config.data_names[id]) ? config.data_names[id] : id;
  7430. }) // MEMO: needed for update
  7431. .each(function (id, i) {
  7432. updatePositions(this, id, i);
  7433. });
  7434. (withTransition ? texts.transition() : texts).attr('x', xForLegendText).attr('y', yForLegendText);
  7435. rects = $$.legend.selectAll('rect.' + CLASS.legendItemEvent).data(targetIds);
  7436. (withTransition ? rects.transition() : rects).attr('width', function (id) {
  7437. return widths[id];
  7438. }).attr('height', function (id) {
  7439. return heights[id];
  7440. }).attr('x', xForLegendRect).attr('y', yForLegendRect);
  7441. tiles = $$.legend.selectAll('line.' + CLASS.legendItemTile).data(targetIds);
  7442. (withTransition ? tiles.transition() : tiles).style('stroke', $$.levelColor ? function (id) {
  7443. return $$.levelColor($$.cache[id].values[0].value);
  7444. } : $$.color).attr('x1', x1ForLegendTile).attr('y1', yForLegendTile).attr('x2', x2ForLegendTile).attr('y2', yForLegendTile);
  7445. if (background) {
  7446. (withTransition ? background.transition() : background).attr('height', $$.getLegendHeight() - 12).attr('width', maxWidth * (step + 1) + 10);
  7447. } // toggle legend state
  7448. $$.legend.selectAll('.' + CLASS.legendItem).classed(CLASS.legendItemHidden, function (id) {
  7449. return !$$.isTargetToShow(id);
  7450. }); // Update all to reflect change of legend
  7451. $$.updateLegendItemWidth(maxWidth);
  7452. $$.updateLegendItemHeight(maxHeight);
  7453. $$.updateLegendStep(step); // Update size and scale
  7454. $$.updateSizes();
  7455. $$.updateScales();
  7456. $$.updateSvgSize(); // Update g positions
  7457. $$.transformAll(withTransitionForTransform, transitions);
  7458. $$.legendHasRendered = true;
  7459. };
  7460. ChartInternal.prototype.initRegion = function () {
  7461. var $$ = this;
  7462. $$.region = $$.main.append('g').attr("clip-path", $$.clipPath).attr("class", CLASS.regions);
  7463. };
  7464. ChartInternal.prototype.updateRegion = function (duration) {
  7465. var $$ = this,
  7466. config = $$.config; // hide if arc type
  7467. $$.region.style('visibility', $$.hasArcType() ? 'hidden' : 'visible');
  7468. var mainRegion = $$.main.select('.' + CLASS.regions).selectAll('.' + CLASS.region).data(config.regions);
  7469. var mainRegionEnter = mainRegion.enter().append('rect').attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", 0);
  7470. $$.mainRegion = mainRegionEnter.merge(mainRegion).attr('class', $$.classRegion.bind($$));
  7471. mainRegion.exit().transition().duration(duration).style("opacity", 0).remove();
  7472. };
  7473. ChartInternal.prototype.redrawRegion = function (withTransition, transition) {
  7474. var $$ = this,
  7475. regions = $$.mainRegion;
  7476. return [(withTransition ? regions.transition(transition) : regions).attr("x", $$.regionX.bind($$)).attr("y", $$.regionY.bind($$)).attr("width", $$.regionWidth.bind($$)).attr("height", $$.regionHeight.bind($$)).style("fill-opacity", function (d) {
  7477. return isValue(d.opacity) ? d.opacity : 0.1;
  7478. })];
  7479. };
  7480. ChartInternal.prototype.regionX = function (d) {
  7481. var $$ = this,
  7482. config = $$.config,
  7483. xPos,
  7484. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7485. if (d.axis === 'y' || d.axis === 'y2') {
  7486. xPos = config.axis_rotated ? 'start' in d ? yScale(d.start) : 0 : 0;
  7487. } else {
  7488. xPos = config.axis_rotated ? 0 : 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0;
  7489. }
  7490. return xPos;
  7491. };
  7492. ChartInternal.prototype.regionY = function (d) {
  7493. var $$ = this,
  7494. config = $$.config,
  7495. yPos,
  7496. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7497. if (d.axis === 'y' || d.axis === 'y2') {
  7498. yPos = config.axis_rotated ? 0 : 'end' in d ? yScale(d.end) : 0;
  7499. } else {
  7500. yPos = config.axis_rotated ? 'start' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.start) : d.start) : 0 : 0;
  7501. }
  7502. return yPos;
  7503. };
  7504. ChartInternal.prototype.regionWidth = function (d) {
  7505. var $$ = this,
  7506. config = $$.config,
  7507. start = $$.regionX(d),
  7508. end,
  7509. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7510. if (d.axis === 'y' || d.axis === 'y2') {
  7511. end = config.axis_rotated ? 'end' in d ? yScale(d.end) : $$.width : $$.width;
  7512. } else {
  7513. end = config.axis_rotated ? $$.width : 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.width;
  7514. }
  7515. return end < start ? 0 : end - start;
  7516. };
  7517. ChartInternal.prototype.regionHeight = function (d) {
  7518. var $$ = this,
  7519. config = $$.config,
  7520. start = this.regionY(d),
  7521. end,
  7522. yScale = d.axis === 'y' ? $$.y : $$.y2;
  7523. if (d.axis === 'y' || d.axis === 'y2') {
  7524. end = config.axis_rotated ? $$.height : 'start' in d ? yScale(d.start) : $$.height;
  7525. } else {
  7526. end = config.axis_rotated ? 'end' in d ? $$.x($$.isTimeSeries() ? $$.parseDate(d.end) : d.end) : $$.height : $$.height;
  7527. }
  7528. return end < start ? 0 : end - start;
  7529. };
  7530. ChartInternal.prototype.isRegionOnX = function (d) {
  7531. return !d.axis || d.axis === 'x';
  7532. };
  7533. ChartInternal.prototype.getScale = function (min, max, forTimeseries) {
  7534. return (forTimeseries ? this.d3.scaleTime() : this.d3.scaleLinear()).range([min, max]);
  7535. };
  7536. ChartInternal.prototype.getX = function (min, max, domain, offset) {
  7537. var $$ = this,
  7538. scale = $$.getScale(min, max, $$.isTimeSeries()),
  7539. _scale = domain ? scale.domain(domain) : scale,
  7540. key; // Define customized scale if categorized axis
  7541. if ($$.isCategorized()) {
  7542. offset = offset || function () {
  7543. return 0;
  7544. };
  7545. scale = function scale(d, raw) {
  7546. var v = _scale(d) + offset(d);
  7547. return raw ? v : Math.ceil(v);
  7548. };
  7549. } else {
  7550. scale = function scale(d, raw) {
  7551. var v = _scale(d);
  7552. return raw ? v : Math.ceil(v);
  7553. };
  7554. } // define functions
  7555. for (key in _scale) {
  7556. scale[key] = _scale[key];
  7557. }
  7558. scale.orgDomain = function () {
  7559. return _scale.domain();
  7560. }; // define custom domain() for categorized axis
  7561. if ($$.isCategorized()) {
  7562. scale.domain = function (domain) {
  7563. if (!arguments.length) {
  7564. domain = this.orgDomain();
  7565. return [domain[0], domain[1] + 1];
  7566. }
  7567. _scale.domain(domain);
  7568. return scale;
  7569. };
  7570. }
  7571. return scale;
  7572. };
  7573. ChartInternal.prototype.getY = function (min, max, domain) {
  7574. var scale = this.getScale(min, max, this.isTimeSeriesY());
  7575. if (domain) {
  7576. scale.domain(domain);
  7577. }
  7578. return scale;
  7579. };
  7580. ChartInternal.prototype.getYScale = function (id) {
  7581. return this.axis.getId(id) === 'y2' ? this.y2 : this.y;
  7582. };
  7583. ChartInternal.prototype.getSubYScale = function (id) {
  7584. return this.axis.getId(id) === 'y2' ? this.subY2 : this.subY;
  7585. };
  7586. ChartInternal.prototype.updateScales = function () {
  7587. var $$ = this,
  7588. config = $$.config,
  7589. forInit = !$$.x; // update edges
  7590. $$.xMin = config.axis_rotated ? 1 : 0;
  7591. $$.xMax = config.axis_rotated ? $$.height : $$.width;
  7592. $$.yMin = config.axis_rotated ? 0 : $$.height;
  7593. $$.yMax = config.axis_rotated ? $$.width : 1;
  7594. $$.subXMin = $$.xMin;
  7595. $$.subXMax = $$.xMax;
  7596. $$.subYMin = config.axis_rotated ? 0 : $$.height2;
  7597. $$.subYMax = config.axis_rotated ? $$.width2 : 1; // update scales
  7598. $$.x = $$.getX($$.xMin, $$.xMax, forInit ? undefined : $$.x.orgDomain(), function () {
  7599. return $$.xAxis.tickOffset();
  7600. });
  7601. $$.y = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y_default : $$.y.domain());
  7602. $$.y2 = $$.getY($$.yMin, $$.yMax, forInit ? config.axis_y2_default : $$.y2.domain());
  7603. $$.subX = $$.getX($$.xMin, $$.xMax, $$.orgXDomain, function (d) {
  7604. return d % 1 ? 0 : $$.subXAxis.tickOffset();
  7605. });
  7606. $$.subY = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y_default : $$.subY.domain());
  7607. $$.subY2 = $$.getY($$.subYMin, $$.subYMax, forInit ? config.axis_y2_default : $$.subY2.domain()); // update axes
  7608. $$.xAxisTickFormat = $$.axis.getXAxisTickFormat();
  7609. $$.xAxisTickValues = $$.axis.getXAxisTickValues();
  7610. $$.yAxisTickValues = $$.axis.getYAxisTickValues();
  7611. $$.y2AxisTickValues = $$.axis.getY2AxisTickValues();
  7612. $$.xAxis = $$.axis.getXAxis($$.x, $$.xOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  7613. $$.subXAxis = $$.axis.getXAxis($$.subX, $$.subXOrient, $$.xAxisTickFormat, $$.xAxisTickValues, config.axis_x_tick_outer);
  7614. $$.yAxis = $$.axis.getYAxis('y', $$.y, $$.yOrient, $$.yAxisTickValues, config.axis_y_tick_outer);
  7615. $$.y2Axis = $$.axis.getYAxis('y2', $$.y2, $$.y2Orient, $$.y2AxisTickValues, config.axis_y2_tick_outer); // Set initialized scales to brush and zoom
  7616. if (!forInit) {
  7617. if ($$.brush) {
  7618. $$.brush.updateScale($$.subX);
  7619. }
  7620. } // update for arc
  7621. if ($$.updateArc) {
  7622. $$.updateArc();
  7623. }
  7624. };
  7625. ChartInternal.prototype.selectPoint = function (target, d, i) {
  7626. var $$ = this,
  7627. config = $$.config,
  7628. cx = (config.axis_rotated ? $$.circleY : $$.circleX).bind($$),
  7629. cy = (config.axis_rotated ? $$.circleX : $$.circleY).bind($$),
  7630. r = $$.pointSelectR.bind($$);
  7631. config.data_onselected.call($$.api, d, target.node()); // add selected-circle on low layer g
  7632. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).data([d]).enter().append('circle').attr("class", function () {
  7633. return $$.generateClass(CLASS.selectedCircle, i);
  7634. }).attr("cx", cx).attr("cy", cy).attr("stroke", function () {
  7635. return $$.color(d);
  7636. }).attr("r", function (d) {
  7637. return $$.pointSelectR(d) * 1.4;
  7638. }).transition().duration(100).attr("r", r);
  7639. };
  7640. ChartInternal.prototype.unselectPoint = function (target, d, i) {
  7641. var $$ = this;
  7642. $$.config.data_onunselected.call($$.api, d, target.node()); // remove selected-circle from low layer g
  7643. $$.main.select('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(d.id)).selectAll('.' + CLASS.selectedCircle + '-' + i).transition().duration(100).attr('r', 0).remove();
  7644. };
  7645. ChartInternal.prototype.togglePoint = function (selected, target, d, i) {
  7646. selected ? this.selectPoint(target, d, i) : this.unselectPoint(target, d, i);
  7647. };
  7648. ChartInternal.prototype.selectPath = function (target, d) {
  7649. var $$ = this;
  7650. $$.config.data_onselected.call($$, d, target.node());
  7651. if ($$.config.interaction_brighten) {
  7652. target.transition().duration(100).style("fill", function () {
  7653. return $$.d3.rgb($$.color(d)).brighter(0.75);
  7654. });
  7655. }
  7656. };
  7657. ChartInternal.prototype.unselectPath = function (target, d) {
  7658. var $$ = this;
  7659. $$.config.data_onunselected.call($$, d, target.node());
  7660. if ($$.config.interaction_brighten) {
  7661. target.transition().duration(100).style("fill", function () {
  7662. return $$.color(d);
  7663. });
  7664. }
  7665. };
  7666. ChartInternal.prototype.togglePath = function (selected, target, d, i) {
  7667. selected ? this.selectPath(target, d, i) : this.unselectPath(target, d, i);
  7668. };
  7669. ChartInternal.prototype.getToggle = function (that, d) {
  7670. var $$ = this,
  7671. toggle;
  7672. if (that.nodeName === 'circle') {
  7673. if ($$.isStepType(d)) {
  7674. // circle is hidden in step chart, so treat as within the click area
  7675. toggle = function toggle() {}; // TODO: how to select step chart?
  7676. } else {
  7677. toggle = $$.togglePoint;
  7678. }
  7679. } else if (that.nodeName === 'path') {
  7680. toggle = $$.togglePath;
  7681. }
  7682. return toggle;
  7683. };
  7684. ChartInternal.prototype.toggleShape = function (that, d, i) {
  7685. var $$ = this,
  7686. d3 = $$.d3,
  7687. config = $$.config,
  7688. shape = d3.select(that),
  7689. isSelected = shape.classed(CLASS.SELECTED),
  7690. toggle = $$.getToggle(that, d).bind($$);
  7691. if (config.data_selection_enabled && config.data_selection_isselectable(d)) {
  7692. if (!config.data_selection_multiple) {
  7693. $$.main.selectAll('.' + CLASS.shapes + (config.data_selection_grouped ? $$.getTargetSelectorSuffix(d.id) : "")).selectAll('.' + CLASS.shape).each(function (d, i) {
  7694. var shape = d3.select(this);
  7695. if (shape.classed(CLASS.SELECTED)) {
  7696. toggle(false, shape.classed(CLASS.SELECTED, false), d, i);
  7697. }
  7698. });
  7699. }
  7700. shape.classed(CLASS.SELECTED, !isSelected);
  7701. toggle(!isSelected, shape, d, i);
  7702. }
  7703. };
  7704. ChartInternal.prototype.initBar = function () {
  7705. var $$ = this;
  7706. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars);
  7707. };
  7708. ChartInternal.prototype.updateTargetsForBar = function (targets) {
  7709. var $$ = this,
  7710. config = $$.config,
  7711. mainBars,
  7712. mainBarEnter,
  7713. classChartBar = $$.classChartBar.bind($$),
  7714. classBars = $$.classBars.bind($$),
  7715. classFocus = $$.classFocus.bind($$);
  7716. mainBars = $$.main.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets).attr('class', function (d) {
  7717. return classChartBar(d) + classFocus(d);
  7718. });
  7719. mainBarEnter = mainBars.enter().append('g').attr('class', classChartBar).style("pointer-events", "none"); // Bars for each data
  7720. mainBarEnter.append('g').attr("class", classBars).style("cursor", function (d) {
  7721. return config.data_selection_isselectable(d) ? "pointer" : null;
  7722. });
  7723. };
  7724. ChartInternal.prototype.updateBar = function (durationForExit) {
  7725. var $$ = this,
  7726. barData = $$.barData.bind($$),
  7727. classBar = $$.classBar.bind($$),
  7728. initialOpacity = $$.initialOpacity.bind($$),
  7729. color = function color(d) {
  7730. return $$.color(d.id);
  7731. };
  7732. var mainBar = $$.main.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data(barData);
  7733. var mainBarEnter = mainBar.enter().append('path').attr("class", classBar).style("stroke", color).style("fill", color);
  7734. $$.mainBar = mainBarEnter.merge(mainBar).style("opacity", initialOpacity);
  7735. mainBar.exit().transition().duration(durationForExit).style("opacity", 0);
  7736. };
  7737. ChartInternal.prototype.redrawBar = function (drawBar, withTransition, transition) {
  7738. return [(withTransition ? this.mainBar.transition(transition) : this.mainBar).attr('d', drawBar).style("stroke", this.color).style("fill", this.color).style("opacity", 1)];
  7739. };
  7740. ChartInternal.prototype.getBarW = function (axis, barTargetsNum) {
  7741. var $$ = this,
  7742. config = $$.config,
  7743. w = typeof config.bar_width === 'number' ? config.bar_width : barTargetsNum ? axis.tickInterval() * config.bar_width_ratio / barTargetsNum : 0;
  7744. return config.bar_width_max && w > config.bar_width_max ? config.bar_width_max : w;
  7745. };
  7746. ChartInternal.prototype.getBars = function (i, id) {
  7747. var $$ = this;
  7748. return (id ? $$.main.selectAll('.' + CLASS.bars + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.bar + (isValue(i) ? '-' + i : ''));
  7749. };
  7750. ChartInternal.prototype.expandBars = function (i, id, reset) {
  7751. var $$ = this;
  7752. if (reset) {
  7753. $$.unexpandBars();
  7754. }
  7755. $$.getBars(i, id).classed(CLASS.EXPANDED, true);
  7756. };
  7757. ChartInternal.prototype.unexpandBars = function (i) {
  7758. var $$ = this;
  7759. $$.getBars(i).classed(CLASS.EXPANDED, false);
  7760. };
  7761. ChartInternal.prototype.generateDrawBar = function (barIndices, isSub) {
  7762. var $$ = this,
  7763. config = $$.config,
  7764. getPoints = $$.generateGetBarPoints(barIndices, isSub);
  7765. return function (d, i) {
  7766. // 4 points that make a bar
  7767. var points = getPoints(d, i); // switch points if axis is rotated, not applicable for sub chart
  7768. var indexX = config.axis_rotated ? 1 : 0;
  7769. var indexY = config.axis_rotated ? 0 : 1;
  7770. 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';
  7771. return path;
  7772. };
  7773. };
  7774. ChartInternal.prototype.generateGetBarPoints = function (barIndices, isSub) {
  7775. var $$ = this,
  7776. axis = isSub ? $$.subXAxis : $$.xAxis,
  7777. barTargetsNum = barIndices.__max__ + 1,
  7778. barW = $$.getBarW(axis, barTargetsNum),
  7779. barX = $$.getShapeX(barW, barTargetsNum, barIndices, !!isSub),
  7780. barY = $$.getShapeY(!!isSub),
  7781. barOffset = $$.getShapeOffset($$.isBarType, barIndices, !!isSub),
  7782. barSpaceOffset = barW * ($$.config.bar_space / 2),
  7783. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  7784. return function (d, i) {
  7785. var y0 = yScale.call($$, d.id)(0),
  7786. offset = barOffset(d, i) || y0,
  7787. // offset is for stacked bar chart
  7788. posX = barX(d),
  7789. posY = barY(d); // fix posY not to overflow opposite quadrant
  7790. if ($$.config.axis_rotated) {
  7791. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  7792. posY = y0;
  7793. }
  7794. }
  7795. posY -= y0 - offset; // 4 points that make a bar
  7796. return [[posX + barSpaceOffset, offset], [posX + barSpaceOffset, posY], [posX + barW - barSpaceOffset, posY], [posX + barW - barSpaceOffset, offset]];
  7797. };
  7798. };
  7799. ChartInternal.prototype.isWithinBar = function (mouse, that) {
  7800. if (that.pathSegList.numberOfItems < 2) {
  7801. return false;
  7802. }
  7803. var box = getBBox(that),
  7804. seg0 = that.pathSegList.getItem(0),
  7805. seg1 = that.pathSegList.getItem(1),
  7806. x = Math.min(seg0.x, seg1.x),
  7807. y = Math.min(seg0.y, seg1.y),
  7808. w = box.width,
  7809. h = box.height,
  7810. offset = 2,
  7811. sx = x - offset,
  7812. ex = x + w + offset,
  7813. sy = y + h + offset,
  7814. ey = y - offset;
  7815. return sx < mouse[0] && mouse[0] < ex && ey < mouse[1] && mouse[1] < sy;
  7816. };
  7817. ChartInternal.prototype.getShapeIndices = function (typeFilter) {
  7818. var $$ = this,
  7819. config = $$.config,
  7820. indices = {},
  7821. i = 0,
  7822. j,
  7823. k;
  7824. $$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$)).forEach(function (d) {
  7825. for (j = 0; j < config.data_groups.length; j++) {
  7826. if (config.data_groups[j].indexOf(d.id) < 0) {
  7827. continue;
  7828. }
  7829. for (k = 0; k < config.data_groups[j].length; k++) {
  7830. if (config.data_groups[j][k] in indices) {
  7831. indices[d.id] = indices[config.data_groups[j][k]];
  7832. break;
  7833. }
  7834. }
  7835. }
  7836. if (isUndefined(indices[d.id])) {
  7837. indices[d.id] = i++;
  7838. }
  7839. });
  7840. indices.__max__ = i - 1;
  7841. return indices;
  7842. };
  7843. ChartInternal.prototype.getShapeX = function (offset, targetsNum, indices, isSub) {
  7844. var $$ = this,
  7845. scale = isSub ? $$.subX : $$.x;
  7846. return function (d) {
  7847. var index = d.id in indices ? indices[d.id] : 0;
  7848. return d.x || d.x === 0 ? scale(d.x) - offset * (targetsNum / 2 - index) : 0;
  7849. };
  7850. };
  7851. ChartInternal.prototype.getShapeY = function (isSub) {
  7852. var $$ = this;
  7853. return function (d) {
  7854. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id);
  7855. return scale($$.isTargetNormalized(d.id) ? $$.getRatio('index', d, true) : d.value);
  7856. };
  7857. };
  7858. ChartInternal.prototype.getShapeOffset = function (typeFilter, indices, isSub) {
  7859. var $$ = this,
  7860. targets = $$.orderTargets($$.filterTargetsToShow($$.data.targets.filter(typeFilter, $$))),
  7861. targetIds = targets.map(function (t) {
  7862. return t.id;
  7863. });
  7864. return function (d, i) {
  7865. var scale = isSub ? $$.getSubYScale(d.id) : $$.getYScale(d.id),
  7866. y0 = scale(0),
  7867. offset = y0;
  7868. targets.forEach(function (t) {
  7869. var rowValues = $$.isStepType(d) ? $$.convertValuesToStep(t.values) : t.values;
  7870. var isTargetNormalized = $$.isTargetNormalized(d.id);
  7871. var values = rowValues.map(function (v) {
  7872. return isTargetNormalized ? $$.getRatio("index", v, true) : v.value;
  7873. });
  7874. if (t.id === d.id || indices[t.id] !== indices[d.id]) {
  7875. return;
  7876. }
  7877. if (targetIds.indexOf(t.id) < targetIds.indexOf(d.id)) {
  7878. // check if the x values line up
  7879. if (isUndefined(rowValues[i]) || +rowValues[i].x !== +d.x) {
  7880. // "+" for timeseries
  7881. // if not, try to find the value that does line up
  7882. i = -1;
  7883. rowValues.forEach(function (v, j) {
  7884. var x1 = v.x.constructor === Date ? +v.x : v.x;
  7885. var x2 = d.x.constructor === Date ? +d.x : d.x;
  7886. if (x1 === x2) {
  7887. i = j;
  7888. }
  7889. });
  7890. }
  7891. if (i in rowValues && rowValues[i].value * d.value >= 0) {
  7892. offset += scale(values[i]) - y0;
  7893. }
  7894. }
  7895. });
  7896. return offset;
  7897. };
  7898. };
  7899. ChartInternal.prototype.isWithinShape = function (that, d) {
  7900. var $$ = this,
  7901. shape = $$.d3.select(that),
  7902. isWithin;
  7903. if (!$$.isTargetToShow(d.id)) {
  7904. isWithin = false;
  7905. } else if (that.nodeName === 'circle') {
  7906. isWithin = $$.isStepType(d) ? $$.isWithinStep(that, $$.getYScale(d.id)(d.value)) : $$.isWithinCircle(that, $$.pointSelectR(d) * 1.5);
  7907. } else if (that.nodeName === 'path') {
  7908. isWithin = shape.classed(CLASS.bar) ? $$.isWithinBar($$.d3.mouse(that), that) : true;
  7909. }
  7910. return isWithin;
  7911. };
  7912. ChartInternal.prototype.getInterpolate = function (d) {
  7913. var $$ = this,
  7914. d3 = $$.d3,
  7915. types = {
  7916. 'linear': d3.curveLinear,
  7917. 'linear-closed': d3.curveLinearClosed,
  7918. 'basis': d3.curveBasis,
  7919. 'basis-open': d3.curveBasisOpen,
  7920. 'basis-closed': d3.curveBasisClosed,
  7921. 'bundle': d3.curveBundle,
  7922. 'cardinal': d3.curveCardinal,
  7923. 'cardinal-open': d3.curveCardinalOpen,
  7924. 'cardinal-closed': d3.curveCardinalClosed,
  7925. 'monotone': d3.curveMonotoneX,
  7926. 'step': d3.curveStep,
  7927. 'step-before': d3.curveStepBefore,
  7928. 'step-after': d3.curveStepAfter
  7929. },
  7930. type;
  7931. if ($$.isSplineType(d)) {
  7932. type = types[$$.config.spline_interpolation_type] || types.cardinal;
  7933. } else if ($$.isStepType(d)) {
  7934. type = types[$$.config.line_step_type];
  7935. } else {
  7936. type = types.linear;
  7937. }
  7938. return type;
  7939. };
  7940. ChartInternal.prototype.initLine = function () {
  7941. var $$ = this;
  7942. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines);
  7943. };
  7944. ChartInternal.prototype.updateTargetsForLine = function (targets) {
  7945. var $$ = this,
  7946. config = $$.config,
  7947. mainLines,
  7948. mainLineEnter,
  7949. classChartLine = $$.classChartLine.bind($$),
  7950. classLines = $$.classLines.bind($$),
  7951. classAreas = $$.classAreas.bind($$),
  7952. classCircles = $$.classCircles.bind($$),
  7953. classFocus = $$.classFocus.bind($$);
  7954. mainLines = $$.main.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets).attr('class', function (d) {
  7955. return classChartLine(d) + classFocus(d);
  7956. });
  7957. mainLineEnter = mainLines.enter().append('g').attr('class', classChartLine).style('opacity', 0).style("pointer-events", "none"); // Lines for each data
  7958. mainLineEnter.append('g').attr("class", classLines); // Areas
  7959. mainLineEnter.append('g').attr('class', classAreas); // Circles for each data point on lines
  7960. mainLineEnter.append('g').attr("class", function (d) {
  7961. return $$.generateClass(CLASS.selectedCircles, d.id);
  7962. });
  7963. mainLineEnter.append('g').attr("class", classCircles).style("cursor", function (d) {
  7964. return config.data_selection_isselectable(d) ? "pointer" : null;
  7965. }); // Update date for selected circles
  7966. targets.forEach(function (t) {
  7967. $$.main.selectAll('.' + CLASS.selectedCircles + $$.getTargetSelectorSuffix(t.id)).selectAll('.' + CLASS.selectedCircle).each(function (d) {
  7968. d.value = t.values[d.index].value;
  7969. });
  7970. }); // MEMO: can not keep same color...
  7971. //mainLineUpdate.exit().remove();
  7972. };
  7973. ChartInternal.prototype.updateLine = function (durationForExit) {
  7974. var $$ = this;
  7975. var mainLine = $$.main.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  7976. var mainLineEnter = mainLine.enter().append('path').attr('class', $$.classLine.bind($$)).style("stroke", $$.color);
  7977. $$.mainLine = mainLineEnter.merge(mainLine).style("opacity", $$.initialOpacity.bind($$)).style('shape-rendering', function (d) {
  7978. return $$.isStepType(d) ? 'crispEdges' : '';
  7979. }).attr('transform', null);
  7980. mainLine.exit().transition().duration(durationForExit).style('opacity', 0);
  7981. };
  7982. ChartInternal.prototype.redrawLine = function (drawLine, withTransition, transition) {
  7983. return [(withTransition ? this.mainLine.transition(transition) : this.mainLine).attr("d", drawLine).style("stroke", this.color).style("opacity", 1)];
  7984. };
  7985. ChartInternal.prototype.generateDrawLine = function (lineIndices, isSub) {
  7986. var $$ = this,
  7987. config = $$.config,
  7988. line = $$.d3.line(),
  7989. getPoints = $$.generateGetLinePoints(lineIndices, isSub),
  7990. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  7991. xValue = function xValue(d) {
  7992. return (isSub ? $$.subxx : $$.xx).call($$, d);
  7993. },
  7994. yValue = function yValue(d, i) {
  7995. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)(d.value);
  7996. };
  7997. line = config.axis_rotated ? line.x(yValue).y(xValue) : line.x(xValue).y(yValue);
  7998. if (!config.line_connectNull) {
  7999. line = line.defined(function (d) {
  8000. return d.value != null;
  8001. });
  8002. }
  8003. return function (d) {
  8004. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  8005. x = isSub ? $$.subX : $$.x,
  8006. y = yScaleGetter.call($$, d.id),
  8007. x0 = 0,
  8008. y0 = 0,
  8009. path;
  8010. if ($$.isLineType(d)) {
  8011. if (config.data_regions[d.id]) {
  8012. path = $$.lineWithRegions(values, x, y, config.data_regions[d.id]);
  8013. } else {
  8014. if ($$.isStepType(d)) {
  8015. values = $$.convertValuesToStep(values);
  8016. }
  8017. path = line.curve($$.getInterpolate(d))(values);
  8018. }
  8019. } else {
  8020. if (values[0]) {
  8021. x0 = x(values[0].x);
  8022. y0 = y(values[0].value);
  8023. }
  8024. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  8025. }
  8026. return path ? path : "M 0 0";
  8027. };
  8028. };
  8029. ChartInternal.prototype.generateGetLinePoints = function (lineIndices, isSub) {
  8030. // partial duplication of generateGetBarPoints
  8031. var $$ = this,
  8032. config = $$.config,
  8033. lineTargetsNum = lineIndices.__max__ + 1,
  8034. x = $$.getShapeX(0, lineTargetsNum, lineIndices, !!isSub),
  8035. y = $$.getShapeY(!!isSub),
  8036. lineOffset = $$.getShapeOffset($$.isLineType, lineIndices, !!isSub),
  8037. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  8038. return function (d, i) {
  8039. var y0 = yScale.call($$, d.id)(0),
  8040. offset = lineOffset(d, i) || y0,
  8041. // offset is for stacked area chart
  8042. posX = x(d),
  8043. posY = y(d); // fix posY not to overflow opposite quadrant
  8044. if (config.axis_rotated) {
  8045. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  8046. posY = y0;
  8047. }
  8048. } // 1 point that marks the line position
  8049. return [[posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  8050. [posX, posY - (y0 - offset)], // needed for compatibility
  8051. [posX, posY - (y0 - offset)] // needed for compatibility
  8052. ];
  8053. };
  8054. };
  8055. ChartInternal.prototype.lineWithRegions = function (d, x, y, _regions) {
  8056. var $$ = this,
  8057. config = $$.config,
  8058. prev = -1,
  8059. i,
  8060. j,
  8061. s = "M",
  8062. sWithRegion,
  8063. xp,
  8064. yp,
  8065. dx,
  8066. dy,
  8067. dd,
  8068. diff,
  8069. diffx2,
  8070. xOffset = $$.isCategorized() ? 0.5 : 0,
  8071. xValue,
  8072. yValue,
  8073. regions = [];
  8074. function isWithinRegions(x, regions) {
  8075. var i;
  8076. for (i = 0; i < regions.length; i++) {
  8077. if (regions[i].start < x && x <= regions[i].end) {
  8078. return true;
  8079. }
  8080. }
  8081. return false;
  8082. } // Check start/end of regions
  8083. if (isDefined(_regions)) {
  8084. for (i = 0; i < _regions.length; i++) {
  8085. regions[i] = {};
  8086. if (isUndefined(_regions[i].start)) {
  8087. regions[i].start = d[0].x;
  8088. } else {
  8089. regions[i].start = $$.isTimeSeries() ? $$.parseDate(_regions[i].start) : _regions[i].start;
  8090. }
  8091. if (isUndefined(_regions[i].end)) {
  8092. regions[i].end = d[d.length - 1].x;
  8093. } else {
  8094. regions[i].end = $$.isTimeSeries() ? $$.parseDate(_regions[i].end) : _regions[i].end;
  8095. }
  8096. }
  8097. } // Set scales
  8098. xValue = config.axis_rotated ? function (d) {
  8099. return y(d.value);
  8100. } : function (d) {
  8101. return x(d.x);
  8102. };
  8103. yValue = config.axis_rotated ? function (d) {
  8104. return x(d.x);
  8105. } : function (d) {
  8106. return y(d.value);
  8107. }; // Define svg generator function for region
  8108. function generateM(points) {
  8109. return 'M' + points[0][0] + ' ' + points[0][1] + ' ' + points[1][0] + ' ' + points[1][1];
  8110. }
  8111. if ($$.isTimeSeries()) {
  8112. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  8113. var x0 = d0.x.getTime(),
  8114. x_diff = d1.x - d0.x,
  8115. xv0 = new Date(x0 + x_diff * j),
  8116. xv1 = new Date(x0 + x_diff * (j + diff)),
  8117. points;
  8118. if (config.axis_rotated) {
  8119. points = [[y(yp(j)), x(xv0)], [y(yp(j + diff)), x(xv1)]];
  8120. } else {
  8121. points = [[x(xv0), y(yp(j))], [x(xv1), y(yp(j + diff))]];
  8122. }
  8123. return generateM(points);
  8124. };
  8125. } else {
  8126. sWithRegion = function sWithRegion(d0, d1, j, diff) {
  8127. var points;
  8128. if (config.axis_rotated) {
  8129. points = [[y(yp(j), true), x(xp(j))], [y(yp(j + diff), true), x(xp(j + diff))]];
  8130. } else {
  8131. points = [[x(xp(j), true), y(yp(j))], [x(xp(j + diff), true), y(yp(j + diff))]];
  8132. }
  8133. return generateM(points);
  8134. };
  8135. } // Generate
  8136. for (i = 0; i < d.length; i++) {
  8137. // Draw as normal
  8138. if (isUndefined(regions) || !isWithinRegions(d[i].x, regions)) {
  8139. s += " " + xValue(d[i]) + " " + yValue(d[i]);
  8140. } // Draw with region // TODO: Fix for horizotal charts
  8141. else {
  8142. xp = $$.getScale(d[i - 1].x + xOffset, d[i].x + xOffset, $$.isTimeSeries());
  8143. yp = $$.getScale(d[i - 1].value, d[i].value);
  8144. dx = x(d[i].x) - x(d[i - 1].x);
  8145. dy = y(d[i].value) - y(d[i - 1].value);
  8146. dd = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
  8147. diff = 2 / dd;
  8148. diffx2 = diff * 2;
  8149. for (j = diff; j <= 1; j += diffx2) {
  8150. s += sWithRegion(d[i - 1], d[i], j, diff);
  8151. }
  8152. }
  8153. prev = d[i].x;
  8154. }
  8155. return s;
  8156. };
  8157. ChartInternal.prototype.updateArea = function (durationForExit) {
  8158. var $$ = this,
  8159. d3 = $$.d3;
  8160. var mainArea = $$.main.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  8161. var mainAreaEnter = mainArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  8162. $$.orgAreaOpacity = +d3.select(this).style('opacity');
  8163. return 0;
  8164. });
  8165. $$.mainArea = mainAreaEnter.merge(mainArea).style("opacity", $$.orgAreaOpacity);
  8166. mainArea.exit().transition().duration(durationForExit).style('opacity', 0);
  8167. };
  8168. ChartInternal.prototype.redrawArea = function (drawArea, withTransition, transition) {
  8169. return [(withTransition ? this.mainArea.transition(transition) : this.mainArea).attr("d", drawArea).style("fill", this.color).style("opacity", this.orgAreaOpacity)];
  8170. };
  8171. ChartInternal.prototype.generateDrawArea = function (areaIndices, isSub) {
  8172. var $$ = this,
  8173. config = $$.config,
  8174. area = $$.d3.area(),
  8175. getPoints = $$.generateGetAreaPoints(areaIndices, isSub),
  8176. yScaleGetter = isSub ? $$.getSubYScale : $$.getYScale,
  8177. xValue = function xValue(d) {
  8178. return (isSub ? $$.subxx : $$.xx).call($$, d);
  8179. },
  8180. value0 = function value0(d, i) {
  8181. return config.data_groups.length > 0 ? getPoints(d, i)[0][1] : yScaleGetter.call($$, d.id)($$.getAreaBaseValue(d.id));
  8182. },
  8183. value1 = function value1(d, i) {
  8184. return config.data_groups.length > 0 ? getPoints(d, i)[1][1] : yScaleGetter.call($$, d.id)(d.value);
  8185. };
  8186. area = config.axis_rotated ? area.x0(value0).x1(value1).y(xValue) : area.x(xValue).y0(config.area_above ? 0 : value0).y1(value1);
  8187. if (!config.line_connectNull) {
  8188. area = area.defined(function (d) {
  8189. return d.value !== null;
  8190. });
  8191. }
  8192. return function (d) {
  8193. var values = config.line_connectNull ? $$.filterRemoveNull(d.values) : d.values,
  8194. x0 = 0,
  8195. y0 = 0,
  8196. path;
  8197. if ($$.isAreaType(d)) {
  8198. if ($$.isStepType(d)) {
  8199. values = $$.convertValuesToStep(values);
  8200. }
  8201. path = area.curve($$.getInterpolate(d))(values);
  8202. } else {
  8203. if (values[0]) {
  8204. x0 = $$.x(values[0].x);
  8205. y0 = $$.getYScale(d.id)(values[0].value);
  8206. }
  8207. path = config.axis_rotated ? "M " + y0 + " " + x0 : "M " + x0 + " " + y0;
  8208. }
  8209. return path ? path : "M 0 0";
  8210. };
  8211. };
  8212. ChartInternal.prototype.getAreaBaseValue = function () {
  8213. return 0;
  8214. };
  8215. ChartInternal.prototype.generateGetAreaPoints = function (areaIndices, isSub) {
  8216. // partial duplication of generateGetBarPoints
  8217. var $$ = this,
  8218. config = $$.config,
  8219. areaTargetsNum = areaIndices.__max__ + 1,
  8220. x = $$.getShapeX(0, areaTargetsNum, areaIndices, !!isSub),
  8221. y = $$.getShapeY(!!isSub),
  8222. areaOffset = $$.getShapeOffset($$.isAreaType, areaIndices, !!isSub),
  8223. yScale = isSub ? $$.getSubYScale : $$.getYScale;
  8224. return function (d, i) {
  8225. var y0 = yScale.call($$, d.id)(0),
  8226. offset = areaOffset(d, i) || y0,
  8227. // offset is for stacked area chart
  8228. posX = x(d),
  8229. posY = y(d); // fix posY not to overflow opposite quadrant
  8230. if (config.axis_rotated) {
  8231. if (0 < d.value && posY < y0 || d.value < 0 && y0 < posY) {
  8232. posY = y0;
  8233. }
  8234. } // 1 point that marks the area position
  8235. return [[posX, offset], [posX, posY - (y0 - offset)], [posX, posY - (y0 - offset)], // needed for compatibility
  8236. [posX, offset] // needed for compatibility
  8237. ];
  8238. };
  8239. };
  8240. ChartInternal.prototype.updateCircle = function (cx, cy) {
  8241. var $$ = this;
  8242. var mainCircle = $$.main.selectAll('.' + CLASS.circles).selectAll('.' + CLASS.circle).data($$.lineOrScatterOrStanfordData.bind($$));
  8243. var mainCircleEnter = mainCircle.enter().append("circle").attr('shape-rendering', $$.isStanfordGraphType() ? 'crispEdges' : '').attr("class", $$.classCircle.bind($$)).attr("cx", cx).attr("cy", cy).attr("r", $$.pointR.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color);
  8244. $$.mainCircle = mainCircleEnter.merge(mainCircle).style("opacity", $$.isStanfordGraphType() ? 1 : $$.initialOpacityForCircle.bind($$));
  8245. mainCircle.exit().style("opacity", 0);
  8246. };
  8247. ChartInternal.prototype.redrawCircle = function (cx, cy, withTransition, transition) {
  8248. var $$ = this,
  8249. selectedCircles = $$.main.selectAll('.' + CLASS.selectedCircle);
  8250. return [(withTransition ? $$.mainCircle.transition(transition) : $$.mainCircle).style('opacity', this.opacityForCircle.bind($$)).style("color", $$.isStanfordGraphType() ? $$.getStanfordPointColor.bind($$) : $$.color).attr("cx", cx).attr("cy", cy), (withTransition ? selectedCircles.transition(transition) : selectedCircles).attr("cx", cx).attr("cy", cy)];
  8251. };
  8252. ChartInternal.prototype.circleX = function (d) {
  8253. return d.x || d.x === 0 ? this.x(d.x) : null;
  8254. };
  8255. ChartInternal.prototype.updateCircleY = function () {
  8256. var $$ = this,
  8257. lineIndices,
  8258. getPoints;
  8259. if ($$.config.data_groups.length > 0) {
  8260. lineIndices = $$.getShapeIndices($$.isLineType), getPoints = $$.generateGetLinePoints(lineIndices);
  8261. $$.circleY = function (d, i) {
  8262. return getPoints(d, i)[0][1];
  8263. };
  8264. } else {
  8265. $$.circleY = function (d) {
  8266. return $$.getYScale(d.id)(d.value);
  8267. };
  8268. }
  8269. };
  8270. ChartInternal.prototype.getCircles = function (i, id) {
  8271. var $$ = this;
  8272. return (id ? $$.main.selectAll('.' + CLASS.circles + $$.getTargetSelectorSuffix(id)) : $$.main).selectAll('.' + CLASS.circle + (isValue(i) ? '-' + i : ''));
  8273. };
  8274. ChartInternal.prototype.expandCircles = function (i, id, reset) {
  8275. var $$ = this,
  8276. r = $$.pointExpandedR.bind($$);
  8277. if (reset) {
  8278. $$.unexpandCircles();
  8279. }
  8280. $$.getCircles(i, id).classed(CLASS.EXPANDED, true).attr('r', r);
  8281. };
  8282. ChartInternal.prototype.unexpandCircles = function (i) {
  8283. var $$ = this,
  8284. r = $$.pointR.bind($$);
  8285. $$.getCircles(i).filter(function () {
  8286. return $$.d3.select(this).classed(CLASS.EXPANDED);
  8287. }).classed(CLASS.EXPANDED, false).attr('r', r);
  8288. };
  8289. ChartInternal.prototype.pointR = function (d) {
  8290. var $$ = this,
  8291. config = $$.config;
  8292. return $$.isStepType(d) ? 0 : isFunction(config.point_r) ? config.point_r(d) : config.point_r;
  8293. };
  8294. ChartInternal.prototype.pointExpandedR = function (d) {
  8295. var $$ = this,
  8296. config = $$.config;
  8297. if (config.point_focus_expand_enabled) {
  8298. return isFunction(config.point_focus_expand_r) ? config.point_focus_expand_r(d) : config.point_focus_expand_r ? config.point_focus_expand_r : $$.pointR(d) * 1.75;
  8299. } else {
  8300. return $$.pointR(d);
  8301. }
  8302. };
  8303. ChartInternal.prototype.pointSelectR = function (d) {
  8304. var $$ = this,
  8305. config = $$.config;
  8306. return isFunction(config.point_select_r) ? config.point_select_r(d) : config.point_select_r ? config.point_select_r : $$.pointR(d) * 4;
  8307. };
  8308. ChartInternal.prototype.isWithinCircle = function (that, r) {
  8309. var d3 = this.d3,
  8310. mouse = d3.mouse(that),
  8311. d3_this = d3.select(that),
  8312. cx = +d3_this.attr("cx"),
  8313. cy = +d3_this.attr("cy");
  8314. return Math.sqrt(Math.pow(cx - mouse[0], 2) + Math.pow(cy - mouse[1], 2)) < r;
  8315. };
  8316. ChartInternal.prototype.isWithinStep = function (that, y) {
  8317. return Math.abs(y - this.d3.mouse(that)[1]) < 30;
  8318. };
  8319. ChartInternal.prototype.getCurrentWidth = function () {
  8320. var $$ = this,
  8321. config = $$.config;
  8322. return config.size_width ? config.size_width : $$.getParentWidth();
  8323. };
  8324. ChartInternal.prototype.getCurrentHeight = function () {
  8325. var $$ = this,
  8326. config = $$.config,
  8327. h = config.size_height ? config.size_height : $$.getParentHeight();
  8328. return h > 0 ? h : 320 / ($$.hasType('gauge') && !config.gauge_fullCircle ? 2 : 1);
  8329. };
  8330. ChartInternal.prototype.getCurrentPaddingTop = function () {
  8331. var $$ = this,
  8332. config = $$.config,
  8333. padding = isValue(config.padding_top) ? config.padding_top : 0;
  8334. if ($$.title && $$.title.node()) {
  8335. padding += $$.getTitlePadding();
  8336. }
  8337. return padding;
  8338. };
  8339. ChartInternal.prototype.getCurrentPaddingBottom = function () {
  8340. var config = this.config;
  8341. return isValue(config.padding_bottom) ? config.padding_bottom : 0;
  8342. };
  8343. ChartInternal.prototype.getCurrentPaddingLeft = function (withoutRecompute) {
  8344. var $$ = this,
  8345. config = $$.config;
  8346. if (isValue(config.padding_left)) {
  8347. return config.padding_left;
  8348. } else if (config.axis_rotated) {
  8349. return !config.axis_x_show || config.axis_x_inner ? 1 : Math.max(ceil10($$.getAxisWidthByAxisId('x', withoutRecompute)), 40);
  8350. } else if (!config.axis_y_show || config.axis_y_inner) {
  8351. // && !config.axis_rotated
  8352. return $$.axis.getYAxisLabelPosition().isOuter ? 30 : 1;
  8353. } else {
  8354. return ceil10($$.getAxisWidthByAxisId('y', withoutRecompute));
  8355. }
  8356. };
  8357. ChartInternal.prototype.getCurrentPaddingRight = function () {
  8358. var $$ = this,
  8359. config = $$.config,
  8360. padding = 0,
  8361. defaultPadding = 10,
  8362. legendWidthOnRight = $$.isLegendRight ? $$.getLegendWidth() + 20 : 0;
  8363. if (isValue(config.padding_right)) {
  8364. padding = config.padding_right + 1; // 1 is needed not to hide tick line
  8365. } else if (config.axis_rotated) {
  8366. padding = defaultPadding + legendWidthOnRight;
  8367. } else if (!config.axis_y2_show || config.axis_y2_inner) {
  8368. // && !config.axis_rotated
  8369. padding = 2 + legendWidthOnRight + ($$.axis.getY2AxisLabelPosition().isOuter ? 20 : 0);
  8370. } else {
  8371. padding = ceil10($$.getAxisWidthByAxisId('y2')) + legendWidthOnRight;
  8372. }
  8373. if ($$.colorScale && $$.colorScale.node()) {
  8374. padding += $$.getColorScalePadding();
  8375. }
  8376. return padding;
  8377. };
  8378. ChartInternal.prototype.getParentRectValue = function (key) {
  8379. var parent = this.selectChart.node(),
  8380. v;
  8381. while (parent && parent.tagName !== 'BODY') {
  8382. try {
  8383. v = parent.getBoundingClientRect()[key];
  8384. } catch (e) {
  8385. if (key === 'width') {
  8386. // In IE in certain cases getBoundingClientRect
  8387. // will cause an "unspecified error"
  8388. v = parent.offsetWidth;
  8389. }
  8390. }
  8391. if (v) {
  8392. break;
  8393. }
  8394. parent = parent.parentNode;
  8395. }
  8396. return v;
  8397. };
  8398. ChartInternal.prototype.getParentWidth = function () {
  8399. return this.getParentRectValue('width');
  8400. };
  8401. ChartInternal.prototype.getParentHeight = function () {
  8402. var h = this.selectChart.style('height');
  8403. return h.indexOf('px') > 0 ? +h.replace('px', '') : 0;
  8404. };
  8405. ChartInternal.prototype.getSvgLeft = function (withoutRecompute) {
  8406. var $$ = this,
  8407. config = $$.config,
  8408. hasLeftAxisRect = config.axis_rotated || !config.axis_rotated && !config.axis_y_inner,
  8409. leftAxisClass = config.axis_rotated ? CLASS.axisX : CLASS.axisY,
  8410. leftAxis = $$.main.select('.' + leftAxisClass).node(),
  8411. svgRect = leftAxis && hasLeftAxisRect ? leftAxis.getBoundingClientRect() : {
  8412. right: 0
  8413. },
  8414. chartRect = $$.selectChart.node().getBoundingClientRect(),
  8415. hasArc = $$.hasArcType(),
  8416. svgLeft = svgRect.right - chartRect.left - (hasArc ? 0 : $$.getCurrentPaddingLeft(withoutRecompute));
  8417. return svgLeft > 0 ? svgLeft : 0;
  8418. };
  8419. ChartInternal.prototype.getAxisWidthByAxisId = function (id, withoutRecompute) {
  8420. var $$ = this,
  8421. position = $$.axis.getLabelPositionById(id);
  8422. return $$.axis.getMaxTickWidth(id, withoutRecompute) + (position.isInner ? 20 : 40);
  8423. };
  8424. ChartInternal.prototype.getHorizontalAxisHeight = function (axisId) {
  8425. var $$ = this,
  8426. config = $$.config,
  8427. h = 30;
  8428. if (axisId === 'x' && !config.axis_x_show) {
  8429. return 8;
  8430. }
  8431. if (axisId === 'x' && config.axis_x_height) {
  8432. return config.axis_x_height;
  8433. }
  8434. if (axisId === 'y' && !config.axis_y_show) {
  8435. return config.legend_show && !$$.isLegendRight && !$$.isLegendInset ? 10 : 1;
  8436. }
  8437. if (axisId === 'y2' && !config.axis_y2_show) {
  8438. return $$.rotated_padding_top;
  8439. } // Calculate x axis height when tick rotated
  8440. if (axisId === 'x' && !config.axis_rotated && config.axis_x_tick_rotate) {
  8441. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_x_tick_rotate)) / 180);
  8442. } // Calculate y axis height when tick rotated
  8443. if (axisId === 'y' && config.axis_rotated && config.axis_y_tick_rotate) {
  8444. h = 30 + $$.axis.getMaxTickWidth(axisId) * Math.cos(Math.PI * (90 - Math.abs(config.axis_y_tick_rotate)) / 180);
  8445. }
  8446. return h + ($$.axis.getLabelPositionById(axisId).isInner ? 0 : 10) + (axisId === 'y2' ? -10 : 0);
  8447. };
  8448. ChartInternal.prototype.initBrush = function (scale) {
  8449. var $$ = this,
  8450. d3 = $$.d3; // TODO: dynamically change brushY/brushX according to axis_rotated.
  8451. $$.brush = ($$.config.axis_rotated ? d3.brushY() : d3.brushX()).on("brush", function () {
  8452. var event = d3.event.sourceEvent;
  8453. if (event && event.type === "zoom") {
  8454. return;
  8455. }
  8456. $$.redrawForBrush();
  8457. }).on("end", function () {
  8458. var event = d3.event.sourceEvent;
  8459. if (event && event.type === "zoom") {
  8460. return;
  8461. }
  8462. if ($$.brush.empty() && event && event.type !== 'end') {
  8463. $$.brush.clear();
  8464. }
  8465. });
  8466. $$.brush.updateExtent = function () {
  8467. var range = this.scale.range(),
  8468. extent;
  8469. if ($$.config.axis_rotated) {
  8470. extent = [[0, range[0]], [$$.width2, range[1]]];
  8471. } else {
  8472. extent = [[range[0], 0], [range[1], $$.height2]];
  8473. }
  8474. this.extent(extent);
  8475. return this;
  8476. };
  8477. $$.brush.updateScale = function (scale) {
  8478. this.scale = scale;
  8479. return this;
  8480. };
  8481. $$.brush.update = function (scale) {
  8482. this.updateScale(scale || $$.subX).updateExtent();
  8483. $$.context.select('.' + CLASS.brush).call(this);
  8484. };
  8485. $$.brush.clear = function () {
  8486. $$.context.select('.' + CLASS.brush).call($$.brush.move, null);
  8487. };
  8488. $$.brush.selection = function () {
  8489. return d3.brushSelection($$.context.select('.' + CLASS.brush).node());
  8490. };
  8491. $$.brush.selectionAsValue = function (selectionAsValue, withTransition) {
  8492. var selection, brush;
  8493. if (selectionAsValue) {
  8494. if ($$.context) {
  8495. selection = [this.scale(selectionAsValue[0]), this.scale(selectionAsValue[1])];
  8496. brush = $$.context.select('.' + CLASS.brush);
  8497. if (withTransition) {
  8498. brush = brush.transition();
  8499. }
  8500. $$.brush.move(brush, selection);
  8501. }
  8502. return [];
  8503. }
  8504. selection = $$.brush.selection() || [0, 0];
  8505. return [this.scale.invert(selection[0]), this.scale.invert(selection[1])];
  8506. };
  8507. $$.brush.empty = function () {
  8508. var selection = $$.brush.selection();
  8509. return !selection || selection[0] === selection[1];
  8510. };
  8511. return $$.brush.updateScale(scale);
  8512. };
  8513. ChartInternal.prototype.initSubchart = function () {
  8514. var $$ = this,
  8515. config = $$.config,
  8516. context = $$.context = $$.svg.append("g").attr("transform", $$.getTranslate('context')),
  8517. visibility = config.subchart_show ? 'visible' : 'hidden'; // set style
  8518. context.style('visibility', visibility); // Define g for chart area
  8519. context.append('g').attr("clip-path", $$.clipPathForSubchart).attr('class', CLASS.chart); // Define g for bar chart area
  8520. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartBars); // Define g for line chart area
  8521. context.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartLines); // Add extent rect for Brush
  8522. context.append("g").attr("clip-path", $$.clipPath).attr("class", CLASS.brush); // ATTENTION: This must be called AFTER chart added
  8523. // Add Axis
  8524. $$.axes.subx = context.append("g").attr("class", CLASS.axisX).attr("transform", $$.getTranslate('subx')).attr("clip-path", config.axis_rotated ? "" : $$.clipPathForXAxis);
  8525. };
  8526. ChartInternal.prototype.initSubchartBrush = function () {
  8527. var $$ = this; // Add extent rect for Brush
  8528. $$.initBrush($$.subX).updateExtent();
  8529. $$.context.select('.' + CLASS.brush).call($$.brush);
  8530. };
  8531. ChartInternal.prototype.updateTargetsForSubchart = function (targets) {
  8532. var $$ = this,
  8533. context = $$.context,
  8534. config = $$.config,
  8535. contextLineEnter,
  8536. contextLine,
  8537. contextBarEnter,
  8538. contextBar,
  8539. classChartBar = $$.classChartBar.bind($$),
  8540. classBars = $$.classBars.bind($$),
  8541. classChartLine = $$.classChartLine.bind($$),
  8542. classLines = $$.classLines.bind($$),
  8543. classAreas = $$.classAreas.bind($$);
  8544. if (config.subchart_show) {
  8545. //-- Bar --//
  8546. contextBar = context.select('.' + CLASS.chartBars).selectAll('.' + CLASS.chartBar).data(targets);
  8547. contextBarEnter = contextBar.enter().append('g').style('opacity', 0);
  8548. contextBarEnter.merge(contextBar).attr('class', classChartBar); // Bars for each data
  8549. contextBarEnter.append('g').attr("class", classBars); //-- Line --//
  8550. contextLine = context.select('.' + CLASS.chartLines).selectAll('.' + CLASS.chartLine).data(targets);
  8551. contextLineEnter = contextLine.enter().append('g').style('opacity', 0);
  8552. contextLineEnter.merge(contextLine).attr('class', classChartLine); // Lines for each data
  8553. contextLineEnter.append("g").attr("class", classLines); // Area
  8554. contextLineEnter.append("g").attr("class", classAreas); //-- Brush --//
  8555. context.selectAll('.' + CLASS.brush + ' rect').attr(config.axis_rotated ? "width" : "height", config.axis_rotated ? $$.width2 : $$.height2);
  8556. }
  8557. };
  8558. ChartInternal.prototype.updateBarForSubchart = function (durationForExit) {
  8559. var $$ = this;
  8560. var contextBar = $$.context.selectAll('.' + CLASS.bars).selectAll('.' + CLASS.bar).data($$.barData.bind($$));
  8561. var contextBarEnter = contextBar.enter().append('path').attr("class", $$.classBar.bind($$)).style("stroke", 'none').style("fill", $$.color);
  8562. contextBar.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  8563. $$.contextBar = contextBarEnter.merge(contextBar).style("opacity", $$.initialOpacity.bind($$));
  8564. };
  8565. ChartInternal.prototype.redrawBarForSubchart = function (drawBarOnSub, withTransition, duration) {
  8566. (withTransition ? this.contextBar.transition(Math.random().toString()).duration(duration) : this.contextBar).attr('d', drawBarOnSub).style('opacity', 1);
  8567. };
  8568. ChartInternal.prototype.updateLineForSubchart = function (durationForExit) {
  8569. var $$ = this;
  8570. var contextLine = $$.context.selectAll('.' + CLASS.lines).selectAll('.' + CLASS.line).data($$.lineData.bind($$));
  8571. var contextLineEnter = contextLine.enter().append('path').attr('class', $$.classLine.bind($$)).style('stroke', $$.color);
  8572. contextLine.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  8573. $$.contextLine = contextLineEnter.merge(contextLine).style("opacity", $$.initialOpacity.bind($$));
  8574. };
  8575. ChartInternal.prototype.redrawLineForSubchart = function (drawLineOnSub, withTransition, duration) {
  8576. (withTransition ? this.contextLine.transition(Math.random().toString()).duration(duration) : this.contextLine).attr("d", drawLineOnSub).style('opacity', 1);
  8577. };
  8578. ChartInternal.prototype.updateAreaForSubchart = function (durationForExit) {
  8579. var $$ = this,
  8580. d3 = $$.d3;
  8581. var contextArea = $$.context.selectAll('.' + CLASS.areas).selectAll('.' + CLASS.area).data($$.lineData.bind($$));
  8582. var contextAreaEnter = contextArea.enter().append('path').attr("class", $$.classArea.bind($$)).style("fill", $$.color).style("opacity", function () {
  8583. $$.orgAreaOpacity = +d3.select(this).style('opacity');
  8584. return 0;
  8585. });
  8586. contextArea.exit().transition().duration(durationForExit).style('opacity', 0).remove();
  8587. $$.contextArea = contextAreaEnter.merge(contextArea).style("opacity", 0);
  8588. };
  8589. ChartInternal.prototype.redrawAreaForSubchart = function (drawAreaOnSub, withTransition, duration) {
  8590. (withTransition ? this.contextArea.transition(Math.random().toString()).duration(duration) : this.contextArea).attr("d", drawAreaOnSub).style("fill", this.color).style("opacity", this.orgAreaOpacity);
  8591. };
  8592. ChartInternal.prototype.redrawSubchart = function (withSubchart, transitions, duration, durationForExit, areaIndices, barIndices, lineIndices) {
  8593. var $$ = this,
  8594. d3 = $$.d3,
  8595. config = $$.config,
  8596. drawAreaOnSub,
  8597. drawBarOnSub,
  8598. drawLineOnSub;
  8599. $$.context.style('visibility', config.subchart_show ? 'visible' : 'hidden'); // subchart
  8600. if (config.subchart_show) {
  8601. // reflect main chart to extent on subchart if zoomed
  8602. if (d3.event && d3.event.type === 'zoom') {
  8603. $$.brush.selectionAsValue($$.x.orgDomain());
  8604. } // update subchart elements if needed
  8605. if (withSubchart) {
  8606. // extent rect
  8607. if (!$$.brush.empty()) {
  8608. $$.brush.selectionAsValue($$.x.orgDomain());
  8609. } // setup drawer - MEMO: this must be called after axis updated
  8610. drawAreaOnSub = $$.generateDrawArea(areaIndices, true);
  8611. drawBarOnSub = $$.generateDrawBar(barIndices, true);
  8612. drawLineOnSub = $$.generateDrawLine(lineIndices, true);
  8613. $$.updateBarForSubchart(duration);
  8614. $$.updateLineForSubchart(duration);
  8615. $$.updateAreaForSubchart(duration);
  8616. $$.redrawBarForSubchart(drawBarOnSub, duration, duration);
  8617. $$.redrawLineForSubchart(drawLineOnSub, duration, duration);
  8618. $$.redrawAreaForSubchart(drawAreaOnSub, duration, duration);
  8619. }
  8620. }
  8621. };
  8622. ChartInternal.prototype.redrawForBrush = function () {
  8623. var $$ = this,
  8624. x = $$.x,
  8625. d3 = $$.d3,
  8626. s;
  8627. $$.redraw({
  8628. withTransition: false,
  8629. withY: $$.config.zoom_rescale,
  8630. withSubchart: false,
  8631. withUpdateXDomain: true,
  8632. withEventRect: false,
  8633. withDimension: false
  8634. }); // update zoom transation binded to event rect
  8635. s = d3.event.selection || $$.brush.scale.range();
  8636. $$.main.select('.' + CLASS.eventRect).call($$.zoom.transform, d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0));
  8637. $$.config.subchart_onbrush.call($$.api, x.orgDomain());
  8638. };
  8639. ChartInternal.prototype.transformContext = function (withTransition, transitions) {
  8640. var $$ = this,
  8641. subXAxis;
  8642. if (transitions && transitions.axisSubX) {
  8643. subXAxis = transitions.axisSubX;
  8644. } else {
  8645. subXAxis = $$.context.select('.' + CLASS.axisX);
  8646. if (withTransition) {
  8647. subXAxis = subXAxis.transition();
  8648. }
  8649. }
  8650. $$.context.attr("transform", $$.getTranslate('context'));
  8651. subXAxis.attr("transform", $$.getTranslate('subx'));
  8652. };
  8653. ChartInternal.prototype.getDefaultSelection = function () {
  8654. var $$ = this,
  8655. config = $$.config,
  8656. selection = isFunction(config.axis_x_selection) ? config.axis_x_selection($$.getXDomain($$.data.targets)) : config.axis_x_selection;
  8657. if ($$.isTimeSeries()) {
  8658. selection = [$$.parseDate(selection[0]), $$.parseDate(selection[1])];
  8659. }
  8660. return selection;
  8661. };
  8662. ChartInternal.prototype.initText = function () {
  8663. var $$ = this;
  8664. $$.main.select('.' + CLASS.chart).append("g").attr("class", CLASS.chartTexts);
  8665. $$.mainText = $$.d3.selectAll([]);
  8666. };
  8667. ChartInternal.prototype.updateTargetsForText = function (targets) {
  8668. var $$ = this,
  8669. classChartText = $$.classChartText.bind($$),
  8670. classTexts = $$.classTexts.bind($$),
  8671. classFocus = $$.classFocus.bind($$);
  8672. var mainText = $$.main.select('.' + CLASS.chartTexts).selectAll('.' + CLASS.chartText).data(targets);
  8673. var mainTextEnter = mainText.enter().append('g').attr('class', classChartText).style('opacity', 0).style("pointer-events", "none");
  8674. mainTextEnter.append('g').attr('class', classTexts);
  8675. mainTextEnter.merge(mainText).attr('class', function (d) {
  8676. return classChartText(d) + classFocus(d);
  8677. });
  8678. };
  8679. ChartInternal.prototype.updateText = function (xForText, yForText, durationForExit) {
  8680. var $$ = this,
  8681. config = $$.config,
  8682. barOrLineData = $$.barOrLineData.bind($$),
  8683. classText = $$.classText.bind($$);
  8684. var mainText = $$.main.selectAll('.' + CLASS.texts).selectAll('.' + CLASS.text).data(barOrLineData);
  8685. var mainTextEnter = mainText.enter().append('text').attr("class", classText).attr('text-anchor', function (d) {
  8686. return config.axis_rotated ? d.value < 0 ? 'end' : 'start' : 'middle';
  8687. }).style("stroke", 'none').attr('x', xForText).attr('y', yForText).style("fill", function (d) {
  8688. return $$.color(d);
  8689. }).style("fill-opacity", 0);
  8690. $$.mainText = mainTextEnter.merge(mainText).text(function (d, i, j) {
  8691. return $$.dataLabelFormat(d.id)(d.value, d.id, i, j);
  8692. });
  8693. mainText.exit().transition().duration(durationForExit).style('fill-opacity', 0).remove();
  8694. };
  8695. ChartInternal.prototype.redrawText = function (xForText, yForText, forFlow, withTransition, transition) {
  8696. return [(withTransition ? this.mainText.transition(transition) : this.mainText).attr('x', xForText).attr('y', yForText).style("fill", this.color).style("fill-opacity", forFlow ? 0 : this.opacityForText.bind(this))];
  8697. };
  8698. ChartInternal.prototype.getTextRect = function (text, cls, element) {
  8699. var dummy = this.d3.select('body').append('div').classed('c3', true),
  8700. svg = dummy.append("svg").style('visibility', 'hidden').style('position', 'fixed').style('top', 0).style('left', 0),
  8701. font = this.d3.select(element).style('font'),
  8702. rect;
  8703. svg.selectAll('.dummy').data([text]).enter().append('text').classed(cls ? cls : "", true).style('font', font).text(text).each(function () {
  8704. rect = getBBox(this);
  8705. });
  8706. dummy.remove();
  8707. return rect;
  8708. };
  8709. ChartInternal.prototype.generateXYForText = function (areaIndices, barIndices, lineIndices, forX) {
  8710. var $$ = this,
  8711. getAreaPoints = $$.generateGetAreaPoints(areaIndices, false),
  8712. getBarPoints = $$.generateGetBarPoints(barIndices, false),
  8713. getLinePoints = $$.generateGetLinePoints(lineIndices, false),
  8714. getter = forX ? $$.getXForText : $$.getYForText;
  8715. return function (d, i) {
  8716. var getPoints = $$.isAreaType(d) ? getAreaPoints : $$.isBarType(d) ? getBarPoints : getLinePoints;
  8717. return getter.call($$, getPoints(d, i), d, this);
  8718. };
  8719. };
  8720. ChartInternal.prototype.getXForText = function (points, d, textElement) {
  8721. var $$ = this,
  8722. box = getBBox(textElement),
  8723. xPos,
  8724. padding;
  8725. if ($$.config.axis_rotated) {
  8726. padding = $$.isBarType(d) ? 4 : 6;
  8727. xPos = points[2][1] + padding * (d.value < 0 ? -1 : 1);
  8728. } else {
  8729. xPos = $$.hasType('bar') ? (points[2][0] + points[0][0]) / 2 : points[0][0];
  8730. } // show labels regardless of the domain if value is null
  8731. if (d.value === null) {
  8732. if (xPos > $$.width) {
  8733. xPos = $$.width - box.width;
  8734. } else if (xPos < 0) {
  8735. xPos = 4;
  8736. }
  8737. }
  8738. return xPos;
  8739. };
  8740. ChartInternal.prototype.getYForText = function (points, d, textElement) {
  8741. var $$ = this,
  8742. box = getBBox(textElement),
  8743. yPos;
  8744. if ($$.config.axis_rotated) {
  8745. yPos = (points[0][0] + points[2][0] + box.height * 0.6) / 2;
  8746. } else {
  8747. yPos = points[2][1];
  8748. if (d.value < 0 || d.value === 0 && !$$.hasPositiveValue) {
  8749. yPos += box.height;
  8750. if ($$.isBarType(d) && $$.isSafari()) {
  8751. yPos -= 3;
  8752. } else if (!$$.isBarType(d) && $$.isChrome()) {
  8753. yPos += 3;
  8754. }
  8755. } else {
  8756. yPos += $$.isBarType(d) ? -3 : -6;
  8757. }
  8758. } // show labels regardless of the domain if value is null
  8759. if (d.value === null && !$$.config.axis_rotated) {
  8760. if (yPos < box.height) {
  8761. yPos = box.height;
  8762. } else if (yPos > this.height) {
  8763. yPos = this.height - 4;
  8764. }
  8765. }
  8766. return yPos;
  8767. };
  8768. ChartInternal.prototype.initTitle = function () {
  8769. var $$ = this;
  8770. $$.title = $$.svg.append("text").text($$.config.title_text).attr("class", $$.CLASS.title);
  8771. };
  8772. ChartInternal.prototype.redrawTitle = function () {
  8773. var $$ = this;
  8774. $$.title.attr("x", $$.xForTitle.bind($$)).attr("y", $$.yForTitle.bind($$));
  8775. };
  8776. ChartInternal.prototype.xForTitle = function () {
  8777. var $$ = this,
  8778. config = $$.config,
  8779. position = config.title_position || 'left',
  8780. x;
  8781. if (position.indexOf('right') >= 0) {
  8782. x = $$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width - config.title_padding.right;
  8783. } else if (position.indexOf('center') >= 0) {
  8784. x = Math.max(($$.currentWidth - $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).width) / 2, 0);
  8785. } else {
  8786. // left
  8787. x = config.title_padding.left;
  8788. }
  8789. return x;
  8790. };
  8791. ChartInternal.prototype.yForTitle = function () {
  8792. var $$ = this;
  8793. return $$.config.title_padding.top + $$.getTextRect($$.title.node().textContent, $$.CLASS.title, $$.title.node()).height;
  8794. };
  8795. ChartInternal.prototype.getTitlePadding = function () {
  8796. var $$ = this;
  8797. return $$.yForTitle() + $$.config.title_padding.bottom;
  8798. };
  8799. function powerOfTen(d) {
  8800. return d / Math.pow(10, Math.ceil(Math.log(d) / Math.LN10 - 1e-12)) === 1;
  8801. }
  8802. ChartInternal.prototype.drawColorScale = function () {
  8803. var $$ = this,
  8804. d3 = $$.d3,
  8805. config = $$.config,
  8806. target = $$.data.targets[0],
  8807. barWidth,
  8808. barHeight,
  8809. axis,
  8810. points,
  8811. legendAxis,
  8812. axisScale,
  8813. inverseScale,
  8814. height;
  8815. barWidth = !isNaN(config.stanford_scaleWidth) ? config.stanford_scaleWidth : 20;
  8816. barHeight = 5;
  8817. if (barHeight < 0 || barWidth < 0) {
  8818. throw Error("Colorscale's barheight and barwidth must be greater than 0.");
  8819. }
  8820. height = $$.height - config.stanford_padding.bottom - config.stanford_padding.top;
  8821. points = d3.range(config.stanford_padding.bottom, height, barHeight);
  8822. inverseScale = d3.scaleSequential(target.colors).domain([points[points.length - 1], points[0]]);
  8823. if ($$.colorScale) {
  8824. $$.colorScale.remove();
  8825. }
  8826. $$.colorScale = $$.svg.append("g").attr('width', 50).attr('height', height).attr('class', CLASS.colorScale);
  8827. $$.colorScale.append('g').attr('transform', "translate(0, ".concat(config.stanford_padding.top, ")")).selectAll('bars').data(points).enter().append('rect').attr('y', function (d, i) {
  8828. return i * barHeight;
  8829. }).attr('x', 0).attr('width', barWidth).attr('height', barHeight).attr('fill', function (d) {
  8830. return inverseScale(d);
  8831. }); // Legend Axis
  8832. axisScale = d3.scaleLog().domain([target.minEpochs, target.maxEpochs]).range([points[0] + config.stanford_padding.top + points[points.length - 1] + barHeight - 1, points[0] + config.stanford_padding.top]);
  8833. legendAxis = d3.axisRight(axisScale);
  8834. if (config.stanford_scaleFormat === 'pow10') {
  8835. legendAxis.tickValues([1, 10, 100, 1000, 10000, 100000, 1000000, 10000000]);
  8836. } else if (isFunction(config.stanford_scaleFormat)) {
  8837. legendAxis.tickFormat(config.stanford_scaleFormat);
  8838. } else {
  8839. legendAxis.tickFormat(d3.format("d"));
  8840. }
  8841. if (isFunction(config.stanford_scaleValues)) {
  8842. legendAxis.tickValues(config.stanford_scaleValues(target.minEpochs, target.maxEpochs));
  8843. } // Draw Axis
  8844. axis = $$.colorScale.append("g").attr("class", "legend axis").attr("transform", "translate(".concat(barWidth, ",0)")).call(legendAxis);
  8845. if (config.stanford_scaleFormat === 'pow10') {
  8846. axis.selectAll(".tick text").text(null).filter(powerOfTen).text(10).append("tspan").attr("dy", "-.7em") // https://bl.ocks.org/mbostock/6738229
  8847. .text(function (d) {
  8848. return Math.round(Math.log(d) / Math.LN10);
  8849. });
  8850. }
  8851. $$.colorScale.attr('transform', "translate(".concat($$.currentWidth - $$.xForColorScale(), ", 0)"));
  8852. };
  8853. ChartInternal.prototype.xForColorScale = function () {
  8854. var $$ = this;
  8855. return $$.config.stanford_padding.right + getBBox($$.colorScale.node()).width;
  8856. };
  8857. ChartInternal.prototype.getColorScalePadding = function () {
  8858. var $$ = this;
  8859. return $$.xForColorScale() + $$.config.stanford_padding.left + 20;
  8860. };
  8861. ChartInternal.prototype.isStanfordGraphType = function () {
  8862. var $$ = this;
  8863. return $$.config.data_type === 'stanford';
  8864. };
  8865. ChartInternal.prototype.initStanfordData = function () {
  8866. var $$ = this,
  8867. d3 = $$.d3,
  8868. config = $$.config,
  8869. target = $$.data.targets[0],
  8870. epochs,
  8871. maxEpochs,
  8872. minEpochs; // Make larger values appear on top
  8873. target.values.sort(compareEpochs); // Get array of epochs
  8874. epochs = target.values.map(function (a) {
  8875. return a.epochs;
  8876. });
  8877. minEpochs = !isNaN(config.stanford_scaleMin) ? config.stanford_scaleMin : d3.min(epochs);
  8878. maxEpochs = !isNaN(config.stanford_scaleMax) ? config.stanford_scaleMax : d3.max(epochs);
  8879. if (minEpochs > maxEpochs) {
  8880. throw Error("Number of minEpochs has to be smaller than maxEpochs");
  8881. }
  8882. target.colors = isFunction(config.stanford_colors) ? config.stanford_colors : d3.interpolateHslLong(d3.hsl(250, 1, 0.5), d3.hsl(0, 1, 0.5));
  8883. target.colorscale = d3.scaleSequentialLog(target.colors).domain([minEpochs, maxEpochs]);
  8884. target.minEpochs = minEpochs;
  8885. target.maxEpochs = maxEpochs;
  8886. };
  8887. ChartInternal.prototype.getStanfordPointColor = function (d) {
  8888. var $$ = this,
  8889. target = $$.data.targets[0];
  8890. return target.colorscale(d.epochs);
  8891. }; // http://jsfiddle.net/Xotic750/KtzLq/
  8892. ChartInternal.prototype.getCentroid = function (points) {
  8893. var area = getRegionArea(points);
  8894. var x = 0,
  8895. y = 0,
  8896. i,
  8897. j,
  8898. f,
  8899. point1,
  8900. point2;
  8901. for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
  8902. point1 = points[i];
  8903. point2 = points[j];
  8904. f = point1.x * point2.y - point2.x * point1.y;
  8905. x += (point1.x + point2.x) * f;
  8906. y += (point1.y + point2.y) * f;
  8907. }
  8908. f = area * 6;
  8909. return {
  8910. x: x / f,
  8911. y: y / f
  8912. };
  8913. };
  8914. ChartInternal.prototype.getStanfordTooltipTitle = function (d) {
  8915. var $$ = this,
  8916. labelX = $$.axis.getLabelText('x'),
  8917. labelY = $$.axis.getLabelText('y');
  8918. return "\n <tr><th>".concat(labelX ? sanitise(labelX) : "x", "</th><th class='value'>").concat(d.x, "</th></tr>\n <tr><th>").concat(labelY ? sanitise(labelY) : "y", "</th><th class='value'>").concat(d.value, "</th></tr>\n ");
  8919. };
  8920. ChartInternal.prototype.countEpochsInRegion = function (region) {
  8921. var $$ = this,
  8922. target = $$.data.targets[0],
  8923. total,
  8924. count;
  8925. total = target.values.reduce(function (accumulator, currentValue) {
  8926. return accumulator + Number(currentValue.epochs);
  8927. }, 0);
  8928. count = target.values.reduce(function (accumulator, currentValue) {
  8929. if (pointInRegion(currentValue, region)) {
  8930. return accumulator + Number(currentValue.epochs);
  8931. }
  8932. return accumulator;
  8933. }, 0);
  8934. return {
  8935. value: count,
  8936. percentage: count !== 0 ? (count / total * 100).toFixed(1) : 0
  8937. };
  8938. };
  8939. var getRegionArea = function getRegionArea(points) {
  8940. // thanks to: https://stackoverflow.com/questions/16282330/find-centerpoint-of-polygon-in-javascript
  8941. var area = 0,
  8942. i,
  8943. j,
  8944. point1,
  8945. point2;
  8946. for (i = 0, j = points.length - 1; i < points.length; j = i, i += 1) {
  8947. point1 = points[i];
  8948. point2 = points[j];
  8949. area += point1.x * point2.y;
  8950. area -= point1.y * point2.x;
  8951. }
  8952. area /= 2;
  8953. return area;
  8954. };
  8955. var pointInRegion = function pointInRegion(point, region) {
  8956. // thanks to: http://bl.ocks.org/bycoffe/5575904
  8957. // ray-casting algorithm based on
  8958. // http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
  8959. var xi,
  8960. yi,
  8961. yj,
  8962. xj,
  8963. intersect,
  8964. x = point.x,
  8965. y = point.value,
  8966. inside = false;
  8967. for (var i = 0, j = region.length - 1; i < region.length; j = i++) {
  8968. xi = region[i].x;
  8969. yi = region[i].y;
  8970. xj = region[j].x;
  8971. yj = region[j].y;
  8972. intersect = yi > y !== yj > y && x < (xj - xi) * (y - yi) / (yj - yi) + xi;
  8973. if (intersect) {
  8974. inside = !inside;
  8975. }
  8976. }
  8977. return inside;
  8978. };
  8979. var compareEpochs = function compareEpochs(a, b) {
  8980. if (a.epochs < b.epochs) {
  8981. return -1;
  8982. }
  8983. if (a.epochs > b.epochs) {
  8984. return 1;
  8985. }
  8986. return 0;
  8987. };
  8988. ChartInternal.prototype.initStanfordElements = function () {
  8989. var $$ = this; // Avoid blocking eventRect
  8990. $$.stanfordElements = $$.main.select('.' + CLASS.chart).append('g').attr('class', CLASS.stanfordElements);
  8991. $$.stanfordElements.append('g').attr('class', CLASS.stanfordLines);
  8992. $$.stanfordElements.append('g').attr('class', CLASS.stanfordTexts);
  8993. $$.stanfordElements.append('g').attr('class', CLASS.stanfordRegions);
  8994. };
  8995. ChartInternal.prototype.updateStanfordElements = function (duration) {
  8996. var $$ = this,
  8997. main = $$.main,
  8998. config = $$.config,
  8999. stanfordLine,
  9000. stanfordLineEnter,
  9001. stanfordRegion,
  9002. stanfordRegionEnter,
  9003. stanfordText,
  9004. stanfordTextEnter,
  9005. xvCustom = $$.xvCustom.bind($$),
  9006. yvCustom = $$.yvCustom.bind($$),
  9007. countPointsInRegion = $$.countEpochsInRegion.bind($$); // Stanford-Lines
  9008. stanfordLine = main.select('.' + CLASS.stanfordLines).style('shape-rendering', 'geometricprecision').selectAll('.' + CLASS.stanfordLine).data(config.stanford_lines); // enter
  9009. stanfordLineEnter = stanfordLine.enter().append('g').attr("class", function (d) {
  9010. return CLASS.stanfordLine + (d['class'] ? ' ' + d['class'] : '');
  9011. });
  9012. stanfordLineEnter.append('line').attr("x1", function (d) {
  9013. return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');
  9014. }).attr("x2", function (d) {
  9015. return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');
  9016. }).attr("y1", function (d) {
  9017. return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');
  9018. }).attr("y2", function (d) {
  9019. return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');
  9020. }).style("opacity", 0); // update
  9021. $$.stanfordLines = stanfordLineEnter.merge(stanfordLine);
  9022. $$.stanfordLines.select('line').transition().duration(duration).attr("x1", function (d) {
  9023. return config.axis_rotated ? yvCustom(d, 'value_y1') : xvCustom(d, 'value_x1');
  9024. }).attr("x2", function (d) {
  9025. return config.axis_rotated ? yvCustom(d, 'value_y2') : xvCustom(d, 'value_x2');
  9026. }).attr("y1", function (d) {
  9027. return config.axis_rotated ? xvCustom(d, 'value_x1') : yvCustom(d, 'value_y1');
  9028. }).attr("y2", function (d) {
  9029. return config.axis_rotated ? xvCustom(d, 'value_x2') : yvCustom(d, 'value_y2');
  9030. }).style("opacity", 1); // exit
  9031. stanfordLine.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Text
  9032. stanfordText = main.select('.' + CLASS.stanfordTexts).selectAll('.' + CLASS.stanfordText).data(config.stanford_texts); // enter
  9033. stanfordTextEnter = stanfordText.enter().append('g').attr("class", function (d) {
  9034. return CLASS.stanfordText + (d['class'] ? ' ' + d['class'] : '');
  9035. });
  9036. stanfordTextEnter.append('text').attr("x", function (d) {
  9037. return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x');
  9038. }).attr("y", function (d) {
  9039. return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y');
  9040. }).style("opacity", 0); // update
  9041. $$.stanfordTexts = stanfordTextEnter.merge(stanfordText);
  9042. $$.stanfordTexts.select('text').transition().duration(duration).attr("x", function (d) {
  9043. return config.axis_rotated ? yvCustom(d, 'y') : xvCustom(d, 'x');
  9044. }).attr("y", function (d) {
  9045. return config.axis_rotated ? xvCustom(d, 'x') : yvCustom(d, 'y');
  9046. }).text(function (d) {
  9047. return d.content;
  9048. }).style("opacity", 1); // exit
  9049. stanfordText.exit().transition().duration(duration).style("opacity", 0).remove(); // Stanford-Regions
  9050. stanfordRegion = main.select('.' + CLASS.stanfordRegions).selectAll('.' + CLASS.stanfordRegion).data(config.stanford_regions); // enter
  9051. stanfordRegionEnter = stanfordRegion.enter().append('g').attr("class", function (d) {
  9052. return CLASS.stanfordRegion + (d['class'] ? ' ' + d['class'] : '');
  9053. });
  9054. stanfordRegionEnter.append('polygon').attr("points", function (d) {
  9055. return d.points.map(function (value) {
  9056. return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(",");
  9057. }).join(" ");
  9058. }).style("opacity", 0);
  9059. stanfordRegionEnter.append('text').attr("x", function (d) {
  9060. return $$.getCentroid(d.points).x;
  9061. }).attr("y", function (d) {
  9062. return $$.getCentroid(d.points).y;
  9063. }).style("opacity", 0); // update
  9064. $$.stanfordRegions = stanfordRegionEnter.merge(stanfordRegion);
  9065. $$.stanfordRegions.select('polygon').transition().duration(duration).attr("points", function (d) {
  9066. return d.points.map(function (value) {
  9067. return [config.axis_rotated ? yvCustom(value, 'y') : xvCustom(value, 'x'), config.axis_rotated ? xvCustom(value, 'x') : yvCustom(value, 'y')].join(",");
  9068. }).join(" ");
  9069. }).style("opacity", function (d) {
  9070. return d.opacity ? d.opacity : 0.2;
  9071. });
  9072. $$.stanfordRegions.select('text').transition().duration(duration).attr("x", function (d) {
  9073. return config.axis_rotated ? yvCustom($$.getCentroid(d.points), 'y') : xvCustom($$.getCentroid(d.points), 'x');
  9074. }).attr("y", function (d) {
  9075. return config.axis_rotated ? xvCustom($$.getCentroid(d.points), 'x') : yvCustom($$.getCentroid(d.points), 'y');
  9076. }).text(function (d) {
  9077. if (d.text) {
  9078. var value, percentage, temp;
  9079. if ($$.isStanfordGraphType()) {
  9080. temp = countPointsInRegion(d.points);
  9081. value = temp.value;
  9082. percentage = temp.percentage;
  9083. }
  9084. return d.text(value, percentage);
  9085. }
  9086. return "";
  9087. }).attr("text-anchor", "middle").attr("dominant-baseline", "middle").style("opacity", 1); // exit
  9088. stanfordRegion.exit().transition().duration(duration).style("opacity", 0).remove();
  9089. };
  9090. ChartInternal.prototype.initTooltip = function () {
  9091. var $$ = this,
  9092. config = $$.config,
  9093. i;
  9094. $$.tooltip = $$.selectChart.style("position", "relative").append("div").attr('class', CLASS.tooltipContainer).style("position", "absolute").style("pointer-events", "none").style("display", "none"); // Show tooltip if needed
  9095. if (config.tooltip_init_show) {
  9096. if ($$.isTimeSeries() && isString(config.tooltip_init_x)) {
  9097. config.tooltip_init_x = $$.parseDate(config.tooltip_init_x);
  9098. for (i = 0; i < $$.data.targets[0].values.length; i++) {
  9099. if ($$.data.targets[0].values[i].x - config.tooltip_init_x === 0) {
  9100. break;
  9101. }
  9102. }
  9103. config.tooltip_init_x = i;
  9104. }
  9105. $$.tooltip.html(config.tooltip_contents.call($$, $$.data.targets.map(function (d) {
  9106. return $$.addName(d.values[config.tooltip_init_x]);
  9107. }), $$.axis.getXAxisTickFormat(), $$.getYFormat($$.hasArcType()), $$.color));
  9108. $$.tooltip.style("top", config.tooltip_init_position.top).style("left", config.tooltip_init_position.left).style("display", "block");
  9109. }
  9110. };
  9111. ChartInternal.prototype.getTooltipSortFunction = function () {
  9112. var $$ = this,
  9113. config = $$.config;
  9114. if (config.data_groups.length === 0 || config.tooltip_order !== undefined) {
  9115. // if data are not grouped or if an order is specified
  9116. // for the tooltip values we sort them by their values
  9117. var order = config.tooltip_order;
  9118. if (order === undefined) {
  9119. order = config.data_order;
  9120. }
  9121. var valueOf = function valueOf(obj) {
  9122. return obj ? obj.value : null;
  9123. }; // if data are not grouped, we sort them by their value
  9124. if (isString(order) && order.toLowerCase() === 'asc') {
  9125. return function (a, b) {
  9126. return valueOf(a) - valueOf(b);
  9127. };
  9128. } else if (isString(order) && order.toLowerCase() === 'desc') {
  9129. return function (a, b) {
  9130. return valueOf(b) - valueOf(a);
  9131. };
  9132. } else if (isFunction(order)) {
  9133. // if the function is from data_order we need
  9134. // to wrap the returned function in order to format
  9135. // the sorted value to the expected format
  9136. var sortFunction = order;
  9137. if (config.tooltip_order === undefined) {
  9138. sortFunction = function sortFunction(a, b) {
  9139. return order(a ? {
  9140. id: a.id,
  9141. values: [a]
  9142. } : null, b ? {
  9143. id: b.id,
  9144. values: [b]
  9145. } : null);
  9146. };
  9147. }
  9148. return sortFunction;
  9149. } else if (isArray(order)) {
  9150. return function (a, b) {
  9151. return order.indexOf(a.id) - order.indexOf(b.id);
  9152. };
  9153. }
  9154. } else {
  9155. // if data are grouped, we follow the order of grouped targets
  9156. var ids = $$.orderTargets($$.data.targets).map(function (i) {
  9157. return i.id;
  9158. }); // if it was either asc or desc we need to invert the order
  9159. // returned by orderTargets
  9160. if ($$.isOrderAsc() || $$.isOrderDesc()) {
  9161. ids = ids.reverse();
  9162. }
  9163. return function (a, b) {
  9164. return ids.indexOf(a.id) - ids.indexOf(b.id);
  9165. };
  9166. }
  9167. };
  9168. ChartInternal.prototype.getTooltipContent = function (d, defaultTitleFormat, defaultValueFormat, color) {
  9169. var $$ = this,
  9170. config = $$.config,
  9171. titleFormat = config.tooltip_format_title || defaultTitleFormat,
  9172. nameFormat = config.tooltip_format_name || function (name) {
  9173. return name;
  9174. },
  9175. text,
  9176. i,
  9177. title,
  9178. value,
  9179. name,
  9180. bgcolor;
  9181. var valueFormat = config.tooltip_format_value;
  9182. if (!valueFormat) {
  9183. valueFormat = $$.isTargetNormalized(d.id) ? function (v, ratio) {
  9184. return "".concat((ratio * 100).toFixed(2), "%");
  9185. } : defaultValueFormat;
  9186. }
  9187. var tooltipSortFunction = this.getTooltipSortFunction();
  9188. if (tooltipSortFunction) {
  9189. d.sort(tooltipSortFunction);
  9190. }
  9191. for (i = 0; i < d.length; i++) {
  9192. if (!(d[i] && (d[i].value || d[i].value === 0))) {
  9193. continue;
  9194. }
  9195. if ($$.isStanfordGraphType()) {
  9196. // Custom tooltip for stanford plots
  9197. if (!text) {
  9198. title = $$.getStanfordTooltipTitle(d[i]);
  9199. text = "<table class='" + $$.CLASS.tooltip + "'>" + title;
  9200. }
  9201. bgcolor = $$.getStanfordPointColor(d[i]);
  9202. name = sanitise(config.data_epochs); // Epochs key name
  9203. value = d[i].epochs;
  9204. } else {
  9205. // Regular tooltip
  9206. if (!text) {
  9207. title = sanitise(titleFormat ? titleFormat(d[i].x, d[i].index) : d[i].x);
  9208. text = "<table class='" + $$.CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
  9209. }
  9210. value = sanitise(valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index, d));
  9211. if (value !== undefined) {
  9212. // Skip elements when their name is set to null
  9213. if (d[i].name === null) {
  9214. continue;
  9215. }
  9216. name = sanitise(nameFormat(d[i].name, d[i].ratio, d[i].id, d[i].index));
  9217. bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
  9218. }
  9219. }
  9220. if (value !== undefined) {
  9221. text += "<tr class='" + $$.CLASS.tooltipName + "-" + $$.getTargetSelectorSuffix(d[i].id) + "'>";
  9222. text += "<td class='name'><span style='background-color:" + bgcolor + "'></span>" + name + "</td>";
  9223. text += "<td class='value'>" + value + "</td>";
  9224. text += "</tr>";
  9225. }
  9226. }
  9227. return text + "</table>";
  9228. };
  9229. ChartInternal.prototype.tooltipPosition = function (dataToShow, tWidth, tHeight, element) {
  9230. var $$ = this,
  9231. config = $$.config,
  9232. d3 = $$.d3;
  9233. var svgLeft, tooltipLeft, tooltipRight, tooltipTop, chartRight;
  9234. var forArc = $$.hasArcType(),
  9235. mouse = d3.mouse(element); // Determin tooltip position
  9236. if (forArc) {
  9237. tooltipLeft = ($$.width - ($$.isLegendRight ? $$.getLegendWidth() : 0)) / 2 + mouse[0];
  9238. tooltipTop = ($$.hasType('gauge') ? $$.height : $$.height / 2) + mouse[1] + 20;
  9239. } else {
  9240. svgLeft = $$.getSvgLeft(true);
  9241. if (config.axis_rotated) {
  9242. tooltipLeft = svgLeft + mouse[0] + 100;
  9243. tooltipRight = tooltipLeft + tWidth;
  9244. chartRight = $$.currentWidth - $$.getCurrentPaddingRight();
  9245. tooltipTop = $$.x(dataToShow[0].x) + 20;
  9246. } else {
  9247. tooltipLeft = svgLeft + $$.getCurrentPaddingLeft(true) + $$.x(dataToShow[0].x) + 20;
  9248. tooltipRight = tooltipLeft + tWidth;
  9249. chartRight = svgLeft + $$.currentWidth - $$.getCurrentPaddingRight();
  9250. tooltipTop = mouse[1] + 15;
  9251. }
  9252. if (tooltipRight > chartRight) {
  9253. // 20 is needed for Firefox to keep tooltip width
  9254. tooltipLeft -= tooltipRight - chartRight + 20;
  9255. }
  9256. if (tooltipTop + tHeight > $$.currentHeight) {
  9257. tooltipTop -= tHeight + 30;
  9258. }
  9259. }
  9260. if (tooltipTop < 0) {
  9261. tooltipTop = 0;
  9262. }
  9263. return {
  9264. top: tooltipTop,
  9265. left: tooltipLeft
  9266. };
  9267. };
  9268. ChartInternal.prototype.showTooltip = function (selectedData, element) {
  9269. var $$ = this,
  9270. config = $$.config;
  9271. var tWidth, tHeight, position;
  9272. var forArc = $$.hasArcType(),
  9273. dataToShow = selectedData.filter(function (d) {
  9274. return d && isValue(d.value);
  9275. }),
  9276. positionFunction = config.tooltip_position || ChartInternal.prototype.tooltipPosition;
  9277. if (dataToShow.length === 0 || !config.tooltip_show) {
  9278. return;
  9279. }
  9280. $$.tooltip.html(config.tooltip_contents.call($$, selectedData, $$.axis.getXAxisTickFormat(), $$.getYFormat(forArc), $$.color)).style("display", "block"); // Get tooltip dimensions
  9281. tWidth = $$.tooltip.property('offsetWidth');
  9282. tHeight = $$.tooltip.property('offsetHeight');
  9283. position = positionFunction.call(this, dataToShow, tWidth, tHeight, element); // Set tooltip
  9284. $$.tooltip.style("top", position.top + "px").style("left", position.left + 'px');
  9285. };
  9286. ChartInternal.prototype.hideTooltip = function () {
  9287. this.tooltip.style("display", "none");
  9288. };
  9289. ChartInternal.prototype.setTargetType = function (targetIds, type) {
  9290. var $$ = this,
  9291. config = $$.config;
  9292. $$.mapToTargetIds(targetIds).forEach(function (id) {
  9293. $$.withoutFadeIn[id] = type === config.data_types[id];
  9294. config.data_types[id] = type;
  9295. });
  9296. if (!targetIds) {
  9297. config.data_type = type;
  9298. }
  9299. };
  9300. ChartInternal.prototype.hasType = function (type, targets) {
  9301. var $$ = this,
  9302. types = $$.config.data_types,
  9303. has = false;
  9304. targets = targets || $$.data.targets;
  9305. if (targets && targets.length) {
  9306. targets.forEach(function (target) {
  9307. var t = types[target.id];
  9308. if (t && t.indexOf(type) >= 0 || !t && type === 'line') {
  9309. has = true;
  9310. }
  9311. });
  9312. } else if (Object.keys(types).length) {
  9313. Object.keys(types).forEach(function (id) {
  9314. if (types[id] === type) {
  9315. has = true;
  9316. }
  9317. });
  9318. } else {
  9319. has = $$.config.data_type === type;
  9320. }
  9321. return has;
  9322. };
  9323. ChartInternal.prototype.hasArcType = function (targets) {
  9324. return this.hasType('pie', targets) || this.hasType('donut', targets) || this.hasType('gauge', targets);
  9325. };
  9326. ChartInternal.prototype.isLineType = function (d) {
  9327. var config = this.config,
  9328. id = isString(d) ? d : d.id;
  9329. return !config.data_types[id] || ['line', 'spline', 'area', 'area-spline', 'step', 'area-step'].indexOf(config.data_types[id]) >= 0;
  9330. };
  9331. ChartInternal.prototype.isStepType = function (d) {
  9332. var id = isString(d) ? d : d.id;
  9333. return ['step', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  9334. };
  9335. ChartInternal.prototype.isSplineType = function (d) {
  9336. var id = isString(d) ? d : d.id;
  9337. return ['spline', 'area-spline'].indexOf(this.config.data_types[id]) >= 0;
  9338. };
  9339. ChartInternal.prototype.isAreaType = function (d) {
  9340. var id = isString(d) ? d : d.id;
  9341. return ['area', 'area-spline', 'area-step'].indexOf(this.config.data_types[id]) >= 0;
  9342. };
  9343. ChartInternal.prototype.isBarType = function (d) {
  9344. var id = isString(d) ? d : d.id;
  9345. return this.config.data_types[id] === 'bar';
  9346. };
  9347. ChartInternal.prototype.isScatterType = function (d) {
  9348. var id = isString(d) ? d : d.id;
  9349. return this.config.data_types[id] === 'scatter';
  9350. };
  9351. ChartInternal.prototype.isStanfordType = function (d) {
  9352. var id = isString(d) ? d : d.id;
  9353. return this.config.data_types[id] === 'stanford';
  9354. };
  9355. ChartInternal.prototype.isScatterOrStanfordType = function (d) {
  9356. return this.isScatterType(d) || this.isStanfordType(d);
  9357. };
  9358. ChartInternal.prototype.isPieType = function (d) {
  9359. var id = isString(d) ? d : d.id;
  9360. return this.config.data_types[id] === 'pie';
  9361. };
  9362. ChartInternal.prototype.isGaugeType = function (d) {
  9363. var id = isString(d) ? d : d.id;
  9364. return this.config.data_types[id] === 'gauge';
  9365. };
  9366. ChartInternal.prototype.isDonutType = function (d) {
  9367. var id = isString(d) ? d : d.id;
  9368. return this.config.data_types[id] === 'donut';
  9369. };
  9370. ChartInternal.prototype.isArcType = function (d) {
  9371. return this.isPieType(d) || this.isDonutType(d) || this.isGaugeType(d);
  9372. };
  9373. ChartInternal.prototype.lineData = function (d) {
  9374. return this.isLineType(d) ? [d] : [];
  9375. };
  9376. ChartInternal.prototype.arcData = function (d) {
  9377. return this.isArcType(d.data) ? [d] : [];
  9378. };
  9379. /* not used
  9380. function scatterData(d) {
  9381. return isScatterType(d) ? d.values : [];
  9382. }
  9383. */
  9384. ChartInternal.prototype.barData = function (d) {
  9385. return this.isBarType(d) ? d.values : [];
  9386. };
  9387. ChartInternal.prototype.lineOrScatterOrStanfordData = function (d) {
  9388. return this.isLineType(d) || this.isScatterType(d) || this.isStanfordType(d) ? d.values : [];
  9389. };
  9390. ChartInternal.prototype.barOrLineData = function (d) {
  9391. return this.isBarType(d) || this.isLineType(d) ? d.values : [];
  9392. };
  9393. ChartInternal.prototype.isSafari = function () {
  9394. var ua = window.navigator.userAgent;
  9395. return ua.indexOf('Safari') >= 0 && ua.indexOf('Chrome') < 0;
  9396. };
  9397. ChartInternal.prototype.isChrome = function () {
  9398. var ua = window.navigator.userAgent;
  9399. return ua.indexOf('Chrome') >= 0;
  9400. };
  9401. ChartInternal.prototype.initZoom = function () {
  9402. var $$ = this,
  9403. d3 = $$.d3,
  9404. config = $$.config,
  9405. startEvent;
  9406. $$.zoom = d3.zoom().on("start", function () {
  9407. if (config.zoom_type !== 'scroll') {
  9408. return;
  9409. }
  9410. var e = d3.event.sourceEvent;
  9411. if (e && e.type === "brush") {
  9412. return;
  9413. }
  9414. startEvent = e;
  9415. config.zoom_onzoomstart.call($$.api, e);
  9416. }).on("zoom", function () {
  9417. if (config.zoom_type !== 'scroll') {
  9418. return;
  9419. }
  9420. var e = d3.event.sourceEvent;
  9421. if (e && e.type === "brush") {
  9422. return;
  9423. }
  9424. $$.redrawForZoom();
  9425. config.zoom_onzoom.call($$.api, $$.x.orgDomain());
  9426. }).on('end', function () {
  9427. if (config.zoom_type !== 'scroll') {
  9428. return;
  9429. }
  9430. var e = d3.event.sourceEvent;
  9431. if (e && e.type === "brush") {
  9432. return;
  9433. } // if click, do nothing. otherwise, click interaction will be canceled.
  9434. if (e && startEvent.clientX === e.clientX && startEvent.clientY === e.clientY) {
  9435. return;
  9436. }
  9437. config.zoom_onzoomend.call($$.api, $$.x.orgDomain());
  9438. });
  9439. $$.zoom.updateDomain = function () {
  9440. if (d3.event && d3.event.transform) {
  9441. $$.x.domain(d3.event.transform.rescaleX($$.subX).domain());
  9442. }
  9443. return this;
  9444. };
  9445. $$.zoom.updateExtent = function () {
  9446. this.scaleExtent([1, Infinity]).translateExtent([[0, 0], [$$.width, $$.height]]).extent([[0, 0], [$$.width, $$.height]]);
  9447. return this;
  9448. };
  9449. $$.zoom.update = function () {
  9450. return this.updateExtent().updateDomain();
  9451. };
  9452. return $$.zoom.updateExtent();
  9453. };
  9454. ChartInternal.prototype.zoomTransform = function (range) {
  9455. var $$ = this,
  9456. s = [$$.x(range[0]), $$.x(range[1])];
  9457. return $$.d3.zoomIdentity.scale($$.width / (s[1] - s[0])).translate(-s[0], 0);
  9458. };
  9459. ChartInternal.prototype.initDragZoom = function () {
  9460. var $$ = this;
  9461. var d3 = $$.d3;
  9462. var config = $$.config;
  9463. var context = $$.context = $$.svg;
  9464. var brushXPos = $$.margin.left + 20.5;
  9465. var brushYPos = $$.margin.top + 0.5;
  9466. if (!(config.zoom_type === 'drag' && config.zoom_enabled)) {
  9467. return;
  9468. }
  9469. var getZoomedDomain = function getZoomedDomain(selection) {
  9470. return selection && selection.map(function (x) {
  9471. return $$.x.invert(x);
  9472. });
  9473. };
  9474. var brush = $$.dragZoomBrush = d3.brushX().on("start", function () {
  9475. $$.api.unzoom();
  9476. $$.svg.select("." + CLASS.dragZoom).classed("disabled", false);
  9477. config.zoom_onzoomstart.call($$.api, d3.event.sourceEvent);
  9478. }).on("brush", function () {
  9479. config.zoom_onzoom.call($$.api, getZoomedDomain(d3.event.selection));
  9480. }).on("end", function () {
  9481. if (d3.event.selection == null) {
  9482. return;
  9483. }
  9484. var zoomedDomain = getZoomedDomain(d3.event.selection);
  9485. if (!config.zoom_disableDefaultBehavior) {
  9486. $$.api.zoom(zoomedDomain);
  9487. }
  9488. $$.svg.select("." + CLASS.dragZoom).classed("disabled", true);
  9489. config.zoom_onzoomend.call($$.api, zoomedDomain);
  9490. });
  9491. context.append("g").classed(CLASS.dragZoom, true).attr("clip-path", $$.clipPath).attr("transform", "translate(" + brushXPos + "," + brushYPos + ")").call(brush);
  9492. };
  9493. ChartInternal.prototype.getZoomDomain = function () {
  9494. var $$ = this,
  9495. config = $$.config,
  9496. d3 = $$.d3,
  9497. min = d3.min([$$.orgXDomain[0], config.zoom_x_min]),
  9498. max = d3.max([$$.orgXDomain[1], config.zoom_x_max]);
  9499. return [min, max];
  9500. };
  9501. ChartInternal.prototype.redrawForZoom = function () {
  9502. var $$ = this,
  9503. d3 = $$.d3,
  9504. config = $$.config,
  9505. zoom = $$.zoom,
  9506. x = $$.x;
  9507. if (!config.zoom_enabled) {
  9508. return;
  9509. }
  9510. if ($$.filterTargetsToShow($$.data.targets).length === 0) {
  9511. return;
  9512. }
  9513. zoom.update();
  9514. if (config.zoom_disableDefaultBehavior) {
  9515. return;
  9516. }
  9517. if ($$.isCategorized() && x.orgDomain()[0] === $$.orgXDomain[0]) {
  9518. x.domain([$$.orgXDomain[0] - 1e-10, x.orgDomain()[1]]);
  9519. }
  9520. $$.redraw({
  9521. withTransition: false,
  9522. withY: config.zoom_rescale,
  9523. withSubchart: false,
  9524. withEventRect: false,
  9525. withDimension: false
  9526. });
  9527. if (d3.event.sourceEvent && d3.event.sourceEvent.type === 'mousemove') {
  9528. $$.cancelClick = true;
  9529. }
  9530. };
  9531. return c3;
  9532. }));